I am trying to upgrade Kirby 3 to 4 but I got below errors which i am not sure how to fix.
I have been using objects that extend StructureObject in Kirby 3 like:
class TestStructureObject extends StructureObject
And then it was passed down and Model was expected in those function, but now I Am getting:
Kirby\Content\Field::__construct(): Argument #1 ($parent) must be of type ?Kirby\Cms\ModelWithContent, TestStructureObject given
And in the past StructureObject extended Model class, but it does not do that anymore, is there another class i should use right now? Is there an easy fix to that?
We need to better understand where your TestStructureObject seems to get passed to Content\Field::__construct() as $parent. Do you have any insights on this yourself?
Hard to tell right now if it’s happening somewhere in the core code itself or if this is from custom code, e.g. in your TestStructureObject class itself.
It looks that object has page setting that is being read.
$TestStructureObject->formattedCompactPrice()->html()
Then it creates field in it at the end:
return new Field($this, ‘formattedCompactPrice’, $value);
return new Field(null, ‘formattedCompactPrice’, $value);
The parent is mainly needed for $field->exists() and there for checking if it actually exists in the content. This is why we had to fix the type hinting and require ModelWithContent.
Assuming that your objects don’t need to make use of this, passing null should be fine.
This will be a hard one. setOptionalProperties and setOptionalProperties don’t exist anymore as we are shifting away from the troublesome Kirby\Toolkit\Properties trait. They were a lot more for internal usage and I am not sure why/what for/how you used them in Kirby 3. Is the redis plugin yours?
I think you will need to make a deep dive into your custom code and plugins as they seem to be deeply using undocumented Kirby 3 methods that have changed for Kirby 4. It’s hard to give support without the full picture but I am also afraid looking at the full picture exceeds what we can offer as support here.
Most of the setter methods are gone that are called here in the last line. So you really need to approach this more from the end of what your Kirby 3 code was trying to do calling these methods.
If we have our own classes extending StructureObject in Kirby 3, how should we change them, do we extend from some other class in Kirby 4 now?
Since setters are different the results are different for those as well after upgrade causing errors.
class CustomScheduleStructureObject extends StructureObject
We used extensively this setter from structureObject, is there a way to make our classes work similar under Kirby 4?
public function __set(string $id, $props): void
{
if ($props instanceof StructureObject) {
$object = $props;
} else {
if (is_array($props) === false) {
throw new InvalidArgumentException('Invalid structure data');
}
$object = new StructureObject([
'content' => $props,
'id' => $props['id'] ?? $id,
'parent' => $this->parent,
'structure' => $this
]);
}
parent::__set($object->id(), $object);
}
So when you create an object and send array to __set in old solution the indexes of array were updated by $object->id() so if your $object->id() was string or whatever, your indexes became strings values of that id which later could be used to identify objects in array by that string but no more.
But now, array indexes never changes and stay numerical and are not updated by $object->id().
Old solution: