Orphans CMP Tutorial
If you use this extra and like it, please consider donating. The suggested donation for this extra is $20.00, but any amount you want to give is fine (really). For a one-time donation of $50.00 you can use all of my non-premium extras with a clear conscience.
Orphans is a utility for MODX Revolution that tries to identify unused elements, such as Chunks, Snippets, Templates, and Template variables. Unused elements can slow down your site and make it more difficult to find the things you want in the Manager. A utility to identify them has been requested many times. The process is amazingly complex, but I thought I'd give it a shot. The results, while not perfect, are more accurate than I thought they would be, and it was a fun challenge to write it. If you want to make yourself dizzy, read the code of the Orphans class file, especially the section around line 253 (my apologies if that code has been moved by the time you read this, and I've forgotten to update this section).
[Fully updated for MODX 3 and PHP 8]
Important: Orphans will list the names of elements that might be unused, but it can't guarantee that they are really not in use somewhere.
Updates Notes
Version 1.2.3 has been refactored to keep MODX 3.0+ happy. All controllers and processors are now class-based to prevent Orphans from crapping up the MODX error log. The code has also shrunk considerably. The original twenty-four separate processors have been consolidated into six, smarter processors that can handle multiple object types.
On large sites, the Orphans CMP can time out and produce no output. As of Orphans 1.1.1, there is added code to prevent this, but it may not work for you, so the new version includes a standalone snippet that will give you an Orphans report. The location is core/components/orphans/elements/snippets/orphans.snippet.php
. It can be run from the command line or as a one-time cron job — in either case, it will not time out. Because it processes chunks, templates, TVs, and snippets, it can take a long time to run.
Important! Because Orphans can use a lot of memory and time, the snippet is disabled on installation. You definitely don't want outsiders to be able to run it at will. To enable it, just comment out the first line of code like this:
// exit;
Disable it when you're through running it by changing it back:
exit;
Installing Orphans
Go to System -> Package Management on the main menu in the MODX Manager and click on the "Download Extras" button. That will take you to the Revolution Repository. Put Orphans in the search box and press Enter. Click on the "Download" button, and when the download is finished, click on the "Back to Package Manager" button. That should bring you back to your Package Management grid. Click on the "Install" button next to Orphans in the grid. The Orphans package should now be installed.
After installing Orphans, you'll need to reload the Manager page before it will show up under the Components menu. In fact, if you don't already have any components installed, the Extras (formerly Components) menu itself won't appear until after you install Orphans and then reload the Manager page.
Usage
To run Orphans, just select the Orphans menu item under Extras in the Manager's Main Menu. You'll need to reload the Manager page after installing Orphans before the menu item will show up.
Once Orphans has launched, select the tab for the element you want to examine and click on the "Search for Orphans" button. Orphans does a tremendous amount of processing before it can render its output, so be patient. Nothing will show up until the analysis is complete. Orphans looks at the entire source code of all Resources and all Elements. It also examines all Element properties, Settings retrieved with getOption(), and the code of all class files included by snippets and plugins (and recursively looks at files included in those class files). It takes time.
In the grid, you can perform any of the following functions by selecting the checkboxes next to the items you want to process and either right-clicking in the grid or using the "Bulk Actions" dropdown to select the action you want to perform.
- Change Category — Changes the category of selected Elements
- Rename — Adds the prefix set in the Orphans.prefix System Setting to the names of selected Elements
- UN-Rename — Removes the prefix from the names of selected Elements
- Add to Ignore List — Adds the selected elements to the Ignore List so they won't show up again
- Delete — Permanently deletes the selected elements.
The default prefix used by Rename is "aaOrphan." so the renamed orphans will be at the top of the grid when it's sorted by name. You can change the prefix by going to System -> System Settings and selecting the orphans namespace (or putting "Orphans" in the search box at the upper right). Double-click on the prefix value to edit it, and after editing it, click somewhere else in the grid.
The Ignore List is just a chunk called "OrphansIgnoreList." Important: Do not change the name of the chunk. You can add Element names to the chunk manually, but it's usually easier to do it in the grid. If you change your mind about ignoring some Element, you can delete it from the chunk Manually. The format of the chunk is unimportant, as long as each object appears on a separate line, so don't worry about messing it up.
Important! Remember that deleting an Element is permanent. There's no way to get it back once you've deleted it.
You can sort the Orphans grids by ID, Name, or Category by clicking on the heading in the grid. Clicking again reverses the order. The "Per Page" setting at the bottom of the grid is set permanently to 300. This is necessary due to a bug in how ExtJS sorts paged results. Hopefully, you don't have more than 300 orphans in any category.
In order to gain as much speed as possible, Orphans does not refresh the Elements tree after you perform an action. If you want to see what the tree looks like after performing an action in Orphans, you can refresh it manually by clicking on the "refresh" icon at the top of the tree.
Considerations
Orphans is very conservative about identifying Orphans. If the name of an object is used anywhere (even in comments or files that aren't really included because the include statement is commented out), Orphans will consider the file in use and won't list it as an Orphan. Even with this policy, however, there can still be false positives in the Orphans list.
The listing of orphan Templates is generally quite accurate because if any Resource uses a template, Orphans will consider it in use and won't list it. It's still possible that a Template might be referred to by ID in snippet or plugin code or in the properties of a snippet tag, but this is fairly rare.
TVs are more of a challenge because they can be referred to by ID in snippets. Referring to them by ID is faster, so a TV that is identified by its ID and is used to control a snippet may never appear in a tag. Orphans will mistakenly consider it unused.
I couldn't think of any sensible way to identify unused Plugins or Resources, so they are not listed.
Chunks are particularly difficult for Orphans because their names in code are often dynamic. For example, suppose you have an extra that uses a Tpl chunk called "FileUploadTpl." The Tpl chunk might be referred to in this way in the extra's code:
$name = "FileUpload"; $tpl = $name . 'Tpl'; $modx->getChunk($tpl);
Since the name "FileUploadTpl" does not appear anywhere in the code, Orphans will consider it unused, even though it is in use and may be critical for that extra. Because of this, you should take all listed orphans with a grain of salt. In spite of this, Orphans is actually surprisingly good about identifying Tpl chunks that are in use because they are usually named in snippet and plugin properties, which Orphans always checks. Note that Orphans does not check custom Property Sets, which could also have references to Tpl chunks.
The report on Snippets is fairly reliable, since every snippet that's in use is referred to by name somewhere. It's theoretically possible to use a snippet without using its name, but it's quite rare.
Caution: Snippets for snippet-based dashboard widgets like UpgradeMODX will often be identified as orphans even though they are used by some widget. Add them to the ignore list.
General Advice
Often, you'll recognize listed orphans as things that are definitely no longer in use. You can delete those, although it's not a bad idea to rename them first and delete them later.
Other Elements listed as orphans will be elements that are either not used but important to keep (e.g., example Tpl Chunks) or elements that you know are used even though Orphans didn't find the use (e.g., MyComponent Tpl chunks). Add those to the Ignore list and Orphans will not show them to you again.
For listed orphans you're not sure about, the best practice is to rename them. Run your site for a good while and try to check the operation of all extras to see if there are any problems. If there are no problems, you can delete the Orphans. If things go sideways, you can un-rename them in the grid.
Another consideration is that you will often use your own Tpl chunks in place of the default ones that come with an extra. Orphans will list the default Tpl chunks as unused, but it's a good idea to add them to the Ignore List and keep them around for reference in case your own Tpl chunks develop problems.
JS notes
If you use ExtJS, you might be curious about how the grid actions can be so fast when the search for orphans is so slow. Because the search for orphans takes such a long time, I had to be a little tricky about updating the grid.
Typically, with grids in MODX, making changes calls the processors (which modify the DB), then the whole grid is refreshed by calling the grid's getlist()
processor. That gets all the data from the DB and repopulates the grid. The Batcher extra, for example, actually does that twice for every action you perform.
Refreshing the grid using the getList()
processor is acceptable if your getList()
processor is relatively fast. In the case of Orphans, though, the getList()
processor performs the complete orphan search, which can take 20 seconds or more. No one wants to wait that long just to rename an Element. Worse yet, in a typical tabbed grid like Batcher, *all* the processors are called and every grid is populated whether it's active or not. With Orphans, this could take a minute or more.
The solution is to load the grids with a dummy processor that returns an empty list. When you click on the "Search for Orphans" button, the real processor is called and the grid is populated. When you select one of the actions in the grid, the processor gets called, but all the action from there on is local. Custom JavaScript modifies the grid locally, without contacting the server. There's a chance that the grid won't match what's in the DB if the processor messes up, but clicking on the "Search for Orphans" button will always synchronize the grid with what's in the DB.
My book, MODX: The Official Guide - Digital Edition is now available here. The paper version of the book may still be available from Amazon.
If you have the book and would like to download the code, you can find it here.
If you have the book and would like to see the updates and corrections page, you can find it here.
MODX: The Official Guide is 772 pages long and goes far beyond this web site in explaining beginning and advanced MODX techniques. It includes detailed information on:
- Installing MODX
- How MODX Works
- Working with MODX resources and Elements
- Using Git with MODX
- Using common MODX add-on components like SPForm, Login, getResources, and FormIt
- MODX security Permissions
- Customizing the MODX Manager
- Using Form Customization
- Creating Transport Packages
- MODX and xPDO object methods
- MODX System Events
- Using PHP with MODX
Go here for more information about the book.
Thank you for visiting BobsGuides.com
— Bob Ray