125 lines
3.9 KiB
PHP
125 lines
3.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace RprtCli\Utils\TimeTrackingServices\YoutrackRestApi;
|
|
|
|
use RprtCli\Utils\TimeTrackingServices\EntityManagerInterface;
|
|
use RprtCli\Utils\TimeTrackingServices\EntityDefinition;
|
|
use RprtCli\Utils\TimeTrackingServices\EntityInterface;
|
|
use Symfony\Component\Finder\Finder;
|
|
|
|
class EntityManager implements EntityManagerInterface {
|
|
|
|
protected const ENTITIES_DIR = 'YoutrackEntityTypes';
|
|
|
|
protected const ENTITIES_NAMESPACE = 'RprtCli\\Utils\\TimeTrackingServices\\YoutrackRestApi';
|
|
|
|
protected ?array $entityDefinitions = null;
|
|
|
|
public function __construct(protected Finder $finder) {
|
|
$this->finder = $finder;
|
|
}
|
|
|
|
/**
|
|
* Attributes based discovery from EntityTypes folder.
|
|
*/
|
|
public function list() :array {
|
|
return $this->listEntityDefinitions();
|
|
}
|
|
|
|
/**
|
|
* Returns all the entity definitions.
|
|
*/
|
|
public function listEntityDefinitions() {
|
|
if (!$this->entityDefinitions) {
|
|
$this->discoverEntities();
|
|
}
|
|
return $this->entityDefinitions;
|
|
}
|
|
|
|
/**
|
|
* Discovers entity definitions.
|
|
*/
|
|
private function discoverEntities() {
|
|
if (!empty($this->entityDefinitions)) {
|
|
return $this->entityDefinitions;
|
|
}
|
|
$path = __DIR__ . '/' . self::ENTITIES_DIR;
|
|
$definitions = [];
|
|
// @todo create a proxy service for finder.
|
|
$this->finder->files()->in($path);
|
|
/** @var SplFileInfo $file */
|
|
foreach ($this->finder as $file) {
|
|
$class = self::ENTITIES_NAMESPACE . '\\' . self::ENTITIES_DIR . '\\' . $file->getBasename('.php');
|
|
$reflection = new \ReflectionClass($class);
|
|
$attribute = $this->getAttributeOfInstance($reflection, EntityDefinition::class);
|
|
// We expect a single attribute of this kind.
|
|
if (!$attribute) {
|
|
var_dump($file);
|
|
continue;
|
|
}
|
|
$instance = $attribute->newInstance();
|
|
$id = $instance->getId();
|
|
$content = $instance->getDefinition();
|
|
$content['class'] = $class;
|
|
$definitions[$id] = $content;
|
|
}
|
|
$this->entityDefinitions = $definitions;
|
|
return $definitions;
|
|
}
|
|
|
|
/**
|
|
* Returns an attribute of a given instance or NULL.
|
|
*
|
|
* @param \ReflectionClass $reflection
|
|
* The reflection class.
|
|
* @param string $instance
|
|
* The instance the attribute should be of.
|
|
*
|
|
* @return
|
|
* The attribute instance.
|
|
*/
|
|
protected function getAttributeOfInstance(\ReflectionClass $reflection, string $instance) {
|
|
$t = $reflection->getAttributes();
|
|
var_dump($t);
|
|
var_dump($t[0]->getName());
|
|
var_dump($t[0]->getArguments());
|
|
var_dump($t[0]->newInstance());
|
|
$s = $reflection->getAttributes(EntityDefinition::class, \ReflectionAttribute::IS_INSTANCEOF);
|
|
var_dump($s);
|
|
$attributes = $reflection->getAttributes($instance, \ReflectionAttribute::IS_INSTANCEOF);
|
|
var_dump($attributes);
|
|
if (empty($attributes)) {
|
|
return NULL;
|
|
}
|
|
|
|
return reset($attributes);
|
|
}
|
|
|
|
public function getDefinition(string $id) :?array {
|
|
if (!isset($this->entityDefinitions)) {
|
|
$this->list();
|
|
}
|
|
if (!isset($this->entityDefinitions[$id])) {
|
|
// @TODO maybe we should throw an error here.
|
|
return NULL;
|
|
}
|
|
return $this->entityDefinitions[$id];
|
|
}
|
|
|
|
public function createInstance(string $id, array $values) :?EntityInterface {
|
|
if (!isset($this->entityDefinitions)) {
|
|
$this->list();
|
|
}
|
|
if (!isset($this->entityDefinitions[$id])) {
|
|
// @TODO maybe we should throw an error here.
|
|
return NULL;
|
|
}
|
|
$definition = $this->getDefinition($id);
|
|
$reflection = new \ReflectionClass($definition['class']);
|
|
return new $reflection->newInstanceArgs($values);
|
|
}
|
|
|
|
}
|