From 69c7efb74faebd3f18dca28a116690ffca6a70fd Mon Sep 17 00:00:00 2001 From: John Peca Date: Fri, 5 Jul 2024 20:13:49 +0200 Subject: [PATCH] Resource icons in resource groups tree (#16099) ### What does it do? Abstract logic for getting icon classes from `Resource\GetNodes` processor to the `modResource::getIconClasses`. Use the new method in `Resource\GetNodes` and `ResourceGroup\GetNodes`. Lock icon is not part of this - as it's specific for resource tree and has no real benefit in resource group tree, same with classes around permissions. ### Why is it needed? Fixes the BUG that resource group's tree doesn't show resource icons. (100% viable for 3.0) ### How to test Create resource group, add resource, check if it has an icon :) ### Related issue(s)/PR(s) Different approach in #16011 --- .../Processors/Resource/GetNodes.php | 60 +------------ .../Security/ResourceGroup/GetNodes.php | 4 +- core/src/Revolution/modResource.php | 87 +++++++++++++++++++ 3 files changed, 92 insertions(+), 59 deletions(-) diff --git a/core/src/Revolution/Processors/Resource/GetNodes.php b/core/src/Revolution/Processors/Resource/GetNodes.php index b456b357905..0e009c65ba3 100644 --- a/core/src/Revolution/Processors/Resource/GetNodes.php +++ b/core/src/Revolution/Processors/Resource/GetNodes.php @@ -410,9 +410,8 @@ public function prepareResourceNode(modResource $resource) if ($hasChildren) { $class[] = 'is_folder'; } - if (!$resource->get('published')) $class[] = 'unpublished'; - if ($resource->get('deleted')) $class[] = 'deleted'; - if ($resource->get('hidemenu')) $class[] = 'hidemenu'; + + $class = array_merge($class, $resource->getStatusClasses()); if (!empty($this->permissions['save_document'])) $class[] = $this->permissions['save_document']; if (!empty($this->permissions['view_document'])) $class[] = $this->permissions['view_document']; @@ -452,60 +451,7 @@ public function prepareResourceNode(modResource $resource) } } - // Assign an icon class based on the class_key - try { - $reflectionClass = new ReflectionClass($resource->get('class_key')); - $classKey = strtolower($reflectionClass->getShortName()); - } catch (ReflectionException $e) { - $classKey = strtolower($resource->get('class_key')); - } - if (substr($classKey, 0, 3) === 'mod') { - $classKey = substr($classKey, 3); - } - - $iconCls = []; - - $contentType = $resource->getOne('ContentType'); - if ($contentType && $contentType->get('icon')) { - $iconCls = [$contentType->get('icon')]; - } - - $template = $resource->getOne('Template'); - $tplIcon = ''; - if ($template && $template->get('icon')) { - $tplIcon = $template->get('icon'); - $iconCls = [$template->get('icon')]; - } - - $classKeyIcon = $this->modx->getOption('mgr_tree_icon_' . $classKey, null, 'tree-resource', true); - if (empty($iconCls)) { - $iconCls[] = $classKeyIcon; - } - - switch ($classKey) { - case 'weblink': - $iconCls[] = $this->modx->getOption('mgr_tree_icon_weblink', null, 'tree-weblink'); - break; - - case 'symlink': - $iconCls[] = $this->modx->getOption('mgr_tree_icon_symlink', null, 'tree-symlink'); - break; - - case 'staticresource': - $iconCls[] = $this->modx->getOption('mgr_tree_icon_staticresource', null, 'tree-static-resource'); - break; - } - - // Icons specific with the context and resource ID for super specific tweaks - $iconCls[] = 'icon-' . $resource->get('context_key') . '-' . $resource->get('id'); - $iconCls[] = 'icon-parent-' . $resource->get('context_key') . '-' . $resource->get('parent'); - - // Modifiers to indicate resource _state_ - if ($hasChildren || $resource->isfolder) { - if (empty($tplIcon) && $classKeyIcon === 'tree-resource') { - $iconCls[] = $this->modx->getOption('mgr_tree_icon_folder', null, 'parent-resource'); - } - } + $iconCls = $resource->getIconClasses(); // Add icon class - and additional description to the tooltip - if the resource is locked. $locked = $resource->getLock(); diff --git a/core/src/Revolution/Processors/Security/ResourceGroup/GetNodes.php b/core/src/Revolution/Processors/Security/ResourceGroup/GetNodes.php index 94e96cdcf0f..93159455c7e 100644 --- a/core/src/Revolution/Processors/Security/ResourceGroup/GetNodes.php +++ b/core/src/Revolution/Processors/Security/ResourceGroup/GetNodes.php @@ -90,8 +90,8 @@ public function process() 'id' => 'n_' . $resource->get('id') . '_' . $resourceGroup->get('id'), 'leaf' => true, 'type' => modResource::class, - 'cls' => 'icon-' . $resource->get('class_key'), - 'iconCls' => 'icon-file', + 'iconCls' => implode(' ', $resource->getIconClasses()), + 'cls' => implode(" ", $resource->getStatusClasses()), ]; } } diff --git a/core/src/Revolution/modResource.php b/core/src/Revolution/modResource.php index 16c419f6939..c66293752a4 100644 --- a/core/src/Revolution/modResource.php +++ b/core/src/Revolution/modResource.php @@ -5,6 +5,8 @@ use MODX\Revolution\Registry\modDbRegister; use MODX\Revolution\Registry\modRegistry; use PDO; +use ReflectionClass; +use ReflectionException; use xPDO\Cache\xPDOCache; use xPDO\Cache\xPDOCacheManager; use xPDO\Om\xPDOCriteria; @@ -1534,4 +1536,89 @@ public function clearCache($context = '') $this->xpdo->invokeEvent('OnResourceCacheUpdate', ['id' => $this->get('id')]); } } + + /** + * Get icon classes for the resource, based on template, class_key, system settings, etc. + * + * @return array + */ + public function getIconClasses() + { + try { + $reflectionClass = new ReflectionClass($this->get('class_key')); + $classKey = strtolower($reflectionClass->getShortName()); + } catch (ReflectionException $e) { + $classKey = strtolower($this->get('class_key')); + } + + if (substr($classKey, 0, 3) === 'mod') { + $classKey = substr($classKey, 3); + } + + $iconCls = []; + + $contentType = $this->getOne('ContentType'); + if ($contentType && $contentType->get('icon')) { + $iconCls[] = $contentType->get('icon'); + } + + $template = $this->getOne('Template'); + $tplIcon = ''; + if ($template && $template->get('icon')) { + $tplIcon = $template->get('icon'); + $iconCls[] = $template->get('icon'); + } + + $classKeyIcon = $this->xpdo->getOption('mgr_tree_icon_' . $classKey, null, 'tree-resource', true); + if (empty($iconCls)) { + $iconCls[] = $classKeyIcon; + } + + switch ($classKey) { + case 'weblink': + $iconCls[] = $this->xpdo->getOption('mgr_tree_icon_weblink', null, 'tree-weblink'); + break; + + case 'symlink': + $iconCls[] = $this->xpdo->getOption('mgr_tree_icon_symlink', null, 'tree-symlink'); + break; + + case 'staticresource': + $iconCls[] = $this->xpdo->getOption('mgr_tree_icon_staticresource', null, 'tree-static-resource'); + break; + } + + // Icons specific with the context and resource ID for super specific tweaks + $iconCls[] = 'icon-' . $this->get('context_key') . '-' . $this->get('id'); + $iconCls[] = 'icon-parent-' . $this->get('context_key') . '-' . $this->get('parent'); + + // Modifiers to indicate resource _state_ + $childrenCount = $this->xpdo->getCount(modResource::class, ['parent' => $this->get('id')]); + if ($childrenCount > 0 || $this->isfolder) { + if (empty($tplIcon) && $classKeyIcon === 'tree-resource') { + $iconCls[] = $this->xpdo->getOption('mgr_tree_icon_folder', null, 'parent-resource'); + } + } + + return $iconCls; + } + + public function getStatusClasses() + { + $classes = []; + + if (!$this->get('published')) { + $classes[] = 'unpublished'; + } + + if ($this->get('deleted')) { + $classes[] = 'deleted'; + } + + if ($this->get('hidemenu')) { + $classes[] = 'hidemenu'; + } + + return $classes; + } }