OpenXE/classes/Modules/Api/Engine/ApiContainer.php
2021-05-21 08:49:41 +02:00

302 lines
8.1 KiB
PHP

<?php
namespace Xentral\Modules\Api\Engine;
use ReflectionClass;
use Xentral\Components\Database\Database;
use Xentral\Components\Http\Request;
use Xentral\Modules\Api\Auth\DigestAuth;
use Xentral\Modules\Api\Controller\Version1\AbstractController;
use Xentral\Modules\Api\Converter\Converter;
use Xentral\Modules\Api\Converter\JsonConverter;
use Xentral\Modules\Api\Converter\OpenTransConverter;
use Xentral\Modules\Api\Converter\XmlConverter;
use Xentral\Modules\Api\LegacyBridge\LegacyApiLazyProxy;
use Xentral\Modules\Api\LegacyBridge\LegacyApplication;
use Xentral\Modules\Api\Resource\AbstractResource as AbstractApiResource;
use Xentral\Modules\Api\Resource\ResourceManager;
use Xentral\Modules\Api\Router\Router as ApiRouter;
use Xentral\Modules\Api\Validator\Rule\BooleanRule;
use Xentral\Modules\Api\Validator\Rule\DbValueRule;
use Xentral\Modules\Api\Validator\Rule\DecimalRule;
use Xentral\Modules\Api\Validator\Rule\LengthRule;
use Xentral\Modules\Api\Validator\Rule\LowerRule;
use Xentral\Modules\Api\Validator\Rule\NotPresentRule;
use Xentral\Modules\Api\Validator\Rule\TimeRule;
use Xentral\Modules\Api\Validator\Rule\UniqueRule;
use Xentral\Modules\Api\Validator\Rule\UpperRule;
use Xentral\Modules\Api\Validator\Validator;
final class ApiContainer
{
/** @var array $services Speicher für Service-Instanzen */
private $services = array();
/**
* Service-Instanz von außen injizieren
*
* @param string $name
* @param object $instance
*/
public function add($name, $instance)
{
if (isset($this->services['name'])) {
throw new \RuntimeException(
sprintf('Service "%s" is already registered.', $name)
);
}
$this->services[$name] = $instance;
}
/**
* @param string $name Service-Name oder FQCN
*
* @return object
*/
public function get($name)
{
if ($this->has($name)) {
return $this->services[$name];
}
return $this->createService($name);
}
/**
* @param string $name
*
* @return bool
*/
public function has($name)
{
return isset($this->services[$name]);
}
/**
* @param string $name
*
* @return object
*/
private function createService($name)
{
$createServiceMethod = 'create' . $name . 'Service';
if (!method_exists($this, $createServiceMethod)) {
throw new \RuntimeException(
sprintf(
'Service "%s" could not be created. Container method "%s" is missing.',
$name, $createServiceMethod
)
);
}
$this->services[$name] = $this->$createServiceMethod();
return $this->services[$name];
}
/**
* @param string $contollerClass
* @param Request|null $request
*
* @return AbstractController
*/
public function getApiController($contollerClass, Request $request = null)
{
// @todo
/*$interfaces = class_implements($contollerClass, true);
if (!in_array('Xentral\Modules\Api\Version1\Controller\ControllerInterface', $interfaces, true)) {
throw new \CountryInvalidArgumentException(sprintf(
'"%s" must implement "%s"',
$contollerClass, 'Xentral\Modules\Api\Version1\Controller\ControllerInterface'
));
}*/
$parents = class_parents($contollerClass, true);
if (!in_array(AbstractController::class, $parents, true)) {
throw new \InvalidArgumentException(sprintf(
'"%s" must implement "%s"',
$contollerClass, AbstractController::class
));
}
// Controller nicht sharen!
// Resourcen können sich Controller teilen
return new $contollerClass(
$this->get('LegacyApi'),
$this->get('Database'),
$this->get('Converter'),
$request ?: $this->get('Request'),
$this->get('ResourceManager')
);
}
/**
* @param string $resourceClass
*
* @return AbstractApiResource
*
* @throws \ReflectionException
*/
public function getApiResource($resourceClass)
{
$resourceReflection = new ReflectionClass($resourceClass);
$resourceName = $resourceReflection->getShortName();
if ($this->has($resourceName)) {
return $this->services[$resourceName];
}
$parents = class_parents($resourceClass, true);
if (!in_array(AbstractApiResource::class, $parents, true)) {
throw new \InvalidArgumentException(sprintf(
'"%s" must extend "%s"',
$resourceClass, AbstractApiResource::class
));
}
// @todo
/*$interfaces = class_implements($resourceClass, false);
if (!in_array(ApiResourceInterface::class, $interfaces, true)) {
throw new \CountryInvalidArgumentException(sprintf(
'"%s" must implement "%s"',
$resourceClass, ApiResourceInterface::class
));
}*/
// Resource erzeugen
$resource = new $resourceClass(
$this->get('Database'),
$this->get('Validator')
);
// Resource sharen
$this->add($resourceName, $resource);
return $resource;
}
/**
* @return ResourceManager
*/
private function createResourceManagerService()
{
return new ResourceManager(
$this->get('Database'),
$this->get('Validator'),
$this->get('LegacyApi')
);
}
/**
* @return LegacyApiLazyProxy
*/
private function createLegacyApiService()
{
return new LegacyApiLazyProxy();
}
/**
* @return LegacyApplication
*/
private function createLegacyApplicationService()
{
return new LegacyApplication();
}
/**
* @return DigestAuth
*/
private function createDigestAuthService()
{
return new DigestAuth($this->get('Database'), $this->get('Request'));
}
/**
* @return Database
*/
private function createDatabaseService()
{
/** @var LegacyApplication $legacyApp */
$legacyApp = $this->get('LegacyApplication');
return $legacyApp->Container->get('Database');
}
/**
* @return Validator
*/
private function createValidatorService()
{
$validator = new Validator();
$validator->addValidator('db_value', new DbValueRule($this->get('Database')));
$validator->addValidator('boolean', new BooleanRule());
$validator->addValidator('decimal', new DecimalRule());
$validator->addValidator('length', new LengthRule());
$validator->addValidator('lower', new LowerRule());
$validator->addValidator('not_present', new NotPresentRule());
$validator->addValidator('time', new TimeRule());
$validator->addValidator('unique', new UniqueRule($this->get('Database')));
$validator->addValidator('upper', new UpperRule());
return $validator;
}
/**
* @return Request
*/
private function createRequestService()
{
/** @var LegacyApplication $legacyApp */
$legacyApp = $this->get('LegacyApplication');
return $legacyApp->Container->get('Request');
}
/**
* @return ApiRouter
*/
private function createApiRouterService()
{
return new ApiRouter();
}
/**
* @return Converter
*/
private function createConverterService()
{
return new Converter($this->get('XmlConverter'), $this->get('JsonConverter'));
}
/**
* @return OpenTransConverter
*/
private function createOpenTransConverterService()
{
return new OpenTransConverter();
}
/**
* @return XmlConverter
*/
private function createXmlConverterService()
{
return new XmlConverter();
}
/**
* @return JsonConverter
*/
private function createJsonConverterService()
{
return new JsonConverter();
}
public function __clone()
{
}
public function __wakeup()
{
}
}