PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.1
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
← All changes | back/Classes/FieldClass.php +0 -1014 11.0.3 → 11.1.1 View file →
@@ -1,1014 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Classes;
4 -
5 -use AcyMailing\Core\AcymClass;
6 -use AcyMailing\Helpers\SecurityHelper;
7 -
8 -class FieldClass extends AcymClass
9 -{
10 - const LANGUAGE_FIELD_ID_KEY = 'language_field_id';
11 -
12 - public function __construct()
13 - {
14 - parent::__construct();
15 -
16 - $this->table = 'field';
17 - $this->pkey = 'id';
18 - }
19 -
20 - public function getMatchingElements(array $settings = []): array
21 - {
22 - $query = 'SELECT * FROM #__acym_field';
23 - $queryCount = 'SELECT COUNT(*) FROM #__acym_field';
24 -
25 - $where = [];
26 - if (!empty($settings['types'])) {
27 - foreach ($settings['types'] as $i => $oneType) {
28 - $settings['types'][$i] = acym_escapeDB($oneType);
29 - }
30 - $where[] = ' type IN ('.implode(',', $settings['types']).')';
31 - }
32 -
33 - if (!empty($where)) {
34 - $query .= ' WHERE '.implode(' AND ', $where);
35 - $queryCount .= ' WHERE '.implode(' AND ', $where);
36 - }
37 -
38 - $query .= ' ORDER BY `ordering` ASC';
39 -
40 - return [
41 - 'elements' => acym_loadObjectList($query, 'id'),
42 - 'total' => acym_loadResult($queryCount),
43 - ];
44 - }
45 -
46 - public function getFieldsByID(array $ids): array
47 - {
48 - if (empty($ids)) {
49 - return [];
50 - }
51 -
52 - acym_arrayToInteger($ids);
53 -
54 - return acym_loadObjectList('SELECT * FROM #__acym_field WHERE `id` IN('.implode(',', $ids).') ORDER BY `ordering` ASC');
55 - }
56 -
57 - public function getFieldsByNameKey(array $nameKeys): array
58 - {
59 - if (empty($nameKeys)) {
60 - return [];
61 - }
62 -
63 - $nameKeys = array_map('acym_escapeDB', $nameKeys);
64 -
65 - return acym_loadObjectList('SELECT * FROM #__acym_field WHERE `namekey` IN('.implode(',', $nameKeys).') ORDER BY `ordering` ASC', 'id');
66 - }
67 -
68 - public function getFieldsByType(array $types): array
69 - {
70 - if (empty($types)) {
71 - return [];
72 - }
73 -
74 - $types = array_map('acym_escapeDB', $types);
75 - $query = 'SELECT * FROM #__acym_field WHERE `type` IN('.implode(',', $types).') ORDER BY `ordering` ASC';
76 -
77 - return acym_loadObjectList($query);
78 - }
79 -
80 - public function getOrdering(): int
81 - {
82 - return (int)acym_loadResult('SELECT COUNT(*) FROM #__acym_field');
83 - }
84 -
85 - public function getAllFieldsForUser(): array
86 - {
87 - return acym_loadObjectList('SELECT * FROM #__acym_field WHERE id NOT IN (1, 2) ORDER BY `ordering` ASC', 'id');
88 - }
89 -
90 - public function getAllFieldsForModuleFront(): array
91 - {
92 - return acym_loadObjectList(
93 - 'SELECT *
94 - FROM #__acym_field
95 - WHERE id != 2
96 - AND active = 1
97 - ORDER BY `ordering` ASC',
98 - 'id'
99 - );
100 - }
101 -
102 - public function getFieldsValueByUserId(int $userId): array
103 - {
104 - return acym_loadObjectList('SELECT * FROM #__acym_user_has_field WHERE user_id = '.intval($userId), 'field_id');
105 - }
106 -
107 - public function getFieldsValueByFieldId(int $fieldId): array
108 - {
109 - return acym_loadObjectList('SELECT * FROM #__acym_user_has_field WHERE field_id = '.intval($fieldId));
110 - }
111 -
112 - public function generateNamekey(string $name, string $namekey = ''): string
113 - {
114 - $fieldsNamekey = acym_loadResultArray('SELECT namekey FROM #__acym_field');
115 - $columnsUser = acym_getColumns('user');
116 - $namekeyForbidden = array_merge($fieldsNamekey, $columnsUser);
117 -
118 - $namekey = empty($namekey) ? substr(preg_replace('#[^a-z0-9_]#i', '', strtolower($name)), 0, 50) : $namekey;
119 - $baseNamekey = $namekey;
120 - $baseCount = count($namekeyForbidden);
121 -
122 - while (in_array($namekey, $namekeyForbidden)) {
123 - $namekey = $baseNamekey.'_'.$baseCount;
124 - $baseCount++;
125 - }
126 -
127 - return $namekey;
128 - }
129 -
130 - public function getValueFromDB(object $fieldDB): array
131 - {
132 - $query = 'SELECT '.acym_secureDBColumn($fieldDB->value).' AS value, '.acym_secureDBColumn($fieldDB->title).' AS title
133 - FROM `'.acym_secureDBColumn($fieldDB->database).'`.`'.acym_secureDBColumn($fieldDB->table).'`';
134 - if (isset($fieldDB->where_value) && strlen($fieldDB->where_value) > 0) {
135 - $allowedSigns = ['=', '!=', '>', '<', '>=', '<=', 'BEGINS', 'END', 'CONTAINS', 'NOTCONTAINS', 'LIKE', 'NOT LIKE', 'REGEXP', 'NOT REGEXP', 'IS NULL', 'IS NOT NULL'];
136 - $whereSign = in_array($fieldDB->where_sign ?? '', $allowedSigns, true) ? $fieldDB->where_sign : '=';
137 - $query .= ' WHERE `'.acym_secureDBColumn($fieldDB->where).'` '.$whereSign.' '.acym_escapeDB($fieldDB->where_value);
138 - }
139 - if (!empty($fieldDB->order_by)) $query .= ' ORDER BY '.acym_secureDBColumn($fieldDB->order_by).' '.acym_secureDBColumn($fieldDB->sort_order);
140 -
141 - return acym_loadObjectList($query);
142 - }
143 -
144 - public function store(int $userID, array $fields, bool $ajax = false): void
145 - {
146 - $customField = acym_getVar('array', 'customField', [], 'FILES');
147 - if (!empty($customField['tmp_name'])) {
148 - $uploadFolder = trim(acym_cleanPath(html_entity_decode(acym_getFilesFolder(true))), DS.' ').DS;
149 - $uploadPath = acym_cleanPath(ACYM_ROOT.$uploadFolder.'userfiles'.DS.$userID.DS);
150 - if (!file_exists($uploadPath)) {
151 - acym_createDir($uploadPath);
152 - }
153 - $allowedExtensions = explode(',', $this->config->get('allowed_files'));
154 -
155 - foreach ($customField['tmp_name'] as $key => $value) {
156 - if (is_array($value) && isset($value[0])) $value = $value[0];
157 - if (empty($value)) continue;
158 -
159 - // Get the uploaded file name
160 - $fileName = $customField['name'][$key];
161 - while (is_array($fileName) && isset($fileName[0])) {
162 - $fileName = $fileName[0];
163 - }
164 -
165 - if (!preg_match('#\.('.implode('|', $allowedExtensions).')$#Ui', $fileName)) {
166 - $ext = substr($fileName, strrpos($fileName, '.') + 1);
167 - if ($ajax) {
168 - $this->errors[] = acym_translationSprintf(
169 - 'ACYM_ACCEPTED_TYPE',
170 - esc_html($ext),
171 - implode(', ', $allowedExtensions)
172 - );
173 - } else {
174 - acym_enqueueMessage(
175 - acym_translationSprintf(
176 - 'ACYM_ACCEPTED_TYPE',
177 - esc_html($ext),
178 - implode(', ', $allowedExtensions)
179 - ),
180 - 'error',
181 - 5000
182 - );
183 - }
184 -
185 - continue;
186 - }
187 -
188 - if (!acym_uploadFile($value, $uploadPath.$fileName)) {
189 - if ($ajax) {
190 - $this->errors[] = acym_translation('ACYM_ERROR_SAVING');
191 - } else {
192 - acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVING'), 'error');
193 - }
194 -
195 - continue;
196 - }
197 - $fields[$key] = $customField['name'][$key];
198 - }
199 - }
200 -
201 - if (empty($fields)) return;
202 -
203 - foreach ($fields as $id => $value) {
204 - $field = $this->getOneById($id);
205 - if (empty($field)) {
206 - acym_enqueueMessage(acym_translationSprintf('ACYM_WRONG_FIELD_ID', $id), 'error');
207 - continue;
208 - }
209 - $fieldOptions = @json_decode(empty($field->option) ? '{}' : $field->option);
210 -
211 - if (is_array($value)) {
212 - if (in_array($field->type, ['multiple_dropdown', 'radio', 'phone'])) {
213 - if ($field->type === 'phone' && !empty($fieldOptions->max_characters) && !empty($value['phone'])) {
214 - $value['phone'] = substr($value['phone'], 0, $fieldOptions->max_characters);
215 - }
216 -
217 - $value = implode(',', $value);
218 - if ($value === ',') $value = '';
219 - } elseif ($field->type == 'checkbox') {
220 - $value = implode(',', array_keys($value));
221 - } elseif ($field->type == 'date') {
222 - $formatToDisplay = explode('%', $fieldOptions->format);
223 - unset($formatToDisplay[0]);
224 -
225 - $year = '0000';
226 - $month = '00';
227 - $day = '00';
228 - $i = 0;
229 - foreach ($formatToDisplay as $one) {
230 - if ($one === 'd') {
231 - $day = $value[$i];
232 - }
233 - if ($one === 'm') {
234 - $month = $value[$i];
235 - }
236 - if ($one === 'y') {
237 - $year = $value[$i];
238 - }
239 - $i++;
240 - }
241 -
242 - $value = $year.'-'.$month.'-'.$day;
243 - } else {
244 - $value = json_encode($value);
245 - }
246 - }
247 -
248 - if (in_array($field->type, ['text', 'textarea']) && !empty($fieldOptions->max_characters)) {
249 - $value = substr($value, 0, $fieldOptions->max_characters);
250 - }
251 -
252 - // If deleting a file field, also delete the physical file
253 - if ($field->type === 'file' && strlen($value) === 0) {
254 - $oldValue = acym_loadResult(
255 - 'SELECT `value` FROM #__acym_user_has_field WHERE `user_id` = '.intval($userID).' AND `field_id` = '.intval($id)
256 - );
257 - if (!empty($oldValue)) {
258 - $fileName = @json_decode($oldValue, true);
259 - if (is_array($fileName)) $fileName = $fileName[0];
260 - if (empty($fileName)) $fileName = $oldValue;
261 -
262 - $uploadFolder = trim(acym_cleanPath(html_entity_decode(acym_getFilesFolder(true))), DS.' ').DS;
263 - // Try new path (with user folder) first, then legacy path (without user folder)
264 - $filePath = acym_cleanPath(ACYM_ROOT.$uploadFolder.'userfiles'.DS.$userID.DS.$fileName);
265 - if (!file_exists($filePath)) {
266 - $filePath = acym_cleanPath(ACYM_ROOT.$uploadFolder.'userfiles'.DS.$fileName);
267 - }
268 - acym_deleteFile($filePath);
269 - }
270 - }
271 -
272 - // The user removed a value, don't add an empty line and remove any previous value from the bd
273 - if (strlen($value) === 0) {
274 - $query = 'DELETE FROM `#__acym_user_has_field`
275 - WHERE `user_id` = '.intval($userID).'
276 - AND `field_id` = '.intval($id);
277 - } else {
278 - $query = 'INSERT INTO #__acym_user_has_field (`user_id`, `field_id`, `value`) VALUES ('.intval($userID).', '.intval($id).', '.acym_escapeDB($value).')';
279 - $query .= ' ON DUPLICATE KEY UPDATE `value`= VALUES(`value`)';
280 - }
281 -
282 - acym_query($query);
283 - }
284 - }
285 -
286 - public function getAllFieldsByUserIds(array $userIds): array
287 - {
288 - acym_arrayToInteger($userIds);
289 - if (empty($userIds)) return [];
290 -
291 - $query = 'SELECT user_field.user_id, user_field.value, field.name FROM #__acym_user_has_field AS user_field
292 - JOIN #__acym_field AS field ON user_field.field_id = field.id
293 - WHERE user_field.user_id IN ('.implode(',', $userIds).')';
294 -
295 - return acym_loadObjectList($query);
296 - }
297 -
298 - public function getAllFieldsListingByUserIds(array $userIds, array $fieldIds, string $listing = ''): array
299 - {
300 - acym_arrayToInteger($userIds);
301 - if (empty($userIds)) return [];
302 -
303 - acym_arrayToInteger($fieldIds);
304 - if (empty($fieldIds)) return [];
305 -
306 - $query = 'SELECT field.type AS `type`, field.value AS `value`, field.name AS field_name, user_field.user_id AS user_id, user_field.field_id AS field_id, user_field.value AS field_value, field.active, field.option
307 - FROM #__acym_user_has_field AS user_field
308 - JOIN #__acym_field AS field ON user_field.field_id = field.id';
309 -
310 - $conditions = [];
311 -
312 - if (!empty($listing)) {
313 - $conditions[] = $listing;
314 - }
315 -
316 - $conditions[] = 'user_field.user_id IN ('.implode(',', $userIds).')';
317 - $conditions[] = 'user_field.field_id IN ('.implode(',', $fieldIds).')';
318 -
319 - if (!empty($conditions)) {
320 - $query .= ' WHERE ('.implode(') AND (', $conditions).')';
321 - }
322 -
323 - $fieldValues = [];
324 - $values = acym_loadObjectList($query);
325 -
326 - $fieldsTypeWithInField = ['radio', 'checkbox', 'single_dropdown', 'multiple_dropdown'];
327 - foreach ($values as $one) {
328 - if (intval($one->active) === 0) {
329 - continue;
330 - }
331 -
332 - $key = $one->field_id.'-'.$one->user_id;
333 -
334 - if (!in_array($one->type, $fieldsTypeWithInField)) {
335 - if ($one->type === 'phone') {
336 - if (empty($one->field_value)) {
337 - $fieldValues[$key] = '';
338 - } else {
339 - if (substr($one->field_value, 0, 1) === ',') {
340 - $fieldValues[$key] = str_replace(',', '', $one->field_value);
341 - } else {
342 - $fieldValues[$key] = '+'.str_replace(',', ' ', $one->field_value);
343 - }
344 - }
345 - } elseif ($one->type === 'date') {
346 - if (empty($one->field_value)) {
347 - $fieldValues[$key] = '';
348 - } else {
349 - $one->option = json_decode($one->option);
350 - $fieldValues[$key] = acym_displayDateFormat($one->option->format, '', $one->field_value, [], false);
351 - }
352 - } else {
353 - $decoded = json_decode($one->field_value);
354 - $fieldValues[$key] = is_array($decoded) ? implode(', ', $decoded) : $one->field_value;
355 - }
356 - } else {
357 - $defaultValues = json_decode($one->value, true);
358 - $defaultValues = array_filter($defaultValues, function ($fieldOption) {
359 - return !empty($fieldOption['value']) || !empty($fieldOption['title']);
360 - });
361 -
362 - if (empty($defaultValues)) {
363 - // Options from database
364 - if (!empty($one->field_value)) {
365 - $fieldOptions = json_decode($one->option, true);
366 - if (!empty($fieldOptions['fieldDB'])) {
367 - $dbOptions = json_decode($fieldOptions['fieldDB'], true);
368 - if (!empty($dbOptions['database']) && !empty($dbOptions['table']) && !empty($dbOptions['value']) && !empty($dbOptions['title'])) {
369 - $query = 'SELECT '.acym_secureDBColumn($dbOptions['title']).'
370 - FROM '.acym_secureDBColumn($dbOptions['database']).'.'.acym_secureDBColumn($dbOptions['table']).'
371 - WHERE '.acym_secureDBColumn($dbOptions['value']).' = '.acym_escapeDB($one->field_value);
372 - $fieldValues[$key][] = acym_loadResult($query);
373 - }
374 - }
375 - }
376 - } else {
377 - // Classic options
378 - foreach ($defaultValues as $oneValue) {
379 - if (!in_array($oneValue['value'], explode(',', $one->field_value))) continue;
380 - $fieldValues[$key][] = $oneValue['title'];
381 - }
382 - }
383 -
384 - if (!empty($fieldValues[$key])) {
385 - $fieldValues[$key] = implode(', ', $fieldValues[$key]);
386 - }
387 - }
388 - }
389 -
390 - return $fieldValues;
391 - }
392 -
393 - public function getAllFieldsBackendListing(): array
394 - {
395 - $whereLanguage = '(backend_listing = 1 OR `type` = "language")';
396 - $query = 'SELECT id, name FROM #__acym_field WHERE '.$whereLanguage.' AND active = 1 AND id NOT IN (1, 2) ORDER BY ordering';
397 -
398 - $return = [
399 - 'names' => [],
400 - 'ids' => [],
401 - ];
402 -
403 - foreach (acym_loadObjectList($query) as $one) {
404 - $return['names'][] = $one->name;
405 - $return['ids'][] = $one->id;
406 - }
407 -
408 - return $return;
409 - }
410 -
411 - public function getAllFieldsFrontendListing(): array
412 - {
413 - $fields = acym_loadObjectList('SELECT id, name FROM #__acym_field WHERE frontend_listing = 1 AND active = 1 AND id NOT IN (1, 2)');
414 -
415 - $return = [
416 - 'names' => [],
417 - 'ids' => [],
418 - ];
419 -
420 - foreach ($fields as $oneField) {
421 - $return['names'][] = $oneField->name;
422 - $return['ids'][] = $oneField->id;
423 - }
424 -
425 - return $return;
426 - }
427 -
428 - public function delete(array $elements): int
429 - {
430 - if (empty($elements)) return 0;
431 -
432 - acym_arrayToInteger($elements);
433 -
434 - acym_trigger('specialActionOnDelete', ['field', $elements]);
435 -
436 - acym_query('DELETE FROM #__acym_user_has_field WHERE field_id IN ('.implode(',', $elements).')');
437 -
438 - return parent::delete($elements);
439 - }
440 -
441 - /**
442 - * @param mixed $defaultValue
443 - */
444 - public function displayField(
445 - object $field,
446 - $defaultValue,
447 - array $valuesArray,
448 - bool $displayOutside = true,
449 - bool $displayFront = false,
450 - ?object $user = null,
451 - bool $showField = true
452 - ): void {
453 - if (intval($field->active) === 0 && intval($field->core) !== 1) {
454 - return;
455 - }
456 -
457 - $extraErrors = $this->config->get('extra_errors', '0');
458 - $isCoreField = $field->core == 1;
459 -
460 - if (!$isCoreField && !acym_level(ACYM_ENTERPRISE)) {
461 - return;
462 - }
463 -
464 - if (!$showField) {
465 - if (!acym_isAdmin()) {
466 - return;
467 - }
468 -
469 - if (acym_isAdmin() && acym_level(ACYM_ENTERPRISE) && !$isCoreField) {
470 - return;
471 - }
472 - }
473 -
474 - $data = [];
475 -
476 - $cmsUser = false;
477 - if ($displayFront && !empty($user->id)) {
478 - $cmsUser = !empty($user->cms_id);
479 - if ($field->id == 1) {
480 - $defaultValue = $user->name;
481 - } elseif ($field->id == 2) {
482 - $defaultValue = $user->email;
483 - } else {
484 - $allValues = [];
485 - $defaultUserValue = $this->getFieldsValueByUserId($user->id);
486 - if (!empty($defaultUserValue)) {
487 - foreach ($defaultUserValue as $one) {
488 - $allValues[$one->field_id] = $one->value;
489 - }
490 - }
491 -
492 - if (isset($allValues[$field->id])) {
493 - $defaultValue = is_null(json_decode($allValues[$field->id])) ? $allValues[$field->id] : json_decode($allValues[$field->id]);
494 - }
495 - }
496 - }
497 -
498 - if (in_array($field->type, ['radio', 'checkbox'])) {
499 - $valuesArrayTmp = [];
500 - foreach ($valuesArray as $oneValue) {
501 - if (!is_object($oneValue)) {
502 - $valuesArrayTmp = $valuesArray;
503 - break;
504 - }
505 -
506 - if (!empty($oneValue->disable)) continue;
507 - $valuesArrayTmp[$oneValue->value] = $oneValue->text;
508 - }
509 - $valuesArray = $valuesArrayTmp;
510 - }
511 -
512 - // Translate text of the options
513 - if (is_array($valuesArray)) {
514 - foreach ($valuesArray as $key => $oneValue) {
515 - if (is_object($oneValue) && !empty($valuesArray[$key]->text)) {
516 - $valuesArray[$key]->text = acym_translation($valuesArray[$key]->text);
517 - } elseif (is_string($oneValue)) {
518 - $valuesArray[$key] = acym_translation($valuesArray[$key]);
519 - }
520 - }
521 - }
522 -
523 - if (acym_isMultilingual() && $displayFront && !empty($field->translation)) {
524 - $field->translation = json_decode($field->translation, true);
525 - if (!empty($field->translation[acym_getLanguageTag()]) && !empty($field->translation[acym_getLanguageTag()]['name'])) {
526 - $field->name = $field->translation[acym_getLanguageTag()]['name'];
527 - }
528 - }
529 -
530 - $field->name = acym_translation($field->name);
531 -
532 - if (!empty((array)$field->option) && isset($field->option->authorized_content)) {
533 - if (empty($field->option->error_message_invalid)) {
534 - $field->option->authorized_content->message = acym_translationSprintf('ACYM_INCORRECT_FIELD_VALUE', $field->name);
535 - } else {
536 - $field->option->authorized_content->message = $field->option->error_message_invalid;
537 - }
538 - $data['authorizedContent'] = json_encode($field->option->authorized_content);
539 - }
540 -
541 - $attributesSelectField = [];
542 - if (!empty($field->option->max_characters)) {
543 - $data['maxCharacters'] = $field->option->max_characters;
544 - }
545 - if (!empty($field->option->size)) {
546 - $attributesSelectField['style'] = 'width:'.$field->option->size.'px';
547 - $data['style'] = 'width:'.$field->option->size.'px';
548 - }
549 -
550 - if (!$displayOutside) {
551 - $data['placeholder'] = $field->name;
552 - }
553 -
554 - $name = 'customField['.intval($field->id).']';
555 - if ($field->type === 'text') {
556 - $data['value'] = empty($defaultValue)
557 - ? ''
558 - : (
559 - is_scalar($defaultValue)
560 - ? $defaultValue
561 - : json_encode($defaultValue)
562 - );
563 - }
564 -
565 - $labelTypes = ['text', 'textarea', 'single_dropdown', 'multiple_dropdown', 'custom_text', 'language'];
566 - $titleTypes = ['date', 'radio', 'checkbox', 'file'];
567 -
568 - $useLabel = $displayOutside && (in_array($field->id, [1, 2]) || in_array($field->type, $labelTypes));
569 - $useTitle = $displayOutside && in_array($field->type, $titleTypes);
570 -
571 - if ($useLabel) {
572 - echo '<label class="cell margin-top-1"><span class="acym__users__creation__fields__title">'.esc_html($field->name).'</span>';
573 - }
574 - if ($useTitle) {
575 - echo '<div class="cell margin-top-1"><div class="acym__users__creation__fields__title">'.esc_html($field->name).'</div>';
576 - }
577 -
578 - $messageRequired = empty($field->option->error_message) ? '' : acym_translation($field->option->error_message);
579 - $requiredJson = json_encode(['type' => $field->type, 'message' => $messageRequired]);
580 - $required = '';
581 - if ($field->required) {
582 - $data['data-required'] = $requiredJson;
583 - $required = ' data-required="'.esc_attr($requiredJson).'"';
584 - $attributesSelectField['data-required'] = $requiredJson;
585 - }
586 -
587 - $readonly = '';
588 - if (!$showField && acym_isAdmin() && acym_level(ACYM_ENTERPRISE) && $isCoreField) {
589 - $attributesSelectField['disabled'] = true;
590 - unset($attributesSelectField['data-required']);
591 - $readonly = ' disabled ';
592 - $required = '';
593 - $data['disabled'] = true;
594 - unset($data['data-required']);
595 - }
596 -
597 - $defaultValue = $this->prepareDefaultValue($defaultValue, $field->type, $user);
598 -
599 - if ($field->id == 1) {
600 - $data['type'] = 'text';
601 - $data['name'] = 'user[name]';
602 - $data['autocomplete'] = 'name';
603 - $data['class'] = 'cell';
604 -
605 - if (empty($readonly)) {
606 - include acym_getPartial('fields', 'input');
607 - } else {
608 - ob_start();
609 - include acym_getPartial('fields', 'input');
610 - $input = ob_get_clean();
611 -
612 - acym_tooltip(
613 - [
614 - 'hoveredText' => $input,
615 - 'textShownInTooltip' => acym_translation('ACYM_CF_EDITION_BLOCKED'),
616 - ]
617 - );
618 - }
619 - } elseif ($field->id == 2) {
620 - $uniqueId = 'email_field_'.acym_rand(100, 900);
621 -
622 - unset($data['data-required']);
623 - $data['type'] = 'email';
624 - $data['name'] = 'user[email]';
625 - $data['autocomplete'] = 'email';
626 - $data['id'] = $uniqueId;
627 - $data['class'] = 'cell acym__user__edit__email';
628 - $data['required'] = true;
629 - $data['readonly'] = $cmsUser;
630 -
631 - if (empty($readonly)) {
632 - include acym_getPartial('fields', 'input');
633 - } else {
634 - ob_start();
635 - include acym_getPartial('fields', 'input');
636 - $input = ob_get_clean();
637 -
638 - acym_tooltip(
639 - [
640 - 'hoveredText' => $input,
641 - 'textShownInTooltip' => acym_translation('ACYM_CF_EDITION_BLOCKED'),
642 - ]
643 - );
644 - }
645 -
646 - if ($displayFront && !$cmsUser && !empty($this->config->get('email_spellcheck'))) {
647 - echo '<ul acym-data-field="'.esc_attr($uniqueId).'" class="acym_email_suggestions" style="display: none;"></ul>';
648 - }
649 - } elseif ($field->type === 'language') {
650 - $attributesSelectField['class'] = 'acym__select';
651 - if (empty($readonly)) {
652 - acym_select(
653 - $this->getLanguagesForDropdown(),
654 - 'user[language]',
655 - $defaultValue,
656 - $attributesSelectField,
657 - 'value',
658 - 'text',
659 - null,
660 - false,
661 - true
662 - );
663 - } else {
664 - acym_tooltip(
665 - [
666 - 'hoveredText' => acym_select(
667 - $this->getLanguagesForDropdown(),
668 - 'user[language]',
669 - $defaultValue,
670 - $attributesSelectField
671 - ),
672 - 'textShownInTooltip' => acym_translation('ACYM_CF_EDITION_BLOCKED'),
673 - ]
674 - );
675 - }
676 - } elseif ($field->type === 'text') {
677 - $data['type'] = 'text';
678 - $data['name'] = $name;
679 - include acym_getPartial('fields', 'input');
680 - } elseif ($field->type === 'textarea') {
681 - echo '<textarea name="'.esc_attr($name).'"';
682 - if (!empty($data['data-required'])) {
683 - echo ' data-required="'.esc_attr($data['data-required']).'"';
684 - }
685 - if (isset($data['maxCharacters'])) {
686 - echo ' maxlength="'.esc_attr($data['maxCharacters']).'"';
687 - }
688 - echo ' rows="'.intval($field->option->rows).'" cols="'.intval($field->option->columns).'">';
689 - echo esc_html(is_scalar($defaultValue) ? $defaultValue : '');
690 - echo '</textarea>';
691 - } elseif ($field->type === 'radio') {
692 - if ($displayFront) {
693 - $data['name'] = $name;
694 - $data['values'] = $valuesArray;
695 - $data['value'] = $defaultValue;
696 - include acym_getPartial('fields', 'radio');
697 - } else {
698 - acym_radio(
699 - $valuesArray,
700 - $name.'[]',
701 - $defaultValue,
702 - $field->required ? ['data-required' => $requiredJson] : []
703 - );
704 - }
705 - } elseif ($field->type === 'checkbox') {
706 - $data['name'] = $name;
707 - $data['values'] = $valuesArray;
708 - $data['value'] = $defaultValue;
709 - $data['displayFront'] = $displayFront;
710 - include acym_getPartial('fields', 'checkbox');
711 - } elseif ($field->type === 'single_dropdown') {
712 - $attributesSelectField['class'] = 'acym__custom__fields__select__form acym__select';
713 - acym_select(
714 - $valuesArray,
715 - $name,
716 - $defaultValue,
717 - $attributesSelectField,
718 - 'value',
719 - 'text',
720 - null,
721 - false,
722 - true
723 - );
724 - } elseif ($field->type === 'multiple_dropdown') {
725 - $attributes = [
726 - 'class' => 'acym__custom__fields__select__multiple__form acym__select',
727 - 'style' => empty($field->option->size) ? '' : 'width:'.$field->option->size.'px',
728 - ];
729 - if ($field->required) {
730 - $attributes['data-required'] = $displayFront ? esc_attr($requiredJson) : $requiredJson;
731 - }
732 -
733 - acym_selectMultiple(
734 - $valuesArray,
735 - $name,
736 - $defaultValue,
737 - $attributes,
738 - 'value',
739 - 'text',
740 - true
741 - );
742 - } elseif ($field->type === 'date') {
743 - $attributes = [
744 - 'class' => 'acym__custom__fields__select__form acym__select',
745 - 'acym-field-type' => 'date',
746 - ];
747 - if (!empty($required)) {
748 - $attributes['data-required'] = $requiredJson;
749 - }
750 -
751 - echo wp_kses(
752 - acym_displayDateFormat(
753 - $field->option->format,
754 - $name.'[]',
755 - $defaultValue,
756 - $attributes
757 - ),
758 - array_merge_recursive(
759 - SecurityHelper::ALLOWED_HTML_SELECT,
760 - [
761 - 'select' => [
762 - 'data-required' => true,
763 - 'acym-field-type' => true,
764 - ],
765 - 'div' => [
766 - 'class' => true,
767 - ],
768 - ]
769 - )
770 - );
771 - } elseif ($field->type === 'file') {
772 - if ($displayFront) {
773 - unset($data['placeholder'], $data['value'], $data['authorizedContent'], $data['style'], $data['maxCharacters']);
774 - $data['type'] = 'file';
775 - $data['name'] = $name;
776 - include acym_getPartial('fields', 'input');
777 - } else {
778 - $downloadUrl = '';
779 - if (!empty($defaultValue) && !empty($user->id)) {
780 - $fileName = is_array($defaultValue) ? $defaultValue[0] : $defaultValue;
781 - if (!empty($fileName)) {
782 - $uploadFolder = trim(acym_cleanPath(html_entity_decode(acym_getFilesFolder(true))), DS.' ').DS;
783 - $userFilePath = $uploadFolder.'userfiles'.DS.$user->id.DS.$fileName;
784 - $legacyFilePath = $uploadFolder.'userfiles'.DS.$fileName;
785 -
786 - if (file_exists(acym_cleanPath(ACYM_ROOT.$userFilePath))) {
787 - $downloadUrl = ACYM_LIVE.str_replace(DS, '/', $userFilePath);
788 - } elseif (file_exists(acym_cleanPath(ACYM_ROOT.$legacyFilePath))) {
789 - $downloadUrl = ACYM_LIVE.str_replace(DS, '/', $legacyFilePath);
790 - }
791 - }
792 - }
793 - $attributes = [];
794 - if (!empty($required)) {
795 - $attributes['data-required'] = $requiredJson;
796 - }
797 - acym_inputFile($name.'[]', $defaultValue, '', $attributes, $downloadUrl);
798 - }
799 - } elseif ($field->type === 'phone') {
800 - $indicator = !empty($defaultValue[0]) ? $defaultValue[0] : '';
801 - $number = !empty($defaultValue[1]) ? $defaultValue[1] : '';
802 -
803 - if ($displayOutside) {
804 - echo '<div class="cell margin-top-1 grid-x"><div class="acym__users__creation__fields__title cell">'.esc_html($field->name).'</div>';
805 - }
806 - echo '<div class="cell large-5 medium-4 padding-next-1">';
807 - acym_generateCountryNumber($name.'[code]', $indicator);
808 - echo '</div>';
809 -
810 - unset($data['authorizedContent']);
811 - $data['type'] = 'tel';
812 - $data['name'] = $name.'[phone]';
813 - $data['autocomplete'] = 'tel-national';
814 - $data['class'] = 'cell large-7 medium-8';
815 - $data['value'] = $number;
816 - include acym_getPartial('fields', 'input');
817 -
818 - if ($displayOutside) {
819 - echo '</div>';
820 - }
821 - } elseif ($field->type === 'custom_text') {
822 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Admin-defined custom HTML content, intentionally rendered as-is.
823 - echo $field->option->custom_text;
824 - }
825 -
826 - if ($useLabel) {
827 - echo '</label>';
828 - }
829 - if ($useTitle) {
830 - echo '</div>';
831 - }
832 -
833 - echo '<div class="acym__field__error__block" data-acym-field-id="'.intval($field->id).'"></div>';
834 - if ($displayFront && $extraErrors && !acym_isAdmin()) {
835 - echo '<div class="acym__message__invalid__field acym__color__error" style="display: none;">';
836 - echo '<i class="acymicon-times-circle acym__cross__invalid acym__color__error"></i>'.esc_html(acym_translation('ACYM_THANKS_TO_FILL_IN_THIS_FIELD')).'</div>';
837 - }
838 - }
839 -
840 - /**
841 - * @param mixed $defaultValue
842 - *
843 - * @return mixed
844 - */
845 - private function prepareDefaultValue($defaultValue, string $fieldType, ?object $user)
846 - {
847 - if ($fieldType === 'language') {
848 - if (empty($defaultValue) && !empty($user->language)) {
849 - $defaultValue = $user->language;
850 - }
851 -
852 - return empty($defaultValue) ? acym_getLanguageTag() : $defaultValue;
853 - }
854 -
855 - if ($fieldType === 'phone') {
856 - return !empty($defaultValue) ? explode(',', $defaultValue) : '';
857 - }
858 -
859 - if ($fieldType === 'file') {
860 - return is_array($defaultValue) ? $defaultValue[0] : $defaultValue;
861 - }
862 -
863 - if (in_array($fieldType, ['single_dropdown', 'textarea'])) {
864 - return empty($defaultValue) ? '' : $defaultValue;
865 - }
866 -
867 - if ($fieldType === 'radio') {
868 - return strlen($defaultValue) === 0 ? null : $defaultValue;
869 - }
870 -
871 - if (in_array($fieldType, ['checkbox', 'multiple_dropdown'])) {
872 - if (empty($defaultValue)) {
873 - return [];
874 - }
875 -
876 - if (is_string($defaultValue)) {
877 - return explode(',', $defaultValue);
878 - }
879 -
880 - if (is_object($defaultValue)) {
881 - $defaultValues = [];
882 - foreach ($defaultValue as $oneKey => $oneValue) {
883 - if (!empty($oneValue)) {
884 - $defaultValues[] = $oneKey;
885 - }
886 - }
887 -
888 - return $defaultValues;
889 - }
890 -
891 - return is_array($defaultValue) ? $defaultValue : [];
892 - }
893 -
894 - return $defaultValue;
895 - }
896 -
897 - public function getFieldTypeById(int $id): string
898 - {
899 - return acym_loadResult('SELECT type FROM #__acym_field WHERE id = '.intval($id));
900 - }
901 -
902 - public function setInactive(array $elements): void
903 - {
904 - if (empty($elements)) {
905 - return;
906 - }
907 -
908 - acym_arrayToInteger($elements);
909 -
910 - // Core fields can't be disabled
911 - $excludedFields = acym_loadResultArray('SELECT `id` FROM #__acym_field WHERE `core` = 1');
912 - acym_arrayToInteger($excludedFields);
913 -
914 - $elements = array_diff($elements, $excludedFields);
915 -
916 - parent::setInactive($elements);
917 - }
918 -
919 - public function insertLanguageField(): void
920 - {
921 - if (!empty($this->getLanguageFieldId())) {
922 - return;
923 - }
924 -
925 - $field = new \stdClass();
926 - $field->name = 'ACYM_LANGUAGE';
927 - $field->type = 'language';
928 - $field->active = 1;
929 - $field->required = 1;
930 - $field->ordering = $this->getOrdering() + 1;
931 - $field->core = 1;
932 - $field->backend_edition = 1;
933 - $field->backend_listing = 0;
934 - $field->frontend_edition = 1;
935 - $field->frontend_listing = 0;
936 - $field->namekey = 'acym_language';
937 -
938 - $rowId = acym_insertObject('#__acym_field', $field);
939 -
940 - if (empty($rowId)) {
941 - return;
942 - }
943 -
944 - $this->config->saveConfig([self::LANGUAGE_FIELD_ID_KEY => $rowId]);
945 - }
946 -
947 - public function getLanguageFieldId(): int
948 - {
949 - $languageFieldId = acym_loadResult('SELECT `id` FROM `#__acym_field` WHERE `namekey` = "acym_language"');
950 -
951 - return empty($languageFieldId) ? 0 : $languageFieldId;
952 - }
953 -
954 - public function getLanguagesForDropdown(): array
955 - {
956 - $languages = acym_getLanguages(false, true);
957 - $dataLanguages = [];
958 -
959 - foreach ($languages as $langCode => $language) {
960 - if ($langCode == "xx-XX") continue;
961 -
962 - $oneLanguage = new \stdClass();
963 - $oneLanguage->value = $langCode;
964 - $oneLanguage->text = $language->name;
965 -
966 - $dataLanguages[] = $oneLanguage;
967 - }
968 -
969 - usort($dataLanguages, function ($a, $b) {
970 - return strtolower($a->text) > strtolower($b->text) ? 1 : -1;
971 - });
972 -
973 - return $dataLanguages;
974 - }
975 -
976 - public function setEmailConfirmationField(bool $displayOutside, object $field, string $container = 'div', bool $displayInline = false): void
977 - {
978 - $uniqueId = 'email_confirmation_field_'.acym_rand(100, 900);
979 -
980 - echo '<'.esc_attr($container).' class="onefield acym_email_confirmation_field acyfield_text">';
981 - if ($displayOutside) {
982 - echo '<label class="cell margin-top-1">';
983 - echo '<span class="acym__users__creation__fields__title">'.esc_html(acym_translation('ACYM_EMAIL_CONFIRMATION')).'</span>';
984 - }
985 -
986 - $placeholder = !$displayOutside ? acym_translation('ACYM_EMAIL_CONFIRMATION') : '';
987 - echo '<input id="'.esc_attr($uniqueId).'"
988 - '.(empty($field->option->size) ? '' : ' style="width:'.intval($field->option->size).'px"').'
989 - required
990 - type="email"
991 - class="cell acym__user__edit__email"
992 - name="user[email_confirmation]"
993 - placeholder="'.esc_attr($placeholder).'" />';
994 - echo '<span class="acym__field__error__block"></span>';
995 -
996 - $extraErrors = $this->config->get('extra_errors', '0');
997 - if ($extraErrors && !acym_isAdmin()) {
998 - echo '<span class="acym__message__invalid__field acym__color__error" style="display: none;">';
999 - echo '<i class="acymicon-times-circle acym__cross__invalid acym__color__error"></i>';
1000 - echo esc_html(acym_translation('ACYM_THANKS_TO_FILL_IN_THIS_FIELD'));
1001 - echo '</span>';
1002 - }
1003 -
1004 - if ($displayOutside) {
1005 - echo '</label>';
1006 - }
1007 - echo '</'.esc_attr($container).'>';
1008 -
1009 - if ($container === 'td' && !$displayInline) {
1010 - //TODO either open tr here, or close it where setEmailConfirmationField is called
1011 - echo '</tr>';
1012 - }
1013 - }
1014 -}