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

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