Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OOP config concept [NO MERGE] #5

Open
wants to merge 13 commits into
base: master
from
@@ -20,9 +20,13 @@ Specify config file in `params` section for `composer-config-plugin`\
[How to configure DBAL connections](https://github.com/cycle/docs/blob/master/basic/connect.md)
```php
<?php
use Yiisoft\Yii\Cycle\CycleDbalConfig;
use Yiisoft\Yii\Cycle\CycleCommonConfig;
use Yiisoft\Yii\Cycle\CycleMigrationConfig;
return [
// cycle DBAL config
'cycle.dbal' => [
CycleDbalConfig::class => [
'default' => 'default',
'aliases' => [],
'databases' => [
@@ -39,14 +43,14 @@ return [
],
// cycle common config
'cycle.common' => [
CycleCommonConfig::class => [
'entityPaths' => [
'@src/Entity'
],
],
// cycle migration config
'cycle.migrations' => [
CycleMigrationConfig::class => [
'directory' => '@root/migrations',
'namespace' => 'App\\Migration',
'table' => 'migration',
@@ -3,6 +3,7 @@
use Cycle\ORM\ORMInterface;
use Psr\Container\ContainerInterface;
use Spiral\Database\DatabaseManager;
use Yiisoft\Yii\Cycle;
use Yiisoft\Yii\Cycle\Factory\DbalFactory;
use Yiisoft\Yii\Cycle\Factory\OrmFactory;
use Yiisoft\Yii\Cycle\Generator\AnnotatedSchemaConveyor;
@@ -14,14 +15,13 @@
return [
// Cycle DBAL
DatabaseManager::class => new DbalFactory($params['cycle.dbal']),
DatabaseManager::class => new DbalFactory(),
// Cycle ORM
ORMInterface::class => new OrmFactory(),
SchemaConveyorInterface::class => static function (ContainerInterface $container) use (&$params) {
SchemaConveyorInterface::class => static function (ContainerInterface $container) {
$conveyor = new AnnotatedSchemaConveyor($container);
$conveyor->addEntityPaths($params['cycle.common']['entityPaths']);
$conveyor->addEntityPaths($container->get(Cycle\CycleCommonConfig::class)->entityPaths);
return $conveyor;
}
];
},
] + (new Cycle\Config\DIConfigGenerator($params))->generate();
@@ -11,6 +11,6 @@
return [
Migrator::class => new MigratorFactory(),
MigrationConfig::class => new MigrationConfigFactory($params['cycle.migrations']),
MigrationConfig::class => new MigrationConfigFactory(),
];
@@ -1,7 +1,7 @@
<?php
use Spiral\Database\Driver\SQLite\SQLiteDriver;
use Yiisoft\Yii\Cycle\Command;
use Yiisoft\Yii\Cycle;
return [
// Console commands
@@ -12,26 +12,4 @@
'migrate/down' => Command\DownCommand::class,
'migrate/list' => Command\ListCommand::class,
],
// DBAL config
'cycle.dbal' => [
'default' => null,
'aliases' => [],
'databases' => [],
'connections' => [],
],
// common config
'cycle.common' => [
'entityPaths' => [],
],
// migration config
'cycle.migrations' => [
'directory' => '@root/migrations',
'namespace' => 'App\\Migration',
'table' => 'migration',
'safe' => false,
],
];
@@ -0,0 +1,78 @@
<?php
namespace Yiisoft\Yii\Cycle\Config;
use Yiisoft\Yii\Cycle\Config\Exception\PropertyNotFoundException;
class BaseConfig
{
public function __get($name)
{
$getter = 'get' . ucfirst($name);
if (method_exists($this, $getter)) {
return $this->$getter();
}
if (property_exists($this, $name)) {
return $this->$name;
}
throw new PropertyNotFoundException("The `$name` property not found in a " . static::class . " object");
}
public function __call($name, $arguments)
{
$prefix = substr($name, 0, 3);
if ($prefix === 'get') {
$prop = lcfirst(substr($name, 3));
if (!property_exists($this, $prop)) {
throw new PropertyNotFoundException("The `$name` property was not found when the `$name` method was called");
}
return $this->$prop;
}
throw new \BadMethodCallException();
}
public function configure(array $params): void
{
foreach ($params as $name => $value) {
$setter = 'set' . ucfirst($name);
if (method_exists($this, $setter)) {
$this->$setter($value);
} elseif (property_exists($this, $name)) {
$this->$name = $value;
} else {
throw new PropertyNotFoundException("The `$name` property not found when configure " . static::class . " object");
}
}
}
/**
* Return all public and protected properties as array.
* Property values will be obtained using getter methods.
* Note: all private properties will be ignored!
* @return array
* @throws PropertyNotFoundException
*/
public function toArray(): array
{
$result = [];
$arrayed = (array)$this;
$keys = array_keys($arrayed);
foreach ($keys as $key) {
if ($key[0] !== chr(0)) {
// public property
$result[$key] = $this->__get($key);
} elseif ($key[1] === '*') {
// protected property
$key = substr($key, 3);
$result[$key] = $this->__get($key);
} else {
// private property
// ignore
}
}
return $result;
}
}
@@ -0,0 +1,27 @@
<?php
namespace Yiisoft\Yii\Cycle\Config;
class DIConfigGenerator
{
private $params;
public function __construct(array &$params)
{
$this->params = &$params;
}
public function generate(): array
{
$result = [];
foreach ($this->params as $key => &$config) {
if (is_a($key, BaseConfig::class, true)) {
$result[$key] = [
'__class' => $key,
'configure()' => [&$config]
];
}
}
return $result;
}
}
@@ -0,0 +1,19 @@
<?php
namespace Yiisoft\Yii\Cycle\Config\Exception;
use Yiisoft\FriendlyException\FriendlyExceptionInterface;
class PropertyNotFoundException extends \Exception implements FriendlyExceptionInterface
{
public function getName(): string
{
return 'Unsupported property';
}
public function getSolution(): ?string
{
return "Perhaps you made a mistake in the name of the config parameter.\n"
. "Verify that the specified configuration parameters are correct.";
}
}
@@ -0,0 +1,18 @@
<?php
namespace Yiisoft\Yii\Cycle;
use Yiisoft\Yii\Cycle\Config\BaseConfig;
/**
* @property-read array $entityPaths
* @property-read string $cacheKey
*
* @method array getEntityPaths()
* @method string getCacheKey()
*/
class CycleCommonConfig extends BaseConfig
{
protected $entityPaths = [];
protected $cacheKey = 'Cycle-ORM-Schema';
}
@@ -0,0 +1,58 @@
<?php
namespace Yiisoft\Yii\Cycle;
use Spiral\Database\Config\DatabaseConfig;
use Yiisoft\Aliases\Aliases;
use Yiisoft\Yii\Cycle\Config\BaseConfig;
/**
* @property-read string $default
* @property-read array $aliases
* @property-read array $databases
* @property-read array $connections
*
* @method string getDefault()
* @method array getAliases()
* @method array getDatabases()
* @method array getConnections()
*/
class CycleDbalConfig extends BaseConfig
{
protected $default = '';
protected $aliases = [];
protected $databases = [];
protected $connections = [];
// private property will be ignored in toArray() method
/** @var Aliases */
private $objAliases;
public function __construct(Aliases $aliases)
{
$this->objAliases = $aliases;
}
public function prepareConfig(): DatabaseConfig
{
return new DatabaseConfig($this->toArray());
}
protected function setConnections($data): void
{
$this->connections = $data;
foreach ($this->connections as &$connection) {
// if connection option contain alias in path
if (isset($connection['connection']) && preg_match('/^(?<proto>\w+:)?@/', $connection['connection'], $m)) {
$proto = $m['proto'];
$path = $this->convertAlias(substr($connection['connection'], strlen($proto)));
$connection['connection'] = $proto . $path;
}
}
}
protected function convertAlias(string $alias): string
{
return $this->objAliases->get($alias, true);
}
}
@@ -0,0 +1,42 @@
<?php
namespace Yiisoft\Yii\Cycle;
use Yiisoft\Aliases\Aliases;
use Yiisoft\Yii\Cycle\Config\BaseConfig;
/**
* @property-read string $directory
* @property-read string $namespace
* @property-read string $table
* @property-read bool $safe
*
* @method string getNamespace()
* @method string getTable()
* @method bool getSafe()
*/
class CycleMigrationConfig extends BaseConfig
{
protected $directory = '@root/migrations';
protected $namespace = 'App\\Migration';
protected $table = 'migration';
protected $safe = false;
/** @var Aliases */
private $objAliases;
public function __construct(Aliases $aliases)
{
$this->objAliases = $aliases;
}
protected function getDirectory(): string
{
return $this->convertAlias($this->directory);
}
protected function convertAlias(string $alias): string
{
return $this->objAliases->get($alias, true);
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.