Index: core/units/helpers/helpers_config.php =================================================================== --- core/units/helpers/helpers_config.php +++ core/units/helpers/helpers_config.php @@ -78,5 +78,6 @@ Array ('pseudo' => 'AjaxFormHelper', 'class' => 'AjaxFormHelper', 'file' => 'ajax_form_helper.php', 'build_event' => ''), Array ('pseudo' => 'kCronHelper', 'class' => 'kCronHelper', 'file' => 'cron_helper.php', 'build_event' => ''), Array ('pseudo' => 'kUploadHelper', 'class' => 'kUploadHelper', 'file' => 'upload_helper.php', 'build_event' => ''), + array('pseudo' => 'TemplateCommentParser', 'class' => 'TemplateCommentParser', 'file' => 'template_comment_parser.php', 'build_event' => ''), ), ); Index: core/units/helpers/template_comment_parser.php =================================================================== --- /dev/null +++ core/units/helpers/template_comment_parser.php @@ -0,0 +1,181 @@ + 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. + * + * @throws Exception When template file not found. + */ + public function __construct($template_file) + { + if ( !file_exists($template_file) ) { + throw new Exception('Template file "' . $template_file . '" not found.'); + } + + $this->templateFile = $template_file; + } + + /** + * Parses template comment + * + * @return array + * @throws Exception When missing end of template comment. + * @throws Exception When invalid XML in the template comment. + */ + public function parse() + { + $result = $this->getDefaults(); + $template_data = file_get_contents($this->templateFile); + + if ( substr($template_data, 0, 6) != ' + */ + + $comment_end = strpos($template_data, '##-->'); + + if ( $comment_end === false ) { + throw new Exception(sprintf( + 'Unclosed meta-comment in "%s" template file.', + $this->templateFile + )); + } + + $comment = trim(substr($template_data, 6, $comment_end - 6)); + + if ( strpos($comment, PHP_EOL) === false ) { + return $result; + } + + if ( preg_match_all('/<([^>]*)>(.*?)<\/([^>]*)>/is', $comment, $regs) ) { + $result = array(); + + foreach ( $regs[1] as $param_order => $setting_name ) { + $result[strtolower($setting_name)] = $this->parseSettingValue( + $setting_name, + trim($regs[2][$param_order]) + ); + } + } + + 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; + } + + /** + * Parses setting value + * + * @param string $name Name. + * @param string $value Value. + * + * @return mixed + * @throws Exception When unsupported setting in the template comment. + * @throws Exception When missing integer value in the template comment. + * @throws Exception When missing positive value in the template comment. + * @throws Exception When missing "yes" or "no" value in the template comment. + */ + protected function parseSettingValue($name, $value) + { + if ( !isset($this->supportedSettings[$name]) ) { + throw new Exception(sprintf( + 'Meta-comment in "%s" template file contains unsupported setting "%s". Supported settings are: %s.', + $this->templateFile, + $name, + '"' . implode('", "', array_keys($this->supportedSettings)) . '"' + )); + } + + switch ( $this->supportedSettings[$name]['type'] ) { + case 'category_path': + $category_path = explode('||', $value); + $category_path = array_map('trim', $category_path); + $value = implode('||', $category_path); + break; + + case 'integer': + $parsed = (int)$value; + + if ( (string)$parsed != $value || $parsed < 0 ) { + throw new Exception(sprintf( + 'Only positive numbers are allowed as "%2$s" setting value in "%1$s" template file.', + $this->templateFile, + $name + )); + } + break; + + case 'boolean': + if ( $value !== 'yes' && $value !== 'no' ) { + throw new Exception(sprintf( + 'Only "yes" or "no" are allowed as "%2$s" setting value in "%1$s" template file.', + $this->templateFile, + $name + )); + } + + $value = $value == 'yes'; + } + + return $value; + } + +} 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 @@ -453,47 +453,19 @@ return $this->parseTemplateMetaInfo($template_file); } - function parseTemplateMetaInfo($template_file) + /** + * Parses template meta info + * + * @param string $template_file Template file. + * + * @return array + */ + public 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) == '*/ - - $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; - } - } + /** @var TemplateCommentParser $template_comment_parser */ + $template_comment_parser = $this->Application->makeClass('TemplateCommentParser', array($template_file)); - 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,13 +119,11 @@ fwrite($fp, $object->GetDBField('FileContents')); fclose($fp); - /** @var kThemesHelper $themes_helper */ - $themes_helper = $this->Application->recallObject('ThemesHelper'); + /** @var TemplateCommentParser $template_comment_parser */ + $template_comment_parser = $this->Application->makeClass('TemplateCommentParser', array($filename)); + $meta_info = $template_comment_parser->parse(); - $meta_info = $themes_helper->parseTemplateMetaInfo($filename); - $file_description = array_key_exists('desc', $meta_info) ? $meta_info['desc'] : ''; - - $object->SetDBField('Description', $file_description); + $object->SetDBField('Description', $meta_info['desc']); $object->SetDBField('FileMetaInfo', serialize($meta_info)); $object->Update(); }