
<?php
class myUser extends modUser {
public function __construct(xPDO & $xpdo) {
parent::__construct($xpdo);
$this->set('class_key', 'myUser');
}
}
<?php
require_once MODX_CORE_PATH . 'components/mytest/model/mytest/myuser.class.php';
class myChildUser extends myUser {
public function __construct(xPDO & $xpdo) {
parent::__construct($xpdo);
$this->set('class_key', 'myChildUser');
}
}
<?php
$modx->setLogLevel(xPDO::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
$modx->log(xPDO::LOG_LEVEL_INFO, 'Hello!');
$path = MODX_CORE_PATH . 'components/mytest/model/';
$modx->addPackage('mytest', $path, 'mt_');
/* Uncomment line below and comment the next one to make the problem disappear. */
//$user = $modx->newObject('myUser');
$user = $modx->newObject('myChildUser');
$comp = $modx->newObject(
'myComp',
array(
'name' => 'Name'
)
);
$added = $user->addOne($comp, 'Comp');
return $added ? 'true' : 'false';
public function __construct(modX &$modx) {
$this->modx = &$modx;
$this->modx->addPackage('pkgName', 'path/to/extra/model/', 'tablePrefix_');
$this->loadBaseClasses();
}
This question has been answered by dunnock. See the first response.
$user = $modx->newObject('myChildUser');
class myChildUser extends myUser {
public function __construct(xPDO & $xpdo) {
$xpdo->loadClass('myUser', MODX_CORE_PATH . 'components/mytest/model/mytest/');
parent::__construct($xpdo);
$this->set('class_key', 'myChildUser');
}
}
I guess the common way would be to just to loadClass() the parent class before newObject.
$modx->loadClass('myUser', MODX_CORE_PATH . 'components/mytest/model/');
$user = $modx->newObject('myChildUser');
class myChildUser extends myUser {
public function __construct(xPDO & $xpdo) {
$xpdo->loadClass('myUser', MODX_CORE_PATH . 'components/mytest/model/mytest/');
parent::__construct($xpdo);
$this->set('class_key', 'myChildUser');
}
}
Another common solution is to use service class to addPackage() within the constructor and the loadClass('myUser'); directly after addPackage().
class myExtra {
private $modx;
public function __construct(modX $modx) {
$this->modx = $modx;
$this->modx->addPackage('mytest', MODX_CORE_PATH . 'components/mytest/model/');
$this->modx->loadClass('myUser', MODX_CORE_PATH . 'components/mytest/model/mytest/');
}
}
100% safe is that you add require_once('myuser.class.php'); to start of the mychilduser.class.php file.
require_once MODX_CORE_PATH . 'components/mytest/model/mytest/myuser.class.php';
class myChildUser extends myUser {
public function __construct(xPDO & $xpdo) {
$xpdo->loadClass('myUser', MODX_CORE_PATH . 'components/mytest/model/mytest/');
parent::__construct($xpdo);
$this->set('class_key', 'myChildUser');
}
}
Need to ponder, the getAncestry definitely leads to right direction but just wrong place. To get it working correctly it should be set with loadClass() already.
Also xPDO should have additional default classes loaded functionality with the constructor. But looks like that the constant is wrong in it right now, (guess that should post bug report on it)
public function getComposites($className) {
$composites= array ();
if ($className= $this->loadClass($className)) {
if ($ancestry= $this->getAncestry($className)) {
for ($i= count($ancestry) - 1; $i >= 0; $i--) {
$ancestorClass = $this->loadClass($ancestry[$i]);
if ($ancestorClass && isset ($this->map[$ancestry[$i]]['composites'])) {
$composites= array_merge($composites, $this->map[$ancestry[$i]]['composites']);
}
}
}
if ($this->getInherit($className) === 'single') {
$descendants= $this->getDescendants($className);
if ($descendants) {
foreach ($descendants as $descendant) {
$descendantClass= $this->loadClass($descendant);
if ($descendantClass && isset($this->map[$descendantClass]['composites'])) {
$composites= array_merge($composites, array_diff_key($this->map[$descendantClass]['composites'], $composites));
}
}
}
}
}
return $composites;
}
), xPDO::loadClass() around line 621 where the first comment //Check depency is set. This will try to load the class if it is not declared. Package needs to be set before this works.if (!empty($path) || $ignorePkg) {
$class= $this->_loadClass($class, $fqn, $included, $path, $transient);
} elseif (isset ($this->packages[$this->package])) {
$pqn= $this->package . '.' . $fqn;
// Check depency
foreach ($this->classMap as $baseClass => $classes) {
if (array_search($classname, $classes) !== false && !class_exists($baseClass)) { $this->loadClass($baseClass); }
}
// End Check
if (!$pkgClass= $this->_loadClass($class, $pqn, $included, $this->packages[$this->package]['path'], $transient)) {
foreach ($this->packages as $pkg => $pkgDef) {
if ($pkg === $this->package) continue;
$pqn= $pkg . '.' . $fqn;
if ($pkgClass= $this->_loadClass($class, $pqn, $included, $pkgDef['path'], $transient)) {
break;
}
}
}
$class= $pkgClass;
} else {
$class= false;
}$vchart = $modx->addPackage('mytest', $modx->getOption('core_path') . 'components/myuser/model/model/', 'test_');
$usr = $modx->newObject('myChildUser');
$usr->set('id', 1);
$comp = $usr->getOne('Comp');
return "<pre>" . print_r($comp->toArray(), true);Still in the wrong place as the loadClass() before the ancestry check would cause Fatal error.
This then again works, (note, just a demo use only), xPDO::loadClass() around line 621 where the first comment //Check depency is set. This will try to load the class if it is not declared.
if (!empty($path) || $ignorePkg) { $class= $this->_loadClass($class, $fqn, $included, $path, $transient); } elseif (isset ($this->packages[$this->package])) { $pqn= $this->package . '.' . $fqn; // Check depency foreach ($this->classMap as $baseClass => $classes) { if (array_search($classname, $classes) !== false && !class_exists($baseClass)) { $this->loadClass($baseClass); } } // End Check if (!$pkgClass= $this->_loadClass($class, $pqn, $included, $this->packages[$this->package]['path'], $transient)) { foreach ($this->packages as $pkg => $pkgDef) { if ($pkg === $this->package) continue; $pqn= $pkg . '.' . $fqn; if ($pkgClass= $this->_loadClass($class, $pqn, $included, $pkgDef['path'], $transient)) { break; } } } $class= $pkgClass; } else { $class= false; }
foreach ($this->classMap as $baseClass => $classes) {
if (array_search($classname, $classes) !== false) {
if ($this->loadClass($baseClass) !== false) {
break;
}
}
}
$a = $modx->newObject('ClassA');
$a = $modx->newObject('ClassA', 'packageA');
class xPDOPackage {
var $package;
var $path;
function getObject() {}
function getObjectCollection() {}
function newObject() {}
...
}
writing debug cmp for modx to run and analyze queries through one page. Now wondering what options adding to it.
[ed. note: dunnock last edited this post 13 years, 4 months ago.]