/** * */ public function contentGenerator($template) { while (preg_match(macro_regexp('chat'), $template, $match) > 0) { // parse template parameters into array $params = parse_plugin_template($match[0]); // generate menu HTML $html = '<div class="j-chat"><div>loading...</div><form><input type="text" /></form></div>'; // replace it $template = str_replace($match[0], $html, $template); } 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; }
/** * */ function contentGenerator($template) { if (!user_allowed_to('manage site')) { return $template; } // create XML with admin panel description $xml = new DOMDocument('1.0', 'utf-8'); $root_node = $xml->createElement('admin-buttons'); $xml->appendChild($root_node); // detect active module_definition. no active module means some content is displayd $root_node->appendChild($xml->createElement('active-module'))->nodeValue = isset($_GET['module']) ? $_GET['module'] : ''; $root_node->appendChild($xml->createElement('cms-settings-phantom'))->nodeValue = self::CMS_SETTINGS_MODULE_PHANTOM; $root_node->appendChild($xml->createElement('active-page'))->nodeValue = isset($_GET['p_id']) ? $_GET['p_id'] : ''; $root_node->appendChild($xml->createElement('edit-mode'))->nodeValue = isset($_GET['edit']) ? 'yes' : 'no'; $root_node->appendChild($xml->createElement('show-config-link'))->nodeValue = empty($_GET['module']) || empty(CMS::$cache[$_GET['module']]['config']['config']) ? 'no' : 'yes'; // get all modules' admin buttons, where exists foreach (CMS::$cache as $module_name => $module) { if (in_array($module_name, CMS::$R['modules_apply_order']) && isset($module['config']['admin_caption']) && $module['config']['admin_caption'] > '') { $root_node->appendChild($button_node = $xml->createElement('button')); $button_node->appendChild($xml->createElement('caption'))->nodeValue = $module['config']['admin_caption']; $button_node->appendChild($xml->createElement('module-name'))->nodeValue = $module_name; } } // if any module requests admin part, replace all the content with module's admin code and add CSS/JS // otherwise, display page editorial buttons // TAG_TODO move them to content module if (isset($_GET['module']) && isset(CMS::$cache[$_GET['module']]) && isset($_GET['action']) && $_GET['action'] == 'manage') { $module_name = $_GET['module']; module_init($module_name); $module = CMS::$cache[$module_name]; // replace content $template = preg_replace('~<body(.*?)>.*</body>~smui', '<body$1><div class="admin-content">' . $module['object']->AdminGenerator() . '</div></body>', $template, 1); $template = preg_replace(macro_regexp('page_title'), 'администрирование: "' . CMS::$cache[$_GET['module']]['config']['comment'] . '"', $template, 1); // remove user's CSS from template $template = preg_replace('~<link[^>]*rel="stylesheet"[^>]*href="(\\./|)userfiles[^">]*"[^>]*>~', '', $template); $template = preg_replace('~<link[^>]*href="(\\./|)userfiles[^">]*"[^>]*rel="stylesheet"[^>]*>~', '', $template); // also add module's admin CSSes and scripts add_CSS(get_array_value($module['config'], 'admin_css', array()), MODULES_DIR . $module_name . '/'); add_JS(get_array_value($module['config'], 'admin_js', array()), MODULES_DIR . $module_name . '/'); } // add button box to the template $admin_box_html = XSLTransform($xml->saveXML($root_node), __DIR__ . '/admin_box.xsl'); $template = preg_replace('~<body(.*?)>~', '<body$1>' . $admin_box_html, $template, 1); return $template; }
/** * Content generator - creates table-formed report * */ function contentGenerator($template) { // append userapi scripts and CSS if (is_dir('userapi/js/')) { $user_js_files = scandir('userapi/js/'); foreach ($user_js_files as $user_js_file) { if (pathinfo($user_js_file, PATHINFO_EXTENSION) == 'js') { add_JS('userapi/js/' . $user_js_file); logthis('userAPI script added: ' . $user_js_file); } } } if (is_dir('userapi/css/')) { $user_css_files = scandir('userapi/css/'); foreach ($user_css_files as $user_css_file) { if (pathinfo($user_css_file, PATHINFO_EXTENSION) == 'css') { add_CSS('userapi/css/' . $user_css_file); logthis('userAPI CSS added: ' . $user_css_file); } } } // replace all templates to generated content while (preg_match(macro_regexp('db'), $template, $match) > 0) { // parse template parameters into array $params = parse_plugin_template($match[0]); // generate HTML if (!isset($params['id'])) { $table_html = '<b>[JuliaCMS][db] error:</b> no ID specified for the table'; } else { // all API/UI require "report_id" parameter $params['report_id'] = $params['id']; $table_html = J_DB_UI::generateTable($params, $this->DB); } // replace $template = str_replace($match[0], $table_html, $template); } // yeah we are ready return $template; }
/** * Main content generator * */ function contentGenerator($template) { // iterate all macros while (preg_match(macro_regexp('news'), $template, $match) > 0) { $menu_params = parse_plugin_template($match[0]); // determine template $template_name = get_array_value($menu_params, 'template', false, '~^[a-zA-Zа-яА-Я_][a-zA-Zа-яА-Я_0-9]*$~u') ?: 'default'; $full_filename = __DIR__ . '/templates/' . $template_name . '.html'; if (!file_exists($full_filename)) { popup_message_add('[ NEWS ] template not found (name: ' . get_array_value($menu_params, 'template', 'not set') . ', filename: ' . $full_filename . ')', JCMS_MESSAGE_ERROR); return $template; } // get news as HTML $str = $this->newsGenerate(file_get_contents($full_filename), get_array_value($menu_params, 'stream', 'default'), get_array_value($menu_params, 'count', -1)); $template = str_replace($match[0], $str, $template); } return $template; }
/** * */ 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 contentGenerator($template) { $USERFILES_DIRS = CMS::$R['USERFILES_DIRS']; // если этот флажок есть, будет вызван редактор вместо отображения контента $edit_mode = isset($_GET['edit']); // идентификатор странички, которую надо вставить в шаблон. валидация не нужна - делается поиск в массиве // собираем список имеющихся страниц $pages = array(); $query = CMS::$DB->query("select * from `{$this->CONFIG['table']}`"); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $pages[$row['alias']] = $row; } $page_id = isset($_GET['p_id']) ? $_GET['p_id'] : DEFAULT_PAGE_ALIAS; // ок, берем стандартную страницу, если таковая есть $page_found = false; if (isset($pages[$page_id])) { $page_found = true; $page_info = $pages[$page_id]; } else { // если нужного идентификатора нет в страницах, посмотрим в меню, если там найдется - пускай сами разбираются if (module_get_config('menu', $menu_module_config) === true) { $query = CMS::$DB->query("select alias from `{$menu_module_config['config']['table_menu']}` where alias > ''"); while ($row = $query->fetch(PDO::FETCH_ASSOC)) { if ($page_id == $row['alias']) { $page_found = true; return $template; } } } } // если страница не найдена, попробуем использовать то, что указано в настройках для страницы 404, // если и там нету - тупо заменяем макрос на строку и вываливаемся if (!$page_found) { header('HTTP/1.1 404 Not found'); if (isset($pages[$this->CONFIG['page_404']])) { $page_info = $pages[$this->CONFIG['page_404']]; } else { $template = preg_replace(macro_regexp('content'), 'Страница не найдена', $template); return $template; } } // имя файла с контентом $content_filename = isset($page_info['filename']) && file_exists($USERFILES_DIRS['pages']['dir'] . $page_info['filename']) ? $USERFILES_DIRS['pages']['dir'] . $page_info['filename'] : $this->CONFIG['page_404']; // в режиме редактирования текст/xml не генерируем, а показываем в редакторе (textarea) if ($edit_mode && user_allowed_to('edit pages')) { switch (pathinfo($page_info['filename'], PATHINFO_EXTENSION)) { case 'php': case 'xml': $pagehtml = sprintf(MODULE_CONTENT_TEXTAREA_WRAPPER_PHP, $page_id, @file_get_contents($content_filename)); break; default: $pagecontent = @file_get_contents($content_filename); // при редактировании заменим макросы на защищенную версию, иначе следующие модули на них среагируют // и заменят на свой контент, что наи не нужно. ядро само заменит их обратно потом $pagecontent = str_replace('<macro', '<protected-macro', $pagecontent); $pagecontent = str_replace('[macro', '[protected-macro', $pagecontent); $pagecontent = str_replace('</macro', '</protected-macro', $pagecontent); $pagecontent = str_replace('[/macro', '[/protected-macro', $pagecontent); $pagehtml = sprintf(MODULE_CONTENT_TEXTAREA_WRAPPER, $page_id, $pagecontent); break; } } else { // если html, тащим как есть, иначе формируем с помошью генератора или XSLT switch ($ext = pathinfo($content_filename, PATHINFO_EXTENSION)) { case 'php': include_once $content_filename; $pagehtml = call_user_func($page_info['generator']); break; case 'xml': $pagehtml = XSLTransform($content_filename, $USERFILES_DIRS['xsl']['dir'] . $page_info['xsl'], false, false); break; default: ($pagehtml = file_get_contents($content_filename)) !== false or $pagehtml = 'error reading page content (code CONTENT/001)'; break; } } // если есть BODY, берем его внутреннее содержимое, иначе весь файл целиком if (preg_match(self::REGEXP_HTML_BODY, $pagehtml, $page_body) > 0) { $replace = $page_body[1]; } else { $replace = $pagehtml; } if (isset($_GET['print'])) { $template = str_replace('%content%', $replace, MODULE_CONTENT_PRINT_FORM); } else { $template = preg_replace(macro_regexp('content'), $replace, $template); } // мета в заголовке. если только буквы-цифры, делаем мету keywords if (preg_match('~^[a-zA-Zа-яА-Я0-9,.\\-\\s]+$~ui', $page_info['meta'], $match)) { $template = add_meta($template, 'name', 'keywords', $match[0]); } elseif (preg_match_all('~(\\(([a-zA-Z\\-]*)\\|([a-zA-Z\\-0-9]+)\\|([a-zA-Z\\-0-9а-яА-Я.,;:\\s+=!@#$%^&*\\(\\)]*)\\))~smui', $page_info['meta'], $matches)) { // не прокатило, попробуем структуру со скобками и пайпами for ($i = 0; $i < count($matches[0]); $i++) { $template = add_meta($template, $matches[2][$i], $matches[3][$i], $matches[4][$i]); } } elseif (preg_match_all('~<meta\\s[^>]+>~smui', $page_info['meta'], $matches)) { // проверим, возможно вписали сырые теги for ($i = 0; $i < count($matches[0]); $i++) { $template = str_insert_before('</head>', $matches[0][$i] . PHP_EOL, $template); } } // заменяем залоговок страницы, если определен if (isset($page_info['title']) && ($replace = $page_info['title']) > '') { $template = preg_replace(macro_regexp('page_title'), $replace, $template, 1); } // кастомный CSS, если указан if (isset($page_info['custom_css']) && ($css = $page_info['custom_css']) > '') { add_CSS(CMS::$R['USERFILES_DIRS']['css']['dir'] . $css); } // кастомный JS, если указан if (isset($page_info['custom_js']) && ($js = $page_info['custom_js']) > '') { add_JS(CMS::$R['USERFILES_DIRS']['js']['dir'] . $js); } return $template; }
/** * */ function contentGenerator($template) { // catalog mode: intercept _GET page alias, look in self elements, display child items list if exists $input_filter = array('p_id' => array('filter' => FILTER_VALIDATE_REGEXP, 'options' => array('regexp' => REGEXP_ALIAS))); $_INPUT = get_filtered_input($input_filter, array(FILTER_GET_BY_LIST)); if ($_INPUT['p_id'] > '') { // this will mean that nothing was found $id = -1; $query = CMS::$DB->query("select * from `{$this->CONFIG['table_menu']}` where alias = '{$_INPUT['p_id']}'"); if ($row = $query->fetch(PDO::FETCH_ASSOC)) { $id = $row['id']; $css_content = $row['style_content']; $caption = $row['caption']; $title = $row['title'] ? $row['title'] : $row['caption']; $meta = $row['meta']; } // if we found something, insert it instead content if ($id >= 0) { while (preg_match(macro_regexp('content'), $template, $match) > 0) { $params = parse_plugin_template($match[0]); $html = $this->generateCatalogPageHTML($_INPUT['p_id'], $params); // possibly we will need navigator from the current page if (get_array_value($params, 'show-navigator', 'yes') == 'yes') { $html = $this->generateNavigatorHTML($_INPUT['p_id'], $params) . $html; } $template = preg_replace(macro_regexp('content'), $html, $template); $template = preg_replace(macro_regexp('page_title'), $title, $template); // add meta. if only letter and digits, make "keywords" meta (!copy-paste detected!) if (preg_match('~^[a-zA-Zа-яА-Я0-9,.\\-\\s]+$~ui', $meta, $match)) { $template = add_meta($template, 'name', 'keywords', $match[0]); } elseif (preg_match_all('~(\\(([a-zA-Z\\-]*)\\|([a-zA-Z\\-0-9]+)\\|([a-zA-Z\\-0-9а-яА-Я.,;:\\s+=!@#$%^&*\\(\\)]*)\\))~smui', $meta, $matches)) { // не прокатило, попробуем структуру со скобками и пайпами for ($i = 0; $i < count($matches[0]); $i++) { $template = add_meta($template, $matches[2][$i], $matches[3][$i], $matches[4][$i]); } } elseif (preg_match_all('~<[a-zA-Z]+\\s[^<>]+>~smui', $meta, $matches)) { // check if raw tags there for ($i = 0; $i < count($matches[0]); $i++) { $template = str_insert_before('</head>', $matches[0][$i] . PHP_EOL, $template); } } // yeah, nice stylesheets add_CSS($css_content, CMS::$R['USERFILES_DIRS']['css']['dir']); } } } // standard behavior - menu by macro while (preg_match(macro_regexp('menu'), $template, $match) > 0) { // parse template parameters into array $params = parse_plugin_template($match[0]); // generate menu HTML $xml = $this->generateMenuAsXML(get_array_value($params, 'start-from', '')); $xsl = get_array_value($params, 'menu-template', 'default'); // now test with path $xsl_filename = __DIR__ . '/../../userfiles/_data_modules/menu/templates/menu/' . $xsl . '.xsl'; if (!file_exists($xsl_filename)) { $xsl_filename = __DIR__ . '/templates/' . $catalog_dir . '/' . $xsl . '.xsl'; } $html = XSLTransform($xml->saveXML($xml->documentElement), $xsl_filename); // replace it $template = str_replace($match[0], $html, $template); } // navigator mode while (preg_match(macro_regexp('menu-navigator'), $template, $match) > 0) { // parse template parameters into array $params = parse_plugin_template($match[0]); // generate navigator HTML $html = $this->generateNavigatorHTML(get_array_value($params, 'start-from', ''), $params); // replace it $template = str_replace($match[0], $html, $template); } // yeah we are ready return $template; }
/** * Places feedback form from the file * * Macro parameters available: * "form" : specifies a file to get a form from (no extension, will be added automatically, "default" by default) * "target" : get recipient from the config list (first item by default) * "template" : forces to add "template" hidden input to the form causing sender to use alternate email template * * @param string $template source template * @return string */ function contentGenerator($template) { // look for macro while (preg_match(macro_regexp('feedback'), $template, $match) > 0) { $params = parse_plugin_template($match[0]); // now get form HTML. if no source found specified, try to use "default.html". Malformed values always generate an error if ($filename = get_array_value($params, 'form', 'default', REGEXP_IDENTIFIER)) { if (file_exists(__DIR__ . '/forms/' . $filename . '.html')) { $form = file_get_contents(__DIR__ . '/forms/' . $filename . '.html'); } else { $form = '<b>[JuliaCMS][feedback] error:</b> form file "' . $filename . '.html" not found'; } } else { $form = '<b>[JuliaCMS][feedback] error:</b> bad form name "' . $params['form'] . '"'; } // let's determine form target (source form's one will be deleted automatically) $target = get_array_value($params, 'target', false); $address_keys = array_keys($this->CONFIG['addresses']); $recipient = isset($this->CONFIG['addresses'][$target]) ? $target : array_shift($address_keys); // ok, implant recipient field into a form (first, cut existing if any) $form = preg_replace('~<input\\s[^>]*?name="recipient"[^/>]*/?>~', '', $form); $form = str_insert_before('</form>', '<input type="hidden" name="recipient" value="' . $recipient . '" />', $form); // add (or replace) template identifier, if specified $message_template_name = get_array_value($params, 'template', '', REGEXP_IDENTIFIER); if ($message_template_name > '') { $form = preg_replace('~<input\\s[^>]*?name="template"[^/>]*/?>~', '', $form); $form = str_insert_before('</form>', '<input type="hidden" name="template" value="' . $message_template_name . '" />', $form); } // form ready, add it to template! $template = str_replace($match[0], $form, $template); } return $template; }