diff --git a/README.md b/README.md index ae6cb93..8c1da00 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ### forms -## Модуль Формы v2.1.0 +## Модуль Формы v1.26.0 -### адаптирован для AVE.CMS AVE.CMS v3.28 и AVE.CMS v3.29 ALT +### адаптирован для AVE.CMS v3.28 ### Модуль предназначен для создания веб-форм (например, обратной связи или простейшего оформления заказа), которые могут состоять из любого набора полей. @@ -12,11 +12,6 @@ ### Changelog: -08.11.2025 - Версия v2.1.0 - модуль обновлен для работы с шаблонизатором Smarty 5 - -25.09.2025 - Версия v2.0.0 - модуль обновлен для работы в среде PHP-8.4.x и MySQL-8.4.x -Добавлен функционал массовых действий с историей: удаление, изменение статусов - 01.09.2019 - Версия v1.26.0 - Модуль переименован в модуль Формы. Адаптация для версии ave-cms версии 3.25 и выше, удалено лишнее. 27.04.2017 - Версия 1.2.4 - добавлена возможность в поле "Атрибуты тега поля" работать атрибутом value, в … diff --git a/forms/class/forms.php b/forms/class/forms.php index 5c2aaf5..5cc0e5e 100644 --- a/forms/class/forms.php +++ b/forms/class/forms.php @@ -13,7 +13,7 @@ * * @package AVE.cms * @subpackage module: forms - * @since 2.1.0 + * @since 1.4 * @author * @filesource */ @@ -117,7 +117,7 @@ /** * Метод забирает форму из бд по алиасу/id * - * @param $alias_id + * @param $alias_id * @param bool $_fields * * @return array @@ -143,8 +143,7 @@ $form['alias_id'] = $alias_id; // получатели - // ИСПРАВЛЕНИЕ: Добавляем @ для подавления Warning при десериализации, т.к. пользователь сообщил о проблеме - $form['mail_set'] = @unserialize($form['mail_set']); + $form['mail_set'] = unserialize($form['mail_set']); if ($_fields === true) { @@ -166,22 +165,18 @@ if (in_array($field['type'],array('doc','multidoc')) && !empty($field['setting']) && is_numeric($field['setting'])) $field['setting'] = array(0 => $field['setting']); else - // ИСПРАВЛЕНИЕ: Добавляем @ для подавления Warning при десериализации - $field['setting'] = @unserialize($field['setting']) !== false ? @unserialize($field['setting']) : array(); + $field['setting'] = unserialize($field['setting']) !== false ? unserialize($field['setting']) : array(); } // если тип поля поменялся, ставим пустую строку - // ИСПРАВЛЕНИЕ: Добавляем дополнительную проверку на то, что строка может быть сериализована (начинается с 'a', 'O', 's', 'i', 'd', 'b') - elseif (is_string($field['setting']) && strlen($field['setting']) > 2 && in_array($field['setting'][0], ['a', 'O', 's', 'i', 'd', 'b']) && @unserialize($field['setting']) !== false) $field['setting'] = ''; + elseif (unserialize($field['setting']) !== false) $field['setting'] = ''; // раскрываем массив опций по умолчанию для мультиселекта if ($field['type'] == 'multiselect') { - // ИСПРАВЛЕНИЕ: Добавляем @ для подавления Warning при десериализации - $field['defaultval'] = @unserialize($field['defaultval']) !== false ? @unserialize($field['defaultval']) : array(); + $field['defaultval'] = unserialize($field['defaultval']) !== false ? unserialize($field['defaultval']) : array(); } // если тип поля поменялся, ставим пустую строку - // ИСПРАВЛЕНИЕ: Добавляем дополнительную проверку на то, что строка может быть сериализована - elseif (is_string($field['defaultval']) && strlen($field['defaultval']) > 2 && in_array($field['defaultval'][0], ['a', 'O', 's', 'i', 'd', 'b']) && @unserialize($field['defaultval']) !== false) $field['defaultval'] = ''; + elseif (unserialize($field['defaultval']) !== false) $field['defaultval'] = ''; // главные поля if (in_array($field['title'],$this->fields_main) && $field['main']) @@ -204,20 +199,19 @@ } -/** + /** * Метод убирает слэши во всей переменной * - * @param mixed $var + * @param $var * * @return array|string */ function _stripslashes($var) { - if (is_array($var)) - return array_map(array($this, '_stripslashes'), $var); + if (! is_array($var)) + return stripslashes($var); else - // ИСПРАВЛЕНИЕ: Гарантируем, что $var является строкой, используя ?? '' - return stripslashes($var ?? ''); + return array_map(array($this, '_stripslashes'), $var); } @@ -237,41 +231,43 @@ } -/** - * Метод чистит переменную от пустых значений и массивов - * - * @param $var - * - * @return array|null|string - */ -function _cleanvar($var) -{ - if (!is_array($var)) { - return trim($var) > '' - ? trim($var) - : null; - } + /** + * Метод чистит переменную от пустых значений и массивов + * + * @param $var + * + * @return array|null|string + */ + function _cleanvar($var) + { + if (! is_array($var)) + return trim($var) > '' + ? trim($var) + : null; - $narr = array(); + $narr = array(); - // Заменяем while (list($key, $val) = each($var)) на foreach - foreach ($var as $key => $val) { - if (is_array($val)) { - $val = $this->_cleanvar($val); - if (count($val) > 0) { - $narr[$key] = $val; - } - } else { - if (trim($val) > '') { - $narr[$key] = $val; - } - } - } + while (list($key, $val) = each($var)) + { + if (is_array($val)) + { + $val = $this->_cleanvar($val); - unset($var); + if (count($val) > 0) + $narr[$key] = $val; + } + else + { + if (trim($val) > '') + $narr[$key] = $val; + } + } + + unset ($var); + + return $narr; + } - return $narr; -} /** * Валидация Email-а @@ -367,7 +363,7 @@ function _cleanvar($var) } -/** + /** * Парсинг главных тегов */ function _parse_tags ($str) @@ -383,9 +379,6 @@ function _cleanvar($var) $str = parse_hide($str); - // Получаем запись пользователя ОДИН раз - // Если get_user_rec_by_id(UID) вернет null, мы можем безопасно использовать ее дальше. - $user_rec = get_user_rec_by_id(UID); return str_replace(array( '[tag:docid]', '[tag:formtitle]', @@ -403,7 +396,6 @@ function _cleanvar($var) '[tag:uemail]', '[tag:sitename]', '[tag:sitehost]', - '[tag:submitted_page]', ),array( $AVE_Core->curentdoc->Id, $this->form['title'], @@ -411,19 +403,15 @@ function _cleanvar($var) $_SERVER['REQUEST_URI'], $this->form['alias'] ? $this->form['alias'] : $this->form['id'], ABS_PATH, - ABS_PATH . 'templates/' . ((defined('THEME_FOLDER') === false) ? DEFAULT_THEME_FOLDER : THEME_FOLDER) . '/', + ABS_PATH . 'templates/' . THEME_FOLDER . '/', 'inc/captcha.php', $_SESSION['user_name'], - - // ИСПРАВЛЕНИЕ: Безопасное получение firstname и lastname - $user_rec->firstname ?? '', - $user_rec->lastname ?? '', - - $_SESSION['user_login'] ?? '', - $_SESSION['user_email'] ?? '', + get_user_rec_by_id(UID)->firstname, + get_user_rec_by_id(UID)->lastname, + $_SESSION['user_login'], + $_SESSION['user_email'], htmlspecialchars(get_settings('site_name'), ENT_QUOTES), $_SERVER['HTTP_HOST'], - getSiteUrl() . $_SERVER['REQUEST_URI'], ), $str); } @@ -495,7 +483,7 @@ function _cleanvar($var) */ function _parse_tag_fld_post ($matches) { - return $_POST['form-' . $this->form['alias_id']][$matches[1]] ?? ''; + return $_POST['form-' . $this->form['alias_id']][$matches[1]]; } /** @@ -505,10 +493,6 @@ function _cleanvar($var) { $field_id = (int)$matches[1]; - if (!isset($this->form['fields'][$field_id])) { - return $matches[0]; - } - // забираем массив поля $field = $this->form['fields'][$field_id]; @@ -523,16 +507,11 @@ function _cleanvar($var) $alias_id = $this->form['alias_id']; $fld_val = $this->form['is_submited'] - ? $this->_stripslashes($_POST['form-' . $alias_id][$field_id] ?? null) + ? $this->_stripslashes($_POST['form-' . $alias_id][$field_id]) : (in_array($field['type'],array('input','textarea')) ? $this->_eval2var('?>' . $field['defaultval'] . 'form['fields'][$field_id]['is_used'] = true; @@ -542,78 +521,78 @@ function _cleanvar($var) switch ($field['type']) { - case 'input': - $input = ''; - break; + case 'input': + $input = ''; + break; - case 'textarea': - $input = ''; - break; + case 'textarea': + $input = ''; + break; - case 'select': - $input = ''; - break; + case 'select': + $input = ''; + break; - case 'multiselect': - $input = ''; - break; + case 'multiselect': + $input = ''; + break; - case 'checkbox': - $input = ' - - '; - break; + case 'checkbox': + $input = ' + + '; + break; - case 'file': - $input = ''; - break; + case 'file': + $input = ''; + break; - case 'doc': - $input = ''; - break; + case 'doc': + $input = ''; + break; - case 'multidoc': - $input = ''; - break; + case 'multidoc': + $input = ''; + break; } - // Вставляем поле в шаблон поля - $return = trim($field['tpl']) > '' - ? str_replace('[tag:fld]', $input, $field['tpl']) - : $input; + // вставляем поле в шаблон поля + $return = trim($field['tpl']) > '' + ? str_replace('[tag:fld]',$input,$field['tpl']) + : $input; - // Парсим теги названия и id - $return = str_replace(array( - '[tag:id]', - '[tag:title]', - ), array( - $field['id'], - '[tag:title:' . $field_id . ']', - ), $return); + // парсим теги названия и id + $return = str_replace(array( + '[tag:id]', + '[tag:title]', + ), array( + $field['id'], + '[tag:title:' . $field_id . ']', + ), $return); // если попытка отправить форму, обрабатываем валидацию и пустоту if ($this->form['is_submited']) @@ -626,39 +605,13 @@ function _cleanvar($var) { $valid = false; // если капча - if ($field['title'] == 'captcha') $valid = (empty($_SESSION['captcha_keystring']) || empty($fld_val[0]) || $_SESSION['captcha_keystring'] != $fld_val[0]) ? false : true; - - // если файл - elseif ($field['type'] == 'file') { - $file_size = (isset($_FILES['form-' . $alias_id]['size'][$field_id])) ? $_FILES['form-' . $alias_id]['size'][$field_id] : 0; - $valid = ($file_size / 1024 / 1024) <= $field['setting']; - } - - // Если передали регулярку - elseif (isset($field['setting'][0]) && $field['setting'][0] == '/') { - $valid = false; // Изначально считаем, что валидности нет - - // Если $fld_val - массив, проверяем каждое значение - if (is_array($fld_val)) { - foreach ($fld_val as $value) { - if (preg_match($field['setting'], $value) === 1) { - $valid = true; // Если хотя бы одно значение валидно - break; // Выходим из цикла - } - } - } else { - // Если это одно значение, просто проверяем его - $valid = preg_match($field['setting'],$fld_val) === 1 ? true : false; - } - } + if ($field['title'] == 'captcha') $valid = (empty($_SESSION['captcha_keystring']) || empty($fld_val) || $_SESSION['captcha_keystring'] != $fld_val) ? false : true; + // если файл + elseif ($field['type'] == 'file') $valid = ($_FILES['form-' . $alias_id]['size'][$field_id] / 1024 / 1024) <= $field['setting']; + // если передали регулярку + elseif ($field['setting']{0} == '/') $valid = preg_match($field['setting'],$fld_val) === 1 ? true : false; // если константу - elseif (isset($field['setting']) && is_string($field['setting']) && defined($field['setting'])) - { - if (is_array($fld_val) && isset($fld_val[0])) { - $fld_val = $fld_val[0]; // Берем первое значение из массива - } - $valid = filter_var($fld_val, constant($field['setting'])) !== false ? true : false; - } + elseif (defined($field['setting'])) $valid = filter_var($fld_val,constant($field['setting'])) !== false ? true : false; // иначе, ничего не делаем else return 'Неверные параметры валидации!'; // парсим теги валидности @@ -683,13 +636,11 @@ function _cleanvar($var) // пустота (для любых обязательных полей) if (! empty($field['required']) && $field['required']) { - if ($field['type'] == 'file') { - // Безопасный доступ к $_FILES - $is_uploaded = isset($_FILES['form-' . $alias_id]['tmp_name'][$field_id]) && !empty($_FILES['form-' . $alias_id]['tmp_name'][$field_id]); - $has_error = isset($_FILES['form-' . $alias_id]['error'][$field_id]) && !empty($_FILES['form-' . $alias_id]['error'][$field_id]); - - $empty = (!$is_uploaded || $has_error); - } + if ($field['type'] == 'file') + $empty = ( + empty($_FILES['form-' . $alias_id]['tmp_name'][$field_id]) || + !empty($_FILES['form-' . $alias_id]['error'][$field_id]) + ); else { $clean_fld_val = $this->_cleanvar($fld_val); @@ -738,8 +689,7 @@ function _cleanvar($var) if ($field['is_used'] !== true || empty($field['active'])) return ''; // иначе, продолжаем $alias_id = $this->form['alias_id']; - // Если ключ $field_id отсутствует в $_POST, берем пустую строку. - $val = $_POST['form-' . $alias_id][$field_id] ?? ''; + $val = $_POST['form-' . $alias_id][$field_id]; $newval = ''; $tag_mail_empty = ($this->form['mail_set']['format'] === 'text' ? '<' : '<') . $AVE_Template->get_config_vars('tag_mail_empty') . ($this->form['mail_set']['format'] === 'text' ? '>' : '>'); @@ -773,14 +723,8 @@ function _cleanvar($var) } break; - case 'file': - // 1. Безопасно получаем массив имен файлов, используя оператор объединения с null (??). - // Если $_FILES['form-bag-report'] отсутствует или не содержит ['name'], - // $file_names будет пустым массивом []. - $file_names = $_FILES['form-' . $alias_id]['name'] ?? []; - - // 2. implode() теперь безопасно работает с $file_names (массив или []). - $newval = implode(', ', $file_names); + case 'file': + $newval = implode(', ',$_FILES['form-' . $alias_id]['name']); break; default: @@ -849,16 +793,12 @@ function _cleanvar($var) // для правильного вывода селектов if (empty($form['mail_set']['receivers'])) $form['mail_set']['receivers'] = array(0 => array()); - - // Добавляем проверку, чтобы избежать ошибки - if (is_array($form['fields'])) + foreach ($form['fields'] as &$field) { - foreach ($form['fields'] as &$field) + if (($field['type'] == 'select' || $field['type'] == 'multiselect') && empty($field['setting'])) { - if (($field['type'] == 'select' || $field['type'] == 'multiselect') && empty($field['setting'])) - { - $field['setting'] = array(array()); - } + $field['setting'] = array(0 => ''); + $field['setting_empty'] = true; } } } @@ -875,7 +815,7 @@ function _cleanvar($var) $assign['rubrics'] = $this->_rubrics(); // назначаем массив CodeMirror - $assign['codemirror_data'] = array( + $assign['codemirror'] = array( 'rubheader' => 200, 'from_name' => 60, 'from_email' => 60, @@ -919,22 +859,13 @@ function _cleanvar($var) return $AVE_Template->fetch($this->tpl_dir . 'form_fields.tpl'); } - /** + /** * Сохранение формы */ function form_save ($fid) { global $AVE_DB; - // 🛑 ИСПРАВЛЕНИЕ PHP 8.4: Инициализация mail_set и receivers, если они отсутствуют в $_REQUEST - if (!isset($_REQUEST['mail_set']) || !is_array($_REQUEST['mail_set'])) { - $_REQUEST['mail_set'] = array(); - } - if (!isset($_REQUEST['mail_set']['receivers']) || !is_array($_REQUEST['mail_set']['receivers'])) { - $_REQUEST['mail_set']['receivers'] = array(); - } - // ---------------------------------------------------------------------------------- - // проверяем Email-ы получателей $receivers = array(); foreach ($_REQUEST['mail_set']['receivers'] as $receiver) @@ -942,13 +873,9 @@ function _cleanvar($var) if ($this->_email_validate($receiver['email'])) $receivers[] = $receiver; } $_REQUEST['mail_set']['receivers'] = $receivers; - // параметры отправителя - // 🛑 ИСПРАВЛЕНИЕ PHP 8.4: Использование оператора ?? '' для from_email - if (! trim($_REQUEST['mail_set']['from_email'] ?? '') > '') $_REQUEST['mail_set']['from_email'] = get_settings('mail_from'); - - // 🛑 ИСПРАВЛЕНИЕ PHP 8.4: Использование оператора ?? '' для from_name - if (! trim($_REQUEST['mail_set']['from_name'] ?? '') > '') $_REQUEST['mail_set']['from_name'] = get_settings('mail_from_name'); + if (! trim($_REQUEST['mail_set']['from_email']) > '') $_REQUEST['mail_set']['from_email'] = get_settings('mail_from'); + if (! trim($_REQUEST['mail_set']['from_name']) > '') $_REQUEST['mail_set']['from_name'] = get_settings('mail_from_name'); if ($fid) { @@ -966,7 +893,7 @@ function _cleanvar($var) code_onsubmit = '" . addslashes($_REQUEST['code_onsubmit']) . "', code_onvalidate = '" . addslashes($_REQUEST['code_onvalidate']) . "', code_onsend = '" . addslashes($_REQUEST['code_onsend']) . "', - code_beforesend = '" . addslashes(isset($_REQUEST['code_beforesend']) ? $_REQUEST['code_beforesend'] : '') . "' + code_beforesend = '" . addslashes($_REQUEST['code_beforesend']) . "' WHERE id = '" . $fid . "' "); @@ -992,13 +919,6 @@ function _cleanvar($var) mail_set = '" . addslashes(serialize($mail_set)) . "' "); $fid = (int)$AVE_DB->InsertId(); - -/* // 🛑 ИСПРАВЛЕНИЕ AJAX: Явный вывод ID для редиректа JS (fid=NaN) - if (isset($_REQUEST['ajax']) && empty($_REQUEST['demo'])) { - echo $fid; - return; // Прекращаем выполнение, чтобы не выводить лишние данные полей - }*/ - $_REQUEST['fields'] = $this->fields_main_data; // прописываем алерт об успешном создании if ($fid > 0) $_SESSION['module_forms_admin'][$fid]['edit_alert'] = array('text' => 'created', 'theme' => 'accept'); @@ -1012,14 +932,7 @@ function _cleanvar($var) // обновляем форму с данными примера $this->form_save($fid); // подставляем в шаблон новые id полей - $demo['form_tpl'] = preg_replace_callback( - '/\[tag:fld:(\d+)]/', - function($matches) { - return "[tag:fld:" . ($_REQUEST["demo_change"][(int)$matches[1]] ?? '') . "]"; - }, - $demo['form_tpl'] - ); - + $demo['form_tpl'] = preg_replace_callback('/\[tag:fld:(\d+)]/', create_function('$matches','return "[tag:fld:" . $_REQUEST["demo_change"][(int)$matches[1]] . "]";'),$demo['form_tpl']); $AVE_DB->Query(" UPDATE " . PREFIX . "_module_forms_forms SET @@ -1034,7 +947,7 @@ function _cleanvar($var) foreach ($_REQUEST['fields'] as $field_id => $field) { if (!trim($field['title'])) continue; - if (isset($field['setting']) && is_array($field['setting'])) + if (is_array($field['setting'])) { $settings = array(); foreach ($field['setting'] as $setting) @@ -1050,32 +963,28 @@ function _cleanvar($var) } elseif ($field['type'] == 'file') $field['setting'] = (int)$field['setting']; - // 🛑 ИСПРАВЛЕНИЕ PHP 8.4: Проверка существования ключа перед доступом - if (isset($field['defaultval']) && is_array($field['defaultval'])) { - $field['defaultval'] = serialize($field['defaultval']); - } + if (is_array($field['defaultval'])) $field['defaultval'] = serialize($field['defaultval']); $sql = " title = '" . addslashes($field['title']) . "', - active = '" . (int)($field['active'] ?? 0) . "', + active = '" . (int)$field['active'] . "', type = '" . $field['type'] . "', - setting = '" . addslashes($field['setting'] ?? '') . "', - required = '" . (int)($field['required'] ?? 0) . "', - defaultval = '" . addslashes($field['defaultval'] ?? '') . "', - attributes = '" . addslashes(trim($field['attributes'] ?? '')) . "', - tpl = '" . addslashes($field['tpl'] ?? '') . "' + setting = '" . addslashes($field['setting']) . "', + required = '" . (int)$field['required'] . "', + defaultval = '" . addslashes($field['defaultval']) . "', + attributes = '" . addslashes(trim($field['attributes'])) . "', + tpl = '" . addslashes($field['tpl']) . "' "; - // ИСПРАВЛЕНИЕ PHP 8.4: Проверка существования ключа 'new' - if (isset($field['new']) && $field['new']) + if ($field['new']) { $AVE_DB->Query(" INSERT INTO " . PREFIX . "_module_forms_fields SET form_id = '" . (int)$fid . "', - main = '" . (int)($field['main'] ?? 0) . "', + main = '" . (int)$field['main'] . "', " . $sql . " "); - if ($_REQUEST['demo'] ?? false) $_REQUEST['demo_change'][$field_id] = (int)$AVE_DB->InsertId(); + if ($_REQUEST['demo']) $_REQUEST['demo_change'][$field_id] = (int)$AVE_DB->InsertId(); } else { @@ -1089,20 +998,18 @@ function _cleanvar($var) "); } } + foreach ($_REQUEST['field_del'] as $field_id => $delete) + { + if (empty($delete)) continue; + $AVE_DB->Query(" + DELETE FROM " . PREFIX . "_module_forms_fields + WHERE + id = '" . (int)$field_id . "' AND + main != '1' + "); + } - // ИСПРАВЛЕНИЕ PHP 8.4: Безопасная итерация по удаляемым полям - foreach ($_REQUEST['field_del'] ?? [] as $field_id => $delete) - { - if (empty($delete)) continue; - $AVE_DB->Query(" - DELETE FROM " . PREFIX . "_module_forms_fields - WHERE - id = '" . (int)$field_id . "' AND - main != '1' - "); - } - - return $fid; + return $fid; } /** @@ -1189,15 +1096,12 @@ function _cleanvar($var) // rubheader $GLOBALS['user_header']['module_forms_' . $alias_id] = $this->_parse_tags($this->form['rubheader']); - // вывод финишной страницы, если включена проверка от повторной отправки + // вывод финишной страницы, если включена проверка от повторной отправки if (! empty($_GET['mcnfinish']) && $form['protection']) { - $session_key = $form['id'] . $_GET['mcnfinish']; // Определяем ключ заранее - - // ИСПРАВЛЕНО: Используем isset() для проверки существования ключа сессии - if (isset($_SESSION['mcnfinish'][$session_key]) && $_SESSION['mcnfinish'][$session_key] === true) + if ($_SESSION['mcnfinish'][$form['id'] . $_GET['mcnfinish']] === true) { - unset($_SESSION['mcnfinish'][$session_key]); + unset($_SESSION['mcnfinish'][$form['id'] . $_GET['mcnfinish']]); // формируем финишную страницу $tpl = $this->_parse_tags($form['finish_tpl']); @@ -1276,21 +1180,16 @@ function _cleanvar($var) // формируем список получателей $recs = array(); - // Определяем ID главных полей безопасно (Line 1225 fix preparation) - $copy_field_id = isset($form['fields_main']['copy']) ? $form['fields_main']['copy'] : null; - $email_field_id = isset($form['fields_main']['email']) ? $form['fields_main']['email'] : null; - - // пользователь (отправка копии) - (Line 1225 fix) - // Проверяем наличие ключа 'copy' и его значение в POST или в defaultval - $send_copy_post = ($copy_field_id !== null && isset($_POST['form-' . $alias_id][$copy_field_id]) && $_POST['form-' . $alias_id][$copy_field_id] == 1); - $send_copy_default = ($copy_field_id !== null && isset($fields[$copy_field_id]['defaultval']) && $fields[$copy_field_id]['defaultval'] == 1); - - if (($form['is_copy'] === true && $send_copy_post) || $send_copy_default) + // пользователь (отправка копии) + if ( + ($form['is_copy'] === true && $_POST['form-' . $alias_id][$form['fields_main']['copy']] == 1) || + $fields[$form['fields_main']['copy']]['defaultval'] == 1 + ) { $email = ''; - if ($form['is_email'] === true && $email_field_id !== null && isset($_POST['form-' . $alias_id][$email_field_id])) - $email = $_POST['form-' . $alias_id][$email_field_id]; + if ($form['is_email'] === true) + $email = $_POST['form-' . $alias_id][$form['fields_main']['email']]; if (empty($email)) $email = $_SESSION['user_email']; @@ -1310,8 +1209,8 @@ function _cleanvar($var) { $email = ''; - if ($form['is_email'] === true && $email_field_id !== null && isset($_POST['form-' . $alias_id][$email_field_id])) - $email = $_POST['form-' . $alias_id][$email_field_id]; + if ($form['is_email'] === true) + $email = $_POST['form-' . $alias_id][$form['fields_main']['email']]; if (empty($email)) $email = $_SESSION['user_email']; @@ -1320,24 +1219,13 @@ function _cleanvar($var) } // главные получатели - // Проверка, что receivers - это массив, прежде чем слиять - $mail_receivers = is_array($form['mail_set']['receivers']) ? $form['mail_set']['receivers'] : []; - $recs = array_merge($recs, $mail_receivers); + $recs = array_merge($recs, $form['mail_set']['receivers']); // выбранные в форме получатели if ($this->form['is_receivers'] === true) { - // Проверка наличия ключа 'receivers' (Line 1268 fix) - $recs_field_id = isset($form['fields_main']['receivers']) ? $form['fields_main']['receivers'] : null; - - if ($recs_field_id !== null && isset($_POST['form-' . $alias_id][$recs_field_id])) - { - // Проверка, что поле и его настройки существуют, прежде чем получить значение - $post_value = $_POST['form-' . $alias_id][$recs_field_id]; - if (isset($fields[$recs_field_id]['setting'][$post_value])) { - $recs[] = $fields[$recs_field_id]['setting'][$post_value]; - } - } + $recs_field_id = $form['fields_main']['receivers']; + $recs[] = $fields[$recs_field_id]['setting'][$_POST['form-' . $alias_id][$recs_field_id]]; } // если ни один получатель не назначен, отправляем админскому @@ -1351,34 +1239,17 @@ function _cleanvar($var) foreach ($recs as $rec) { - // Fix Line 1282: Убеждаемся, что $rec — это массив и имеет ключ 'email' - if (is_array($rec) && isset($rec['email'])) - { - $trimmed_email = trim($rec['email']); - if (!isset($this->form['receivers'][$trimmed_email]) && $trimmed_email > '') - $this->form['receivers'][$trimmed_email] = $rec; - } + if (!isset($this->form['receivers'][$rec['email']]) && trim($rec['email']) > '') + $this->form['receivers'][trim($rec['email'])] = $rec; } $recs = $this->form['receivers']; $recs[] = array('agent' => 'history'); // обрабатываем тему по умолчанию - // Проверка наличия ключа 'subject' и самого поля - $subject_field_id = isset($form['fields_main']['subject']) ? $form['fields_main']['subject'] : null; - - if ($subject_field_id !== null && isset($form['fields'][$subject_field_id])) + if (!$form['fields'][$form['fields_main']['subject']]['active'] || !$form['fields'][$form['fields_main']['subject']]['is_used']) { - $subject_field = $form['fields'][$subject_field_id]; - - // Добавляем isset для 'active' и 'is_used' - $is_active = isset($subject_field['active']) ? $subject_field['active'] : false; - $is_used = isset($subject_field['is_used']) ? $subject_field['is_used'] : false; - - if (!$is_active || !$is_used) - { - $_POST['form-' . $alias_id][$subject_field_id] = $subject_field['defaultval']; - } + $_POST['form-' . $alias_id][$form['fields_main']['subject']] = $form['fields'][$form['fields_main']['subject']]['defaultval']; } // обрабатываем шаблон письма @@ -1394,10 +1265,7 @@ function _cleanvar($var) foreach ($fields as $field_id => $field) { - // Fix Line 1308: Проверка существования ключа 'is_used' - $is_used = isset($field['is_used']) ? $field['is_used'] : false; - - if ($is_used !== true || $field['title'] == 'captcha' || empty($field['active'])) + if ($field['is_used'] !== true || $field['title'] == 'captcha' || empty($field['active'])) continue; $easy .= "[tag:title:$field_id]" . ": [tag:fld:$field_id];" . ($form['mail_set']['format'] === 'text' ? "\r\n" : '
'); @@ -1426,9 +1294,7 @@ function _cleanvar($var) { foreach ($_FILES['form-' . $alias_id]['name'] as $field_id => $fname) { - // ИСПРАВЛЕНИЕ: Безопасное получение расширения - $path_parts = pathinfo($fname); - $ext = $path_parts['extension'] ?? ''; + $ext = (end(explode('.', $fname))); if ( !empty($_FILES['form-' . $alias_id]['tmp_name'][$field_id]) && @@ -1481,7 +1347,7 @@ function _cleanvar($var) $subject = $subject_tpl; - $if_user_open = (($rec['agent'] ?? '') === 'user'); // ИСПРАВЛЕНО: Безопасный доступ к 'agent' + $if_user_open = ($rec['agent'] === 'user'); $if_admin_open = !$if_user_open; $this->_parse_tag_if($mail,'if_user',$if_user_open); @@ -1497,7 +1363,7 @@ function _cleanvar($var) $subject = trim($this->_eval2var(' ?>' . $subject . 'Query(" - SELECT user_name, firstname, lastname - FROM " . PREFIX . "_users - WHERE Id = '" . $response['user_id'] . "' - ")->FetchAssocArray(); + // ответы + foreach ($history['dialog']['response'] as &$response) + { + $response_author = $AVE_DB->Query(" + SELECT user_name, firstname, lastname + FROM " . PREFIX . "_users + WHERE Id = '" . $response['user_id'] . "' + ")->FetchAssocArray(); - if (!empty($response_author)) - $response = array_merge($response, $response_author); -} + if (!empty($response_author)) + $response = array_merge($response, $response_author); + } // форма ответа if (empty($history['dialog']['response_draft'])) diff --git a/forms/demo.php b/forms/demo.php index 808ee79..0b9d875 100644 --- a/forms/demo.php +++ b/forms/demo.php @@ -27,15 +27,6 @@ $form_tpl = array( - [tag:if_form_invalid]
@@ -91,38 +91,38 @@ $smarty['start_alert_theme'] = '{$alert.theme|default:''}'; {/if} -{if !empty($dialog.response)} - -
{if $dialog.response|@count == 1}{#response#}{else}{#responses#}{/if}
- - {foreach from=$dialog.response item=item} - - - {if $item.user_name|default:false} <-- ИСПРАВЛЕНИЕ: Проверяем user_name безопасно - [{$item.user_name}] {if $item.firstname|default:false || $item.lastname|default:false}{$item.firstname|default:''} {$item.lastname|default:''}{/if}
- {/if} - {#from#} {$item.from_email} <{$item.from_name|escape}>
- {$item.date|date_format:$TIME_FORMAT|pretty_date} - - - {if $item.format=='text'} -
{$item.body}
+ {if $dialog.response} + +
{if $dialog.response|@count == 1}{#response#}{else}{#responses#}{/if}
+ + {foreach from=$dialog.response item=item} + + + {if $item.user_name} + [{$item.user_name}] {if $item.firstname || $item.lastname}{$item.firstname} {$item.lastname}{/if}
+ {/if} + {#from#} {$item.from_email} <{$item.from_name|escape}>
+ {$item.date|date_format:$TIME_FORMAT|pretty_date} + + + {if $item.format=='text'} +
{$item.body}
+ {else} + {$item.body} + {/if} + + + {/foreach} {else} - {$item.body} + + + {if $status!=='replied'}{#set_replied#} + {else} + {#marked_replied#} + {/if} + + {/if} - - - {/foreach} -{else} - - - {if $status!=='replied'}{#set_replied#} - {else} - {#marked_replied#} - {/if} - - -{/if}
@@ -148,18 +148,16 @@ $smarty['start_alert_theme'] = '{$alert.theme|default:''}'; {#mfld_subject#}: - + {#format#}: - - - - - - + + + + + + {#body#} diff --git a/forms/templates/form_edit.tpl b/forms/templates/form_edit.tpl index 441825f..38cfd38 100644 --- a/forms/templates/form_edit.tpl +++ b/forms/templates/form_edit.tpl @@ -90,14 +90,12 @@ $fid = parseInt('{$fid}'); $sess = '{$sess}'; $smarty = new Array; -$smarty['start_alert'] = '{$alert.text|default:''}'; -$smarty['start_alert_theme'] = '{$alert.theme|default:''}'; +$smarty['start_alert'] = '{$alert.text}'; +$smarty['start_alert_theme'] = '{$alert.theme}'; $smarty['_email_accept'] = '{#email_accept#}'; $smarty['_email_error'] = '{#email_error#}'; $smarty['tpl_dir'] = '{$tpl_dir}'; $smarty['_refresh'] = '{#refresh#}'; -$smarty['form_title_error_text'] = '{#form_title_error_text#}'; -$smarty['form_title_error_title'] = '{#form_title_error_title#}';
@@ -134,7 +132,7 @@ $smarty['form_title_error_title'] = '{#form_title_error_title#}'; {#title#}: - + @@ -146,9 +144,9 @@ $smarty['form_title_error_title'] = '{#form_title_error_title#}';
- + - +
@@ -161,7 +159,7 @@ $smarty['form_title_error_title'] = '{#form_title_error_title#}';
- + {if !$fid} @@ -601,26 +599,8 @@ $(function() { }); }); -// Функция сохранения формы +// функция сохранения формы function form_save (fields_reload, data) { - - // 1. ПРОВЕРКА ПОЛЯ "НАЗВАНИЕ" - var formTitle = $('#form_title').val().trim(); - - if (formTitle === "") { - - // 1.1. Выводим сообщение об ошибке с использованием jAlert - jAlert($smarty['form_title_error_text'], $smarty['form_title_error_title']); - - // 1.2. Устанавливаем фокус на поле - $('#form_title').focus(); - - return false; // Прерываем выполнение функции - } - // КОНЕЦ ПРОВЕРКИ - - - // 2. СТАНДАРТНАЯ ЛОГИКА AJAX (Если проверка пройдена) if (data == undefined) var data = new Object(); var form = $('#form_edit'); data.ajax = 1; @@ -784,16 +764,10 @@ $(document) {/literal} - - -{* Итерируем по новому, чистому массиву *} -{foreach from=$codemirror_data key='cdmr_id' item='cdmr_h'} - +{foreach from=$codemirror key='cdmr_id' item='cdmr_h'} {if $ave15} - {* Ветка $ave15 (инклуд) *} {include file="$codemirror_editor" ctrls='form_save();' conn_id="_$cdmr_id" textarea_id=$cdmr_id height=$cdmr_h} {else} - {* Ветка !ave15 (оригинальный код) *} {/if} {/foreach} - - -{literal} - -{/literal} \ No newline at end of file + \ No newline at end of file diff --git a/forms/templates/form_fields.tpl b/forms/templates/form_fields.tpl index 570f092..74207b7 100644 --- a/forms/templates/form_fields.tpl +++ b/forms/templates/form_fields.tpl @@ -56,8 +56,8 @@ {if $field.main && $field.title=='receivers'} {foreach from=$field.setting item=receiver name=receivers}
- - + + {if $smarty.foreach.receivers.index == 0} {else} @@ -139,7 +139,6 @@ [tag:uname] | [tag:ufname] | [tag:ulname] | - [tag:submitted_page]
{if $ave15} @@ -186,11 +185,11 @@ {/if} {elseif ($field.type=='select' || $field.type=='multiselect')} - {if !$field.setting_empty|default:0} + {if !$field.setting_empty} + {if !$field.main} @@ -214,30 +213,10 @@ {/if} - +
-
{#attributes#} {#info_attr_name#} -
- - - -
-
+
{#attributes#}
| php | @@ -263,7 +242,7 @@
-
{#field_tpl#}
+
{#field_tpl#}
| php | diff --git a/forms/templates/history.tpl b/forms/templates/history.tpl index bda5cbd..83d2c35 100644 --- a/forms/templates/history.tpl +++ b/forms/templates/history.tpl @@ -11,12 +11,6 @@ $smarty = new Array; $smarty['stat_replied'] = '{#stat_replied#}'; $smarty['stat_viewed'] = '{#stat_viewed#}'; -$smarty['delete'] = '{#delete#}'; -$smarty['cn_select_for_action'] = '{#cn_select_for_action#}'; -$smarty['cn_confirm_mass_del'] = '{#cn_confirm_mass_del#}'; -$smarty['delete_error'] = '{#delete_error#}'; -$smarty['action_confirm_title'] = '{#action_confirm_title#}'; -$smarty['action_error_title'] = '{#action_error_title#}';
@@ -32,7 +26,7 @@ $smarty['action_error_title'] = '{#action_error_title#}';
  • {#MODULES_SUB_TITLE#}
  • {#contacts#}
  • {#forms#}
  • -
  • {$form.title|default:''|escape}
  • +
  • {$form.title|escape}
  • {#history#}
  • @@ -46,7 +40,6 @@ $smarty['action_error_title'] = '{#action_error_title#}';
    - @@ -55,7 +48,6 @@ $smarty['action_error_title'] = '{#action_error_title#}'; - @@ -66,7 +58,6 @@ $smarty['action_error_title'] = '{#action_error_title#}'; {foreach from=$dialogs item=dialog} - @@ -100,36 +91,9 @@ $smarty['action_error_title'] = '{#action_error_title#}'; {/foreach} - {if $dialog} - - - - - - - - - - - {/if}
    {#date#} {#mfld_subject#} {#author#}
    {$dialog.date|date_format:$TIME_FORMAT|pretty_date}
    {#date#}{#mfld_subject#}{#author#}{#status#}{#cn_actions#}
    -{if $dialog} -
    -
    - -    - -
    -
    -{/if}
    + {if $page_nav}