diff --git a/README.md b/README.md index b6bd24e..638ec70 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,31 @@ -# forms +### forms -Модуль Формы v3.31 \ No newline at end of file +## Модуль Формы v3.31 + +### адаптирован для AVE.CMS ALT + +### Модуль предназначен для создания веб-форм (например, обратной связи или простейшего оформления заказа), которые могут состоять из любого набора полей. + +### Для вывода в публичной части сайта используйте тег [mod_forms:XXX], где XXX - это id или алиас формы. + +### Changelog: + +18.02.2026 - Версия v3.31 - дальнейшее развитие модуля только для работы с AVE.CMS ALT + +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, в … +…который можно подставлять теги (например [tag:docid]) и php код + +16.04.2017 - Версия 1.2.3 - исправление ошибок, в демоверсии включен пример обновление капчи по клику + +19.09.2016 - Версия 1.2.2 - изменения в административной части модуля + +18.09.2016 - Версия 1.2.1 - добавлена возможность удаления сообщений + +11.09.2016 - инициализация модуля для AVE.CMS v3.1.5 \ No newline at end of file diff --git a/class/forms.php b/class/forms.php new file mode 100644 index 0000000..5c2aaf5 --- /dev/null +++ b/class/forms.php @@ -0,0 +1,1787 @@ + array( + 'new' => true, + 'title' => 'email', + 'type' => 'input', + 'main' => 1, + 'setting' => 'FILTER_VALIDATE_EMAIL', + 'required' => 1 + ), + 'subject' => array( + 'new' => true, + 'title' => 'subject', + 'type' => 'input', + 'main' => 1 + ), + 'receivers' => array( + 'new' => true, + 'title' => 'receivers', + 'type' => 'select', + 'main' => 1, + 'setting' => array() + ), + 'copy' => array( + 'new' => true, + 'title' => 'copy', + 'type' => 'checkbox', + 'main' => 1 + ), + 'captcha' => array( + 'new' => true, + 'title' => 'captcha', + 'type' => 'input', + 'main' => 1, + 'required' => 1 + ) + ); + // переменная для хранения формы + public $form = array(); + + /** + * Внутренние методы класса + */ + + /** + * Конструктор + */ + function __construct () + { + $this->fields_main = array_keys($this->fields_main_data); + $this->fields_main_in_string = "'" . implode("','",$this->fields_main) . "'"; + } + + + /** + * Возвращаем JSON + * + * @param $data + * @param bool $exit + */ + function _json($data, $exit = false) + { + header("Content-Type: application/json;charset=utf-8"); + + $json = json_encode($data); + + if ($json === false) + { + $json = json_encode(array("jsonError", json_last_error_msg())); + + if ($json === false) + { + $json = '{"jsonError": "unknown"}'; + } + + http_response_code(500); + } + + echo $json; + + if ($exit) + exit; + } + + + /** + * Метод забирает форму из бд по алиасу/id + * + * @param $alias_id + * @param bool $_fields + * + * @return array + */ + function _form ($alias_id, $_fields = true) + { + global $AVE_DB, $AVE_Template; + + // иначе забираем из бд форму + $form = array(); + + // основные параметры + $form = $AVE_DB->Query(" + SELECT * FROM " . PREFIX . "_module_forms_forms + WHERE + " . (is_numeric($alias_id) ? 'id' : 'alias') . " = '" . $alias_id . "' + ")->FetchAssocArray(); + + // если форма не обнаружена, выходим + if (empty($form)) + return array(); + + $form['alias_id'] = $alias_id; + + // получатели + // ИСПРАВЛЕНИЕ: Добавляем @ для подавления Warning при десериализации, т.к. пользователь сообщил о проблеме + $form['mail_set'] = @unserialize($form['mail_set']); + + if ($_fields === true) + { + // поля + $sql = $AVE_DB->Query(" + SELECT * FROM " . PREFIX . "_module_forms_fields + WHERE form_id = '" . $form['id'] . "' + ORDER BY id ASC + "); + + $form['fields'] = array(); + + while ($field = $sql->FetchAssocArray()) + { + // раскрываем массив настроек для селектов + if (in_array($field['type'],array('select','multiselect','doc','multidoc'))) + { + // @fix для v1.0 beta <= 2: поддержка одной рубрики, не массива + 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(); + } + // если тип поля поменялся, ставим пустую строку + // ИСПРАВЛЕНИЕ: Добавляем дополнительную проверку на то, что строка может быть сериализована (начинается с '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'] = ''; + + // раскрываем массив опций по умолчанию для мультиселекта + if ($field['type'] == 'multiselect') + { + // ИСПРАВЛЕНИЕ: Добавляем @ для подавления Warning при десериализации + $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'] = ''; + + // главные поля + if (in_array($field['title'],$this->fields_main) && $field['main']) + { + $form['fields_main'][$field['title']] = $field['id']; + $field['title_lang'] = $AVE_Template->get_config_vars('mfld_' . $field['title']); + } + + $form['fields'][$field['id']] = $field; + } + } + + // убираем слеши + $form = $this->_stripslashes($form); + + // сохраняем форму в переменную класса + $this->form = $form; + + return $form; + } + + +/** + * Метод убирает слэши во всей переменной + * + * @param mixed $var + * + * @return array|string + */ + function _stripslashes($var) + { + if (is_array($var)) + return array_map(array($this, '_stripslashes'), $var); + else + // ИСПРАВЛЕНИЕ: Гарантируем, что $var является строкой, используя ?? '' + return stripslashes($var ?? ''); + } + + + /** + * Метод тримует всю переменную + * + * @param $var + * + * @return array|string + */ + function _trim($var) + { + if (! is_array($var)) + return trim($var); + else + return array_map(array($this, '_trim'), $var); + } + + +/** + * Метод чистит переменную от пустых значений и массивов + * + * @param $var + * + * @return array|null|string + */ +function _cleanvar($var) +{ + if (!is_array($var)) { + return trim($var) > '' + ? trim($var) + : null; + } + + $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; + } + } + } + + unset($var); + + return $narr; +} + + /** + * Валидация Email-а + * + * @param string $email + * + * @return bool + */ + function _email_validate ($email = '') + { + return (filter_var($email, FILTER_VALIDATE_EMAIL) === false ? false : true); + } + + + /** + * Проверка алиаса тега на валидность и уникальность + * + * @param string $alias + * @param int $fid + * + * @return bool|string + */ + function _alias_validate ($alias = '', $fid = 0) + { + global $AVE_DB; + + // соответствие требованиям + if ( + empty ($alias) || + preg_match('/^[A-Za-z0-9-_]{1,20}$/i', $alias) !== 1 || + is_numeric($alias) + ) return 'syn'; + + // уникальность + return !(bool)$AVE_DB->Query(" + SELECT 1 FROM " . PREFIX . "_module_forms_forms + WHERE + alias = '" . $alias . "' AND + id != '" . $fid . "' + ")->GetCell(); + } + + + /** + * Получение списка рубрик + */ + function _rubrics () + { + global $AVE_DB; + + $rubs = array(); + + $sql = $AVE_DB->Query(" + SELECT Id, rubric_title FROM " . PREFIX . "_rubrics + "); + + while ($rub = $sql->FetchAssocArray()) + $rubs[$rub['Id']] = $rub['rubric_title']; + + return $rubs; + } + + + /** + * Получение списка документов + * + * @param array $rubs_id + * + * @return array + */ + function _docs ($rubs_id = array()) + { + global $AVE_DB; + + if (empty($rubs_id)) + return array(); + + // @fix для v1.0 beta <= 2: поддержка одной рубрики, не массива + if (! is_array($rubs_id)) + $rubs_id = array(0 => $rubs_id); + + $docs = array(); + + $sql = $AVE_DB->Query(" + SELECT Id, document_title FROM " . PREFIX . "_documents + WHERE rubric_id IN (" . implode(',',$rubs_id) . ") + "); + + while ($doc = $sql->FetchAssocArray()) + $docs[$doc['Id']] = $doc['document_title']; + + return $docs; + } + + +/** + * Парсинг главных тегов + */ + function _parse_tags ($str) + { + global $AVE_Core, $AVE_DB; + + if (empty($_SESSION['user_login'])) + $_SESSION['user_login'] = (UGROUP != 2) + ? $AVE_DB->Query("SELECT user_name FROM " . PREFIX . "_users WHERE Id = '" . UID . "'")->GetCell() + : ''; + + $str = preg_replace_callback('/\[tag:(css|js):([^ :\/]+):?(\S+)*\]/', array($AVE_Core, '_parse_combine'), $str); + + $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]', + // @fix для v1.0 beta <= 2: поддержка тега formaction + '[tag:formaction]', + '[tag:document]', + '[tag:formalias]', + '[tag:path]', + '[tag:mediapath]', + '[tag:captcha]', + '[tag:uname]', + '[tag:ufname]', + '[tag:ulname]', + '[tag:ulogin]', + '[tag:uemail]', + '[tag:sitename]', + '[tag:sitehost]', + '[tag:submitted_page]', + ),array( + $AVE_Core->curentdoc->Id, + $this->form['title'], + $_SERVER['REQUEST_URI'], + $_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) . '/', + 'inc/captcha.php', + $_SESSION['user_name'], + + // ИСПРАВЛЕНИЕ: Безопасное получение firstname и lastname + $user_rec->firstname ?? '', + $user_rec->lastname ?? '', + + $_SESSION['user_login'] ?? '', + $_SESSION['user_email'] ?? '', + htmlspecialchars(get_settings('site_name'), ENT_QUOTES), + $_SERVER['HTTP_HOST'], + getSiteUrl() . $_SERVER['REQUEST_URI'], + ), $str); + } + + /** + * Внутренний PHP-парсер + */ + function _eval2var($code) + { + global $AVE_DB, $AVE_Core, $AVE_Template; + + ob_start(); + + eval($code); + + return ob_get_clean(); + } + + /** + * Приведение тегов главных полей к стандартной форме + */ + function _parse_tag_fld_main ($tpl='', $save_is=false) + { + foreach ($this->fields_main as $field_title) + { + $count = 0; + + $tpl = str_replace(array( + '[tag:fld:' . $field_title . ']', + '[tag:if_fld:' . $field_title, + '[tag:elseif_fld:' . $field_title, + ), array( + '[tag:fld:' . $this->form['fields_main'][$field_title] . ']', + '[tag:if_fld:' . $this->form['fields_main'][$field_title], + '[tag:elseif_fld:' . $this->form['fields_main'][$field_title], + ),$tpl,$count); + + if ($save_is) + $this->form['is_' . $field_title] = $count > 0 ? true : false; + } + + return $tpl; + } + + /** + * Замена тега условия + */ + function _parse_tag_if (&$tpl,$tag='',$open = true) + { + if ($open) + $tpl = str_replace(array('[tag:' . $tag . ']','[/tag:' . $tag . ']'),'',$tpl); + else + $tpl = preg_replace('/\[tag:' . $tag . '](.*?)\[\/tag:' . $tag . ']/si','',$tpl); + } + + /** + * Замена тега названия поля + */ + function _parse_tag_title ($matches) + { + $field_id = $matches[1]; + + return !$this->form['fields'][$field_id]['main'] + ? $this->form['fields'][$field_id]['title'] + : $this->form['fields'][$field_id]['title_lang']; + } + + /** + * Замена тега поля на значение $_POST + */ + function _parse_tag_fld_post ($matches) + { + return $_POST['form-' . $this->form['alias_id']][$matches[1]] ?? ''; + } + + /** + * Замена тега поля при выводе формы + */ + function _parse_tag_fld_form ($matches) + { + $field_id = (int)$matches[1]; + + if (!isset($this->form['fields'][$field_id])) { + return $matches[0]; + } + + // забираем массив поля + $field = $this->form['fields'][$field_id]; + + // если поля нет, возвращаем тег обратно + if (empty($field)) + return $matches[0]; + + // если поле выключено, возвращаем пустую строку + if (empty($field['active'])) + return ''; + + $alias_id = $this->form['alias_id']; + + $fld_val = $this->form['is_submited'] + ? $this->_stripslashes($_POST['form-' . $alias_id][$field_id] ?? null) + : (in_array($field['type'],array('input','textarea')) + ? $this->_eval2var('?>' . $field['defaultval'] . 'form['fields'][$field_id]['is_used'] = true; + + $input = ''; + $return = ''; + + switch ($field['type']) + { + case 'input': + $input = ''; + break; + + case 'textarea': + $input = ''; + break; + + case 'select': + $input = ''; + break; + + case 'multiselect': + $input = ''; + break; + + case 'checkbox': + $input = ' + + '; + break; + + case 'file': + $input = ''; + break; + + case 'doc': + $input = ''; + break; + + case 'multidoc': + $input = ''; + break; + } + + // Вставляем поле в шаблон поля + $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); + + // если попытка отправить форму, обрабатываем валидацию и пустоту + if ($this->form['is_submited']) + { + // валидация (только для капчи, input, textarea и file) + if ( + ($field['title'] == 'captcha' && $field['main'] && $this->form['is_captcha'] === true) || + (in_array($field['type'],array('input','textarea','file')) && !empty($field['setting'])) + ) + { + $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; + } + } + // если константу + 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; + } + // иначе, ничего не делаем + else return 'Неверные параметры валидации!'; + // парсим теги валидности + $this->_parse_tag_if($return,'if_valid',$valid); + $this->_parse_tag_if($return,'if_invalid',!$valid); + // записываем результаты + $this->form['ajax']['fields'][$field_id]['validate'] = true; + $this->form['ajax']['fields'][$field_id]['pattern'] = $field['setting']; + $this->form['ajax']['fields'][$field_id]['is_valid'] = $valid; + if (!$valid) + { + $this->form['is_valid'] = false; + $this->form['ajax']['form']['is_valid'] = false; + } + } + else + { + $this->form['ajax']['fields'][$field_id]['validate'] = false; + $this->form['ajax']['fields'][$field_id]['is_valid'] = null; + } + + // пустота (для любых обязательных полей) + 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); + } + else + { + $clean_fld_val = $this->_cleanvar($fld_val); + $empty = empty($clean_fld_val); + } + // парсим теги + $this->_parse_tag_if($return,'if_empty',$empty); + $this->_parse_tag_if($return,'if_notempty',!$empty); + // записываем результаты + $this->form['ajax']['fields'][$field_id]['required'] = true; + $this->form['ajax']['fields'][$field_id]['is_empty'] = $empty; + if ($empty) + { + $this->form['is_valid'] = false; + $this->form['ajax']['form']['is_valid'] = false; + } + } + else + { + $this->form['ajax']['fields'][$field_id]['required'] = false; + $this->form['ajax']['fields'][$field_id]['is_empty'] = null; + } + } + // удаляем оставшиеся теги + $this->_parse_tag_if($return,'if_valid',false); + $this->_parse_tag_if($return,'if_invalid',false); + $this->_parse_tag_if($return,'if_empty',false); + $this->_parse_tag_if($return,'if_notempty',false); + + return $return; + } + + /** + * Замена тега поля в шаблоне письма + */ + function _parse_tag_fld_mail ($matches) + { + global $AVE_DB, $AVE_Template; + + $field_id = (int)$matches[1]; + // забираем массив поля + $field = $this->form['fields'][$field_id]; + // если поля нет, возвращаем тег обратно + if (empty($field)) return $matches[0]; + // если поля не было в шаблоне формы, убираем тег + 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] ?? ''; + $newval = ''; + $tag_mail_empty = ($this->form['mail_set']['format'] === 'text' ? '<' : '<') . $AVE_Template->get_config_vars('tag_mail_empty') . ($this->form['mail_set']['format'] === 'text' ? '>' : '>'); + + // делаем поправки для типов + switch ($field['type']) + { + case 'select': + $newval = $field['setting'][$val]; + if ($field['title'] == 'receivers') $newval = $newval['name']; + break; + + case 'multiselect': + foreach ($val as $val1) $newval .= $field['setting'][$val1] . ','; + $newval = rtrim($newval,','); + break; + + case 'checkbox': + $newval = ($val ? $AVE_Template->get_config_vars('yes') : $AVE_Template->get_config_vars('no')); + break; + + case 'doc': + if (!empty($val)) $newval = $AVE_DB->Query("SELECT document_title FROM " . PREFIX . "_documents WHERE Id='" . $val . "'")->GetCell(); + break; + + case 'multidoc': + if (!empty($val)) + { + $sql = $AVE_DB->Query("SELECT document_title FROM " . PREFIX . "_documents WHERE Id IN (" . implode(',',$val) . ")"); + while ($titl = $sql->GetCell()) $titls[] = $titl; + $newval = implode(', ',$titls); + } + 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); + break; + + default: + $newval = $val; + } + return (empty($newval) ? $tag_mail_empty : $newval); + } + + /** + * Внешние методы класса + */ + + /** + * Вывод списка форм + */ + function forms_list () + { + global $AVE_DB, $AVE_Template; + $assign = array(); + + $limit = 20; + $start = get_current_page() * $limit - $limit; + $sql = $AVE_DB->Query(" + SELECT SQL_CALC_FOUND_ROWS + f.*, + SUM(IF(h.status='new',1,0)) AS history_new, + SUM(IF(h.status='viewed',1,0)) AS history_viewed, + SUM(IF(h.status='replied',1,0)) AS history_replied + FROM " . PREFIX . "_module_forms_forms AS f + LEFT OUTER JOIN " . PREFIX . "_module_forms_history AS h ON f.id = h.form_id + GROUP BY f.id + ORDER BY f.id ASC + LIMIT " . $start . "," . $limit . " + "); + $num = (int)$AVE_DB->Query("SELECT FOUND_ROWS()")->GetCell(); + $pages = @ceil($num / $limit); + if ($num > $limit) + { + $page_nav = '{t}'; + $page_nav = get_pagination($pages, 'page', $page_nav); + $AVE_Template->assign('page_nav', $page_nav); + } + + while ($row = $sql->FetchAssocArray()) + { + $assign['forms'][] = $row; + } + + $AVE_Template->assign($assign); + $AVE_Template->assign('content', $AVE_Template->fetch($this->tpl_dir . 'forms.tpl')); + } + + /** + * Создание/редактирование формы + */ + function form_edit () + { + global $AVE_DB, $AVE_Template; + $form = array(); + $assign = array(); + $fid = $assign['fid'] = !empty($_REQUEST['fid']) ? (int)$_REQUEST['fid'] : 0; + + if ($fid) + { + $form = $this->_form($fid); + + // для правильного вывода селектов + if (empty($form['mail_set']['receivers'])) $form['mail_set']['receivers'] = array(0 => array()); + + // Добавляем проверку, чтобы избежать ошибки + if (is_array($form['fields'])) + { + foreach ($form['fields'] as &$field) + { + if (($field['type'] == 'select' || $field['type'] == 'multiselect') && empty($field['setting'])) + { + $field['setting'] = array(array()); + } + } + } + } + + // алерт при открытии правки + if (!empty($_SESSION['module_forms_admin'][$fid]['edit_alert'])) + { + $assign['alert']['text'] = $AVE_Template->get_config_vars($_SESSION['module_forms_admin'][$fid]['edit_alert']['text']); + $assign['alert']['theme'] = $_SESSION['module_forms_admin'][$fid]['edit_alert']['theme']; + unset($_SESSION['module_forms_admin'][$fid]['edit_alert']); + } + $assign['form'] = $form; + $assign['form_fields_tpl'] = $this->tpl_dir . 'form_fields.tpl'; + $assign['rubrics'] = $this->_rubrics(); + + // назначаем массив CodeMirror + $assign['codemirror_data'] = array( + 'rubheader' => 200, + 'from_name' => 60, + 'from_email' => 60, + 'subject_tpl' => 60, + 'form_tpl' => 460, + 'mail_tpl' => 460, + 'finish_tpl' => 320, + 'code_onsubmit' => 200, + 'code_onvalidate' => 200, + 'code_onsend' => 200, + 'code_beforesend' => 200 + ); + + $AVE_Template->assign($assign); + $AVE_Template->assign('content', $AVE_Template->fetch($this->tpl_dir . 'form_edit.tpl')); + } + + /** + * Получение полей через аякс + */ + function form_fields_fetch () + { + global $AVE_DB, $AVE_Template; + $fid = $assign['fid'] = !empty($_REQUEST['fid']) ? (int)$_REQUEST['fid'] : 0; + if (!$fid) return; + $form = $this->_form($fid); + // для правильного вывода селектов + if (empty($form['mail_set']['receivers'])) $form['mail_set']['receivers'] = array(0 => array()); + foreach ($form['fields'] as &$field) + { + if (($field['type'] == 'select' || $field['type'] == 'multiselect') && empty($field['setting'])) + { + $field['setting'] = array(0 => ''); + $field['setting_empty'] = true; + } + } + $AVE_Template->assign('fields',$form['fields']); + $AVE_Template->assign('rubrics',$this->_rubrics()); + $AVE_Template->assign('field_tpl_open',$_REQUEST['field_tpl_open']); + + 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) + { + 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 ($fid) + { + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_forms_forms + SET + title = '" . addslashes($_REQUEST['title']) . "', + protection = '" . (int)$_REQUEST['protection'] . "', + " . (($_REQUEST['alias'] === '' || $this->_alias_validate($_REQUEST['alias'],$fid) === true) ? " alias = '" . $_REQUEST['alias'] . "'," : '') . " + mail_set = '" . addslashes(serialize($_REQUEST['mail_set'])) . "', + rubheader = '" . addslashes($_REQUEST['rubheader']) . "', + form_tpl = '" . addslashes($_REQUEST['form_tpl']) . "', + mail_tpl = '" . addslashes($_REQUEST['mail_tpl']) . "', + finish_tpl = '" . addslashes($_REQUEST['finish_tpl']) . "', + 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'] : '') . "' + WHERE + id = '" . $fid . "' + "); + } + else + { + $mail_set = array( + 'from_name' => get_settings('mail_from_name'), + 'from_email' => get_settings('mail_from'), + 'receivers' => array(0 => array( + 'name' => get_settings('mail_from_name'), + 'email' => get_settings('mail_from') + ), + ), + 'subject_tpl' => '[tag:formtitle]', + 'format' => 'text' + ); + $AVE_DB->Query(" + INSERT INTO " . PREFIX . "_module_forms_forms + SET + title = '" . addslashes($_REQUEST['title']) . "', + " . (($this->_alias_validate($_REQUEST['alias'],$fid) === true || $_REQUEST['alias'] === '') ? " alias = '" . $_REQUEST['alias'] . "'," : '') . " + 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'); + + // если устанавливаем пример + if (!empty($_REQUEST['demo'])) + { + $demo = array(); + include(BASE_DIR . '/modules/forms/demo.php'); + $_REQUEST = array_merge($_REQUEST,$demo); + // обновляем форму с данными примера + $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'] + ); + + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_forms_forms + SET + form_tpl = '" . addslashes($demo['form_tpl']) . "' + WHERE id = '" . $fid . "' + "); + return $fid; + } + } + + // сохраняем поля + foreach ($_REQUEST['fields'] as $field_id => $field) + { + if (!trim($field['title'])) continue; + if (isset($field['setting']) && is_array($field['setting'])) + { + $settings = array(); + foreach ($field['setting'] as $setting) + { + // если получатели + if ($field['title'] == 'receivers' && is_array($setting) && trim($setting['name']) > '' && trim($setting['email']) > '' && $this->_email_validate($setting['email'])) + $settings[] = $setting; + // другое + elseif (!is_array($setting) && trim($setting) > '') + $settings[] = $setting; + } + $field['setting'] = serialize($settings); + } + 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']); + } + + $sql = " + title = '" . addslashes($field['title']) . "', + active = '" . (int)($field['active'] ?? 0) . "', + 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'] ?? '') . "' + "; + // ИСПРАВЛЕНИЕ PHP 8.4: Проверка существования ключа 'new' + if (isset($field['new']) && $field['new']) + { + $AVE_DB->Query(" + INSERT INTO " . PREFIX . "_module_forms_fields + SET + form_id = '" . (int)$fid . "', + main = '" . (int)($field['main'] ?? 0) . "', + " . $sql . " + "); + if ($_REQUEST['demo'] ?? false) $_REQUEST['demo_change'][$field_id] = (int)$AVE_DB->InsertId(); + } + else + { + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_forms_fields + SET + " . $sql . " + WHERE + id = '" . (int)$field_id . "' AND + form_id = '" . $fid . "' + "); + } + } + + // ИСПРАВЛЕНИЕ 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; + } + + /** + * Удаление формы + */ + function form_del ($fid) + { + global $AVE_DB; + + $AVE_DB->Query(" + DELETE FROM " . PREFIX . "_module_forms_forms + WHERE id = '" . $fid . "' + "); + $AVE_DB->Query(" + DELETE FROM " . PREFIX . "_module_forms_fields + WHERE form_id = '" . $fid . "' + "); + } + + /** + * Сохранение формы + */ + function form_copy ($fid) + { + global $AVE_DB; + + // форма + $form = $AVE_DB->Query(" + SELECT * FROM " . PREFIX . "_module_forms_forms + WHERE id = '" . $fid . "' + ")->FetchAssocArray(); + if (empty($form)) return; + $query = "INSERT INTO " . PREFIX . "_module_forms_forms SET "; + foreach ($form as $key => $val) + { + if ($key == 'id' || $key == 'alias') continue; + $query .= $key . " = '" . addslashes($val) . "', "; + } + $query = rtrim($query,', '); + $AVE_DB->Query($query); + $fid_new = (int)$AVE_DB->InsertId(); + + // поля + $sql = $AVE_DB->Query(" + SELECT * FROM " . PREFIX . "_module_forms_fields + WHERE form_id = '" . $fid . "' + "); + while ($row = $sql->FetchAssocArray()) + { + if (empty($row['id'])) continue; + $query = "INSERT INTO " . PREFIX . "_module_forms_fields SET "; + foreach ($row as $key => $val) + { + if ($key == 'id') continue; + elseif ($key == 'form_id') $val = $fid_new; + $query .= $key . " = '" . addslashes($val) . "', "; + } + $query = rtrim($query,', '); + $AVE_DB->Query($query); + } + + return $fid_new; + } + + + /** + * Вывод формы + */ + function form_display ($alias_id) + { + global $AVE_Template; + + $form = $this->_form($alias_id); + + if (empty($form)) + return "[mod_forms:$alias_id] - " . $AVE_Template->get_config_vars('form_notfound'); + + // по дефолту форма валидна, но не отправлена - потом перезаписываем, если что + $this->form['is_valid'] = true; + $this->form['ajax']['form']['is_valid'] = true; + $this->form['ajax']['form']['is_sent'] = false; + $this->form['ajax']['form']['finish_tpl'] = null; + + // 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) + { + unset($_SESSION['mcnfinish'][$session_key]); + + // формируем финишную страницу + $tpl = $this->_parse_tags($form['finish_tpl']); + $tpl = $this->_eval2var('?>' . $tpl . 'form['is_submited'] = false; + + if (! empty($_POST['form-' . $alias_id])) + { + $this->form['is_submited'] = true; + // выполняем код после отправки формы + eval('?>' . $this->form['code_onsubmit'] . 'form['form_tpl']; + // меняем теги основных полей на стандартные + $tpl = $this->_parse_tag_fld_main($tpl,true); + // парсим теги полей и названий + $tpl = preg_replace_callback('/\[tag:fld:(\d+)]/', array($this,'_parse_tag_fld_form'), $tpl); + $tpl = preg_replace_callback('/\[tag:title:([A-Za-z0-9-_]+)]/', array($this,'_parse_tag_title'),$tpl); + + // выполняем код после валидации + eval('?>' . $this->form['code_onvalidate'] . 'form['is_submited'] === true && $this->form['is_valid'] === true) + return $this->form_submit($alias_id); + // иначе - заканчиваем вывод + else + { + // парсим основные теги + $tpl = $this->_parse_tags($tpl); + // теги общей валидности + if ($this->form['is_submited']) + { + $this->_parse_tag_if($tpl,'if_form_valid',$this->form['is_valid']); + $this->_parse_tag_if($tpl,'if_form_invalid',!$this->form['is_valid']); + } + else + { + $this->_parse_tag_if($tpl,'if_form_valid',false); + $this->_parse_tag_if($tpl,'if_form_invalid',false); + } + // заменяем теги условий + $tpl = preg_replace('/\[tag:(if|elseif)_fld:(\d*)(.*?)]/si','',$tpl); + $tpl = str_replace(array('[tag:else_fld]','[/tag:if_fld]'),array('',''),$tpl); + // выполняем код + return $this->_eval2var('?>' . $tpl . 'form; + + $fields = $form['fields']; + + $fid = $form['id']; + + // формируем список получателей + $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) + { + $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 (empty($email)) + $email = $_SESSION['user_email']; + + if (! empty($email)) + { + $recs[] = array( + 'email' => $email, + 'name' => $_SESSION['user_name'], + 'agent' => 'user', + ); + } + + $history['email'] = $email; + } + else // если чекбоксы - отправить копию неактивные + { + $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 (empty($email)) + $email = $_SESSION['user_email']; + + $history['email'] = $email; + } + + // главные получатели + // Проверка, что receivers - это массив, прежде чем слиять + $mail_receivers = is_array($form['mail_set']['receivers']) ? $form['mail_set']['receivers'] : []; + $recs = array_merge($recs, $mail_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]; + } + } + } + + // если ни один получатель не назначен, отправляем админскому + if (empty($recs)) $recs[] = array( + 'name' => get_settings('mail_from_name'), + 'email' => get_settings('mail_from') + ); + + // перезаписываем список уникальных получателей в переменную письма + $this->form['receivers'] = array(); + + 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; + } + } + + $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])) + { + $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']; + } + } + + // обрабатываем шаблон письма + $tpl = $form['mail_tpl']; + + // меняем теги основных полей на стандартные + $tpl = $this->_parse_tag_fld_main($tpl); + + // парсим [tag:easymail] + if (strpos($tpl,'[tag:easymail]') !== false) + { + $easy = ''; + + 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'])) + continue; + + $easy .= "[tag:title:$field_id]" . ": [tag:fld:$field_id];" . ($form['mail_set']['format'] === 'text' ? "\r\n" : '
'); + } + + // убираем последний перевод строки + $easy = ($form['mail_set']['format'] === 'text') ? rtrim($easy) : substr($easy,0,-4); + $tpl = str_replace('[tag:easymail]',$easy,$tpl); + } + + // парсим теги полей и названий + $tpl = preg_replace_callback('/\[tag:fld:(\d+)]/', array($this,'_parse_tag_fld_mail'),$tpl); + $tpl = preg_replace_callback('/\[tag:title:([A-Za-z0-9-_]+)]/', array($this,'_parse_tag_title'),$tpl); + + // парсим основные теги + $tpl = $this->_parse_tags($tpl); + + // заменяем теги условий + $tpl = preg_replace('/\[tag:(if|elseif)_fld:(\d*)(.*?)]/si','',$tpl); + $tpl = str_replace(array('[tag:else_fld]','[/tag:if_fld]'),array('',''),$tpl); + + // файлы-вложения + $attach = array(); + + if (! empty($_FILES['form-' . $alias_id]['tmp_name'])) + { + foreach ($_FILES['form-' . $alias_id]['name'] as $field_id => $fname) + { + // ИСПРАВЛЕНИЕ: Безопасное получение расширения + $path_parts = pathinfo($fname); + $ext = $path_parts['extension'] ?? ''; + + if ( + !empty($_FILES['form-' . $alias_id]['tmp_name'][$field_id]) && + !empty($form['fields'][$field_id]) && + empty($_FILES['form-' . $alias_id]['error'][$field_id]) && + !in_array($ext,array('php', 'phtml', 'php3', 'php4', 'php5', 'js', 'pl')) + ) + { + $fname = BASE_DIR . '/tmp/' . ATTACH_DIR . '/' . str_replace(' ', '_', mb_strtolower(trim($fname))); + + if (file_exists($fname)) + $fname = rtrim($fname,'.' . $ext) . '_' . mt_rand(0,10000) . '.' . $ext; + + @move_uploaded_file($_FILES['form-' . $alias_id]['tmp_name'][$field_id], $fname); + + $attach[] = $fname; + } + } + } + + // Имя отправителя + $from_name_tpl = $form['mail_set']['from_name']; + $from_name_tpl = $this->_parse_tags($from_name_tpl); + $from_name_tpl = $this->_parse_tag_fld_main($from_name_tpl); + $from_name_tpl = preg_replace_callback('/\[tag:fld:(\d+)]/', array($this,'_parse_tag_fld_post'),$from_name_tpl); + + // Email отправителя + $from_email_tpl = $form['mail_set']['from_email']; + $from_email_tpl = $this->_parse_tags($from_email_tpl); + $from_email_tpl = $this->_parse_tag_fld_main($from_email_tpl); + $from_email_tpl = preg_replace_callback('/\[tag:fld:(\d+)]/', array($this,'_parse_tag_fld_post'),$from_email_tpl); + + // Тема + $subject_tpl = $form['mail_set']['subject_tpl']; + $subject_tpl = $this->_parse_tags($subject_tpl); + $subject_tpl = $this->_parse_tag_fld_main($subject_tpl); + $subject_tpl = preg_replace_callback('/\[tag:fld:(\d+)]/', array($this,'_parse_tag_fld_post'),$subject_tpl); + + // выполняем код перед отправкой писем + eval(' ?>' . $this->form['code_beforesend'] . '_parse_tag_if($mail,'if_user',$if_user_open); + $this->_parse_tag_if($mail,'if_admin',$if_admin_open); + $this->_parse_tag_if($subject,'if_user',$if_user_open); + $this->_parse_tag_if($subject,'if_admin',$if_admin_open); + + // @fix для v1.0 beta <= 2: поддержка тега if_notuser + $this->_parse_tag_if($mail,'if_notuser',$if_admin_open); + $this->_parse_tag_if($subject,'if_notuser',$if_admin_open); + + $mail = trim($this->_eval2var(' ?>' . $mail . '_eval2var(' ?>' . $subject . 'Query(" + INSERT INTO " . PREFIX . "_module_forms_history + SET + form_id = '" . $fid . "', + email = '" . $history['email'] . "', + subject = '" . addslashes($subject) . "', + date = '" . time() . "', + dialog = '" . addslashes(serialize($history['dialog'])) . "', + postdata = '" . addslashes(serialize($_POST)) . "' + "); + + unset($history); + } + // иначе, отправляем письмо + else + { + $this->_parse_tag_if($from_name,'if_user',$if_user_open); + $this->_parse_tag_if($from_name,'if_admin',$if_admin_open); + $this->_parse_tag_if($from_email,'if_user',$if_user_open); + $this->_parse_tag_if($from_email,'if_admin',$if_admin_open); + + $from_name = $this->_eval2var('?>' . $from_name . '_eval2var('?>' . $from_email . '' . $this->form['code_onsend'] . '_parse_tags($form['finish_tpl']); + $tpl = $this->_eval2var(' ?>' . $tpl . 'form['ajax']['form']['is_sent'] = true; + $this->form['ajax']['form']['finish_tpl'] = $tpl; + + return $tpl; + } + } + + + /** + * Вывод истории + */ + function history_list ($fid) + { + global $AVE_DB, $AVE_Template; + $assign = array(); + $assign['fid'] = $fid; + $assign['form'] = $this->_form($fid,false); + + $limit = 50; + $start = get_current_page() * $limit - $limit; + $sql = $AVE_DB->Query(" + SELECT SQL_CALC_FOUND_ROWS * + FROM " . PREFIX . "_module_forms_history + WHERE form_id = '" . $fid . "' + ORDER BY date DESC + LIMIT " . $start . "," . $limit . " + "); + + $num = (int)$AVE_DB->Query("SELECT FOUND_ROWS()")->GetCell(); + $pages = @ceil($num / $limit); + + if ($num > $limit) + { + $page_nav = '{t}'; + $page_nav = get_pagination($pages, 'page', $page_nav); + $AVE_Template->assign('page_nav', $page_nav); + } + + while ($row = $sql->FetchAssocArray()) + { + unset($row['dialog']); + $assign['dialogs'][] = $row; + } + + $assign = $this->_stripslashes($assign); + $AVE_Template->assign($assign); + $AVE_Template->assign('content', $AVE_Template->fetch($this->tpl_dir . 'history.tpl')); + } + + /** + * Удаление выбранного e-mail + */ + function email_del ($hid) + { + global $AVE_DB, $AVE_Template; + + $AVE_DB->Query(" + DELETE FROM " . PREFIX . "_module_forms_history + WHERE id = '" . $hid . "' + "); + } + + /** + * Сохранение статуса диалога + */ + function dialog_status ($hid) + { + global $AVE_DB; + + if ($_REQUEST['status'] !== 'new') + { + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_forms_history + SET + status = '" . $_REQUEST['status'] . "' + WHERE id = '" . $hid . "' + "); + } + + if (empty($_REQUEST['ajax'])) + { + header('Location: index.php?do=modules&action=modedit&mod=forms&moduleaction=history_list&fid=' . $_REQUEST['fid'] . '&cp=' . SESSION); + exit; + } + } + + /** + * Вывод диалога + */ + function history_dialog ($hid) + { + global $AVE_DB, $AVE_Template; + $assign = array(); + + $assign['hid'] = $hid; + $history = $AVE_DB->Query(" + SELECT * + FROM " . PREFIX . "_module_forms_history + WHERE id = '" . $hid . "' + ")->FetchAssocArray(); + + $history['dialog'] = unserialize($history['dialog']); + $history = $this->_stripslashes($history); + $assign['fid'] = $history['form_id']; + $assign['form'] = $this->_form($history['form_id'],false); + + // меняем статус на прочитанное + if ($history['status'] === 'new') + { + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_forms_history + SET + status = 'viewed' + WHERE id = '" . $hid . "' + "); + } + + // обращение + $request_author = $AVE_DB->Query(" + SELECT Id AS user_id, user_name, firstname, lastname + FROM " . PREFIX . "_users + WHERE email = '" . $history['email'] . "' + ")->FetchAssocArray(); + + if (!empty($request_author)) + $history['dialog']['request'] = array_merge($history['dialog']['request'], $request_author); + +// ответы +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($history['dialog']['response_draft'])) + { + $history['dialog']['response_draft'] = array( + 'from_email' => get_settings('mail_from'), + 'from_name' => get_settings('mail_from_name'), + 'body' => "\r\n\r\n\r\n--\r\n" . get_settings('mail_signature'), + ); + } + + // алерт при открытии $fid -> $hid + if (!empty($_SESSION['module_forms_admin'][$hid]['dialog_alert'])) + { + $assign['alert']['text'] = $AVE_Template->get_config_vars($_SESSION['module_forms_admin'][$hid]['dialog_alert']['text']); + $assign['alert']['theme'] = $_SESSION['module_forms_admin'][$hid]['dialog_alert']['theme']; + unset($_SESSION['module_forms_admin'][$hid]['dialog_alert']); + } + + $AVE_Template->assign($assign); + $AVE_Template->assign($history); + $AVE_Template->assign('content', $AVE_Template->fetch($this->tpl_dir . 'dialog.tpl')); + } + + /** + * Сохранение и отправка ответа + */ + function history_dialog_submit ($hid) + { + global $AVE_DB; + + $history = $AVE_DB->Query(" + SELECT * + FROM " . PREFIX . "_module_forms_history + WHERE id = '" . $hid . "' + ")->FetchAssocArray(); + $history['dialog'] = unserialize($history['dialog']); + + if ($_REQUEST['send']) + { + $response = $_POST; + $response['user_id'] = UID; + $response['date'] = time(); + $history['dialog']['response'][] = $response; + $history['status'] = 'replied'; + unset($history['dialog']['response_draft']); + send_mail( + $history['email'], + $_POST['body'], + $_POST['subject'], + $_POST['from_email'], + $_POST['from_name'], + $_POST['format'], + array(), + false,false + ); + } + else + { + $history['dialog']['response_draft'] = $_POST; + } + + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_forms_history + SET + dialog = '" . addslashes(serialize($history['dialog'])) . "', + status = '" . $history['status'] . "' + WHERE id = '" . $hid . "' + "); + + if ($_REQUEST['send']) + { + // прописываем алерт об успешной отправке письма $fid -> $hid + $_SESSION['module_forms_admin'][$hid]['dialog_alert'] = array('text' => 'respose_sent', 'theme' => 'accept'); + + header('Location: index.php?do=modules&action=modedit&mod=forms&moduleaction=history_dialog&hid=' . $hid . '&cp=' . SESSION); + exit; + } + } + } +?> \ No newline at end of file diff --git a/demo.php b/demo.php new file mode 100644 index 0000000..808ee79 --- /dev/null +++ b/demo.php @@ -0,0 +1,478 @@ + +'[tag:hide:2:У вас нет прав для заполнения данной формы!] +
+
+ [tag:if_form_invalid] +
+ При заполнении формы возникли ошибки! + +
+ [/tag:if_form_invalid] + [tag:fld:email] + [tag:fld:subject] + [tag:fld:receivers] + [tag:fld:6] + [tag:fld:7] + [tag:fld:8] + [tag:fld:9] + [tag:fld:10] + [tag:fld:11] + [tag:fld:copy] + [tag:fld:captcha] +
+
+ +
+
+
+ + [tag:if_form_invalid] + + [/tag:if_form_invalid] +
+[/tag:hide]', +'ajax' => '[tag:hide:2:У вас нет прав для заполнения данной формы!] +
+
+ Если форма не работает, убедитесь, что скрипт jquery.form.min.js подключен к странице + +
+ [tag:if_form_invalid] +
+ При заполнении формы возникли ошибки! + +
+ [/tag:if_form_invalid] + [tag:fld:email] + [tag:fld:subject] + [tag:fld:receivers] + [tag:fld:6] + [tag:fld:7] + [tag:fld:8] + [tag:fld:9] + [tag:fld:10] + [tag:fld:11] + [tag:fld:copy] + [tag:fld:captcha] +
+
+ +
+
+
+ +[/tag:hide]', +'ajax_o' => +'[tag:hide:2:У вас нет прав для заполнения данной формы!] +
+
+
+ Если форма не работает, убедитесь, что скрипт jquery.form.min.js подключен к странице + +
+ [tag:if_form_invalid] +
+ При заполнении формы возникли ошибки! + +
+ [/tag:if_form_invalid] + [tag:fld:email] + [tag:fld:subject] + [tag:fld:receivers] + [tag:fld:6] + [tag:fld:7] + [tag:fld:8] + [tag:fld:9] + [tag:fld:10] + [tag:fld:11] + [tag:fld:copy] +
+
+ +
+
+
+ +
+[/tag:hide]' +); + +$demo = array( + 'mail_set' => array( + 'from_name' => '[tag:if_user]Администратор сайта [tag:sitename][/tag:if_user] +[tag:if_admin][tag:uname] ([tag:ulogin])[/tag:if_admin]', + 'from_email' => '[tag:if_user]admin@form.ru[/tag:if_user] +[tag:if_admin][tag:fld:email][/tag:if_admin]', + 'subject_tpl' => '[tag:if_user]Вы заполнили форму "[tag:fld:subject]" на сайте [tag:sitename][/tag:if_user] +[tag:if_admin]Заполнена форма: [tag:formtitle] ([tag:formalias])[/tag:if_admin]', + 'receivers' => array( + array( + 'email' => 'form@form.ru', + 'name' => 'form' + ) + ), + 'format' => 'text', + ), + 'rubheader' => '', + 'form_tpl' => $form_tpl[$_REQUEST['demo']], + 'mail_tpl' => '[tag:if_user] +Здравствуйте, [tag:uname]! + +Вы заполнили форму на нашем сайте и ввели следующие данные: + +[tag:easymail] + +В ближайшее время администрация рассмотрит вашу заявку +-- +С уважением, Администрация +[/tag:if_user] + +[tag:if_admin] +Здравствуйте! + +Пользователь [tag:uname] ([tag:ulogin]) заполнил форму \\\'[tag:formtitle]\\\' ([tag:formalias]) и ожидает ответа. + +Введённые данные: +[tag:easymail] +[/tag:if_admin]', + 'finish_tpl' => '
+ Форма успешно отправлена! +
', + 'code_onsubmit' => '', + 'code_onvalidate' => '', + 'code_onsend' => '', + 'fields' => array( + 1 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'email', + 'active' => 1, + 'type' => 'input', + 'main' => 1, + 'setting' => 'FILTER_VALIDATE_EMAIL', + 'required' => 1, + 'defaultval' => '[tag:uemail]', + 'attributes' => 'id="fld[[tag:id]]" class="form-control [tag:if_invalid]invalid[/tag:if_invalid]" placeholder="[tag:title]" data-placement="right" data-content="Неверный email!" data-container="body" data-trigger="manual"', + 'tpl' => '
+ +
+ [tag:fld] + [tag:if_valid][/tag:if_valid] + [tag:if_invalid][/tag:if_invalid] +
+
' + ), + 2 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'subject', + 'active' => 1, + 'type' => 'input', + 'main' => 1, + 'setting' => '', + 'required' => 1, + 'defaultval' => 'Тема по умолчанию', + 'attributes' => 'id="fld[[tag:id]]" class="form-control [tag:if_empty]invalid[/tag:if_empty]" placeholder="[tag:title]" data-placement="right" data-content="Укажите тему!" data-container="body" data-trigger="manual"', + 'tpl' => '
+ +
+ [tag:fld] + [tag:if_notempty][/tag:if_notempty] + [tag:if_empty][/tag:if_empty] +
+
' + ), + 3 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'receivers', + 'active' => 1, + 'type' => 'select', + 'main' => 1, + 'setting' => array( + 0 => array( + 'email' => 'sales@form.ru', + 'name' => 'Отдел продаж' + ), + 1 => array( + 'email' => 'support@form.ru', + 'name' => 'Служба поддержки' + ) + ), + 'required' => 0, + 'defaultval' => 0, + 'attributes' => 'id="fld[[tag:id]]" class="form-control" placeholder="[tag:title]"', + 'tpl' => '
+ +
+ [tag:fld] +
+
' + ), + 4 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'copy', + 'active' => 1, + 'type' => 'checkbox', + 'main' => 1, + 'setting' => '', + 'required' => 0, + 'defaultval' => 1, + 'attributes' => '', + 'tpl' => '
+
+
+ +
+
+
' + ), + 5 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'captcha', + 'active' => 1, + 'type' => 'input', + 'main' => 1, + 'setting' => '', + 'required' => 1, + 'defaultval' => '', + 'attributes' => 'id="fld[[tag:id]]" class="form-control [tag:if_invalid]invalid[/tag:if_invalid]" placeholder="Введите защитный код" data-placement="right" data-content="Неверный код!" data-container="body" autocomplete="off" data-trigger="manual"', + 'tpl' => '
+
+
+ + Капча
+
+
+ +
+
+ [tag:fld] + [tag:if_invalid] + [/tag:if_invalid] +
+
+
' + ), + 6 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'Выбор', + 'active' => 1, + 'type' => 'select', + 'main' => 0, + 'setting' => array('выберите','а','б','в'), + 'required' => 1, + 'defaultval' => 0, + 'attributes' => 'id="fld[[tag:id]]" class="form-control [tag:if_empty]invalid[/tag:if_empty]" placeholder="[tag:title]" data-placement="right" data-content="Выберите что-нибудь!" data-container="body" data-trigger="manual"', + 'tpl' => '
+ +
+ [tag:fld] +
+
' + ), + 7 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'Текстовое поле', + 'active' => 1, + 'type' => 'textarea', + 'main' => 0, + 'setting' => '', + 'required' => 0, + 'defaultval' => '', + 'attributes' => 'id="fld[[tag:id]]" class="form-control" placeholder="[tag:title]"', + 'tpl' => '
+ +
+ [tag:fld] + [tag:if_notempty][/tag:if_notempty] + [tag:if_empty][/tag:if_empty] +
+
' + ), + 8 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'Мульти', + 'active' => 1, + 'type' => 'multiselect', + 'main' => 0, + 'setting' => array(1,2,3,4,5), + 'required' => 1, + 'defaultval' => array(0,3), + 'attributes' => 'id="fld[[tag:id]]" class="form-control [tag:if_empty]invalid[/tag:if_empty]" placeholder="[tag:title]" data-placement="right" data-content="Выберите что-нибудь!" data-container="body" data-trigger="manual"', + 'tpl' => '
+ +
+ [tag:fld] +
+
' + ), + 9 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'Файл (до 1мб)', + 'active' => 1, + 'type' => 'file', + 'main' => 0, + 'setting' => 1, + 'required' => 0, + 'defaultval' => '', + 'attributes' => 'id="fld[[tag:id]]" class="form-control [tag:if_invalid]invalid[/tag:if_invalid] [tag:if_empty]invalid[/tag:if_empty]" placeholder="[tag:title]" data-placement="right" data-content="[tag:if_invalid]Слишком большой файл![/tag:if_invalid][tag:if_empty]Отсутствует файл![/tag:if_empty]" data-container="body" data-trigger="manual"', + 'tpl' => '
+ +
+ [tag:fld] + [tag:if_notempty][tag:if_valid][/tag:if_valid][/tag:if_notempty] + [tag:if_invalid][/tag:if_invalid] + [tag:if_empty][/tag:if_empty] +
+
' + ), + 10 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'Документ', + 'active' => 1, + 'type' => 'doc', + 'main' => 0, + 'setting' => array(1), + 'required' => 0, + 'defaultval' => '', + 'attributes' => 'id="fld[[tag:id]]" class="form-control [tag:if_empty]invalid[/tag:if_empty]" placeholder="[tag:title]"', + 'tpl' => '
+ +
+ [tag:fld] +
+
' + ), + 11 => array( + 'new' => true, + 'form_id' => $fid, + 'title' => 'Мультидокумент', + 'active' => 1, + 'type' => 'multidoc', + 'main' => 0, + 'setting' => array(1,2), + 'required' => 0, + 'defaultval' => '', + 'attributes' => 'id="fld[[tag:id]]" class="form-control [tag:if_empty]invalid[/tag:if_empty]" placeholder="[tag:title]"', + 'tpl' => '
+ +
+ [tag:fld] +
+
' + ) + ) +); \ No newline at end of file diff --git a/images/ref.png b/images/ref.png new file mode 100644 index 0000000..bdcd6be Binary files /dev/null and b/images/ref.png differ diff --git a/index.php b/index.php new file mode 100644 index 0000000..046ab72 --- /dev/null +++ b/index.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/info.php b/info.php new file mode 100644 index 0000000..f9f9ae2 --- /dev/null +++ b/info.php @@ -0,0 +1,19 @@ + 'forms', + 'ModuleVersion' => '3.31', + 'ModuleAutor' => 'AVE.cms Team & Repellent', + 'ModuleCopyright' => '© 20026-' . date('Y') . ' AVE4CMS.RU', + 'ModuleIsFunction' => 1, + 'ModuleTemplate' => 0, + 'ModuleAdminEdit' => 1, + 'ModuleFunction' => 'mod_forms', + 'ModuleTag' => '[mod_forms:alias/id:email]', + 'ModuleTagLink' => null, + 'ModuleAveTag' => '#\\\[mod_forms:([A-Za-z0-9-_]{1,20})\\\]#', + 'ModulePHPTag' => "" + ); +?> \ No newline at end of file diff --git a/lang/bg.txt b/lang/bg.txt new file mode 100644 index 0000000..5aaecaa --- /dev/null +++ b/lang/bg.txt @@ -0,0 +1,192 @@ +[name] +MODULE_NAME = "Формы" +MODULE_DESCRIPTION = "Данный модуль предназначен для создания веб-форм (например, обратной связи или простейшего оформления заказа), которые могут состоять из любого набора полей. Для вывода в публичной части сайта используйте тег [mod_forms:XXX], где XXX - это id или алиас формы." + +[module] +contacts = "Контакти New" +mod_info = "В дадения раздел са всички контактни форми в системата. тук Вие може да добавите нова контактна форма. както и да редактирате вече съществуващи." +forms = "Списък форми" +form = "Форма" +noforms = "В модула няма добавени форми" +form_new = "Добавяне на форма" +form_deleting = "Сигурни ли сте, че желаете да изтриете формата?" + +form_creating = "Добавяне на нова форма" +form_notfound = "тази форма не е намерена" +form_editing = "Редактиране на форма" +main_sets = "Основни параметри" +title = "Наименование" +alias = "Алиас" +protection = "Защита от повторно изпращане" +protect_i = "Препоръчително за форми без Ajax.<br/><br/>Ако защитата е включена, на финалната страница (след успешното изпращане на формата) при обновяванто на страницата потребителя няма да види съобщението "Подтвърдете повторното изпращане на данните...". Вместо това ще се зареди наново празна форма." +demo = "Създаване на примерна форма" +demo_noajax = "без Ajax" +demo_ajax = "Ajax, сървъра връща кода на формата" +demo_ajax_o = "Ajax, сървъра връща резултатът от валидацията" +alias_i = "Опционално. Алиасът на формата позволява да се използва леко запомнящ се таг [mod_contact:alias] вместо [mod_contact:id]. Алиасът не трябва да бъде число, може да съдържа само цифри, латински букви, долна черта и дължина не повече от 20 символа и да е уникално в пределите на модула" +alias_accept = "Този алиас може да се използва" +alias_er_syn = "Грешен алиас!
Алиасът не може да бъде число, може да съдържа само цифри, латински букви, долна черта и дължина не повече от 20 символа" +alias_er_exists = "Грешен алиас!
Този алиас вече е зададен на друга контактна форма" +recs = "Получатели" +name = "Име" +fields_sets = "Настройки на полетата" +active_i = "Активиране на поле (ако чекбокса е празен, тагът в шаблона ще бъде заменен с празен ред)" +type = "Тип" +doc = "Документ" +multidoc = "Документ (multi)" +other_input = "Друг input" +other_input_i = "Атрибут type" +pattern_i = "Шаблон за preg_match
Пример: /^[A-Za-z0-9]+$/ie

Или филтър за filter_var
Пример: FILTER_VALIDATE_EMAIL" +pattern = "Валидация" +defaultval = "По подразбиране" +sets = "Параметри" +attributes = "Атрибути на тега поле" +field_add = "Добави поле" +form_tpl = "Шаблон на формата" +mail_tpl = "Шаблон на писмо" +finish_tpl = "Шаблон на страница след изпращане на формата" +conditions = "Условия" +rubheader = "Скриптове и стилове, необходими за оформяне и функциониране на формата" +rubheader_info = "Избягвайте дублиране на скриптовете в модула и шаблона" +tag = "Таг" +field_creating = "Добавяне на поле..." +field_new_error = "Моля, въведете наименование на полето!" +type_i = "За input в атрибутите може да се укаже свой type (по подразбиране се поставя text)" +fld_tpl_toggle = "Покажи/скрий шаблона за извеждане на полето" +field_tpl = "Шаблон на полето" +fld_del = "Сигурни ли сте, че желаете да изтриете това поле?" +fld_deleting = "Изтриване на поле..." +required = "Задължително поле" +setting_empty = "Първо настройте опциите за избор (вляво)" +yes = "да" +no = "не" +fld_i = "Полето работи само ако тагът в поставен в шаблон и вляво е маркирано полето активация" +copy_fld_i = "Отправка копии будет выполнена, даже если в значении по умолчанию стоит галка, а тег в шаблон не вставлен / поле не активировано" +select_req_i = "Селект будет считаться не заполненным, если выбран первый вариант" +file_size = "Макс. размер, мб" +file_size2 = "Ограничение на размера на файла, мб" + +create = "Добави" +edit = "Редактиране" +copy = "Копиране" +delete = "Изтриване" +actions = "Действия" +saved = "Съхранено" +notsaved = "Възникна грешка по време на съхранението" +created = "Формата е успешно записана" +copied = "Формата е успешно копирана и записана
Моля, редактирайте наименованието и алиаса" +deleting = "Изтриване..." +add_refresh = "Добави и обнови" +save = "Запиши" +return_to_forms = "Върни се към списъка с контактни форми" +refresh = "Обнови" +mail_set = "Настройки на писмата" +format = "Формат" +text = "Текст" +from_email = "Имейл на изпращача" +from_name = "Име на изпращача" +recs_main = "Главни получатели" +recs_main_i = "Тези адресати ще получават писмото задължително" +subject_tpl = "Шаблон на темата" + +email_accept = "Правилен имейл" +email_error = "Грешен синтаксис на имейл!" + +tag_fld = "Таг за поле, полето се поставя с използване на своя шаблон" +tag_fld_mail = "Значение на полето, въведено от потребителя" +tag_fld_tpl = "Таг за поле, полето се поставя с атрибутите си" +tag_attr = "Вмъкни основни атрибити" +tag_id = "Id на полето" +tag_title = "Таг за наименование на поле" +tag_valid = "Извеждано съдържание, ако полето съответства на зададения шаблон" +tag_invalid = "Извеждано съдържание, ако полето не съответства на зададения шаблон" +tag_nempty = "Извеждано съдържание, ако полето е маркирано като задължително и потребителя е въвел данни" +tag_empty = "Извеждано съдържание, ако полето е маркирано като задължително и потребителя не е въвел данни" +tag_path = "Път към корена на инсталацията" +tag_media = "Път към папката с шаблона

Пример: [tag:mediapath]images/logo.gif" +tag_css = "Свива няколко css-файла в един. Връща път.
FFF - имена на файлове, разделени с запетая
P - път към папката с файлове, назадължителен. По подразбиране - [tag:mediapath]css/

Пример: href="[tag:css:reset.css,style.css]"" +tag_js = "Свива няколко js-файла в един. Връща път.
FFF - имена на файлове, разделени с запетая
P - път към папката с файлове, назадължителен. По подразбиране - [tag:mediapath]js/

Пример: href="[tag:js:common.js,main.js]"" +tag_formtitle = "Наименование на формата" +tag_formalias = "Алиас на формата (или id, ако не е въведен алиас)" +tag_url = "URL на текущата страница" +tag_docid = "ID на текущия документ" +tag_hide = "Таг, позволяващ скрит контент за определени групи потребители

Х - номер на групата
TEXT - текст, ако достъпа е забранен

Пример: [tag:hide:2:Тази форма не е за вас!][/tag:hide]" +tag_uemail = "Имейл на потребителя (въз основата на данните от профила, а не на формата!)" +tag_uname = "Име и Фамилия на потребителя (въз основа на данните от профила)" +tag_ufname = "Име на потребителя (въз основа на данните от профила)" +tag_ulname = "Фамилия на потребителя (въз основа на данните от профила)" +tag_ulogin = "Потребителско име (въз основа на данните от профила)" +tag_if_fld = "Условие за значението на полето. В тага, използвайте стандартните конструкции за сравнение на PHP/JS

Пример:
[tag:if_fld:15 == '1']
...
[tag:elseif_fld:15 > '2']
...
[tag:else_fld]
...
[/tag:if_fld]" +tag_f_valid = "Извеждано съдържание, ако всички полета са преминали валидацията" +tag_f_invalid = "Извеждано съдържание, ако поне едно поле не преминало валидацията" +tag_easymail = "Генерива списък на всички значения на полетата, участващи в шаблона на формата ( вместо ръчно да се описват всички тагове)" +tag_if_user = "Извежда съдържанието в писмото на потребителя, попълнил формата" +tag_if_admin = "Извежда съдържанието в писмото за получателя-админ ("главен получател" или получател от поле "избор на получателр")" +tag_fld_subject = "Значение на полето Тема" +tag_fld_email = "Значение на полето Имейл" +tag_sitename = "Наименование на сайта" +tag_sitehost = "Адрес на сайта" +info_php_tags = "Достъпни php и тагове" + +code = "Изпълним код" +code_info = "Данните на формата (валидация, шаблони, получатели и т.д.) се пазят е променливата на класа $this->form." +code_onsubmit = "Код, изпълняван след изпращането на формата (преди валидацията)" +code_onvalidate = "Код, изпълняван след валидацията на формата" +code_onsend = "Код, изпълняван след изпращането на писмата" + +mfld_email = "Имейл" +mfld_subject = "Тема" +mfld_receivers = "Избор на получатели" +mfld_captcha = "Капча" +mfld_copy = "Изпращане на копие" + +tag_mail_empty = "не е попълнено" + +history = "История" +date = "Дата" +author = "Автор" +status = "Статус" +stat_new = "Ново" +list_new = "Нови" +stat_viewed = "Видяно" +list_viewed = "Видени" +stat_replied = "Отговорено" +list_replied = "Отговорени" +request = "Обръщение" +response = "Отговор" +responses = "Отговори" +write_response = "Напиши отговор" +body = "Тяло на писмото" +save_draft = "Запази черновата" +send = "Изпрати отговор" +return_dialogs = "Върни се към списъка" +profile_look = "Премини към профила" +write_email = "Напиши писмо" +from = "от" +look = "Преглед" +set_replied = "Маркирай като отговорено" +marked_replied = "Маркирано като отговорено" +attach = "Прикачени" + +respose_sent = "Отговорът е успешно изпратен" + +cn_actions = "Действия" +cn_del_mail = "Сигурни ли сте, че желаете да изтриете този e-mail?" +cn_not_mail = "В тази форма няма писма ..." +cn_view = "Преглед на историята" +cn_status = "Статус на писмата" +cn_alias_not = " -- " +cn_count_messages = "писма: " +cn_copy_to_clipboard = "Копирай в буфера" +cn_return_list_form = "Връщане към списъка" +cn_mod_info = "Важно: модулът използва метода за изпращане на писма, установен в системните настройки " +cn_mod_info_a = "Настройки поща" +info_attr_name = "Значение атрибута name для этого поля:" +public_key_recaptcha_v3 = "Публичный ключ reCAPTCHA v3" +title_pub_key_recap = "Открытый ключ reCAPTCHA v3 указанный в системных настройках, используется на стороне клиента (например в js скриптах)" +found_key_recap_v3 = "В системных настройках обнаружены и будут использоваться модулем API ключи reCAPTCHA v3" +notfound_key_recap_v3_1 ="API ключи reCAPTCHA v3 не обнаружены." +notfound_key_recap_v3_2 =" Вы можете установить их в разделе " +notfound_key_recap_v3_3 ="Системные настройки" +demo_jqval_cap = "Без Ajax, с jQuery Validation Plugin и reCAPTCHA v3" +demo_ajax_jqval_cap = "Ajax, с jQuery Validation Plugin и reCAPTCHA v3" \ No newline at end of file diff --git a/lang/en.txt b/lang/en.txt new file mode 100644 index 0000000..3f517b2 --- /dev/null +++ b/lang/en.txt @@ -0,0 +1,192 @@ +[name] +MODULE_NAME = "Формы" +MODULE_DESCRIPTION = "Данный модуль предназначен для создания веб-форм (например, обратной связи или простейшего оформления заказа), которые могут состоять из любого набора полей. Для вывода в публичной части сайта используйте тег [mod_forms:XXX], где XXX - это id или алиас формы." + +[module] +contacts = "Контакты New" +mod_info = "В данном разделе приведен список всех контактных форм. Вы можете, добавить новую форму или отредактировать существующую." +forms = "Список форм" +form = "Форма" +noforms = "В модуле пока нет ни одной контактной формы" +form_new = "Создать форму" +form_deleting = "Вы уверены, что хотите удалить форму?" + +form_creating = "Создание новой формы" +form_notfound = "указанная форма не найдена" +form_editing = "Редактирование формы" +main_sets = "Основные параметры" +title = "Название" +alias = "Алиас" +protection = "Защита от повторной отправки" +protect_i = "Рекомендуется включать для форм без Ajax.<br/><br/>Если защита включена, на финишной странице (после успешной отправки формы) при обновлении страницы пользователь не увидит сообщения "Подтвердите повторную отправку данных...". Вместо этого загрузится заново чистая форма." +demo = "Создать пример формы" +demo_noajax = "без Ajax" +demo_ajax = "Ajax, сервер возвращает код формы" +demo_ajax_o = "Ajax, сервер возвращает результат валидации" +alias_i = "Опционально. Алиас формы позволяет использовать легко запоминающийся тег [mod_contact:alias] вместо [mod_contact:id]. Алиас не должен являться числом, может содержать только цифры, латинские буквы, дефис, подчёркивание, иметь длину не более 20 символов и быть уникальным в пределах модуля" +alias_accept = "Этот алиас можно использовать" +alias_er_syn = "Неверный алиас!
Алиас не должен являться числом, может содержать только цифры, латинские буквы, дефис, подчёркивание и иметь длину не более 20 символов" +alias_er_exists = "Неверный алиас!
Данный алиас уже привязан к другой контактной форме" +recs = "Получатели" +name = "Имя" +fields_sets = "Настройки полей" +active_i = "Активировать поле (если чекбокс пустой, тег в шаблоне будет заменён на пустую строку)" +type = "Тип" +doc = "Документ" +multidoc = "Документ (multi)" +other_input = "Другой input" +other_input_i = "Аттрибут type" +pattern_i = "Шаблон для preg_match
Пример: /^[A-Za-z0-9]+$/ie

Либо фильтр для filter_var
Пример: FILTER_VALIDATE_EMAIL" +pattern = "Валидация" +defaultval = "По умолчанию" +sets = "Параметры" +attributes = "Аттрибуты тега поля" +field_add = "Добавить поле" +form_tpl = "Шаблон формы" +mail_tpl = "Шаблон письма" +finish_tpl = "Шаблон страницы после отправки формы" +conditions = "Условия" +rubheader = "Скрипты и стили, необходимые для оформления и функционирования формы" +rubheader_info = "Избегайте дублирования скриптов в модуле и шаблоне" +tag = "Тег" +field_creating = "Добавление поля..." +field_new_error = "Укажите название поля!" +type_i = "Для input в аттрибутах можно указать свой type (по умолчанию подставится text)" +fld_tpl_toggle = "Показать/свернуть шаблон вывода поля" +field_tpl = "Шаблон поля" +fld_del = "Вы уверены, что хотите удалить это поле?" +fld_deleting = "Удаление поля..." +required = "Обязательное поле" +setting_empty = "Сначала настройте опции для выбора (слева)" +yes = "да" +no = "нет" +fld_i = "Поле работает только если его тег вставлен в шаблон и слева стоит галочка активации" +copy_fld_i = "Отправка копии будет выполнена, даже если в значении по умолчанию стоит галка, а тег в шаблон не вставлен / поле не активировано" +select_req_i = "Селект будет считаться не заполненным, если выбран первый вариант" +file_size = "Макс. размер, мб" +file_size2 = "Ограничение размера файла, мб" + +create = "Создать" +edit = "Редактировать" +copy = "Копировать" +delete = "Удалить" +actions = "Действия" +saved = "Сохранено" +notsaved = "Во время сохранения произошла ошибка" +created = "Форма успешно создана" +copied = "Форма успешно скопирована и сохранена
Отредактируйте название и алиас" +deleting = "Удаление..." +add_refresh = "Добавить и обновить" +save = "Сохранить" +return_to_forms = "Вернуться к списку контактных форм" +refresh = "Обновить" +mail_set = "Настройки письма" +format = "Формат" +text = "Текст" +from_email = "Email отправителя" +from_name = "Имя отправителя" +recs_main = "Главные получатели" +recs_main_i = "Эти адресаты получат письмо в любом случае" +subject_tpl = "Шаблон темы" + +email_accept = "Правильный Email" +email_error = "Неверный синтаксис Email-а!" + +tag_fld = "Тег поля, поле подставляется с использованием своего шаблона" +tag_fld_mail = "Значение поля, введённое пользователем" +tag_fld_tpl = "Тег поля, поле подставляется с подстановкой аттрибутов" +tag_attr = "Вставить основные аттрибуты" +tag_id = "Id поля" +tag_title = "Тег названия поля" +tag_valid = "Выведет контент, если поле соответствует заданному шаблону" +tag_invalid = "Выведет контент, если поле не соответствует заданному шаблону" +tag_nempty = "Выведет контент, если поле помечено как обязательное и пользователь ввёл данные" +tag_empty = "Выведет контент, если поле помечено как обязательное и пользователь не ввёл данные" +tag_path = "Корневой путь установки" +tag_media = "Путь до папки с шаблоном

Пример: [tag:mediapath]images/logo.gif" +tag_css = "Сжимает несколько css-файлов в один. Возвращает путь.
FFF - имена файлов через запятую
P - путь к папке с файлами, не обязательно. По умолчанию - [tag:mediapath]css/

Пример: href="[tag:css:reset.css,style.css]"" +tag_js = "Сжимает несколько js-файлов в один. Возвращает путь.
FFF - имена файлов через запятую
P - путь к папке с файлами, не обязательно. По умолчанию - [tag:mediapath]js/

Пример: href="[tag:js:common.js,main.js]"" +tag_formtitle = "Название формы" +tag_formalias = "Алиас формы (или id, если алиас не назначен)" +tag_url = "URL текущей страницы" +tag_docid = "ID текущего документа" +tag_hide = "Тег, позволяющий скрыть контент для определенных групп пользователей

Х - номер группы
TEXT - текст, если доступ запрещён

Пример: [tag:hide:2:Эта форма не для вас!][/tag:hide]" +tag_uemail = "Email пользователя (на основе данных из профиля, а не формы!)" +tag_uname = "И. Фамилия пользователя (на основе данных из профиля)" +tag_ufname = "Имя пользователя (на основе данных из профиля)" +tag_ulname = "Фамилия пользователя (на основе данных из профиля)" +tag_ulogin = "Логин пользователя (на основе данных из профиля)" +tag_if_fld = "Условие на значение поля. В теге используйте стандартные конструкции сравнения PHP/JS

Пример:
[tag:if_fld:15 == '1']
...
[tag:elseif_fld:15 > '2']
...
[tag:else_fld]
...
[/tag:if_fld]" +tag_f_valid = "Выведет контент, если все поля формы прошли валидацию" +tag_f_invalid = "Выведет контент, если хотя бы одно поле формы не прошло валидацию" +tag_easymail = "Быстро генерирует список всех значений полей, участвующих в шаблоне формы (вместо того, чтобы прописывать все теги вручную)" +tag_if_user = "Выведет контент в письме пользователю, заполнившему форму" +tag_if_admin = "Выведет контент в письме получателям-админам ("главным получателям" или адресату из поля "получатель на выбор")" +tag_fld_subject = "Значение поля Тема" +tag_fld_email = "Значение поля Email" +tag_sitename = "Название сайта" +tag_sitehost = "Адрес сайта" +info_php_tags = "Доступен php и теги" + +code = "Исполняемый код" +code_info = "Данные формы (валидация, шаблоны, получатели и т.д.) хранятся в переменной класса $this->form." +code_onsubmit = "Код, исполняемый сразу после отправки формы (до валидации)" +code_onvalidate = "Код, исполняемый после валидации формы" +code_onsend = "Код, исполняемый после отправки писем" + +mfld_email = "Email" +mfld_subject = "Тема" +mfld_receivers = "Получатель на выбор" +mfld_captcha = "Капча" +mfld_copy = "Отправка копии" + +tag_mail_empty = "не заполнено" + +history = "История" +date = "Дата" +author = "Автор" +status = "Статус" +stat_new = "Новое" +list_new = "Новых" +stat_viewed = "Просмотрено" +list_viewed = "Просмотренных" +stat_replied = "Отвечено" +list_replied = "Отвеченных" +request = "Обращение" +response = "Ответ" +responses = "Ответы" +write_response = "Написать ответ" +body = "Тело письма" +save_draft = "Сохранить черновик" +send = "Отправить ответ" +return_dialogs = "Вернуться к списку обращений" +profile_look = "Перейти к профилю" +write_email = "Написать письмо" +from = "от" +look = "Посмотреть" +set_replied = "Пометить как отвеченное" +marked_replied = "Было отмечено как отвеченное" +attach = "Вложения" + +respose_sent = "Ответ успешно отправлен" + +cn_actions = "Действия" +cn_del_mail = "Вы уверены, что хотите удалить этот e-mail?" +cn_not_mail = "В этой форме нет писем..." +cn_view = "Просмотр истории" +cn_status = "Статус сообщений" +cn_alias_not = " -- " +cn_count_messages = "сообщений: " +cn_copy_to_clipboard = "Скопировать в буфер обмена" +cn_return_list_form = "Вернуться к списку форм" +cn_mod_info = "Важно: модуль использует метод отправки почты установленный в системных настройках, в разделе " +cn_mod_info_a = "Настройки почты." +info_attr_name = "Значение атрибута name для этого поля:" +public_key_recaptcha_v3 = "Публичный ключ reCAPTCHA v3" +title_pub_key_recap = "Открытый ключ reCAPTCHA v3 указанный в системных настройках, используется на стороне клиента (например в js скриптах)" +found_key_recap_v3 = "В системных настройках обнаружены и будут использоваться модулем API ключи reCAPTCHA v3" +notfound_key_recap_v3_1 ="API ключи reCAPTCHA v3 не обнаружены." +notfound_key_recap_v3_2 =" Вы можете установить их в разделе " +notfound_key_recap_v3_3 ="Системные настройки" +demo_jqval_cap = "Без Ajax, с jQuery Validation Plugin и reCAPTCHA v3" +demo_ajax_jqval_cap = "Ajax, с jQuery Validation Plugin и reCAPTCHA v3" \ No newline at end of file diff --git a/lang/index.php b/lang/index.php new file mode 100644 index 0000000..9c20174 --- /dev/null +++ b/lang/index.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/lang/ru.txt b/lang/ru.txt new file mode 100644 index 0000000..da78114 --- /dev/null +++ b/lang/ru.txt @@ -0,0 +1,195 @@ + +MODULE_NAME = "Формы" +MODULE_DESCRIPTION = "Данный модуль предназначен для создания веб-форм (например, обратной связи или простейшего оформления заказа), которые могут состоять из любого набора полей. Для вывода в публичной части сайта используйте тег [mod_forms:XXX], где XXX - это id или алиас формы." + + +contacts = "Формы" +mod_info = "В данном разделе приведен список всех форм. Вы можете, добавить новую форму или отредактировать существующую." +forms = "Список форм" +form = "Форма" +noforms = "В модуле пока нет ни одной формы" +form_new = "Создать форму" +form_deleting = "Вы уверены, что хотите удалить форму?" + +form_creating = "Создание новой формы" +form_notfound = "указанная форма не найдена" +form_editing = "Редактирование формы" +main_sets = "Основные параметры" +title = "Название" +alias = "Алиас" +protection = "Защита от повторной отправки" +protect_i = "Рекомендуется включать для форм без Ajax.<br/><br/>Если защита включена, на финишной странице (после успешной отправки формы) при обновлении страницы пользователь не увидит сообщения "Подтвердите повторную отправку данных...". Вместо этого загрузится заново чистая форма." +demo = "Создать пример формы" +demo_noajax = "без Ajax" +demo_ajax = "Ajax, сервер возвращает код формы" +demo_ajax_o = "Ajax, сервер возвращает результат валидации" +alias_i = "Опционально. Алиас формы позволяет использовать легко запоминающийся тег [mod_forms:alias] вместо [mod_forms:id]. Алиас не должен являться числом, может содержать только цифры, латинские буквы, дефис, подчёркивание, иметь длину не более 20 символов и быть уникальным в пределах модуля" +alias_accept = "Этот алиас можно использовать" +alias_er_syn = "Неверный алиас!
Алиас не должен являться числом, может содержать только цифры, латинские буквы, дефис, подчёркивание и иметь длину не более 20 символов" +alias_er_exists = "Неверный алиас!
Данный алиас уже привязан к другой форме" +recs = "Получатели" +name = "Имя" +fields_sets = "Настройки полей" +active_i = "Активировать поле (если чекбокс пустой, тег в шаблоне будет заменён на пустую строку)" +type = "Тип" +doc = "Документ" +multidoc = "Документ (multi)" +other_input = "Другой input" +other_input_i = "Аттрибут type" +pattern_i = "Шаблон для preg_match
Пример: /^[A-Za-z0-9]+$/ie

Либо фильтр для filter_var
Пример: FILTER_VALIDATE_EMAIL" +pattern = "Валидация" +defaultval = "По умолчанию" +sets = "Параметры" +attributes = "Аттрибуты тега поля" +field_add = "Добавить поле" +form_tpl = "Шаблон формы" +mail_tpl = "Шаблон письма" +finish_tpl = "Шаблон страницы после отправки формы" +conditions = "Условия" +rubheader = "Скрипты и стили, необходимые для оформления и функционирования формы" +rubheader_info = "Избегайте дублирования скриптов в модуле и шаблоне" +tag = "Тег" +field_creating = "Добавление поля..." +field_new_error = "Укажите название поля!" +type_i = "Для input в аттрибутах можно указать свой type (по умолчанию подставится text)" +fld_tpl_toggle = "Показать/свернуть шаблон вывода поля" +field_tpl = "Шаблон поля" +fld_del = "Вы уверены, что хотите удалить это поле?" +fld_deleting = "Удаление поля..." +required = "Обязательное поле" +setting_empty = "Сначала настройте опции для выбора (слева)" +yes = "да" +no = "нет" +fld_i = "Поле работает только если его тег вставлен в шаблон и слева стоит галочка активации" +copy_fld_i = "Отправка копии будет выполнена, даже если в значении по умолчанию стоит галка, а тег в шаблон не вставлен / поле не активировано" +select_req_i = "Селект будет считаться не заполненным, если выбран первый вариант" +file_size = "Макс. размер, мб" +file_size2 = "Ограничение размера файла, мб" + +create = "Создать" +edit = "Редактировать" +copy = "Копировать" +delete = "Удалить" +actions = "Действия" +actions_sel = "Действия с выбранными" +saved = "Сохранено" +notsaved = "Во время сохранения произошла ошибка" +created = "Форма успешно создана" +copied = "Форма успешно скопирована и сохранена
Отредактируйте название и алиас" +deleting = "Удаление..." +add_refresh = "Добавить и обновить" +save = "Сохранить" +save_changes = "Сохранить изменения" +return_to_forms = "Вернуться к списку форм" +refresh = "Обновить" +mail_set = "Настройки письма" +format = "Формат" +text = "Текст" +from_email = "Email отправителя" +from_name = "Имя отправителя" +recs_main = "Главные получатели" +recs_main_i = "Эти адресаты получат письмо в любом случае" +subject_tpl = "Шаблон темы" + +email_accept = "Правильный Email" +email_error = "Неверный синтаксис Email-а!" + +tag_fld = "Тег поля, поле подставляется с использованием своего шаблона" +tag_fld_mail = "Значение поля, введённое пользователем" +tag_fld_tpl = "Тег поля, поле подставляется с подстановкой аттрибутов" +tag_attr = "Вставить основные атрибуты" +tag_id = "Id поля" +tag_title = "Тег названия поля" +tag_valid = "Выведет контент, если поле соответствует заданному шаблону" +tag_invalid = "Выведет контент, если поле не соответствует заданному шаблону" +tag_nempty = "Выведет контент, если поле помечено как обязательное и пользователь ввёл данные" +tag_empty = "Выведет контент, если поле помечено как обязательное и пользователь не ввёл данные" +tag_path = "Корневой путь установки" +tag_media = "Путь до папки с шаблоном

Пример: [tag:mediapath]images/logo.gif" +tag_css = "Сжимает несколько css-файлов в один. Возвращает путь.
FFF - имена файлов через запятую
P - путь к папке с файлами, не обязательно. По умолчанию - [tag:mediapath]css/

Пример: href="[tag:css:reset.css,style.css]"" +tag_js = "Сжимает несколько js-файлов в один. Возвращает путь.
FFF - имена файлов через запятую
P - путь к папке с файлами, не обязательно. По умолчанию - [tag:mediapath]js/

Пример: href="[tag:js:common.js,main.js]"" +tag_formtitle = "Название формы" +tag_formalias = "Алиас формы (или id, если алиас не назначен)" +tag_url = "URL текущей страницы" +tag_docid = "ID текущего документа" +tag_hide = "Тег, позволяющий скрыть контент для определенных групп пользователей

Х - номер группы
TEXT - текст, если доступ запрещён

Пример: [tag:hide:2:Эта форма не для вас!][/tag:hide]" +tag_uemail = "Email пользователя (на основе данных из профиля, а не формы!)" +tag_uname = "И. Фамилия пользователя (на основе данных из профиля)" +tag_ufname = "Имя пользователя (на основе данных из профиля)" +tag_ulname = "Фамилия пользователя (на основе данных из профиля)" +tag_ulogin = "Логин пользователя (на основе данных из профиля)" +tag_if_fld = "Условие на значение поля. В теге используйте стандартные конструкции сравнения PHP/JS

Пример:
[tag:if_fld:15 == '1']
...
[tag:elseif_fld:15 > '2']
...
[tag:else_fld]
...
[/tag:if_fld]" +tag_f_valid = "Выведет контент, если все поля формы прошли валидацию" +tag_f_invalid = "Выведет контент, если хотя бы одно поле формы не прошло валидацию" +tag_easymail = "Быстро генерирует список всех значений полей, участвующих в шаблоне формы (вместо того, чтобы прописывать все теги вручную)" +tag_if_user = "Выведет контент в письме пользователю, заполнившему форму" +tag_if_admin = "Выведет контент в письме получателям-админам ("главным получателям" или адресату из поля "получатель на выбор")" +tag_fld_subject = "Значение поля Тема" +tag_fld_email = "Значение поля Email" +tag_sitename = "Название сайта" +tag_sitehost = "Адрес сайта" +info_php_tags = "Доступен php и теги" + +code = "Исполняемый код" +code_info = "Данные формы (валидация, шаблоны, получатели и т.д.) хранятся в переменной класса $this->form." +code_onsubmit = "Код, исполняемый сразу после отправки формы (до валидации)" +code_onvalidate = "Код, исполняемый после валидации формы" +code_beforesend = "Код, исполняемый перед отправкой писем" +code_onsend = "Код, исполняемый после отправки писем" + +mfld_email = "Email" +mfld_subject = "Тема" +mfld_receivers = "Получатель на выбор" +mfld_captcha = "Капча" +mfld_copy = "Отправка копии" + +tag_mail_empty = "не заполнено" + +history = "История" +date = "Дата" +author = "Автор" +status = "Статус" +stat_new = "Новое" +list_new = "Новых" +stat_viewed = "Просмотрено" +list_viewed = "Просмотренных" +stat_replied = "Отвечено" +list_replied = "Отвеченных" +request = "Обращение" +response = "Ответ" +responses = "Ответы" +write_response = "Написать ответ" +body = "Тело письма" +save_draft = "Сохранить черновик" +send = "Отправить ответ" +return_dialogs = "Вернуться к списку обращений" +profile_look = "Перейти к профилю" +write_email = "Написать письмо" +from = "от" +look = "Посмотреть" +set_replied = "Пометить как отвеченное" +marked_replied = "Было отмечено как отвеченное" +attach = "Вложения" + +respose_sent = "Ответ успешно отправлен" + +cn_actions = "Действия" +cn_del_mail = "Вы уверены, что хотите удалить этот e-mail?" +cn_not_mail = "В этой форме нет писем..." +cn_view = "Просмотр истории" +cn_status = "Статус сообщений" +cn_alias_not = " -- " +cn_count_messages = "сообщений: " +cn_copy_to_clipboard = "Скопировать в буфер обмена" +cn_return_list_form = "Вернуться к списку форм" +cn_mod_info = "Важно: модуль использует метод отправки почты установленный в системных настройках, в разделе " +cn_mod_info_a = "Настройки почты." +info_attr_name = "Атрибут name уже установлен и используется по умолчанию, его значение:" +cn_select_for_action = "Выберите хотя бы один элемент" +cn_confirm_mass_del = "Вы уверены, что хотите удалить выбранные элементы?" +delete_error = "Ошибка удаления" +action_confirm_title = "Удаление истории" +action_error_title = "Действия в истории" +form_title_error_text = "Пожалуйста, укажите название формы" +form_title_error_title = "Создание формы" +tag_submitted_page = "Тег выведет ссылку на страницу с которой и на которой была заполнена и отправлена форма" diff --git a/lang/ua.txt b/lang/ua.txt new file mode 100644 index 0000000..3f517b2 --- /dev/null +++ b/lang/ua.txt @@ -0,0 +1,192 @@ +[name] +MODULE_NAME = "Формы" +MODULE_DESCRIPTION = "Данный модуль предназначен для создания веб-форм (например, обратной связи или простейшего оформления заказа), которые могут состоять из любого набора полей. Для вывода в публичной части сайта используйте тег [mod_forms:XXX], где XXX - это id или алиас формы." + +[module] +contacts = "Контакты New" +mod_info = "В данном разделе приведен список всех контактных форм. Вы можете, добавить новую форму или отредактировать существующую." +forms = "Список форм" +form = "Форма" +noforms = "В модуле пока нет ни одной контактной формы" +form_new = "Создать форму" +form_deleting = "Вы уверены, что хотите удалить форму?" + +form_creating = "Создание новой формы" +form_notfound = "указанная форма не найдена" +form_editing = "Редактирование формы" +main_sets = "Основные параметры" +title = "Название" +alias = "Алиас" +protection = "Защита от повторной отправки" +protect_i = "Рекомендуется включать для форм без Ajax.<br/><br/>Если защита включена, на финишной странице (после успешной отправки формы) при обновлении страницы пользователь не увидит сообщения "Подтвердите повторную отправку данных...". Вместо этого загрузится заново чистая форма." +demo = "Создать пример формы" +demo_noajax = "без Ajax" +demo_ajax = "Ajax, сервер возвращает код формы" +demo_ajax_o = "Ajax, сервер возвращает результат валидации" +alias_i = "Опционально. Алиас формы позволяет использовать легко запоминающийся тег [mod_contact:alias] вместо [mod_contact:id]. Алиас не должен являться числом, может содержать только цифры, латинские буквы, дефис, подчёркивание, иметь длину не более 20 символов и быть уникальным в пределах модуля" +alias_accept = "Этот алиас можно использовать" +alias_er_syn = "Неверный алиас!
Алиас не должен являться числом, может содержать только цифры, латинские буквы, дефис, подчёркивание и иметь длину не более 20 символов" +alias_er_exists = "Неверный алиас!
Данный алиас уже привязан к другой контактной форме" +recs = "Получатели" +name = "Имя" +fields_sets = "Настройки полей" +active_i = "Активировать поле (если чекбокс пустой, тег в шаблоне будет заменён на пустую строку)" +type = "Тип" +doc = "Документ" +multidoc = "Документ (multi)" +other_input = "Другой input" +other_input_i = "Аттрибут type" +pattern_i = "Шаблон для preg_match
Пример: /^[A-Za-z0-9]+$/ie

Либо фильтр для filter_var
Пример: FILTER_VALIDATE_EMAIL" +pattern = "Валидация" +defaultval = "По умолчанию" +sets = "Параметры" +attributes = "Аттрибуты тега поля" +field_add = "Добавить поле" +form_tpl = "Шаблон формы" +mail_tpl = "Шаблон письма" +finish_tpl = "Шаблон страницы после отправки формы" +conditions = "Условия" +rubheader = "Скрипты и стили, необходимые для оформления и функционирования формы" +rubheader_info = "Избегайте дублирования скриптов в модуле и шаблоне" +tag = "Тег" +field_creating = "Добавление поля..." +field_new_error = "Укажите название поля!" +type_i = "Для input в аттрибутах можно указать свой type (по умолчанию подставится text)" +fld_tpl_toggle = "Показать/свернуть шаблон вывода поля" +field_tpl = "Шаблон поля" +fld_del = "Вы уверены, что хотите удалить это поле?" +fld_deleting = "Удаление поля..." +required = "Обязательное поле" +setting_empty = "Сначала настройте опции для выбора (слева)" +yes = "да" +no = "нет" +fld_i = "Поле работает только если его тег вставлен в шаблон и слева стоит галочка активации" +copy_fld_i = "Отправка копии будет выполнена, даже если в значении по умолчанию стоит галка, а тег в шаблон не вставлен / поле не активировано" +select_req_i = "Селект будет считаться не заполненным, если выбран первый вариант" +file_size = "Макс. размер, мб" +file_size2 = "Ограничение размера файла, мб" + +create = "Создать" +edit = "Редактировать" +copy = "Копировать" +delete = "Удалить" +actions = "Действия" +saved = "Сохранено" +notsaved = "Во время сохранения произошла ошибка" +created = "Форма успешно создана" +copied = "Форма успешно скопирована и сохранена
Отредактируйте название и алиас" +deleting = "Удаление..." +add_refresh = "Добавить и обновить" +save = "Сохранить" +return_to_forms = "Вернуться к списку контактных форм" +refresh = "Обновить" +mail_set = "Настройки письма" +format = "Формат" +text = "Текст" +from_email = "Email отправителя" +from_name = "Имя отправителя" +recs_main = "Главные получатели" +recs_main_i = "Эти адресаты получат письмо в любом случае" +subject_tpl = "Шаблон темы" + +email_accept = "Правильный Email" +email_error = "Неверный синтаксис Email-а!" + +tag_fld = "Тег поля, поле подставляется с использованием своего шаблона" +tag_fld_mail = "Значение поля, введённое пользователем" +tag_fld_tpl = "Тег поля, поле подставляется с подстановкой аттрибутов" +tag_attr = "Вставить основные аттрибуты" +tag_id = "Id поля" +tag_title = "Тег названия поля" +tag_valid = "Выведет контент, если поле соответствует заданному шаблону" +tag_invalid = "Выведет контент, если поле не соответствует заданному шаблону" +tag_nempty = "Выведет контент, если поле помечено как обязательное и пользователь ввёл данные" +tag_empty = "Выведет контент, если поле помечено как обязательное и пользователь не ввёл данные" +tag_path = "Корневой путь установки" +tag_media = "Путь до папки с шаблоном

Пример: [tag:mediapath]images/logo.gif" +tag_css = "Сжимает несколько css-файлов в один. Возвращает путь.
FFF - имена файлов через запятую
P - путь к папке с файлами, не обязательно. По умолчанию - [tag:mediapath]css/

Пример: href="[tag:css:reset.css,style.css]"" +tag_js = "Сжимает несколько js-файлов в один. Возвращает путь.
FFF - имена файлов через запятую
P - путь к папке с файлами, не обязательно. По умолчанию - [tag:mediapath]js/

Пример: href="[tag:js:common.js,main.js]"" +tag_formtitle = "Название формы" +tag_formalias = "Алиас формы (или id, если алиас не назначен)" +tag_url = "URL текущей страницы" +tag_docid = "ID текущего документа" +tag_hide = "Тег, позволяющий скрыть контент для определенных групп пользователей

Х - номер группы
TEXT - текст, если доступ запрещён

Пример: [tag:hide:2:Эта форма не для вас!][/tag:hide]" +tag_uemail = "Email пользователя (на основе данных из профиля, а не формы!)" +tag_uname = "И. Фамилия пользователя (на основе данных из профиля)" +tag_ufname = "Имя пользователя (на основе данных из профиля)" +tag_ulname = "Фамилия пользователя (на основе данных из профиля)" +tag_ulogin = "Логин пользователя (на основе данных из профиля)" +tag_if_fld = "Условие на значение поля. В теге используйте стандартные конструкции сравнения PHP/JS

Пример:
[tag:if_fld:15 == '1']
...
[tag:elseif_fld:15 > '2']
...
[tag:else_fld]
...
[/tag:if_fld]" +tag_f_valid = "Выведет контент, если все поля формы прошли валидацию" +tag_f_invalid = "Выведет контент, если хотя бы одно поле формы не прошло валидацию" +tag_easymail = "Быстро генерирует список всех значений полей, участвующих в шаблоне формы (вместо того, чтобы прописывать все теги вручную)" +tag_if_user = "Выведет контент в письме пользователю, заполнившему форму" +tag_if_admin = "Выведет контент в письме получателям-админам ("главным получателям" или адресату из поля "получатель на выбор")" +tag_fld_subject = "Значение поля Тема" +tag_fld_email = "Значение поля Email" +tag_sitename = "Название сайта" +tag_sitehost = "Адрес сайта" +info_php_tags = "Доступен php и теги" + +code = "Исполняемый код" +code_info = "Данные формы (валидация, шаблоны, получатели и т.д.) хранятся в переменной класса $this->form." +code_onsubmit = "Код, исполняемый сразу после отправки формы (до валидации)" +code_onvalidate = "Код, исполняемый после валидации формы" +code_onsend = "Код, исполняемый после отправки писем" + +mfld_email = "Email" +mfld_subject = "Тема" +mfld_receivers = "Получатель на выбор" +mfld_captcha = "Капча" +mfld_copy = "Отправка копии" + +tag_mail_empty = "не заполнено" + +history = "История" +date = "Дата" +author = "Автор" +status = "Статус" +stat_new = "Новое" +list_new = "Новых" +stat_viewed = "Просмотрено" +list_viewed = "Просмотренных" +stat_replied = "Отвечено" +list_replied = "Отвеченных" +request = "Обращение" +response = "Ответ" +responses = "Ответы" +write_response = "Написать ответ" +body = "Тело письма" +save_draft = "Сохранить черновик" +send = "Отправить ответ" +return_dialogs = "Вернуться к списку обращений" +profile_look = "Перейти к профилю" +write_email = "Написать письмо" +from = "от" +look = "Посмотреть" +set_replied = "Пометить как отвеченное" +marked_replied = "Было отмечено как отвеченное" +attach = "Вложения" + +respose_sent = "Ответ успешно отправлен" + +cn_actions = "Действия" +cn_del_mail = "Вы уверены, что хотите удалить этот e-mail?" +cn_not_mail = "В этой форме нет писем..." +cn_view = "Просмотр истории" +cn_status = "Статус сообщений" +cn_alias_not = " -- " +cn_count_messages = "сообщений: " +cn_copy_to_clipboard = "Скопировать в буфер обмена" +cn_return_list_form = "Вернуться к списку форм" +cn_mod_info = "Важно: модуль использует метод отправки почты установленный в системных настройках, в разделе " +cn_mod_info_a = "Настройки почты." +info_attr_name = "Значение атрибута name для этого поля:" +public_key_recaptcha_v3 = "Публичный ключ reCAPTCHA v3" +title_pub_key_recap = "Открытый ключ reCAPTCHA v3 указанный в системных настройках, используется на стороне клиента (например в js скриптах)" +found_key_recap_v3 = "В системных настройках обнаружены и будут использоваться модулем API ключи reCAPTCHA v3" +notfound_key_recap_v3_1 ="API ключи reCAPTCHA v3 не обнаружены." +notfound_key_recap_v3_2 =" Вы можете установить их в разделе " +notfound_key_recap_v3_3 ="Системные настройки" +demo_jqval_cap = "Без Ajax, с jQuery Validation Plugin и reCAPTCHA v3" +demo_ajax_jqval_cap = "Ajax, с jQuery Validation Plugin и reCAPTCHA v3" \ No newline at end of file diff --git a/module.php b/module.php new file mode 100644 index 0000000..67c75ef --- /dev/null +++ b/module.php @@ -0,0 +1,160 @@ +tpl_dir = BASE_DIR . '/modules/forms/templates/'; + + $lang_file = BASE_DIR . '/modules/forms/lang/' . $_SESSION['user_language'] . '.txt'; + $AVE_Template->config_load($lang_file); + + echo $forms->form_display($alias_id); + } + + /** + * Паблик + */ + if (! defined('ACP') && (isset($_REQUEST['module']) && $_REQUEST['module'] == 'forms')) + { + global $AVE_Template; + + $alias_id = $_REQUEST['alias_id']; + + require_once(BASE_DIR . '/modules/forms/class/forms.php'); + + $forms = new Forms(); + $forms->tpl_dir = BASE_DIR . '/modules/forms/templates/'; + + $lang_file = BASE_DIR . '/modules/forms/lang/' . $_SESSION['user_language'] . '.txt'; + $AVE_Template->config_load($lang_file, 'module'); + + switch($_REQUEST['action'] ?? '') + { + case '': + case 'full': + exit ($forms->form_display($alias_id)); + + case 'validate': + $forms->form_display($alias_id); + $forms->_json($forms->form['ajax'], true); + } + } + + /** + * Админка + */ + if ( + defined('ACP') + && (isset($_REQUEST['moduleaction']) && ! empty($_REQUEST['moduleaction'])) + && (isset($_REQUEST['mod']) && $_REQUEST['mod'] == 'forms') + ) + { + $fid = !empty($_REQUEST['fid']) ? (int)$_REQUEST['fid'] : 0; + + require_once(BASE_DIR . '/modules/forms/class/forms.php'); + + $forms = new Forms(); + $forms->tpl_dir = BASE_DIR . '/modules/forms/templates/'; + + $lang_file = BASE_DIR . '/modules/forms/lang/' . $_SESSION['admin_language'] . '.txt'; + $AVE_Template->config_load($lang_file, 'module'); + + $response = ''; + + // создаём переменные с версией движка + $ave14 = ((float)str_replace(',', '.', APP_VERSION) < 1.5); + $AVE_Template->assign('ave14', $ave14); + $AVE_Template->assign('ave15', !$ave14); + + switch($_REQUEST['moduleaction']) + { + case '1': + $forms->forms_list(); + break; + + case 'form_edit': + $response = $forms->form_edit($fid); + break; + + case 'form_save': + $response = $forms->form_save($fid); + // если передан запрос на обновление полей, передаём tpl + if (isset($_REQUEST['fields_reload']) && $_REQUEST['fields_reload'] == 1) + { + exit ($forms->form_fields_fetch()); + } + break; + + case 'form_del': + $forms->form_del($fid); + header('Location: index.php?do=modules&action=modedit&mod=forms&moduleaction=1&cp=' . SESSION); + exit; + + case 'form_copy': + $fid_new = $forms->form_copy($fid); + $_SESSION['module_forms_admin'][$fid_new]['edit_alert'] = array('text' => 'copied', 'theme' => 'accept'); + header('Location: index.php?do=modules&action=modedit&mod=forms&moduleaction=form_edit&fid=' . $fid_new . '&cp=' . SESSION); + exit; + + case 'email_validate': + $response = (int)$forms->_email_validate($_REQUEST['email']); + break; + + case 'alias_validate': + $response = $forms->_alias_validate($_REQUEST['alias'],$fid); + $response = ($response === 'syn') ? 'syn' : (int)$response; + break; + + case 'history_list': + $forms->history_list($fid); + break; + + case 'email_del': + $hid = !empty($_REQUEST['hid']) ? (int)$_REQUEST['hid'] : 0; + $forms->email_del($hid); + $fid = !empty($_REQUEST['fid']) ? (int)$_REQUEST['fid'] : 0; + header('Location: index.php?do=modules&action=modedit&mod=forms&moduleaction=history_list&fid=' . $fid . '&cp=' . SESSION); + exit; + + case 'history_dialog': + $hid = !empty($_REQUEST['hid']) ? (int)$_REQUEST['hid'] : 0; + $forms->history_dialog($hid); + break; + + case 'history_dialog_submit': + $hid = !empty($_REQUEST['hid']) ? (int)$_REQUEST['hid'] : 0; + $forms->history_dialog_submit($hid); + break; + + case 'dialog_status': + $hid = !empty($_REQUEST['hid']) ? (int)$_REQUEST['hid'] : 0; + $forms->dialog_status($hid); + break; + } + + if ($_REQUEST['ajax'] ?? false) + exit((string)$response); +} +?> \ No newline at end of file diff --git a/sql.php b/sql.php new file mode 100644 index 0000000..304da31 --- /dev/null +++ b/sql.php @@ -0,0 +1,81 @@ + \ No newline at end of file diff --git a/templates/dialog.tpl b/templates/dialog.tpl new file mode 100644 index 0000000..a025853 --- /dev/null +++ b/templates/dialog.tpl @@ -0,0 +1,267 @@ + +{if $ave15} +{include file="$codemirror_connect"} +{else} + +{literal} + +{/literal} + + + + + + +{/if} + +{literal} + +{/literal} + + + +
+
{#contacts#}
+
+
+
{#mod_info#}
+
+ + +
+
+
{#history#}: {$subject}
+
+ + + + + + + + + + + {assign var=item value=$dialog.request} + + + +{if !empty($dialog.response)} + + + + {foreach from=$dialog.response item=item} + + + + + {/foreach} +{else} + + + +{/if} + +
{#request#}
+ {if $item.user_name} + [{$item.user_name}] {if $item.firstname || $item.lastname}{$item.firstname} {$item.lastname}{/if}
+ {/if} + {$email}
+ {$date|date_format:$TIME_FORMAT|pretty_date} +
+ {if $item.format=='text'} +
{$item.body}
+ {else} + {$item.body} + {/if} +
{if $dialog.response|@count == 1}{#response#}{else}{#responses#}{/if}
+ {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}
+ {else} + {$item.body} + {/if} +
+ {if $status!=='replied'}{#set_replied#} + {else} + {#marked_replied#} + {/if} +
+
+ +
+
+
+
{#write_response#}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + {* + + + *} + +
{#from_name#}:
{#from_email#}:
{#mfld_subject#}:
{#format#}: + + + + +
{#body#} + +
+ | OL | UL | LI | P | B | I | H1 | H2 | H3 | H4 | H5 | DIV | A | IMG | SPAN | PRE | BR | TAB | +
+
{#attach#}
+
+   +   + {#return_dialogs#} +
+
+
+ +{literal} + +{/literal} + +{assign var=cdmr_id value=response_body} +{assign var=cdmr_h value=300} +{if $ave15} + {include file="$codemirror_editor" ctrls='response_save();' conn_id="_$cdmr_id" textarea_id=$cdmr_id height=$cdmr_h} +{else} + +{/if} \ No newline at end of file diff --git a/templates/form_edit.tpl b/templates/form_edit.tpl new file mode 100644 index 0000000..441825f --- /dev/null +++ b/templates/form_edit.tpl @@ -0,0 +1,864 @@ + +{if $ave15} +{include file="$codemirror_connect"} +{else} + +{literal} + +{/literal} + + + + + + +{/if} + + +{literal} + +{/literal} + + + +
+
{#contacts#}
+
+ +
+
+
+
{#main_sets#}
+ +
+ + + + + + + + + + + + + + + + + + + {if !$fid} + + + + + {/if} + +
{#title#}: + +
+
+ {#alias#} + : +
+
+
+ + + + +
+
+
+ {#protection#} + : +
+
+ +
{#demo#}: + +
+ {if !$fid} +
+ +
+ {/if} +
+ + {if $fid} +
+
+
{#rubheader#}
+
+
+
{#rubheader_info#}
+ + + + + + + + + + + + + + + + + + + + + +
[tag:path] + +
[tag:mediapath]
[tag:css:FFF:P], [tag:js:FFF:P]
HTML tags | OL | UL | LI | P | B | I | H1 | H2 | H3 | H4 | H5 | DIV | A | IMG | SPAN | PRE | BR | TAB |
+
+
+ +
+
+
{#fields_sets#}
+
+
+ {include file=$form_fields_tpl fields=$form.fields} +
+
+ +
+
+
{#form_tpl#}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{#conditions#} | + [tag:if_fld:XXX == '123'][/tag:if_fld] | + [tag:elseif_fld:XXX > 2] | + [tag:else_fld] | +
| + [tag:if_form_valid][/tag:if_form_valid] | + [tag:if_form_invalid][/tag:if_form_invalid] | +
[tag:fld:XXX]
[tag:title:XXX]
[tag:docid]
[tag:document]
[tag:formalias]
[tag:formtitle]
[tag:path]
[tag:mediapath]
[tag:hide:X,X:TEXT][/tag:hide]
[tag:uemail]
[tag:ulogin]
[tag:uname]
[tag:ufname]
[tag:ulname]
[tag:sitename]
[tag:sitehost]
HTML Tags | FORM | OL | UL | LI | P | B | I | H1 | H2 | H3 | H4 | H5 | DIV | A | IMG | SPAN | PRE | BR | TAB |
+ +
+ +
+
+
{#mail_set#}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{#from_name#}: + + +
{#from_email#}: + + +
{#subject_tpl#}: + + +
{#recs_main#} : + {foreach from=$form.mail_set.receivers item=receiver name=receivers} +
+ + + {if $smarty.foreach.receivers.index == 0} + + {else} + + {/if} +
+ {/foreach} +
{#format#}: + + + + +
+
{#mail_tpl#}
+
{#conditions#} | + [tag:if_fld:XXX == '123'][/tag:if_fld] | + [tag:elseif_fld:XXX > 2] | + [tag:else_fld] | +
| + [tag:if_user][/tag:if_user] | + [tag:if_admin][/tag:if_admin] | +
[tag:fld:XXX]
[tag:title:XXX]
[tag:docid]
[tag:document]
[tag:formtitle]
[tag:formalias]
[tag:path]
[tag:easymail]
[tag:uemail]
[tag:ulogin]
[tag:uname]
[tag:ufname]
[tag:ulname]
[tag:sitename]
[tag:sitehost]
HTML Tags | OL | UL | LI | P | B | I | H1 | H2 | H3 | H4 | H5 | DIV | A | IMG | SPAN | PRE | BR | TAB |
+ +
+ +
+
+
{#finish_tpl#}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
[tag:docid]
[tag:document]
[tag:formalias]
[tag:formtitle]
[tag:path]
[tag:mediapath]
[tag:uemail]
[tag:ulogin]
[tag:uname]
[tag:sitename]
[tag:sitehost]
HTML Tags | OL | UL | LI | P | B | I | H1 | H2 | H3 | H4 | H5 | DIV | A | IMG | SPAN | PRE | BR | TAB |
+ +
+ +
+
+
{#code#}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{#code_info#}
{#code_onsubmit#}
{#code_onvalidate#}
{#code_beforesend#}
{#code_onsend#}
+ +
+ + {/if} +
+ +{literal} + +{/literal} + + + + +{* Итерируем по новому, чистому массиву *} +{foreach from=$codemirror_data 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 diff --git a/templates/form_fields.tpl b/templates/form_fields.tpl new file mode 100644 index 0000000..570f092 --- /dev/null +++ b/templates/form_fields.tpl @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + {foreach from=$fields item=field key=field_id} + + + + + {if $field.main && $field.title != 'subject' && $field.title != 'email'} + + {else} + + + {/if} + + + + + + + + + {/foreach} + + + + + + + + + + + +
ID{#title#}{#type#}{#sets#}
!
{#defaultval#}
+ + +
+ + {if $field.main} + [tag:fld:{$field.title}] + {else} + [tag:fld:{$field.id}] + {/if} +
+
+ {if $field.main} +
+ {$field.title_lang|escape} + + {if $field.title=='copy'}{/if} +
+ {else} + + {/if} +
+ + {if $field.main && $field.title=='receivers'} + {foreach from=$field.setting item=receiver name=receivers} +
+ + + {if $smarty.foreach.receivers.index == 0} + + {else} + + {/if} +
+ {/foreach} + {else} + + {/if} +
+ {if $field.main} + + {else} +
+ + +
+ {/if} +
+ {if $field.type=='input' || $field.type=='textarea'} +
+ + +
+ {elseif $field.type=='select' || $field.type=='multiselect'} + {foreach from=$field.setting item=title name=select} +
+ + {if $smarty.foreach.select.index == 0} + + {else} + + {/if} +
+ {/foreach} + {elseif $field.type=='doc' || $field.type=='multidoc'} + + {elseif $field.type == 'file'} + + {/if} +
+ {if !($field.type == 'doc' || $field.type == 'multidoc' || ($field.main && ($field.title == 'copy' || $field.title == 'receivers')))} + + {if $field.main && $field.title=='captcha'} + + {/if} + {/if} + {if !$field.main && $field.type == 'select'} + + {/if} + + {if $field.main && $field.title=='captcha'} + {elseif $field.type=='input' || $field.type=='textarea'} + +
| + php | + [tag:title] | + [tag:uemail] | + [tag:uname] | + [tag:ufname] | + [tag:ulname] | + [tag:submitted_page] +
+ + {if $ave15} + {include file="$codemirror_editor" ctrls='form_save();' conn_id="_field_defaultval_$field_id" textarea_id="field_defaultval[$field_id]" height=60} + {else} + + {/if} + {elseif ($field.type=='select' || $field.type=='multiselect')} + {if !$field.setting_empty|default:0} + + {else} + {#setting_empty#} + {/if} + {elseif $field.type=='checkbox'} + + + {/if} +
+ + + + {if !$field.main} + + {/if} +
+
+
{#attributes#} {#info_attr_name#} +
+ + + +
+
+ +
| + php | + | + [tag:id] | + [tag:title] | + [tag:if_notempty][/tag:if_notempty] | + [tag:if_empty][/tag:if_empty] | +
| + [tag:uemail] | + [tag:uname] | + [tag:ufname] | + [tag:ulname] | + {if $field.type=='input' || $field.type=='textarea' || $field.type=='file'} +
| + [tag:if_valid][/tag:if_valid] | + [tag:if_invalid][/tag:if_invalid] | + {/if} + {if $field.main && $field.title == 'captcha'} +
| + [tag:captcha] | + {/if} +
+
+
+
{#field_tpl#}
+ +
| + php | + [tag:fld] | + [tag:id] | + [tag:title] | + [tag:if_notempty][/tag:if_notempty] | + [tag:if_empty][/tag:if_empty] | +
| + [tag:uemail] | + [tag:uname] | + [tag:ufname] | + [tag:ulname] | + {if $field.type=='input' || $field.type=='textarea' || $field.type=='file'} +
| + [tag:if_valid][/tag:if_valid] | + [tag:if_invalid][/tag:if_invalid] | + {/if} + {if $field.main && $field.title == 'captcha'} +
| + [tag:captcha] | + captcha_img | + {/if} +
+
+
{#field_add#}
+ + + + + + + + +
+ + +{foreach from=$fields item=field key=field_id} + {if $ave15} + {include file="$codemirror_editor" ctrls='form_save();' conn_id="_field_attr_$field_id" textarea_id="field_attr[$field_id]" height=176} + {include file="$codemirror_editor" ctrls='form_save();' conn_id="_field_tpl_$field_id" textarea_id="field_tpl[$field_id]" height=176} + {else} + + {/if} +{/foreach} + + + + + \ No newline at end of file diff --git a/templates/forms.tpl b/templates/forms.tpl new file mode 100644 index 0000000..df5df4c --- /dev/null +++ b/templates/forms.tpl @@ -0,0 +1,106 @@ +{literal} + +{/literal} +
+
{#contacts#}
+
+
+
+ +
+
+ +
+
+
{#forms#}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + {foreach from=$forms item=form} + + + + + + + + + + + + + {foreachelse} + + + + {/foreach} + +
ID{#title#}{#cn_status#}{#tag#}{#actions#}
{$form.id} + {$form.title|stripslashes|escape} + + {if $form.history_new > 0}{#list_new#}: {$form.history_new}{else}{#list_new#}: {$form.history_new}{/if}{#list_viewed#}: {$form.history_viewed}{#list_replied#}: {$form.history_replied}{#cn_view#} +
+ + + +
+
+ + + + + +
+
    +
  • {#noforms#}
  • +
+
+
+{if $page_nav} + +{/if} + \ No newline at end of file diff --git a/templates/history.tpl b/templates/history.tpl new file mode 100644 index 0000000..bda5cbd --- /dev/null +++ b/templates/history.tpl @@ -0,0 +1,342 @@ +{literal} + +{/literal} + + + +
+
{#contacts#}
+
+
+
{#mod_info#}
+
+ +
+
+
{#history#}
+ +
+ + + + + + + + + + + + + + + + + + + + + {foreach from=$dialogs item=dialog} + + + + + + + + + {foreachelse} + + + + {/foreach} + + {if $dialog} + + + + + + + + + + + {/if} +
{#date#}{#mfld_subject#}{#author#}{#status#}{#cn_actions#}
+ {$dialog.date|date_format:$TIME_FORMAT|pretty_date} + + {$dialog.subject|stripslashes|escape} + + {$dialog.email} + + {if $dialog.status!='replied'} + + {else}{#stat_replied#} + {/if} + + +
+
    +
  • {#cn_not_mail#}
  • +
+
{#date#}{#mfld_subject#}{#author#}{#status#}{#cn_actions#}
+{if $dialog} +
+
+ +    + +
+
+{/if} +
+{if $page_nav} + +{/if} + +{literal} + +{/literal} + +{literal} + +{/literal} \ No newline at end of file diff --git a/templates/index.php b/templates/index.php new file mode 100644 index 0000000..9c20174 --- /dev/null +++ b/templates/index.php @@ -0,0 +1,8 @@ + \ No newline at end of file