I want to contribute a safe implementation for inheritance between objects of differing classes and I was wondering @brusch / @fashxp what the implications of doing this would be.
I have only so far spotted that this is limited by code in https://github.com/pimcore/pimcore/blob/master/pimcore/models/Object/Concrete.php#L528
My question is, has this feature simply not been implemented yet or are there other limiting factors elsewhere?
My proposed solution would be to allow a list of "Inheritance Classes" (class id's) in the Class Definition for an object that could allow it's values to be inherited? (Obviously the properties would have to be present in the inherited class too)
Cheers!
Ok so I did a few tests on this and I can see that it is can of worms.
I have managed to implement multi-class inheritance on simple fields so far, but when it comes to the more complex relational fields there is far more work to be done. Many of the field collections and Bricks I have managed to solve by adding method_exists($parent, $getter) in their getFieldData methods where the $level != 0, but I'm thinking already that given the fact there will be many core modifications required (and thus a ridiculous amount of testing after) that I should look at a more bespoke alternative using preGetters and classmap for the usecase
It is a shame as it would be awesome to have this as an advanced feature in the core - If I come up with a elegant solution for this I will stick a tutorial and blogpost to share :-)
FYI here's an example of where I was heading...
<?php
namespace Website\Model\Object;
use Pimcore\Model\Object\AbstractObject;
class Concrete extends \Pimcore\Model\Object\Concrete
{
public $inheritableClasses = [
//Class ID => Class ID's that can inherit values
6 => [1],
9 => [10]
];
/**
* @return AbstractObject|null
*/
public function getNextParentForInheritance()
{
if ($this->getParent() instanceof AbstractObject) {
$parent = $this->getParent();
while ($parent && $parent->getType() == "folder") {
$parent = $parent->getParent();
}
if ($parent && ($parent->getType() == "object" || $parent->getType() == "variant")) {
if ($this->isAllowedInheritanceClass($parent->getClassId())) {
return $parent;
}
}
}
return null;
}
public function isAllowedInheritanceClass($parentClassId)
{
return $parentClassId == $this->getClassId()
|| (isset($this->inheritableClasses[$parentClassId])
&& in_array($this->getClassId(), $this->inheritableClasses[$parentClassId])
);
}
}
I think I've cracked this one see:
https://gist.github.com/cleggypdc/a58844f9143b43d05ca3d9c149be37f7
Essentially this allows field specific inheritance :dancers:
This functionality is now in one extendable Concrete Class, feel free to use!
so we leave it as that then and close the issue?
For now I think so.
Most helpful comment
This functionality is now in one extendable Concrete Class, feel free to use!