Index: branches/RC/core/units/general/helpers/template_helper.php =================================================================== diff -u -N -r11892 -r11963 --- branches/RC/core/units/general/helpers/template_helper.php (.../template_helper.php) (revision 11892) +++ branches/RC/core/units/general/helpers/template_helper.php (.../template_helper.php) (revision 11963) @@ -1,6 +1,6 @@ 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