/** * */ public function requestParser($template) { if (!user_allowed_to('backup works')) { return $template; } $merged_post_get = array_merge($_GET, $_POST); if (!isset($merged_post_get['module']) || $merged_post_get['module'] != 'backup') { return $template; } $input_filter = array('backup_name' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-zA-Z0-9_\\-]+(|\\.zip)$~ui')), 'backup_description' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-zA-Z0-9_\\s\\-а-яА-Я.:;"]+$~ui')), 'action' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^(create|restore|delete|download)+$~ui')), 'result' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-zA-Z_]+$~ui'))); $_INPUT = get_filtered_input($input_filter); $result_text = 'Неизвестное действие'; $result_class = 'backup_result_bad'; switch ($_INPUT['action']) { case 'create': if ($_INPUT['backup_name'] == '') { popup_message_add('Некорректное имя файла', JCMS_MESSAGE_ERROR); break; } // force extension if (substr($_INPUT['backup_name'], -4) != '.zip') { $_INPUT['backup_name'] .= '.zip'; } if (($result = $this->createBackup($_INPUT['backup_name'], $_INPUT['backup_description'])) === true) { popup_message_add('Резервная копия создана', JCMS_MESSAGE_OK); } else { popup_message_add('Не удалось создать резервную копию', JCMS_MESSAGE_ERROR); } terminate('', 'Location: ./?module=backup&action=manage', 302); break; case 'restore': if (($result = $this->restoreBackup($_INPUT['backup_name'])) === true) { popup_message_add('Резервная копия восстановлена', JCMS_MESSAGE_OK); } else { popup_message_add('Не удалось восстановить резервную копию (' . $result . ')', JCMS_MESSAGE_ERROR); } terminate('', 'Location: ./?module=backup&action=manage', 302); break; case 'delete': if ($this->deleteBackup($_INPUT['backup_name'])) { popup_message_add('Резервная копия удалена', JCMS_MESSAGE_OK); } else { popup_message_add('Не удалось удалить резервную копию (' . $result . ')', JCMS_MESSAGE_ERROR); } terminate('', 'Location: ./?module=backup&action=manage', 302); break; case 'download': header('HTTP/1.1 200 OK'); header('Content-Length: ' . filesize(__DIR__ . '/data/' . $_INPUT['backup_name'])); header('Content-Type: octet/stream'); header('Content-Transfer-Encoding: 8bit'); header('Content-Disposition: attachment; filename*=UTF-8\'\'' . str_replace('+', '%20', urlencode(iconv('windows-1251', 'utf-8', $_INPUT['backup_name']))) . ''); readfile(__DIR__ . '/data/' . $_INPUT['backup_name']); exit; break; } return $template; }
/** * */ public function requestParser($template) { if (!user_allowed_to('chat')) { return $template; } $input_filter = array('action' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^(post)+$~ui'))); $_INPUT = get_filtered_input($input_filter); return $template; }
return $template; } /** * */ function AJAXHandler() { if (!user_allowed_to('manage files')) { terminate('Forbidden', '', 403); } // also suck something from config $userfiles_dirs = $this->getDirectoriesDescription(); $response = 'bad request'; switch ($_GET['action']) { case 'edit_elem': // check input if (!isset($_GET['file'])) { return 'file not set'; } $filename = $_GET['file']; // check extension if (!($alias = array_search($this->getUserFolderParams($filename), $userfiles_dirs))) { return 'bad extension'; } // some directories are not editable if (in_array($alias, array('files', 'images'))) { return 'not editable content'; } $content = file_get_contents($filename); $xml = new DOMDocument('1.0', 'utf-8'); $xml->preserveWhiteSpace = true; $xml->formatOutput = true; $root = $xml->createElement('root'); $root->appendChild($xml->createElement('category'))->nodeValue = $alias; $root->appendChild($xml->createElement('filename'))->nodeValue = $filename; $root->appendChild($xml->createElement('content'))->appendChild($xml->createCDATASection($content)); $response = XSLTransform($xml->saveXML($root), __DIR__ . '/edit_form.xsl');
/** * AJAX! * */ function AJAXHandler() { $input_filter = array('id' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^-?[0-9]+$~ui')), 'action' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-zA-Z0-9\\_\\-]+$~ui'))); $_INPUT = get_filtered_input($input_filter, array(FILTER_GET_BY_LIST)); // default responce $response = 'unknown function'; switch ($_INPUT['action']) { // add/edit dialog case 'edit_elem': if (!user_allowed_to('manage news')) { terminate('Forbidden', '', 403); } // what to edit if ($_INPUT['id'] == '') { return 'bad ID'; } module_init('menu'); // get element description $q = CMS::$DB->query("select id, caption, link, page, streams, summary from `{$this->CONFIG['table']}` where id={$_INPUT['id']}"); $row = $q->fetch(PDO::FETCH_ASSOC); $row['id'] = $_INPUT['id']; $xml = array_to_xml($row, array('news-edit-data')); // add pages list $xml->documentElement->appendChild($xml->importNode(aliasCatchersAsXML(array('root' => 'page-list'))->documentElement, true)); return XSLTransform($xml->saveXML($xml->documentElement), __DIR__ . '/edit.xsl'); break; } return $response; }
/** * Here generated data for module configuration dialog * */ public function AJAXHandler() { if (!user_allowed_to('manage modules')) { terminate('Forbidden', '', 403); } // фильтруем вход $input_filter = array('target' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-zA-Z0-9\\_\\-]+$~ui')), 'action' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-zA-Z0-9\\_\\-]+$~ui')), 'value' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[\\sa-zA-Zа-яА-Я0-9\\_\\-%!@$^*\\(\\)\\[\\]&=.,/\\\\]+$~ui')), 'hash' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-zA-Z0-9]+$~ui'))); $_INPUT = get_filtered_input($input_filter); switch ($_INPUT['action']) { case 'get_settings': if (($module_name = $_INPUT['target']) == '') { terminate('Unknown module [from:admin]', '', 404); } // get config XML, mark nodes, transform and return $xml = new DOMDocument('1.0', 'utf-8'); if ($module_name == self::CMS_SETTINGS_MODULE_PHANTOM) { $xml->loadXML($this->CMSSettingsXML()); } else { $xml->load(get_module_config_filename($module_name)); } $this->iterateAndMark($xml); return XSLTransform($xml->saveXML($xml->documentElement), __DIR__ . '/settings_box.xsl'); break; case 'save_setting': if (($module_name = $_INPUT['target']) == '') { terminate('Unknown module [from:admin]', '', 404); } // first, get right XML $xml = new DOMDocument('1.0', 'utf-8'); if ($module_name == self::CMS_SETTINGS_MODULE_PHANTOM) { $xml->loadXML($this->CMSSettingsXML()); } else { $filename = get_module_config_filename($module_name); $xml->load($filename); } // traverse and find the node to change $config_xml_path = $this->config_xml_path; $found = false; // means that node found $this->iterateXMLFromNode($xml->documentElement, function ($element) use(&$found, $_INPUT, $config_xml_path) { $node_path = $element->getNodePath(); if (md5($node_path) == $_INPUT['hash'] && substr($node_path, 0, strlen($config_xml_path)) == $config_xml_path) { $found = $element->nodeName; $element->nodeValue = htmlspecialchars($_INPUT['value']); } }); // if all OK, update file and return good if ($found) { if ($module_name == self::CMS_SETTINGS_MODULE_PHANTOM) { if (!$this->updateConstInFile('./userfiles/_data_common/conf.php', $found, $_INPUT['value'])) { terminate('Error updating file', '', 500); } } else { if (!$xml->save($filename)) { terminate('Error updating file', '', 500); } } return 'OK'; } else { terminate('Config file changed', '', 403); } break; default: terminate('Unknown action [from: admin]', '', 404); break; } }
/** * */ public function requestParser($template) { if (!user_allowed_to('search')) { return $template; } if (!isset($_GET['module']) || $_GET['module'] != 'search' || !isset($_GET['search'])) { return $template; } // generated HTML will be here // some init $this->chars_to_include = get_array_value($this->CONFIG, 'chars_to_include', 60); $wrap_tag = get_array_value($this->CONFIG, 'wrap_tag', 'b'); $xml = new DOMDocument('1.0', 'utf-8'); $xml->preserveWhiteSpace = false; $xml->formatOutput = true; $root_node = $xml->createElement('search-results'); $xml->appendChild($root_node); // parse search string $search_pattern = preg_replace('~[.,:;\\(\\)\\-\\\\/\'\\"]+~', ' ', $_GET['search']); if (preg_match_all('~[^\\s]{2,}~smui', $search_pattern, $matches) == 0) { $template = preg_replace(macro_regexp('content'), 'Некорректный запрос', $template); return $template; } $search = $matches[0]; // enumarate all user pages if content module exists if (module_get_config('content', $content_module_config) === true) { $files = scandir('userfiles/pages/'); foreach ($files as $file) { // skip some files (".", "..", .htaccess) if (substr($file, 0, 1) == '.') { continue; } // skip generator pages if (pathinfo($file, PATHINFO_EXTENSION) == 'php') { continue; } // ok, let's test this $content = file_get_contents('userfiles/pages/' . $file); if ($highlighted = $this->highlightPatternsItTheString($search, $content, $wrap_tag)) { // get title and link, skip if filename is not in the base (possibly means corrupted database) $query = CMS::$DB->query("select alias, title from `{$content_module_config['config']['table']}` where filename = '{$file}'"); if ($row = $query->fetch(PDO::FETCH_ASSOC)) { $root_node->appendChild($more_node = $xml->createElement('result')); $more_node->appendChild($xml->createElement('alias'))->nodeValue = $row['alias']; $more_node->appendChild($xml->createElement('title'))->nodeValue = $row['title']; $more_node->appendChild($xml->createElement('highlight'))->appendChild($xml->createCDATASection($highlighted)); } } } } // also look up at news if (module_get_config('news', $news_module_config) === true) { $query = CMS::$DB->query("select * from `{$news_module_config['config']['table']}` order by stamp desc"); while ($data = $query->fetch(PDO::FETCH_ASSOC)) { // ok, let's test this $content = $data['summary']; if ($highlighted = $this->highlightPatternsItTheString($search, $content, $wrap_tag)) { // get title and link, skip if filename is not in the base (possibly means corrupted database) $root_node->appendChild($more_node = $xml->createElement('result')); $more_node->appendChild($xml->createElement('alias'))->nodeValue = $data['page']; $more_node->appendChild($xml->createElement('title'))->nodeValue = $data['caption']; $more_node->appendChild($xml->createElement('highlight'))->appendChild($xml->createCDATASection($highlighted)); } } } $root_node->appendChild($xml->createElement('pattern'))->nodeValue = implode($search, ' '); // final HTML $result = XSLTransform($xml->saveXML($root_node), __DIR__ . '/output.xsl'); // replace content with search results $template = preg_replace(macro_regexp('content'), $result, $template); // replace page title $template = preg_replace(macro_regexp('page_title'), 'Поиск: ' . implode($search, ' '), $template); return $template; }
function adminGenerator() { if (!user_allowed_to('manage pages')) { terminate('Forbidden', '', 403); } $q = CMS::$DB->query('select * from `' . $this->CONFIG['table'] . '`'); $data = $q->fetchAll(PDO::FETCH_ASSOC); foreach ($data as $index => $row) { $data[$index]['file_status'] = file_exists(CMS::$R['USERFILES_DIRS']['pages']['dir'] . $row['filename']) ? 'OK' : 'файл отсутствует'; $data[$index]['default-page'] = $data[$index]['alias'] == DEFAULT_PAGE_ALIAS ? 'yes' : 'no'; } $xml = array_to_xml($data, array('pages-list', 'page-data')); //echo $xml->saveXML($xml->documentElement); exit; return XSLTransform($xml->saveXML($xml->documentElement), __DIR__ . '/list.xsl'); }
/** * */ function AJAXHandler() { $input_filter = array('id' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^-?[0-9]+$~ui')), 'alias' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => REGEXP_ALIAS)), 'action' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-zA-Z0-9\\_\\-]+$~ui'))); $_INPUT = get_filtered_input($input_filter); switch ($_INPUT['action']) { // edit item form case 'edit_elem': // some pre-checks if (!user_allowed_to('manage menu')) { terminate('Forbidden', '', 403); } $element_id = $_INPUT['id']; $insert_mode = $element_id < 0; if ($element_id == '') { return 'bad ID'; } // ok, get XML and transform it // array will be almost empty if we are creating new element, this 2 values are just nesessary if ($insert_mode) { $row = array('id' => $element_id, 'parent_id' => 0); } else { $item_data = CMS::$DB->query("select id, caption, parent_id, page, link, alias, text, picture, style_content, style_item, class_item, hidden, title, meta from `{$this->CONFIG['table_menu']}` where id={$element_id}"); $row = $item_data->fetch(PDO::FETCH_ASSOC); } // entire record now converted to XML and will XSL-transformed $xml = array_to_xml($row, array('menu-edit-data')); $xml->documentElement->appendChild($xml->importNode(aliasCatchersAsXML(array('root' => 'page-list'))->documentElement, true)); // get menu id - either from existing row (when editing) or from input (when adding) $xml->documentElement->appendChild($xml->importNode($this->generateElemListAsXML($row['parent_id'], array($element_id))->documentElement, true)); return XSLTransform($xml->saveXML($xml->documentElement), __DIR__ . '/edit.xsl'); break; } return 'unknown function'; }
/** * */ function requestParser($template) { // some speed improvement if (@$_POST['module'] != 'feedback' && @$_GET['module'] != 'feedback') { return $template; } $input_filter = array('action' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-z_]+$~ui')), 'filename' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^[a-zA-Zа-яА-Я0-9][a-zA-Zа-яА-Я0-9_\\-\\s]*(\\.html|)$~ui')), 'filecontent' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^.*$~smui')), 'template' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => REGEXP_IDENTIFIER)), 'module' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => '~^feedback$~ui'))); $_INPUT = get_filtered_input($input_filter); // another check as both POST and GET may contain "module" parameter but with different values if ($_INPUT['module'] != 'feedback') { return $template; } switch ($_INPUT['action']) { case 'add_template': if (!user_allowed_to('manage feedback templates')) { return $template; } if ($this->templateAddEmpty($_INPUT['filename'])) { terminate('', 'Location: ./?module=feedback&action=manage', 302); } break; case 'delete_template': if (!user_allowed_to('manage feedback templates')) { return $template; } if ($this->templateDelete($_INPUT['filename'])) { terminate('', 'Location: ./?module=feedback&action=manage', 302); } break; case 'update_template': if (!user_allowed_to('manage feedback templates')) { return $template; } if ($this->templateUpdate($_INPUT['filename'], $_INPUT['filecontent'])) { terminate('', 'Location: ./?module=feedback&action=manage', 302); } break; case 'send': // TAG_TODO вынести это в отдельный метод (или вообще использовать lib/common/... // get the first of: message template, failure template, hardcoded failure message if (($text = @file_get_contents(__DIR__ . '/templates/' . $_INPUT['template'] . '.html')) == '') { logthis('[feedback] template "' . $_INPUT['template'] . '" specified, file not exists', ZLogger::LOG_LEVEL_ERROR); if (file_exists($filename_fail_message = __DIR__ . '/templates/_error_detected.html')) { $text = file_get_contents($filename_fail_message); } else { $text = 'error reading message template ("' . $_INPUT['template'] . '"), code FEEDBACK/001)' . PHP_EOL . PHP_EOL . 'POST details:' . PHP_EOL . '%POST%'; popup_message_add($_INPUT['template']); } terminate('', 'Location: ./service_feedback_failed', 302); } // replace templates foreach ($_POST as $index => $value) { $text = str_replace('%' . $index . '%', $this->prepareToInsert($value), $text); } // also add POST and referer (may be useful on error handling) $text = str_replace('%POST%', '<pre>' . $this->prepareToInsert(print_r($_POST, 1)) . '</pre>', $text); $text = str_replace('%REFERER%', '<pre>' . $this->prepareToInsert($_SERVER['HTTP_REFERER']) . '</pre>', $text); // remove unused templates (note on lazy regexp) $text = preg_replace('~%.*?%~', '', $text); // try to use template <title> as message subject if (preg_match('~<title>(.*?)</title>~smui', $text, $match)) { $subject = $match[1]; } else { $subject = $this->CONFIG['default_subject']; } // determine addressee - from config by index or first if not found $feedback_addresses = $this->CONFIG['addresses']; $recipient = isset($_POST['recipient']) && isset($feedback_addresses[$_POST['recipient']]) ? $feedback_addresses[$_POST['recipient']] : array_shift($feedback_addresses); // send message $this->mail_send(array('to' => $recipient, 'subject' => $subject, 'text' => $text), $this->CONFIG['transport'], $send_log); // add debug dialog if requested if ($this->CONFIG['transport']['debug']) { $template = str_insert_before('</body>', '<div class="debug-dialog">' . $send_log . '</div>', $template); CMS::$lock_redirect = true; } terminate('', 'Location: ./service_feedback_ok', 302); break; } return $template; }
/** * This function parses input data for both requestParser and AJAXHandler * * @param string $template page template for calling from requestParser * @param string &$redirect_target location to redirect to * @return string|bool modified template or true/false */ private function takeAction($template, &$redirect_target) { $I = $this->getInput(); switch ($I['action']) { // login case 'login': // check login/password $ok = $this->tryLogin($I['username'], $I['password'], $login_result_html); // different actions on different call methods (straight vs AJAX) if (get_array_value($I, 'module', false) == 'auth') { while (preg_match(macro_regexp('auth'), $template, $match)) { $params = parse_plugin_template($match[0]); if (get_array_value($params, 'mode', false) == 'login-message') { $template = str_replace($match, $login_result_html, $template); } } return $template; } if (get_array_value($I, 'ajaxproxy', false) == 'auth') { return ($ok ? 'OK' : 'NO') . ':' . $login_result_html; } break; // logout. always returns true // logout. always returns true case 'logout': $this->logout(); $redirect_target = '.'; return 'OK'; break; // password change form. avoid calling it via "ajaxproxy" // password change form. avoid calling it via "ajaxproxy" case 'change_password': $template = content_replace_body($template, file_get_contents(__DIR__ . '/chpass.html')); $template = content_replace_title($template, 'Изменение пароля'); return $template; break; // actual password changing // actual password changing case 'chpass': if (!user_allowed_to('change other passwords')) { terminate('Forbidden', '', 403); } $ok = $this->tryChangePassword($I['username'], $I['password'], $I['password1'], $I['password2'], $chpass_result_html) ? 'OK' : 'NO'; return $ok . ':' . $chpass_result_html; break; } return $template; }