PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.11.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.11.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
acymailing / back / Classes / FieldClass.php

FieldClass.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.11.1, at back/Classes/FieldClass.php

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