revolution
revolution copied to clipboard
Calling parseSchema repeatedly corrupts the generated class file in MODX 3
Bug report
Summary
When I call parseSchema (class xPDOGenerator) and the class file already exists, the content of the class file gets changed to this:
[+class-header+]
[+phpdoc-start+]
[+phpdoc-properties+]
[+phpdoc-end+]
[+class-declaration+]
[+class-traits+][+class-constants+][+class-properties+][+class-methods+][+class-close-declaration+][+class-footer+]
Step to reproduce
Snippet code to parse the schema:
$model_dir = $modx->getOption('core_path') . "components/mypackage/model/";
$xml_schema_file = $modx->getOption('core_path') . "components/mypackage/model/schema/mypackage.mysql.schema.xml";
$manager = $modx->getManager();
$generator = $manager->getGenerator();
$generator->parseSchema($xml_schema_file, $model_dir);
Schema file mypackage.mysql.schema.xml
<?xml version="1.0" encoding="UTF-8"?>
<model package="mypackage" baseClass="xPDO\Om\xPDOObject" platform="mysql" defaultEngine="InnoDB" version="3.0">
<object class="Myclass" table="myclass" extends="xPDO\Om\xPDOSimpleObject">
<field key="name" dbtype="varchar" precision="50" phptype="string" null="false" default="" />
</object>
</model>
Observed behavior
Executing the snippet once creates the correct files MyClass.php (and mysql/MyClass.php).
Executing the snippet a second time corrupts the content of both files (with placeholders like [+class-header+] etc.).
Expected behavior
I can set the "regenerate" option in parseSchema $generator->parseSchema($xml_schema_file, $model_dir, ["regenerate" => 2]) to avoid the problem, but the default options shouldn't corrupt the file content.
Environment
MODX 3.0.1
I believe the process cannot load the existing classes and therefore cannot update them since it uses Reflection to get the existing code. For some reason, it cannot find the existing classes after the initial generation. It could be that this is broken, as I generally only use --update=1 when I update a schema after the initial generation. Without adding the generated package to modx so it can autoload the classes, I'm not sure how this could ever work. If this is the case, then this needs an issue in the xpdo repository so it can be addressed at that level.
I added a line to the snippet to add the package and this indeed helped somewhat.
The file mysql/MyClass.php is correct now, but the file MyClass.php still contains some placeholders:
<?php
namespace mypackage;
use xPDO\xPDO;
/**
* Class Myclass
*
* @property string $name
*
* @package mypackage
*/
[+phpdoc-start+]
[+phpdoc-properties+]
[+phpdoc-end+]
class Myclass extends \xPDO\Om\xPDOSimpleObject
{
}
New snippet code:
<?php
$model_dir = $modx->getOption('core_path') . "components/mypackage/model/";
$xml_schema_file = $modx->getOption('core_path') . "components/mypackage/model/schema/mypackage.mysql.schema.xml";
$modx->addPackage('mypackage', $model_dir);
$manager = $modx->getManager();
$generator = $manager->getGenerator();
$generator->parseSchema($xml_schema_file, $model_dir);