Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Wed, Feb 5, 4:11 AM

in-portal

Index: branches/5.1.x/core/kernel/nparser/nparser.php
===================================================================
--- branches/5.1.x/core/kernel/nparser/nparser.php (revision 13486)
+++ branches/5.1.x/core/kernel/nparser/nparser.php (revision 13487)
@@ -1,1105 +1,1127 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 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!');
include_once(KERNEL_PATH.'/nparser/ntags.php');
define('TAG_NAMESPACE', 'inp2:');
define('TAG_NAMESPACE_LENGTH', 5);
class NParser extends kBase {
var $Stack = Array ();
var $Level = 0;
var $Buffers = array();
var $InsideComment = false;
/**
* Parse tags inside HTML comments
*
* @var bool
*/
var $SkipComments = true;
var $Params = array();
var $ParamsStack = array();
var $ParamsLevel = 0;
var $Definitions = '';
/**
* Holds dynamic elements to function names mapping during execution
*
* @var Array
*/
var $Elements = Array ();
/**
* Holds location of element definitions inside templates.
* key - element function name, value - array of 2 keys: {from_pos, to_pos}
*
* @var Array
*/
var $ElementLocations = Array ();
var $DataExists = false;
var $TemplateName = null;
var $TempalteFullPath = null;
var $CachePointers = Array ();
var $Cachable = Array ();
/**
* Caching in templates enabled
*
* @var bool
*/
var $CachingEnabled = false;
/**
* Completely cache given page
*
* @var bool
*/
var $FullCachePage = false;
/**
* Prefixes, that are used on current page
*
* @var Array
*/
var $PrefixesInUse = Array ();
/**
* Parser parameter names, that are created via m_Capture tag are listed here
*
* @var Array
*/
var $Captures = array();
/**
* Phrases, used on "Edit" buttons, that parser adds during block decoration
*
* @var Array
*/
var $_btnPhrases = Array ();
/**
* Mod-rewrite system enabled
*
* @var bool
*/
var $RewriteUrls = false;
/**
* Current user is logged-in
*
* @var bool
*/
var $UserLoggedIn = false;
function NParser()
{
parent::kBase();
if (defined('EDITING_MODE') && (EDITING_MODE == EDITING_MODE_DESIGN)) {
$this->_btnPhrases['design'] = $this->Application->Phrase('la_btn_EditDesign', false, true);
$this->_btnPhrases['block'] = $this->Application->Phrase('la_btn_EditBlock', false, true);
}
$this->RewriteUrls = $this->Application->RewriteURLs();
$this->UserLoggedIn = $this->Application->LoggedIn();
// cache only Front-End templated, when memory caching is available and template caching is enabled in configuration
$this->CachingEnabled = !$this->Application->isAdmin && $this->Application->ConfigValue('SystemTagCache') && $this->Application->isCachingType(CACHING_TYPE_MEMORY);
}
function Compile($pre_parsed, $template_name = 'unknown')
{
$data = file_get_contents($pre_parsed['tname']);
if (!$this->CompileRaw($data, $pre_parsed['tname'], $template_name)) {
// compilation failed during errors in template
// trigger_error('Template "<strong>' . $template_name . '</strong>" not compiled because of errors', E_USER_WARNING);
return false;
}
// saving compiled version (only when compilation was successful)
$this->Application->TemplatesCache->saveTemplate($pre_parsed['fname'], $this->Buffers[0]);
return true;
}
function Parse($raw_template, $name = null)
{
$this->CompileRaw($raw_template, $name);
ob_start();
$_parser =& $this;
eval('?'.'>'.$this->Buffers[0]);
return ob_get_clean();
}
function CompileRaw($data, $t_name, $template_name = 'unknown')
{
$code = "extract (\$_parser->Params);\n";
$code .= "\$_parser->ElementLocations['{$template_name}'] = Array('template' => '{$template_name}', 'start_pos' => 0, 'end_pos' => " . strlen($data) . ");\n";
// $code .= "__@@__DefinitionsMarker__@@__\n";
// $code .= "if (!\$this->CacheStart('".abs(crc32($t_name))."_0')) {\n";
$this->Buffers[0] = '<?'."php $code ?>\n";
$this->Cacheable[0] = true;
$this->Definitions = '';
// finding all the tags
$reg = '(.*?)(<[\\/]?)' . TAG_NAMESPACE . '([^>]*?)([\\/]?>)(\r\n){0,1}';
preg_match_all('/'.$reg.'/s', $data, $results, PREG_SET_ORDER + PREG_OFFSET_CAPTURE);
$this->InsideComment = false;
foreach ($results as $tag_data) {
$tag = array(
'opening' => $tag_data[2][0],
'tag' => $tag_data[3][0],
'closing' => $tag_data[4][0],
'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
// if the numbers do not match we inverse the status of InsideComment
if ($this->SkipComments && (substr_count($tag_data[1][0], '<!--') != substr_count($tag_data[1][0], '-->'))) {
$this->InsideComment = !$this->InsideComment;
}
// appending any text/html data found before tag
$this->Buffers[$this->Level] .= $tag_data[1][0];
if (!$this->InsideComment) {
$tmp_tag = $this->Application->CurrentNTag;
$this->Application->CurrentNTag = $tag;
if ($this->ProcessTag($tag) === false) {
$this->Application->CurrentNTag = $tmp_tag;
return false;
}
$this->Application->CurrentNTag = $tmp_tag;
}
else {
$this->Buffers[$this->Level] .= $tag_data[2][0].$tag_data[3][0].$tag_data[4][0];
}
}
if ($this->Level > 0) {
$this->Application->handleError(E_USER_ERROR, 'Unclosed tag opened by '.$this->TagInfo($this->Stack[$this->Level]->Tag), $this->Stack[$this->Level]->Tag['file'], $this->Stack[$this->Level]->Tag['line']);
return false;
}
// appending text data after last tag (after its closing pos),
// if no tag was found at all ($tag_data is not set) - append the whole $data
$this->Buffers[$this->Level] .= isset($tag_data) ? substr($data, $tag_data[4][1]+strlen($tag_data[4][0])) : $data;
$this->Buffers[$this->Level] = preg_replace('/<!--##(.*?)##-->/s', '', $this->Buffers[$this->Level]); // remove hidden comments IB#23065
// $this->Buffers[$this->Level] .= '<?'.'php '."\n\$_parser->CacheEnd();\n}\n"." ?".">\n";
// $this->Buffers[$this->Level] = str_replace('__@@__DefinitionsMarker__@@__', $this->Definitions, $this->Buffers[$this->Level]);
return true;
}
function SplitParamsStr($params_str)
{
preg_match_all('/([\${}a-zA-Z0-9_.\\-\\\\#\\[\\]]+)=(["\']{1,1})(.*?)(?<!\\\)\\2/s', $params_str, $rets, PREG_SET_ORDER);
$values = Array();
// we need to replace all occurences of any current param $key with {$key} for correct variable substitution
foreach ($rets AS $key => $val){
$values[$val[1]] = str_replace('\\' . $val[2], $val[2], $val[3]);
}
return $values;
}
function SplitTag($tag)
{
if (!preg_match('/([^_ \t\r\n]*)[_]?([^ \t\r\n]*)[ \t\r\n]*(.*)$$/s', $tag['tag'], $parts)) {
// this is virtually impossible, but just in case
$this->Application->handleError(E_USER_ERROR, 'Incorrect tag format: '.$tag['tag'], $tag['file'], $tag['line']);
return false;
}
$splited['prefix'] = $parts[2] ? $parts[1] : '__auto__';
$splited['name'] = $parts[2] ? $parts[2] : $parts[1];
$splited['attrs'] = $parts[3];
return $splited;
}
function ProcessTag($tag)
{
$splited = $this->SplitTag($tag);
if ($splited === false) {
return false;
}
$tag = array_merge($tag, $splited);
$tag['processed'] = false;
$tag['NP'] = $this->SplitParamsStr($tag['attrs']);
$o = '';
$tag['is_closing'] = $tag['opening'] == '</' || $tag['closing'] == '/>';
if (class_exists('_Tag_'.$tag['name'])) { // block tags should have special handling class
if ($tag['opening'] == '<') {
$class = '_Tag_'.$tag['name'];
$instance = new $class($tag);
$instance->Parser =& $this;
/* @var $instance _BlockTag */
$this->Stack[++$this->Level] =& $instance;
$this->Buffers[$this->Level] = '';
$this->Cachable[$this->Level] = true;
$open_code = $instance->Open($tag);
if ($open_code === false) {
return false;
}
$o .= $open_code;
}
if ($tag['is_closing']) { // not ELSE here, because tag may be <empty/> and still has a handler-class
if ($this->Level == 0) {
$dump = array();
foreach ($this->Stack as $instance) {
$dump[] = $instance->Tag;
}
print_pre($dump);
$this->Application->handleError(E_USER_ERROR, 'Closing tag without an opening: '.$this->TagInfo($tag).' <b> - probably opening tag was removed or nested tags error</b>', $tag['file'], $tag['line']);
return false;
}
if ($this->Stack[$this->Level]->Tag['name'] != $tag['name']) {
$opening_tag = $this->Stack[$this->Level]->Tag;
$this->Application->handleError(E_USER_ERROR,
'Closing tag '.$this->TagInfo($tag).' does not match
opening tag at current nesting level ('.$this->TagInfo($opening_tag).'
opened at line '.$opening_tag['line'].')', $tag['file'], $tag['line']);
return false;
}
$o .= $this->Stack[$this->Level]->Close($tag); // DO NOT use $this->Level-- here because it's used inside Close
$this->Level--;
}
}
else { // regular tags - just compile
if (!$tag['is_closing']) {
$this->Application->handleError(E_USER_ERROR, 'Tag without a handler: '.$this->TagInfo($tag).' <b> - probably missing &lt;empty <span style="color: red">/</span>&gt; tag closing</b>', $tag['file'], $tag['line']);
return false;
}
if ($this->Level > 0) $o .= $this->Stack[$this->Level]->PassThrough($tag);
if (!$tag['processed']) {
$compiled = $this->CompileTag($tag);
if ($compiled === false) return false;
if (isset($tag['NP']['cachable']) && (!$tag['NP']['cachable'] || $tag['NP']['cachable'] == 'false')) {
$this->Cachable[$this->Level] = false;
}
$o .= '<?'.'php ' . $compiled . " ?>\n";
// $o .= '<?'.'php ';
// $o .= (isset($tag['NP']['cachable']) && (!$tag['NP']['cachable'] || $tag['NP']['cachable'] == 'false')) ? $this->BreakCache($compiled, $this->GetPointer($tag)) : $compiled;
// $o .= " ?".">\n";
}
}
$this->Buffers[$this->Level] .= $o;
return true;
}
function GetPointer($tag)
{
return abs(crc32($tag['file'])).'_'.$tag['line'];
}
function BreakCache($code, $pointer, $condition='')
{
return "\$_parser->CacheEnd();\n}\n" . $code."\nif ( !\$_parser->CacheStart('{$pointer}'" . ($condition ? ", {$condition}" : '') . ") ) {\n";
}
function TagInfo($tag, $with_params=false)
{
return "<b>{$tag['prefix']}_{$tag['name']}".($with_params ? ' '.$tag['attrs'] : '')."</b>";
}
function CompileParamsArray($arr)
{
$to_pass = 'Array(';
foreach ($arr as $name => $val) {
$to_pass .= '"'.$name.'" => "'.str_replace('"', '\"', $val).'",';
}
$to_pass .= ')';
return $to_pass;
}
function CompileTag($tag)
{
$code = '';
$to_pass = $this->CompileParamsArray($tag['NP']);
if ($tag['prefix'] == '__auto__') {
$prefix = $this->GetParam('PrefixSpecial');
$code .= '$_p_ =& $_parser->GetProcessor($PrefixSpecial);'."\n";
$code .= 'echo $_p_->ProcessParsedTag(\''.$tag['name'].'\', '.$to_pass.', "$PrefixSpecial", \''.$tag['file'].'\', '.$tag['line'].');'."\n";
}
else {
$prefix = $tag['prefix'];
$code .= '$_p_ =& $_parser->GetProcessor("'.$tag['prefix'].'");'."\n";
$code .= 'echo $_p_->ProcessParsedTag(\''.$tag['name'].'\', '.$to_pass.', "'.$tag['prefix'].'", \''.$tag['file'].'\', '.$tag['line'].');'."\n";
}
if (array_key_exists('result_to_var', $tag['NP']) && $tag['NP']['result_to_var']) {
$code .= "\$params['{$tag['NP']['result_to_var']}'] = \$_parser->GetParam('{$tag['NP']['result_to_var']}');\n";
$code .= "\${$tag['NP']['result_to_var']} = \$params['{$tag['NP']['result_to_var']}'];\n";
}
if ($prefix && strpos($prefix, '$') === false) {
$p =& $this->GetProcessor($prefix);
if (!is_object($p) || !$p->CheckTag($tag['name'], $tag['prefix'])) {
$this->Application->handleError(E_USER_ERROR, 'Unknown tag: '.$this->TagInfo($tag).' <b> - incorrect tag name or prefix </b>', $tag['file'], $tag['line']);
return false;
}
}
return $code;
}
function CheckTemplate($t, $silent = null)
{
$pre_parsed = $this->Application->TemplatesCache->GetPreParsed($t);
if (!$pre_parsed) {
if (!$silent) {
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendTrace();
}
trigger_error('Cannot include "<strong>' . $t . '</strong>" - file does not exist', E_USER_ERROR);
}
return false;
}
$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;
}
function Run($t, $silent = null)
{
if ((strpos($t, '../') !== false) || (trim($t) !== $t)) {
// when relative paths or special chars are found template names from url, then it's hacking attempt
return false;
}
$pre_parsed = $this->CheckTemplate($t, $silent);
if (!$pre_parsed) {
return false;
}
$backup_template = $this->TemplateName;
$backup_fullpath = $this->TempalteFullPath;
$this->TemplateName = $t;
$this->TempalteFullPath = $pre_parsed['tname'];
if (!isset($backup_template) && $this->CachingEnabled && !$this->UserLoggedIn && !EDITING_MODE) {
// this is main page template -> check for page-based aggressive caching settings
$output =& $this->RunMainPage($pre_parsed);
}
else {
$output =& $this->Application->TemplatesCache->runTemplate($this, $pre_parsed);
}
$this->TemplateName = $backup_template;
$this->TempalteFullPath = $backup_fullpath;
return $output;
}
function &RunMainPage($pre_parsed)
{
$page =& $this->Application->recallObject('st.-virtual');
/* @var $page kDBItem */
if ($page->isLoaded()) {
// page found in database
$debug_mode = $this->Application->isDebugMode(); // don't cache debug output
$template_path = preg_replace('/^' . preg_quote(FULL_PATH, '/') . '/', '', $this->TempalteFullPath, 1);
$element = ($debug_mode ? 'DEBUG_MODE:' : '') . 'file=' . $template_path;
$this->FullCachePage = $page->GetDBField('EnablePageCache');
if ($this->FullCachePage && $page->GetDBField('PageCacheKey')) {
// page caching enabled -> try to get from cache
$cache_key = $this->FormCacheKey($element, $page->GetDBField('PageCacheKey'));
$output = $this->getCache($cache_key);
if ($output !== false) {
return $output;
}
}
// page not cached OR cache expired
$output =& $this->Application->TemplatesCache->runTemplate($this, $pre_parsed);
$this->generatePageCacheKey($page);
if ($this->FullCachePage && $page->GetDBField('PageCacheKey')) {
$cache_key = $this->FormCacheKey($element, $page->GetDBField('PageCacheKey'));
$this->setCache($cache_key, $output, (int)$page->GetDBField('PageExpiration'));
}
}
else {
// page not found in database
$output =& $this->Application->TemplatesCache->runTemplate($this, $pre_parsed);
}
return $output;
}
/**
* Generate page caching key based on prefixes used on it + prefix IDs passed in url
*
* @param kDBItem $page
*/
function generatePageCacheKey(&$page)
{
if (!$page->isLoaded() || $page->GetDBField('OverridePageCacheKey')) {
return ;
}
$page_cache_key = Array ();
// nobody resets "m" prefix serial, don't count no user too
unset($this->PrefixesInUse['m'], $this->PrefixesInUse['u']);
if (array_key_exists('st', $this->PrefixesInUse)) {
// prefix "st" serial will never be changed
unset($this->PrefixesInUse['st']);
$this->PrefixesInUse['c'] = 1;
}
$prefix_ids = Array ();
$prefixes = array_keys($this->PrefixesInUse);
asort($prefixes);
foreach ($prefixes as $index => $prefix) {
$id = $this->Application->GetVar($prefix . '_id');
if (is_numeric($id)) {
if (defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode()) {
$this->Application->Debugger->appendHTML('Found: "' . $prefix . '_id" = ' . $id . ' during PageCacheKey forming.');
}
$prefix_ids[] = $prefix;
unset($prefixes[$index]);
}
}
if ($prefix_ids) {
$page_cache_key[] = 'prefix_id:' . implode(',', $prefix_ids);
}
if ($prefixes) {
$page_cache_key[] = 'prefix:' . implode(',', $prefixes);
}
$page_cache_key = implode(';', $page_cache_key);
if ($page_cache_key != $page->GetOriginalField('PageCacheKey')) {
if (defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode()) {
$this->Application->Debugger->appendHTML('Canging PageCacheKey from "<strong>' . $page->GetOriginalField('PageCacheKey') . '</strong>" to "<strong>' . $page_cache_key . '</strong>".');
}
$page->SetDBField('PageCacheKey', $page_cache_key);
// don't use kDBItem::Update(), because it will change ModifiedById to current front-end user
$sql = 'UPDATE ' . $page->TableName . '
SET PageCacheKey = ' . $page->Conn->qstr($page_cache_key) . '
WHERE ' . $page->IDField . ' = ' . $page->GetID();
$page->Conn->Query($sql);
// increment serial, because we issue direct sql above!
$this->Application->incrementCacheSerial('c');
$this->Application->incrementCacheSerial('c', $page->GetID());
}
}
function &GetProcessor($prefix)
{
static $Processors = array();
if (!isset($Processors[$prefix])) {
$Processors[$prefix] = $this->Application->recallObject($prefix.'_TagProcessor');
}
return $Processors[$prefix];
}
function SelectParam($params, $possible_names)
{
if (!is_array($params)) return;
if (!is_array($possible_names))
$possible_names = explode(',', $possible_names);
foreach ($possible_names as $name)
{
if( isset($params[$name]) ) return $params[$name];
}
return false;
}
function SetParams($params)
{
$this->Params = $params;
$keys = array_keys($this->Params);
}
function GetParam($name)
{
return isset($this->Params[$name]) ? $this->Params[$name] : false;
}
function SetParam($name, $value)
{
$this->Params[$name] = $value;
}
function PushParams($params)
{
$this->ParamsStack[$this->ParamsLevel++] = $this->Params;
$this->Params = $params;
}
function PopParams()
{
$this->Params = $this->ParamsStack[--$this->ParamsLevel];
}
function ParseBlock($params, $pass_params=false)
{
if (array_key_exists('cache_timeout', $params) && $params['cache_timeout']) {
$ret = $this->getCache( $this->FormCacheKey('element_' . $params['name']) );
if ($ret) {
return $ret;
}
}
if (substr($params['name'], 0, 5) == 'html:') {
return substr($params['name'], 6);
}
if (!array_key_exists($params['name'], $this->Elements) && array_key_exists('default_element', $params)) {
// when given element not found, but default element name given, then render it instead
$params['name'] = $params['default_element'];
unset($params['default_element']);
return $this->ParseBlock($params, $pass_params);
}
$original_params = $params;
if ($pass_params || isset($params['pass_params'])) $params = array_merge($this->Params, $params);
$this->PushParams($params);
$data_exists_bak = $this->DataExists;
// if we are parsing design block and we have block_no_data - we need to wrap block_no_data into design,
// so we should set DataExists to true manually, otherwise the design block will be skipped because of data_exists in params (by Kostja)
//
// keep_data_exists is used by block RenderElement (always added in ntags.php), to keep the DataExists value
// from inside-content block, otherwise when parsing the design block DataExists will be reset to false resulting missing design block (by Kostja)
//
// Inside-content block parsing result is given to design block in "content" parameter (ntags.php) and "keep_data_exists"
// is only passed, when parsing design block. In case, when $this->DataExists is set to true, but
// zero-length content (in 2 cases: method NParser::CheckNoData set it OR really empty block content)
// is returned from inside-content block, then design block also should not be shown (by Alex)
$this->DataExists = (isset($params['keep_data_exists']) && isset($params['content']) && $params['content'] != '' && $this->DataExists) || (isset($params['design']) && isset($params['block_no_data']) && $params['name'] == $params['design']);
if (!array_key_exists($params['name'], $this->Elements)) {
$pre_parsed = $this->Application->TemplatesCache->GetPreParsed($params['name']);
if ($pre_parsed) {
$ret = $this->IncludeTemplate($params);
if (array_key_exists('no_editing', $params) && $params['no_editing']) {
// when individual render element don't want to be edited
return $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, '<b>Rendering of undefined element '.$params['name'].'</b>', $trace_results[0]['file'], $trace_results[0]['line']);
return false;
}
$m_processor =& $this->GetProcessor('m');
$flag_values = $m_processor->PreparePostProcess($params);
$f_name = $this->Elements[$params['name']];
$ret = $f_name($this, $params);
$ret = $m_processor->PostProcess($ret, $flag_values);
$block_params = $this->Params; // input parameters, but modified inside rendered block
$this->PopParams();
if (array_key_exists('result_to_var', $flag_values) && $flag_values['result_to_var']) {
// when "result_to_var" used inside ParseBlock, then $$result_to_var parameter is set inside ParseBlock,
// but not outside it as expected and got lost at all after PopParams is called, so make it work by
// setting it's value on current parameter deep level (from where ParseBlock was called)
$this->SetParam($flag_values['result_to_var'], $block_params[ $flag_values['result_to_var'] ]);
}
$this->CheckNoData($ret, $params);
$this->DataExists = $data_exists_bak || $this->DataExists;
if (array_key_exists('cache_timeout', $original_params) && $original_params['cache_timeout']) {
$cache_key = $this->FormCacheKey('element_' . $original_params['name']);
$this->setCache($cache_key, $ret, (int)$original_params['cache_timeout']);
}
if (array_key_exists('no_editing', $block_params) && $block_params['no_editing']) {
// when individual render element don't want to be edited
return $ret;
}
return defined('EDITING_MODE') ? $this->DecorateBlock($ret, $params) : $ret;
}
function DecorateBlock($block_content, $block_params, $is_template = false)
{
static $used_ids = Array (), $base_url = null;
if (!isset($base_url)) {
$base_url = $this->Application->BaseURL();
}
// $prepend = '[name: ' . $block_params['name'] . '] [params: ' . implode(', ', array_keys($block_params)) . ']';
$decorate = false;
$design = false;
if (EDITING_MODE == EDITING_MODE_DESIGN) {
$decorate = true;
if ($is_template) {
// content inside pair RenderElement tag
}
else {
if (strpos($block_params['name'], '__capture_') === 0) {
// capture tag (usually inside pair RenderElement)
$decorate = false;
}
elseif (array_key_exists('content', $block_params)) {
// pair RenderElement (on template, were it's used)
$design = 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];
$block_title = '';
if (array_key_exists($function_name, $this->Application->Parser->ElementLocations)) {
$element_location = $this->Application->Parser->ElementLocations[$function_name];
$block_title .= $element_location['template'] . '.tpl';
$block_title .= ' (' . $element_location['start_pos'] . ' - ' . $element_location['end_pos'] . ')';
}
// ensure unique id for every div (used from print lists)
$container_num = 1;
$container_id = 'parser_block[' . $function_name . ']';
while (in_array($container_id . '_' . $container_num, $used_ids)) {
$container_num++;
}
$container_id .= '_' . $container_num;
$used_ids[] = $container_id;
// prepare parameter string
$param_string = $block_name . ':' . $function_name;
if ($design) {
$btn_text = $this->_btnPhrases['design'];
$btn_class = 'cms-edit-design-btn';
$btn_container_class = 'block-edit-design-btn-container';
$btn_name = 'design';
}
else {
$btn_text = $this->_btnPhrases['block'];
$btn_class = 'cms-edit-block-btn';
$btn_container_class = 'block-edit-block-btn-container';
$btn_name = 'content';
}
$block_editor = '
<div id="' . $container_id . '" params="' . $param_string . '" class="' . $btn_container_class . '" title="' . htmlspecialchars($block_title) . '">
<div class="' . $btn_class . '">
<div class="cms-btn-image">
<img src="' . $base_url . 'core/admin_templates/img/top_frame/icons/' . $btn_name . '_mode.png" width="15" height="16" alt=""/>
</div>
<div class="cms-btn-text" id="' . $container_id . '_btn">' . $btn_text . '</div>
</div>
<div class="cms-btn-content">
%s
</div>
</div>';
// 1 - text before, 2 - open tag, 3 - open tag attributes, 4 - content inside tag, 5 - closing tag, 6 - text after closing tag
if (preg_match('/^(\s*)<(td|span)(.*?)>(.*)<\/(td|span)>(.*)$/is', $block_content, $regs)) {
// div inside span -> put div outside span
return $regs[1] . '<' . $regs[2] . ' ' . $regs[3] . '>' . str_replace('%s', $regs[4], $block_editor) . '</' . $regs[5] . '>' . $regs[6];
}
return str_replace('%s', $block_content, $block_editor);
}
function IncludeTemplate($params, $silent=null)
{
$t = is_array($params) ? $this->SelectParam($params, 't,template,block,name') : $params;
$cache_timeout = array_key_exists('cache_timeout', $params) ? $params['cache_timeout'] : false;
if ($cache_timeout) {
$cache_key = $this->FormCacheKey('template:' . $t);
$ret = $this->getCache($cache_key);
if ($ret !== false) {
return $ret;
}
}
$t = preg_replace('/\.tpl$/', '', $t);
$data_exists_bak = $this->DataExists;
$this->DataExists = false;
if (!isset($silent) && array_key_exists('is_silent', $params)) {
$silent = $params['is_silent'];
}
if (isset($params['pass_params'])) {
// ability to pass params from block to template
$params = array_merge($this->Params, $params);
}
$this->PushParams($params);
$ret = $this->Run($t, $silent);
$this->PopParams();
$this->CheckNoData($ret, $params);
$this->DataExists = $data_exists_bak || $this->DataExists;
if ($cache_timeout) {
$this->setCache($cache_key, $ret, (int)$cache_timeout);
}
return $ret;
}
function CheckNoData(&$ret, $params)
{
if (array_key_exists('data_exists', $params) && $params['data_exists'] && !$this->DataExists) {
$block_no_data = isset($params['BlockNoData']) ? $params['BlockNoData'] : (isset($params['block_no_data']) ? $params['block_no_data'] : false);
if ($block_no_data) {
$ret = $this->ParseBlock(array('name'=>$block_no_data));
}
else {
$ret = '';
}
}
}
function getCache($name)
{
if (!$this->CachingEnabled) {
return false;
}
$ret = $this->Application->getCache($name, false);
if (preg_match('/^\[DE_MARK:(.*?)\]$/', substr($ret, -11), $regs)) {
$this->DataExists = $regs[1] ? true : false;
$ret = substr($ret, 0, -11);
}
return $ret;
}
function setCache($name, $value, $expiration = 0)
{
if (!$this->CachingEnabled) {
return false;
}
// remeber DataExists in cache, because after cache will be restored
// it will not be available naturally (no tags, that set it will be called)
$value .= '[DE_MARK:' . (int)$this->DataExists . ']';
return $this->Application->setCache($name, $value, $expiration);
}
function FormCacheKey($element, $key_string = '')
{
if (strpos($key_string, 'guest_only') !== false && $this->UserLoggedIn) {
// don't cache, when user is logged-in "guest_only" is specified in key
return '';
}
$parts = Array ();
// 1. replace INLINE variable (from request) into key parts
if (preg_match_all('/\(%(.*?)\)/', $key_string, $regs)) {
// parts in form "(%variable_name)" were found
foreach ($regs[1] as $variable_name) {
$variable_value = $this->Application->GetVar($variable_name);
$key_string = str_replace('(%' . $variable_name . ')', $variable_value, $key_string);
}
}
// 2. replace INLINE serial numbers (they may not be related to any prefix at all)
// Serial number also could be composed of inline variables!
if (preg_match_all('/\[%(.*?)%\]/', $key_string, $regs)) {
// format "[%LangSerial%]" - prefix-wide serial in case of any change in "lang" prefix
// format "[%LangIDSerial:5%]" - one id-wide serial in case of data, associated with given id was changed
// format "[%CiIDSerial:ItemResourceId:5%]" - foreign key-based serial in case of data, associated with given foreign key was changed
foreach ($regs[1] as $serial_name) {
$serial_value = $this->Application->getCache('[%' . $serial_name . '%]');
$key_string = str_replace('[%' . $serial_name . '%]', '[%' . $serial_name . '=' . $serial_value . '%]', $key_string);
}
}
/*
Always add:
===========
* "var:m_lang" - show content on current language
* "var:t" - template from url, used to differ multiple pages using same physical template (like as design)
* "var:admin,editing_mode" - differ cached content when different editing modes are used
* "var:m_cat_id,m_cat_page" - pass current category
* "var:page,per_page,sort_by" - list pagination/sorting parameters
* "prefix:theme-file" - to be able to reset all cached templated using "Rebuild Theme Files" function
* "prefix:phrases" - use latest phrase translations
* "prefix:conf" - output could slighly differ based on configuration settings
*/
$key_string = rtrim('var:m_lang,t,admin,editing_mode,m_cat_id,m_cat_page,page,per_page,sort_by;prefix:theme-file,phrases,conf;' . $key_string, ';');
$keys = explode(';', $key_string);
/*
Possible parts of a $key_string (all can have multiple occurencies):
====================================================================
* prefix:<prefixA>[,<prefixB>,<prefixC>] - include global serial for given prefix(-es)
* skip_prefix:<prefix1>[,<prefix2>,<prefix3>] - exclude global serial for given prefix(-es)
* prefix_id:<prefixA>[,<prefixB>,<prefixC>] - include id-based serial for given prefix(-es)
* skip_prefix_id:<prefix1>[,<prefix2>,<prefix3>] - exclude id-based serial for given prefix(-es)
* var:<aaa>[,<bbb>,<ccc>] - include request variable value(-s)
* skip_var:<varA>[,<varB>,<varC>] - exclude request variable value(-s)
* (%variable_name) - include request variable value (only value without variable name ifself, like in "var:variable_name")
* [%SerialName%] - use to retrieve serial value in free form
*/
// 3. get variable names, prefixes and prefix ids, that should be skipped
$skip_prefixes = $skip_prefix_ids = $skip_variables = Array ();
foreach ($keys as $index => $key) {
if (preg_match('/^(skip_var|skip_prefix|skip_prefix_id):(.*?)$/i', $key, $regs)) {
unset($keys[$index]);
$tmp_parts = explode(',', $regs[2]);
switch ($regs[1]) {
case 'skip_var':
$skip_variables = array_merge($skip_variables, $tmp_parts);
break;
case 'skip_prefix':
$skip_prefixes = array_merge($skip_prefixes, $tmp_parts);
break;
case 'skip_prefix_id':
$skip_prefix_ids = array_merge($skip_prefix_ids, $tmp_parts);
break;
}
}
}
$skip_prefixes = array_unique($skip_prefixes);
$skip_variables = array_unique($skip_variables);
$skip_prefix_ids = array_unique($skip_prefix_ids);
// 4. process keys
foreach ($keys as $key) {
if (preg_match('/^(var|prefix|prefix_id):(.*?)$/i', $key, $regs)) {
$tmp_parts = explode(',', $regs[2]);
switch ($regs[1]) {
case 'var':
// format: "var:country_id" will become "country_id=<country_id>"
$tmp_parts = array_diff($tmp_parts, $skip_variables);
foreach ($tmp_parts as $variable_name) {
$variable_value = $this->Application->GetVar($variable_name);
if ($variable_value !== false) {
$parts[] = $variable_name . '=' . $variable_value;
}
}
break;
case 'prefix':
// format: "prefix:country" will become "[%CountrySerial%]"
$tmp_parts = array_diff($tmp_parts, $skip_prefixes);
foreach ($tmp_parts as $prefix) {
$serial_name = $this->Application->incrementCacheSerial($prefix, null, false);
$parts[] = '[%' . $serial_name . '=' . $this->Application->getCache($serial_name) . '%]';
if (!$this->RewriteUrls) {
// add env-style page and per-page variable, when mod-rewrite is off
$prefix_variables = Array ($prefix . '_Page', $prefix . '_PerPage');
foreach ($prefix_variables as $variable_name) {
$variable_value = $this->Application->GetVar($variable_name);
if ($variable_value !== false) {
$parts[] = $variable_name . '=' . $variable_value;
}
}
}
}
break;
case 'prefix_id':
// format: "id:country" will become "[%CountryIDSerial:5%]"
$tmp_parts = array_diff($tmp_parts, $skip_prefix_ids);
foreach ($tmp_parts as $prefix_id) {
$id = $this->Application->GetVar($prefix_id . '_id');
if ($id !== false) {
$serial_name = $this->Application->incrementCacheSerial($prefix_id, $id, false);
$parts[] = '[%' . $serial_name . '=' . $this->Application->getCache($serial_name) . '%]';
}
}
break;
}
}
elseif ($key == 'currency') {
// based on current currency
$parts[] = 'curr_iso=' . $this->Application->RecallVar('curr_iso');
}
elseif ($key == 'groups') {
// based on logged-in user groups
$parts[] = 'groups=' . $this->Application->RecallVar('UserGroups');
}
elseif ($key == 'guest_only') {
// we know this key, but process it at method beginning
}
else {
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendTrace();
}
trigger_error('Unknown key part "<strong>' . $key . '</strong>" used in "<strong>key</strong>" parameter of <inp2:m_Cache key="..."/> tag.', E_USER_ERROR);
}
}
// 5. add unique given cache key identifier on this page
$parts[] = $element;
$key = implode(':', $parts);
if (defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode()) {
$this->Application->Debugger->appendHTML('Parser Key: ' . $key);
}
return 'parser_' . crc32($key);
}
function PushPointer($pointer, $key)
{
$cache_key = $this->FullCachePage || !$this->CachingEnabled ? '' : $this->FormCacheKey('pointer:' . $pointer, $key);
$this->CachePointers[++$this->CacheLevel] = $cache_key;
return $this->CachePointers[$this->CacheLevel];
}
function PopPointer()
{
return $this->CachePointers[$this->CacheLevel--];
}
function CacheStart($pointer, $key)
{
$pointer = $this->PushPointer($pointer, $key);
if ($pointer) {
$ret = $this->getCache($pointer);
$debug_mode = defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode();
if ($ret !== false) {
echo $debug_mode ? '<!-- CACHED OUTPUT START -->' . $ret . '<!-- /CACHED OUTPUT END -->' : $ret;
$this->PopPointer();
return true;
}
if ($debug_mode) {
echo '<!-- NO CACHE FOR POINTER: ' . $pointer . ' -->';
}
}
ob_start();
return false;
}
function CacheEnd($expiration = 0)
{
$ret = ob_get_clean();
$pointer = $this->PopPointer();
if ($pointer) {
$res = $this->setCache($pointer, $ret, $expiration);
if (defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode()) {
echo '<!-- STORING CACHE FOR POINTER: ' . $pointer . ' [' . $res . '] -->';
}
}
echo $ret;
}
+
+ /**
+ * Performs compression of given files or text
+ *
+ * @param mixed $data
+ * @param bool $raw_script
+ * @param string $file_extension
+ * @return string
+ */
+ function CompressScript($data, $raw_script = false, $file_extension = '')
+ {
+ $minify_helper =& $this->Application->recallObject('MinifyHelper');
+ /* @var $minify_helper MinifyHelper */
+
+ if ($raw_script) {
+ $minify_helper->compressString($data, $file_extension);
+
+ return $data;
+ }
+
+ return $minify_helper->CompressScriptTag($data);
+ }
}
\ No newline at end of file
Index: branches/5.1.x/core/kernel/nparser/ntags.php
===================================================================
--- branches/5.1.x/core/kernel/nparser/ntags.php (revision 13486)
+++ branches/5.1.x/core/kernel/nparser/ntags.php (revision 13487)
@@ -1,620 +1,689 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 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 _BlockTag extends kBase {
/**
* Enter description here...
*
* @var NParser
*/
var $Parser = null;
var $Tag = null;
/**
* Contains parameter names, that should be given to tag in any case
*
* @var Array
*/
var $_requiredParams = Array ();
function _BlockTag($tag)
{
parent::kBase();
$this->Tag = $tag;
}
function Open($tag)
{
if (!$this->_checkRequiredParams($tag)) {
return false;
}
return '';
}
/**
* Checks, that all required attributes for tag are passed
*
* @param Array $tag
* @return bool
*/
function _checkRequiredParams($tag)
{
$missing_params = array_diff($this->_requiredParams, array_keys($tag['NP']));
if (!$missing_params) {
return true;
}
$error_msg = 'Tag ' . $this->Parser->TagInfo($tag, true) . ' called <b> without required ' . implode(', ', $missing_params) . ' </b> attribute';
if (count($missing_params) > 1) {
$error_msg .= '(-s)';
}
$this->Application->handleError(E_USER_ERROR, $error_msg, $tag['file'], $tag['line']);
return false;
}
/**
* All tags inside block tag are passed through to this method
* Any returned result is appened to current level's buffer
* This can be used to implement special handling of such tags as <inp2:m_else/>
*
* @param unknown_type $tag
* @return unknown
*/
function PassThrough(&$tag)
{
return '';
}
function Close($tag)
{
return $this->Parser->Buffers[$this->Parser->Level];
}
function AppendCode(&$o, $code, $php_tags=true)
{
if ($php_tags) {
$o .= '<?'."php\n" . ( is_array($code) ? "\t".implode("\n\t", $code)."\n" : $code) .'?>';
}
else {
$o .= ( is_array($code) ? "\t".implode("\n\t", $code)."\n" : $code);
}
}
}
class _Tag_Comment extends _BlockTag {
function Open($tag)
{
$this->Parser->SkipComments = false;
return '';
}
function Close($tag)
{
$this->Parser->SkipComments = true;
return $this->Parser->Buffers[$this->Parser->Level];
}
}
class _Tag_DefineElement extends _BlockTag {
/*var $ElemName;
function Open($tag)
{
$o = '';
$pointer = abs(crc32($tag['file'])).'_'.$tag['line'];
$f_name = $tag['NP']['name'].'_'.$pointer;
$this->ElemName = $tag['NP']['name'];
$code[] = "\$_parser->Elements['{$tag['NP']['name']}'] = '$f_name';";
// function_exists is required here, because a template may be included more than once
// leading to Cannot redeclare error
$code[] = "if (!function_exists('{$f_name}')) {";
$code[] = "function $f_name(&\$_parser, \$params) {";
$code[] = "global \$application;";
$code[] = "if (!\$_output = \$_parser->CacheStart('{$pointer}')) {";
$defaults = $this->Parser->CompileParamsArray($tag['NP']);
$code[] = "\$params = array_merge($defaults, \$params);";
$code[] = "if (!isset(\$params['PrefixSpecial']) && isset(\$params['prefix'])) {\$params['PrefixSpecial'] = \$params['prefix'];};";
$code[] = "extract(\$params);";
$code[] = "\$_parser->SetParams(\$params);";
$code[] = 'ob_start();';
$this->AppendCode($o, $code, false);
return $o . '?'.'>';
}
function Close($tag)
{
$o = $this->Parser->Buffers[$this->Parser->Level];
$code[] = "\$_parser->CacheEnd();\n";
$code[] = '$_output = ob_get_contents();';
$code[] = 'ob_end_clean();';
$code[] = '}';
$code[] = "return \$_output === true ? '' : \$_output;";
$code[] = '}}';
$code[] = "\$_parser->CachableElements['".$this->ElemName."'] = ".($this->Parser->Cachable[$this->Parser->Level] ? 'true':'false').';';
$o .= '<?'.'php';
$this->AppendCode($o, $code, false);
return $o;
// $this->Parser->Definitions .= $o."\n";
// return '';
} */
function _Tag_DefineElement($tag)
{
parent::_BlockTag($tag);
$this->_requiredParams = Array ('name');
}
function Open($tag)
{
$o = parent::Open($tag);
if ($o === false) {
// some required params not passed
return $o;
}
$f_name = $tag['NP']['name'].'_'.abs(crc32($tag['file'])).'_'.$tag['line'];
$this->Tag['function_name'] = $f_name; // for later use in closing tag
$code[] = "\$_parser->Elements['{$tag['NP']['name']}'] = '$f_name';";
// function_exists is required here, because a template may be included more than once
// leading to Cannot redeclare error
$code[] = "if (!function_exists('{$f_name}')) {";
$code[] = "function $f_name(&\$_parser, \$params) {";
$code[] = "global \$application;";
$tag['NP'] = $this->_extractParams($tag['NP']);
$defaults = $this->Parser->CompileParamsArray($tag['NP']);
$code[] = "\$params = array_merge($defaults, \$params);";
$code[] = "if (!isset(\$params['PrefixSpecial']) && isset(\$params['prefix'])) {\$params['PrefixSpecial'] = \$params['prefix'];};";
$code[] = "extract(\$params);";
$code[] = "\$_parser->SetParams(\$params);";
$code[] = 'ob_start();';
$this->AppendCode($o, $code);
return $o;
}
/**
* Converts $param_name to $params['param_name']
*
* @param Array $params
* @return Array
*/
function _extractParams($params)
{
foreach ($params as $param_name => $param_value) {
$params[$param_name] = preg_replace('/[\{]{0,1}([\$])(.*?[^\$\s\{\}]*)[\}]{0,1}/', '{$params[\'\\2\']}', $param_value);
}
return $params;
}
function Close($tag)
{
$o = $this->Parser->Buffers[$this->Parser->Level];
$code[] = '$_output = ob_get_contents();';
$code[] = 'ob_end_clean();';
$code[] = 'return $_output;';
$code[] = '}}';
$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;
}
}
class _Tag_Capture extends _Tag_DefineElement {
function _Tag_Capture($tag)
{
parent::_Tag_DefineElement($tag);
$this->_requiredParams = Array ('to_var');
}
function Open($tag)
{
if (!$this->_checkRequiredParams($tag)) {
return false;
}
$tag['NP']['name'] = '__capture_'.$tag['NP']['to_var'];
$o = '';
// $this->AppendCode($o, "\$_parser->Captures['{$tag['NP']['to_var']}'] = 1;", false);
$this->AppendCode($o, "\$_parser->Captures['{$tag['NP']['to_var']}'] = 1;");
$o .= parent::Open($tag);
return $o;
}
}
class _Tag_RenderElement extends _Tag_DefineElement {
var $Single = true;
var $OriginalTag;
var $_lambdaName = '';
function _Tag_RenderElement($tag)
{
parent::_Tag_DefineElement($tag);
if (!$tag['is_closing']) {
$this->_requiredParams = Array ('design');
}
}
function Open($tag)
{
if (!$this->_checkRequiredParams($tag)) {
return false;
}
$o = '';
if ($tag['is_closing']) {
if (isset($tag['NP']['design'])) {
$this->RenderDesignCode($o, $tag['NP']);
return $o;
}
$to_pass = $this->Parser->CompileParamsArray($tag['NP']);
/* $pointer = abs(crc32($tag['file'])).'_'.$tag['line'];
// $code[] = "}";
// $code[] = "if (!\$_parser->CachableElements['".$tag['NP']['name']."']) {";
// $code[] = "\$_parser->CacheEndInside();";
// $code[] = "}";
$o .= '<?'.'php ';
$this->AppendCode($o, $this->Parser->BreakCache('', $pointer.'a', "\$_parser->CachableElements['".$tag['NP']['name']."']"), false);
$this->AppendCode($o, "echo (\$_parser->ParseBlock($to_pass));\n", false);
$this->AppendCode($o, $this->Parser->BreakCache('', $pointer.'b') . " ?".">\n", false);
// $this->AppendCode($o, "if (!\$_parser->CacheStartOrContinue(\$_parser->CachableElements['".$tag['NP']['name']."'], '{$pointer}')) {".' ?'.'>', false);
*/
$this->AppendCode($o, "echo (\$_parser->ParseBlock($to_pass));");
return $o;
}
$this->Single = false;
$this->OriginalTag = $tag;
$tag['NP']['name'] = $tag['NP']['design'] . '_' . abs(crc32($tag['file'])) . '_' . $tag['line']; //'__lambda';
return parent::Open($tag);
}
function RenderDesignCode(&$o, $params)
{
$to_pass = $this->Parser->CompileParamsArray($params);
$code[] = "echo (\$_parser->ParseBlock(array_merge($to_pass, array('name'=>\"{$params['design']}\",'content'=>\$_parser->ParseBlock($to_pass), 'keep_data_exists'=>1))));";
$this->AppendCode($o, $code);
}
function Close($tag)
{
if ($this->Single) {
return $this->Parser->Buffers[$this->Parser->Level];
}
$o = parent::Close($tag);
$this->OriginalTag['NP']['name'] = $this->OriginalTag['NP']['design'] . '_' . abs(crc32($this->OriginalTag['file'])) . '_' . $this->OriginalTag['line']; //'__lambda';
$this->RenderDesignCode($o, $this->OriginalTag['NP']);
return $o;
}
}
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)
{
parent::_BlockTag($tag);
$this->_requiredParams = Array ('name');
}
function Open($tag)
{
$o = parent::Open($tag);
if ($o === false) {
// some required params not passed
return $o;
}
$capture_params = $tag['NP'];
$capture_params['name'] = '__capture_' . $tag['NP']['name'];
$capture_to_pass = $this->Parser->CompileParamsArray($capture_params);
$code[] = "if (isset(\$_parser->Captures['{$tag['NP']['name']}'])) {";
$code[] = "\${$tag['NP']['name']} = \$_parser->ParseBlock($capture_to_pass);";
$code[] = "}";
$code[] = "else {";
$to_pass = $this->Parser->CompileParamsArray($tag['NP']);
$code[] = '$_p_ =& $_parser->GetProcessor(\'m\');';
$code[] = '$_tag_params = ' . $to_pass . ';';
$code[] = "\${$tag['NP']['name']} = \$_p_->PostProcess(\${$tag['NP']['name']}, \$_p_->PreparePostProcess(\$_tag_params));";
$code[] = "}";
if (array_key_exists('result_to_var', $tag['NP']) && $tag['NP']['result_to_var']) {
$code[] = "\$params['{$tag['NP']['result_to_var']}'] = \$_parser->GetParam('{$tag['NP']['result_to_var']}');";
if (array_key_exists('plus', $tag['NP'])) {
$code[] = "\$params['{$tag['NP']['result_to_var']}'] += {$tag['NP']['plus']};";
}
$code[] = "\${$tag['NP']['result_to_var']} = \$params['{$tag['NP']['result_to_var']}'];";
}
elseif (array_key_exists('plus', $tag['NP'])) {
$code[] = "\${$tag['NP']['name']} += {$tag['NP']['plus']};";
}
$code[] = "\$params['{$tag['NP']['name']}'] = \${$tag['NP']['name']};";
$code[] = "echo (\${$tag['NP']['name']});";
$this->AppendCode($o, $code);
return $o;
}
}
class _Tag_Include extends _BlockTag {
function Open($tag)
{
$o = '';
$to_pass = $this->Parser->CompileParamsArray($tag['NP']);
$this->AppendCode($o, "echo (\$_parser->IncludeTemplate($to_pass))");
return $o;
}
}
class _Tag_If extends _BlockTag {
/**
* Permanently inverses if tag (used in ifnot tag)
*
* @var bool
*/
var $_Inversed = false;
/**
* Count of "elseif" tags inside
*
* @var int
*/
var $_elseIfCount = 0;
function _Tag_If($tag)
{
parent::_BlockTag($tag);
$this->_requiredParams = Array ('check');
}
function Open($tag)
{
$o = parent::Open($tag);
if ($o === false) {
// some required params not passed
return $o;
}
$to_pass = $this->Parser->CompileParamsArray($tag['NP']);
$code[] = "\$_splited = \$_parser->SplitTag(array('tag'=>\"{$tag['NP']['check']}\", 'file'=>'{$tag['file']}', 'line'=>{$tag['line']}));";
$code[] = 'if ($_splited[\'prefix\'] == \'__auto__\') {$_splited[\'prefix\'] = $PrefixSpecial;}';
$code[] = '$_p_ =& $_parser->GetProcessor($_splited[\'prefix\']);';
if (isset($tag['NP']['inverse']) || $this->_Inversed) {
$code[] = "if (!\$_p_->ProcessParsedTag(\$_splited['name'], $to_pass, \$_splited['prefix'], '{$tag['file']}', {$tag['line']})) {";
}
else {
$code[] = "if (\$_p_->ProcessParsedTag(\$_splited['name'], $to_pass, \$_splited['prefix'], '{$tag['file']}', {$tag['line']})) {";
}
$this->AppendCode($o, $code);
return $o;
}
function PassThrough(&$tag)
{
$o = '';
if ($tag['name'] == 'else') {
$this->AppendCode($o, '} else {');
$tag['processed'] = true;
}
if ($tag['name'] == 'elseif') {
if (!$this->_checkRequiredParams($tag)) {
return '';
}
$to_pass = $this->Parser->CompileParamsArray($tag['NP']);
$this->_elseIfCount++; // add same count of closing brackets in closing tag
$this->AppendCode($o, "} else {");
$code[] = "\$_splited = \$_parser->SplitTag(array('tag'=>\"{$tag['NP']['check']}\", 'file'=>'{$tag['file']}', 'line'=>{$tag['line']}));";
$code[] = 'if ($_splited[\'prefix\'] == \'__auto__\') {$_splited[\'prefix\'] = $PrefixSpecial;}';
$code[] = '$_p_ =& $_parser->GetProcessor($_splited[\'prefix\']);';
if (isset($tag['NP']['inverse']) || $this->_Inversed) {
$code[] = "if (!\$_p_->ProcessParsedTag(\$_splited['name'], $to_pass, \$_splited['prefix'], '{$tag['file']}', {$tag['line']})) {";
}
else {
$code[] = "if (\$_p_->ProcessParsedTag(\$_splited['name'], $to_pass, \$_splited['prefix'], '{$tag['file']}', {$tag['line']})) {";
}
$this->AppendCode($o, $code);
$tag['processed'] = true;
}
return $o;
}
function Close($tag)
{
$o = $this->Parser->Buffers[$this->Parser->Level];
$code = str_repeat("}\n", $this->_elseIfCount + 1);
$this->AppendCode($o, $code);
return $o;
}
}
class _Tag_IfNot extends _Tag_If {
function _Tag_IfNot($tag)
{
parent::_Tag_If($tag);
$this->_Inversed = true;
}
}
class _Tag_DefaultParam extends _BlockTag {
function Open($tag)
{
$o = '';
foreach ($tag['NP'] as $key => $val) {
$code[] = 'if (!isset($' . $key . ')) $params[\'' . $key . '\'] = \'' . $val . '\';';
$code[] = '$' . $key . ' = isset($' . $key . ') ? $' . $key . ' : \'' . $val . '\';';
$code[] = '$_parser->SetParam(\'' . $key . '\', $' . $key . ');';
}
$this->AppendCode($o, $code);
return $o;
}
}
class _Tag_SetParam extends _BlockTag {
function Open($tag)
{
$o = '';
foreach ($tag['NP'] as $key => $val) {
$code[] = '$params[\'' . $key . '\'] = \'' . $val . '\';';
$code[] = '$' . $key . ' = \'' . $val . '\';';
$code[] = '$_parser->SetParam(\'' . $key . '\', $' . $key . ');';
}
$this->AppendCode($o, $code);
return $o;
}
}
class _Tag_Cache extends _BlockTag {
function Open($tag)
{
$o = '';
$pointer = abs(crc32($tag['file'])).'_'.$tag['line'];
$key = array_key_exists('key', $tag['NP']) ? $tag['NP']['key'] : '';
$this->AppendCode($o, "if (!\$_parser->CacheStart('{$pointer}', \"{$key}\")) {\n");
return $o;
}
function Close($tag)
{
$o = $this->Parser->Buffers[$this->Parser->Level];
$cache_timeout = array_key_exists('cache_timeout', $this->Tag['NP']) ? $this->Tag['NP']['cache_timeout'] : 0;
$this->AppendCode($o, "\$_parser->CacheEnd(" . (int)$cache_timeout . ");\n}\n");
return $o;
}
}
class _Tag_IfDataExists extends _BlockTag {
function Open($tag)
{
$o = '';
$code = array();
$code[] = "ob_start();\n";
$code[] = '$_tmp_data_exists = $_parser->DataExists;';
$code[] = '$_parser->DataExists = false;';
$this->AppendCode($o, $code);
return $o;
}
function Close($tag)
{
$o = $this->Parser->Buffers[$this->Parser->Level];
$code = array();
$code[] = '$res = ob_get_clean();';
$code[] = 'if ($_parser->DataExists) {echo $res;}';
$code[] = '$_parser->DataExists = $_tmp_data_exists;';
$this->AppendCode($o, $code);
return $o;
}
+}
+
+class _Tag_Compress extends _BlockTag {
+
+ function _Tag_Compress($tag)
+ {
+ parent::_BlockTag($tag);
+
+ if ($tag['is_closing']) {
+ if (!array_key_exists('files', $tag['NP'])) {
+ $this->_requiredParams = Array ('from');
+ }
+ else {
+ $this->_requiredParams = Array ('files');
+ }
+ }
+ else {
+ $this->_requiredParams = Array ('type'); // js/css
+ }
+ }
+
+ /**
+ * When used as non-block tag, then compress given files and return url to result
+ *
+ * @param Array $tag
+ * @return string
+ */
+ function Open($tag)
+ {
+ $o = parent::Open($tag);
+
+ if ($o === false) {
+ // some required params not passed
+ return $o;
+ }
+
+ if ($tag['is_closing']) {
+ $to_pass = $this->Parser->CompileParamsArray($tag['NP']);
+ $this->AppendCode($o, "echo \$_parser->CompressScript($to_pass, false);");
+ }
+ else {
+ $this->AppendCode($o, "ob_start();");
+ }
+
+ return $o;
+ }
+
+ /**
+ * When used as block tag, then compress contents between tags
+ *
+ * @param Array $tag
+ * @return string
+ */
+ function Close($tag)
+ {
+ if ($this->Tag['is_closing']) {
+ return parent::Close($tag);
+ }
+
+ $o = parent::Close($tag);
+
+ $code = Array ();
+ $code[] = '$res = ob_get_clean();';
+ $code[] = 'echo $_parser->CompressScript($res, true, \'' . $this->Tag['NP']['type'] . '\');';
+
+ $this->AppendCode($o, $code);
+
+ return $o;
+ }
}
\ No newline at end of file
Index: branches/5.1.x/core/units/categories/categories_tag_processor.php
===================================================================
--- branches/5.1.x/core/units/categories/categories_tag_processor.php (revision 13486)
+++ branches/5.1.x/core/units/categories/categories_tag_processor.php (revision 13487)
@@ -1,1954 +1,1970 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 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.
*/
class CategoriesTagProcessor extends kDBTagProcessor {
function SubCatCount($params)
{
$object =& $this->getObject($params);
if (isset($params['today']) && $params['today']) {
$sql = 'SELECT COUNT(*)
FROM '.$object->TableName.'
WHERE (ParentPath LIKE "'.$object->GetDBField('ParentPath').'%") AND (CreatedOn > '.(adodb_mktime() - 86400).')';
return $this->Conn->GetOne($sql) - 1;
}
return $object->GetDBField('CachedDescendantCatsQty');
}
/**
* Returns category count in system
*
* @param Array $params
* @return int
*/
function CategoryCount($params)
{
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
$today_only = isset($params['today']) && $params['today'];
return $count_helper->CategoryCount($today_only);
}
function IsNew($params)
{
$object =& $this->getObject($params);
return $object->GetDBField('IsNew') ? 1 : 0;
}
function IsPick($params)
{
return $this->IsEditorsPick($params);
}
/**
* Returns item's editors pick status (using not formatted value)
*
* @param Array $params
* @return bool
*/
function IsEditorsPick($params)
{
$object =& $this->getObject($params);
return $object->GetDBField('EditorsPick') == 1;
}
function ItemIcon($params)
{
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
$grid = $grids[ $params['grid'] ];
if (!array_key_exists('Icons', $grid)) {
return '';
}
$icons = $grid['Icons'];
if (array_key_exists('name', $params)) {
$icon_name = $params['name'];
return array_key_exists($icon_name, $icons) ? $icons[$icon_name] : '';
}
$object =& $this->getObject($params);
/* @var $object kDBList */
if ($object->GetDBField('CreatedBySystem')) {
if (!$object->GetDBField('IsMenu')) {
return 'icon16_section_menuhidden_system.png';
}
return 'icon16_section_system.png';
}
$status = $object->GetDBField('Status');
if ($status == STATUS_DISABLED) {
return 'icon16_section_disabled.png';
}
if (!$object->GetDBField('IsMenu')) {
return 'icon16_section_menuhidden.png';
}
if ($status == STATUS_PENDING) {
return 'icon16_section_pending.png';
}
if ($object->GetDBField('IsNew')) {
return 'icon16_section_new.png';
}
return 'icon16_section.png';
}
function ItemCount($params)
{
$object =& $this->getObject($params);
$ci_table = $this->Application->getUnitOption('l-ci', 'TableName');
$sql = 'SELECT COUNT(*)
FROM ' . $object->TableName . ' c
LEFT JOIN ' . $ci_table . ' ci ON c.CategoryId = ci.CategoryId
WHERE (c.TreeLeft BETWEEN ' . $object->GetDBField('TreeLeft') . ' AND ' . $object->GetDBField('TreeRight') . ') AND NOT (ci.CategoryId IS NULL)';
return $this->Conn->GetOne($sql);
}
function ListCategories($params)
{
return $this->PrintList2($params);
}
function RootCategoryName($params)
{
return $this->Application->ProcessParsedTag('m', 'RootCategoryName', $params);
}
function CheckModuleRoot($params)
{
$module_name = getArrayValue($params, 'module') ? $params['module'] : 'In-Commerce';
$module_root_cat = $this->Application->findModule('Name', $module_name, 'RootCat');
$additional_cats = $this->SelectParam($params, 'add_cats');
if ($additional_cats) {
$additional_cats = explode(',', $additional_cats);
}
else {
$additional_cats = array();
}
if ($this->Application->GetVar('m_cat_id') == $module_root_cat || in_array($this->Application->GetVar('m_cat_id'), $additional_cats)) {
$home_template = getArrayValue($params, 'home_template');
if (!$home_template) return;
$this->Application->Redirect($home_template, Array('pass'=>'all'));
};
}
function CategoryPath($params)
{
$category_helper =& $this->Application->recallObject('CategoryHelper');
/* @var $category_helper CategoryHelper */
return $category_helper->NavigationBar($params);
}
/**
* Shows category path to specified category
*
* @param Array $params
* @return string
*/
function FieldCategoryPath($params)
{
$object =& $this->getObject();
/* @var $object kDBItem */
$field = $this->SelectParam($params, 'name,field');
$category_id = $object->GetDBField($field);
if ($category_id) {
$params['cat_id'] = $category_id;
return $this->CategoryPath($params);
}
return '';
}
function CurrentCategoryName($params)
{
$cat_object =& $this->Application->recallObject($this->getPrefixSpecial(), $this->Prefix.'_List');
$sql = 'SELECT '.$this->getTitleField().'
FROM '.$cat_object->TableName.'
WHERE CategoryId = '.(int)$this->Application->GetVar('m_cat_id');
return $this->Conn->GetOne($sql);
}
/**
* Returns current category name
*
* @param Array $params
* @return string
* @todo Find where it's used
*/
function CurrentCategory($params)
{
return $this->CurrentCategoryName($params);
}
function getTitleField()
{
$ml_formatter =& $this->Application->recallObject('kMultiLanguage');
return $ml_formatter->LangFieldName('Name');
}
/**
* Returns symlinked category for given category
*
* @param $category_id
*/
function getCategorySymLink($category_id)
{
if (!$category_id) {
// don't bother to get symlink for "Home" category
return $category_id;
}
$cache_key = 'category_symlinks[%CSerial%]';
$cache = $this->Application->getCache($cache_key);
if ($cache === false) {
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
// get symlinked categories, that are not yet deleted
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT c1.SymLinkCategoryId, c1.' . $id_field . '
FROM ' . $table_name . ' c1
JOIN ' . $table_name . ' c2 ON c1.SymLinkCategoryId = c2.' . $id_field;
$cache = $this->Conn->GetCol($sql, $id_field);
$this->Application->setCache($cache_key, $cache);
}
return array_key_exists($category_id, $cache) ? $cache[$category_id] : $category_id;
}
function CategoryLink($params)
{
$category_id = getArrayValue($params, 'cat_id');
if ($category_id === false) {
$category_id = $this->Application->GetVar($this->getPrefixSpecial() . '_id');
}
if ("$category_id" == 'Root') {
$category_id = $this->Application->findModule('Name', $params['module'], 'RootCat');
}
elseif ("$category_id" == 'current') {
$category_id = $this->Application->GetVar('m_cat_id');
}
$category_id = $this->getCategorySymLink( (int)$category_id );
unset($params['cat_id'], $params['module']);
$new_params = Array ('pass' => 'm', 'm_cat_id' => $category_id, 'pass_category' => 1);
$params = array_merge_recursive2($params, $new_params);
return $this->Application->ProcessParsedTag('m', 't', $params);
}
function CategoryList($params)
{
//$object =& $this->Application->recallObject( $this->getPrefixSpecial() , $this->Prefix.'_List', $params );
$object =& $this->GetList($params);
if ($object->RecordsCount == 0)
{
if (isset($params['block_no_cats'])) {
$params['name'] = $params['block_no_cats'];
return $this->Application->ParseBlock($params);
}
else {
return '';
}
}
if (isset($params['block'])) {
return $this->PrintList($params);
}
else {
$params['block'] = $params['block_main'];
if (isset($params['block_row_start'])) {
$params['row_start_block'] = $params['block_row_start'];
}
if (isset($params['block_row_end'])) {
$params['row_end_block'] = $params['block_row_end'];
}
return $this->PrintList2($params);
}
}
function Meta($params)
{
$object =& $this->Application->recallObject($this->Prefix); // .'.-item'
/* @var $object CategoriesItem */
$meta_type = $params['name'];
if ($object->isLoaded()) {
// 1. get module prefix by current category
$category_helper =& $this->Application->recallObject('CategoryHelper');
/* @var $category_helper CategoryHelper */
$category_path = explode('|', substr($object->GetDBField('ParentPath'), 1, -1));
$module_info = $category_helper->getCategoryModule($params, $category_path);
// In-Edit & Proj-CMS module prefixes doesn't have custom field with item template
if ($module_info && $module_info['Var'] != 'adm' && $module_info['Var'] != 'st') {
// 2. get item template by current category & module prefix
$mod_rewrite_helper = $this->Application->recallObject('ModRewriteHelper');
/* @var $mod_rewrite_helper kModRewriteHelper */
$category_params = Array (
'CategoryId' => $object->GetID(),
'ParentPath' => $object->GetDBField('ParentPath'),
);
$item_template = $mod_rewrite_helper->GetItemTemplate($category_params, $module_info['Var']);
if ($this->Application->GetVar('t') == $item_template) {
// we are located on item's details page
$item =& $this->Application->recallObject($module_info['Var']);
/* @var $item kCatDBItem */
// 3. get item's meta data
$value = $item->GetField('Meta'.$meta_type);
if ($value) {
return $value;
}
}
// 4. get category meta data
$value = $object->GetField('Meta'.$meta_type);
if ($value) {
return $value;
}
}
}
// 5. get default meta data
switch ($meta_type) {
case 'Description':
$config_name = 'Category_MetaDesc';
break;
case 'Keywords':
$config_name = 'Category_MetaKey';
break;
}
return $this->Application->ConfigValue($config_name);
}
function BuildListSpecial($params)
{
if (($this->Special != '') && !is_numeric($this->Special)) {
// When recursive category list is printed (like in sitemap), then special
// should be generated even if it's already present. Without it list on this
// level will erase list on previous level, because it will be stored in same object.
return $this->Special;
}
if ( isset($params['parent_cat_id']) ) {
$parent_cat_id = $params['parent_cat_id'];
}
else {
$parent_cat_id = $this->Application->GetVar($this->Prefix.'_id');
if (!$parent_cat_id) {
$parent_cat_id = $this->Application->GetVar('m_cat_id');
}
if (!$parent_cat_id) {
$parent_cat_id = 0;
}
}
$list_unique_key = $this->getUniqueListKey($params);
// check for "admin" variable, because we are parsing front-end template from admin when using template editor feature
if ($this->Application->GetVar('admin') || !$this->Application->isAdmin) {
// add parent category to special, when on Front-End,
// because there can be many category lists on same page
$list_unique_key .= $parent_cat_id;
}
if ($list_unique_key == '') {
return parent::BuildListSpecial($params);
}
return crc32($list_unique_key);
}
function IsCurrent($params)
{
$object =& $this->getObject($params);
if ($object->GetID() == $this->Application->GetVar('m_cat_id')) {
return true;
}
else {
return false;
}
}
/**
* Substitutes category in last template base on current category
* This is required becasue when you navigate catalog using AJAX, last_template is not updated
* but when you open item edit from catalog last_template is used to build opener_stack
* So, if we don't substitute m_cat_id in last_template, after saving item we'll get redirected
* to the first category we've opened, not the one we navigated to using AJAX
*
* @param Array $params
*/
function UpdateLastTemplate($params)
{
$category_id = $this->Application->GetVar('m_cat_id');
$wid = $this->Application->GetVar('m_wid');
list($index_file, $env) = explode('|', $this->Application->RecallVar(rtrim('last_template_'.$wid, '_')), 2);
$vars_backup = Array ();
$vars = $this->Application->HttpQuery->processQueryString( str_replace('%5C', '\\', $env) );
foreach ($vars as $var_name => $var_value) {
$vars_backup[$var_name] = $this->Application->GetVar($var_name);
$this->Application->SetVar($var_name, $var_value);
}
// update required fields
$this->Application->SetVar('m_cat_id', $category_id);
$this->Application->Session->SaveLastTemplate($params['template']);
foreach ($vars_backup as $var_name => $var_value) {
$this->Application->SetVar($var_name, $var_value);
}
}
function GetParentCategory($params)
{
$parent_id = 0;
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table = $this->Application->getUnitOption($this->Prefix,'TableName');
$cat_id = $this->Application->GetVar('m_cat_id');
if ($cat_id > 0) {
$sql = 'SELECT ParentId
FROM '.$table.'
WHERE '.$id_field.' = '.$cat_id;
$parent_id = $this->Conn->GetOne($sql);
}
return $parent_id;
}
function InitCacheUpdater($params)
{
safeDefine('CACHE_PERM_CHUNK_SIZE', 30);
$continue = $this->Application->GetVar('continue');
$total_cats = (int) $this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'Category');
if ($continue === false && $total_cats > CACHE_PERM_CHUNK_SIZE) {
// first step, if category count > CACHE_PERM_CHUNK_SIZE, then ask for cache update
return true;
}
if ($continue === false) {
// if we don't have to ask, then assume user selected "Yes" in permcache update dialog
$continue = 1;
}
$updater =& $this->Application->recallObject('kPermCacheUpdater', null, Array('continue' => $continue));
/* @var $updater kPermCacheUpdater */
if ($continue === '0') { // No in dialog
$updater->clearData();
$this->Application->Redirect($params['destination_template']);
}
$ret = false; // don't ask for update
if ($continue == 1) { // Initial run
$updater->setData();
}
if ($continue == 2) { // Continuing
// called from AJAX request => returns percent
$needs_more = true;
while ($needs_more && $updater->iteration <= CACHE_PERM_CHUNK_SIZE) {
// until proceeeded in this step category count exceeds category per step limit
$needs_more = $updater->DoTheJob();
}
if ($needs_more) {
// still some categories are left for next step
$updater->setData();
}
else {
// all done -> redirect
$updater->SaveData();
$this->Application->RemoveVar('PermCache_UpdateRequired');
$this->Application->Redirect($params['destination_template']);
}
$ret = $updater->getDonePercent();
}
return $ret;
}
/**
* Parses warning block, but with style="display: none;". Used during permissions saving from AJAX
*
* @param Array $params
* @return string
*/
function SaveWarning($params)
{
if ($this->Prefix == 'st') {
// don't use this method for other prefixes then Category, that use this tag processor
return parent::SaveWarning($params);
}
$main_prefix = getArrayValue($params, 'main_prefix');
if ($main_prefix && $main_prefix != '$main_prefix') {
$top_prefix = $main_prefix;
}
else {
$top_prefix = $this->Application->GetTopmostPrefix($this->Prefix);
}
$temp_tables = substr($this->Application->GetVar($top_prefix.'_mode'), 0, 1) == 't';
$modified = $this->Application->RecallVar($top_prefix.'_modified');
if (!$temp_tables) {
$this->Application->RemoveVar($top_prefix.'_modified');
return '';
}
$block_name = $this->SelectParam($params, 'render_as,name');
if ($block_name) {
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $block_name;
$block_params['edit_mode'] = $temp_tables ? 1 : 0;
$block_params['display'] = $temp_tables && $modified ? 1 : 0;
return $this->Application->ParseBlock($block_params);
}
else {
return $temp_tables && $modified ? 1 : 0;
}
return ;
}
/**
* Allows to detect if this prefix has something in clipboard
*
* @param Array $params
* @return bool
*/
function HasClipboard($params)
{
$clipboard = $this->Application->RecallVar('clipboard');
if ($clipboard) {
$clipboard = unserialize($clipboard);
foreach ($clipboard as $prefix => $clipboard_data) {
foreach ($clipboard_data as $mode => $ids) {
if (count($ids)) return 1;
}
}
}
return 0;
}
/**
* Allows to detect if root category being edited
*
* @param Array $params
*/
function IsRootCategory($params)
{
$object =& $this->getObject($params);
return $object->IsRoot();
}
/**
* Returns home category id
*
* @param Array $params
* @return int
*/
function HomeCategory($params)
{
static $root_category = null;
if (!isset($root_category)) {
$root_category = $this->Application->findModule('Name', 'Core', 'RootCat');
}
return $root_category;
}
/**
* Used for disabling "Home" and "Up" buttons in category list
*
* @param Array $params
* @return bool
*/
function ModuleRootCategory($params)
{
return $this->Application->GetVar('m_cat_id') == $this->HomeCategory($params);
}
function CatalogItemCount($params)
{
$params['skip_quering'] = true;
$object =& $this->GetList($params);
if (!$object->Counted) {
$object->CountRecs();
}
return $object->NoFilterCount != $object->RecordsCount ? $object->RecordsCount.' / '.$object->NoFilterCount : $object->RecordsCount;
}
function InitCatalog($params)
{
$tab_prefixes = $this->Application->GetVar('tp'); // {all, <prefixes_list>, none}
if ($tab_prefixes === false) $tab_prefixes = 'all';
$skip_prefixes = isset($params['skip_prefixes']) && $params['skip_prefixes'] ? explode(',', $params['skip_prefixes']) : Array();
$replace_main = isset($params['replace_m']) && $params['replace_m'];
// get all prefixes available
$prefixes = Array();
foreach ($this->Application->ModuleInfo as $module_name => $module_data) {
$prefix = $module_data['Var'];
if ($prefix == 'adm'/* || $prefix == 'm'*/) continue;
if ($prefix == 'm' && $replace_main) {
$prefix = 'c';
}
$prefixes[] = $prefix;
}
if ($tab_prefixes == 'none') {
$skip_prefixes = array_unique(array_merge($skip_prefixes, $prefixes));
unset($skip_prefixes[ array_search($replace_main ? 'c' : 'm', $skip_prefixes) ]);
}
elseif ($tab_prefixes != 'all') {
// prefix list here
$tab_prefixes = explode(',', $tab_prefixes); // list of prefixes that should stay
$skip_prefixes = array_unique(array_merge($skip_prefixes, array_diff($prefixes, $tab_prefixes)));
}
$params['name'] = $params['render_as'];
$params['skip_prefixes'] = implode(',', $skip_prefixes);
return $this->Application->ParseBlock($params, 1);
}
/**
* Determines, that printed category/menu item is currently active (will also match parent category)
*
* @param Array $params
* @return bool
*/
function IsActive($params)
{
static $current_path = null;
if (!isset($current_path)) {
$sql = 'SELECT ParentPath
FROM ' . TABLE_PREFIX . 'Category
WHERE CategoryId = ' . (int)$this->Application->GetVar('m_cat_id');
$current_path = $this->Conn->GetOne($sql);
}
if (array_key_exists('parent_path', $params)) {
$test_path = $params['parent_path'];
}
else {
$template = $params['template'];
if ($template) {
// when using from "c:CachedMenu" tag
$sql = 'SELECT ParentPath
FROM ' . TABLE_PREFIX . 'Category
WHERE NamedParentPath = ' . $this->Conn->qstr('Content/' . $template);
$test_path = $this->Conn->GetOne($sql);
}
else {
// when using from "c:PrintList" tag
$cat_id = array_key_exists('cat_id', $params) && $params['cat_id'] ? $params['cat_id'] : false;
if ($cat_id === false) {
// category not supplied -> get current from PrintList
$category =& $this->getObject($params);
}
else {
if ("$cat_id" == 'Root') {
$cat_id = $this->Application->findModule('Name', $params['module'], 'RootCat');
}
$category =& $this->Application->recallObject($this->Prefix . '.-c' . $cat_id, $this->Prefix, Array ('skip_autoload' => true));
$category->Load($cat_id);
}
$test_path = $category->GetDBField('ParentPath');
}
}
return strpos($current_path, $test_path) !== false;
}
/**
* Checks if user have one of required permissions
*
* @param Array $params
* @return bool
*/
function HasPermission($params)
{
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$params['raise_warnings'] = 0;
$object =& $this->getObject($params);
/* @var $object kDBItem */
$params['cat_id'] = $object->isLoaded() ? $object->GetDBField('ParentPath') : $this->Application->GetVar('m_cat_id');
return $perm_helper->TagPermissionCheck($params);
}
/**
* Prepares name for field with event in it (used only on front-end)
*
* @param Array $params
* @return string
*/
function SubmitName($params)
{
return 'events[' . $this->Prefix . '][' . $params['event'] . ']';
}
/**
* Returns last modification date of items in category / system
*
* @param Array $params
* @return string
*/
function LastUpdated($params)
{
$category_id = (int)$this->Application->GetVar('m_cat_id');
$local = array_key_exists('local', $params) && ($category_id > 0) ? $params['local'] : false;
$serial_name = $this->Application->incrementCacheSerial('c', $local ? $category_id : null, false);
$cache_key = 'category_last_updated[%' . $serial_name . '%]';
$row_data = $this->Application->getCache($cache_key);
if ($row_data === false) {
if ($local && ($category_id > 0)) {
// scan only current category & it's children
list ($tree_left, $tree_right) = $this->Application->getTreeIndex($category_id);
$sql = 'SELECT MAX(Modified) AS ModDate, MAX(CreatedOn) AS NewDate
FROM ' . TABLE_PREFIX . 'Category
WHERE TreeLeft BETWEEN ' . $tree_left . ' AND ' . $tree_right;
}
else {
// scan all categories in system
$sql = 'SELECT MAX(Modified) AS ModDate, MAX(CreatedOn) AS NewDate
FROM ' . TABLE_PREFIX . 'Category';
}
$this->Conn->nextQueryCachable = true;
$row_data = $this->Conn->GetRow($sql);
$this->Application->setCache($cache_key, $row_data);
}
if (!$row_data) {
return '';
}
$date = $row_data[ $row_data['NewDate'] > $row_data['ModDate'] ? 'NewDate' : 'ModDate' ];
// format date
$format = isset($params['format']) ? $params['format'] : '_regional_DateTimeFormat';
if (preg_match("/_regional_(.*)/", $format, $regs)) {
$lang =& $this->Application->recallObject('lang.current');
if ($regs[1] == 'DateTimeFormat') {
// combined format
$format = $lang->GetDBField('DateFormat') . ' ' . $lang->GetDBField('TimeFormat');
}
else {
// simple format
$format = $lang->GetDBField($regs[1]);
}
}
return adodb_date($format, $date);
}
function CategoryItemCount($params)
{
$object =& $this->getObject($params);
/* @var $object kDBList */
$params['cat_id'] = $object->GetID();
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
return $count_helper->CategoryItemCount($params['prefix'], $params);
}
/**
* Returns prefix + any word (used for shared between categories per page settings)
*
* @param Array $params
* @return string
*/
function VarName($params)
{
return $this->Prefix.'_'.$params['type'];
}
/**
* Checks if current category is valid symbolic link to another category
*
* @param Array $params
* @return string
*/
function IsCategorySymLink($params)
{
$object =& $this->getObject($params);
/* @var $object kDBList */
$sym_category_id = $object->GetDBField('SymLinkCategoryId');
if (is_null($sym_category_id))
{
return false;
}
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
$sql = 'SELECT '.$id_field.'
FROM '.$table_name.'
WHERE '.$id_field.' = '.$sym_category_id;
return $this->Conn->GetOne($sql)? true : false;
}
/**
* Returns module prefix based on root category for given
*
* @param Array $params
* @return string
*/
function GetModulePrefix($params)
{
$object =& $this->getObject($params);
/* @var $object kDBItem */
$parent_path = explode('|', substr($object->GetDBField('ParentPath'), 1, -1));
$category_helper =& $this->Application->recallObject('CategoryHelper');
/* @var $category_helper CategoryHelper */
$module_info = $category_helper->getCategoryModule($params, $parent_path);
return $module_info['Var'];
}
function ImageSrc($params)
{
list ($ret, $tag_processed) = $this->processAggregatedTag('ImageSrc', $params, $this->getPrefixSpecial());
return $tag_processed ? $ret : false;
}
function PageLink($params)
{
$params['m_cat_page'] = $this->Application->GetVar($this->getPrefixSpecial() . '_Page');
return parent::PageLink($params);
}
/**
* Returns spelling suggestions against search keyword
*
* @param Array $params
* @return string
*/
function SpellingSuggestions($params)
{
$keywords = unhtmlentities( trim($this->Application->GetVar('keywords')) );
if (!$keywords) {
return ;
}
// 1. try to get already cached suggestion
$cache_key = 'search.suggestion[%SpellingDictionary%]:' . $keywords;
$suggestion = $this->Application->getCache($cache_key);
if ($suggestion !== false) {
return $suggestion;
}
$table_name = $this->Application->getUnitOption('spelling-dictionary', 'TableName');
// 2. search suggestion in database
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT SuggestedCorrection
FROM ' . $table_name . '
WHERE MisspelledWord = ' . $this->Conn->qstr($keywords);
$suggestion = $this->Conn->GetOne($sql);
if ($suggestion !== false) {
$this->Application->setCache($cache_key, $suggestion);
return $suggestion;
}
// 3. suggestion not found in database, ask webservice
$app_id = $this->Application->ConfigValue('YahooApplicationId');
$url = 'http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion?appid=' . $app_id . '&query=';
$curl_helper =& $this->Application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
$xml_data = $curl_helper->Send($url . urlencode($keywords));
$xml_helper =& $this->Application->recallObject('kXMLHelper');
/* @var $xml_helper kXMLHelper */
$root_node =& $xml_helper->Parse($xml_data);
$result = $root_node->FindChild('RESULT');
/* @var $result kXMLNode */
if (is_object($result)) {
// webservice responded -> save in local database
$fields_hash = Array (
'MisspelledWord' => $keywords,
'SuggestedCorrection' => $result->Data,
);
$this->Conn->doInsert($fields_hash, $table_name);
$this->Application->setCache($cache_key, $result->Data);
return $result->Data;
}
return '';
}
/**
* Shows link for searching by suggested word
*
* @param Array $params
* @return string
*/
function SuggestionLink($params)
{
$params['keywords'] = $this->SpellingSuggestions($params);
return $this->Application->ProcessParsedTag('m', 'Link', $params);
}
function InitCatalogTab($params)
{
$tab_params['mode'] = $this->Application->GetVar('tm'); // single/multi selection possible
$tab_params['special'] = $this->Application->GetVar('ts'); // use special for this tab
$tab_params['dependant'] = $this->Application->GetVar('td'); // is grid dependant on categories grid
// set default params (same as in catalog)
if ($tab_params['mode'] === false) $tab_params['mode'] = 'multi';
if ($tab_params['special'] === false) $tab_params['special'] = '';
if ($tab_params['dependant'] === false) $tab_params['dependant'] = 'yes';
// pass params to block with tab content
$params['name'] = $params['render_as'];
$special = $tab_params['special'] ? $tab_params['special'] : $this->Special;
$params['prefix'] = trim($this->Prefix.'.'.$special, '.');
$prefix_append = $this->Application->GetVar('prefix_append');
if ($prefix_append) {
$params['prefix'] .= $prefix_append;
}
$default_grid = array_key_exists('default_grid', $params) ? $params['default_grid'] : 'Default';
$radio_grid = array_key_exists('radio_grid', $params) ? $params['radio_grid'] : 'Radio';
$params['cat_prefix'] = trim('c.'.($tab_params['special'] ? $tab_params['special'] : $this->Special), '.');
$params['tab_mode'] = $tab_params['mode'];
$params['grid_name'] = ($tab_params['mode'] == 'multi') ? $default_grid : $radio_grid;
$params['tab_dependant'] = $tab_params['dependant'];
$params['show_category'] = $tab_params['special'] == 'showall' ? 1 : 0; // this is advanced view -> show category name
if ($special == 'showall' || $special == 'user') {
$params['grid_name'] .= 'ShowAll';
}
return $this->Application->ParseBlock($params, 1);
}
/**
* Show CachedNavbar of current item primary category
*
* @param Array $params
* @return string
*/
function CategoryName($params)
{
// show category cachednavbar of
$object =& $this->getObject($params);
$category_id = isset($params['cat_id']) ? $params['cat_id'] : $object->GetDBField('CategoryId');
$cache_key = 'category_paths[%CIDSerial:' . $category_id . '%]';
if ($category_id == 0) {
// home category name is phrase AND phrase name is defined in configuration
$cache_key .= '[%PhrasesSerial%][%ConfSerial%]';
}
$category_path = $this->Application->getCache($cache_key);
if ($category_path === false) {
// not chached
if ($category_id > 0) {
$cached_navbar = $object->GetField('CachedNavbar');
if ($category_id == $object->GetDBField('ParentId')) {
// parent category cached navbar is one element smaller, then current ones
$cached_navbar = explode('&|&', $cached_navbar);
array_pop($cached_navbar);
$cached_navbar = implode('&|&', $cached_navbar);
}
else {
// no relation with current category object -> query from db
$language_id = (int)$this->Application->GetVar('m_lang');
if (!$language_id) {
$language_id = 1;
}
$sql = 'SELECT l' . $language_id . '_CachedNavbar
FROM ' . $object->TableName . '
WHERE ' . $object->IDField . ' = ' . $category_id;
$cached_navbar = $this->Conn->GetOne($sql);
}
$cached_navbar = preg_replace('/^(Content&\|&|Content)/i', '', $cached_navbar);
$category_path = trim($this->CategoryName( Array('cat_id' => 0) ).' > '.str_replace('&|&', ' > ', $cached_navbar), ' > ');
}
else {
$category_path = $this->Application->Phrase( $this->Application->ConfigValue('Root_Name') );
}
$this->Application->setCache($cache_key, $category_path);
}
return $category_path;
}
// structure related
/**
* Returns page object based on requested params
*
* @param Array $params
* @return PagesItem
*/
function &_getPage($params)
{
$page =& $this->Application->recallObject($this->Prefix . '.-virtual', null, $params);
/* @var $page kDBItem */
// 1. load by given id
$page_id = array_key_exists('page_id', $params) ? $params['page_id'] : false;
if ($page_id) {
if ($page_id != $page->GetID()) {
// load if different
$page->Load($page_id);
}
return $page;
}
// 2. load by template
$template = array_key_exists('page', $params) ? $params['page'] : '';
if (!$template) {
$template = $this->Application->GetVar('t');
}
// different path in structure AND design template differes from requested template
$structure_path_match = strtolower( $page->GetDBField('NamedParentPath') ) == strtolower('Content/' . $template);
$design_match = $page->GetDBField('CachedTemplate') == $template;
if (!$structure_path_match && !$design_match) {
// Same sql like in "c:getPassedID". Load, when current page object doesn't match requested page object
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$page_id = $themes_helper->getPageByTemplate($template);
$page->Load($page_id);
}
return $page;
}
/**
* Returns requested content block content of current or specified page
*
* @param Array $params
* @return string
*/
function ContentBlock($params)
{
$num = getArrayValue($params, 'num');
if (!$num) {
return 'NO CONTENT NUM SPECIFIED';
}
$page =& $this->_getPage($params);
/* @var $page kDBItem */
if (!$page->isLoaded()) {
// page is not created yet => all blocks are empty
return '';
}
$page_id = $page->GetID();
$content =& $this->Application->recallObject('content.-block', null, Array ('skip_autoload' => true));
/* @var $content kDBItem */
$data = Array ('PageId' => $page_id, 'ContentNum' => $num);
$content->Load($data);
if (!$content->isLoaded()) {
// bug: missing content blocks are created even if user have no SMS-management rights
$content->SetFieldsFromHash($data);
$content->Create();
}
$edit_code_before = $edit_code_after = '';
if (EDITING_MODE == EDITING_MODE_CONTENT) {
$bg_color = isset($params['bgcolor']) ? $params['bgcolor'] : '#ffffff';
$url_params = Array (
'pass' => 'm,c,content',
'm_opener' => 'd',
'c_id' => $page->GetID(),
'content_id' => $content->GetID(),
'front' => 1,
'admin' => 1,
'__URLENCODE__' => 1,
'__NO_REWRITE__'=> 1,
'escape' => 1,
'index_file' => 'index.php',
// 'bgcolor' => $bg_color,
// '__FORCE_SID__' => 1
);
// link from Front-End to admin, don't remove "index.php"
$edit_url = $this->Application->HREF('categories/edit_content', ADMIN_DIRECTORY, $url_params, 'index.php');
$edit_code_before = '
<div class="cms-edit-btn-container">
<div class="cms-edit-btn" onclick="$form_name=\'kf_cont_'.$content->GetID().'\'; std_edit_item(\'content\', \'categories/edit_content\');">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/content_mode.png" width="15" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_EditContent', false, true) . ' '.(defined('DEBUG_MODE') && DEBUG_MODE ? " - #{$num}" : '').'</div>
</div>
<div class="cms-btn-content">';
$edit_form = '<form method="POST" style="display: inline; margin: 0px" name="kf_cont_'.$content->GetID().'" id="kf_cont_'.$content->GetID().'" action="'.$edit_url.'">';
$edit_form .= '<input type="hidden" name="c_id" value="'.$page->GetID().'"/>';
$edit_form .= '<input type="hidden" name="content_id" value="'.$content->GetID().'"/>';
$edit_form .= '<input type="hidden" name="front" value="1"/>';
$edit_form .= '<input type="hidden" name="bgcolor" value="'.$bg_color.'"/>';
$edit_form .= '<input type="hidden" name="m_lang" value="'.$this->Application->GetVar('m_lang').'"/>';
$edit_form .= '</form>';
$edit_code_after = '</div></div>';
if (array_key_exists('forms_later', $params) && $params['forms_later']) {
$all_forms = $this->Application->GetVar('all_forms');
$this->Application->SetVar('all_forms', $all_forms . $edit_form);
}
else {
$edit_code_after .= $edit_form;
}
}
if ($this->Application->GetVar('_editor_preview_') == 1) {
$data = $this->Application->RecallVar('_editor_preview_content_');
} else {
$data = $content->GetField('Content');
}
$data = $edit_code_before . $this->_transformContentBlockData($data, $params) . $edit_code_after;
if ($data != '') {
$this->Application->Parser->DataExists = true;
}
return $data;
}
/**
* Apply all kinds of content block data transformations without rewriting ContentBlock tag
*
* @param string $data
* @return string
*/
function _transformContentBlockData(&$data, $params)
{
return $data;
}
/**
* Returns current page name or page based on page/page_id parameters
*
* @param Array $params
* @return string
* @todo Used?
*/
function PageName($params)
{
$page =& $this->_getPage($params);
return $page->GetDBField('Name');
}
/**
* Returns current/given page information
*
* @param Array $params
* @return string
*/
function PageInfo($params)
{
$page =& $this->_getPage($params);
if ($params['type'] == 'index_tools') {
$page_info = $page->GetDBField('IndexTools');
if ($page_info) {
return $page_info;
}
else {
if (PROTOCOL == 'https://') {
return $this->Application->ConfigValue('cms_DefaultIndextoolsCode_SSL');
}
else {
return $this->Application->ConfigValue('cms_DefaultIndextoolsCode');
}
}
}
switch ($params['type']) {
case 'title':
$db_field = 'Title';
break;
case 'htmlhead_title':
$db_field = 'Name';
break;
case 'meta_title':
$db_field = 'MetaTitle';
break;
case 'menu_title':
$db_field = 'MenuTitle';
break;
case 'meta_keywords':
$db_field = 'MetaKeywords';
$cat_field = 'Keywords';
break;
case 'meta_description':
$db_field = 'MetaDescription';
$cat_field = 'Description';
break;
default:
return '';
}
$default = isset($params['default']) ? $params['default'] : '';
$val = $page->GetField($db_field);
if (!$default) {
if ($this->Application->isModuleEnabled('In-Portal')) {
if (!$val && ($params['type'] == 'meta_keywords' || $params['type'] == 'meta_description')) {
// take category meta if it's not set for the page
return $this->Application->ProcessParsedTag('c', 'Meta', Array('name' => $cat_field));
}
}
}
if (isset($params['force_default']) && $params['force_default']) {
return $default;
}
if (preg_match('/^_Auto:/', $val)) {
$val = $default;
/*if ($db_field == 'Title') {
$page->SetDBField($db_field, $default);
$page->Update();
}*/
}
elseif ($page->GetID() == false) {
return $default;
}
return $val;
}
/**
* Includes admin css and js, that are required for cms usage on Front-Edn
*
*
* @param Array $params
* @return string
*/
function EditingScripts($params)
{
if ($this->Application->GetVar('admin_scripts_included') || !EDITING_MODE) {
return ;
}
$this->Application->SetVar('admin_scripts_included', 1);
-
$js_url = $this->Application->BaseURL() . 'core/admin_templates/js';
- $ret = '<link rel="stylesheet" href="' . $js_url . '/jquery/thickbox/thickbox.css" type="text/css" media="screen"/>' . "\n";
- $ret .= '<link rel="stylesheet" href="' . $js_url . '/../incs/cms.css" type="text/css" media="screen"/>' . "\n";
+ $minify_helper =& $this->Application->recallObject('MinifyHelper');
+ /* @var $minify_helper MinifyHelper */
+
+ $to_compress = Array (
+ $js_url . '/jquery/thickbox/thickbox.css',
+ $js_url . '/../incs/cms.css',
+ );
+
+ $css_compressed = $minify_helper->CompressScriptTag( Array ('files' => implode('|', $to_compress)) );
+
+ $ret = '<link rel="stylesheet" href="' . $css_compressed . '" type="text/css" media="screen"/>' . "\n";
if (EDITING_MODE == EDITING_MODE_DESIGN) {
$ret .= ' <style type="text/css" media="all">
div.movable-element .movable-header { cursor: move; }
</style>';
}
+
$ret .= '<script type="text/javascript" src="' . $js_url . '/jquery/jquery.pack.js"></script>' . "\n";
$ret .= '<script type="text/javascript" src="' . $js_url . '/jquery/jquery-ui.custom.min.js"></script>' . "\n";
- $ret .= '<script type="text/javascript" src="' . $js_url . '/is.js"></script>' . "\n";
- $ret .= '<script type="text/javascript" src="' . $js_url . '/application.js"></script>' . "\n";
- $ret .= '<script type="text/javascript" src="' . $js_url . '/script.js"></script>' . "\n";
- $ret .= '<script type="text/javascript" src="' . $js_url . '/jquery/thickbox/thickbox.js"></script>' . "\n";
- $ret .= '<script type="text/javascript" src="' . $js_url . '/template_manager.js"></script>' . "\n";
+
+ $to_compress = Array (
+ $js_url . '/is.js',
+ $js_url . '/application.js',
+ $js_url . '/script.js',
+ $js_url . '/jquery/thickbox/thickbox.js',
+ $js_url . '/template_manager.js',
+ );
+
+ $js_compressed = $minify_helper->CompressScriptTag( Array ('files' => implode('|', $to_compress)) );
+
+ $ret .= '<script type="text/javascript" src="' . $js_compressed . '"></script>' . "\n";
$ret .= '<script language="javascript">' . "\n";
$ret .= "TB.pathToImage = '" . $js_url . "/jquery/thickbox/loadingAnimation.gif';" . "\n";
$template = $this->Application->GetVar('t');
$theme_id = $this->Application->GetVar('m_theme');
$url_params = Array ('block' => '#BLOCK#', 'theme-file_event' => '#EVENT#', 'theme_id' => $theme_id, 'source' => $template, 'pass' => 'all,theme-file', 'front' => 1, 'm_opener' => 'd', '__NO_REWRITE__' => 1, 'no_amp' => 1);
$edit_template_url = $this->Application->HREF('themes/template_edit', ADMIN_DIRECTORY, $url_params, 'index.php');
$url_params = Array ('theme-file_event' => 'OnSaveLayout', 'source' => $template, 'pass' => 'all,theme-file', '__NO_REWRITE__' => 1, 'no_amp' => 1);
$save_layout_url = $this->Application->HREF('index', '', $url_params);
$this_url = $this->Application->HREF('', '', Array ('editing_mode' => '#EDITING_MODE#', '__NO_REWRITE__' => 1, 'no_amp' => 1));
$ret .= "var aTemplateManager = new TemplateManager('" . $edit_template_url . "', '" . $this_url . "', '" . $save_layout_url . "', " . (int)EDITING_MODE . ");\n";
$ret .= "var main_title = '" . addslashes( $this->Application->ConfigValue('Site_Name') ) . "';" . "\n";
$use_popups = (int)$this->Application->ConfigValue('UsePopups');
$ret .= "var \$use_popups = " . ($use_popups > 0 ? 'true' : 'false') . ";\n";
$ret .= "var \$modal_windows = " . ($use_popups == 2 ? 'true' : 'false') . ";\n";
if (EDITING_MODE != EDITING_MODE_BROWSE) {
$ret .= "var base_url = '" . $this->Application->BaseURL() . "';" . "\n";
$ret .= 'TB.closeHtml = \'<img src="' . $js_url . '/../img/close_window15.gif" width="15" height="15" style="border-width: 0px;" alt="close"/><br/>\';' . "\n";
$url_params = Array('m_theme' => '', 'pass' => 'm', 'm_opener' => 'r', '__NO_REWRITE__' => 1, 'no_amp' => 1);
$browse_url = $this->Application->HREF('catalog/catalog', ADMIN_DIRECTORY, $url_params, 'index.php');
$browse_url = preg_replace('/&(admin|editing_mode)=[\d]/', '', $browse_url);
$ret .= '
var topmost = window.top;
topmost.document.title = document.title + \' - ' . addslashes($this->Application->Phrase('la_AdministrativeConsole', false)) . '\';
t = \''.$this->Application->GetVar('t').'\';
if (window.parent.frames["menu"] != undefined) {
if ( $.isFunction(window.parent.frames["menu"].SyncActive) ) {
window.parent.frames["menu"].SyncActive("' . $browse_url . '");
}
}
';
}
$ret .= '</script>' . "\n";
if (EDITING_MODE != EDITING_MODE_BROWSE) {
// add form, so admin scripts could work
$ret .= '<form id="kernel_form" name="kernel_form" enctype="multipart/form-data" method="post" action="' . $browse_url . '">
<input type="hidden" name="MAX_FILE_SIZE" id="MAX_FILE_SIZE" value="' . MAX_UPLOAD_SIZE . '" />
<input type="hidden" name="sid" id="sid" value="' . $this->Application->GetSID() . '" />
</form>';
}
return $ret;
}
/**
* Prints "Edit Page" button on cms page
*
* @param Array $params
* @return string
*/
function EditPage($params)
{
if (!EDITING_MODE) {
return '';
}
$display_mode = array_key_exists('mode', $params) ? $params['mode'] : false;
$edit_code = '';
$page =& $this->_getPage($params);
if (!$page->isLoaded() || (($display_mode != 'end') && (EDITING_MODE == EDITING_MODE_BROWSE))) {
// when "EditingScripts" tag is not used, make sure, that scripts are also included
return $this->EditingScripts($params);
}
// show "EditPage" button only for pages, that exists in structure
if ($display_mode != 'end') {
$edit_btn = '';
if (EDITING_MODE == EDITING_MODE_CONTENT) {
$url_params = Array(
'pass' => 'm,c',
'm_opener' => 'd',
'c_id' => $page->GetID(),
'c_mode' => 't',
'c_event' => 'OnEdit',
'front' => 1,
'__URLENCODE__' => 1,
'__NO_REWRITE__'=> 1,
'escape' => 1,
'index_file' => 'index.php',
);
$edit_url = $this->Application->HREF('categories/categories_edit', ADMIN_DIRECTORY, $url_params);
$edit_btn .= '
<div class="cms-section-properties-btn"' . ($display_mode === false ? ' style="margin: 0px;"' : '') . ' onmouseover="window.status=\''.$edit_url.'\'; return true" onclick="$form_name=\'kf_'.$page->GetID().'\'; std_edit_item(\'c\', \'categories/categories_edit\');">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/section_properties.png" width="15" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_SectionProperties', false, true) . '</div>
</div>' . "\n";
} elseif (EDITING_MODE == EDITING_MODE_DESIGN) {
$url_params = Array(
'pass' => 'm,theme',
'm_opener' => 'd',
'theme_id' => $this->Application->GetVar('m_theme'),
'theme_mode' => 't',
'theme_event' => 'OnEdit',
'theme-file_id' => $this->_getThemeFileId(),
'front' => 1,
'__URLENCODE__' => 1,
'__NO_REWRITE__'=> 1,
'escape' => 1,
'index_file' => 'index.php',
);
$edit_url = $this->Application->HREF('themes/file_edit', ADMIN_DIRECTORY, $url_params);
$edit_btn .= '
<div class="cms-layout-btn-container"' . ($display_mode === false ? ' style="margin: 0px;"' : '') . '>
<div class="cms-save-layout-btn" onclick="aTemplateManager.saveLayout(); return false;">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/save_button.gif" width="16" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_SaveChanges', false, true) . '</div>
</div>
<div class="cms-cancel-layout-btn" onclick="aTemplateManager.cancelLayout(); return false;">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/cancel_button.gif" width="16" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_Cancel', false, true) . '</div>
</div>
</div>
<div class="cms-section-properties-btn"' . ($display_mode === false ? ' style="margin: 0px;"' : '') . ' onmouseover="window.status=\''.$edit_url.'\'; return true" onclick="$form_name=\'kf_'.$page->GetID().'\'; std_edit_item(\'theme\', \'themes/file_edit\');">
<div class="cms-btn-image">
<img src="' . $this->Application->BaseURL() . 'core/admin_templates/img/top_frame/icons/section_properties.png" width="15" height="16" alt=""/>
</div>
<div class="cms-btn-text">' . $this->Application->Phrase('la_btn_SectionTemplate', false, true) . '</div>
</div>' . "\n";
}
if ($display_mode == 'start') {
// button with border around the page
$edit_code .= '<div class="cms-section-properties-btn-container">' . $edit_btn . '<div class="cms-btn-content">';
}
else {
// button without border around the page
$edit_code .= $edit_btn;
}
}
if ($display_mode == 'end') {
// draw border around the page
$edit_code .= '</div></div>';
}
if ($display_mode != 'end') {
$edit_code .= '<form method="POST" style="display: inline; margin: 0px" name="kf_'.$page->GetID().'" id="kf_'.$page->GetID().'" action="'.$edit_url.'"></form>';
// when "EditingScripts" tag is not used, make sure, that scripts are also included
$edit_code .= $this->EditingScripts($params);
}
return $edit_code;
}
function _getThemeFileId()
{
$template = $this->Application->GetVar('t');
if (!$this->Application->TemplatesCache->TemplateExists($template) && !$this->Application->isAdmin) {
$cms_handler =& $this->Application->recallObject($this->Prefix . '_EventHandler');
/* @var $cms_handler CategoriesEventHandler */
$template = ltrim($cms_handler->GetDesignTemplate(), '/');
}
$file_path = dirname($template) == '.' ? '' : '/' . dirname($template);
$file_name = basename($template);
$sql = 'SELECT FileId
FROM ' . TABLE_PREFIX . 'ThemeFiles
WHERE (ThemeId = ' . (int)$this->Application->GetVar('m_theme') . ') AND (FilePath = ' . $this->Conn->qstr($file_path) . ') AND (FileName = ' . $this->Conn->qstr($file_name . '.tpl') . ')';
return $this->Conn->GetOne($sql);
}
/**
* Builds site menu
*
* @param Array $params
* @return string
*/
function CachedMenu($params)
{
$menu_helper =& $this->Application->recallObject('MenuHelper');
/* @var $menu_helper MenuHelper */
return $menu_helper->menuTag($this->getPrefixSpecial(), $params);
}
/**
* Trick to allow some kind of output formatting when using CachedMenu tag
*
* @param Array $params
* @return bool
*/
function SplitColumn($params)
{
return $this->Application->GetVar($params['i']) > ceil($params['total'] / $params['columns']);
}
/**
* Returns direct children count of given category
*
* @param Array $params
* @return int
*/
function HasSubCats($params)
{
$sql = 'SELECT COUNT(*)
FROM ' . TABLE_PREFIX . 'Category
WHERE ParentId = ' . $params['cat_id'];
return $this->Conn->GetOne($sql);
}
/**
* Prints sub-pages of given/current page.
*
* @param Array $params
* @return string
* @todo This could be reached by using "parent_cat_id" parameter. Only difference here is new block parameter "path". Need to rewrite.
*/
function PrintSubPages($params)
{
$list =& $this->Application->recallObject($this->getPrefixSpecial(), $this->Prefix.'_List', $params);
/* @var $list kDBList */
$category_id = array_key_exists('category_id', $params) ? $params['category_id'] : $this->Application->GetVar('m_cat_id');
$list->addFilter('current_pages', TABLE_PREFIX . 'CategoryItems.CategoryId = ' . $category_id);
$list->Query();
$list->GoFirst();
$o = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
while (!$list->EOL()) {
$block_params['path'] = $list->GetDBField('Path');
$o .= $this->Application->ParseBlock($block_params, 1);
$list->GoNext();
}
return $o;
}
/**
* Builds link for browsing current page on Front-End
*
* @param Array $params
* @return string
*/
function PageBrowseLink($params)
{
$object =& $this->getObject($params);
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$site_config_helper =& $this->Application->recallObject('SiteConfigHelper');
/* @var $site_config_helper SiteConfigHelper */
$settings = $site_config_helper->getSettings();
$url_params = Array (
'm_cat_id' => $object->GetID(),
'm_theme' => $themes_helper->getCurrentThemeId(),
'editing_mode' => $settings['default_editing_mode'],
'pass' => 'm',
'admin' => 1,
'index_file' => 'index.php'
);
if ($this->Application->ConfigValue('UseModRewrite')) {
$url_params['__MOD_REWRITE__'] = 1;
}
return $this->Application->HREF($object->GetDBField('NamedParentPath'), '_FRONT_END_', $url_params);
}
/**
* Builds link to cms page (used?)
*
* @param Array $params
* @return string
*/
function ContentPageLink($params)
{
$object =& $this->getObject($params);
$params['t'] = $object->GetDBField('NamedParentPath');
$params['m_cat_id'] = 0;
return $this->Application->ProcessParsedTag('m', 'Link', $params);
}
/**
* Prepares cms page description for search result page
*
* @param Array $params
* @return string
*/
function SearchDescription($params)
{
$object =& $this->getObject($params);
$desc = $object->GetField('MetaDescription');
if (!$desc) {
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'PageContent
WHERE PageId = ' . $object->GetID() . ' AND ContentNum = 1';
$content = $this->Conn->GetRow($sql);
if ($content['l'.$this->Application->GetVar('m_lang').'_Content']) {
$desc = $content['l'.$this->Application->GetVar('m_lang').'_Content'];
}
else {
$desc = $content['l'.$this->Application->GetDefaultLanguageId().'_Content'];
}
}
return mb_substr($desc, 0, 300).(mb_strlen($desc) > 300 ? '...' : '');
}
/**
* Simplified version of "c:CategoryLink" for "c:PrintList"
*
* @param Array $params
* @return string
* @todo Used? Needs refactoring.
*/
function EnterCatLink($params)
{
$object =& $this->getObject($params);
$url_params = Array ('pass' => 'm', 'm_cat_id' => $object->GetID());
return $this->Application->HREF($params['template'], '', $url_params);
}
/**
* Simplified version of "c:CategoryPath", that do not use blocks for rendering
*
* @param Array $params
* @return string
* @todo Used? Maybe needs to be removed.
*/
function PagePath($params)
{
$object =& $this->getObject($params);
$path = $object->GetField('CachedNavbar');
if ($path) {
$items = explode('&|&', $path);
array_shift($items);
return implode(' -&gt; ', $items);
}
return '';
}
/**
* Returns configuration variable value
*
* @param Array $params
* @return string
* @todo Needs to be replaced with "m:GetConfig" tag; Not used now (were used on structure_edit.tpl).
*/
function AllowManualFilenames($params)
{
return $this->Application->ConfigValue('ProjCMSAllowManualFilenames');
}
/**
* Draws path to current page (each page can be link to it)
*
* @param Array $params
* @return string
*/
function CurrentPath($params)
{
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $block_params['render_as'];
$object =& $this->Application->recallObject($this->Prefix);
/* @var $object kDBItem */
$category_ids = explode('|', substr($object->GetDBField('ParentPath'), 1, -1));
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
$language = (int)$this->Application->GetVar('m_lang');
if (!$language) {
$language = 1;
}
$sql = 'SELECT l'.$language.'_Name AS Name, NamedParentPath
FROM '.$table_name.'
WHERE '.$id_field.' IN ('.implode(',', $category_ids).')';
$categories_data = $this->Conn->Query($sql);
$ret = '';
foreach ($categories_data as $index => $category_data) {
if ($category_data['Name'] == 'Content') {
continue;
}
$block_params['title'] = $category_data['Name'];
$block_params['template'] = preg_replace('/^Content\//i', '', $category_data['NamedParentPath']);
$block_params['is_first'] = $index == 1; // because Content is 1st element
$block_params['is_last'] = $index == count($categories_data) - 1;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Synonim to PrintList2 for "onlinestore" theme
*
* @param Array $params
* @return string
*/
function ListPages($params)
{
return $this->PrintList2($params);
}
/**
* Returns information about parser element locations in template
*
* @param Array $params
* @return mixed
*/
function BlockInfo($params)
{
if (!EDITING_MODE) {
return '';
}
$template_helper =& $this->Application->recallObject('TemplateHelper');
/* @var $template_helper TemplateHelper */
return $template_helper->blockInfo( $params['name'] );
}
/**
* Hide all editing tabs except permission tab, when editing "Home" (ID = 0) category
*
* @param Array $params
*/
function ModifyUnitConfig($params)
{
$root_category = $this->Application->RecallVar('IsRootCategory_' . $this->Application->GetVar('m_wid'));
if (!$root_category) {
return ;
}
$edit_tab_presets = $this->Application->getUnitOption($this->Prefix, 'EditTabPresets');
$edit_tab_presets['Default'] = Array (
'permissions' => $edit_tab_presets['Default']['permissions'],
);
$this->Application->setUnitOption($this->Prefix, 'EditTabPresets', $edit_tab_presets);
}
/**
* Prints catalog export templates
*
* @param Array $params
* @return string
*/
function PrintCatalogExportTemplates($params)
{
$prefixes = explode(',', $params['prefixes']);
$ret = Array ();
foreach ($prefixes as $prefix) {
if ($this->Application->prefixRegistred($prefix)) {
$module_path = $this->Application->getUnitOption($prefix, 'ModuleFolder') . '/';
$module_name = $this->Application->findModule('Path', $module_path, 'Name');
$ret[$prefix] = mb_strtolower($module_name) . '/export';
}
}
$json_helper =& $this->Application->recallObject('JSONHelper');
/* @var $json_helper JSONHelper */
return $json_helper->encode($ret);
}
/**
* Checks, that "view in browse mode" functionality available
*
* @param Array $params
* @return bool
*/
function BrowseModeAvailable($params)
{
$valid_special = $params['Special'] != 'user';
$not_selector = $this->Application->GetVar('type') != 'item_selector';
return $valid_special && $not_selector;
}
/**
* Returns a link for editing product
*
* @param Array $params
* @return string
*/
function ItemEditLink($params)
{
$object =& $this->getObject();
/* @var $object kDBList */
$edit_template = $this->Application->getUnitOption($this->Prefix, 'AdminTemplatePath') . '/' . $this->Application->getUnitOption($this->Prefix, 'AdminTemplatePrefix') . 'edit';
$url_params = Array (
'm_opener' => 'd',
$this->Prefix.'_mode' => 't',
$this->Prefix.'_event' => 'OnEdit',
$this->Prefix.'_id' => $object->GetID(),
'm_cat_id' => $object->GetDBField('ParentId'),
'pass' => 'all,'.$this->Prefix,
'no_pass_through' => 1,
);
return $this->Application->HREF($edit_template,'', $url_params);
}
function RelevanceIndicator($params)
{
$object =& $this->getObject($params);
$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SELECT Relevance
FROM '.$search_results_table.'
WHERE ResourceId = '.$object->GetDBField('ResourceId');
$percents_off = (int)(100 - (100 * $this->Conn->GetOne($sql)));
$percents_off = ($percents_off < 0) ? 0 : $percents_off;
if ($percents_off) {
$params['percent_off'] = $percents_off;
$params['percent_on'] = 100 - $percents_off;
$params['name'] = $this->SelectParam($params, 'relevance_normal_render_as,block_relevance_normal');
}
else {
$params['name'] = $this->SelectParam($params, 'relevance_full_render_as,block_relevance_full');
}
return $this->Application->ParseBlock($params);
}
/**
* Returns list of categories, that have category add/edit permission
*
* @param Array $params
* @return string
*/
function AllowedCategoriesJSON($params)
{
if ($this->Application->RecallVar('user_id') == -1) {
$categories = true;
}
else {
$object =& $this->getObject($params);
/* @var $object kDBItem */
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$perm_prefix = $this->Application->getUnitOption($this->Prefix, 'PermItemPrefix');
$categories = $perm_helper->getPermissionCategories($perm_prefix . '.' . ($object->IsNewItem() ? 'ADD' : 'MODIFY'));
}
$json_helper =& $this->Application->recallObject('JSONHelper');
/* @var $json_helper JSONHelper */
return $json_helper->encode($categories);
}
}
\ No newline at end of file
Index: branches/5.1.x/core/units/helpers/minifiers/minifiers_config.php
===================================================================
--- branches/5.1.x/core/units/helpers/minifiers/minifiers_config.php (nonexistent)
+++ branches/5.1.x/core/units/helpers/minifiers/minifiers_config.php (revision 13487)
@@ -0,0 +1,26 @@
+<?php
+/**
+* @version $Id$
+* @package In-Portal
+* @copyright Copyright (C) 1997 - 2010 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!');
+
+ $config = Array (
+ 'Prefix' => 'minify-helpers',
+ 'EventHandlerClass' => Array ('class' => 'kEventHandler', 'file' => '', 'build_event' => 'OnBuild'),
+
+ 'RegisterClasses' => Array (
+ Array ('pseudo' => 'CssMinifyHelper', 'class' => 'CssMinifyHelper', 'file' => 'css_minify_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'),
+ Array ('pseudo' => 'JsMinifyHelper', 'class' => 'JsMinifyHelper', 'file' => 'js_minify_helper.php', 'build_event' => '', 'require_classes' => Array ('kHelper')),
+ Array ('pseudo' => 'MinifyHelper', 'class' => 'MinifyHelper', 'file' => 'minify_helper.php', 'build_event' => '', 'require_classes' => Array ('kHelper')),
+ ),
+ );
\ No newline at end of file
Property changes on: branches/5.1.x/core/units/helpers/minifiers/minifiers_config.php
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: branches/5.1.x/core/units/helpers/minifiers/minify_helper.php
===================================================================
--- branches/5.1.x/core/units/helpers/minifiers/minify_helper.php (nonexistent)
+++ branches/5.1.x/core/units/helpers/minifiers/minify_helper.php (revision 13487)
@@ -0,0 +1,245 @@
+<?php
+/**
+* @version $Id$
+* @package In-Portal
+* @copyright Copyright (C) 1997 - 2010 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 MinifyHelper extends kHelper {
+
+ /**
+ * Debug mode mark
+ *
+ * @var bool
+ */
+ var $debugMode = false;
+
+ /**
+ * Path to compress information file
+ *
+ * @var string
+ */
+ var $infoFile = '';
+
+ /**
+ * Compress information
+ *
+ * @var Array
+ */
+ var $compressInfo = Array ();
+
+ function MinifyHelper()
+ {
+ parent::kHelper();
+
+ $this->debugMode = $this->Application->isDebugMode();
+ $this->infoFile = WRITEABLE . '/cache/compress_info.txt';
+
+ if ( file_exists($this->infoFile) ) {
+ $this->compressInfo = unserialize( file_get_contents($this->infoFile) );
+ }
+ }
+
+ /**
+ * When used as non-block tag, then compress given files and return url to result
+ *
+ * @param Array $files
+ * @return string
+ */
+ function CompressScriptTag($params)
+ {
+ // put to queue
+ if (array_key_exists('to', $params)) {
+ $files = $this->Application->GetVar($params['to'], '');
+ $this->Application->SetVar($params['to'], $files . '|' . $params['files']);
+
+ return '';
+ }
+
+ if (array_key_exists('from', $params)) {
+ // get from queue
+ $files = $this->Application->GetVar($params['from']);
+ }
+ else {
+ // get from tag
+ $files = $params['files'];
+ }
+
+ $files = $this->_getTemplatePaths( array_map('trim', explode('|', $files)) );
+ $extension = pathinfo($files[0], PATHINFO_EXTENSION);
+
+ $hash = $this->_getHash($files);
+ $file_mask = 'cache/' . ($this->debugMode ? 'd' : 'c') . '_' . $hash . '_%s.' . $extension;
+
+ $was_compressed = array_key_exists($hash, $this->compressInfo);
+
+ if ($was_compressed) {
+ $current_file = WRITEABLE . '/' . sprintf($file_mask, $this->compressInfo[$hash]);
+
+ if (!file_exists($current_file)) {
+ // when info exists, but file doesn't -> re-compress
+ $was_compressed = false;
+ }
+
+ if ($this->debugMode) {
+ // check if any of listed files was changed since compressed file was created (only, when in debug mode)
+ foreach ($files as $file) {
+ if (filemtime($file) > $this->compressInfo[$hash]) {
+ $was_compressed = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!$was_compressed) {
+ $string = '';
+ $path_length = strlen(FULL_PATH) + 1;
+
+ foreach ($files as $file) {
+ // add filename before for easier debugging
+ if ($this->debugMode) {
+ $string .= '/* === File: ' . substr($file, $path_length) . ' === */' . "\n";
+ $string .= '/* ' . str_repeat('=', strlen(substr($file, $path_length)) + 14) . ' */' . "\n\n";
+ }
+
+ // add file content
+ $string .= file_get_contents($file) . "\n\n";
+ }
+
+ // remove previous version of compressed file
+ if (isset($current_file)) {
+ if (file_exists($current_file)) {
+ unlink($current_file);
+ }
+ }
+
+ // replace templates base
+ $templates_base = $this->Application->ProcessParsedTag('m', 'TemplatesBase', Array ());
+ $string = str_replace('@templates_base@', rtrim($templates_base, '/'), $string);
+
+ // compress collected data
+ $this->compressInfo[$hash] = adodb_mktime();
+
+ if (!$this->debugMode) {
+ // don't compress merged js/css file in debug mode to allow js/css debugging
+ $this->compressString($string, $extension);
+ }
+
+ // save compressed file
+ $fp = fopen(WRITEABLE . '/' . sprintf($file_mask, $this->compressInfo[$hash]), 'w');
+ fwrite($fp, $string);
+ fclose($fp);
+
+ $this->_saveInfo();
+ }
+
+ // got compressed file -> use it
+ return $this->Application->BaseURL(WRITEBALE_BASE) . sprintf($file_mask, $this->compressInfo[$hash]);
+ }
+
+ /**
+ * Returns hash string based on given files
+ *
+ * @param Array $files
+ * @return int
+ */
+ function _getHash($files)
+ {
+ $hash = $files;
+
+ if ($this->Application->isAdmin) {
+ array_unshift($hash, 'A:1');
+ }
+ else {
+ array_unshift($hash, 'A:0;T:' . $this->Application->GetVar('m_theme'));
+ }
+
+ return crc32( implode('|', $hash) );
+ }
+
+ /**
+ * Saves file with compress information
+ *
+ */
+ function _saveInfo()
+ {
+ $fp = fopen($this->infoFile, 'w');
+ fwrite($fp, serialize($this->compressInfo));
+ fclose($fp);
+ }
+
+ /**
+ * Deletes compression info file
+ *
+ * @todo also delete all listed there files
+ */
+ function delete()
+ {
+ if (file_exists($this->infoFile)) {
+ unlink($this->infoFile);
+ }
+ }
+
+ /**
+ * Compress $string based on $extension
+ *
+ * @param string $string
+ * @param string $extension
+ */
+ function compressString(&$string, $extension)
+ {
+ if ($extension == 'js') {
+ $minifier =& $this->Application->makeClass('JsMinifyHelper');
+ /* @var $minifier JsMinifyHelper */
+
+ $string = $minifier->minify($string);
+ }
+ elseif ($extension == 'css') {
+ $minifier =& $this->Application->makeClass('CssMinifyHelper');
+ /* @var $minifier CssMinifyHelper */
+
+ $string = $minifier->minify($string);
+ }
+ }
+
+ /**
+ * Get full paths on disk for each of given templates
+ *
+ * @param Array $templates
+ * @return Array
+ */
+ function _getTemplatePaths($templates)
+ {
+ $ret = Array ();
+ $reg_exp = '/^' . preg_quote($this->Application->BaseURL(), '/') . '(.*)/';
+
+ foreach ($templates as $template) {
+ if (!$template) {
+ continue;
+ }
+
+ if (preg_match($reg_exp, $template, $regs)) {
+ // full url (from current domain) to a file
+ $path = FULL_PATH . '/' . $regs[1];
+ }
+ else {
+ list ($path, $module_filename) = $this->Application->TemplatesCache->GetTemplatePaths($template);
+ $path .= DIRECTORY_SEPARATOR . $module_filename;
+ }
+
+ $ret[] = $path;
+ }
+
+ return $ret;
+ }
+ }
\ No newline at end of file
Property changes on: branches/5.1.x/core/units/helpers/minifiers/minify_helper.php
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: branches/5.1.x/core/units/helpers/minifiers/css_minify_helper.php
===================================================================
--- branches/5.1.x/core/units/helpers/minifiers/css_minify_helper.php (nonexistent)
+++ branches/5.1.x/core/units/helpers/minifiers/css_minify_helper.php (revision 13487)
@@ -0,0 +1,216 @@
+<?php
+
+defined('FULL_PATH') or die('restricted access!');
+
+/**
+ * Compress CSS
+ *
+ * This is a heavy regex-based removal of whitespace, unnecessary
+ * comments and tokens, and some CSS value minimization, where practical.
+ * Many steps have been taken to avoid breaking comment-based hacks,
+ * including the ie5/mac filter (and its inversion), but expect tricky
+ * hacks involving comment tokens in 'content' value strings to break
+ * minimization badly.
+ *
+ * @package Minify
+ * @author Stephen Clay <steve@mrclay.org>
+ * @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
+ */
+class CssMinifyHelper extends kHelper {
+
+ /**
+ * @var bool Are we "in" a hack?
+ *
+ * I.e. are some browsers targetted until the next comment?
+ */
+ var $_inHack = false;
+
+ /**
+ * Minify a CSS string
+ *
+ * @param string $css
+ *
+ * @return string
+ */
+ function minify($css)
+ {
+ $css = str_replace("\r\n", "\n", $css);
+
+ // preserve empty comment after '>'
+ // http://www.webdevout.net/css-hacks#in_css-selectors
+ $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css);
+
+ // preserve empty comment between property and value
+ // http://css-discuss.incutio.com/?page=BoxModelHack
+ $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css);
+ $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css);
+
+ // apply callback to all valid comments (and strip out surrounding ws
+ $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@'
+ ,array($this, '_commentCB'), $css);
+
+ // remove ws around { } and last semicolon in declaration block
+ $css = preg_replace('/\\s*{\\s*/', '{', $css);
+ $css = preg_replace('/;?\\s*}\\s*/', '}', $css);
+
+ // remove ws surrounding semicolons
+ $css = preg_replace('/\\s*;\\s*/', ';', $css);
+
+ // remove ws around urls
+ $css = preg_replace('/
+ url\\( # url(
+ \\s*
+ ([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis)
+ \\s*
+ \\) # )
+ /x', 'url($1)', $css);
+
+ // remove ws between rules and colons
+ $css = preg_replace('/
+ \\s*
+ ([{;]) # 1 = beginning of block or rule separator
+ \\s*
+ ([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter)
+ \\s*
+ :
+ \\s*
+ (\\b|[#\'"]) # 3 = first character of a value
+ /x', '$1$2:$3', $css);
+
+ // remove ws in selectors
+ $css = preg_replace_callback('/
+ (?: # non-capture
+ \\s*
+ [^~>+,\\s]+ # selector part
+ \\s*
+ [,>+~] # combinators
+ )+
+ \\s*
+ [^~>+,\\s]+ # selector part
+ { # open declaration block
+ /x'
+ ,array($this, '_selectorsCB'), $css);
+
+ // minimize hex colors
+ $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i'
+ , '$1#$2$3$4$5', $css);
+
+ // remove spaces between font families
+ $css = preg_replace_callback('/font-family:([^;}]+)([;}])/'
+ ,array($this, '_fontFamilyCB'), $css);
+
+ $css = preg_replace('/@import\\s+url/', '@import url', $css);
+
+ // replace any ws involving newlines with a single newline
+ $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css);
+
+ // separate common descendent selectors w/ newlines (to limit line lengths)
+ $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css);
+
+ // Use newline after 1st numeric value (to limit line lengths).
+ $css = preg_replace('/
+ ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value
+ \\s+
+ /x'
+ ,"$1\n", $css);
+
+ // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
+ $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);
+
+ return trim($css);
+ }
+
+ /**
+ * Replace what looks like a set of selectors
+ *
+ * @param array $m regex matches
+ *
+ * @return string
+ */
+ function _selectorsCB($m)
+ {
+ // remove ws around the combinators
+ return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]);
+ }
+
+ /**
+ * Process a comment and return a replacement
+ *
+ * @param array $m regex matches
+ *
+ * @return string
+ */
+ function _commentCB($m)
+ {
+ $hasSurroundingWs = (trim($m[0]) !== $m[1]);
+ $m = $m[1];
+ // $m is the comment content w/o the surrounding tokens,
+ // but the return value will replace the entire comment.
+ if ($m === 'keep') {
+ return '/**/';
+ }
+ if ($m === '" "') {
+ // component of http://tantek.com/CSS/Examples/midpass.html
+ return '/*" "*/';
+ }
+ if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) {
+ // component of http://tantek.com/CSS/Examples/midpass.html
+ return '/*";}}/* */';
+ }
+ if ($this->_inHack) {
+ // inversion: feeding only to one browser
+ if (preg_match('@
+ ^/ # comment started like /*/
+ \\s*
+ (\\S[\\s\\S]+?) # has at least some non-ws content
+ \\s*
+ /\\* # ends like /*/ or /**/
+ @x', $m, $n)) {
+ // end hack mode after this comment, but preserve the hack and comment content
+ $this->_inHack = false;
+ return "/*/{$n[1]}/**/";
+ }
+ }
+ if (substr($m, -1) === '\\') { // comment ends like \*/
+ // begin hack mode and preserve hack
+ $this->_inHack = true;
+ return '/*\\*/';
+ }
+ if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */
+ // begin hack mode and preserve hack
+ $this->_inHack = true;
+ return '/*/*/';
+ }
+ if ($this->_inHack) {
+ // a regular comment ends hack mode but should be preserved
+ $this->_inHack = false;
+ return '/**/';
+ }
+ // Issue 107: if there's any surrounding whitespace, it may be important, so
+ // replace the comment with a single space
+ return $hasSurroundingWs // remove all other comments
+ ? ' '
+ : '';
+ }
+
+ /**
+ * Process a font-family listing and return a replacement
+ *
+ * @param array $m regex matches
+ *
+ * @return string
+ */
+ function _fontFamilyCB($m)
+ {
+ $m[1] = preg_replace('/
+ \\s*
+ (
+ "[^"]+" # 1 = family in double qutoes
+ |\'[^\']+\' # or 1 = family in single quotes
+ |[\\w\\-]+ # or 1 = unquoted family
+ )
+ \\s*
+ /x', '$1', $m[1]);
+ return 'font-family:' . $m[1] . $m[2];
+ }
+}
Index: branches/5.1.x/core/units/helpers/minifiers/js_minify_helper.php
===================================================================
--- branches/5.1.x/core/units/helpers/minifiers/js_minify_helper.php (nonexistent)
+++ branches/5.1.x/core/units/helpers/minifiers/js_minify_helper.php (revision 13487)
@@ -0,0 +1,297 @@
+<?php
+/**
+ * PHP implementation of Douglas Crockford's JSMin.
+ *
+ * This is a direct port of jsmin.c to PHP with a few PHP performance tweaks and
+ * modifications to preserve some comments (see below). Also, rather than using
+ * stdin/stdout, JsMinifyHelper->minify() accepts a string as input and returns
+ * another string as output.
+ *
+ * Comments containing IE conditional compilation are preserved, as are multi-line
+ * comments that begin with "/*!" (for documentation purposes). In the latter case
+ * newlines are inserted around the comment to enhance readability.
+ *
+ * Permission is hereby granted to use this version of the library under the
+ * same terms as jsmin.c, which has the following license:
+ *
+ * --
+ * Copyright (c) 2002 Douglas Crockford (www.crockford.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * --
+ *
+ * @package JSMin
+ * @author Ryan Grove <ryan@wonko.com> (PHP port)
+ * @author Steve Clay <steve@mrclay.org> (modifications + cleanup)
+ * @author Andrea Giammarchi <http://www.3site.eu> (spaceBeforeRegExp)
+ * @author Alexander Obuhovich <aik.bold@gmail.com> (PHP4,In-Portal compatibility)
+ * @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
+ * @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @link http://code.google.com/p/jsmin-php/
+ */
+
+defined('FULL_PATH') or die('restricted access!');
+
+define('JSM_ORD_LF', 10);
+define('JSM_ORD_SPACE', 32);
+define('JSM_ACTION_KEEP_A', 1);
+define('JSM_ACTION_DELETE_A', 2);
+define('JSM_ACTION_DELETE_A_B', 3);
+
+class JsMinifyHelper extends kHelper {
+ /*const ORD_LF = 10;
+ const ORD_SPACE = 32;
+ const ACTION_KEEP_A = 1;
+ const ACTION_DELETE_A = 2;
+ const ACTION_DELETE_A_B = 3;*/
+
+ /* protected */ var $a = "\n";
+ /* protected */ var $b = '';
+ /* protected */ var $input = '';
+ /* protected */ var $inputIndex = 0;
+ /* protected */ var $inputLength = 0;
+ /* protected */ var $lookAhead = null;
+ /* protected */ var $output = '';
+
+ /**
+ * Perform minification, return result
+ */
+ /* public*/ function minify($input)
+ {
+ $this->input = str_replace("\r\n", "\n", $input);
+ $this->inputLength = strlen($this->input);
+
+ if ($this->output !== '') { // min already run
+ return $this->output;
+ }
+ $this->action(JSM_ACTION_DELETE_A_B/*self::ACTION_DELETE_A_B*/);
+
+ while ($this->a !== null) {
+ // determine next command
+ $command = JSM_ACTION_KEEP_A/*self::ACTION_KEEP_A*/; // default
+ if ($this->a === ' ') {
+ if (! $this->isAlphaNum($this->b)) {
+ $command = JSM_ACTION_DELETE_A/*self::ACTION_DELETE_A*/;
+ }
+ } elseif ($this->a === "\n") {
+ if ($this->b === ' ') {
+ $command = JSM_ACTION_DELETE_A_B/*self::ACTION_DELETE_A_B*/;
+ } elseif (false === strpos('{[(+-', $this->b)
+ && ! $this->isAlphaNum($this->b)) {
+ $command = JSM_ACTION_DELETE_A/*self::ACTION_DELETE_A*/;
+ }
+ } elseif (! $this->isAlphaNum($this->a)) {
+ if ($this->b === ' '
+ || ($this->b === "\n"
+ && (false === strpos('}])+-"\'', $this->a)))) {
+ $command = JSM_ACTION_DELETE_A_B/*self::ACTION_DELETE_A_B*/;
+ }
+ }
+ $this->action($command);
+ }
+ $this->output = trim($this->output);
+ return $this->output;
+ }
+
+ /**
+ * ACTION_KEEP_A = Output A. Copy B to A. Get the next B.
+ * ACTION_DELETE_A = Copy B to A. Get the next B.
+ * ACTION_DELETE_A_B = Get the next B.
+ */
+ /* protected */ function action($command)
+ {
+ switch ($command) {
+ case JSM_ACTION_KEEP_A/*self::ACTION_KEEP_A*/:
+ $this->output .= $this->a;
+ // fallthrough
+ case JSM_ACTION_DELETE_A/*self::ACTION_DELETE_A*/:
+ $this->a = $this->b;
+ if ($this->a === "'" || $this->a === '"') { // string literal
+ $str = $this->a; // in case needed for exception
+ while (true) {
+ $this->output .= $this->a;
+ $this->a = $this->get();
+ if ($this->a === $this->b) { // end quote
+ break;
+ }
+ if (ord($this->a) <= JSM_ORD_LF/*self::ORD_LF*/) {
+ trigger_error('Unterminated String: ' . var_export($str, true), E_USER_ERROR);
+ }
+ $str .= $this->a;
+ if ($this->a === '\\') {
+ $this->output .= $this->a;
+ $this->a = $this->get();
+ $str .= $this->a;
+ }
+ }
+ }
+ // fallthrough
+ case JSM_ACTION_DELETE_A_B/*self::ACTION_DELETE_A_B*/:
+ $this->b = $this->next();
+ if ($this->b === '/' && $this->isRegexpLiteral()) { // RegExp literal
+ $this->output .= $this->a . $this->b;
+ $pattern = '/'; // in case needed for exception
+ while (true) {
+ $this->a = $this->get();
+ $pattern .= $this->a;
+ if ($this->a === '/') { // end pattern
+ break; // while (true)
+ } elseif ($this->a === '\\') {
+ $this->output .= $this->a;
+ $this->a = $this->get();
+ $pattern .= $this->a;
+ } elseif (ord($this->a) <= JSM_ORD_LF/*self::ORD_LF*/) {
+ trigger_error('Unterminated RegExp: '. var_export($pattern, true), E_USER_ERROR);
+ }
+ $this->output .= $this->a;
+ }
+ $this->b = $this->next();
+ }
+ // end case ACTION_DELETE_A_B
+ }
+ }
+
+ /* protected */ function isRegexpLiteral()
+ {
+ if (false !== strpos("\n{;(,=:[!&|?", $this->a)) { // we aren't dividing
+ return true;
+ }
+ if (' ' === $this->a) {
+ $length = strlen($this->output);
+ if ($length < 2) { // weird edge case
+ return true;
+ }
+ // you can't divide a keyword
+ if (preg_match('/(?:case|else|in|return|typeof)$/', $this->output, $m)) {
+ if ($this->output === $m[0]) { // odd but could happen
+ return true;
+ }
+ // make sure it's a keyword, not end of an identifier
+ $charBeforeKeyword = substr($this->output, $length - strlen($m[0]) - 1, 1);
+ if (! $this->isAlphaNum($charBeforeKeyword)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get next char. Convert ctrl char to space.
+ */
+ /* protected */ function get()
+ {
+ $c = $this->lookAhead;
+ $this->lookAhead = null;
+ if ($c === null) {
+ if ($this->inputIndex < $this->inputLength) {
+ $c = $this->input[$this->inputIndex];
+ $this->inputIndex += 1;
+ } else {
+ return null;
+ }
+ }
+ if ($c === "\r" || $c === "\n") {
+ return "\n";
+ }
+ if (ord($c) < JSM_ORD_SPACE/*self::ORD_SPACE*/) { // control char
+ return ' ';
+ }
+ return $c;
+ }
+
+ /**
+ * Get next char. If is ctrl character, translate to a space or newline.
+ */
+ /* protected */ function peek()
+ {
+ $this->lookAhead = $this->get();
+ return $this->lookAhead;
+ }
+
+ /**
+ * Is $c a letter, digit, underscore, dollar sign, escape, or non-ASCII?
+ */
+ /* protected */ function isAlphaNum($c)
+ {
+ return (preg_match('/^[0-9a-zA-Z_\\$\\\\]$/', $c) || ord($c) > 126);
+ }
+
+ /* protected */ function singleLineComment()
+ {
+ $comment = '';
+ while (true) {
+ $get = $this->get();
+ $comment .= $get;
+ if (ord($get) <= JSM_ORD_LF/*self::ORD_LF*/) { // EOL reached
+ // if IE conditional comment
+ if (preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment)) {
+ return "/{$comment}";
+ }
+ return $get;
+ }
+ }
+ }
+
+ /* protected */ function multipleLineComment()
+ {
+ $this->get();
+ $comment = '';
+ while (true) {
+ $get = $this->get();
+ if ($get === '*') {
+ if ($this->peek() === '/') { // end of comment reached
+ $this->get();
+ // if comment preserved by YUI Compressor
+ if (0 === strpos($comment, '!')) {
+ return "\n/*" . substr($comment, 1) . "*/\n";
+ }
+ // if IE conditional comment
+ if (preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $comment)) {
+ return "/*{$comment}*/";
+ }
+ return ' ';
+ }
+ } elseif ($get === null) {
+ trigger_error('Unterminated Comment: ' . var_export('/*' . $comment, true), E_USER_ERROR);
+ }
+ $comment .= $get;
+ }
+ }
+
+ /**
+ * Get the next character, skipping over comments.
+ * Some comments may be preserved.
+ */
+ /* protected */ function next()
+ {
+ $get = $this->get();
+ if ($get !== '/') {
+ return $get;
+ }
+ switch ($this->peek()) {
+ case '/': return $this->singleLineComment();
+ case '*': return $this->multipleLineComment();
+ default: return $get;
+ }
+ }
+}
\ No newline at end of file
Index: branches/5.1.x/core/units/helpers/minifiers
===================================================================
--- branches/5.1.x/core/units/helpers/minifiers (nonexistent)
+++ branches/5.1.x/core/units/helpers/minifiers (revision 13487)
Property changes on: branches/5.1.x/core/units/helpers/minifiers
___________________________________________________________________
Added: bugtraq:logregex
## -0,0 +1,2 ##
+(?:[Bb]ugs?|[Ii]ssues?|[Rr]eports?|[Ff]ixe?s?|[Rr]esolves?)+\s+(?:#?(?:\d+)[,\.\s]*)+
+(\d+)
\ No newline at end of property
Added: bugtraq:url
## -0,0 +1 ##
+http://tracker.in-portal.org/view.php?id=%BUGID%
\ No newline at end of property
Index: branches/5.1.x/core/units/helpers/themes_helper.php
===================================================================
--- branches/5.1.x/core/units/helpers/themes_helper.php (revision 13486)
+++ branches/5.1.x/core/units/helpers/themes_helper.php (revision 13487)
@@ -1,485 +1,490 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 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 kThemesHelper extends kHelper {
/**
* Where all themes are located
*
* @var string
*/
var $themesFolder = '';
/**
* List of theme names, found on system
*
* @var Array
*/
var $_themeNames = Array ();
/**
* Temporary array when all theme files from db are stored
*
* @var Array
*/
var $themeFiles = Array ();
function kThemesHelper()
{
parent::kHelper();
$this->themesFolder = FULL_PATH.'/themes';
}
/**
* Updates file system changes to database for selected theme
*
* @param string $theme_name
*
* @return mixed returns ID of created/used theme or false, if none created
*/
function refreshTheme($theme_name)
{
if (!file_exists($this->themesFolder . '/' . $theme_name)) {
// requested theme was not found on hdd
return false;
}
$id_field = $this->Application->getUnitOption('theme', 'IDField');
$table_name = $this->Application->getUnitOption('theme', 'TableName');
$sql = 'SELECT *
FROM ' . $table_name . '
WHERE Name = ' . $this->Conn->qstr($theme_name);
$theme_info = $this->Conn->GetRow($sql);
if ($theme_info) {
$theme_id = $theme_info[$id_field];
$theme_enabled = $theme_info['Enabled'];
}
else {
$theme_id = $theme_enabled = false;
}
$this->themeFiles = Array ();
if ($theme_id) {
if (!$theme_enabled) {
// don't process existing theme files, that are disabled
return $theme_id;
}
// reset found mark for every themes file (if theme is not new)
$sql = 'UPDATE '.TABLE_PREFIX.'ThemeFiles
SET FileFound = 0
WHERE ThemeId = '.$theme_id;
$this->Conn->Query($sql);
// get all theme files from db
$sql = 'SELECT FileId, CONCAT(FilePath, "/", FileName) AS FullPath
FROM '.TABLE_PREFIX.'ThemeFiles
WHERE ThemeId = '.$theme_id;
$this->themeFiles = $this->Conn->GetCol($sql, 'FullPath');
}
else {
// theme was not found in db, but found on hdd -> create new
$theme_info = Array (
'Name' => $theme_name,
'Enabled' => 0,
'Description' => $theme_name,
'PrimaryTheme' => 0,
'CacheTimeout' => 3600, // not in use right now
'StylesheetId' => 0, // not in use right now
'LanguagePackInstalled' => 0
);
$this->Conn->doInsert($theme_info, $table_name);
$theme_id = $this->Conn->getInsertID();
if (!$theme_enabled) {
// don't process newly created theme files, because they are disabled
return $theme_id;
}
}
$this->_themeNames[$theme_id] = $theme_name;
$theme_path = $this->themesFolder.'/'.$theme_name;
$this->FindThemeFiles('', $theme_path, $theme_id); // search from base theme directory
// delete file records from db, that were not found on hdd
$sql = 'DELETE FROM '.TABLE_PREFIX.'ThemeFiles
WHERE ThemeId = '.$theme_id.' AND FileFound = 0';
$this->Conn->Query($sql);
// install language packs, associated with theme (if any found and wasn't aready installed)
if (!$theme_info['LanguagePackInstalled']) {
$language_import_helper =& $this->Application->recallObject('LanguageImportHelper');
/* @var $language_import_helper LanguageImportHelper */
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
if ($module_name == 'In-Portal') {
continue;
}
$lang_file = $theme_path . '/' . $module_info['TemplatePath'] . '_install/english.lang';
if (file_exists($lang_file)) {
$language_import_helper->performImport($lang_file, '|0|', '', LANG_SKIP_EXISTING);
}
}
$fields_hash = Array (
'LanguagePackInstalled' => 1,
);
$this->Conn->doUpdate($fields_hash, $table_name, $id_field . ' = ' . $theme_id);
}
// get template aliases from "/_install/theme.xml" files in theme
$template_aliases = Array ();
$xml_parser =& $this->Application->recallObject('kXMLHelper');
/* @var $xml_parser kXMLHelper */
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
if ($module_name == 'In-Portal') {
continue;
}
$xml_file = $theme_path . '/' . $module_info['TemplatePath'] . '_install/theme.xml';
if (file_exists($xml_file)) {
$xml_data = file_get_contents($xml_file);
$root_node =& $xml_parser->Parse($xml_data);
if (!is_object($root_node) || !is_a($root_node, 'kXMLNode') || !$root_node->Children) {
// broken xml OR no aliases defined
continue;
}
$current_node =& $root_node->firstChild;
do {
$template_path = trim($current_node->Data);
$alias = '#' . $module_info['TemplatePath'] . strtolower($current_node->Name). '#';
// remember alias in global theme mapping
$template_aliases[$alias] = $template_path;
// store alias in theme file record to use later in design dropdown
$t_parts = Array (
'path' => dirname($template_path) == '.' ? '' : '/' . dirname($template_path),
'file' => basename($template_path),
);
$sql = 'UPDATE ' . TABLE_PREFIX . 'ThemeFiles
SET TemplateAlias = ' . $this->Conn->qstr($alias) . '
WHERE (ThemeId = ' . $theme_id . ') AND (FilePath = ' . $this->Conn->qstr($t_parts['path']) . ') AND (FileName = ' . $this->Conn->qstr($t_parts['file'] . '.tpl') . ')';
$this->Conn->Query($sql);
} while (($current_node =& $current_node->NextSibling()));
}
}
$fields_hash = Array (
'TemplateAliases' => serialize($template_aliases),
);
$this->Conn->doUpdate($fields_hash, $table_name, $id_field . ' = ' . $theme_id);
return $theme_id;
}
/**
* Searches for new templates (missing in db) in spefied folder
*
* @param string $folder_path subfolder of searchable theme
* @param string $theme_path theme path from web server root
* @param int $theme_id id of theme we are scanning
*/
function FindThemeFiles($folder_path, $theme_path, $theme_id, $auto_structure_mode = 1)
{
$fh = opendir($theme_path.$folder_path.'/');
// always ingore design and element templates
$ignore = Array ('^CVS$', '^\.svn$', '\.des\.tpl$', '\.elm\.tpl$');
$sms_ingore = $theme_path . $folder_path . '/.smsignore';
if (file_exists($sms_ingore)) {
$ignore = array_merge($ignore, file($sms_ingore));
}
while (($filename = readdir($fh))) {
if ($filename == '.' || $filename == '..') continue;
$auto_structure = $auto_structure_mode;
foreach ($ignore as $pattern) {
if (preg_match('/'.str_replace('/', '\\/', trim($pattern)).'/', $filename)) {
$auto_structure = 2;
break;
}
}
$full_path = $theme_path.$folder_path.'/'.$filename;
if (is_dir($full_path)) {
$this->FindThemeFiles($folder_path.'/'.$filename, $theme_path, $theme_id, $auto_structure);
}
elseif (substr($filename, -4) == '.tpl') {
$file_path = $folder_path.'/'.$filename;
$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'] : '';
if ($file_id) {
// file was found in db & on hdd -> mark as existing
$fields_hash = Array (
'FileFound' => 1,
'Description' => $file_description,
'FileType' => $auto_structure,
'FileMetaInfo' => serialize($meta_info),
);
$this->Conn->doUpdate($fields_hash, TABLE_PREFIX . 'ThemeFiles', 'FileId = ' . $file_id);
}
else {
// file was found on hdd, but missing in db -> create new file record
$fields_hash = Array (
'ThemeId' => $theme_id,
'FileName' => $filename,
'FilePath' => $folder_path,
'Description' => $file_description,
'FileType' => $auto_structure, // 1 - built-in, 0 - custom (not in use right now), 2 - skipped in structure
'FileMetaInfo' => serialize($meta_info),
'FileFound' => 1,
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'ThemeFiles');
$this->themeFiles[$file_path] = $this->Conn->getInsertID();
}
// echo 'FilePath: [<strong>'.$folder_path.'</strong>]; FileName: [<strong>'.$filename.'</strong>]; IsNew: [<strong>'.($file_id > 0 ? 'NO' : 'YES').'</strong>]<br />';
}
}
}
/**
* Returns template information (name, description, path) from it's header comment
*
* @param string $template
* @param int $theme_id
* @return Array
*/
function _getTemplateMetaInfo($template, $theme_id)
{
static $init_made = false;
if (!$init_made) {
$this->Application->InitParser(true);
$init_made = true;
}
$template = 'theme:' . $this->_themeNames[$theme_id] . '/' . $template;
$template_file = $this->Application->TemplatesCache->GetRealFilename($template); // ".tpl" was added before
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 ();
}
/**
* Updates file system changes to database for all themes (including new ones)
*
*/
function refreshThemes()
{
$themes_found = Array();
$skip_filenames = Array ('.', '..', 'CVS', '.svn');
$fh = opendir($this->themesFolder.'/');
while (($filename = readdir($fh))) {
if (in_array($filename, $skip_filenames)) {
continue;
}
if (is_dir($this->themesFolder.'/'.$filename)) {
$theme_id = $this->refreshTheme($filename);
if ($theme_id) {
$themes_found[] = $theme_id;
// increment serial of updated themes
$this->Application->incrementCacheSerial('theme', $theme_id);
}
}
}
$id_field = $this->Application->getUnitOption('theme', 'IDField');
$table_name = $this->Application->getUnitOption('theme', 'TableName');
// 1. only one theme found -> enable it and make primary
/*if (count($themes_found) == 1) {
$sql = 'UPDATE ' . $table_name . '
SET Enabled = 1, PrimaryTheme = 1
WHERE ' . $id_field . ' = ' . current($themes_found);
$this->Conn->Query($sql);
}*/
// 2. if none themes found -> delete all from db OR delete all except of found themes
$sql = 'SELECT '.$id_field.'
FROM '.$table_name;
if ($themes_found) {
$sql .= ' WHERE '.$id_field.' NOT IN ('.implode(',', $themes_found).')';
}
$theme_ids = $this->Conn->GetCol($sql);
$this->deleteThemes($theme_ids);
foreach ($theme_ids as $theme_id) {
// increment serial of deleted themes
$this->Application->incrementCacheSerial('theme', $theme_id);
}
$this->Application->incrementCacheSerial('theme');
$this->Application->incrementCacheSerial('theme-file');
+
+ $minify_helper =& $this->Application->recallObject('MinifyHelper');
+ /* @var $minify_helper MinifyHelper */
+
+ $minify_helper->delete();
}
/**
* Deletes themes with ids passed from db
*
* @param Array $theme_ids
*/
function deleteThemes($theme_ids)
{
if (!$theme_ids) {
return ;
}
$id_field = $this->Application->getUnitOption('theme', 'IDField');
$table_name = $this->Application->getUnitOption('theme', 'TableName');
$sql = 'DELETE FROM '.$table_name.'
WHERE '.$id_field.' IN ('.implode(',', $theme_ids).')';
$this->Conn->Query($sql);
$sql = 'DELETE FROM '.TABLE_PREFIX.'ThemeFiles
WHERE '.$id_field.' IN ('.implode(',', $theme_ids).')';
$this->Conn->Query($sql);
}
/**
* Returns current theme (also works in admin)
*
* @return int
*/
function getCurrentThemeId()
{
static $theme_id = null;
if (isset($theme_id)) {
return $theme_id;
}
if ($this->Application->isAdmin) {
// get theme, that user selected in catalog
$theme_id = $this->Application->RecallVar('theme_id');
if ($theme_id === false) {
// query, because "m_theme" is always empty in admin
$id_field = $this->Application->getUnitOption('theme', 'IDField');
$table_name = $this->Application->getUnitOption('theme', 'TableName');
$sql = 'SELECT ' . $id_field . '
FROM ' . $table_name . '
WHERE (PrimaryTheme = 1) AND (Enabled = 1)';
$theme_id = $this->Conn->GetOne($sql);
}
return $theme_id;
}
// use current theme, because it's available on Front-End
$theme_id = $this->Application->GetVar('m_theme');
if (!$theme_id) {
// happens in mod-rewrite mode, then requested template is not found
$theme_id = $this->Application->GetDefaultThemeId();
}
return $theme_id;
}
/**
* Returns page id based on given template
*
* @param string $template
* @param int $theme_id
* @return int
*/
function getPageByTemplate($template, $theme_id = null)
{
if (!isset($theme_id)) {
// during mod-rewrite url parsing current theme
// is not available to kHTTPQuery class, so don't use it
$theme_id = (int)$this->getCurrentThemeId();
}
$sql = 'SELECT ' . $this->Application->getUnitOption('c', 'IDField') . '
FROM ' . $this->Application->getUnitOption('c', 'TableName') . '
WHERE
(
(NamedParentPath = ' . $this->Conn->qstr('Content/' . $template) . ') OR
(IsSystem = 1 AND CachedTemplate = ' . $this->Conn->qstr($template) . ')
)
AND (ThemeId = ' . $theme_id . ($theme_id > 0 ? ' OR ThemeId = 0' : '') . ')';
return $this->Conn->GetOne($sql);
}
}
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/sections_list.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/sections_list.tpl (revision 13486)
+++ branches/5.1.x/core/admin_templates/sections_list.tpl (revision 13487)
@@ -1,42 +1,42 @@
<inp2:m_include t="incs/header"/>
-<link rel="stylesheet" rev="stylesheet" href="incs/sections_list.css" type="text/css" />
+<link rel="stylesheet" rev="stylesheet" href="<inp2:m_Compress files='incs/sections_list.css'/>" type="text/css" />
<inp2:m_DefineElement name="section_list_header" icon_module="">
<inp2:m_RenderElement name="combined_header" prefix="$SectionPrefix" section="$section_name" title_preset="tree_#section#" parent="0"/>
</inp2:m_DefineElement>
<inp2:adm_PrintSection section_name="#session#" render_as="section_list_header"/>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td valign="top" width="100%">
<table width="100%" border="0" cellspacing="0" cellpadding="4" class="bordered">
<inp2:m_DefineElement name="section_element" icon_module="">
<tr class="<inp2:m_odd_even odd='table-color1' even='table-color2'/>">
<td class="subitem_icon">
<img src="<inp2:$SectionPrefix_ModulePath module='$icon_module'/>img/icons/icon46_list_<inp2:m_param name='icon'/>.gif" border="0" alt="<inp2:m_phrase name='$label'/>" align="absmiddle"/>
</td>
<td class="subitem_description">
<a href="<inp2:m_param name='section_url'/>" class="dLink" title="<inp2:m_phrase name='$label'/>" target="main"><inp2:m_phrase name="$label"/></a>
<inp2:m_if check="m_Param" name="is_tab" equals_to="1">
<inp2:m_phrase name="la_Description_{$parent}"/>
<inp2:m_else/>
<inp2:m_phrase name="la_Description_{$section_name}"/>
</inp2:m_if>
</td>
</tr>
</inp2:m_DefineElement>
<inp2:m_set odd_even="table-color1"/>
<inp2:adm_PrintSections block="section_element" section_name="#session#"/>
</table>
</td>
<td valign="top" align="right">
<inp2:adm_ModuleInclude template="summary/#section#"/>
</td>
</tr>
</table>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/browser/browser_header.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/browser/browser_header.tpl (revision 13486)
+++ branches/5.1.x/core/admin_templates/browser/browser_header.tpl (revision 13487)
@@ -1,54 +1,56 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<inp2:m_DefaultParam body_properties=""/>
<html>
<head>
<title><inp2:m_GetConfig var="Site_Name"/> - <inp2:m_Phrase label="la_AdministrativeConsole"/></title>
<meta http-equiv="content-type" content="text/html; charset=<inp2:lang_GetCharset/>"/>
<meta name="keywords" content="..."/>
<meta name="description" content="..."/>
<meta name="robots" content="all"/>
<meta name="copyright" content="Copyright &#174; 2006 Test, Inc"/>
<meta name="author" content="Intechnic Inc."/>
<inp2:m_base_ref/>
<link rel="icon" href="img/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
-<link rel="stylesheet" rev="stylesheet" href="browser/browser.css" type="text/css" />
+<link rel="stylesheet" rev="stylesheet" href="<inp2:m_Compress files='browser/browser.css'/>" type="text/css" />
-<script type="text/javascript" src="js/is.js"></script>
-<script type="text/javascript" src="js/ajax.js"></script>
-<script type="text/javascript" src="js/application.js"></script>
-<script type="text/javascript" src="js/script.js"></script>
+<script type="text/javascript" src="<inp2:m_Compress files='
+ js/is.js|
+ js/ajax.js|
+ js/application.js|
+ js/script.js
+'/>"></script>
<script type="text/javascript">
var t = '<inp2:m_get param="t"/>';
var popups = '1';
var $use_popups = <inp2:m_if check="adm_UsePopups">true<inp2:m_else/>false</inp2:m_if>;
var $modal_windows = <inp2:m_if check="adm_UsePopups" mode="modal">true<inp2:m_else/>false</inp2:m_if>;
var multiple_windows = '1';
var main_title = '<inp2:m_GetConfig var="Site_Name" escape="1"/>';
var tpl_changed = 0;
var base_url = '<inp2:m_BaseURL/>';
var $base_path = '<inp2:m_GetConst name="BASE_PATH"/>';
var img_path = '<inp2:m_TemplatesBase module="#MODULE#"/>/img/';
var phrases = {
'la_Delete_Confirm' : '<inp2:m_Phrase label="la_Delete_Confirm" js_escape="1"/>'
}
<inp2:m_if check="m_GetEquals" name="m_wid" value="" inverse="inverse">
window.name += '_<inp2:m_get name="m_wid"/>';
</inp2:m_if>
var $use_toolbarlabels = <inp2:m_if check="adm_UseToolbarLabels">true<inp2:m_else/>false</inp2:m_if>;
</script>
</head>
<inp2:m_include t="incs/blocks"/>
<inp2:m_include t="incs/in-portal"/>
<inp2:m_if check="m_ParamEquals" name="nobody" value="yes" inverse="inverse">
<body <inp2:m_param name="body_properties"/>>
</inp2:m_if>
Index: branches/5.1.x/core/admin_templates/users/user_edit_items.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/users/user_edit_items.tpl (revision 13486)
+++ branches/5.1.x/core/admin_templates/users/user_edit_items.tpl (revision 13487)
@@ -1,169 +1,170 @@
<inp2:adm_SetPopupSize width="720" height="500"/>
<inp2:m_include t="incs/header"/>
<inp2:m_RenderElement name="combined_header" section="in-portal:user_list" prefix="u" title_preset="user_edit_items" tab_preset="Default"/>
<inp2:m_include template="catalog/catalog_elements"/>
<!-- ToolBar -->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
- <td>
- <link rel="stylesheet" rev="stylesheet" href="incs/nlsmenu.css" type="text/css" />
- <script type="text/javascript" src="js/nlsmenu.js"></script>
- <script type="text/javascript" src="js/nlsmenueffect_1_2_1.js"></script>
+ <td>
+ <link rel="stylesheet" rev="stylesheet" href="<inp2:m_Compress files='incs/nlsmenu.css'/>" type="text/css" />
+ <script type="text/javascript" src="<inp2:m_Compress files='
+ js/nlsmenu.js|
+ js/nlsmenueffect_1_2_1.js|
+ js/catalog.js
+ '/>"></script>
- <script type="text/javascript" src="js/ajax.js"></script>
- <script type="text/javascript" src="js/catalog.js"></script>
<script type="text/javascript">
var menuMgr = new NlsMenuManager("mgr");
menuMgr.timeout = 500;
menuMgr.flowOverFormElement = true;
Request.progressText = '<inp2:m_phrase name="la_title_Loading" no_editing="1" escape="1"/>';
Catalog.prototype.AfterInit = function () {
this.switchTab(); // refresh current item tab
}
/*Catalog.prototype.refreshTab = function($prefix, $div_id, $force) {
// query tab content only in case if not queried or category don't match
var $cat_id = get_hidden_field('m_cat_id');
var $tab_cat_id = document.getElementById($div_id).getAttribute('category_id');
if ($cat_id != $tab_cat_id || $force) {
var $url = this.URLMask.replace('#TEMPLATE_NAME#', this.queryTabRegistry('prefix', $prefix, 'module_path') + '/user_item_tab');
this.BusyRequest[$prefix] = false;
Request.makeRequest($url, this.BusyRequest[$prefix], $div_id, this.successCallback, this.errorCallback, $div_id, this);
}
}*/
var $Catalog = new Catalog('<inp2:m_Link template="#TEMPLATE_NAME#" pass_through="ts" ts="user" pass="m,u" no_amp="1"/>', 'useritems_', 'UserItemEditor');
a_toolbar = new ToolBar();
a_toolbar.AddButton( new ToolBarButton('select', '<inp2:m_phrase label="la_ToolTip_Save" escape="1"/>', function() {
submit_event('u','<inp2:u_SaveEvent/>');
}
) );
a_toolbar.AddButton( new ToolBarButton('cancel', '<inp2:m_phrase label="la_ToolTip_Cancel" escape="1"/>', function() {
submit_event('u','OnCancelEdit');
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
a_toolbar.AddButton( new ToolBarButton('prev', '<inp2:m_phrase label="la_ToolTip_Prev" escape="1"/>', function() {
go_to_id('u', '<inp2:u_PrevId/>');
}
) );
a_toolbar.AddButton( new ToolBarButton('next', '<inp2:m_phrase label="la_ToolTip_Next" escape="1"/>', function() {
go_to_id('u', '<inp2:u_NextId/>');
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep2') );
a_toolbar.AddButton( new ToolBarButton('edit', '<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>', edit) );
a_toolbar.AddButton( new ToolBarButton('delete', '<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
function() {
var $template = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'view_template');
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + '.user]', 1);
std_delete_items($Catalog.ActivePrefix, $template, 1);
} ) );
a_toolbar.AddButton( new ToolBarSeparator('sep3') );
a_toolbar.AddButton( new ToolBarButton('view', '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>', function() {
show_viewmenu(a_toolbar,'view');
}
) );
function edit() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
var $kf = document.getElementById($form_name);
var $prev_action = $kf.action;
$kf.action = '<inp2:m_t pass="all" no_pass_through="1"/>';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + ']', 1);
std_edit_item(
$Catalog.ActivePrefix, $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'edit_template'),
function() {
$kf.action = $prev_action;
}
);
}
a_toolbar.Render();
<inp2:m_if check="u_IsSingle">
a_toolbar.HideButton('prev');
a_toolbar.HideButton('next');
a_toolbar.HideButton('sep1');
<inp2:m_else/>
<inp2:m_if check="u_IsLast">
a_toolbar.DisableButton('next');
</inp2:m_if>
<inp2:m_if check="u_IsFirst">
a_toolbar.DisableButton('prev');
</inp2:m_if>
</inp2:m_if>
</script>
</td>
<inp2:m_RenderElement name="catalog_search_box"/>
</tr>
</tbody>
</table>
<inp2:m_RenderElement name="kernel_form_end"/>
<inp2:u_SaveWarning name="grid_save_warning"/>
<inp2:u_ErrorWarning name="form_error_warning"/>
<div id="scroll_container" mode="minimal">
<table class="edit-form">
<inp2:m_RenderElement name="subsection" prefix="u" fields="PortalUserId,Login" title="la_section_General"/>
<inp2:m_RenderElement name="inp_id_label" prefix="u" field="PortalUserId" title="!la_fld_Id!"/>
<inp2:m_RenderElement name="inp_label" prefix="u" field="Login" title="la_fld_Username"/>
<inp2:m_RenderElement name="inp_edit_filler"/>
<inp2:m_RenderElement name="subsection" title="la_section_Items"/>
</table>
</div>
<br />
<!-- item tabs: begin -->
<inp2:m_DefineElement name="item_tab" title="" special=".user">
<td class="tab-spacer"><img src="img/spacer.gif" width="3" height="1"/></td>
<td id="<inp2:m_param name="prefix"/><inp2:m_param name="special"/>_tab" class="tab">
<img src="<inp2:m_TemplatesBase module='$icon_module'/>/img/itemicons/<inp2:m_Param name='icon'/>" width="16" height="16" align="absmiddle" alt=""/>
<a href="#" onclick="$Catalog.switchTab('<inp2:m_param name="prefix"/><inp2:m_Param name="special"/>'); return false;" class="tab-link">
<inp2:m_Phrase name="$title"/> <span class="small-statistics" style="color: inherit;">(<span id="<inp2:m_param name="prefix"/><inp2:m_Param name="special"/>_item_count">?</span>)</span>
</a>
</td>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="user_items_tabs">
<inp2:m_ModuleInclude template="user_item_tab" tab_init="2" title_property="ViewMenuPhrase" skip_prefixes="m,adm,cms"/>
</inp2:m_DefineElement>
<inp2:m_RenderElement name="tabs_container" tabs_render_as="user_items_tabs"/>
<!-- item tabs: end -->
<inp2:m_set ts="user"/>
<inp2:m_ModuleInclude template="user_item_tab" tab_init="1" skip_prefixes="m,adm,cms"/>
<script type="text/javascript">
addLoadEvent(
function() {
$Catalog.Init();
}
);
</script>
<inp2:m_include t="incs/footer" noform="yes"/>
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/reviews/reviews.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/reviews/reviews.tpl (revision 13486)
+++ branches/5.1.x/core/admin_templates/reviews/reviews.tpl (revision 13487)
@@ -1,121 +1,123 @@
<inp2:m_include t="incs/header" noform="yes"/>
<inp2:m_include template="catalog/catalog_elements"/>
<inp2:m_RenderElement name="combined_header" section="in-portal:reviews" prefix="c" module="in-portal" title_preset="reviews" tabs="catalog/catalog_tabs" special="-rev" skip_prefixes="m,c"/>
<!-- main kernel_form: begin -->
<inp2:m_RenderElement name="kernel_form"/>
<!-- ToolBar -->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<input type="hidden" name="m_cat_id" value="<inp2:m_get name="m_cat_id"/>"/>
- <link rel="stylesheet" rev="stylesheet" href="incs/nlsmenu.css" type="text/css" />
- <script type="text/javascript" src="js/nlsmenu.js"></script>
- <script type="text/javascript" src="js/nlsmenueffect_1_2_1.js"></script>
- <script type="text/javascript" src="js/ajax.js"></script>
- <script type="text/javascript" src="js/catalog.js"></script>
+ <link rel="stylesheet" rev="stylesheet" href="<inp2:m_Compress files='incs/nlsmenu.css'/>" type="text/css" />
+ <script type="text/javascript" src="<inp2:m_Compress files='
+ js/nlsmenu.js|
+ js/nlsmenueffect_1_2_1.js|
+ js/catalog.js'
+ />"></script>
+
<script type="text/javascript">
var menuMgr = new NlsMenuManager("mgr");
menuMgr.timeout = 500;
menuMgr.flowOverFormElement = true;
Request.progressText = '<inp2:m_phrase name="la_title_Loading" no_editing="1" escape="1"/>';
Catalog.prototype.AfterInit = function() {
this.switchTab();
}
Catalog.prototype.refreshTab = function($prefix, $div_id, $force) {
var $cat_id = get_hidden_field('m_cat_id');
var $tab_cat_id = document.getElementById($div_id).getAttribute('category_id');
if ($cat_id != $tab_cat_id || $force) {
// query tab content only in case if not queried or category don't match
var $url = this.URLMask.replace('#ITEM_PREFIX#', $prefix).replace('#TAB_NAME#', this.queryTabRegistry('prefix', $prefix, 'tab_id'));
this.BusyRequest[$prefix] = false;
Request.makeRequest($url, this.BusyRequest[$prefix], $div_id, this.successCallback, this.errorCallback, $div_id, this);
}
}
var $Catalog = new Catalog('<inp2:m_Link template="reviews/reviews_tab" item_prefix="#ITEM_PREFIX#" tab_name="#TAB_NAME#" pass_through="td,item_prefix,tab_name" td="no" m_cat_id="-1" no_amp="1"/>', 'reviews_', 'Reviews');
var a_toolbar = new ToolBar();
a_toolbar.AddButton( new ToolBarButton('edit', '<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>', edit) );
a_toolbar.AddButton( new ToolBarButton('delete', '<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
function() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
std_delete_items($Catalog.ActivePrefix, null, 1);
} ) );
<inp2:m_ModuleInclude template="catalog_buttons" main_template="reviews" skip_prefixes="m,c" replace_m="yes"/>
a_toolbar.AddButton( new ToolBarSeparator('sep2') );
a_toolbar.AddButton( new ToolBarButton('approve', '<inp2:m_phrase label="la_ToolTip_Approve" escape="1"/>', function() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
$Catalog.submit_event($Catalog.ActivePrefix, 'OnMassApprove');
}
) );
a_toolbar.AddButton( new ToolBarButton('decline', '<inp2:m_phrase label="la_ToolTip_Decline" escape="1"/>', function() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
$Catalog.submit_event($Catalog.ActivePrefix, 'OnMassDecline');
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep3') );
a_toolbar.AddButton( new ToolBarButton('view', '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>', function() {
show_viewmenu(a_toolbar, 'view');
}
) );
a_toolbar.Render();
function edit()
{
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
var $kf = document.getElementById($form_name);
var $prev_action = $kf.action;
$kf.action = '<inp2:m_t pass="all" pass_through="item_prefix" item_prefix="#PREFIX#" no_amp="1"/>' . replace('#PREFIX#', $Catalog.ActivePrefix);
std_edit_temp_item(
$Catalog.ActivePrefix, 'reviews/review_direct_edit',
function() {
$kf.action = $prev_action;
}
);
}
</script>
</td>
<inp2:m_RenderElement name="catalog_search_box"/>
</tr>
</tbody>
</table>
<inp2:m_RenderElement name="kernel_form_end"/>
<!-- main kernel_form: end -->
<inp2:m_set prefix_append="-rev" td="no"/>
<inp2:m_ModuleInclude template="catalog_tab" tab_init="2" skip_prefixes="m,c" replace_m="yes"/>
<inp2:m_if check="m_get" var="SetTab">
<script type="text/javascript">
$Catalog.switchTab('<inp2:m_get var="SetTab"/>-rev');
</script>
</inp2:m_if>
<script type="text/javascript">
addLoadEvent(
function() {
$Catalog.Init();
}
);
</script>
<inp2:m_include t="incs/footer" noform="yes"/>
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/incs/grid_blocks.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/incs/grid_blocks.tpl (revision 13486)
+++ branches/5.1.x/core/admin_templates/incs/grid_blocks.tpl (revision 13487)
@@ -1,905 +1,901 @@
<inp2:m_DefineElement name="current_page">
<span class="current_page"><inp2:m_param name="page"/></span>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="page">
<a href="javascript:go_to_page('<inp2:m_param name="PrefixSpecial"/>', <inp2:m_param name="page"/>, <inp2:m_param name="ajax"/>)" class="nav_url"><inp2:m_param name="page"/></a>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="next_page">
<a href="javascript:go_to_page('<inp2:m_param name="PrefixSpecial"/>', <inp2:m_param name="page"/>, <inp2:m_param name="ajax"/>)" class="nav_url">&gt;</a>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="prev_page">
<a href="javascript:go_to_page('<inp2:m_param name="PrefixSpecial"/>', <inp2:m_param name="page"/>, <inp2:m_param name="ajax"/>)" class="nav_url">&lt;</a>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="next_page_split">
<a href="javascript:go_to_page('<inp2:m_param name="PrefixSpecial"/>', <inp2:m_param name="page"/>, <inp2:m_param name="ajax"/>)" class="nav_url">&gt;&gt;</a>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="prev_page_split">
<a href="javascript:go_to_page('<inp2:m_param name="PrefixSpecial"/>', <inp2:m_param name="page"/>, <inp2:m_param name="ajax"/>)" class="nav_url">&lt;&lt;</a>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_pagination_elem" main_special="" ajax="0">
<inp2:m_if check="GridInfo" type="needs_pagination" pass_params="1">
&nbsp;<inp2:m_phrase name="la_Page"/>:
<inp2:PrintPages active_block="current_page" split="10" inactive_block="page" prev_page_block="prev_page" next_page_block="next_page" prev_page_split_block="prev_page_split" next_page_split_block="next_page_split" main_special="$main_special" ajax="$ajax" grid="$grid"/>
</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_pagination" SearchPrefixSpecial="" ajax="0">
<!--## Maybe not in use ##-->
<table cellspacing="0" cellpadding="2" width="100%" border="0" class="pagination_bar">
<tbody>
<tr>
<td width="100%">
<inp2:m_RenderElement name="grid_pagination_elem" pass_params="1"/>
</td>
<td>
<inp2:m_if check="m_ParamEquals" param="search" value="on">
<inp2:m_if check="m_ParamEquals" name="SearchPrefixSpecial" value="">
<inp2:m_RenderElement name="grid_search" grid="$grid" PrefixSpecial="$PrefixSpecial" ajax="$ajax"/>
<inp2:m_else />
<inp2:m_RenderElement name="grid_search" grid="$grid" PrefixSpecial="$SearchPrefixSpecial" ajax="$ajax"/>
</inp2:m_if>
</inp2:m_if>
</td>
</tr>
</tbody>
</table>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="search_main_toolbar">
<td style="white-space: nowrap; text-align: right; width: 260px;" align="right">
<div style="float: right">
<table cellpadding="0" cellspacing="0">
<tr>
<td>
<input type="text"
id="<inp2:m_param name='prefix'/>_search_keyword"
class="filter <inp2:m_ifnot check='m_Recall' var='{$prefix}_search_keyword' equals_to=''>filter-active</inp2:m_ifnot>"
name="<inp2:m_param name='prefix'/>_search_keyword"
value="<inp2:m_recall var='{$prefix}_search_keyword' no_null='no_null' special='1'/>"
PrefixSpecial="<inp2:m_param name='prefix'/>"
Grid="<inp2:m_param name='grid'/>"
ajax="0" style="width:160px"/>
</td>
<td style="white-space: nowrap;">
<script type="text/javascript">
b_toolbar = new ToolBar();
b_toolbar.AddButton( new ToolBarButton('search', '<inp2:m_phrase label="la_ToolTip_Search" escape="1"/>',
function() {
search('<inp2:m_Param name="prefix"/>', '<inp2:m_Param name="grid"/>', 0);
} ) );
b_toolbar.AddButton( new ToolBarButton('search_reset_alt', '<inp2:m_phrase label="la_ToolTip_SearchReset" escape="1"/>',
function() {
search_reset('<inp2:m_Param name="prefix"/>', '<inp2:m_Param name="grid"/>', 0);
} ) );
b_toolbar.Render();
</script>
</td>
</tr>
</table>
</div>
</td>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_search" ajax="0">
<td align="right" class="search-cell">
<img src="img/spacer.gif" width="250" height="1" alt=""/><br />
<table cellspacing="0" cellpadding="0">
<tr>
<td><inp2:m_phrase name="la_Search"/>:&nbsp;</td>
<td>
<input type="text"
id="<inp2:m_param name='PrefixSpecial'/>_search_keyword"
class="filter <inp2:m_ifnot check='m_Recall' var='{$PrefixSpecial}_search_keyword' equals_to=''>filter-active</inp2:m_ifnot>"
name="<inp2:m_param name='PrefixSpecial'/>_search_keyword"
value="<inp2:m_recall var='{$PrefixSpecial}_search_keyword' no_null='no_null' special='1'/>"
PrefixSpecial="<inp2:m_param name='PrefixSpecial'/>"
Grid="<inp2:m_param name='grid'/>"
ajax="<inp2:m_param name='ajax'/>"/>
<input type="text" style="display: none;"/>
</td>
<td style="white-space: nowrap;" id="search_buttons[<inp2:m_param name="PrefixSpecial"/>]">
</td>
</tr>
</table>
<inp2:m_if check="m_Param" name="ajax" equals_to="0">
<script type="text/javascript">
addLoadEvent(
function () {
<inp2:m_RenderElement name="grid_search_buttons" pass_params="true"/>
}
)
</script>
</inp2:m_if>
</td>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_search_buttons" PrefixSpecial="" grid="" ajax="1">
var $search_box = document.getElementById('<inp2:m_param name="PrefixSpecial"/>_search_keyword');
if ($search_box) {
//$search_box.onkeydown = search_keydown;
$( jq('#<inp2:m_param name="PrefixSpecial"/>_search_keyword') ).keydown(search_keydown);
}
var $search_buttons = document.getElementById('search_buttons[<inp2:m_param name="PrefixSpecial"/>]');
if ($search_buttons) {
Toolbars['<inp2:m_param name="PrefixSpecial"/>_search'] = new ToolBar('icon16_');
Toolbars['<inp2:m_param name="PrefixSpecial"/>_search'].IconSize = {w:22,h:22};
Toolbars['<inp2:m_param name="PrefixSpecial"/>_search'].UseLabels = false;
Toolbars['<inp2:m_param name="PrefixSpecial"/>_search'].AddButton(
new ToolBarButton(
'search',
'<inp2:m_phrase name="la_ToolTip_Search" escape="1"/>',
function() {
search('<inp2:m_param name="PrefixSpecial"/>','<inp2:m_param name="grid"/>', <inp2:m_param name="ajax"/>)
},
null,
'<inp2:m_param name="PrefixSpecial"/>'
)
);
Toolbars['<inp2:m_param name="PrefixSpecial"/>_search'].AddButton(
new ToolBarButton(
'search_reset',
'<inp2:m_phrase name="la_ToolTip_SearchReset" escape="1"/>',
function() {
search_reset('<inp2:m_param name="PrefixSpecial"/>','<inp2:m_param name="grid"/>', <inp2:m_param name="ajax"/>)
},
null,
'<inp2:m_param name="PrefixSpecial"/>'
)
);
Toolbars['<inp2:m_param name="PrefixSpecial"/>_search'].Render($search_buttons);
}
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_checkbox_td" format="">
<inp2:m_RenderElement name="grid_data_td" pass_params="1"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_checkbox_td_no_icon" format="">
<inp2:m_RenderElement name="grid_data_td" pass_params="1"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="label_grid_checkbox_td" format="">
<inp2:m_RenderElement name="grid_data_label_td" pass_params="1"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_icon_td" format="">
<inp2:m_RenderElement name="grid_data_td" pass_params="1"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_radio_td" format="">
<inp2:m_RenderElement name="grid_data_td" pass_params="1"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_data_td" format="" no_special="1" nl2br="" first_chars="" td_style="">
<inp2:Field field="$field" first_chars="$first_chars" nl2br="$nl2br" grid="$grid" no_special="$no_special" format="$format"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_total_td">
<inp2:m_if check="FieldOption" field="$field" option="totals">
<inp2:FieldOption field="$field" option="totals" result_to_var="totals"/>
'<inp2:FieldTotal field="$field" function="$totals"/>'
<inp2:m_else/>
'&nbsp;'
</inp2:m_if>
<inp2:m_ifnot check="m_Param" name="is_last">, </inp2:m_ifnot>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_priority_td" format="" no_special="" nl2br="" first_chars="" td_style="" currency="">
<inp2:Field field="$field" first_chars="$first_chars" currency="$currency" nl2br="$nl2br" grid="$grid" no_special="$no_special" format="$format"/>
<inp2:m_ifnot check="Field" field="Priority" equals_to="0" db="db"><span class="priority"><sup><inp2:Field field="Priority"/></sup></span></inp2:m_ifnot>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_edit_td" format="" >
<input type="text" id="<inp2:{$PrefixSpecial}_InputName field="$field"/>" name="<inp2:{$PrefixSpecial}_InputName field="$field"/>" value="<inp2:{$PrefixSpecial}_field field="$field" grid="$grid" format="$format"/>">
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_picker_td" nl2br="0" no_special="1" separator="&nbsp;">
<inp2:Field name="$field" format="$separator" nl2br="$nl2br" no_special="$no_special"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_options_td" format="">
<select name="<inp2:InputName field="$field"/>" id="<inp2:InputName field="$field"/>">
<inp2:m_if check="FieldOption" field="$field" option="use_phrases">
<inp2:PredefinedOptions field="$field" block="inp_option_phrase" selected="selected" has_empty="1" empty_value="0"/>
<inp2:m_else/>
<inp2:PredefinedOptions field="$field" block="inp_option_item" selected="selected" has_empty="1" empty_value="0"/>
</inp2:m_if>
</select>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_date_td" format="">
<input type="text" name="<inp2:InputName field="{$field}_date"/>" id="<inp2:InputName field="{$field}_date"/>" value="<inp2:Field field="{$field}_date" format="_regional_InputDateFormat"/>" size="<inp2:Format field="{$field}_date" input_format="1" edit_size="edit_size"/>" datepickerIcon="<inp2:m_ProjectBase/>core/admin_templates/img/calendar_icon.gif">&nbsp;
<img src="img/calendar_icon.gif" id="cal_img_<inp2:InputName field="{$field}"/>" width="13" height="12"
style="cursor: pointer; margin-right: 5px"
title="Date selector"
/>
<span class="small">(<inp2:Format field="{$field}_date" input_format="1" human="true"/>)</span>
<script type="text/javascript">
Calendar.setup({
inputField : "<inp2:InputName field="{$field}_date"/>",
ifFormat : Calendar.phpDateFormat("<inp2:Format field="{$field}_date" input_format="1"/>"),
button : "cal_img_<inp2:InputName field="{$field}"/>",
align : "br",
singleClick : true,
showsTime : true,
weekNumbers : false,
firstDay : <inp2:m_GetConfig var="FirstDayOfWeek"/>,
onUpdate : function(cal) {
runOnChange('<inp2:InputName field="{$field}_date"/>');
}
});
</script>
<input type="hidden" name="<inp2:InputName field="{$field}_time"/>" id="<inp2:InputName field="{$field}_time" input_format="1"/>" value="">
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_data_label_td">
<inp2:Field field="$field" grid="$grid" plus_or_as_label="1" no_special="no_special" format="$format"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_data_label_ml_td" format="">
<span class="<inp2:m_if check="{$SourcePrefix}_HasError" field="$virtual_field">error-cell</inp2:m_if>">
<inp2:{$PrefixSpecial}_Field field="$field" grid="$grid" as_label="1" no_special="no_special" format="$format"/>
</span><inp2:m_if check="{$SourcePrefix}_IsRequired" field="$virtual_field"><span class="field-required"> *</span></inp2:m_if>:<br />
<inp2:m_if check="FieldEquals" field="$ElementTypeField" value="textarea">
<inp2:m_if check="Field" name="MultiLingual" equals_to="1" db="db">
<a href="javascript:PreSaveAndOpenTranslatorCV('<inp2:m_param name="SourcePrefix"/>,<inp2:m_param name="SourcePrefix"/>-cdata', '<inp2:m_param name="SourcePrefix"/>-cdata:cust_<inp2:Field name="CustomFieldId"/>', 'popups/translator', <inp2:$SourcePrefix_Field field="ResourceId"/>, 1);" title="<inp2:m_Phrase label="la_Translate" escape="1"/>"><img src="img/icons/icon24_translate.png" style="cursor:hand;" width="24" height="24" border="0"></a>
<inp2:m_else/>
<inp2:Field name="FieldName" result_to_var="custom_field"/>
<a href="javascript:OpenEditor('&section=in-link:editlink_general', 'kernel_form', '<inp2:{$SourcePrefix}_InputName field="cust_{$custom_field}"/>');"><img src="img/icons/icon24_link_editor.gif" style="cursor: hand;" width="24" height="24" border="0"></a>
</inp2:m_if>
<inp2:m_else/>
<inp2:m_if check="Field" name="MultiLingual" equals_to="1" db="db">
<a href="javascript:PreSaveAndOpenTranslatorCV('<inp2:m_param name="SourcePrefix"/>,<inp2:m_param name="SourcePrefix"/>-cdata', '<inp2:m_param name="SourcePrefix"/>-cdata:cust_<inp2:Field name="CustomFieldId"/>', 'popups/translator', <inp2:$SourcePrefix_Field field="ResourceId"/>);" title="<inp2:m_Phrase label="la_Translate" escape="1"/>"><img src="img/icons/icon24_translate.png" style="cursor:hand;" width="24" height="24" border="0"></a>
</inp2:m_if>
</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_empty_filter">
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_column_filter">
<!--## this cheat makes sure, that columns without a filter are using like filter ##-->
<inp2:m_RenderElement name="grid_like_filter" pass_params="1"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_options_filter" use_phrases="0" filter_width="90%">
<select
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='options' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
name="<inp2:SearchInputName field="$filter_field" filter_type="options" grid="$grid"/>"
style="width: <inp2:m_Param name="filter_width"/>">
<inp2:m_if check="m_ParamEquals" name="use_phrases" value="1">
<inp2:PredefinedSearchOptions field="$filter_field" block="inp_option_phrase" selected="selected" has_empty="1" empty_value="" filter_type="options" grid="$grid"/>
<inp2:m_else/>
<inp2:PredefinedSearchOptions field="$filter_field" block="inp_option_item" selected="selected" has_empty="1" empty_value="" filter_type="options" grid="$grid"/>
</inp2:m_if>
</select>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_like_filter" filter_width="95%">
<input type="text"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='like' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
style="width: <inp2:m_Param name="filter_width"/>"
name="<inp2:SearchInputName field="$filter_field" filter_type="like" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="like" grid="$grid"/>"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_user_like_filter" selector_template="user_selector" filter_width="95%">
<table class="range-filter">
<tr>
<td style="width: 100%">
<input type="text"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='like' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
style="width: <inp2:m_Param name="filter_width"/>"
name="<inp2:SearchInputName field="$filter_field" filter_type="like" grid="$grid"/>"
id="<inp2:SearchInputName field="$filter_field" filter_type="like" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="like" grid="$grid"/>"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
</td>
<td valign="middle">
<a href="javascript:openSelector('<inp2:m_param name="PrefixSpecial"/>', '<inp2:m_t t="$selector_template" pass="all,$PrefixSpecial" escape="1"/>', '<inp2:m_param name="filter_field"/>');">
<img src="img/icons/icon24_link_user.gif" style="cursor:hand;" width="24" height="24" border="0">
</a>
</td>
</tr>
</table>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_picker_filter" use_phrases="0" filter_width="90%">
<select
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='options' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
name="<inp2:SearchInputName field="$filter_field" filter_type="picker" grid="$grid"/>"
style="width: <inp2:m_Param name="filter_width"/>">
<inp2:m_if check="m_ParamEquals" name="use_phrases" value="1">
<inp2:PredefinedSearchOptions field="$filter_field" block="inp_option_phrase" selected="selected" has_empty="1" empty_value="" filter_type="picker" grid="$grid"/>
<inp2:m_else/>
<inp2:PredefinedSearchOptions field="$filter_field" block="inp_option_item" selected="selected" has_empty="1" empty_value="" filter_type="picker" grid="$grid"/>
</inp2:m_if>
</select>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_like_combo_filter" filter_width="95%">
<input type="text"
autocomplete="off"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='like' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
style="width: <inp2:m_Param name="filter_width"/>"
name="<inp2:SearchInputName field="$filter_field" filter_type="like" grid="$grid"/>"
id="<inp2:SearchInputName field="$filter_field" filter_type="like" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="like" grid="$grid"/>"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
<script type="text/javascript">
new AJAXDropDown('<inp2:SearchInputName field="$filter_field" filter_type="like" grid="$grid"/>',
function(cur_value) {
return '<inp2:m_t no_amp="1" pass="m,{$PrefixSpecial}" field="$filter_field" {$PrefixSpecial}_event="OnSuggestValues" cur_value="#VALUE#"/>'.replace('#VALUE#', cur_value);
}
);
</script>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_equals_filter" filter_width="95%">
<input type="text"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='equals' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
style="width: <inp2:m_Param name="filter_width"/>"
name="<inp2:SearchInputName field="$filter_field" filter_type="equals" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="equals" grid="$grid"/>"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_range_filter" filter_width="90%">
<table class="range-filter">
<tr>
<td style="width: 100%">
<input type="text"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='range' type='from' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
name="<inp2:SearchInputName field="$filter_field" filter_type="range" type="from" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="range" type="from" grid="$grid"/>"
style="width: <inp2:m_Param name="filter_width"/>;"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
</td>
<td rowspan="2" valign="middle">
<img src="<inp2:m_TemplatesBase/>/img/expand_filter.gif" width="7" height="9" alt="" onclick="filter_toggle('<inp2:SearchInputName field='$filter_field' filter_type='range' type='to' grid='$grid'/>_row', '<inp2:m_Param name='PrefixSpecial'/>');"/>
</td>
</tr>
<tr class="to-range-filter<inp2:m_ifnot check='RangeFiltersUsed' grid='$grid'> hidden-filter</inp2:m_ifnot>" id="<inp2:SearchInputName field='$filter_field' filter_type='range' type='to' grid='$grid'/>_row">
<td style="width: 100%;<inp2:m_ifnot check='RangeFiltersUsed' grid='$grid'> display: none;</inp2:m_ifnot>">
<input type="text"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='range' type='to' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
name="<inp2:SearchInputName field="$filter_field" filter_type="range" type="to" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="range" type="to" grid="$grid"/>"
style="width: <inp2:m_Param name="filter_width"/>;"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
</td>
</tr>
</table>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_float_range_filter" filter_width="90%">
<table class="range-filter">
<tr>
<td style="width: 100%">
<input type="text"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='float_range' type='from' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
name="<inp2:SearchInputName field="$filter_field" filter_type="float_range" type="from" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="float_range" type="from" grid="$grid"/>"
style="width: <inp2:m_Param name="filter_width"/>"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
</td>
<td rowspan="2" valign="middle">
<img src="<inp2:m_TemplatesBase/>/img/expand_filter.gif" width="7" height="9" alt="" onclick="filter_toggle('<inp2:SearchInputName field='$filter_field' filter_type='range' type='to' grid='$grid'/>_row', '<inp2:m_Param name='PrefixSpecial'/>');"/>
</td>
</tr>
<tr class="to-range-filter<inp2:m_ifnot check='RangeFiltersUsed' grid='$grid'> hidden-filter</inp2:m_ifnot>" id="<inp2:SearchInputName field='$filter_field' filter_type='float_range' type='to' grid='$grid'/>_row">
<td style="width: 100%;<inp2:m_ifnot check='RangeFiltersUsed' grid='$grid'> display: none;</inp2:m_ifnot>">
<input type="text"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='float_range' type='to' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
name="<inp2:SearchInputName field="$filter_field" filter_type="float_range" type="to" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="float_range" type="to" grid="$grid"/>"
style="width: <inp2:m_Param name="filter_width"/>"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
</td>
</tr>
</table>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_date_range_filter" calendar_format="" filter_width="80%">
<table class="range-filter">
<tr>
<td style="width: 100%">
<input type="text"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='date_range' type='from' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
style="width: <inp2:m_Param name="filter_width"/>"
name="<inp2:SearchInputName field="$filter_field" filter_type="date_range" type="from" grid="$grid"/>"
id="<inp2:SearchInputName field="$filter_field" filter_type="date_range" type="from" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="date_range" type="from" grid="$grid"/>"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
</td>
<td>
<img src="img/calendar_icon.gif" width="13" height="12" id="cal_img_<inp2:SearchInputName field="$filter_field" filter_type="date_range" type="from" grid="$grid"/>"
style="cursor: pointer; margin-right: 5px"
title="Date selector"
/>
</td>
<td rowspan="2" valign="middle">
<img src="<inp2:m_TemplatesBase/>/img/expand_filter.gif" width="7" height="9" alt="" onclick="filter_toggle('<inp2:SearchInputName field='$filter_field' filter_type='date_range' type='to' grid='$grid'/>_row', '<inp2:m_Param name='PrefixSpecial'/>');"/>
</td>
</tr>
<tr class="to-range-filter<inp2:m_ifnot check='RangeFiltersUsed' grid='$grid'> hidden-filter</inp2:m_ifnot>" id="<inp2:SearchInputName field='$filter_field' filter_type='date_range' type='to' grid='$grid'/>_row">
<td style="width: 100%;<inp2:m_ifnot check='RangeFiltersUsed' grid='$grid'> display: none;</inp2:m_ifnot>">
<input type="text"
class="filter <inp2:m_ifnot check='SearchField' field='$filter_field' filter_type='date_range' type='to' grid='$grid' equals_to=''>filter-active</inp2:m_ifnot>"
style="width: <inp2:m_Param name="filter_width"/>"
name="<inp2:SearchInputName field="$filter_field" filter_type="date_range" type="to" grid="$grid"/>"
id="<inp2:SearchInputName field="$filter_field" filter_type="date_range" type="to" grid="$grid"/>"
value="<inp2:SearchField field="$filter_field" filter_type="date_range" type="to" grid="$grid"/>"
onkeypress="search_keydown(event, '<inp2:m_Param name="PrefixSpecial"/>', '<inp2:m_Param name="grid"/>', '<inp2:m_Param name="ajax"/>')"/>
</td>
<td<inp2:m_ifnot check='RangeFiltersUsed' grid='$grid'> style="display: none;"</inp2:m_ifnot>>
<img src="img/calendar_icon.gif" width="13" height="12" id="cal_img_<inp2:SearchInputName field="$filter_field" filter_type="date_range" type="to" grid="$grid"/>"
style="cursor: pointer; margin-right: 5px"
title="Date selector"
/>
</td>
</tr>
</table>
<script type="text/javascript">
var $format = "<inp2:m_if check='m_Param' name='calendar_format'><inp2:m_Param name='calendar_format'/><inp2:m_else/><inp2:Format field='{$sort_field}' input_format='1'/></inp2:m_if>";
Calendar.setup({
inputField : "<inp2:SearchInputName field='$filter_field' filter_type='date_range' type='from' grid='$grid'/>",
ifFormat : Calendar.phpDateFormat($format),
button : "cal_img_<inp2:SearchInputName field='$filter_field' filter_type='date_range' type='from' grid='$grid'/>",
align : 'br',
singleClick : true,
showsTime : true,
weekNumbers : false,
firstDay : <inp2:m_GetConfig var="FirstDayOfWeek"/>
});
Calendar.setup({
inputField : "<inp2:SearchInputName field='$filter_field' filter_type='date_range' type='to' grid='$grid'/>",
ifFormat : Calendar.phpDateFormat($format),
button : "cal_img_<inp2:SearchInputName field='$filter_field' filter_type='date_range' type='to' grid='$grid'/>",
align : 'br',
singleClick : true,
showsTime : true,
weekNumbers : false,
firstDay : <inp2:m_GetConfig var="FirstDayOfWeek"/>
});
</script>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="viewmenu_sort_block">
$Menus['<inp2:m_param name="PrefixSpecial"/>'+'_sorting_menu'].addMenuItem('<inp2:m_phrase name="$title" js_escape="1"/>','direct_sort_grid("<inp2:m_param name="PrefixSpecial"/>","<inp2:m_param name="sort_field"/>","<inp2:{$PrefixSpecial}_OrderInfo type="direction" pos="1"/>", null, <inp2:m_param name="ajax"/>);','<inp2:m_if check="{$PrefixSpecial}_IsOrder" field="$sort_field" pos="1" >2</inp2:m_if>');
</inp2:m_DefineElement>
<inp2:m_DefineElement name="viewmenu_filter_block">
$Menus['<inp2:m_param name="PrefixSpecial"/>'+'_filter_menu'].addMenuItem('<inp2:m_param name="label" js_escape="1"/>','<inp2:m_param name="filter_action"/>','<inp2:m_param name="filter_status"/>');
</inp2:m_DefineElement>
<inp2:m_DefineElement name="viewmenu_filter_separator">
$Menus['<inp2:m_param name="PrefixSpecial"/>'+'_filter_menu'].addMenuSeparator();
</inp2:m_DefineElement>
<inp2:m_include template="incs/menu_blocks"/>
<inp2:m_DefineElement name="grid_save_warning">
<table width="100%" border="0" cellspacing="0" cellpadding="4" class="warning-table">
<tr>
<td valign="top" class="form-warning">
<inp2:m_phrase name="la_Warning_Save_Item"/>
</td>
</tr>
</table>
<script type="text/javascript">
$edit_mode = <inp2:m_if check="m_ParamEquals" name="edit_mode" value="1">true<inp2:m_else />false</inp2:m_if>;
if (Form) Form.Changed();
// window.parent.document.title += ' - MODE: ' + ($edit_mode ? 'EDIT' : 'LIVE');
</script>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_status" pagination="1">
<table class="grid-status-bar">
<tr>
<td nowrap="nowrap" style="vertical-align: middle;">
<inp2:m_Phrase label="la_Records"/>: <inp2:GridInfo type="filtered"/> (<inp2:GridInfo type="from"/> - <inp2:GridInfo type="to"/>) <inp2:m_Phrase label="la_OutOf"/> <inp2:GridInfo type="total"/>
</td>
<td align="right" class="tablenav" valign="middle">
<inp2:m_if check="m_Param" name="pagination">
<inp2:m_RenderElement name="grid_pagination_elem" pass_params="1"/>
</inp2:m_if>
</td>
</tr>
</table>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_column_title_html">
<table style="width: auto" class="layout-only-table"><tr>
<td style="vertical-align: middle; padding: 0px">
<a
href="javascript:resort_grid('<inp2:m_param name="PrefixSpecial"/>','<inp2:m_param name="sort_field"/>', <inp2:m_param name="ajax"/>);"
class="columntitle_small"
title="<inp2:m_Phrase name='la_col_SortBy' no_editing='1' html_escape='1'/> <inp2:m_if check='m_Param' name='use_phrases'><inp2:m_Phrase name='$title' no_editing='1' html_escape='1'/><inp2:m_else/><inp2:m_Param name='title'/></inp2:m_if>">
<img
alt="<inp2:m_Phrase name='la_col_SortBy' no_editing='1' html_escape='1'/> <inp2:m_if check='m_Param' name='use_phrases'><inp2:m_Phrase name='$title' no_editing='1' html_escape='1'/><inp2:m_else/><inp2:m_Param name='title'/></inp2:m_if>"
src="img/list_arrow_<inp2:Order field='$sort_field'/>.gif" width="15" height="15" border="0" align="absmiddle"
/>
</a>
</td>
<td style="vertical-align: middle; text-align: left; padding: 1px; white-space: normal">
<a
href="javascript:resort_grid('<inp2:m_param name="PrefixSpecial"/>','<inp2:m_param name="sort_field"/>', <inp2:m_param name="ajax"/>);"
class="columntitle_small"
title="<inp2:m_Phrase name='la_col_SortBy' no_editing='1' html_escape='1'/> <inp2:m_if check='m_Param' name='use_phrases'><inp2:m_Phrase name='$title' no_editing='1' html_escape='1'/><inp2:m_else/><inp2:m_Param name='title'/></inp2:m_if>">
<inp2:m_if check="m_Param" name="use_phrases"><inp2:m_Phrase name="$title"/><inp2:m_else/><inp2:m_Param name="title"/></inp2:m_if>
</a>
</td>
</tr></table>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_selector_icon_html" selector="checkbox">
<div style="white-space: nowrap;">
<inp2:m_if check="m_Param" name="selector">
<input type="<inp2:m_Param name='selector'/>" name="<inp2:InputName field='$IdField' IdField='$IdField'/>" id="<inp2:InputName field='$IdField' IdField='$IdField'/>">
</inp2:m_if>
<inp2:ItemIcon name="module" grid="$grid" result_to_var="icon_module"/>
<img src="<inp2:ModulePath module='$icon_module'/>img/itemicons/<inp2:ItemIcon grid='$grid'/>" width="16" height="16" alt=""/>
</div>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_selector_html" selector="checkbox">
<inp2:m_if check="m_Param" name="selector">
<input type="<inp2:m_Param name='selector'/>" name="<inp2:InputName field='$IdField' IdField='$IdField'/>" id="<inp2:InputName field='$IdField' IdField='$IdField'/>">
</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_select_all_checkbox_html">
<input type="checkbox" onclick="Grids['<inp2:m_param name="PrefixSpecial"/>'].InvertSelection(); this.checked=false;" ondblclick="Grids['<inp2:m_param name="PrefixSpecial"/>'].ClearSelection(); this.checked=false;" />
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_column_title" use_phrases="1">
'<inp2:m_RenderElement name="grid_column_title_html" pass_params="1" js_escape="1"/>'<inp2:m_if check="m_Param" name="is_last" inverse="1">,</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_column_title_no_sorting" use_phrases="1">
'<inp2:m_if check="m_ParamEquals" name="use_phrases" value="1"><inp2:m_phrase name="$title" js_escape="1"/><inp2:m_else/><inp2:m_param name="title" js_escape="1"/></inp2:m_if>'<inp2:m_if check="m_Param" name="is_last" inverse="1">,</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_js_data_td" format="" no_special="1" nl2br="" first_chars="" td_style="">
'<inp2:m_RenderElement name="$data_block" pass_params="1" js_escape="1"/>'<inp2:m_if check="m_Param" name="is_last" inverse="1">,</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_js_filter_block" use_phrases="0">
'<inp2:m_RenderElement name="$filter_block" pass_params="1" js_escape="1"/>'<inp2:m_if check="m_Param" name="is_last" inverse="1">,</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_js_width_td" format="" width="" no_special="1" nl2br="" first_chars="" td_style="">
<inp2:m_Param name="width" js_escape="1"/><inp2:m_if check="m_Param" name="is_last" inverse="1">,</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid" main_prefix="" per_page="" main_special="" grid_filters=""
search="on"
header_block="grid_column_title"
filter_block="grid_column_filter"
data_block="grid_data_td"
totals_block="grid_total_td"
row_block="_row"
ajax="0"
totals="0"
limited_heights="false"
max_row_height="45"
grid_height="auto"
selector="checkbox"
grid_status="1"
totals_render_as=""
>
<!--##
grid_filters - show individual filters for each column
has_filters - draw filter section in "View" menu in toolbar
##-->
<inp2:InitList pass_params="1"/> <!--## this is to avoid recalling prefix as an item in first iterate grid, by col-picker for instance ##-->
<inp2:{$PrefixSpecial}_SaveWarning name="grid_save_warning" pass_params="1"/>
<inp2:m_if check="{$PrefixSpecial}_SearchActive" grid="$grid">
<table width="100%" border="0" cellspacing="0" cellpadding="4" class="warning-table">
<tr>
<td valign="top" class="form-warning">
<inp2:m_phrase name="la_Warning_Filter"/>
</td>
</tr>
</table>
</inp2:m_if>
<div id="grid_<inp2:m_Param name='PrefixSpecial'/>_container"></div>
<inp2:m_if check="m_Param" name="grid_status">
<inp2:m_RenderElement name="grid_status" grid="$grid" PrefixSpecial="$PrefixSpecial" main_special="$main_special" search="$search" ajax="$ajax"/>
</inp2:m_if>
<inp2:m_if check="m_ParamEquals" name="ajax" value="0">
<inp2:m_if check="m_GetEquals" name="fw_menu_included" value="">
- <link rel="stylesheet" rev="stylesheet" href="incs/nlsmenu.css" type="text/css" />
- <script type="text/javascript" src="js/nlsmenu.js"></script>
- <script type="text/javascript" src="js/nlsmenueffect_1_2_1.js"></script>
+ <link rel="stylesheet" rev="stylesheet" href="<inp2:m_Compress files='incs/nlsmenu.css'/>" type="text/css" />
+ <script type="text/javascript" src="<inp2:m_Compress files='js/nlsmenu.js|js/nlsmenueffect_1_2_1.js'/>"></script>
<script type="text/javascript">
var menuMgr = new NlsMenuManager("mgr");
menuMgr.timeout = 500;
menuMgr.flowOverFormElement = true;
</script>
<inp2:m_set fw_menu_included="1"/>
</inp2:m_if>
<script type="text/javascript">
<inp2:m_RenderElement name="grid_js" mouseover_class="grid-data-row-mouseover" selected_class="grid-data-row-selected:grid-data-row-even-selected" tag_name="tr" pass_params="true"/>
</script>
</inp2:m_if>
<input type="hidden" id="<inp2:m_param name="PrefixSpecial"/>_Sort1" name="<inp2:m_param name="PrefixSpecial"/>_Sort1" value="">
<input type="hidden" id="<inp2:m_param name="PrefixSpecial"/>_Sort1_Dir" name="<inp2:m_param name="PrefixSpecial"/>_Sort1_Dir" value="asc">
</inp2:m_DefineElement>
<inp2:m_DefineElement name="default_sorting_element" ajax="0">
<div style="text-align: center;">
<a href="#" onclick="reset_sorting('<inp2:m_Param name="prefix"/>', <inp2:m_param name="ajax"/>); return false;" title="<inp2:m_phrase name="la_col_ResetToDefaultSorting" html_escape="1"/>">
<img src="img/list_arrow_<inp2:m_if check='{$prefix}_OrderChanged'>no<inp2:m_else/>desc</inp2:m_if>_big.gif" width="16" height="16" alt="<inp2:m_phrase name="la_col_ResetToDefaultSorting" html_escape="1"/>"/>
</a>
</div>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_total_row">
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].SetFooter(
[
['&nbsp;', <inp2:IterateGridFields grid="$grid" mode="total" force_block="$totals_block" ajax="$ajax"/>]
]
);
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_js"
main_prefix="" per_page="" main_special="" grid_filters=""
header_block="grid_column_title"
filter_block="grid_column_filter"
data_block="grid_data_td"
totals_block="grid_total_td"
row_block="_row"
ajax="0"
totals="0"
limited_heights="false"
max_row_height="45"
grid_height="auto"
grid_status="1" ajax="1"
totals_render_as=""
selector="checkbox"
mouseover_class="grid-data-row-mouseover" selected_class="grid-data-row-selected:grid-data-row-even-selected" tag_name="tr"
>
<inp2:GridSelector grid="$grid" default="$selector" result_to_var="selector"/>
// 1. create grid
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'] = new GridScroller('grid_<inp2:m_Param name="PrefixSpecial" />', 'auto', <inp2:m_if check="m_Param" name="grid_height" equals_to="auto">'<inp2:m_Param name="grid_height"/>'<inp2:m_else/><inp2:m_Param name="grid_height"/></inp2:m_if>);
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].Spacer = 'img/spacer.gif';
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].LeftCells = <inp2:FreezerPosition grid="$grid"/>;
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].BottomOffset = <inp2:m_if check="m_Param" name="grid_status">30<inp2:m_else/>0</inp2:m_if>;
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].MinWidths = [<inp2:GridSelectorColumnWidth selector="$selector" icon_width="20" selector_width="30" grid="$grid"/>, <inp2:IterateGridFields grid="$grid" mode="width" block="grid_js_width_td" ajax="$ajax"/>];
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].PickerCRC = '<inp2:PickerCRC grid="$grid"/>';
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].LimitedHeights = <inp2:m_param name="limited_heights"/>;
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].MaxRowHeight = <inp2:m_param name="max_row_height"/>;
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].SetHeader(
[
[' <inp2:m_RenderElement name="default_sorting_element" prefix="$PrefixSpecial" ajax="$ajax" js_escape="1" strip_nl="2"/>', <inp2:IterateGridFields grid="$grid" mode="header" block="$header_block" ajax="$ajax"/>],
['<inp2:m_if check="m_Param" name="selector" equals_to="checkbox"><inp2:m_RenderElement name="grid_select_all_checkbox_html" pass_params="1" js_escape="1"/><inp2:m_else/>&nbsp;</inp2:m_if>', <inp2:IterateGridFields grid="$grid" mode="filter" force_block="grid_js_filter_block" ajax="$ajax"/>]
]
)
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].FieldNames = ['_CheckboxColumn', <inp2:IterateGridFields grid="$grid" mode="fields"/>];
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].SetData(
[
<inp2:m_DefineElement name="js_row" td_style="" row_class_render_as="" selector_render_as="grid_selector_html" row_class="">
{ 'row_class': '<inp2:m_if check="m_Param" name="row_class_render_as"><inp2:m_RenderElement name="$row_class_render_as" PrefixSpecial="$PrefixSpecial" trim="1"/><inp2:m_else/><inp2:m_Param name="row_class"/></inp2:m_if>',
'data': ['<inp2:m_RenderElement name="$selector_render_as" pass_params="1" js_escape="1"/>',<inp2:IterateGridFields grid="$grid" mode="data" force_block="grid_js_data_td"/>]
}<inp2:m_if check="m_Param" name="is_last" inverse="1">,</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_set {$PrefixSpecial}_sequence="1" odd_even="table-color1"/>
<inp2:m_if check="UseItemIcons" grid="$grid">
<inp2:PrintList block="js_row" selector_render_as="grid_selector_icon_html" per_page="$per_page" main_special="$main_special" selector="$selector" grid="$grid"/>
<inp2:m_else/>
<inp2:PrintList block="js_row" selector_render_as="grid_selector_html" per_page="$per_page" main_special="$main_special" selector="$selector" grid="$grid"/>
</inp2:m_if>
]
)
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].IDs = [
<inp2:m_DefineElement name="js_id">
'<inp2:m_param name="PrefixSpecial"/>_<inp2:Field field="$IdField"/>'<inp2:m_if check="m_Param" name="is_last" inverse="1">,</inp2:m_if>
</inp2:m_DefineElement>
<inp2:PrintList block="js_id" per_page="$per_page" main_special="$main_special"/>
]
<inp2:m_if check="m_Param" name="totals_render_as">
<inp2:m_RenderElement name="$totals_render_as" pass_params="1"/>
</inp2:m_if>
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].Render('grid_<inp2:m_Param name="PrefixSpecial" />_container');
<inp2:m_ifnot check="m_Param" name="ajax">
<inp2:m_RenderElement name="grid_search_buttons" pass_params="1"/>
</inp2:m_ifnot>
GridScrollers['<inp2:m_param name="PrefixSpecial"/>'].SaveURL = '<inp2:m_t pass="m,$PrefixSpecial" {$PrefixSpecial}_event="OnSaveWidths" widths="#WIDTHS#" no_amp="1" grid_name="$grid"/>';
<inp2:m_if check="m_Param" name="selector">
// 2. scan grid (only when using selector)
Grids['<inp2:m_param name="PrefixSpecial"/>'] = new Grid('<inp2:m_param name="PrefixSpecial"/>', '<inp2:m_param name="selected_class"/>', ':original', ($allow_dbl_click === undefined || $allow_dbl_click ? edit : function() {}) , a_toolbar);
Grids['<inp2:m_param name="PrefixSpecial"/>'].MouseOverClass = '<inp2:m_param name="mouseover_class"/>';
Grids['<inp2:m_param name="PrefixSpecial"/>'].StickySelection = true;
Grids['<inp2:m_param name="PrefixSpecial"/>'].AddItemsByIdMask('<inp2:m_param name="tag_name"/>', /^<inp2:m_param name="PrefixSpecial"/>_([\d\w-=]+)/, '<inp2:m_param name="PrefixSpecial"/>[$$ID$$][<inp2:m_param name="IdField"/>]');
Grids['<inp2:m_param name="PrefixSpecial"/>'].InitItems();
<inp2:m_if check="m_Param" name="selector" equals_to="radio">
Grids['<inp2:m_param name="PrefixSpecial"/>'].EnableRadioMode();
</inp2:m_if>
<inp2:m_if check="{$PrefixSpecial}_UseAutoRefresh">
function refresh_grid() {
// window.location.reload();
var $window_url = window.location.href;
if ($window_url.indexOf('skip_session_refresh=1') == -1) {
$window_url += '&skip_session_refresh=1';
}
window.location.href = $window_url;
}
setTimeout('refresh_grid()', <inp2:{$PrefixSpecial}_AutoRefreshInterval/> * 60000);
</inp2:m_if>
</inp2:m_if>
<inp2:m_RenderElement name="nlsmenu_declaration" pass_params="true"/>
$ViewMenus = new Array('<inp2:m_param name="PrefixSpecial"/>');
</inp2:m_DefineElement>
<inp2:m_DefineElement name="old_grid" main_prefix="" per_page="" main_special="" grid_filters="" search="on" header_block="grid_column_title" filter_block="grid_column_filter" data_block="grid_data_td" totals_block="grid_total_td" row_block="_row" ajax="0" totals="0" selector="checkbox">
<!--##
DEPRICATED. LEFT FOR EDUCATION PURPOSES.
grid_filters - show individual filters for each column
has_filters - draw filter section in "View" menu in toolbar
##-->
<inp2:InitList pass_params="1"/> <!--## this is to avoid recalling prefix as an item in first iterate grid, by col-picker for instance ##-->
<inp2:GridSelector grid="$grid" default="$selector" result_to_var="selector"/>
<inp2:{$PrefixSpecial}_SaveWarning name="grid_save_warning" main_prefix="$main_prefix"/>
<inp2:m_if check="{$PrefixSpecial}_SearchActive" grid="$grid">
<table width="100%" border="0" cellspacing="0" cellpadding="4" class="warning-table" >
<tr>
<td valign="top" class="hint_red">
<inp2:m_phrase name="la_Warning_Filter"/>
</td>
</tr>
</table>
</inp2:m_if>
<inp2:m_if check="m_ParamEquals" name="per_page" value="-1" inverse="1">
<inp2:m_RenderElement name="grid_pagination" grid="$grid" PrefixSpecial="$PrefixSpecial" main_special="$main_special" search="$search" ajax="$ajax"/>
</inp2:m_if>
<table width="100%" cellspacing="0" cellpadding="4" class="bordered">
<inp2:m_if check="m_ParamEquals" name="grid_filters" value="1">
<tr class="pagination_bar">
<inp2:{$PrefixSpecial}_IterateGridFields grid="$grid" mode="filter" block="$filter_block" ajax="$ajax"/>
</tr>
</inp2:m_if>
<tr class="grid-header-row grid-header-row-1">
<inp2:{$PrefixSpecial}_IterateGridFields grid="$grid" mode="header" block="$header_block" ajax="$ajax"/>
</tr>
<inp2:m_DefineElement name="_row" td_style="">
<tr class="<inp2:m_odd_even odd="grid-data-row grid-data-row-even" even="grid-data-row"/>" id="<inp2:m_param name="PrefixSpecial"/>_<inp2:Field field="$IdField"/>" sequence="<inp2:m_get param="{$PrefixSpecial}_sequence"/>"><inp2:m_inc param="{$PrefixSpecial}_sequence" by="1"/>
<inp2:IterateGridFields grid="$grid" mode="data" block="$data_block"/>
</tr>
</inp2:m_DefineElement>
<inp2:m_set {$PrefixSpecial}_sequence="1" odd_even="table-color1"/>
<inp2:{$PrefixSpecial}_PrintList block="$row_block" per_page="$per_page" main_special="$main_special" />
<inp2:m_DefineElement name="grid_total_td">
<inp2:m_if check="m_Param" name="total">
<td style="<inp2:m_param name="td_style"/>">
<inp2:FieldTotal name="$field" function="$total"/>
</td>
<inp2:m_else/>
<td style="<inp2:m_param name="td_style"/>">&nbsp;</td>
</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_if check="m_ParamEquals" name="totals" value="1">
<tr class="totals-row"/>
<inp2:IterateGridFields grid="$grid" mode="data" block="$totals_block"/>
</tr>
</inp2:m_if>
</table>
<inp2:m_if check="m_ParamEquals" name="ajax" value="0">
<inp2:m_if check="m_GetEquals" name="fw_menu_included" value="">
- <script type="text/javascript" src="incs/fw_menu.js"></script>
-
- <link rel="stylesheet" rev="stylesheet" href="incs/nlsmenu.css" type="text/css" />
- <script type="text/javascript" src="js/nlsmenu.js"></script>
- <script type="text/javascript" src="js/nlsmenueffect_1_2_1.js"></script>
+ <link rel="stylesheet" rev="stylesheet" href="<inp2:m_Compress files='incs/nlsmenu.css'/>" type="text/css" />
+ <script type="text/javascript" src="<inp2:m_Compress files='js/nlsmenu.js|js/nlsmenueffect_1_2_1.js'/>"></script>
<script type="text/javascript">
var menuMgr = new NlsMenuManager("mgr");
menuMgr.timeout = 500;
menuMgr.flowOverFormElement = true;
</script>
<inp2:m_set fw_menu_included="1"/>
</inp2:m_if>
<script type="text/javascript">
<inp2:m_RenderElement name="old_grid_js" mouseover_class="grid-data-row-mouseover" selected_class="grid-data-row-selected:grid-data-row-even-selected" tag_name="tr" pass_params="true"/>
</script>
</inp2:m_if>
<input type="hidden" id="<inp2:m_param name="PrefixSpecial"/>_Sort1" name="<inp2:m_param name="PrefixSpecial"/>_Sort1" value="">
<input type="hidden" id="<inp2:m_param name="PrefixSpecial"/>_Sort1_Dir" name="<inp2:m_param name="PrefixSpecial"/>_Sort1_Dir" value="asc">
</inp2:m_DefineElement>
<inp2:m_DefineElement name="old_grid_js" selector="checkbox" ajax="1">
<!--## DEPRICATED. LEFT FOR EDUCATION PURPOSES. ##-->
<inp2:GridSelector grid="$grid" default="$selector" result_to_var="selector"/>
<inp2:m_if check="m_Param" name="selector">
Grids['<inp2:m_param name="PrefixSpecial"/>'] = new Grid('<inp2:m_param name="PrefixSpecial"/>', 'grid-data-row-selected:grid-data-row-even-selected', ':original', edit, a_toolbar);
Grids['<inp2:m_param name="PrefixSpecial"/>'].MouseOverClass = 'grid-data-row-mouseover';
Grids['<inp2:m_param name="PrefixSpecial"/>'].StickySelection = true;
Grids['<inp2:m_param name="PrefixSpecial"/>'].AddItemsByIdMask('<inp2:m_param name="tag_name"/>', /^<inp2:m_param name="PrefixSpecial"/>_([\d\w-]+)/, '<inp2:m_param name="PrefixSpecial"/>[$$ID$$][<inp2:m_param name="IdField"/>]');
Grids['<inp2:m_param name="PrefixSpecial"/>'].InitItems();
<inp2:m_if check="m_Param" name="selector" equals_to="radio">
Grids['<inp2:m_param name="PrefixSpecial"/>'].EnableRadioMode();
</inp2:m_if>
</inp2:m_if>
<inp2:m_RenderElement name="nlsmenu_declaration" pass_params="true"/>
$ViewMenus = new Array('<inp2:m_param name="PrefixSpecial"/>');
</inp2:m_DefineElement>
<inp2:m_DefineElement name="grid_ml_selector">
<inp2:m_if check="lang_IsMultiLanguage">
<inp2:m_phrase name="la_fld_Language"/>:
<select name="language" onchange="submit_event('<inp2:m_param name='prefix'/>', 'OnPreSaveAndChangeLanguage');">
<inp2:m_DefineElement name="lang_elem">
<option value="<inp2:Field name='LanguageId'/>" <inp2:m_if check="SelectedLanguage" type="data">selected="selected"</inp2:m_if> ><inp2:Field name="LocalName" no_special='no_special' /></option>
</inp2:m_DefineElement>
<inp2:lang_PrintList render_as="lang_elem"/>
</select>
<inp2:m_else/>
<inp2:m_if check="m_Param" name="pagination">
<inp2:$prefix_SelectParam possible_names="pagination_prefix,prefix" result_to_var="pagination_prefix"/>
<inp2:m_RenderElement name="grid_pagination_elem" PrefixSpecial="$pagination_prefix" pass_params="1"/>
</inp2:m_if>
</inp2:m_if>
</inp2:m_DefineElement>
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/incs/header.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/incs/header.tpl (revision 13486)
+++ branches/5.1.x/core/admin_templates/incs/header.tpl (revision 13487)
@@ -1,109 +1,113 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<inp2:m_CheckSSL mode="required" condition="Require_AdminSSL" />
<inp2:m_CheckSSL/>
<inp2:m_DefaultParam body_properties=""/>
<html>
<head>
<title><inp2:m_GetConfig var="Site_Name"/> - <inp2:m_Phrase label="la_AdministrativeConsole"/></title>
<meta http-equiv="content-type" content="text/html; charset=<inp2:lang_GetCharset/>"/>
<meta name="keywords" content="..."/>
<meta name="description" content="..."/>
<meta name="robots" content="all"/>
<meta name="copyright" content="In-Portal CMS, Copyright &#174; 2009"/>
<meta name="author" content="Intechnic Inc."/>
<inp2:m_base_ref/>
<link rel="icon" href="img/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
-<inp2:adm_AdminSkin/>
+<inp2:adm_AdminSkin file_only="1" result_to_var="skin_css"/>
-<link rel="stylesheet" href="js/jquery/thickbox/thickbox.css" type="text/css" media="screen" />
+<link rel="stylesheet" href="<inp2:m_Compress files='
+ js/jquery/thickbox/thickbox.css|
+ js/calendar/calendar-blue.css|
+ $skin_css
+'/>" type="text/css" media="screen" />
<script type="text/javascript" src="js/jquery/jquery.pack.js"></script>
<script type="text/javascript" src="js/jquery/jquery-ui.custom.min.js"></script>
-<script type="text/javascript" src="js/is.js"></script>
-<script type="text/javascript" src="js/ajax.js"></script>
-<script type="text/javascript" src="js/application.js"></script>
-<script type="text/javascript" src="js/script.js"></script>
-<script type="text/javascript" src="js/in-portal.js"></script>
-<script type="text/javascript" src="js/toolbar.js"></script>
-<script type="text/javascript" src="js/grid.js"></script>
-<script type="text/javascript" src="js/simple_grid.js"></script>
-<script type="text/javascript" src="js/grid_scroller.js"></script>
-<script type="text/javascript" src="js/forms.js"></script>
-<script type="text/javascript" src="js/drag.js"></script>
-<script type="text/javascript" src="js/ajax_dropdown.js"></script>
-<script type="text/javascript" src="js/form_controls.js"></script>
-
-<script type="text/javascript" src="js/jquery/thickbox/thickbox.js"></script>
-<script type="text/javascript" src="js/tab_scroller.js"></script>
-
-<link rel="stylesheet" rev="stylesheet" href="js/calendar/calendar-blue.css" type="text/css" />
-<script type="text/javascript" src="js/calendar/calendar.js"></script>
-<script type="text/javascript" src="js/calendar/calendar-setup.js"></script>
-<script type="text/javascript" src="js/calendar/calendar-en.js"></script>
+<script type="text/javascript" src="<inp2:m_Compress files='
+ js/is.js|
+ js/ajax.js|
+ js/application.js|
+ js/script.js|
+ js/in-portal.js|
+ js/toolbar.js|
+ js/grid.js|
+ js/simple_grid.js|
+ js/grid_scroller.js|
+ js/forms.js|
+ js/drag.js|
+ js/ajax_dropdown.js|
+ js/form_controls.js|
+ js/jquery/thickbox/thickbox.js|
+ js/tab_scroller.js|
+ js/calendar/calendar.js|
+ js/calendar/calendar-setup.js|
+ js/calendar/calendar-en.js
+'/>"></script>
+
<script type="text/javascript">
TB.pathToImage = 'js/jquery/thickbox/loadingAnimation.gif';
var t = '<inp2:m_get param="t"/>';
var popups = '1';
var $use_popups = <inp2:m_if check="adm_UsePopups">true<inp2:m_else/>false</inp2:m_if>;
var $modal_windows = <inp2:m_if check="adm_UsePopups" mode="modal">true<inp2:m_else/>false</inp2:m_if>;
var multiple_windows = '1';
var main_title = '<inp2:m_GetConfig var="Site_Name" escape="1"/>';
var tpl_changed = 0;
var base_url = '<inp2:m_BaseURL/>';
var $base_path = '<inp2:m_GetConst name="BASE_PATH"/>';
var img_path = '<inp2:m_TemplatesBase module="#MODULE#"/>/img/';
var phrases = {
'la_Delete_Confirm' : '<inp2:m_Phrase label="la_Delete_Confirm" js_escape="1"/>'
}
NumberFormatter.ThousandsSep = '<inp2:lang.current_Field name="ThousandSep" js_escape="1"/>';
NumberFormatter.DecimalSep = '<inp2:lang.current_Field name="DecimalPoint" js_escape="1"/>';
<inp2:m_if check="m_GetEquals" name="m_wid" value="" inverse="inverse">
if (!window.name.match(/_<inp2:m_get name="m_wid"/>$/)) {
window.name += '_<inp2:m_get name="m_wid"/>'; // change window name only once per window
if ($modal_windows) {
getFrame('main').TB.setWindowMetaData('window_name', window.name); // used to simulate window.opener functionality
}
}
</inp2:m_if>
var $use_toolbarlabels = <inp2:m_if check="adm_UseToolbarLabels">true<inp2:m_else/>false</inp2:m_if>;
</script>
<inp2:m_if check="m_get" var="m_wid">
<style type="text/css">
.tableborder {
border: none;
}
.toolbar {
border-right: none;
border-left: none;
}
.tableborder_full {
border-right: none;
border-left: none;
}
</style>
</inp2:m_if>
</head>
<inp2:m_include t="incs/blocks"/>
<inp2:m_include t="incs/in-portal"/>
<inp2:m_if check="m_ParamEquals" name="nobody" value="yes" inverse="inverse">
<body class="<inp2:m_if check="m_get" var="m_wid">edit-popup<inp2:m_else/>regular-body</inp2:m_if>" <inp2:m_param name="body_properties"/>>
</inp2:m_if>
<inp2:m_if check="m_ParamEquals" name="noform" value="yes" inverse="inverse">
<inp2:m_RenderElement name="kernel_form"/>
</inp2:m_if>
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/catalog/catalog.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/catalog/catalog.tpl (revision 13486)
+++ branches/5.1.x/core/admin_templates/catalog/catalog.tpl (revision 13487)
@@ -1,304 +1,306 @@
<inp2:m_include t="incs/header" noform="yes"/>
<inp2:m_include template="catalog/catalog_elements"/>
<inp2:m_RenderElement name="combined_header" section="in-portal:browse" prefix="c" title_preset="catalog" tabs="catalog/catalog_tabs" additional_blue_bar_render_as="theme_selector"/>
<!-- main kernel_form: begin -->
<inp2:m_RenderElement name="kernel_form"/>
<!-- ToolBar -->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<input type="hidden" name="m_cat_id" value="<inp2:m_get name="m_cat_id"/>"/>
- <link rel="stylesheet" rev="stylesheet" href="incs/nlsmenu.css" type="text/css" />
- <script type="text/javascript" src="js/nlsmenu.js"></script>
- <script type="text/javascript" src="js/nlsmenueffect_1_2_1.js"></script>
+ <link rel="stylesheet" rev="stylesheet" href="<inp2:m_Compress files='incs/nlsmenu.css'/>" type="text/css" />
+ <script type="text/javascript" src="<inp2:m_Compress files='
+ js/nlsmenu.js|
+ js/nlsmenueffect_1_2_1.js|
+ js/catalog.js
+ '/>"></script>
- <script type="text/javascript" src="js/catalog.js"></script>
<script type="text/javascript">
<inp2:m_if check="adm_CheckPermCache">
$(document).ready(
function() {
Application.SetVar('continue', 1);
openSelector('c', '<inp2:m_t t="categories/cache_updater" pass="m"/>');
}
);
</inp2:m_if>
var menuMgr = new NlsMenuManager("mgr");
menuMgr.timeout = 500;
menuMgr.flowOverFormElement = true;
Request.progressText = '<inp2:m_phrase name="la_title_Loading" no_editing="1" escape="1"/>';
var $is_catalog = true;
var $Catalog = new Catalog('<inp2:m_Link template="#TEMPLATE_NAME#" m_cat_id="#CATEGORY_ID#" no_amp="1"/>', 'catalog_', 'Catalog');
$Catalog.TabByCategory = <inp2:m_if check="m_GetConfig" name="Catalog_PreselectModuleTab">true<inp2:m_else/>false</inp2:m_if>;
var a_toolbar = new ToolBar();
a_toolbar.AddButton(
new ToolBarButton(
'upcat',
'<inp2:m_phrase label="la_ToolTip_Up" escape="1"/>::<inp2:m_phrase label="la_ShortToolTip_GoUp" escape="1"/>',
function() {
$Catalog.go_to_cat($Catalog.ParentCategoryID);
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'homecat',
'<inp2:m_phrase label="la_ToolTip_Home" escape="1"/>',
function() {
$Catalog.go_to_cat(<inp2:c_HomeCategory/>);
}
)
);
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
<inp2:m_ModuleInclude template="catalog_tab" tab_init="1" replace_m="yes"/>
a_toolbar.AddButton(
new ToolBarButton(
'edit',
'<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>',
edit
)
);
a_toolbar.AddButton(
new ToolBarButton(
'delete',
'<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
function() {
var $template = $Catalog.queryTabRegistry('prefix', $Catalog.getCurrentPrefix(), 'view_template');
std_delete_items($Catalog.getCurrentPrefix(), $template, 1);
}
)
);
<inp2:m_ModuleInclude template="catalog_buttons" main_template="catalog"/>
a_toolbar.AddButton( new ToolBarSeparator('sep2') );
a_toolbar.AddButton(
new ToolBarButton(
'approve',
'<inp2:m_phrase label="la_ToolTip_Approve" escape="1"/>',
function() {
askCategoryPropagate();
$Catalog.submit_event(null, 'OnMassApprove');
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'decline',
'<inp2:m_phrase label="la_ToolTip_Decline" escape="1"/>',
function() {
askCategoryPropagate();
$Catalog.submit_event(null, 'OnMassDecline');
}
)
);
function askCategoryPropagate() {
if ($Catalog.getCurrentPrefix() == 'c') {
var $propagate_status = confirm('<inp2:m_Phrase name="la_msg_PropagateCategoryStatus" escape="1"/>');
$form_name = $Catalog.queryTabRegistry('prefix', 'c', 'tab_id') + '_form';
Application.SetVar('propagate_category_status', $propagate_status ? 1 : 0);
}
}
a_toolbar.AddButton( new ToolBarSeparator('sep3') );
a_toolbar.AddButton(
new ToolBarButton(
'cut',
'<inp2:m_phrase label="la_ToolTip_Cut" escape="1"/>',
function() {
$Catalog.submit_event(null, 'OnCut');
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'copy',
'<inp2:m_phrase label="la_ToolTip_Copy" escape="1"/>',
function() {
$Catalog.submit_event(null, 'OnCopy');
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'paste',
'<inp2:m_phrase label="la_ToolTip_Paste" escape="1"/>',
function() {
submit_event('c', 'OnPasteClipboard', 'catalog/catalog');
/*$Catalog.submit_event(
'c', 'OnPasteClipboard', null,
function($object) {
$object.resetTabs(true);
$object.switchTab();
}
);*/
}
)
);
/*a_toolbar.AddButton( new ToolBarButton('clear_clipboard', '<inp2:m_phrase label="la_ToolTip_ClearClipboard" escape="1"/>', function() {
if (confirm('<inp2:m_phrase name="la_text_ClearClipboardWarning" js_escape="1"/>')) {
$Catalog.submit_event('c', 'OnClearClipboard', null, function($object) {
$GridManager.CheckDependencies($object.ActivePrefix);
} );
}
}
) );*/
a_toolbar.AddButton( new ToolBarSeparator('sep5') );
a_toolbar.AddButton(
new ToolBarButton(
'move_up',
'<inp2:m_phrase label="la_ToolTip_MoveUp" escape="1"/>::<inp2:m_phrase label="la_ToolTipShort_Move_Up" escape="1"/>',
function() {
$Catalog.submit_event(null, 'OnMassMoveUp');
}
)
);
a_toolbar.AddButton(
new ToolBarButton(
'move_down',
'<inp2:m_phrase label="la_ToolTip_MoveDown" escape="1"/>::<inp2:m_phrase label="la_ToolTipShort_Move_Down" escape="1"/>',
function() {
$Catalog.submit_event(null, 'OnMassMoveDown');
}
)
);
a_toolbar.AddButton( new ToolBarSeparator('sep6') );
a_toolbar.AddButton(
new ToolBarButton(
'tools',
'<inp2:m_Phrase label="la_ToolTip_Tools" escape="1"/>',
function() {
var $menu = menuMgr.createMenu(rs('tools_menu'));
$menu.applyBorder(false, false, false, false);
$menu.dropShadow('none');
$menu.showIcon = true;
$menu.addItem(rs('editcat'), '<inp2:m_Phrase name="la_ToolTip_Edit_Current_Category" js_escape="1"/>', 'javascript:executeButton("editcat");');
$menu.addItem(rs('export'), '<inp2:m_Phrase name="la_ToolTip_Export" js_escape="1"/>', 'javascript:executeButton("export");');
$menu.addSeparator();
$menu.addItem(rs('rebuild_cache'), '<inp2:m_Phrase name="la_ToolTip_RebuildCategoryCache" js_escape="1"/>', 'javascript:executeButton("rebuild_cache");');
if ($Catalog.ActivePrefix == 'c') {
$menu.addItem(rs('recalculate_priorities'), '<inp2:m_Phrase name="la_ToolTip_RecalculatePriorities" js_escape="1"/>', 'javascript:executeButton("recalculate_priorities");');
}
renderMenus();
nls_showMenu(rs('tools_menu'), a_toolbar.GetButtonImage('tools'));
}
)
);
function executeButton($button_name) {
switch ($button_name) {
case 'editcat':
var $edit_url = '<inp2:m_t t="#TEMPLATE#" m_opener="d" c_mode="t" c_event="OnEdit" c_id="#CATEGORY_ID#" pass="all,c" no_amp="1"/>';
var $category_id = get_hidden_field('m_cat_id');
var $redirect_url = $edit_url.replace('#CATEGORY_ID#', $category_id);
$redirect_url = $redirect_url.replace('#TEMPLATE#', $category_id == 0 || $category_id == <inp2:c_HomeCategory/> ? 'categories/categories_edit_permissions' : 'categories/categories_edit');
direct_edit('c', $redirect_url);
break;
case 'export':
var $export_templates = <inp2:c_PrintCatalogExportTemplates prefixes="l,n,p"/>;
if ($export_templates[$Catalog.ActivePrefix] != undefined) {
$Catalog.storeIDs('export_categories');
open_popup($Catalog.ActivePrefix, 'OnExport', $export_templates[$Catalog.ActivePrefix]);
}
else {
alert('<inp2:m_phrase name="la_Text_InDevelopment" escape="1"/>');
}
break;
case 'rebuild_cache':
openSelector('c', '<inp2:m_t t="categories/cache_updater" pass="m"/>');
break;
case 'recalculate_priorities':
$Catalog.submit_event('c', 'OnRecalculatePriorities');
break;
}
}
a_toolbar.AddButton(
new ToolBarButton(
'view',
'<inp2:m_phrase label="la_ToolTip_View" escape="1"/>',
function() {
show_viewmenu(a_toolbar, 'view');
}
)
);
a_toolbar.Render();
function edit() {
var $current_prefix = $Catalog.getCurrentPrefix();
$form_name = $Catalog.queryTabRegistry('prefix', $current_prefix, 'tab_id') + '_form';
std_edit_item($current_prefix, $Catalog.queryTabRegistry('prefix', $current_prefix, 'edit_template'));
}
function add_item() {
var $current_prefix = $Catalog.getCurrentPrefix();
$form_name = $Catalog.queryTabRegistry('prefix', $current_prefix, 'tab_id') + '_form';
std_precreate_item($current_prefix, $Catalog.queryTabRegistry('prefix', $current_prefix, 'edit_template'));
}
</script>
</td>
<inp2:m_RenderElement name="catalog_search_box"/>
</tr>
</tbody>
</table>
<inp2:m_RenderElement name="kernel_form_end"/>
<!-- main kernel_form: end -->
<inp2:m_ModuleInclude template="catalog_tab" tab_init="2" strip_nl="2"/>
<script type="text/javascript">
var $menu_frame = getFrame('menu');
if (typeof $menu_frame.ShowStructure != 'undefined') {
<inp2:m_DefineElement name="structure_node"><inp2:m_param name="section_url"/></inp2:m_DefineElement>
$menu_frame.ShowStructure('<inp2:adm_PrintSection escape="1" render_as="structure_node" section_name="in-portal:browse"/>', true);
}
Application.setHook(
'm:OnAfterWindowLoad',
function() {
$Catalog.Init();
getFrame('head').$('#extra_toolbar').html('<inp2:m_RenderElement name="extra_toolbar" js_escape="1"/>');
}
);
</script>
<inp2:m_include t="incs/footer" noform="yes"/>
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/catalog/advanced_view.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/catalog/advanced_view.tpl (revision 13486)
+++ branches/5.1.x/core/admin_templates/catalog/advanced_view.tpl (revision 13487)
@@ -1,146 +1,149 @@
<inp2:m_include t="incs/header" noform="yes"/>
<inp2:m_include template="catalog/catalog_elements"/>
<inp2:m_RenderElement name="combined_header" section="in-portal:browse" prefix="c" title_preset="advanced_view" tabs="catalog/catalog_tabs" special=".showall" additional_blue_bar_render_as="theme_selector"/>
<!-- main kernel_form: begin -->
<inp2:m_RenderElement name="kernel_form"/>
<!-- ToolBar -->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<input type="hidden" name="m_cat_id" value="<inp2:m_get name="m_cat_id"/>"/>
- <link rel="stylesheet" rev="stylesheet" href="incs/nlsmenu.css" type="text/css" />
- <script type="text/javascript" src="js/nlsmenu.js"></script>
- <script type="text/javascript" src="js/nlsmenueffect_1_2_1.js"></script>
- <script type="text/javascript" src="js/catalog.js"></script>
+ <link rel="stylesheet" rev="stylesheet" href="<inp2:m_Compress files='incs/nlsmenu.css'/>" type="text/css" />
+ <script type="text/javascript" src="<inp2:m_Compress files='
+ js/nlsmenu.js|
+ js/nlsmenueffect_1_2_1.js|
+ js/catalog.js
+ '/>"></script>
+
<script type="text/javascript">
<inp2:m_if check="adm_CheckPermCache">
$(document).ready(
function() {
Application.SetVar('continue', 1);
openSelector('c', '<inp2:m_t t="categories/cache_updater" pass="m"/>');
}
);
</inp2:m_if>
var menuMgr = new NlsMenuManager("mgr");
menuMgr.timeout = 500;
menuMgr.flowOverFormElement = true;
Request.progressText = '<inp2:m_phrase name="la_title_Loading" no_editing="1" escape="1"/>';
Catalog.prototype.AfterInit = function() {
this.switchTab();
}
var $Catalog = new Catalog('<inp2:m_Link template="#TEMPLATE_NAME#" pass_through="ts,td" ts="showall" td="no" m_cat_id="#CATEGORY_ID#" no_amp="1"/>', 'advanced_view_', 'AdvancedView');
var a_toolbar = new ToolBar();
<inp2:m_set ts="showall" td="no"/>
<inp2:m_ModuleInclude template="catalog_tab" tab_init="1" replace_m="yes"/>
a_toolbar.AddButton( new ToolBarButton('edit', '<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>', edit) );
a_toolbar.AddButton( new ToolBarButton('delete', '<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
function() {
var $template = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'view_template');
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + ']', 1);
std_delete_items($Catalog.ActivePrefix, $template, 1);
} ) );
<inp2:m_ModuleInclude template="catalog_buttons" main_template="advanced_view"/>
a_toolbar.AddButton( new ToolBarSeparator('sep2') );
a_toolbar.AddButton( new ToolBarButton('approve', '<inp2:m_phrase label="la_ToolTip_Approve" escape="1"/>', function() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + ']', 1);
$Catalog.submit_event($Catalog.ActivePrefix, 'OnMassApprove');
}
) );
a_toolbar.AddButton( new ToolBarButton('decline', '<inp2:m_phrase label="la_ToolTip_Decline" escape="1"/>', function() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + ']', 1);
$Catalog.submit_event($Catalog.ActivePrefix, 'OnMassDecline');
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep3') );
a_toolbar.AddButton( new ToolBarButton('view', '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>', function() {
show_viewmenu(a_toolbar, 'view');
}
) );
a_toolbar.Render();
function edit() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
var $kf = document.getElementById($form_name);
var $prev_action = $kf.action;
$kf.action = '<inp2:m_t pass="all" no_pass_through="1"/>';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + ']', 1);
std_edit_item(
$Catalog.ActivePrefix, $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'edit_template'),
function() {
$kf.action = $prev_action;
}
);
}
function add_item() {
$form_name = $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'tab_id') + '_form';
var $kf = document.getElementById($form_name);
var $prev_action = $kf.action;
$kf.action = '<inp2:m_t pass="all" no_pass_through="1"/>';
set_hidden_field('remove_specials[' + $Catalog.ActivePrefix + ']', 1);
std_precreate_item(
$Catalog.ActivePrefix, $Catalog.queryTabRegistry('prefix', $Catalog.ActivePrefix, 'edit_template'),
function() {
$kf.action = $prev_action;
}
);
}
</script>
</td>
<inp2:m_RenderElement name="catalog_search_box"/>
</tr>
</tbody>
</table>
<inp2:m_RenderElement name="kernel_form_end"/>
<!-- main kernel_form: end -->
<inp2:m_set ts="showall" td="no"/>
<inp2:m_ModuleInclude template="catalog_tab" tab_init="2"/>
<script type="text/javascript">
var $menu_frame = getFrame('menu');
if (typeof $menu_frame.ShowStructure != 'undefined') {
<inp2:m_DefineElement name="structure_node"><inp2:m_param name="section_url"/></inp2:m_DefineElement>
$menu_frame.ShowStructure('<inp2:adm_PrintSection escape="1" render_as="structure_node" section_name="in-portal:browse"/>', false);
}
Application.setHook(
'm:OnAfterWindowLoad',
function() {
$Catalog.Init();
<inp2:m_if check="m_get" var="SetTab">
$Catalog.switchTab('<inp2:m_get var="SetTab"/>.showall');
</inp2:m_if>
getFrame('head').$('#extra_toolbar').html('<inp2:m_RenderElement name="extra_toolbar" js_escape="1"/>');
}
);
</script>
<inp2:m_include t="incs/footer" noform="yes"/>
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/catalog/item_selector/item_selector_toolbar.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/catalog/item_selector/item_selector_toolbar.tpl (revision 13486)
+++ branches/5.1.x/core/admin_templates/catalog/item_selector/item_selector_toolbar.tpl (revision 13487)
@@ -1,68 +1,70 @@
-<script type="text/javascript" src="js/ajax.js"></script>
-<link rel="stylesheet" rev="stylesheet" href="incs/nlsmenu.css" type="text/css" />
-<script type="text/javascript" src="js/nlsmenu.js"></script>
-<script type="text/javascript" src="js/nlsmenueffect_1_2_1.js"></script>
-<script type="text/javascript" src="js/catalog.js"></script>
+<link rel="stylesheet" rev="stylesheet" href="<inp2:m_Compress files='incs/nlsmenu.css'/>" type="text/css" />
+<script type="text/javascript" src="<inp2:m_Compress files='
+ js/nlsmenu.js|
+ js/nlsmenueffect_1_2_1.js|
+ js/catalog.js
+'/>"></script>
+
<script type="text/javascript">
var menuMgr = new NlsMenuManager("mgr");
menuMgr.timeout = 500;
menuMgr.flowOverFormElement = true;
Request.progressText = '<inp2:m_phrase name="la_title_Loading" no_editing="1" escape="1"/>';
var a_toolbar = new ToolBar();
a_toolbar.AddButton( new ToolBarButton('select', '<inp2:m_phrase label="la_ToolTip_Save" escape="1"/>', function() {
<inp2:m_if check="m_ParamEquals" name="is_catalog" value="1">
active_selected = '';
if (Grids[$Catalog.ActivePrefix]) {
active_selected = Grids[$Catalog.ActivePrefix].GetSelected();
set_hidden_field('selected_ids[' + $Catalog.ActivePrefix + ']', active_selected);
}
if (active_selected.length == 0) {
var $category_ids = Grids['c'].GetSelected();
if ($category_ids.length == 0) {
// no categories selected, then use current category
$category_ids = get_hidden_field('m_cat_id');
}
set_hidden_field('selected_ids[c]', $category_ids);
}
<inp2:m_else/>
var $prefix = $Catalog.ActivePrefix.replace('.<inp2:m_get name="ts"/>', '');
set_hidden_field('selected_ids[' + $prefix + ']', Grids[$Catalog.ActivePrefix].GetSelected());
</inp2:m_if>
submit_event('<inp2:m_Recall name="main_prefix"/>', 'OnProcessSelected');
}
) );
a_toolbar.AddButton( new ToolBarButton('cancel', '<inp2:m_phrase label="la_ToolTip_Cancel" escape="1"/>', function() {
window_close();
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
<inp2:m_if check="m_ParamEquals" name="is_catalog" value="1">
a_toolbar.AddButton( new ToolBarButton('upcat', '<inp2:m_phrase label="la_ToolTip_Up" escape="1"/>', function() {
$Catalog.go_to_cat($Catalog.ParentCategoryID);
}
) );
a_toolbar.AddButton( new ToolBarButton('homecat', '<inp2:m_phrase label="la_ToolTip_Home" escape="1"/>', function() {
$Catalog.go_to_cat(<inp2:c_HomeCategory/>);
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep2') );
</inp2:m_if>
a_toolbar.AddButton( new ToolBarButton('view', '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>', function() {
show_viewmenu(a_toolbar, 'view');
}
) );
a_toolbar.Render();
function edit()
{
}
</script>
\ No newline at end of file

Event Timeline