Index: core/kernel/application.php =================================================================== --- core/kernel/application.php +++ core/kernel/application.php @@ -733,6 +733,7 @@ $this->registerClass('kCatDBTagProcessor', KERNEL_PATH . '/db/cat_tag_processor.php'); $this->registerClass('NParser', KERNEL_PATH . '/nparser/nparser.php'); $this->registerClass('TemplatesCache', KERNEL_PATH . '/nparser/template_cache.php'); + $this->registerClass('TemplateCommentParser', KERNEL_PATH . '/utility/template_comment_parser.php'); // database $this->registerClass('kDBConnection', KERNEL_PATH . '/db/db_connection.php'); Index: core/kernel/utility/template_comment_parser.php =================================================================== --- /dev/null +++ core/kernel/utility/template_comment_parser.php @@ -0,0 +1,163 @@ +<?php +/** + * Template comment parser + * + * @version $Id$ + * @package In-Portal + * @copyright Copyright (C) 1997 - 2015 Intechnic. All rights reserved. + * @license GNU/GPL + * In-Portal is Open Source software. + * This means that this software may have been modified pursuant + * the GNU General Public License, and as distributed it includes + * or is derivative of works licensed under the GNU General Public License + * or other free or open source software licenses. + * See http://www.in-portal.org/license for copyright notices and details. + */ + +defined('FULL_PATH') or die('restricted access!'); + +class TemplateCommentParser +{ + + /** + * Path to template + * + * @var string + */ + protected $templateFile; + + /** + * Supported settings + * + * @var array + */ + protected $supportedSettings = array( + 'NAME' => array('type' => 'string', 'default' => ''), + 'DESC' => array('type' => 'string', 'default' => ''), + 'SECTION' => array('type' => 'category_path', 'default' => ''), + ); + + /** + * Gets and checks path to template + * + * @param string $template_file Template file. + */ + public function __construct($template_file) + { + $this->templateFile = $template_file; + } + + /** + * Parses template comment + * + * @return array + * @throws Exception When template comment can't be parsed. + */ + public function parse() + { + if ( !file_exists($this->templateFile) ) { + throw new Exception('Template file "' . $this->templateFile . '" not found.'); + } + + $result = $this->getDefaults(); + $template_data = file_get_contents($this->templateFile); + + if ( substr($template_data, 0, 6) != '<!--##' ) { + return $result; + } + + // template starts with comment in such format + /*<!--## + <NAME></NAME> + <DESC></DESC> + <SECTION>||</SECTION> + ##-->*/ + + $comment_end = strpos($template_data, '##-->'); + + if ( $comment_end === false ) { + throw new Exception('Template file "' . $this->templateFile . '" missing end of comment.'); + } + + $comment = trim(substr($template_data, 6, $comment_end - 6)); + + if ( strpos($comment, PHP_EOL) === false ) { + return $result; + } + + $xml_parser = xml_parser_create(); + $is_valid = xml_parse_into_struct($xml_parser, '<comment>' . $comment . '</comment>', $values, $index); + xml_parser_free($xml_parser); + $exception_message_start = 'Template file "' . $this->templateFile . '" have '; + + if ( !$is_valid ) { + throw new Exception($exception_message_start . 'invalid XML in the comment.'); + } + + array_shift($index); + + foreach ( $index as $setting => $section_index ) { + if ( !isset($this->supportedSettings[$setting]) ) { + throw new Exception($exception_message_start . 'unsupported setting "' . $setting . '".'); + } + + $result_key = strtolower($setting); + + if ( isset($values[$section_index[0]]['value']) ) { + $result[$result_key] = $values[$section_index[0]]['value']; + } + + switch ( $this->supportedSettings[$setting]['type'] ) { + case 'category_path': + $category_path = explode('||', $result[$result_key]); + $category_path = array_map('trim', $category_path); + $result[$result_key] = implode('||', $category_path); + + break; + case 'integer': + $parsed = (int)$result[$result_key]; + + if ( (string)$parsed != $result[$result_key] ) { + throw new Exception( + $exception_message_start . ' must have integer value in setting "' . $setting . '".' + ); + } + + if ( $parsed < 1 ) { + throw new Exception( + $exception_message_start . ' may have only positive value in setting "' . $setting . '".' + ); + } + break; + + case 'boolean': + if ( $result[$result_key] !== 'yes' && $result[$result_key] !== 'no' ) { + throw new Exception( + $exception_message_start . ' must have "yes" or "no" value in setting "' . $setting . '".' + ); + } + + $result[$result_key] = $result[$result_key] == 'yes'; + } + } + + return $result; + } + + /** + * Get default values + * + * @return array + */ + protected function getDefaults() + { + $result = array(); + + foreach ( $this->supportedSettings as $setting => $options ) { + $result[strtolower($setting)] = $options['default']; + } + + return $result; + } + +} Index: core/units/helpers/themes_helper.php =================================================================== --- core/units/helpers/themes_helper.php +++ core/units/helpers/themes_helper.php @@ -376,7 +376,7 @@ elseif ( pathinfo($filename, PATHINFO_EXTENSION) == 'tpl' ) { $meta_info = $this->_getTemplateMetaInfo(trim($file_path, '/'), $theme_id); $file_id = isset($this->themeFiles[$file_path]) ? $this->themeFiles[$file_path] : false; - $file_description = array_key_exists('desc', $meta_info) ? $meta_info['desc'] : ''; + $file_description = $meta_info['desc']; if ($file_id) { // file was found in db & on hdd -> mark as existing @@ -449,51 +449,9 @@ $template = 'theme:' . $this->_themeNames[$theme_id] . '/' . $template; $template_file = $this->Application->TemplatesCache->GetRealFilename($template); // ".tpl" was added before + $template_comment_parser = $this->Application->makeClass('TemplateCommentParser', array($template_file)); - return $this->parseTemplateMetaInfo($template_file); - } - - function parseTemplateMetaInfo($template_file) - { - if (!file_exists($template_file)) { - // when template without info it's placed in top category - return Array (); - } - - $template_data = file_get_contents($template_file); - - if (substr($template_data, 0, 6) == '<!--##') { - // template starts with comment in such format - /*<!--## - <NAME></NAME> - <DESC></DESC> - <SECTION>||</SECTION> - ##-->*/ - - $comment_end = strpos($template_data, '##-->'); - if ($comment_end === false) { - // badly formatted comment - return Array (); - } - - $comment = trim( substr($template_data, 6, $comment_end - 6) ); - if (preg_match_all('/<(NAME|DESC|SECTION)>(.*?)<\/(NAME|DESC|SECTION)>/is', $comment, $regs)) { - $ret = Array (); - foreach ($regs[1] as $param_order => $param_name) { - $ret[ strtolower($param_name) ] = trim($regs[2][$param_order]); - } - - if (array_key_exists('section', $ret) && $ret['section']) { - $category_path = explode('||', $ret['section']); - $category_path = array_map('trim', $category_path); - $ret['section'] = implode('||', $category_path); - } - - return $ret; - } - } - - return Array (); + return $template_comment_parser->parse(); } /** Index: core/units/theme_files/theme_file_eh.php =================================================================== --- core/units/theme_files/theme_file_eh.php +++ core/units/theme_files/theme_file_eh.php @@ -119,11 +119,9 @@ fwrite($fp, $object->GetDBField('FileContents')); fclose($fp); - $themes_helper = $this->Application->recallObject('ThemesHelper'); - /* @var $themes_helper kThemesHelper */ - - $meta_info = $themes_helper->parseTemplateMetaInfo($filename); - $file_description = array_key_exists('desc', $meta_info) ? $meta_info['desc'] : ''; + $template_comment_parser = $this->Application->makeClass('TemplateCommentParser', array($filename)); + $meta_info = $template_comment_parser->parse(); + $file_description = $meta_info['desc']; $object->SetDBField('Description', $file_description); $object->SetDBField('FileMetaInfo', serialize($meta_info));