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 -1023 11.0.4 → 11.1.1 View file →
@@ -1,1023 +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">'.wp_kses(
573 - $field->name,
574 - SecurityHelper::ALLOWED_HTML_FIELD_NAME
575 - ).'</span>';
576 - }
577 - if ($useTitle) {
578 - echo '<div class="cell margin-top-1"><div class="acym__users__creation__fields__title">'.wp_kses(
579 - $field->name,
580 - SecurityHelper::ALLOWED_HTML_FIELD_NAME
581 - ).'</div>';
582 - }
583 -
584 - $messageRequired = empty($field->option->error_message) ? '' : acym_translation($field->option->error_message);
585 - $requiredJson = json_encode(['type' => $field->type, 'message' => $messageRequired]);
586 - $required = '';
587 - if ($field->required) {
588 - $data['data-required'] = $requiredJson;
589 - $required = ' data-required="'.esc_attr($requiredJson).'"';
590 - $attributesSelectField['data-required'] = $requiredJson;
591 - }
592 -
593 - $readonly = '';
594 - if (!$showField && acym_isAdmin() && acym_level(ACYM_ENTERPRISE) && $isCoreField) {
595 - $attributesSelectField['disabled'] = true;
596 - unset($attributesSelectField['data-required']);
597 - $readonly = ' disabled ';
598 - $required = '';
599 - $data['disabled'] = true;
600 - unset($data['data-required']);
601 - }
602 -
603 - $defaultValue = $this->prepareDefaultValue($defaultValue, $field->type, $user);
604 -
605 - if ($field->id == 1) {
606 - $data['type'] = 'text';
607 - $data['name'] = 'user[name]';
608 - $data['autocomplete'] = 'name';
609 - $data['class'] = 'cell';
610 -
611 - if (empty($readonly)) {
612 - include acym_getPartial('fields', 'input');
613 - } else {
614 - ob_start();
615 - include acym_getPartial('fields', 'input');
616 - $input = ob_get_clean();
617 -
618 - acym_tooltip(
619 - [
620 - 'hoveredText' => $input,
621 - 'textShownInTooltip' => acym_translation('ACYM_CF_EDITION_BLOCKED'),
622 - ]
623 - );
624 - }
625 - } elseif ($field->id == 2) {
626 - $uniqueId = 'email_field_'.acym_rand(100, 900);
627 -
628 - unset($data['data-required']);
629 - $data['type'] = 'email';
630 - $data['name'] = 'user[email]';
631 - $data['autocomplete'] = 'email';
632 - $data['id'] = $uniqueId;
633 - $data['class'] = 'cell acym__user__edit__email';
634 - $data['required'] = true;
635 - $data['readonly'] = $cmsUser;
636 -
637 - if (empty($readonly)) {
638 - include acym_getPartial('fields', 'input');
639 - } else {
640 - ob_start();
641 - include acym_getPartial('fields', 'input');
642 - $input = ob_get_clean();
643 -
644 - acym_tooltip(
645 - [
646 - 'hoveredText' => $input,
647 - 'textShownInTooltip' => acym_translation('ACYM_CF_EDITION_BLOCKED'),
648 - ]
649 - );
650 - }
651 -
652 - if ($displayFront && !$cmsUser && !empty($this->config->get('email_spellcheck'))) {
653 - echo '<ul acym-data-field="'.esc_attr($uniqueId).'" class="acym_email_suggestions" style="display: none;"></ul>';
654 - }
655 - } elseif ($field->type === 'language') {
656 - $attributesSelectField['class'] = 'acym__select';
657 - if (empty($readonly)) {
658 - acym_select(
659 - $this->getLanguagesForDropdown(),
660 - 'user[language]',
661 - $defaultValue,
662 - $attributesSelectField,
663 - 'value',
664 - 'text',
665 - null,
666 - false,
667 - true
668 - );
669 - } else {
670 - acym_tooltip(
671 - [
672 - 'hoveredText' => acym_select(
673 - $this->getLanguagesForDropdown(),
674 - 'user[language]',
675 - $defaultValue,
676 - $attributesSelectField
677 - ),
678 - 'textShownInTooltip' => acym_translation('ACYM_CF_EDITION_BLOCKED'),
679 - ]
680 - );
681 - }
682 - } elseif ($field->type === 'text') {
683 - $data['type'] = 'text';
684 - $data['name'] = $name;
685 - include acym_getPartial('fields', 'input');
686 - } elseif ($field->type === 'textarea') {
687 - echo '<textarea name="'.esc_attr($name).'"';
688 - if (!empty($data['data-required'])) {
689 - echo ' data-required="'.esc_attr($data['data-required']).'"';
690 - }
691 - if (isset($data['maxCharacters'])) {
692 - echo ' maxlength="'.esc_attr($data['maxCharacters']).'"';
693 - }
694 - echo ' rows="'.intval($field->option->rows).'" cols="'.intval($field->option->columns).'">';
695 - echo esc_html(is_scalar($defaultValue) ? $defaultValue : '');
696 - echo '</textarea>';
697 - } elseif ($field->type === 'radio') {
698 - if ($displayFront) {
699 - $data['name'] = $name;
700 - $data['values'] = $valuesArray;
701 - $data['value'] = $defaultValue;
702 - include acym_getPartial('fields', 'radio');
703 - } else {
704 - acym_radio(
705 - $valuesArray,
706 - $name.'[]',
707 - $defaultValue,
708 - $field->required ? ['data-required' => $requiredJson] : []
709 - );
710 - }
711 - } elseif ($field->type === 'checkbox') {
712 - $data['name'] = $name;
713 - $data['values'] = $valuesArray;
714 - $data['value'] = $defaultValue;
715 - $data['displayFront'] = $displayFront;
716 - include acym_getPartial('fields', 'checkbox');
717 - } elseif ($field->type === 'single_dropdown') {
718 - $attributesSelectField['class'] = 'acym__custom__fields__select__form acym__select';
719 - acym_select(
720 - $valuesArray,
721 - $name,
722 - $defaultValue,
723 - $attributesSelectField,
724 - 'value',
725 - 'text',
726 - null,
727 - false,
728 - true
729 - );
730 - } elseif ($field->type === 'multiple_dropdown') {
731 - $attributes = [
732 - 'class' => 'acym__custom__fields__select__multiple__form acym__select',
733 - 'style' => empty($field->option->size) ? '' : 'width:'.$field->option->size.'px',
734 - ];
735 - if ($field->required) {
736 - $attributes['data-required'] = $displayFront ? esc_attr($requiredJson) : $requiredJson;
737 - }
738 -
739 - acym_selectMultiple(
740 - $valuesArray,
741 - $name,
742 - $defaultValue,
743 - $attributes,
744 - 'value',
745 - 'text',
746 - true
747 - );
748 - } elseif ($field->type === 'date') {
749 - $attributes = [
750 - 'class' => 'acym__custom__fields__select__form acym__select',
751 - 'acym-field-type' => 'date',
752 - ];
753 - if (!empty($required)) {
754 - $attributes['data-required'] = $requiredJson;
755 - }
756 -
757 - echo wp_kses(
758 - acym_displayDateFormat(
759 - $field->option->format,
760 - $name.'[]',
761 - $defaultValue,
762 - $attributes
763 - ),
764 - array_merge_recursive(
765 - SecurityHelper::ALLOWED_HTML_SELECT,
766 - [
767 - 'select' => [
768 - 'data-required' => true,
769 - 'acym-field-type' => true,
770 - ],
771 - 'div' => [
772 - 'class' => true,
773 - ],
774 - ]
775 - )
776 - );
777 - } elseif ($field->type === 'file') {
778 - if ($displayFront) {
779 - unset($data['placeholder'], $data['value'], $data['authorizedContent'], $data['style'], $data['maxCharacters']);
780 - $data['type'] = 'file';
781 - $data['name'] = $name;
782 - include acym_getPartial('fields', 'input');
783 - } else {
784 - $downloadUrl = '';
785 - if (!empty($defaultValue) && !empty($user->id)) {
786 - $fileName = is_array($defaultValue) ? $defaultValue[0] : $defaultValue;
787 - if (!empty($fileName)) {
788 - $uploadFolder = trim(acym_cleanPath(html_entity_decode(acym_getFilesFolder(true))), DS.' ').DS;
789 - $userFilePath = $uploadFolder.'userfiles'.DS.$user->id.DS.$fileName;
790 - $legacyFilePath = $uploadFolder.'userfiles'.DS.$fileName;
791 -
792 - if (file_exists(acym_cleanPath(ACYM_ROOT.$userFilePath))) {
793 - $downloadUrl = ACYM_LIVE.str_replace(DS, '/', $userFilePath);
794 - } elseif (file_exists(acym_cleanPath(ACYM_ROOT.$legacyFilePath))) {
795 - $downloadUrl = ACYM_LIVE.str_replace(DS, '/', $legacyFilePath);
796 - }
797 - }
798 - }
799 - $attributes = [];
800 - if (!empty($required)) {
801 - $attributes['data-required'] = $requiredJson;
802 - }
803 - acym_inputFile($name.'[]', $defaultValue, '', $attributes, $downloadUrl);
804 - }
805 - } elseif ($field->type === 'phone') {
806 - $indicator = !empty($defaultValue[0]) ? $defaultValue[0] : '';
807 - $number = !empty($defaultValue[1]) ? $defaultValue[1] : '';
808 -
809 - if ($displayOutside) {
810 - echo '<div class="cell margin-top-1 grid-x"><div class="acym__users__creation__fields__title cell">'.wp_kses(
811 - $field->name,
812 - SecurityHelper::ALLOWED_HTML_FIELD_NAME
813 - ).'</div>';
814 - }
815 - echo '<div class="cell large-5 medium-4 padding-next-1">';
816 - acym_generateCountryNumber($name.'[code]', $indicator);
817 - echo '</div>';
818 -
819 - unset($data['authorizedContent']);
820 - $data['type'] = 'tel';
821 - $data['name'] = $name.'[phone]';
822 - $data['autocomplete'] = 'tel-national';
823 - $data['class'] = 'cell large-7 medium-8';
824 - $data['value'] = $number;
825 - include acym_getPartial('fields', 'input');
826 -
827 - if ($displayOutside) {
828 - echo '</div>';
829 - }
830 - } elseif ($field->type === 'custom_text') {
831 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Admin-defined custom HTML content, intentionally rendered as-is.
832 - echo $field->option->custom_text;
833 - }
834 -
835 - if ($useLabel) {
836 - echo '</label>';
837 - }
838 - if ($useTitle) {
839 - echo '</div>';
840 - }
841 -
842 - echo '<div class="acym__field__error__block" data-acym-field-id="'.intval($field->id).'"></div>';
843 - if ($displayFront && $extraErrors && !acym_isAdmin()) {
844 - echo '<div class="acym__message__invalid__field acym__color__error" style="display: none;">';
845 - 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>';
846 - }
847 - }
848 -
849 - /**
850 - * @param mixed $defaultValue
851 - *
852 - * @return mixed
853 - */
854 - private function prepareDefaultValue($defaultValue, string $fieldType, ?object $user)
855 - {
856 - if ($fieldType === 'language') {
857 - if (empty($defaultValue) && !empty($user->language)) {
858 - $defaultValue = $user->language;
859 - }
860 -
861 - return empty($defaultValue) ? acym_getLanguageTag() : $defaultValue;
862 - }
863 -
864 - if ($fieldType === 'phone') {
865 - return !empty($defaultValue) ? explode(',', $defaultValue) : '';
866 - }
867 -
868 - if ($fieldType === 'file') {
869 - return is_array($defaultValue) ? $defaultValue[0] : $defaultValue;
870 - }
871 -
872 - if (in_array($fieldType, ['single_dropdown', 'textarea'])) {
873 - return empty($defaultValue) ? '' : $defaultValue;
874 - }
875 -
876 - if ($fieldType === 'radio') {
877 - return strlen($defaultValue) === 0 ? null : $defaultValue;
878 - }
879 -
880 - if (in_array($fieldType, ['checkbox', 'multiple_dropdown'])) {
881 - if (empty($defaultValue)) {
882 - return [];
883 - }
884 -
885 - if (is_string($defaultValue)) {
886 - return explode(',', $defaultValue);
887 - }
888 -
889 - if (is_object($defaultValue)) {
890 - $defaultValues = [];
891 - foreach ($defaultValue as $oneKey => $oneValue) {
892 - if (!empty($oneValue)) {
893 - $defaultValues[] = $oneKey;
894 - }
895 - }
896 -
897 - return $defaultValues;
898 - }
899 -
900 - return is_array($defaultValue) ? $defaultValue : [];
901 - }
902 -
903 - return $defaultValue;
904 - }
905 -
906 - public function getFieldTypeById(int $id): string
907 - {
908 - return acym_loadResult('SELECT type FROM #__acym_field WHERE id = '.intval($id));
909 - }
910 -
911 - public function setInactive(array $elements): void
912 - {
913 - if (empty($elements)) {
914 - return;
915 - }
916 -
917 - acym_arrayToInteger($elements);
918 -
919 - // Core fields can't be disabled
920 - $excludedFields = acym_loadResultArray('SELECT `id` FROM #__acym_field WHERE `core` = 1');
921 - acym_arrayToInteger($excludedFields);
922 -
923 - $elements = array_diff($elements, $excludedFields);
924 -
925 - parent::setInactive($elements);
926 - }
927 -
928 - public function insertLanguageField(): void
929 - {
930 - if (!empty($this->getLanguageFieldId())) {
931 - return;
932 - }
933 -
934 - $field = new \stdClass();
935 - $field->name = 'ACYM_LANGUAGE';
936 - $field->type = 'language';
937 - $field->active = 1;
938 - $field->required = 1;
939 - $field->ordering = $this->getOrdering() + 1;
940 - $field->core = 1;
941 - $field->backend_edition = 1;
942 - $field->backend_listing = 0;
943 - $field->frontend_edition = 1;
944 - $field->frontend_listing = 0;
945 - $field->namekey = 'acym_language';
946 -
947 - $rowId = acym_insertObject('#__acym_field', $field);
948 -
949 - if (empty($rowId)) {
950 - return;
951 - }
952 -
953 - $this->config->saveConfig([self::LANGUAGE_FIELD_ID_KEY => $rowId]);
954 - }
955 -
956 - public function getLanguageFieldId(): int
957 - {
958 - $languageFieldId = acym_loadResult('SELECT `id` FROM `#__acym_field` WHERE `namekey` = "acym_language"');
959 -
960 - return empty($languageFieldId) ? 0 : $languageFieldId;
961 - }
962 -
963 - public function getLanguagesForDropdown(): array
964 - {
965 - $languages = acym_getLanguages(false, true);
966 - $dataLanguages = [];
967 -
968 - foreach ($languages as $langCode => $language) {
969 - if ($langCode == "xx-XX") continue;
970 -
971 - $oneLanguage = new \stdClass();
972 - $oneLanguage->value = $langCode;
973 - $oneLanguage->text = $language->name;
974 -
975 - $dataLanguages[] = $oneLanguage;
976 - }
977 -
978 - usort($dataLanguages, function ($a, $b) {
979 - return strtolower($a->text) > strtolower($b->text) ? 1 : -1;
980 - });
981 -
982 - return $dataLanguages;
983 - }
984 -
985 - public function setEmailConfirmationField(bool $displayOutside, object $field, string $container = 'div', bool $displayInline = false): void
986 - {
987 - $uniqueId = 'email_confirmation_field_'.acym_rand(100, 900);
988 -
989 - echo '<'.esc_attr($container).' class="onefield acym_email_confirmation_field acyfield_text">';
990 - if ($displayOutside) {
991 - echo '<label class="cell margin-top-1">';
992 - echo '<span class="acym__users__creation__fields__title">'.esc_html(acym_translation('ACYM_EMAIL_CONFIRMATION')).'</span>';
993 - }
994 -
995 - $placeholder = !$displayOutside ? acym_translation('ACYM_EMAIL_CONFIRMATION') : '';
996 - echo '<input id="'.esc_attr($uniqueId).'"
997 - '.(empty($field->option->size) ? '' : ' style="width:'.intval($field->option->size).'px"').'
998 - required
999 - type="email"
1000 - class="cell acym__user__edit__email"
1001 - name="user[email_confirmation]"
1002 - placeholder="'.esc_attr($placeholder).'" />';
1003 - echo '<span class="acym__field__error__block"></span>';
1004 -
1005 - $extraErrors = $this->config->get('extra_errors', '0');
1006 - if ($extraErrors && !acym_isAdmin()) {
1007 - echo '<span class="acym__message__invalid__field acym__color__error" style="display: none;">';
1008 - echo '<i class="acymicon-times-circle acym__cross__invalid acym__color__error"></i>';
1009 - echo esc_html(acym_translation('ACYM_THANKS_TO_FILL_IN_THIS_FIELD'));
1010 - echo '</span>';
1011 - }
1012 -
1013 - if ($displayOutside) {
1014 - echo '</label>';
1015 - }
1016 - echo '</'.esc_attr($container).'>';
1017 -
1018 - if ($container === 'td' && !$displayInline) {
1019 - //TODO either open tr here, or close it where setEmailConfirmationField is called
1020 - echo '</tr>';
1021 - }
1022 - }
1023 -}