Index: branches/5.3.x/core/units/categories/categories_event_handler.php =================================================================== diff -u -N -r15810 -r15902 --- branches/5.3.x/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 15810) +++ branches/5.3.x/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 15902) @@ -1,6 +1,6 @@ addFilter('perm_filter', TABLE_PREFIX . 'CategoryPermissionsCache.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')); + $this->applyViewPermissionFilter($object); - foreach ($groups as $group) { - $view_filters[] = 'FIND_IN_SET('.$group.', ' . TABLE_PREFIX . 'CategoryPermissionsCache.ACL)'; - } - - $view_filter = implode(' OR ', $view_filters); - $object->addFilter('perm_filter2', $view_filter); - } - if (!$this->Application->isAdminUser) { // apply status filter only on front $object->addFilter('status_filter', $object->TableName.'.Status = 1'); @@ -564,6 +552,35 @@ } /** + * Adds filter, that uses *.VIEW permissions to determine if an item should be shown to a user. + * + * @param kDBList $object Object. + * + * @return void + * @access protected + */ + protected function applyViewPermissionFilter(kDBList $object) + { + if ( !$this->Application->ConfigValue('CheckViewPermissionsInCatalog') ) { + return; + } + + if ( $this->Application->RecallVar('user_id') == USER_ROOT ) { + // for "root" CATEGORY.VIEW permission is checked for items lists too + $view_perm = 1; + } + else { + $count_helper = $this->Application->recallObject('CountHelper'); + /* @var $count_helper kCountHelper */ + + list ($view_perm, $view_filter) = $count_helper->GetPermissionClause($object->Prefix, 'perm'); + $object->addFilter('perm_filter2', $view_filter); + } + + $object->addFilter('perm_filter', 'perm.PermId = ' . $view_perm); // check for CATEGORY.VIEW permission + } + + /** * Returns current theme id * * @return int @@ -589,7 +606,7 @@ */ public function getPassedID(kEvent $event) { - if ( ($event->Special == 'page') || ($event->Special == '-virtual') || ($event->Prefix == 'st') ) { + if ( ($event->Special == 'page') || $this->_isVirtual($event) || ($event->Prefix == 'st') ) { return $this->_getPassedStructureID($event); } @@ -643,31 +660,6 @@ $page_id = $page_by_template[$template]; } - if ( $page_id === false && EDITING_MODE ) { - // create missing pages, when in editing mode - $object = $this->Application->recallObject($this->Prefix . '.rebuild', NULL, Array ('skip_autoload' => true)); - /* @var $object CategoriesItem */ - - $created = $this->_prepareAutoPage($object, $template, NULL, SMS_MODE_AUTO); // create virtual (not system!) page - if ( $created ) { - $rebuild_mode = $this->Application->ConfigValue('CategoryPermissionRebuildMode'); - - if ( $rebuild_mode == CategoryPermissionRebuild::SILENT || !$this->Application->isAdmin ) { - $updater = $this->Application->makeClass('kPermCacheUpdater'); - /* @var $updater kPermCacheUpdater */ - - $updater->OneStepRun(); - } - - $this->_resetMenuCache(); - - $this->Application->RemoveVar('PermCache_UpdateRequired'); - - $page_id = $object->GetID(); - $this->Application->SetVar('m_cat_id', $page_id); - } - } - if ( $page_id ) { $page_by_template[$template] = $page_id; } @@ -695,7 +687,7 @@ */ protected function prepareObject(&$object, kEvent $event) { - if ( $event->Special == '-virtual' ) { + if ( $this->_isVirtual($event) ) { return; } @@ -713,6 +705,30 @@ } /** + * Checks, that this is virtual page + * + * @param kEvent $event + * @return int + * @access protected + */ + protected function _isVirtual(kEvent $event) + { + return strpos($event->Special, '-virtual') !== false; + } + + /** + * Gets right special for configuring virtual page + * + * @param kEvent $event + * @return string + * @access protected + */ + protected function _getCategorySpecial(kEvent $event) + { + return $this->_isVirtual($event) ? '-virtual' : $event->Special; + } + + /** * Set correct parent path for newly created categories * * @param kEvent $event @@ -1272,22 +1288,9 @@ * @return void * @access protected */ - protected function _ensurePermCacheRebuild($event) + protected function _ensurePermCacheRebuild(kEvent $event) { - $rebild_mode = $this->Application->ConfigValue('CategoryPermissionRebuildMode'); - - if ( $rebild_mode == CategoryPermissionRebuild::SILENT ) { - $updater = $this->Application->makeClass('kPermCacheUpdater'); - /* @var $updater kPermCacheUpdater */ - - $updater->OneStepRun(); - } - elseif ( $rebild_mode == CategoryPermissionRebuild::AUTOMATIC ) { - // rebuild with progress bar - $event->redirect = 'categories/cache_updater'; - } - - $this->_resetMenuCache(); + $this->Application->StoreVar('PermCache_UpdateRequired', 1); $this->Application->StoreVar('RefreshStructureTree', 1); } @@ -1432,6 +1435,50 @@ } /** + * Creates needed sql query to load item, + * if no query is defined in config for + * special requested, then use list query + * + * @param kEvent $event + * @return string + * @access protected + */ + protected function ItemPrepareQuery(kEvent $event) + { + $object = $event->getObject(); + /* @var $object kDBItem */ + + $sqls = $object->getFormOption('ItemSQLs', Array ()); + $category_special = $this->_getCategorySpecial($event); + $special = isset($sqls[$category_special]) ? $category_special : ''; + + // preferred special not found in ItemSQLs -> use analog from ListSQLs + + return isset($sqls[$special]) ? $sqls[$special] : $this->ListPrepareQuery($event); + } + + /** + * Creates needed sql query to load list, + * if no query is defined in config for + * special requested, then use default + * query + * + * @param kEvent $event + * @return string + * @access protected + */ + protected function ListPrepareQuery(kEvent $event) + { + $object = $event->getObject(); + /* @var $object kDBItem */ + + $special = $this->_getCategorySpecial($event); + $sqls = $object->getFormOption('ListSQLs', Array ()); + + return $sqls[array_key_exists($special, $sqls) ? $special : '']; + } + + /** * Performs redirect to correct suggest confirmation template * * @param kEvent $event @@ -1777,8 +1824,8 @@ $t = $this->Application->GetVar('t'); $page = $this->Application->recallObject($this->Prefix . '.-virtual'); - if ($page->isLoaded()) { - $this->Application->SetVar('m_cat_id', $page->GetDBField('CategoryId') ); + if ( $page->isLoaded() ) { + $this->Application->SetVar('m_cat_id', $page->GetDBField('CategoryId')); } }*/ @@ -2135,6 +2182,8 @@ if (defined('IS_INSTALL') && IS_INSTALL) { // skip any processing, because Categories table doesn't exists until install is finished + $this->addViewPermissionJoin($event); + return ; } @@ -2197,6 +2246,8 @@ )); } + $this->addViewPermissionJoin($event); + // add grids for advanced view (with primary category column) foreach (Array ('Default', 'Radio') as $process_grid) { $grid_data = $config->getGridByName($process_grid); @@ -2206,6 +2257,33 @@ } /** + * Adds permission table table JOIN clause only, when advanced catalog view permissions enabled. + * + * @param kEvent $event Event. + * + * @return self + * @access protected + */ + protected function addViewPermissionJoin(kEvent $event) + { + if ( $this->Application->ConfigValue('CheckViewPermissionsInCatalog') ) { + $join_clause = 'LEFT JOIN ' . TABLE_PREFIX . 'CategoryPermissionsCache perm ON perm.CategoryId = %1$s.CategoryId'; + } + else { + $join_clause = ''; + } + + $config = $event->getUnitConfig(); + + foreach ( $config->getListSQLSpecials() as $special ) { + $list_sql = str_replace('{PERM_JOIN}', $join_clause, $config->getListSQLsBySpecial($special)); + $config->setListSQLsBySpecial($special, $list_sql); + } + + return $this; + } + + /** * Returns folders, that can contain design templates * * @return array @@ -2721,7 +2799,7 @@ */ protected function LoadItem(kEvent $event) { - if ( $event->Special != '-virtual' ) { + if ( !$this->_isVirtual($event) ) { parent::LoadItem($event); return; }