Zend Expressive and Cycle ORM.
Sergey Telpuk
Posted on July 3, 2019
Hello, community. I decided to write a short article is dedicated to Zend Expressive(ZE) & Cycle ORM(CycleORM). Let's go ahead!
For setting up ZE there can be used the skeleton application and installer.
It's an easy way of starting working with ZE. After that, to add CycleORM dependancies:
composer require cycle/orm
composer require cycle/annotated
composer require cycle/schema-builder
For the next step, should add a folder (call like 'cycle-factories' or another name as willing):
project
│
└───cycle-factories
│ └───CycleFactory.php
└───TransactionFactory.php
Should change composer-autoload, can look like:
"autoload": {
"psr-4": {
"App\\": "src/App/src/",
"Cycle\\": "cycle-factories/"
}
},
CycleFactory.php
<?php declare(strict_types=1);
namespace Cycle;
use Cycle\Annotated\{Embeddings, Entities};
use Cycle\ORM\{Factory, ORM, ORMInterface, Schema as OrmSchema};
use Cycle\Schema\{Compiler, Registry};
use Cycle\Schema\Generator\{GenerateRelations,
GenerateTypecast,
RenderRelations,
RenderTables,
ResetTables,
SyncTables,
ValidateEntities};
use Psr\Container\ContainerInterface;
use Spiral\Database\{DatabaseManager};
use Spiral\Database\Config\{DatabaseConfig};
use Spiral\Database\Exception\{ConfigException};
use Spiral\Tokenizer\ClassLocator;
use Symfony\Component\Finder\Finder;
class CycleFactory
{
/**
* @param ContainerInterface $container
* @return ORMInterface
*/
public function __invoke(ContainerInterface $container): ORMInterface
{
$config = $container->has('config')
? $container->get('config')
: [];
if (!isset($config['cycle'])) {
throw new ConfigException('Expected config databases');
}
$config = $config['cycle'];
$entities = $config['entities'];
$finder = (new Finder())->files()->in($entities);
$cl = new ClassLocator($finder);
$dbal = new DatabaseManager(new DatabaseConfig($config));
$schema = (new Compiler())->compile(new Registry($dbal), [
new Embeddings($cl), // register embeddable entities
new Entities($cl), // register annotated entities
new ResetTables(), // re-declared table schemas (remove columns)
new GenerateRelations(), // generate entity relations
new ValidateEntities(), // make sure all entity schemas are correct
new RenderTables(), // declare table schemas
new RenderRelations(), // declare relation keys and indexes
new SyncTables(), // sync table changes to database
new GenerateTypecast(), // typecast non string columns
]);
$orm = new ORM(new Factory($dbal));
$orm = $orm->withSchema(new OrmSchema($schema));
return $orm;
}
}
TransactionFactory.php
<?php declare(strict_types=1);
namespace Cycle;
use Cycle\ORM\ORMInterface;
use Cycle\ORM\Transaction;
use Cycle\ORM\TransactionInterface;
use Psr\Container\ContainerInterface;
class TransactionFactory
{
/**
* @param ContainerInterface $container
* @return TransactionInterface
*/
public function __invoke(ContainerInterface $container): TransactionInterface
{
return new Transaction($container->get(ORMInterface::class));
}
}
For the next step, should add a config file:
project
│
└───config
│ │
│ └───autoload
│ └───cycle.global.php(cycle.local.php)
│ │ ...
cycle.global.php can look like (For another configuration to follow the documentation link):
<?php declare(strict_types=1);
use Spiral\Database;
return [
'cycle' => [
'default' => 'default',
'databases' => [
'default' => ['connection' => 'sqlite']
],
'connections' => [
'sqlite' => [
'driver' => Database\Driver\SQLite\SQLiteDriver::class,
'connection' => 'sqlite:database.db',
'username' => '',
'password' => '',
]
],
'entities' => [//array of Entities
'src/App/src/Entities'//it depends on a structure of the project
]
]
];
For the next step, should add global dependencies:
project
│
└───config
│ │
│ └───autoload
│ └───dependencies.global.php(dependencies.local.php)
│ │ ...
dependencies.global.php can look like:
<?php declare(strict_types=1);
return [
...
'factories' => [
\Cycle\ORM\ORMInterface::class => \Cycle\CycleFactory::class,
\Cycle\ORM\TransactionInterface::class => \Cycle\TransactionFactory::class,
],
],
];
For testing Cycle ORM to look at an attached screenshot use example.
Posted on July 3, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.