Struggling with creating simple custom xPDO model - Could not load package metadata for package

Hi all, I’m trying to create a custom xPDO-model+table. I manage to create the model-files using this description: Custom Models - xPDO | MODX Documentation

My schema:

<?xml version="1.0" encoding="UTF-8"?>
<model package="skattelistene"
       baseClass="xPDOObject"
       platform="mysql"
       defaultEngine="MyISAM"
       tablePrefix="skattelistene_"
       phpdoc-package="skattelistene"
       phpdoc-subpackage="model"
       version="1.1">
    <object class="person" table="person" extends="xPDOSimpleObject">
        <field key="fornavn" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="etternavn" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="fodselsaar" dbtype="int" precision="4" phptype="string" null="false" default=""/>
        <field key="postnummer" dbtype="varchar" precision="4" phptype="string" null="false" default=""/>
        <field key="poststed" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="formue" dbtype="bigint" precision="20" phptype="string" null="false" default=""/>
        <field key="inntekt" dbtype="bigint" precision="20" phptype="string" null="false" default=""/>
        <field key="skatt" dbtype="bigint" precision="20" phptype="string" null="false" default=""/>
        <field key="kommunenummer" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <index alias="fornavn" name="fornavn" primary="false" unique="false" type="BTREE">
            <column key="fornavn" length="" collation="A" null="false"/>
        </index>
        <index alias="etternavn" name="etternavn" primary="false" unique="false" type="BTREE">
            <column key="etternavn" length="" collation="A" null="false"/>
        </index>
        <index alias="fodselsaar" name="fodselsaar" primary="false" unique="false" type="BTREE">
            <column key="fodselsaar" length="" collation="A" null="false"/>
        </index>
        <index alias="postnummer" name="postnummer" primary="false" unique="false" type="BTREE">
            <column key="postnummer" length="" collation="A" null="false"/>
        </index>
        <index alias="poststed" name="poststed" primary="false" unique="false" type="BTREE">
            <column key="poststed" length="" collation="A" null="false"/>
        </index>
        <index alias="kommunenummer" name="kommunenummer" primary="false" unique="false" type="BTREE">
            <column key="kommunenummer" length="" collation="A" null="false"/>
        </index>
    </object>
</model>

I have created a Snippet (xPDO Generator) with the following code to generate the model-files:

$manager= $modx->getManager();
$modx->setLogLevel(xPDO::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');

$manager= $modx->getManager();
$generator= $manager->getGenerator();
$schema = 'assets/xPDO/schemas/skattelisteperson.mysql.schema.xml';
$target = 'assets/xPDO/sagat/';
$generator->parseSchema($schema,$target);

This gives me the following directory:

Screenshot|393x398

But I see that my mysql table is not created when browsing in MySqlAdmin.

I then try to create the database-table using this code:

$modx->addPackage('skattelistene','assets/xPDO/sagat/skattelistene/', 'skattelistene_');
$manager->createObjectContainer('person');

But this just gives me the errror: Could not load package metadata for package skattelistene.

What am I doing wrong? Is it failing to add the package because the table does not exist? How do I generate the DB-table based on the model? I though the $generator->parseSchema($schema,$target); would do that TBH.

I have spent many hours on this now, and have to admit that doing something as simple as defining a schema, generating a model and table is not very intutivie… either that or I’m just stupid.

My site is hosted in MODx Cloud.

Thanks all.!

I think there is just a problem with the path. You probably have to delete the skattelistene/ at the end of 'assets/xPDO/sagat/skattelistene/' and maybe also add the base path at the beginning.

$modx->addPackage('skattelistene',$modx->getOption('base_path') . 'assets/xPDO/sagat/', 'skattelistene_');
//$manager= $modx->getManager();
$manager->createObjectContainer('person');

Normally I just use the “Package Manager” of the Migx extra, so I don’t have to deal with code/snippets for the creation of packages/db-tables.

It also creates the packages under core/components (where they are usually located) and not in assets/xPDO as you do.

1 Like

What @halftrainedharry says.
Not the best idea to locate them under assets.
Typically they are located under core/components/yourcomponent. I also just use MIGX to parse schemas and create/modify tables, based on the schema.

Thank you both @halftrainedharry and @bruno17 . I will check out the Migx-extra. I have been trying this tutorial: Developing an Extra - Tutorials | MODX Documentation

But seems a bit of an overkill for my simple scenario.

Are there any instructions as how to use Migx to parse my schema and generate model+table? Anything to help me getting started is greatly appreciated.

Thank you.

This should get you started
MIGXdb.Create doodles manager with help of MIGXdb - Tutorials | MODX Documentation
Maybe you don’t need the CMP part

1 Like

There is also this video on youtube if you prefer a more visual instruction.

1 Like

Looks perfect, thanks a lot!! :sunglasses:

One last qustion: for MIGX, is it necessary to to do step 2 of the setup just for parsing schema and creating model+table?

This was only for older versions of MIGX. For the current version it’s no longer needed.

1 Like

MIGX is great, but I have another question: Is there any easy way to delete packages I longer need? Or do I need to manually delete files and tables? @halftrainedharry

I believe there is a function $manager->removeObjectContainer('person'); to delete a db-table, but personally I just use a DROP TABLE SQL statement in phpMyAdmin and delete the class/schema files from the disk manually.

Thank you, I figured as much. Regarding the Default prefix / custom prefix setting, do you have any best practices reganding that? Right now using the Doodles-exapmle, the table name is “modx_doodles”. I guess that is okay, but if I want another prefix: myprefix_doodles, will the default/custom prefix to that? Or is it better to just leave it at the default?

Thank you for all your help, it is immensly appreciated.

What’s commonly done, is to use the default prefix and then add your own prefix to the table name (to avoid naming conflicts).

Here is an example from the Tagger extra (that results in the name modx_tagger_tags for the db-table).

<object class="TaggerTag" table="tagger_tags" extends="xPDOSimpleObject">
	...
</object>

Another example from the Collections extra:

<object class="CollectionTemplate" table="collection_templates" extends="xPDOSimpleObject">
	...
</object>

It’s also a good idea to make the name of the class unique with a prefix. E.g. “YourprefixPerson” instead of just “person”.

<object class="YourprefixPerson" table="yourprefix_person" extends="xPDOSimpleObject">
	...
</object>
1 Like

Thank you, that seems very sensible. Then all then remains is to salute you Sir for your help. :cowboy_hat_face: