Skip to content

4.1.1 pl Some issue fixed, some changes, customizations (Sub Collections, "header") #375

Open
@SilverMabol

Description

@SilverMabol

Hello,
i'm not expert of github and I apologize in advance if I used the wrong format for this message (and sorry for my english )

In serveral years i made some change and customization for Collection and "fixed" some issue.
I share with you what I have done to find out, especially for changes and customizations, if they create conflicts or if there are better solutions
Collection 4.1.1 and Modx 3.1.0

ISSUE
Issue with lexicon topic - ContentTypes
In collection view setting, for content Types, the value of entry of lexicon topic dont' appear, only see the index. This beacause don't load the lexicon topic
Solution
On file core\components\collections\src\Processors\Extra\ GetContentTypes.php at line 10. add collections:default
public $languageTopics = ['content_type','collections:default'];

Issue with icon e class_key
In the prepareIcons function, the old nomenclature for class_key (e.g. modResource) is considered and not the new one (e.g. modx\revolution\modResource)
I didn't change everything but only the part about particular types of resources
Solution
On file core\components\collections\src\Processors\Resource\ GetList.php for function prepareIcons (about line 624)
i change switch

`$classKeyNew = strtolower($resourceArray['class_key']);
        switch ($classKeyNew) {
            case 'modx\revolution\modweblink':
                $iconCls[] = $this->iconMap['weblink'];
                break;


            case 'modx\revolution\modsymlink':
                $iconCls[] = $this->iconMap['symlink'];
                break;

            case 'modx\revolution\modstaticresource':
                $iconCls[] = $this->iconMap['staticresource'];
                break;
        }`

Issue for localizzation (Lexicon Topic)
In Collection view the label for "Default for Template" is a tex and not a entry of lexicon topic
Solution
Add entry in lexicon topic default
$_lang['collections.template.defaultfortemplates'] = 'Default for Templates';
On file assets\components\collections\js\mgr\widgets\template\ template.grid.js on line 53 change text with lexicon
header: _('collections.template.defaultfortemplates')

Issue with preview of resource inside a selection
The button preview for a resource inside a selection don't work, the function handleButtons is wrong
Solution
On file assets\components\collections\js\mgr\widgets\category\ collections.grid.selection.js
simply i copy the same function from collections.grid.resources.js

Issue with multiple nested selection and resources
If link resource in nested selection and open button the resource don't linked
Solution
i don't know if this is the generale soluzion, but for my logic explained below, it works
On file assets\components\collections\js\mgr\widgets\category\ collections.grid.resource.js
I remove the folderGet form getPageUrl
return collections.getPageUrl(MODx.request.a, 'id=' + data.id + selection + collectionGet );

Issue (Change) for RefreshTree, selection
When i change status of a resource linked in selection, the resource's tree don't refresh and the status don't syncronize
Solution
On file assets\components\collections\js\mgr\widgets\category\ collections.grid.selection.js
add Ext.getCmp('modx-layout').refreshTrees(); for listeners success function in function deleteChild, removeChild, deleteSelected

CHANGE
In my logic inside a collection i want to see nested collection and only the resource inside must have the open button.

Change: set icon for resource linked in selection
Now no icon appear, i change this with icon-chain for alla resource linked
For make this
On file core\components\collections\src\Processors\Selection\ GetList.php for function prepareRow (586)
i add $resourceArray['icons'] = 'icon icon-chain'; in the end

Change: set icon for collection and selection
For make this
On file core\components\collections\src\Processors\Resource\ GetList.php in function prepareIcons (about line 624)
i add just before $resourceArray['icons'] = implode(' ', $iconCls); , the following code

        if ($resourceArray['class_key'] == 'Collections\Model\SelectionContainer' ) {
                $iconCls[] = 'selectioncontainer';
        }
        if ($resourceArray['class_key'] == 'Collections\Model\CollectionContainer' ) {
                $iconCls[] = 'collectioncontainer';
        }

Change: open button only for resource
For my logic only resource must have open button
For make this
On file core\components\collections\src\Processors\Resource\ GetList.php in function prepareActions (about line 508)
I change case for switch "open"

case 'open':
//MABOL inserito if che mostra tasto open solo se NON è una collezione/Selezione
if ($resourceArray['class_key'] != 'Collections\Model\CollectionContainer' && $resourceArray['class_key'] != 'Collections\Model\SelectionContainer') {
	$resourceArray['actions'][] = $this->actions['open'];
}
break; 

Change: SUB COLLECTION
I make possible to see the nested sub collections and other

Change: see sub collection inside collection
I create a new sistem setting mostra_sub_collections to decide whether to see them or not inside other collection
On file core\components\collections\src\Processors\Resource\ GetList.php
in function prepareQueryBeforeCount (about line 293)
I change last "where" (with sistem setting)

if (!$this->modx->getOption('mostra_sub_collections', null, false))
		{
        $c->where([
            'class_key:!=' => CollectionContainer::class,
//            "NOT EXISTS (SELECT 1 FROM {$this->modx->getTableName('modResource')} r WHERE r.parent = modResource.id)"
        ]);
		}

Change: see sub collection in resourc's tree
I create a new sistem setting mostra_sub_collections_tree to decide whether to see them or not on resource's (only for nested collection)
For make this
On file core\components\collections\src\Processors\Events\ OnBeforeDocFormSave.php
For function run i change if (line 24) in this (

if ($resource->class_key == CollectionContainer::class) {
			//MABOL, aggiunta possibilità di nascondere le collectioni nel Tree (else valore originario)
			if ($this->modx->getOption('mostra_sub_collections_tree', null, true)==false && $parent && ($parent->class_key == CollectionContainer::class))
			{
				$resource->set('show_in_tree', 0);
			}else{
				$resource->set('show_in_tree', 1);
			}
        }

For function switchToCollections i change if (line 141) in this (

if ($child->class_key == CollectionContainer::class) {
		//MABOL, aggiunta possibilità di nascondere le collectioni nel Tree (else valore originario)
		if ($this->modx->getOption('mostra_sub_collections_tree', null, true)==false)
		{
			$resource->set('show_in_tree', 0);
		}else{
			$resource->set('show_in_tree', 1);
		}
            }

On file core\components\collections\src\Processors\Events\ OnResourceBeforeSort.php
For function run i change if (line 38) in this (

if ($resource->class_key == CollectionContainer::class) {
		//MABOL, aggiunta possibilità di nascondere le collectioni nel Tree (else valore originario)
		if ($this->modx->getOption('mostra_sub_collections_tree', null, true)==false && $parent && ($parent->class_key == CollectionContainer::class))
		{
			$resource->set('show_in_tree', 0);
		}else{
			$resource->set('show_in_tree', 1);
		}
            }

Issue (Change) for RefreshTree, selection
In collection in resource tre when i change status of these, the resource's tree don't refresh and the status don't syncronize
This, obviously, only if mostra_sub_collections_tree is set to true
For make this
On file assets\components\collections\js\mgr\widgets\category\ collections.grid.resources.js add

if(MODx.config.mostra_sub_collections_tree == true){
						Ext.getCmp('modx-layout').refreshTrees();
					}

for listeners success function in
deleteChild, remoChild, deleteSelected, undeleteSelected, publishSelected, unpublishSelected, publishChild, unpublishChild

Customization: COLLECTION's "HEADER"
In some of my projects user groups can only see a collection and nothing else.
To make it more understandable I have introduced a header for each collection or selection with a small breadcrumb
i'm not an expert of extjs but this is my implementation
I create a new sistem setting mostra_cs_testata to decide whether to see them or not the collection'header
and then
Create a new processor file testata.php inside Extra
core\components\collections\src\Processors\Extra\ Testata.php

<?php
namespace Collections\Processors\Extra;

use MODX\Revolution\modResource;
use MODX\Revolution\Processors\Processor;

class Testata extends Processor
{
    public function process()
    {
        $collection = (int)$this->getProperty('collection', 0);
        $selection = (int)$this->getProperty('selection', 0);
		
		if ($collection <= 0) {
            return $this->failure();
        }
		$resource = $this->modx->getObject(modResource::class, $collection);
        if (!$resource) {
            return $this->failure();
        }
				
		//Discrimino a seconda che sia selezione oppure no per icona
		$resource->published?$classPub ='pubblicata':$classPub ='ritirata';
		if($selection)
		{
			$icona ='<i class="icon selectioncontainer"></i>';
		}else{
			$icona ='<i class="icon collectioncontainer"></i>';
		}
				
		//Contesto 
        $contextKey = $resource->context_key;
		$context = $this->modx->getContext( $contextKey );
		$contextName = $context->name;
		
		//Prima creo menu		
		//Prima parte del menu il contesto con la sua icona
		$menu = '<span class="eleMenu contesto"><i class="icon tree-context"></i>'.$contextName.'</span>';
		
		$pids = $this->modx->getParentIds($collection, 10, array('context' => $contextKey));
		$gids = array_reverse($pids);
		foreach($gids as $gid) 
		{
			if($gid == 0){continue;}
				
			$genit = $this->modx->getObject(modResource::class, $gid);
			if (!$genit){continue;}
			$genit->published?$classPubGen ='pubblicata':$classPubGen ='ritirata';
			$genit->hidemenu?$classMenuGen ='nomenu':$classMenuGen ='simenu';
			$menu .= '<span class="eleMenu '.$classPubGen.' '.$classMenuGen.'">'.$genit->pagetitle.'</span>';
		}
		//Ultimo elemento del menu la sua icona
		$menu .= '<span class="ultimo '.$classPub.'">'.$icona.'</span>';
		
		$RisAjax [] = $menu;
		
		//Adesso nome a cui aggiungo icona
		$nome = $icona;
		$nome .= $resource->pagetitle;
		$RisAjax [] = $nome;
		
		return $this->outputArray($RisAjax);
    }
}

On file assets\components\collections\js\mgr\widgets\category\ collections.grid.resources.js
i add, after window.history.replaceState({}, '', window.location.href); (line 52) , this

if(MODx.config.mostra_cs_testata == true)
	{
		this.getTestataCollection(config);
	}

Then i introduce 2 new function (getTestataCollection printTestataCollection) near the end

,getTestataCollection: function(config) {
		
		var collection = parseInt(MODx.request.id);

		MODx.Ajax.request({
                    url: MODx.config.connector_url
                    ,params: {
                        action: 'Collections\\Processors\\Extra\\Testata'
                        ,collection: collection
                        ,selection: 0
                    }
                    ,listeners: {
                        success: {
                            fn: function(r) {
                               this.printTestataCollection(r);
                            },scope: this 
                        },
                        failure: {
                            fn: function(){
                                this.store.removeAll();
                                this.currentFolder = collections.template.parent;
                                this.getStore().baseParams.parent = collections.template.parent;
                                this.getBottomToolbar().changePage(1);
                            },
                            scope: this
                        }
                    }
                });
				
		
	}

    ,printTestataCollection: function(r) {
	   this.testata = ({
			items   : [{
					html: '<div class="titoloTestataCS">'+r.results[1]+'</div>'+
						  '<div class="menuTestataCS">'+r.results[0]+'</div>'
					,bodyCssClass: 'contentTestataCS'
					,anchor: '100%'
				}]
		});
		this.getTopToolbar().insert(1,this.testata);
    }

On file assets\components\collections\js\mgr\widgets\category\ collections.grid.selection.js
add only function getTestataCollection with parameter selection to 1

,getTestataCollection: function(config) {
		
		var collection = parseInt(MODx.request.id);

		MODx.Ajax.request({
                    url: MODx.config.connector_url
                    ,params: {
                        action: 'Collections\\Processors\\Extra\\Testata'
                        ,collection: collection
                        ,selection: 1
                    }
                    ,listeners: {
                        success: {
                            fn: function(r) {
                               this.printTestataCollection(r);
                            },scope: this 
                        },
                        failure: {
                            fn: function(){
                                this.store.removeAll();
                                this.currentFolder = collections.template.parent;
                                this.getStore().baseParams.parent = collections.template.parent;
                                this.getBottomToolbar().changePage(1);
                            },
                            scope: this
                        }
                    }
                });
				
		
	}

That's All
While waiting for your opinions, improvements and error report, I leave you with some images that make everything clearer

Image
Second level collection, no in tree, with header with little crumbs

Image
First Level collection

Image
Collection with 2 opened file

Image
Slection 1 lev

Image
Selection 3 lev

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions