Index: branches/RC/core/units/general/helpers/category_helper.php
===================================================================
diff -u -r9279 -r11336
--- branches/RC/core/units/general/helpers/category_helper.php (.../category_helper.php) (revision 9279)
+++ branches/RC/core/units/general/helpers/category_helper.php (.../category_helper.php) (revision 11336)
@@ -15,7 +15,9 @@
$navigation_parts = $this->getNavigationParts($params['titles'], $params['templates']);
$ret = '';
- $block_params = Array ('category' => 0);
+ $block_params = Array (); //$params; // sort of TagProcessor:prepareTagParams
+ $block_params['no_editing'] = 1;
+ $block_params['category'] = 0;
$block_params['separator'] = $params['separator'];
$current_template = $this->Application->GetVar('t');
$show_category = getArrayValue($params, 'show_category');
@@ -162,6 +164,7 @@
function getHomeCategoryPath($params)
{
$block_params['cat_id'] = 0;
+ $block_params['no_editing'] = 1;
$block_params['cat_name'] = $this->Application->ProcessParsedTag('m', 'RootCategoryName', $params);
$block_params['name'] = $this->SelectParam($params, 'root_cat_render_as,render_as');
return $this->Application->ParseBlock($block_params);
Index: branches/RC/core/kernel/nparser/ntags.php
===================================================================
diff -u -r11214 -r11336
--- branches/RC/core/kernel/nparser/ntags.php (.../ntags.php) (revision 11214)
+++ branches/RC/core/kernel/nparser/ntags.php (.../ntags.php) (revision 11336)
@@ -209,8 +209,8 @@
$code[] = 'return $_output;';
$code[] = '}}';
- $end_pos = $this->Tag['pos'] + $tag['pos'] + strlen($tag['opening']) + strlen($tag['tag']) + strlen($tag['closing']) + TAG_NAMESPACE_LENGTH;
- $code[] = "\$_parser->ElementLocations['{$this->Tag['function_name']}'] = Array('file' => '{$this->Tag['file']}', 'start_pos' => {$this->Tag['pos']}, 'end_pos' => {$end_pos});";
+ $end_pos = $tag['pos'] + strlen($tag['opening']) + strlen($tag['tag']) + strlen($tag['closing']) + TAG_NAMESPACE_LENGTH;
+ $code[] = "\$_parser->ElementLocations['{$this->Tag['function_name']}'] = Array('template' => '{$this->Tag['template']}', 'start_pos' => {$this->Tag['pos']}, 'end_pos' => {$end_pos});";
$this->AppendCode($o, $code);
return $o;
@@ -310,6 +310,49 @@
}
}
+class _Tag_RenderElements extends _BlockTag {
+
+ function _Tag_RenderElements($tag)
+ {
+ parent::_BlockTag($tag);
+
+ $this->_requiredParams = Array ('elements');
+ }
+
+ function Open($tag)
+ {
+ $o = parent::Open($tag);
+
+ if ($o === false) {
+ // some required params not passed
+ return $o;
+ }
+
+ $element_names = array_map('trim', explode(',', $tag['NP']['elements']));
+ unset($tag['NP']['elements']);
+
+ $class = '_Tag_RenderElement';
+ $instance = new $class($tag);
+ /* @var $instance _Tag_RenderElement */
+
+ $instance->Parser =& $this->Parser;
+
+ $skip_elements = array_key_exists('skip', $tag['NP']) ? array_map('trim', explode(',', $tag['NP']['skip'])) : Array ();
+
+ foreach ($element_names as $element_name) {
+ if (in_array($element_name, $skip_elements) || !$element_name) {
+ // empty element name OR element should be excluded
+ continue;
+ }
+
+ $tag['NP']['name'] = $element_name;
+ $o .= $instance->Open($tag);
+ }
+
+ return $o;
+ }
+}
+
class _Tag_Param extends _BlockTag {
function _Tag_Param($tag)
Index: branches/RC/core/units/general/helpers/template_helper.php
===================================================================
diff -u
--- branches/RC/core/units/general/helpers/template_helper.php (revision 0)
+++ branches/RC/core/units/general/helpers/template_helper.php (revision 11336)
@@ -0,0 +1,273 @@
+Application->GetVar('block');
+ list ($this->_blockName, $this->_functionName) = explode(':', $block_info);
+
+ $this->_parseTemplate();
+
+ if (array_key_exists($this->_functionName, $this->Application->Parser->ElementLocations)) {
+ $this->_blockLocation = $this->Application->Parser->ElementLocations[$this->_functionName];
+ }
+ }
+
+ /**
+ * Render source template to get parse errors OR it's element locations
+ *
+ */
+ function _parseTemplate($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(); // we have no parser when saving block content
+ $this->Application->Parser->Run($this->Application->GetVar('source') . $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');
+ $this->Application->SetVar('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);
+ $this->Application->SetVar('Failed to restore template "' . $error_file . '" from backup.');
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * 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':
+ $function_body = $this->Application->GetVar('function_body');
+ if ($function_body !== false) {
+ // error happened -> use unsaved template content
+ return unhtmlentities( $function_body );
+ }
+
+ $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->Application->GetVar('source');
+ }
+
+ /**
+ * 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 kEvent $event
+ */
+ function saveBlock(&$event)
+ {
+ $main_template = $this->_isMainTemplate();
+ $filename = $this->_getTemplateFile(false);
+
+ // 1. get new template content
+ $new_template_body = $this->_getNewTemplateContent($filename, $lines_before);
+ if (is_bool($new_template_body) && ($new_template_body === true)) {
+ // when nothing changed -> stop processing
+ echo '0';
+ return true;
+ }
+
+ // 2. backup original template
+ if (!$main_template && !copy($filename, $filename . '.bak')) {
+ // backup failed
+ $error_file = $this->_getTemplateFile(true, '.tpl.bak');
+ $this->Application->SetVar('error_msg', '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');
+ $this->Application->SetVar('error_msg', '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($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);
+ }
+
+ $this->Application->SetVar('error_msg', '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);
+ $this->Application->SetVar('error_msg', 'Failed to save template "' . $error_file . '".');
+ return false;
+ }
+ }
+ else {
+ // 4.2. delete backup
+ unlink( $this->_getTemplateFile(false, '.tpl.bak') );
+ }
+
+ echo 1; // were changes
+
+ return true;
+ }
+
+ /**
+ * Returns new template content of "true", when nothing is changed
+ *
+ * @param string $filename
+ * @param int $lines_before
+ * @return mixed
+ */
+ function _getNewTemplateContent($filename, &$lines_before)
+ {
+ $new_content = unhtmlentities( $this->Application->GetVar('function_body') );
+
+ $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 (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
Index: branches/RC/core/units/admin/admin_events_handler.php
===================================================================
diff -u -r11173 -r11336
--- branches/RC/core/units/admin/admin_events_handler.php (.../admin_events_handler.php) (revision 11173)
+++ branches/RC/core/units/admin/admin_events_handler.php (.../admin_events_handler.php) (revision 11336)
@@ -146,6 +146,15 @@
$table_info = $this->Conn->Query('DESCRIBE '.$table_name);
// 1. prepare config keys
+ $grids = Array (
+ 'Default' => Array (
+ 'Icons' => Array ('default' => 'icon16_custom.gif'),
+ 'Fields' => Array (),
+ )
+ );
+
+ $grid_fields = Array();
+
$id_field = '';
$fields = Array();
$float_types = Array ('float', 'double', 'numeric');
@@ -156,6 +165,10 @@
}
$field_options = Array ();
+ $grid_col_options = Array(
+ 'title' => 'la_col_' . $field_info['Field'],
+ 'filter_block' => 'grid_like_filter',
+ );
// 1. get php field type by mysql field type
foreach ($types_hash as $php_type => $db_types) {
@@ -208,12 +221,17 @@
}
$fields[ $field_info['Field'] ] = $this->transformDump($field_options);
+ $grids_fields[ $field_info['Field'] ] = $this->transformDump($grid_col_options);
}
- $ret = stripslashes(var_export($fields, true));
+ $grids['Default']['Fields'] = $grids_fields;
+
+ $ret = "'IDField' => '".$id_field."',\n'Fields' => A".substr(stripslashes(var_export($fields, true)), 1).',';
+ $ret .= "\n"."'Grids' => ".stripslashes(var_export($grids, true));
+
+ $ret = str_replace('array (', 'Array (', $ret);
$ret = preg_replace("/'(.*?)' => 'Array \((.*?), \)',/", "'\\1' => Array (\\2),", $ret);
$ret = preg_replace("/\n '/", "\n\t'", $ret);
- $ret = "'IDField' => '".$id_field."',\n'Fields' => A".substr($ret, 1).',';
ob_start();
?>
Index: branches/RC/core/kernel/processors/main_processor.php
===================================================================
diff -u -r11227 -r11336
--- branches/RC/core/kernel/processors/main_processor.php (.../main_processor.php) (revision 11227)
+++ branches/RC/core/kernel/processors/main_processor.php (.../main_processor.php) (revision 11336)
@@ -125,8 +125,14 @@
if (!isset($params['pass']) && !isset($params['no_pass'])) $params['pass'] = 'm';
if (isset($params['no_pass'])) unset($params['no_pass']);
- if( $this->Application->GetVar('admin') ) $params['admin'] = 1;
+ if ( $this->Application->GetVar('admin') ) {
+ $params['admin'] = 1;
+ if (!array_key_exists('editing_mode', $params)) {
+ $params['editing_mode'] = EDITING_MODE;
+ }
+ }
+
return $this->T($params);
}
@@ -566,6 +572,7 @@
function GetEquals($params)
{
$name = $this->SelectParam($params, 'var,name,param');
+
$value = $params['value'];
if ($this->Application->GetVar($name) == $value) {
return 1;
@@ -741,77 +748,6 @@
}*/
/**
- * Parses block and returns result
- *
- * @param Array $params
- * @return string
- * @access public
- *
- * @todo Fools NParser, that m_ParseBlock exists, need that?
- */
- function ParseBlock($params)
- {
- $parser =& $this->Application->Parser; // recallObject('TemplateParser');
- return $parser->ParseBlock($params);
- }
-
- function RenderElement($params)
- {
- if (isset($params['design']) && $params['design']) {
- $block_name = $params['name'];
- if ($block_name != '__this__') {
- // prepare content
- $block_params = $params;
- $block_params['template'] = $block_name;
- $block_params['return_params'] = 1;
- $block_params['strip_nl'] = 2;
- $block_content = $this->MyInclude($block_params);
-
- if (isset($params['data_exists']) && $params['data_exists'] && !$block_content) {
- return '';
- }
-
- // prepare design
- $block_params = Array (
- 'content' => $block_content,
- );
- }
-
- $block_params['name'] = $params['design'];
- return $this->Application->ParseBlock($block_params, 1);
- }
-
- return $this->ParseBlock($params);
- }
-
- function RenderElements($params)
- {
- if (!isset($params['elements']) || !$params['elements']) return;
- $elements = explode(',', $params['elements']);
- if (isset($params['skip']) && $params['skip']) {
- $tmp_skip = explode(',', $params['skip']);
- foreach ($tmp_skip as $elem) {
- $skip[] = trim($elem);
- }
- }
- else {
- $skip = array();
- }
- unset($params['elements']);
- $o = '';
- foreach ($elements as $an_element)
- {
- $cur = trim($an_element);
- if (in_array($cur,$skip) || !$cur) continue;
- $pass_params = $params;
- $pass_params['name'] = $cur;
- $o .= $this->RenderElement($pass_params);
- }
- return $o;
-
- }
-
- /**
* Checks if debug mode is on
*
* @param Array $params
@@ -1019,8 +955,8 @@
else {
if (PROTOCOL == 'https://' && $this->Application->ConfigValue('Force_HTTP_When_SSL_Not_Required')) {
if ($this->Application->GetVar('__KEEP_SSL__')) return;
- $pass = array('pass'=>'m', 'm_cat_id'=>0);
- $this->Application->Redirect('', array_merge_recursive2($pass, Array('__SSL__' => 0)));
+ // $pass_more = Array ('pass' => 'm', 'm_cat_id' => 0, '__SSL__' => 0);
+ $this->Application->Redirect('', array_merge_recursive2($pass, Array('__SSL__' => 0))); // $pass_more
}
}
}
@@ -1066,6 +1002,10 @@
}
}
+ // xml documents are usually long
+ set_time_limit(0);
+ ini_set('memory_limit', -1);
+
return $this->Application->XMLHeader(getArrayValue($params, 'xml_version'));
}
Index: branches/RC/core/kernel/nparser/nparser.php
===================================================================
diff -u -r11297 -r11336
--- branches/RC/core/kernel/nparser/nparser.php (.../nparser.php) (revision 11297)
+++ branches/RC/core/kernel/nparser/nparser.php (.../nparser.php) (revision 11336)
@@ -84,7 +84,7 @@
function CompileRaw($data, $t_name, $template_name = 'unknown')
{
$code = "extract (\$_parser->Params);\n";
- $code .= "\$_parser->ElementLocations['{$template_name}'] = Array('file' => '{$t_name}', 'start_pos' => 0, 'end_pos' => " . strlen($data) . ");\n";
+ $code .= "\$_parser->ElementLocations['{$template_name}'] = Array('template' => '{$template_name}', 'start_pos' => 0, 'end_pos' => " . strlen($data) . ");\n";
// $code .= "__@@__DefinitionsMarker__@@__\n";
@@ -106,6 +106,7 @@
'line' => substr_count(substr($data, 0, $tag_data[2][1]), "\n")+1,
'pos' => $tag_data[2][1],
'file' => $t_name,
+ 'template' => $template_name,
);
// the idea is to count number of comment openings and closings before current tag
@@ -313,8 +314,16 @@
}
return false;
}
- if (!$pre_parsed || !$pre_parsed['active'] || defined('DBG_NPARSER_FORCE_COMPILE') && DBG_NPARSER_FORCE_COMPILE) {
+
+ $force_compile = defined('DBG_NPARSER_FORCE_COMPILE') && DBG_NPARSER_FORCE_COMPILE;
+ if (!$pre_parsed || !$pre_parsed['active'] || $force_compile) {
$inc_parser = new NParser();
+
+ if ($force_compile) {
+ // remove Front-End theme markings during total compilation
+ $t = preg_replace('/^theme:.*?\//', '', $t);
+ }
+
if (!$inc_parser->Compile($pre_parsed, $t)) return false;
}
return $pre_parsed;
@@ -441,14 +450,15 @@
return $ret;
}
- return defined('DBG_DECORATE_BLOCKS') && DBG_DECORATE_BLOCKS ? $this->DecorateBlock($ret, $params, true) : $ret;
+ return defined('EDITING_MODE') ? $this->DecorateBlock($ret, $params, true) : $ret;
}
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendTrace();
}
$trace_results = debug_backtrace();
$this->Application->handleError(E_USER_ERROR, 'Rendering of undefined element '.$params['name'].'', $trace_results[0]['file'], $trace_results[0]['line']);
+ return false;
}
$m_processor =& $this->GetProcessor('m');
@@ -472,16 +482,71 @@
return $ret;
}
- return defined('DBG_DECORATE_BLOCKS') && DBG_DECORATE_BLOCKS ? $this->DecorateBlock($ret, $params) : $ret;
+ return defined('EDITING_MODE') ? $this->DecorateBlock($ret, $params) : $ret;
}
function DecorateBlock($block_content, $block_params, $is_template = false)
{
static $used_ids = Array ();
+ static $edit_insides = null;
+
+ if (!isset($edit_insides)) {
+ $edit_insides = $this->Application->GetVar('edit_insides');
+ }
+
+// $prepend = '[name: ' . $block_params['name'] . '] [params: ' . implode(', ', array_keys($block_params)) . ']';
+
+ $decorate = false;
+
+ if ($is_template) {
+ // content inside pair RenderElement tag
+// $prepend = 'CONTENT_OF_DESIGN: ' . $prepend;
+
+ if ($edit_insides && (EDITING_MODE == EDITING_MODE_CMS)) {
+ $decorate = true;
+ }
+ }
+ else {
+ if (strpos($block_params['name'], '__capture_') === 0) {
+ // capture tag (usually inside pair RenderElement)
+// $prepend = 'CAPTURE: ' . $prepend;
+
+ if ($edit_insides && (EDITING_MODE == EDITING_MODE_CMS)) {
+ $decorate = true;
+ }
+ }
+ elseif (array_key_exists('content', $block_params)) {
+ // pair RenderElement (on template, were it's used)
+// $prepend = 'PAIR_RENDER_ELEMENT: ' . $prepend;
+
+ if (EDITING_MODE == EDITING_MODE_DESIGN) {
+ $decorate = true;
+ }
+ }
+ else {
+ // non-pair RenderElement
+// $prepend = 'SINGLE_RENDER_ELEMENT: ' . $prepend;
+
+ if ($edit_insides && (EDITING_MODE == EDITING_MODE_CMS)) {
+ $decorate = true;
+ }
+
+ if (array_key_exists('layout_view', $block_params) && $block_params['layout_view'] && (EDITING_MODE == EDITING_MODE_LAYOUT)) {
+ $decorate = true;
+ }
+ }
+ }
+
+ if (!$decorate) {
+ return $block_content;
+ }
+ else {
+ $block_content = /*$prepend .*/ $block_content;
+ }
+
$block_name = $block_params['name'];
$function_name = $is_template ? $block_name : $this->Elements[$block_name];
- $element_location = $this->ElementLocations[$function_name];
// ensure unique id for every div (used from print lists)
$container_num = 1;
@@ -494,7 +559,7 @@
$used_ids[] = $container_id;
// prepare parameter string
- $param_string = "$block_name:$function_name:{$element_location['file']}:{$element_location['start_pos']}:{$element_location['end_pos']}";
+ $param_string = $block_name . ':' . $function_name;
$block_editor = '