I'll use modUser as an example, here, but the issue extends to any extended MODX object.
It appears to be a limitation of extending modUser that you can only do it once. If I create an extUser class and set the class_key of all users to extUser, then ActiveDirectory is installed and it changes the class_key to modActiveDirectoryUser, all my extUser code breaks.
This solution is implied by the docs, but it doesn't work (assume that the extUser custom fields are available with $user->getOne('Data') ). As far as I can tell, using the class key will only work if the extUsers and the modActiveDirectoryUsers are different people.
$user = $modx->getObject('modUser', 1);
$user->set('class_key', 'extUser');
$user->getOne('Data');
I've some solutions, but they would require changes in how people extend MODX objects.
Solution 1:
Have every extended modUser object extend another object that extends modUser (i.e., extUser would extend modActiveDirectoryUser or vice versa) and maintain a chain of extended object so new ones could go on the end of the chain. Imo, this is ugly and unworkable.
Solution 2:
Have xPDO take the class_key seriously so that the following code would just work:
$obj->set('class_key', 'extUser');
$obj->get('Data');
I doubt if this is could be done without some major mods to xPDO, so it's probably unworkable for practical purposes.
Solution 3:
Leave all the class_keys as modUser and create a new object of the class you need in your code:
$user = $modx->getObject('modUser', 1);
$fields = $user->toArray();
$fields['class_key'] = 'extUser';
$extUser = $modx->newObject('extUser');
$extUser->fromArray($fields, "", true, true);
$data = $extUser->getOne('Data');
This appears to work, but requires the code above anywhere you want to handle an extUser object.
Solution 4
This is the same as solution 3, except that the conversion code would be in the xPDOObject class:
public function convertToClass($class) {
$fields = $this->toArray();
$fields['class_key'] = $class;
$obj = $this->xpdo->newObject($class);
$obj->fromArray($fields, "", true, true);
return $obj; /* return &$obj; ? */
}
Then in the code that needs an extUser object:
$user = $modx->getObject('modUser', 1);
$extUser = $user->convertToClass('extUser');
$data = $extUser->getOne('Data');
I don't think this would break any existing code (since nobody is calling convertToClass() yet). This might be the best solution in the long run. There might be some objects that would need to disallow or override convertTo(), (e.g., $modx), though it's unlikely that anyone would ever use this method for them.
Maybe there's some easy solution that I'm not aware of. If so I'd love to see it.
Thoughts?
[ed. note: BobRay last edited this post 12 years, 2 months ago.]