From a2029711a8ad8496186c8133da7616ff9bfd3b67 Mon Sep 17 00:00:00 2001 From: andrepereiradasilva Date: Mon, 12 Sep 2016 20:03:34 +0100 Subject: [PATCH 1/6] improve component asset preload speed --- libraries/joomla/access/access.php | 87 ++++++++++++------------------ 1 file changed, 35 insertions(+), 52 deletions(-) diff --git a/libraries/joomla/access/access.php b/libraries/joomla/access/access.php index d89ac207832ad..9f89d7feec570 100644 --- a/libraries/joomla/access/access.php +++ b/libraries/joomla/access/access.php @@ -398,77 +398,60 @@ protected static function preloadPermissions($assetType) */ protected static function preloadComponents() { - // Get the database connection object. - $db = JFactory::getDbo(); - - // Build the database query: - $query = $db->getQuery(true); - $query->select('element'); - $query->from('#__extensions'); - $query->where('type = ' . $db->quote('component')); - $query->where('enabled = ' . $db->quote(1)); - - // Set the query and get the list of active components: - $db->setQuery($query); - $components = $db->loadColumn(); - - // Get a fresh query object: - $query = $db->getQuery(true); - - // Build the in clause for the queries: - $inClause = ''; - $last = end($components); + // Add root to asset names list. + $components = array(); - foreach ($components as $component) + // Add enabled components to asset names list. + foreach (JComponentHelper::getComponents() as $component) { - if ($component === $last) + if ($component->enabled) { - $inClause .= $db->quote($component); - } - else - { - $inClause .= $db->quote($component) . ','; + $components[] = $component->option; } } - // Build the database query: - $query->select('a.name, a.rules'); - $query->from('#__assets AS a'); - $query->where('(a.name IN (' . $inClause . ') OR a.name = ' . $db->quote('root.1') . ')'); + // Get the database connection object. + $db = JFactory::getDbo(); - // Get the Name Permission Map List - $db->setQuery($query); - $namePermissionMap = $db->loadAssocList('name'); + // Get the asset info for all assets in asset names list. + $query = $db->getQuery(true) + ->select($db->qn(array('name', 'rules'))) + ->from($db->qn('#__assets')) + ->where($db->qn('name') . ' IN (' . implode(',', $db->quote($components)) . ', ' . $db->quote('root.1') . ')'); - $root = array(); - $root['rules'] = ''; + // Get the Name Permission Map List + $namePermissionMap = $db->setQuery($query)->loadObjectList('name'); - if (isset($namePermissionMap['root.1'])) - { - $root = $namePermissionMap['root.1']; - unset($namePermissionMap['root.1']); - } + $rootRule = isset($namePermissionMap['root.1']) ? $namePermissionMap['root.1']->rules : '{}'; + $rootAccessRule = new JAccessRules($rootRule); // Container for all of the JAccessRules for this $assetType $rulesList = array(); - // Collects permissions for each $assetName and adds - // into the $assetRules class variable. - foreach ($namePermissionMap as $assetName => &$permissions) + // Collects permissions for each $assetName and adds into the $assetRules class variable. + foreach ($namePermissionMap as $asset) { - // Instantiate and return the JAccessRules object for the asset rules. - $rules = new JAccessRules; - $rules->mergeCollection(array($root['rules'], $permissions['rules'])); + // Do nothing for root asset. + if ($asset->name === 'root.1') + { + continue; + } - $rulesList[$assetName] = $rules; - } + $rulesList[$asset->name] = new JAccessRules; + $rulesList[$asset->name]->merge($rootAccessRule); + + // If there are no component rules, use the root asset rules. + if (!$asset->rules || $asset->rules === '{}') + { + continue; + } - unset($assetName); - unset($permissions); + // Merge the component asset rules. + $rulesList[$asset->name]->merge($asset->rules); + } // Merge our rules list with self::$assetRules self::$assetRules = self::$assetRules + $rulesList; - unset($rulesList); return $components; } From b1bf36843bf5b017a4d8f2e3ddc0e658ac76c54c Mon Sep 17 00:00:00 2001 From: andrepereiradasilva Date: Mon, 12 Sep 2016 22:50:40 +0100 Subject: [PATCH 2/6] Update user.php --- libraries/joomla/user/user.php | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/libraries/joomla/user/user.php b/libraries/joomla/user/user.php index dd5e4852e3433..9b3e79fb41326 100644 --- a/libraries/joomla/user/user.php +++ b/libraries/joomla/user/user.php @@ -350,13 +350,13 @@ public function defParam($key, $value) * object and optionally an access extension object * * @param string $action The name of the action to check for permission. - * @param string $assetname The name of the asset on which to perform the action. + * @param string $assetName The name of the asset on which to perform the action. * * @return boolean True if authorised * * @since 11.1 */ - public function authorise($action, $assetname = null) + public function authorise($action, $assetName = null) { // Make sure we only check for core.admin once during the run. if ($this->isRoot === null) @@ -364,8 +364,7 @@ public function authorise($action, $assetname = null) $this->isRoot = false; // Check for the configuration file failsafe. - $config = JFactory::getConfig(); - $rootUser = $config->get('root_user'); + $rootUser = JFactory::getConfig()->get('root_user'); // The root_user variable can be a numeric user ID or a username. if (is_numeric($rootUser) && $this->id > 0 && $this->id == $rootUser) @@ -376,22 +375,13 @@ public function authorise($action, $assetname = null) { $this->isRoot = true; } - else + elseif ($this->id > 0 && JAccess::check($this->id, 'core.admin', 'root.1')) { - // Get all groups against which the user is mapped. - $identities = $this->getAuthorisedGroups(); - array_unshift($identities, $this->id * -1); - - if (JAccess::getAssetRules(1)->allow('core.admin', $identities)) - { - $this->isRoot = true; - - return true; - } + $this->isRoot = true; } } - return $this->isRoot ? true : JAccess::check($this->id, $action, $assetname); + return $this->isRoot ? true : JAccess::check($this->id, $action, $assetName); } /** From 8f30a6a6995e5f78700b367b2955f4342da5b2b6 Mon Sep 17 00:00:00 2001 From: andrepereiradasilva Date: Tue, 13 Sep 2016 00:33:37 +0100 Subject: [PATCH 3/6] Update access.php --- libraries/joomla/access/access.php | 186 ++++++++++++++++------------- 1 file changed, 103 insertions(+), 83 deletions(-) diff --git a/libraries/joomla/access/access.php b/libraries/joomla/access/access.php index 9f89d7feec570..c50382c0f8d7e 100644 --- a/libraries/joomla/access/access.php +++ b/libraries/joomla/access/access.php @@ -109,6 +109,14 @@ class JAccess */ protected static $groupsByUser = array(); + /** + * Flag to indicate if components assets have been preloaded. + * + * @var boolean + * @since __DEPLOY_VERSION__ + */ + protected static $componentsPreloaded = false; + /** * Method for clearing static caches. * @@ -118,6 +126,7 @@ class JAccess */ public static function clearStatics() { + self::$componentsPreloaded = false; self::$viewLevels = array(); self::$assetPermissionsById = array(); self::$assetPermissionsByName = array(); @@ -146,16 +155,15 @@ public static function check($userId, $action, $asset = null, $preload = true) { // Sanitise inputs. $userId = (int) $userId; - $action = strtolower(preg_replace('#[\s\-]+#', '.', trim($action))); - $asset = strtolower(preg_replace('#[\s\-]+#', '.', trim($asset))); + $asset = strtolower(preg_replace('#[\s\-]+#', '.', trim($asset))); // Default to the root asset node. if (empty($asset)) { $db = JFactory::getDbo(); $assets = JTable::getInstance('Asset', 'JTable', array('dbo' => $db)); - $asset = $assets->getRootId(); + $asset = $assets->getRootId(); } // Auto preloads assets for the asset type: @@ -166,7 +174,6 @@ public static function check($userId, $action, $asset = null, $preload = true) if (!isset(self::$preloadedAssetTypes[$assetType])) { self::preload($assetType); - self::$preloadedAssetTypes[$assetType] = true; } } @@ -198,29 +205,26 @@ public static function check($userId, $action, $asset = null, $preload = true) */ public static function preload($assetTypes = 'components', $reload = false) { - // Get instance of the Profiler: - $profiler = JProfiler::getInstance('Application'); - // Check for default case: - $isDefault = (is_string($assetTypes) && in_array($assetTypes, array('components', 'component'))); + $isDefault = is_string($assetTypes) && in_array($assetTypes, array('components', 'component')); // Preload the rules for all of the components: - if ($isDefault) + if ($isDefault && !self::$componentsPreloaded) { // Mark in the profiler. - JDEBUG ? $profiler->mark('Start JAccess::preload(components)') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::preload(components)') : null; - $components = self::preloadComponents(); - self::$preloadedAssetTypes = array_merge(self::$preloadedAssetTypes, array_flip($components)); + self::preloadComponents(); + self::$componentsPreloaded = true; // Mark in the profiler. - JDEBUG ? $profiler->mark('Finish JAccess::preload(components)') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::preload(components)') : null; + } - // Quick short circuit for default case: - if ($isDefault) - { - return true; - } + // Quick short circuit for default case + if ($isDefault) + { + return true; } // If we get to this point, this is a regular asset type @@ -235,17 +239,12 @@ public static function preload($assetTypes = 'components', $reload = false) { if (!isset(self::$preloadedAssetTypes[$assetType]) || $reload) { - JDEBUG ? $profiler->mark('New JAccess Preloading Process(' . $assetType . ')') : null; - - self::preloadPermissionsParentIdMapping($assetType); - JDEBUG ? $profiler->mark('After preloadPermissionsParentIdMapping (' . $assetType . ')') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess Preloading Process (' . $assetType . ')') : null; self::preloadPermissions($assetType); - JDEBUG ? $profiler->mark('After preloadPermissions (' . $assetType . ')') : null; - - JDEBUG ? $profiler->mark('End New JAccess Preloading Process(' . $assetType . ')') : null; - self::$preloadedAssetTypes[$assetType] = true; + + JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess Preloading Process (' . $assetType . ')') : null; } } @@ -256,18 +255,15 @@ public static function preload($assetTypes = 'components', $reload = false) * Method to recursively retrieve the list of parent Asset IDs * for a particular Asset. * - * @param string $assetType e.g. 'com_content.article' - * @param string|int $assetId numeric Asset ID + * @param string $extensionName e.g. 'com_content.article' + * @param string|int $assetId numeric Asset ID * * @return array List of Ancestor IDs (includes original $assetId) * * @since 1.6 */ - protected static function getAssetAncestors($assetType, $assetId) + protected static function getAssetAncestors($extensionName, $assetId) { - // Get the extension name from the $assetType provided - $extensionName = self::getExtensionNameFromAsset($assetType); - // Holds the list of ancestors for the Asset ID: $ancestors = array(); @@ -308,6 +304,8 @@ protected static function getAssetAncestors($assetType, $assetId) * @return array List of Asset IDs (includes Parent Asset ID Info) * * @since 1.6 + * + * @deprecated 4.0 No used anymore. */ protected static function &preloadPermissionsParentIdMapping($assetType) { @@ -354,31 +352,42 @@ protected static function preloadPermissions($assetType) // Get the extension name from the $assetType provided $extensionName = self::getExtensionNameFromAsset($assetType); - if (!isset(self::$assetPermissionsById[$extensionName]) && !isset(self::$assetPermissionsByName[$extensionName])) + if (!isset(self::$assetPermissionsParentIdMapping[$extensionName]) + || !isset(self::$assetPermissionsById[$extensionName]) || !isset(self::$assetPermissionsByName[$extensionName])) { // Get the database connection object. $db = JFactory::getDbo(); - // Get a fresh query object: - $query = $db->getQuery(true); + $parents = implode(',', $db->q(array($extensionName, 'root.1'))); - // Build the database query: - $query->select('a.id, a.name, a.rules'); - $query->from('#__assets AS a'); - $query->where('(a.name LIKE ' . $db->quote($extensionName . '.%') . ' OR a.name = ' . $db->quote($extensionName) . ' OR a.id = 1 )'); + // Get a fresh query object: + $query = $db->getQuery(true) + ->select($db->qn(array('id', 'name', 'rules', 'parent_id'))) + ->from($db->qn('#__assets')) + ->where($db->qn('name') . ' LIKE ' . $db->q($extensionName . '.%') . ' OR ' . $db->qn('name') . ' IN (' . $parents . ')'); // Get the Name Permission Map List - $db->setQuery($query); - - $iterator = $db->getIterator(); + $assets = $db->setQuery($query)->loadObjectList('name'); - self::$assetPermissionsById[$extensionName] = array(); - self::$assetPermissionsByName[$extensionName] = array(); + self::$assetPermissionsById[$extensionName] = array(); + self::$assetPermissionsByName[$extensionName] = array(); + self::$assetPermissionsParentIdMapping[$extensionName] = array(); - foreach ($iterator as $row) + foreach ($assets as $name => $asset) { - self::$assetPermissionsById[$extensionName][$row->id] = $row; - self::$assetPermissionsByName[$extensionName][$row->name] = $row; + $permissions = new StdClass; + $permissions->id = $asset->id; + $permissions->name = $asset->name; + $permissions->rules = $asset->rules; + + self::$assetPermissionsById[$extensionName][$asset->id] = $permissions; + self::$assetPermissionsByName[$extensionName][$asset->name] = $permissions; + + $parentIdMapping = new StdClass; + $parentIdMapping->id = $asset->id; + $parentIdMapping->parent_id = $asset->parent_id; + + self::$assetPermissionsParentIdMapping[$extensionName][$asset->id] = $parentIdMapping; } } @@ -415,45 +424,59 @@ protected static function preloadComponents() // Get the asset info for all assets in asset names list. $query = $db->getQuery(true) - ->select($db->qn(array('name', 'rules'))) + ->select($db->qn(array('id', 'name', 'rules', 'parent_id'))) ->from($db->qn('#__assets')) ->where($db->qn('name') . ' IN (' . implode(',', $db->quote($components)) . ', ' . $db->quote('root.1') . ')'); // Get the Name Permission Map List - $namePermissionMap = $db->setQuery($query)->loadObjectList('name'); - - $rootRule = isset($namePermissionMap['root.1']) ? $namePermissionMap['root.1']->rules : '{}'; - $rootAccessRule = new JAccessRules($rootRule); + $assets = $db->setQuery($query)->loadObjectList('name'); - // Container for all of the JAccessRules for this $assetType - $rulesList = array(); + $rootId = $assets['root.1']->id; - // Collects permissions for each $assetName and adds into the $assetRules class variable. - foreach ($namePermissionMap as $asset) + if (!isset(self::$preloadedAssetTypes['root.1'])) { - // Do nothing for root asset. - if ($asset->name === 'root.1') - { - continue; - } + $permissionsRoot = new StdClass; + $permissionsRoot->id = $assets['root.1']->id; + $permissionsRoot->name = $assets['root.1']->name; + $permissionsRoot->rules = $assets['root.1']->rules; + + $parentRootMapping = new StdClass; + $parentRootMapping->id = $assets['root.1']->id; + $parentRootMapping->parent_id = $assets['root.1']->parent_id; + + self::$assetPermissionsById['root.1'][$rootId] = $permissionsRoot; + self::$assetPermissionsByName['root.1']['root.1'] = $permissionsRoot; + self::$assetPermissionsParentIdMapping['root.1'][$rootId] = $parentRootMapping; + } - $rulesList[$asset->name] = new JAccessRules; - $rulesList[$asset->name]->merge($rootAccessRule); + unset($assets['root.1']); - // If there are no component rules, use the root asset rules. - if (!$asset->rules || $asset->rules === '{}') + foreach ($assets as $extensionName => $asset) + { + if (!isset(self::$preloadedAssetTypes[$extensionName])) { - continue; + self::$assetPermissionsById[$extensionName] = array(); + self::$assetPermissionsByName[$extensionName] = array(); + self::$assetPermissionsParentIdMapping[$extensionName] = array(); + + $permissions = new StdClass; + $permissions->id = $asset->id; + $permissions->name = $asset->name; + $permissions->rules = $asset->rules; + + self::$assetPermissionsById[$extensionName][$rootId] = self::$assetPermissionsById['root.1'][$rootId]; + self::$assetPermissionsById[$extensionName][$asset->id] = $permissions; + self::$assetPermissionsByName[$extensionName][$rootId] = self::$assetPermissionsByName['root.1']['root.1']; + self::$assetPermissionsByName[$extensionName][$asset->name] = $permissions; + + $parentIdMapping = new StdClass; + $parentIdMapping->id = $asset->id; + $parentIdMapping->parent_id = $asset->parent_id; + + self::$assetPermissionsParentIdMapping[$extensionName][$rootId] = self::$assetPermissionsParentIdMapping['root.1'][$rootId]; + self::$assetPermissionsParentIdMapping[$extensionName][$asset->id] = $parentIdMapping; } - - // Merge the component asset rules. - $rulesList[$asset->name]->merge($asset->rules); } - - // Merge our rules list with self::$assetRules - self::$assetRules = self::$assetRules + $rulesList; - - return $components; } /** @@ -533,8 +556,6 @@ protected static function getGroupPath($groupId) public static function getAssetRules($asset, $recursive = false, $recursiveParentAsset = true) { // Get instance of the Profiler: - $profiler = JProfiler::getInstance('Application'); - $extensionName = self::getExtensionNameFromAsset($asset); // Almost all calls should have recursive set to true @@ -543,12 +564,11 @@ public static function getAssetRules($asset, $recursive = false, $recursiveParen && isset(self::$assetPermissionsByName[$extensionName][$asset])) { // Mark in the profiler. - JDEBUG ? $profiler->mark('Start JAccess::getAssetRules New (' . $asset . ')') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::getAssetRules New (' . $asset . ')') : null; - $assetType = self::getAssetType($asset); $assetId = self::$assetPermissionsByName[$extensionName][$asset]->id; - $ancestors = array_reverse(self::getAssetAncestors($assetType, $assetId)); + $ancestors = array_reverse(self::getAssetAncestors($extensionName, $assetId)); // Collects permissions for each $asset $collected = array(); @@ -568,21 +588,21 @@ public static function getAssetRules($asset, $recursive = false, $recursiveParen if (!isset(self::$assetRulesIdentities[$hash])) { - $rules = new JAccessRules; + $rules = new JAccessRules; $rules->mergeCollection($collected); self::$assetRulesIdentities[$hash] = $rules; } // Mark in the profiler. - JDEBUG ? $profiler->mark('Finish JAccess::getAssetRules New (' . $asset . ')') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::getAssetRules New (' . $asset . print_r($ancestors, true) . ')') : null; return self::$assetRulesIdentities[$hash]; } else { // Mark in the profiler. - JDEBUG ? $profiler->mark('Start JAccess::getAssetRules Old (' . $asset . ')') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::getAssetRules Old (' . $asset . ')') : null; if ($asset === "1") { @@ -653,7 +673,7 @@ public static function getAssetRules($asset, $recursive = false, $recursiveParen $rules = new JAccessRules; $rules->mergeCollection($result); - JDEBUG ? $profiler->mark('Finish JAccess::getAssetRules Old (' . $asset . ')') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::getAssetRules Old (' . $asset . ')') : null; return $rules; } From 77ffef1bc3c48169753591c3ebb68cd9b3df5689 Mon Sep 17 00:00:00 2001 From: andrepereiradasilva Date: Tue, 13 Sep 2016 00:52:37 +0100 Subject: [PATCH 4/6] Update access.php --- libraries/joomla/access/access.php | 58 ++++++++++++++---------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/libraries/joomla/access/access.php b/libraries/joomla/access/access.php index c50382c0f8d7e..46d5821c87069 100644 --- a/libraries/joomla/access/access.php +++ b/libraries/joomla/access/access.php @@ -352,43 +352,39 @@ protected static function preloadPermissions($assetType) // Get the extension name from the $assetType provided $extensionName = self::getExtensionNameFromAsset($assetType); - if (!isset(self::$assetPermissionsParentIdMapping[$extensionName]) - || !isset(self::$assetPermissionsById[$extensionName]) || !isset(self::$assetPermissionsByName[$extensionName])) - { - // Get the database connection object. - $db = JFactory::getDbo(); + // Get the database connection object. + $db = JFactory::getDbo(); - $parents = implode(',', $db->q(array($extensionName, 'root.1'))); + $parents = implode(',', $db->q(array($extensionName, 'root.1'))); - // Get a fresh query object: - $query = $db->getQuery(true) - ->select($db->qn(array('id', 'name', 'rules', 'parent_id'))) - ->from($db->qn('#__assets')) - ->where($db->qn('name') . ' LIKE ' . $db->q($extensionName . '.%') . ' OR ' . $db->qn('name') . ' IN (' . $parents . ')'); + // Get a fresh query object: + $query = $db->getQuery(true) + ->select($db->qn(array('id', 'name', 'rules', 'parent_id'))) + ->from($db->qn('#__assets')) + ->where($db->qn('name') . ' LIKE ' . $db->q($extensionName . '.%') . ' OR ' . $db->qn('name') . ' IN (' . $parents . ')'); - // Get the Name Permission Map List - $assets = $db->setQuery($query)->loadObjectList('name'); + // Get the Name Permission Map List + $assets = $db->setQuery($query)->loadObjectList(); - self::$assetPermissionsById[$extensionName] = array(); - self::$assetPermissionsByName[$extensionName] = array(); - self::$assetPermissionsParentIdMapping[$extensionName] = array(); + self::$assetPermissionsById[$extensionName] = array(); + self::$assetPermissionsByName[$extensionName] = array(); + self::$assetPermissionsParentIdMapping[$extensionName] = array(); - foreach ($assets as $name => $asset) - { - $permissions = new StdClass; - $permissions->id = $asset->id; - $permissions->name = $asset->name; - $permissions->rules = $asset->rules; + foreach ($assets as $asset) + { + $permissions = new StdClass; + $permissions->id = $asset->id; + $permissions->name = $asset->name; + $permissions->rules = $asset->rules; - self::$assetPermissionsById[$extensionName][$asset->id] = $permissions; - self::$assetPermissionsByName[$extensionName][$asset->name] = $permissions; + self::$assetPermissionsById[$extensionName][$asset->id] = $permissions; + self::$assetPermissionsByName[$extensionName][$asset->name] = $permissions; - $parentIdMapping = new StdClass; - $parentIdMapping->id = $asset->id; - $parentIdMapping->parent_id = $asset->parent_id; + $parentIdMapping = new StdClass; + $parentIdMapping->id = $asset->id; + $parentIdMapping->parent_id = $asset->parent_id; - self::$assetPermissionsParentIdMapping[$extensionName][$asset->id] = $parentIdMapping; - } + self::$assetPermissionsParentIdMapping[$extensionName][$asset->id] = $parentIdMapping; } return true; @@ -466,7 +462,7 @@ protected static function preloadComponents() self::$assetPermissionsById[$extensionName][$rootId] = self::$assetPermissionsById['root.1'][$rootId]; self::$assetPermissionsById[$extensionName][$asset->id] = $permissions; - self::$assetPermissionsByName[$extensionName][$rootId] = self::$assetPermissionsByName['root.1']['root.1']; + self::$assetPermissionsByName[$extensionName]['root.1'] = self::$assetPermissionsByName['root.1']['root.1']; self::$assetPermissionsByName[$extensionName][$asset->name] = $permissions; $parentIdMapping = new StdClass; @@ -595,7 +591,7 @@ public static function getAssetRules($asset, $recursive = false, $recursiveParen } // Mark in the profiler. - JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::getAssetRules New (' . $asset . print_r($ancestors, true) . ')') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::getAssetRules New (' . $asset . ')') : null; return self::$assetRulesIdentities[$hash]; } From 3a5158601f246438d88d7a228852ac9549be5517 Mon Sep 17 00:00:00 2001 From: andrepereiradasilva Date: Tue, 13 Sep 2016 10:47:34 +0100 Subject: [PATCH 5/6] Update access.php --- libraries/joomla/access/access.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/joomla/access/access.php b/libraries/joomla/access/access.php index 46d5821c87069..377bdd84703d6 100644 --- a/libraries/joomla/access/access.php +++ b/libraries/joomla/access/access.php @@ -212,13 +212,13 @@ public static function preload($assetTypes = 'components', $reload = false) if ($isDefault && !self::$componentsPreloaded) { // Mark in the profiler. - JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::preload(components)') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::preload (all components)') : null; self::preloadComponents(); self::$componentsPreloaded = true; // Mark in the profiler. - JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::preload(components)') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::preload (all components)') : null; } // Quick short circuit for default case @@ -239,12 +239,12 @@ public static function preload($assetTypes = 'components', $reload = false) { if (!isset(self::$preloadedAssetTypes[$assetType]) || $reload) { - JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess Preloading Process (' . $assetType . ')') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::preload (' . $assetType . ')') : null; self::preloadPermissions($assetType); self::$preloadedAssetTypes[$assetType] = true; - JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess Preloading Process (' . $assetType . ')') : null; + JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::preload (' . $assetType . ')') : null; } } From 1446591432fbe0c710ba60a5f7eb2c665ccc415b Mon Sep 17 00:00:00 2001 From: andrepereiradasilva Date: Tue, 13 Sep 2016 12:33:22 +0100 Subject: [PATCH 6/6] Update access.php --- libraries/joomla/access/access.php | 193 +++++++++-------------------- 1 file changed, 60 insertions(+), 133 deletions(-) diff --git a/libraries/joomla/access/access.php b/libraries/joomla/access/access.php index 377bdd84703d6..c662b1d10598d 100644 --- a/libraries/joomla/access/access.php +++ b/libraries/joomla/access/access.php @@ -61,14 +61,6 @@ class JAccess */ protected static $assetPermissionsByName = array(); - /** - * Array of the permission parent ID mappings - * - * @var array - * @since 11.1 - */ - protected static $assetPermissionsParentIdMapping = array(); - /** * Array of asset types that have been preloaded * @@ -126,17 +118,16 @@ class JAccess */ public static function clearStatics() { - self::$componentsPreloaded = false; - self::$viewLevels = array(); - self::$assetPermissionsById = array(); + self::$componentsPreloaded = false; + self::$viewLevels = array(); + self::$assetPermissionsById = array(); self::$assetPermissionsByName = array(); - self::$assetPermissionsParentIdMapping = array(); - self::$preloadedAssetTypes = array(); - self::$identities = array(); - self::$assetRules = array(); - self::$userGroups = array(); - self::$userGroupPaths = array(); - self::$groupsByUser = array(); + self::$preloadedAssetTypes = array(); + self::$identities = array(); + self::$assetRules = array(); + self::$userGroups = array(); + self::$userGroupPaths = array(); + self::$groupsByUser = array(); } /** @@ -212,13 +203,13 @@ public static function preload($assetTypes = 'components', $reload = false) if ($isDefault && !self::$componentsPreloaded) { // Mark in the profiler. - JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::preload (all components)') : null; + !JDEBUG ?: JProfiler::getInstance('Application')->mark('Before JAccess::preload (all components)'); self::preloadComponents(); self::$componentsPreloaded = true; // Mark in the profiler. - JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::preload (all components)') : null; + !JDEBUG ?: JProfiler::getInstance('Application')->mark('After JAccess::preload (all components)'); } // Quick short circuit for default case @@ -239,12 +230,12 @@ public static function preload($assetTypes = 'components', $reload = false) { if (!isset(self::$preloadedAssetTypes[$assetType]) || $reload) { - JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::preload (' . $assetType . ')') : null; + !JDEBUG ?: JProfiler::getInstance('Application')->mark('Before JAccess::preload (' . $assetType . ')'); self::preloadPermissions($assetType); self::$preloadedAssetTypes[$assetType] = true; - JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::preload (' . $assetType . ')') : null; + !JDEBUG ?: JProfiler::getInstance('Application')->mark('After JAccess::preload (' . $assetType . ')'); } } @@ -275,9 +266,9 @@ protected static function getAssetAncestors($extensionName, $assetId) while ($id !== 0) { - if (isset(self::$assetPermissionsParentIdMapping[$extensionName][$id])) + if (isset(self::$assetPermissionsById[$extensionName][$id])) { - $id = (int) self::$assetPermissionsParentIdMapping[$extensionName][$id]->parent_id; + $id = (int) self::$assetPermissionsById[$extensionName][$id]->parent_id; if ($id !== 0) { @@ -295,46 +286,6 @@ protected static function getAssetAncestors($extensionName, $assetId) return $ancestors; } - /** - * Method to retrieve the list of Asset IDs and their Parent Asset IDs - * and store them for later usage in getAssetRules(). - * - * @param string $assetType e.g. 'com_content.article' - * - * @return array List of Asset IDs (includes Parent Asset ID Info) - * - * @since 1.6 - * - * @deprecated 4.0 No used anymore. - */ - protected static function &preloadPermissionsParentIdMapping($assetType) - { - // Get the extension name from the $assetType provided - $extensionName = self::getExtensionNameFromAsset($assetType); - - if (!isset(self::$assetPermissionsParentIdMapping[$extensionName])) - { - // Get the database connection object. - $db = JFactory::getDbo(); - - // Get a fresh query object: - $query = $db->getQuery(true); - - // Build the database query: - $query->select('a.id, a.parent_id'); - $query->from('#__assets AS a'); - $query->where('(a.name LIKE ' . $db->quote($extensionName . '.%') . ' OR a.name = ' . $db->quote($extensionName) . ' OR a.id = 1)'); - - // Get the Name Permission Map List - $db->setQuery($query); - $parentIdMapping = $db->loadObjectList('id'); - - self::$assetPermissionsParentIdMapping[$extensionName] = &$parentIdMapping; - } - - return self::$assetPermissionsParentIdMapping[$extensionName]; - } - /** * Method to retrieve the Asset Rule strings for this particular * Asset Type and stores them for later usage in getAssetRules(). @@ -366,25 +317,13 @@ protected static function preloadPermissions($assetType) // Get the Name Permission Map List $assets = $db->setQuery($query)->loadObjectList(); - self::$assetPermissionsById[$extensionName] = array(); - self::$assetPermissionsByName[$extensionName] = array(); - self::$assetPermissionsParentIdMapping[$extensionName] = array(); + self::$assetPermissionsById[$extensionName] = array(); + self::$assetPermissionsByName[$extensionName] = array(); foreach ($assets as $asset) { - $permissions = new StdClass; - $permissions->id = $asset->id; - $permissions->name = $asset->name; - $permissions->rules = $asset->rules; - - self::$assetPermissionsById[$extensionName][$asset->id] = $permissions; - self::$assetPermissionsByName[$extensionName][$asset->name] = $permissions; - - $parentIdMapping = new StdClass; - $parentIdMapping->id = $asset->id; - $parentIdMapping->parent_id = $asset->parent_id; - - self::$assetPermissionsParentIdMapping[$extensionName][$asset->id] = $parentIdMapping; + self::$assetPermissionsById[$extensionName][$asset->id] = $asset; + self::$assetPermissionsByName[$extensionName][$asset->name] = $asset; } return true; @@ -427,50 +366,35 @@ protected static function preloadComponents() // Get the Name Permission Map List $assets = $db->setQuery($query)->loadObjectList('name'); - $rootId = $assets['root.1']->id; + // Add the root asset as parent of all components. + $assetsTree = array(); + $rootName = 'root.1'; - if (!isset(self::$preloadedAssetTypes['root.1'])) + foreach ($assets as $extensionName => $asset) { - $permissionsRoot = new StdClass; - $permissionsRoot->id = $assets['root.1']->id; - $permissionsRoot->name = $assets['root.1']->name; - $permissionsRoot->rules = $assets['root.1']->rules; - - $parentRootMapping = new StdClass; - $parentRootMapping->id = $assets['root.1']->id; - $parentRootMapping->parent_id = $assets['root.1']->parent_id; - - self::$assetPermissionsById['root.1'][$rootId] = $permissionsRoot; - self::$assetPermissionsByName['root.1']['root.1'] = $permissionsRoot; - self::$assetPermissionsParentIdMapping['root.1'][$rootId] = $parentRootMapping; - } + $assetsTree[$extensionName][] = $assets[$rootName]; - unset($assets['root.1']); + if ($extensionName !== $rootName) + { + $assetsTree[$extensionName][] = $assets[$extensionName]; + } + } - foreach ($assets as $extensionName => $asset) + // Save the permissions for the components asset. + foreach ($assetsTree as $extensionName => $assets) { if (!isset(self::$preloadedAssetTypes[$extensionName])) { - self::$assetPermissionsById[$extensionName] = array(); - self::$assetPermissionsByName[$extensionName] = array(); - self::$assetPermissionsParentIdMapping[$extensionName] = array(); - - $permissions = new StdClass; - $permissions->id = $asset->id; - $permissions->name = $asset->name; - $permissions->rules = $asset->rules; - - self::$assetPermissionsById[$extensionName][$rootId] = self::$assetPermissionsById['root.1'][$rootId]; - self::$assetPermissionsById[$extensionName][$asset->id] = $permissions; - self::$assetPermissionsByName[$extensionName]['root.1'] = self::$assetPermissionsByName['root.1']['root.1']; - self::$assetPermissionsByName[$extensionName][$asset->name] = $permissions; - - $parentIdMapping = new StdClass; - $parentIdMapping->id = $asset->id; - $parentIdMapping->parent_id = $asset->parent_id; - - self::$assetPermissionsParentIdMapping[$extensionName][$rootId] = self::$assetPermissionsParentIdMapping['root.1'][$rootId]; - self::$assetPermissionsParentIdMapping[$extensionName][$asset->id] = $parentIdMapping; + self::$assetPermissionsById[$extensionName] = array(); + self::$assetPermissionsByName[$extensionName] = array(); + + foreach ($assets as $asset) + { + self::$assetPermissionsById[$extensionName][$asset->id] = $asset; + self::$assetPermissionsByName[$extensionName][$asset->name] = $asset; + } + + self::$preloadedAssetTypes[$extensionName] = true; } } } @@ -551,16 +475,23 @@ protected static function getGroupPath($groupId) */ public static function getAssetRules($asset, $recursive = false, $recursiveParentAsset = true) { + $method = ''; + // Get instance of the Profiler: $extensionName = self::getExtensionNameFromAsset($asset); + $assetType = self::getAssetType($asset); - // Almost all calls should have recursive set to true - // so we'll get to take advantage of preloading: - if ($recursive && $recursiveParentAsset && isset(self::$assetPermissionsByName[$extensionName]) - && isset(self::$assetPermissionsByName[$extensionName][$asset])) + !JDEBUG ?: JProfiler::getInstance('Application')->mark('Before JAccess::getAssetRules (' . $asset . ')'); + + // Almost all calls should have recursive set to true so we'll get to take advantage of preloading. + if ($recursive && $recursiveParentAsset && (isset(self::$preloadedAssetTypes[$assetType]) || isset(self::$preloadedAssetTypes[$extensionName]))) { - // Mark in the profiler. - JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::getAssetRules New (' . $asset . ')') : null; + // The asset type (ex: com_modules.module) as been preloaded, but the asset does not exist (ex: com_modules.module.37). + // In this case we fallback to extension name asset. + if (!isset(self::$assetPermissionsByName[$extensionName][$asset])) + { + self::$assetPermissionsByName[$extensionName][$asset] = self::$assetPermissionsByName[$extensionName][$extensionName]; + } $assetId = self::$assetPermissionsByName[$extensionName][$asset]->id; @@ -590,15 +521,11 @@ public static function getAssetRules($asset, $recursive = false, $recursiveParen self::$assetRulesIdentities[$hash] = $rules; } - // Mark in the profiler. - JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::getAssetRules New (' . $asset . ')') : null; - - return self::$assetRulesIdentities[$hash]; + $rules = self::$assetRulesIdentities[$hash]; } else { - // Mark in the profiler. - JDEBUG ? JProfiler::getInstance('Application')->mark('Start JAccess::getAssetRules Old (' . $asset . ')') : null; + $method = ' Slower, no preloading, method used.'; if ($asset === "1") { @@ -612,7 +539,7 @@ public static function getAssetRules($asset, $recursive = false, $recursiveParen // Build the database query to get the rules for the asset. $query = $db->getQuery(true) - ->select($recursive ? 'b.rules' : 'a.rules') + ->select($recursive ? 'DISTINCT(b.rules)' : 'a.rules') ->from('#__assets AS a'); $extensionString = ''; @@ -668,11 +595,11 @@ public static function getAssetRules($asset, $recursive = false, $recursiveParen // Instantiate and return the JAccessRules object for the asset rules. $rules = new JAccessRules; $rules->mergeCollection($result); + } - JDEBUG ? JProfiler::getInstance('Application')->mark('Finish JAccess::getAssetRules Old (' . $asset . ')') : null; + !JDEBUG ?: JProfiler::getInstance('Application')->mark('After JAccess::getAssetRules (' . $asset . ')' . $method); - return $rules; - } + return $rules; } /**