Index: units/categories/categories_event_handler.php =================================================================== --- units/categories/categories_event_handler.php (revision 14653) +++ units/categories/categories_event_handler.php (working copy) @@ -17,7 +17,7 @@ class CategoriesEventHandler extends kDBEventHandler { /** - * Allows to override standart permission mapping + * Allows to override standard permission mapping * */ function mapPermissions() @@ -253,7 +253,7 @@ $object->SetDBField($this->Application->RecallVar('dst_field'), $selected_ids['c']); $object->Update(); - $this->finalizePopup($event); + $event->SetRedirectParam('opener', 'u'); } /** @@ -330,10 +330,13 @@ $object->addFilter('perm_filter', TABLE_PREFIX . 'PermCache.PermId = 1'); // check for CATEGORY.VIEW permission if ($this->Application->RecallVar('user_id') != USER_ROOT) { // apply permission filters to all users except "root" + $view_filters = Array (); $groups = explode(',',$this->Application->RecallVar('UserGroups')); + foreach ($groups as $group) { $view_filters[] = 'FIND_IN_SET('.$group.', ' . TABLE_PREFIX . 'PermCache.ACL)'; } + $view_filter = implode(' OR ', $view_filters); $object->addFilter('perm_filter2', $view_filter); } @@ -512,9 +515,10 @@ 'advanced' => 'OnAdvancedSearch' ); + $keywords = $event->getEventParam('keyword_string'); $type = $this->Application->GetVar('search_type', 'simple'); - if ($keywords = $event->getEventParam('keyword_string')) { + if ( $keywords ) { // processing keyword_string param of ListProducts tag $this->Application->SetVar('keywords', $keywords); $type = 'simple'; @@ -654,9 +658,9 @@ return $page_id; } - function ParentGetPassedId(&$event) + function ParentGetPassedID(&$event) { - return parent::GetPassedId($event); + return parent::getPassedID($event); } /** @@ -759,6 +763,18 @@ break; } } + + // remember category filename change between temp and live records + if ( $temp_object->GetDBField('Filename') != $live_object->GetDBField('Filename') ) { + $filename_changes = $this->Application->GetVar($event->Prefix . '_filename_changes', Array ()); + + $filename_changes[ $live_object->GetID() ] = Array ( + 'from' => $live_object->GetDBField('Filename'), + 'to' => $temp_object->GetDBField('Filename') + ); + + $this->Application->SetVar($event->Prefix . '_filename_changes', $filename_changes); + } } /** @@ -845,6 +861,23 @@ } } } + + // change opener stack in case if edited category filename was changed + $filename_changes = $this->Application->GetVar($event->Prefix . '_filename_changes', Array ()); + + if ( $filename_changes ) { + $opener_stack =& $this->Application->makeClass('kOpenerStack'); + /* @var $opener_stack kOpenerStack */ + + list ($template, $params, $index_file) = $opener_stack->pop(); + + foreach ($filename_changes as $change_info) { + $template = str_ireplace($change_info['from'], $change_info['to'], $template); + } + + $opener_stack->push($template, $params, $index_file); + $opener_stack->save(); + } } /** @@ -976,7 +1009,7 @@ /** * Deletes all selected items. - * Automatically recurse into sub-items using temp handler, and deletes sub-items + * Automatically recourse into sub-items using temp handler, and deletes sub-items * by calling its Delete method if sub-item has AutoDelete set to true in its config file * * @param kEvent $event @@ -992,8 +1025,9 @@ $to_delete = Array (); $ids = $this->StoreSelectedIDs($event); + $recycle_bin = $this->Application->ConfigValue('RecycleBinFolder'); - if ( $recycle_bin = $this->Application->ConfigValue('RecycleBinFolder') ) { + if ( $recycle_bin ) { $rb =& $this->Application->recallObject('c.recycle', null, Array ('skip_autoload' => true)); /* @var $rb CategoriesItem */ @@ -1066,7 +1100,7 @@ } /** - * Controls all item paste operations. Can occur only with filled clipbord. + * Controls all item paste operations. Can occur only with filled clipboard. * * @param kEvent $event */ @@ -1232,7 +1266,7 @@ }*/ /** - * Cleares clipboard content + * Clears clipboard content * * @param kEvent $event */ @@ -1648,8 +1682,8 @@ /** * Sets page name to requested field in case when: - * 1. page was auto created (through theme file rebuld) - * 2. requested field is emtpy + * 1. page was auto created (through theme file rebuild) + * 2. requested field is empty * * @param kDBItem $object * @param string $field @@ -1711,7 +1745,7 @@ } if (($page_type == PAGE_TYPE_TEMPLATE) && ($template_info === false)) { - // do not autocreate system pages, when browsing through site + // do not auto-create system pages, when browsing through site return false; } @@ -1798,7 +1832,7 @@ $backup_category_id = $this->Application->GetVar('m_cat_id'); $object =& $this->Application->recallObject($this->Prefix . '.rebuild-path', null, Array ('skip_autoload' => true)); - /* @var $object kDBItem */ + /* @var $object CategoriesItem */ $parent_id = $base_category; @@ -1883,7 +1917,13 @@ $event->SetRedirectParam('action_completed', 1); } - function _resetMenuCache() + /** + * Performs reset of category-related caches (menu, structure dropdown, template mapping) + * + * @return void + * @access protected + */ + protected function _resetMenuCache() { // reset cms menu cache (all variables are automatically rebuild, when missing) if ($this->Application->isCachingType(CACHING_TYPE_MEMORY)) { @@ -1920,19 +1960,19 @@ $root_category = $this->Application->getBaseCategory(); // set root category - $section_ajustments = $this->Application->getUnitOption($event->Prefix, 'SectionAdjustments'); + $section_adjustments = $this->Application->getUnitOption($event->Prefix, 'SectionAdjustments'); - $section_ajustments['in-portal:browse'] = Array ( + $section_adjustments['in-portal:browse'] = Array ( 'url' => Array ('m_cat_id' => $root_category), 'late_load' => Array ('m_cat_id' => $root_category), 'onclick' => 'checkCatalog(' . $root_category . ')', ); - $section_ajustments['in-portal:browse_site'] = Array ( + $section_adjustments['in-portal:browse_site'] = Array ( 'url' => Array ('editing_mode' => $settings['default_editing_mode']), ); - $this->Application->setUnitOption($event->Prefix, 'SectionAdjustments', $section_ajustments); + $this->Application->setUnitOption($event->Prefix, 'SectionAdjustments', $section_adjustments); // prepare structure dropdown $category_helper =& $this->Application->recallObject('CategoryHelper'); @@ -1944,15 +1984,9 @@ $fields['ParentId']['options'] = $category_helper->getStructureTreeAsOptions(); // limit design list by theme - $design_folders = Array ('tf.FilePath = "/designs"', 'tf.FilePath = "/platform/designs"'); - foreach ($this->Application->ModuleInfo as $module_name => $module_info) { - $design_folders[] = 'tf.FilePath = "/' . $module_info['TemplatePath'] . 'designs"'; - } - $design_folders = array_unique($design_folders); - $theme_id = $this->_getCurrentThemeId(); $design_sql = $fields['Template']['options_sql']; - $design_sql = str_replace('(tf.FilePath = "/designs")', '(' . implode(' OR ', $design_folders) . ')' . ' AND (t.ThemeId = ' . $theme_id . ')', $design_sql); + $design_sql = str_replace('(tf.FilePath = "/designs")', '(' . implode(' OR ', $this->getDesignFolders()) . ')' . ' AND (t.ThemeId = ' . $theme_id . ')', $design_sql); $fields['Template']['options_sql'] = $design_sql; // adds "Inherit From Parent" option to "Template" field @@ -1988,6 +2022,23 @@ } /** + * Returns folders, that can contain design templates + * + * @return array + * @access protected + */ + protected function getDesignFolders() + { + $ret = Array ('tf.FilePath = "/designs"', 'tf.FilePath = "/platform/designs"'); + + foreach ($this->Application->ModuleInfo as $module_info) { + $ret[] = 'tf.FilePath = "/' . $module_info['TemplatePath'] . 'designs"'; + } + + return array_unique($ret); + } + + /** * Removes this item and it's children (recursive) from structure dropdown * * @param kEvent $event @@ -2045,7 +2096,7 @@ ini_set('memory_limit', -1); $dummy =& $this->Application->recallObject($event->Prefix . '.rebuild', null, Array ('skip_autoload' => true)); - /* @var $dummy kDBItem */ + /* @var $dummy CategoriesItem */ $error_count = 0; foreach ($files as $a_file => $file_info) { @@ -2205,7 +2256,9 @@ } // processing fields from other tables - if ($foreign_field = $search_config[$field]['ForeignField']) { + $foreign_field = $search_config[$field]['ForeignField']; + + if ( $foreign_field ) { $exploded = explode(':', $foreign_field, 2); if ($exploded[0] == 'CALC') { // ignoring having type clauses in simple search @@ -2380,7 +2433,7 @@ WHERE '.$where_clause.' GROUP BY '.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField').' ORDER BY Relevance DESC'; - $res = $this->Conn->Query($sql); + $this->Conn->Query($sql); if ( !$search_table_exists ) { $sql = 'ALTER TABLE ' . $search_table . ' @@ -2459,7 +2512,7 @@ */ protected function OnGetConstrainInfo(&$event) { - $contarain = ''; // for OnSave + $constrain = ''; // for OnSave $event_name = $event->getEventParam('original_event'); $actual_event_name = $event->getEventParam('actual_event'); @@ -2468,18 +2521,18 @@ $object =& $event->getObject(); /* @var $object kDBItem */ - $contarain = 'ParentId = ' . $object->GetDBField('ParentId'); + $constrain = 'ParentId = ' . $object->GetDBField('ParentId'); } elseif ( $actual_event_name == 'OnPreparePriorities' ) { - $contarain = 'ParentId = ' . $this->Application->GetVar('m_cat_id'); + $constrain = 'ParentId = ' . $this->Application->GetVar('m_cat_id'); } elseif ( $event_name == 'OnSave' ) { - $contarain = ''; + $constrain = ''; } else { - $contarain = 'ParentId = ' . $this->Application->GetVar('m_cat_id'); + $constrain = 'ParentId = ' . $this->Application->GetVar('m_cat_id'); } - $event->setEventParam('constrain_info', Array ($contarain, '')); + $event->setEventParam('constrain_info', Array ($constrain, '')); } } \ No newline at end of file Index: kernel/utility/opener_stack.php =================================================================== --- kernel/utility/opener_stack.php (revision 0) +++ kernel/utility/opener_stack.php (revision 0) @@ -0,0 +1,194 @@ +windowID = isset($window_id) ? $window_id : $this->Application->GetVar('m_wid'); + $this->load(); + } + + /** + * Returns window id, that was finally used by opener stack + * + * @return int + * @access public + */ + public function getWindowID() + { + return $this->windowID; + } + + /** + * Returns session variable name, used to store opener stack + * + * @return string + * @access protected + */ + protected function getVariableName() + { + return rtrim('opener_stack_' . $this->windowID, '_'); + } + + /** + * Loads opener stack data from session + * + * @return void + * @access protected + */ + protected function load() + { + $stack_name = $this->getVariableName(); + $opener_stack = $this->Application->RecallVar($stack_name); + + $this->data = $opener_stack ? unserialize($opener_stack) : Array (); + } + + /** + * Stores updated opener stack to session + * + * @param bool $remove_on_empty + * @return void + */ + public function save($remove_on_empty = false) + { + if ( $remove_on_empty ) { + if ( $this->data ) { + $this->Application->StoreVar($this->getVariableName(), serialize($this->data)); + } + else { + $this->Application->RemoveVar($this->getVariableName()); + } + } + else { + $this->Application->StoreVar($this->getVariableName(), serialize($this->data), !$this->data); + } + } + + /** + * Returns opener stack element at given position + * + * @param int $index Position of element in opener stack. Negative number will retrieve element from the end. + * @param bool $raw + * @return Array|string {$template, $params, $index_file} + * @access public + */ + public function get($index, $raw = false) + { + if ( $index < 0 ) { + $index += count($this->data); + } + + if ( !$this->data || !isset($this->data[$index]) ) { + return Array ('', Array (), null); + } + + if ( $raw ) { + return $this->data[$index]; + } + + list ($index_file, $env) = explode('|', $this->data[$index], 2); + $params = $this->Application->HttpQuery->processQueryString($env, 'pass'); + + $template = kUtil::popParam('t', $params, ''); + + return Array ($template, $params, $index_file); + } + + /** + * Parses last opener stack element and returns it + * + * @param bool $raw + * @return Array {$template, $params, $index_file} + * @access public + */ + public function pop($raw = false) + { + $ret = $this->get(self::LAST_ELEMENT, $raw); + array_pop($this->data); + + return $ret; + } + + /** + * Adds new opener stack element + * + * @param string $template + * @param Array $params + * @param string $index_file + * @return void + * @access public + */ + public function push($template = '', $params = Array (), $index_file = null) + { + $pass_events = kUtil::popParam('pass_events', $params, true); + + $new_level = $this->Application->BuildEnv($template, $params, $params['pass'], $pass_events, false); + $this->data[] = $index_file . '|' . $new_level; + } + + /** + * Adds new opener stack element as raw string + * + * @param $data + * @return void + * @access public + */ + public function pushRaw($data) + { + $this->data[] = $data; + } + + /** + * Resets opener stack content + * + * @return void + * @access public + */ + public function reset() + { + $this->data = Array (); + } +} \ No newline at end of file Property changes on: kernel\utility\opener_stack.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: kernel/managers/request_manager.php =================================================================== --- kernel/managers/request_manager.php (revision 14663) +++ kernel/managers/request_manager.php (working copy) @@ -277,16 +277,12 @@ */ protected function processOpener() { - $wid = $this->Application->GetVar('m_wid'); + $opener_stack =& $this->Application->makeClass('kOpenerStack'); + /* @var $opener_stack kOpenerStack */ - $opener_action = $this->Application->GetVar('m_opener'); - $opener_stack = $this->Application->RecallVar(rtrim('opener_stack_'.$wid, '_')); - $opener_stack = $opener_stack ? unserialize($opener_stack) : Array(); - - switch ($opener_action) { + switch ( $this->Application->GetVar('m_opener') ) { case 'r': - // "reset" opener stack - $opener_stack = Array (); + $opener_stack->reset(); break; case 'd': @@ -295,16 +291,16 @@ $front_session =& $this->Application->recallObject('Session.front'); /* @var $front_session Session */ - array_push( $opener_stack, '../' . $front_session->RecallVar('last_template') ); + $opener_stack->pushRaw( '../' . $front_session->RecallVar('last_template') ); } else { - array_push( $opener_stack, $this->Application->RecallVar('last_template') ); + $opener_stack->pushRaw( $this->Application->RecallVar('last_template') ); } break; case 'u': // "up/pop" last template from opener stack, deeplevel-- - array_pop($opener_stack); + $opener_stack->pop(); break; case 'p': @@ -314,40 +310,20 @@ $this->Application->StoreVar('last_wid', $popup_wid); $this->Application->SetVar('m_wid', $popup_wid); - if ( $this->Application->GetVar('front') ) { - $front_session =& $this->Application->recallObject('Session.front'); - /* @var $front_session Session */ + $popup_opener_stack =& $this->Application->makeClass('kOpenerStack', Array ($popup_wid)); + /* @var $popup_opener_stack kOpenerStack */ - $last_template = '../' . $front_session->RecallVar( rtrim('last_template_popup_' . $parent_wid, '_') ); - } - else { - if ( $this->Application->GetVar('merge_opener_stack') ) { - // get last template from parent (that was closed) window opener stack - $parent_opener_stack_name = rtrim('opener_stack_' . $parent_wid, '_'); - $parent_opener_stack = unserialize( $this->Application->RecallVar($parent_opener_stack_name) ); - $last_template = array_pop($parent_opener_stack); + $popup_opener_stack->pushRaw( $this->getLastTemplate($parent_wid) ); + $popup_opener_stack->save(); - if ($parent_opener_stack) { - $this->Application->StoreVar( $parent_opener_stack_name, serialize($parent_opener_stack) ); - } - else { - $this->Application->RemoveVar( $parent_opener_stack_name ); - } - } - else { - $last_template = $this->Application->RecallVar( rtrim('last_template_popup_' . $parent_wid, '_') ); - } - } - - $opener_stack = Array ($last_template); $this->Application->SetVar('m_opener', 's'); - $wid = $popup_wid; /*// store window relations $window_relations = $this->Application->RecallVar('window_relations'); $window_relations = $window_relations ? unserialize($window_relations) : Array (); $window_relations[$popup_wid] = $parent_wid; $this->Application->StoreVar('window_relations', serialize($window_relations));*/ + return; break; default: @@ -356,85 +332,105 @@ } $this->Application->SetVar('m_opener', 's'); - $this->Application->StoreVar(rtrim('opener_stack_' . $wid, '_'), serialize($opener_stack), !$opener_stack); // empty stack is optional + $opener_stack->save(); } /** + * Returns last template from window with given id + * + * @param int $window_id + * @return string + * @access protected + */ + protected function getLastTemplate($window_id) + { + if ( $this->Application->GetVar('front') ) { + $front_session =& $this->Application->recallObject('Session.front'); + /* @var $front_session Session */ + + return '../' . $front_session->RecallVar( rtrim('last_template_popup_' . $window_id, '_') ); + } + + if ( $this->Application->GetVar('merge_opener_stack') ) { + // get last template from parent (that was closed) window opener stack + $parent_opener_stack =& $this->Application->makeClass('kOpenerStack', Array ($window_id)); + /* @var $parent_opener_stack kOpenerStack */ + + $last_template = $parent_opener_stack->pop(true); + $parent_opener_stack->save(true); + } + else { + $last_template = $this->Application->RecallVar( rtrim('last_template_popup_' . $window_id, '_') ); + } + + return $last_template; + } + + /** * Allows to add new element to opener stack * * @param string $template * @param Array $params - * @param string $pass + * @param int $wid * @access public */ - public function openerStackPush($template, $params, $pass = 'all', $wid = null) + public function openerStackPush($template = '', $params = Array (), $wid = null) { - if (!isset($wid)) { - $wid = $this->Application->GetVar('m_wid'); + if ( !isset($params['pass']) ) { + $params['pass'] = 'all'; } /*// get parent window wid, when this was popup $window_relations = $this->Application->RecallVar('window_relations'); $window_relations = $window_relations ? unserialize($window_relations) : Array (); - $wid = array_key_exists($wid, $window_relations) ? $window_relations[$wid] : false;*/ + $wid = isset($window_relations[$wid]) ? $window_relations[$wid] : false;*/ - // get opener stack - $stack_name = rtrim('opener_stack_' . $wid, '_'); - $opener_stack = $this->Application->RecallVar($stack_name); - $opener_stack = $opener_stack ? unserialize($opener_stack) : Array (); + $opener_stack =& $this->Application->makeClass('kOpenerStack', Array ($wid)); + /* @var $opener_stack kOpenerStack */ // change opener stack $default_params = Array ('m_opener' => 'u', '__URLENCODE__' => 1); - if (!$this->Application->ConfigValue('UsePopups') && $wid) { + if ( !$this->Application->ConfigValue('UsePopups') && $opener_stack->getWindowID() ) { // remove wid to show combined header block in editing window $default_params['m_wid'] = ''; + list ($last_template, $last_params, ) = $opener_stack->get(kOpenerStack::LAST_ELEMENT); - // move last popup's opener stack elemenent to main window's opener stack - if ($opener_stack) { - list ($index_file, $env) = explode('|', $opener_stack[ count($opener_stack) - 1 ], 2); - $main_params = $this->Application->HttpQuery->processQueryString($env, 'pass'); - $main_template = $main_params['t']; - unset($main_params['t']); - - $main_params = array_merge($main_params, $default_params); - $this->openerStackPush($main_template, $main_params, $main_params['pass'], ''); + // move last popup's opener stack element to main window's opener stack + if ( $last_params ) { + $last_params = array_merge($last_params, $default_params); + $this->openerStackPush($last_template, $last_params, ''); } } - $redirect_params = array_merge($default_params, $params); - $new_level = $this->Application->BuildEnv($template, $redirect_params, $pass, true); - array_push($opener_stack, 'index.php|' . ltrim($new_level, ENV_VAR_NAME . '=') ); - $this->Application->StoreVar($stack_name, serialize($opener_stack)); + $params = array_merge($default_params, $params); + $opener_stack->push($template, $params, 'index.php'); + $opener_stack->save(); } /** * Allows to change last element in opener stack * - * @param string $template - * @param Array $params - * @param string $pass + * @param string $new_template + * @param Array $new_params * @access public */ - public function openerStackChange($params = Array(), $pass_events = true, $wid = null) + public function openerStackChange($new_template = null, $new_params = null) { - if (!isset($wid)) { - $wid = $this->Application->GetVar('m_wid'); - } + $opener_stack =& $this->Application->makeClass('kOpenerStack'); + /* @var $opener_stack kOpenerStack */ - // get opener stack - $stack_name = rtrim('opener_stack_' . $wid, '_'); - $opener_stack = $this->Application->RecallVar($stack_name); - $opener_stack = $opener_stack ? unserialize($opener_stack) : Array (); + list ($template, $params, $index_file) = $opener_stack->pop(); - // change opener stack - list ($index_file, $env) = explode('|', $opener_stack[ count($opener_stack) - 1 ], 2); - $vars = $this->Application->HttpQuery->processQueryString($env, 'pass'); - $vars = array_merge($vars, $params); + if ( isset($new_template) ) { + $template = $new_template; + } - // save opener stack - $new_level = $this->Application->BuildEnv($vars['t'], $vars, $vars['pass'], $pass_events, false); - $opener_stack[ count($opener_stack) - 1 ] = $index_file . '|' . $new_level; - $this->Application->StoreVar($stack_name, serialize($opener_stack)); + if ( isset($new_params) ) { + $params = array_merge($params, $new_params); + } + + $opener_stack->push($template, $params, $index_file); + $opener_stack->save(); } } \ No newline at end of file Index: kernel/globals.php =================================================================== --- kernel/globals.php (revision 14653) +++ kernel/globals.php (working copy) @@ -640,6 +640,26 @@ return 'application/octet-stream'; } + + /** + * Return param value and removes it from params array + * + * @param string $name + * @param Array $params + * @param bool $default + * @return string + */ + public static function popParam($name, &$params, $default = false) + { + if ( isset($params[$name]) ) { + $value = $params[$name]; + unset($params[$name]); + + return $value; + } + + return $default; + } } /** Index: kernel/event_manager.php =================================================================== --- kernel/event_manager.php (revision 14653) +++ kernel/event_manager.php (working copy) @@ -318,25 +318,23 @@ * * @param string $template * @param Array $params - * @param string $pass * @access public */ - public function openerStackPush($template, $params, $pass = 'all', $wid = null) + public function openerStackPush($template = '', $params = Array ()) { - $this->Request->openerStackPush($template, $params, $pass, $wid); + $this->Request->openerStackPush($template, $params); } /** * Allows to change last element in opener stack * - * @param string $template - * @param Array $params - * @param string $pass + * @param string $new_template + * @param Array $new_params * @access public */ - public function openerStackChange($params = Array(), $pass_events = true, $wid = null) + public function openerStackChange($new_template = null, $new_params = null) { - $this->Request->openerStackChange($params, $pass_events, $wid); + $this->Request->openerStackChange($new_template, $new_params); } /** Index: kernel/application.php =================================================================== --- kernel/application.php (revision 14654) +++ kernel/application.php (working copy) @@ -704,6 +704,7 @@ $this->registerClass('PhrasesCache', KERNEL_PATH . '/languages/phrases_cache.php', 'kPhraseCache'); $this->registerClass('kTempTablesHandler', KERNEL_PATH . '/utility/temp_handler.php'); $this->registerClass('kValidator', KERNEL_PATH . '/utility/validator.php'); + $this->registerClass('kOpenerStack', KERNEL_PATH . '/utility/opener_stack.php'); $this->registerClass('kUnitConfigReader', KERNEL_PATH . '/utility/unit_config_reader.php'); @@ -1314,14 +1315,16 @@ } /** - * Stores variable $val in session under name $var - * - * Use this method to store variable in session. Later this variable could be recalled. - * @see RecallVar - * @access public - * @param string $var Variable name - * @param mixed $val Variable value - */ + * Stores variable $val in session under name $var + * + * Use this method to store variable in session. Later this variable could be recalled. + * + * @param string $var Variable name + * @param mixed $val Variable value + * @param bool $optional + * @see kApplication::RecallVar() + * @access public + */ function StoreVar($var, $val, $optional = false) { $session =& $this->recallObject('Session');