Hey there!
I am having data that is collected in larger parent structure objects that in itself each hold collections of smaller child struture objects.
Now I need to loop over each of these parent structure objects, filter the child structure objects of those and then collect the filtered child structure objects in a new structure object (let’s call that one collectedStructures).
What I am doing is this:
$collectedStructures = new Structure();
$parentStructures = $page->parentStructureField()->toStructure()->map(function($ps) use(&$collectedStructures) {
// [...] do lots of mapping stuff here
$childStructures = $ps->childStructureField()->toStructure()->filter(function($cs) {
// filter these children by certain criteria
})->map(function($cs) use(&$collectedStructures) {
// this is where the collecting of the filtered children should happen
$collectedStructures->add($cs);
});
});
The problem is that with each iteration over a parent structure, the add()
method seems to jump back to index 0
and starts adding them from there to the collectedStructures
.
To demonstrate what that means lets say, I would try to collect strings, the parent structure field has three entries A
, B
and C
. Let’s also say, the first of those parent structures has 4 children, the second one only 1 and the third one two. Then, when I loop over all structures, I would first collect AAAA
, then B
, then CC
. Instead of ending up with AAAABCC
I end up with CCAA
though, because in each loop the add()
method overwrites the previous stuff starting from index 0
.
I have tried to first write everything to an array, then loop over that array and use the add()
method, but it still extracts the ids from the underlying children somehow and starts to write anything from index 0
.
I believe this is a bug in the add()
(or rather in the underlying append()
) method as I would expect it to always just add new entries to the end of the collection, no matter what. Or are there any plausible situations, where you would want the add()
or append()
method to not add something to the end of the collection?
I had a look at the source and if I change this method from
public function append(...$args)
{
if (count($args) === 1) {
// try to determine the key from the provided item
if (is_object($args[0]) === true && is_callable([$args[0], 'id']) === true) {
return parent::append($args[0]->id(), $args[0]);
} else {
return parent::append($args[0]);
}
}
return parent::append(...$args);
}
to
public function append(...$args)
{
if (count($args) === 1) {
return parent::append($args[0]);
}
return parent::append(...$args);
}
it works.
So my questions:
Is this indeed a bug?
If not, how can I achieve adding structure items to collectedStructures()
without restarting the index at 0
for each loop?
If it is a bug, how can I fix this for now? Add a plugin with its own method myAppend()
or something?
Thanks!