marius
marius

Reputation: 1266

Where to define table/entity classes when using the standalone CakePHP ORM?

I am using the standalone sub-project 'cakephp-ORM' of cakephp CakePHP-orm.

I cannot find in the documentation where on the filesystem to define tables and entities.

It is explained how to create tables, but not where to save them to. Will the table then be called on autoload or do you have to require / include them yourself? Documentation chapter

Thanks in advance!

Upvotes: 3

Views: 1738

Answers (2)

ndm
ndm

Reputation: 60453

You might want to create an issue over at GitHub, as the documentation for standalone usage surely could be improved.

The conventions are similar to those for a CakePHP app

When used standalone, the ORM will by default lookup table and entity classes in the Model\Table and Model\Entity namespace, and table classes are expected to use a Table suffix. So using $locator->get('Articles') will look for \Model\Table\ArticlesTable, and if such a table class exists, the respective entity class will be looked up as \Model\Entity\Article.

These are pretty much the same conventions that exists when the ORM is used in a CakePHP application, except that in a CakePHP application there is usually a base namespace that is configured via the App.namespace configuration option. You can use that with the standalone ORM too, ie if you do:

\Cake\Core\Configure::write('App.namespace', 'MyApp');

it will be picked up and prepended when looking up classes, given the example above, that would be \MyApp\Model\Table\ArticlesTable and \MyApp\Model\Entity\Article. When such classes do not exist, the ORM will use so called generic/auto-tables, that is instances of \Cake\ORM\Table and \Cake\ORM\Entity instead of concrete subclasses thereof.

Autoloading is up to you

Where you place the files in the filesystem is completely up to you, you just need to make sure that they are auto-loadable via those names. If you for example use PSR-4 autoloading like this:

"autoload": {
    "psr-4": {
        "MyApp\\": "src/"
    }
}

then the respective files would be src/Model/Table/ArticlesTable.php and src/Model/Entity/Article.php, and you'd configure the base namespace as shown above.

You can use fully qualified names instead of reyling on naming conventions

It's also possible to use FQNs for tables and entities, for example:

$table = $locator->get('Articles', [
    'className' => \Custom\Fully\Qualified\Name\To\ArticlesTable::class
]);

The custom FQN for the entity and associations can be set in the respective table class:

namespace Custom\Fully\Qualified\Name\To;

use Cake\ORM\Table;

class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        $this->setEntityClass(\Custom\Fully\Qualified\Name\To\Article::class);

        $this->hasMany('Comments', [
            'className' => \Custom\Fully\Qualified\Name\To\CommentsTable::class
        ]);
    }
}

So $table will be an instance of \Custom\Fully\Qualified\Name\To\ArticlesTable, querying records will return \Custom\Fully\Qualified\Name\To\Article instances, and containing Comments will use \Custom\Fully\Qualified\Name\To\CommentsTable.

See also

With that in mind you should be able to refer to the CakePHP ORM docs for further usage.

Upvotes: 6

Jan Myszkier
Jan Myszkier

Reputation: 2744

according to https://book.cakephp.org/3.0/en/orm.html all you have to do is to extend your Table from Cake\ORM\Table and as long as the table is autoloaded (i.e comes from a composer package) or loaded manually (i.e via include) it should be recognized by the TableRegistry.

i.e this simple example php file using cake-orm as the only composer dependency (my example loads the custom model manually):

<?php

include('vendor/autoload.php');

include 'App/Models/Table/ExamplesTable.php';

use Cake\Datasource\ConnectionManager;
use Cake\ORM\TableRegistry;

ConnectionManager::setConfig('default', [
    'className' => 'Cake\Database\Connection',
    'driver' => 'Cake\Database\Driver\Mysql',
    'database' => 'cakephpormtest',
    'username' => 'root',
    'password' => '',
    'cacheMetadata' => false,
    'quoteIdentifiers' => false,
]);

// Now $examples is an array of Cake\ORM\Entity instances.
$examples = TableRegistry::getTableLocator()->get('Examples')->query()->toArray();
var_dump($examples);

I wouldn't expect standalone library to tell you where should you store your files, so I think the best answer is: put your table models where you want. How you structure your project and load your classes is up to you. I'd still refer to global best practices in programming when doing this, but that's all :)

Upvotes: 1

Related Questions