I’ve seen something like this when moving things around by dragging and dropping them in the tree. Resources can end up with an invalid parent, or resources can end up being each other’s parent. If something goes wrong when MODX tries to traverse the tree, things can disappear.
That led me to create SiteCheck, which checks for the following (and a lot more):
Resources with invalid parents
Resources with invalid Templates
Resources with empty aliases
Resources with duplicate aliases in the same Context
Resources with frozen, empty URIs
Resources with duplicate URIs in the same Context
Resources with duplicate pagetitles in the same Context
Resources with invalid class keys
Resources with invalid Contexts
Resources where context_key doesn’t match parent’s
I also wrote this post many years ago about Articles disappearing.
I was able to reproduce the problem with an ArticlesContainer in the resource tree.
The problem is connected to the way the _loadCollectionInstance function of the class modAccessibleObject works:
If $obj->isLazy() is true, then the object/resource is added to the collection without a key:
$objCollection[]= $obj;
If $obj->isLazy() is false however, the object/resource is added to the collection with the ID as the key:
$objCollection[$pkval]= $obj;
As isLazy() is true for all the normal resources, and false for ArticlesContainers, this can create the situation, that an item in $objCollection gets overwritten.
Say your ArticlesContainers has the ID = 6. If by the time the ArticlesContainer is processed, there have already been 7 or more normal resources added to the $objCollection, then an assigment to $objCollection[6] overwrites the stored resource (and that resource won’t show up in the resource tree).
I’ve been using Articles for many years (I think with about 300 articles) and haven’t had an Article resource disappear since I wrote that post in 2013, though I don’t think I’m running PHP 8.
No, I ran PHP 7.2 when reproducing the issue.
It also seems to be a very old bug. There is an open issues on github from 2013 that describes the same problem.
It’s not an Article resource that disappears. It’s a normal MODX resource, that has the same parent as an ArticlesContainer resource that may disappear (under certain circumstances).
What you described in your post from 2013 is a different problem.
I believe, it is a bug in the MODx core that can occur, if getCollection() is called for a mixture of lazy and non-lazy objects.
The resource/getNodes processor only queries a subset of the modResource columns, so the normal MODX resources are lazy, but the class “ArticlesContainer” overrides the isLazy() function and always returns false.
Thanks. The anomalies I observed which led me to write SiteCheck all resulted from dragging and dropping resources in the tree. Does that fit with what you found?
I think, this case is somewhat different from the things you check with SiteCheck.
In this case the values in the database are not per se wrong, there is just a bug when querying them with getCollection().
Basically what’s happening is the following:
If the “ArticlesContainer” has an ID of 2 and there are 2 + 1 (or more) resources with a lower value of menuindex, then the resource at position 2 + 1 gets overwritten.
$a = array();
$a[] = 'Resource A'; //key is 0
$a[] = 'Resource B'; //key is 1
$a[] = 'Resource C'; //key is 2
$a[2] = 'ArticlesContainer'; //key is ID (=2) -> overwrites 'Resource C' in the array
The reordering of resources in the tree just sets the menuindex value, that determines what resource is at position 2 + 1.
If there are multiple “ArticlesContainer” resources in the same tree-node, then things get even more unpredictable. Let’s say you have 2 ArticlesContainers with the IDs 20 and 21:
$a = array();
$a[] = 'Resource A'; //key is 0
$a[] = 'Resource B'; //key is 1
$a[20] = 'ArticlesContainer (20)'; //key is ID (=20)
$a[] = 'Resource C'; //key is 21(!)
$a[21] = 'ArticlesContainer (21)'; //key is ID (=21) -> overwrites 'Resource C' in the array
Ah. So at Bob’s Guides, where my Articles container has an ID around 300, and I have well over 300 resources, I probably have a resource that never shows up in the tree, but with so many resources, I’ve never noticed that.
Do you have a suggested fix that doesn’t break Articles?
That’s unlikely.
For that to happen, your 300+ resources had to be in the same tree-node (same value for parent) as your ArticlesContainer resource and placed above it.
If you have only one ArticlesContainer resource with a high ID value, you should be fine.
Unfortunately I don’t see an easy fix.
I think the classes ArticlesContainer and Article probably need a proper implementation of the isLazy() function instead of just always returning false.