Index: branches/RC/core/units/general/helpers/template_helper.php
===================================================================
diff -u -N
--- branches/RC/core/units/general/helpers/template_helper.php (revision 11963)
+++ branches/RC/core/units/general/helpers/template_helper.php (revision 0)
@@ -1,448 +0,0 @@
-_initMade) {
- return ;
- }
-
- define('DBG_IGNORE_FATAL_ERRORS', 1);
-
- // 1. get block information
- $block_info = $this->Application->GetVar('block');
- list ($this->_blockName, $this->_functionName) = explode(':', $block_info);
-
- $this->_parseTemplate($object);
-
- if (array_key_exists($this->_functionName, $this->Application->Parser->ElementLocations)) {
- $this->_blockLocation = $this->Application->Parser->ElementLocations[$this->_functionName];
- }
-
- $this->_initMade = true;
- }
-
- function _getSourceTemplate()
- {
- // get source template
- $t = $this->Application->GetVar('source');
-
- if (!$this->Application->TemplatesCache->TemplateExists($t)) {
- $cms_handler =& $this->Application->recallObject('st_EventHandler');
- /* @var $cms_handler StructureEventHandler */
-
- $t = ltrim($cms_handler->GetDesignTemplate($t), '/');
- }
-
- $this->_sourceTemplate = $t;
- }
-
- function _getThemeName()
- {
- $theme_id = (int)$this->Application->GetVar('theme_id');
-
- $sql = 'SELECT Name
- FROM ' . $this->Application->getUnitOption('theme', 'TableName') . '
- WHERE ' . $this->Application->getUnitOption('theme', 'IDField') . ' = ' . $theme_id;
- return $this->Conn->GetOne($sql);
- }
-
- /**
- * Render source template to get parse errors OR it's element locations
- *
- * @param kDBItem $object
- * @param string $append
- * @return bool
- */
- function _parseTemplate(&$object, $append = '')
- {
- // 1. set internal error handler to catch all parsing errors
- $error_handlers = $this->Application->errorHandlers;
- $this->Application->errorHandlers = Array (
- Array (&$this, '_saveError'),
- );
-
- // 2. parse template
- $this->Application->InitParser( $this->_getThemeName() ); // we have no parser when saving block content
-
- $this->_getSourceTemplate();
-
- // design templates have leading "/" in the beginning
- $this->Application->Parser->Run($this->_sourceTemplate . $append);
-
- // 3. restore original error handler
- $this->Application->errorHandlers = $error_handlers;
-
- if ($this->_parseErrors) {
- if ($this->_isMainTemplate()) {
- // 3.1. delete temporary file, that was parsed
- $filename = $this->_getTemplateFile(false, $append . '.tpl');
- if (!unlink($filename)) {
- $error_file = $this->_getTemplateFile(true, $append . '.tpl');
- $object->SetError('FileContents', 'template_delete_failed', '+Failed to delete temporary template "' . $error_file . '"');
- return false;
- }
- }
- else {
- // 3.2. restore backup
- if (!rename($this->_getTemplateFile(false, '.tpl.bak'), $this->_getTemplateFile(false))) {
- $error_file = $this->_getTemplateFile(true);
- $object->SetError('FileContents', 'template_restore_failed', '+Failed to restore template "' . $error_file . '" from backup.');
- return false;
- }
- }
-
- return false;
- }
-
- return true;
- }
-
- /**
- * Move elements in template and save changes, when possible
- *
- * @param Array $target_order
- * @return bool
- */
- function moveTemplateElements($target_order)
- {
- // 2. parse template
- $this->Application->InitParser(); // we have no parser when saving block content
-
- $this->_getSourceTemplate();
-
- $filename = $this->Application->TemplatesCache->GetRealFilename($this->_sourceTemplate) . '.tpl';
- if (!is_writable($filename)) {
- // we can't save changes, don't bother calculating new template contents
- return false;
- }
-
- $data = file_get_contents($filename);
-
- $line_ending = strpos($data, "\r") !== false ? "\r\n" : "\n";
-
- // 1. get location of movable areas
- $mask = '';
- $start_pos = 0;
- $elements = Array ();
- $areas = $this->_getDivPairs($data, 'movable-area');
- foreach ($areas as $area_index => $area) {
- // 1.1. get locations of all movable elements inside given area
- $area_content = substr($area['data'], $area['open_len'], -$area['close_len']);
- $elements = array_merge($elements, $this->_getDivPairs($area_content, 'movable-element', $area_index, $area['open_pos'] + $area['open_len']));
-
- // 1.2. prepare mask to place movable elements into (don't include movable area div ifself)
- $mask .= "\t" . substr($data, $start_pos, $area['open_pos'] + $area['open_len'] - $start_pos) . $line_ending . "\t\t" . '#AREA' . $area_index . '#' . $line_ending;
- $start_pos = $area['close_pos'] - $area['close_len'];
- }
- $mask = trim($mask . "\t" . substr($data, $area['close_pos'] - $area['close_len']));
-
- if (!$elements) {
- // no elements found
- return false;
- }
-
- foreach ($areas as $area_index => $area) {
- $area_content = '';
- $target_elements = $target_order[$area_index];
- foreach ($target_order[$area_index] as $old_location) {
- $area_content .= $elements[$old_location]['data'] . $line_ending . "\t\t";
- }
-
- $mask = str_replace('#AREA' . $area_index . '#', trim($area_content), $mask);
- }
-
- $fp = fopen($filename, 'w');
- fwrite($fp, $mask);
- fclose($fp);
-
- return true;
- }
-
- /**
- * Extracts div pairs with given class from given text
- *
- * @param string $data
- * @param string $class
- * @param int $area
- * @param int $offset
- * @return Array
- */
- function _getDivPairs(&$data, $class, $area = null, $offset = 0)
- {
- preg_match_all('/(
]*>)|(<\/div>)/s', $data, $divs, PREG_SET_ORDER + PREG_OFFSET_CAPTURE);
-
- $skip_count = 0;
- $pairs = Array ();
-
- foreach ($divs as $div) {
- if (strpos($div[0][0], '/') === false) {
- // opening div
- if (strpos($div[0][0], $class) !== false) {
- $pair = Array ('open_pos' => $div[0][1], 'open_len' => strlen($div[0][0]));
- $skip_count = 0;
- }
- else {
- $skip_count++;
- }
- }
- else {
- // closing div
- if ($skip_count == 0) {
- $pair['close_len'] = strlen($div[0][0]);
- $pair['close_pos'] = $div[0][1] + $pair['close_len'];
- $pair['data'] = substr($data, $pair['open_pos'], $pair['close_pos'] - $pair['open_pos']);
-
- if (isset($area)) {
- $pair['open_pos'] += $offset;
- $pair['close_pos'] += $offset;
- // index indicates area
- $pairs['a' . $area . 'e' . count($pairs)] = $pair;
- }
- else {
- $pairs[] = $pair;
- }
- }
- else {
- $skip_count--;
- }
- }
- }
-
- return $pairs;
- }
-
- /**
- * Returns information about parser element locations in template
- *
- * @param Array $params
- * @return mixed
- */
- function blockInfo($info_type)
- {
- switch ($info_type) {
- case 'block_name':
- return $this->_blockName;
- break;
-
- case 'function_name':
- return $this->_functionName;
- break;
-
- case 'start_pos':
- case 'end_pos':
- case 'template':
- if (!array_key_exists($info_type, $this->_blockLocation)) {
- // invalid block name
- return 'invalid block name';
- }
-
- return $this->_blockLocation[$info_type];
- break;
-
- case 'template_file':
- return $this->_getTemplateFile(true);
- break;
-
- case 'content':
- $template_body = file_get_contents( $this->_getTemplateFile() );
- $length = $this->_blockLocation['end_pos'] - $this->_blockLocation['start_pos'];
-
- return substr($template_body, $this->_blockLocation['start_pos'], $length);
- break;
- }
-
- return 'undefined';
- }
-
- /**
- * Main template being edited (parse copy, instead of original)
- *
- * @return bool
- */
- function _isMainTemplate()
- {
- return $this->_blockLocation['template'] == $this->_sourceTemplate;
- }
-
- /**
- * Returns filename, that contains template, where block is located
- *
- * @return string
- */
- function _getTemplateFile($relative = false, $extension = '.tpl')
- {
- $filename = $this->Application->TemplatesCache->GetRealFilename( $this->_blockLocation['template'] ) . $extension;
-
- if ($relative) {
- $filename = preg_replace('/^' . preg_quote(FULL_PATH, '/') . '/', '', $filename, 1);
- }
-
- return $filename;
- }
-
- /**
- * Saves new version of block to template, where it's located
- *
- * @param kDBItem $object
- */
- function saveBlock(&$object)
- {
- $main_template = $this->_isMainTemplate();
- $filename = $this->_getTemplateFile(false);
-
- // 1. get new template content
- $new_template_body = $this->_getNewTemplateContent($object, $filename, $lines_before);
- if (is_bool($new_template_body) && ($new_template_body === true)) {
- // when nothing changed -> stop processing
- return true;
- }
-
- // 2. backup original template
- if (!$main_template && !copy($filename, $filename . '.bak')) {
- // backup failed
- $error_file = $this->_getTemplateFile(true, '.tpl.bak');
- $object->SetError('FileContents', 'template_backup_failed', '+Failed to create backup template "' . $error_file . '" backup.');
- return false;
- }
-
- // 3. save changed template
- $save_filename = $this->_getTemplateFile(false, $main_template ? '.tmp.tpl' : '.tpl');
- $fp = fopen($save_filename, 'w');
- if (!$fp) {
- // backup template create failed OR existing template save
- $error_file = $this->_getTemplateFile(true, $main_template ? '.tmp.tpl' : '.tpl');
- $object->SetError('FileContents', 'template_changes_save_failed', '+Failed to save template "' . $error_file . '" changes.');
- return false;
- }
- fwrite($fp, $new_template_body);
- fclose($fp);
-
- // 3. parse template to check for errors
- $this->_parseTemplate($object, $main_template ? '.tmp' : '');
-
- if ($this->_parseErrors) {
- $error_msg = Array ();
- foreach ($this->_parseErrors as $error_data) {
- if (preg_match('/line ([\d]+)/', $error_data['msg'], $regs)) {
- // another line number inside message -> patch it
- $error_data['msg'] = str_replace('line ' . $regs[1], 'line ' . ($regs[1] - $lines_before), $error_data['msg']);
- }
-
- $error_msg[] = $error_data['msg'] . ' at line ' . ($error_data['line'] - $lines_before);
- }
-
- $object->SetError('FileContents', 'template_syntax_error', '+Template syntax errors:
' . implode('
', $error_msg));
- return false;
- }
-
- if ($main_template) {
- // 4.1. replace original file with temporary
- if (!rename($this->_getTemplateFile(false, '.tmp.tpl'), $filename)) {
- // failed to save new content to original template
- $error_file = $this->_getTemplateFile(true);
- $object->SetError('FileContents', 'template_save_failed', '+Failed to save template "' . $error_file . '".');
- return false;
- }
- }
- else {
- // 4.2. delete backup
- unlink( $this->_getTemplateFile(false, '.tpl.bak') );
- }
-
- return true;
- }
-
- /**
- * Returns new template content of "true", when nothing is changed
- *
- * @param kDBItem $object
- * @param string $filename
- * @param int $lines_before
- * @return mixed
- */
- function _getNewTemplateContent(&$object, $filename, &$lines_before)
- {
- $new_content = $object->GetDBField('FileContents');
-
- $template_body = file_get_contents($filename);
- $lines_before = substr_count(substr($template_body, 0, $this->_blockLocation['start_pos']), "\n");
-
- $new_template_body = substr($template_body, 0, $this->_blockLocation['start_pos']) .
- $new_content .
- substr($template_body, $this->_blockLocation['end_pos']);
-
- return crc32($template_body) == crc32($new_template_body) ? true : $new_template_body;
- }
-
- function _saveError($errno, $errstr, $errfile, $errline, $errcontext)
- {
- if ($errno != E_USER_ERROR) {
- // ignore all minor errors, except fatals from parser
- return true;
- }
-
- /*if (defined('E_STRICT') && ($errno == E_STRICT)) {
- // always ignore strict errors here (specially when not in debug mode)
- return true;
- }*/
-
- $this->_parseErrors[] = Array ('msg' => $errstr, 'file' => $errfile, 'line' => $errline);
- return true;
- }
- }
\ No newline at end of file