Skip to content

Commit

Permalink
Add support to specify the DataProvider in TypoScript
Browse files Browse the repository at this point in the history
  • Loading branch information
cundd committed May 11, 2019
1 parent 34011b6 commit 7e4c93a
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 82 deletions.
4 changes: 3 additions & 1 deletion Classes/Configuration/AbstractConfigurationProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Cundd\Rest\Domain\Model\ResourceType;
use Cundd\Rest\Exception\InvalidConfigurationException;
use Cundd\Rest\SingletonInterface;
use RuntimeException;

/**
* Abstract Configuration Provider
Expand Down Expand Up @@ -91,7 +92,7 @@ public function getResourceConfiguration(ResourceType $resourceType): ?ResourceC
$resourceTypeString = Utility::normalizeResourceType($resourceType);

if (!$resourceTypeString) {
throw new \RuntimeException(
throw new RuntimeException(
sprintf(
'Invalid normalized Resource Type "%s"',
is_null($resourceTypeString) ? 'null' : $resourceTypeString
Expand Down Expand Up @@ -148,6 +149,7 @@ public function getConfiguredResources(): array
$writeAccess,
$cacheLifetime,
isset($configuration['handlerClass']) ? $configuration['handlerClass'] : '',
isset($configuration['dataProviderClass']) ? $configuration['dataProviderClass'] : '',
$this->getAliasesForResourceType($resourceType)
);
}
Expand Down
23 changes: 19 additions & 4 deletions Classes/Configuration/ResourceConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class ResourceConfiguration
* @var string[]
*/
private $aliases;
/**
* @var string
*/
private $dataProviderClass;

/**
* ResourceConfiguration constructor
Expand All @@ -48,23 +52,26 @@ class ResourceConfiguration
* @param Access $write
* @param int $cacheLifetime
* @param string $handlerClass
* @param string $dataProviderClass
* @param string[] $aliases
*/
public function __construct(
ResourceType $resourceType,
Access $read,
Access $write,
$cacheLifetime,
$handlerClass,
int $cacheLifetime,
string $handlerClass,
string $dataProviderClass,
array $aliases
) {
$this->resourceType = $resourceType;
$this->read = $read;
$this->write = $write;
$this->cacheLifetime = (int)$cacheLifetime;
$this->handlerClass = (string)$handlerClass;
$this->cacheLifetime = $cacheLifetime;
$this->handlerClass = $handlerClass;
$this->assertStringArray($aliases);
$this->aliases = $aliases;
$this->dataProviderClass = $dataProviderClass;
}

/**
Expand Down Expand Up @@ -117,6 +124,14 @@ public function getHandlerClass()
return $this->handlerClass;
}

/**
* @return string
*/
public function getDataProviderClass(): string
{
return $this->dataProviderClass;
}

/**
* @return string[]
*/
Expand Down
58 changes: 38 additions & 20 deletions Classes/ObjectManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Cundd\Rest\Handler\CrudHandler;
use Cundd\Rest\Handler\HandlerInterface;
use Cundd\Rest\Http\RestRequestInterface;
use LogicException;
use Psr\Container\ContainerInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager as TYPO3ObjectManager;
Expand Down Expand Up @@ -79,11 +80,16 @@ public function getResponseFactory(): ResponseFactoryInterface
public function getDataProvider(): DataProviderInterface
{
if (!$this->dataProvider) {
list($vendor, $extension, $model) = Utility::getClassNamePartsForResourceType(
$this->getRequest()->getResourceType()
);
$resourceType = $this->getCurrentResourceType();
$this->dataProvider = $this->getImplementationFromResourceConfiguration($resourceType, 'DataProvider');
if ($this->dataProvider) {
return $this->dataProvider;
}

list($vendor, $extension, $model) = Utility::getClassNamePartsForResourceType($resourceType);

$classes = [
// @deprecated register a `dataProviderClass` instead
// Check if an extension provides a Data Provider for the domain model
sprintf('Tx_%s_Rest_%sDataProvider', $extension, $model),
sprintf('%s%s\\Rest\\%sDataProvider', ($vendor ? $vendor . '\\' : ''), $extension, $model),
Expand Down Expand Up @@ -113,7 +119,7 @@ public function getAuthenticationProvider(): AuthenticationProviderInterface
{
if (!$this->authenticationProvider) {
list($vendor, $extension,) = Utility::getClassNamePartsForResourceType(
$this->getRequest()->getResourceType()
$this->getCurrentResourceType()
);

// Check if an extension provides a Authentication Provider
Expand Down Expand Up @@ -151,7 +157,7 @@ public function getAccessController(): AccessControllerInterface
{
if (!$this->accessController) {
list($vendor, $extension,) = Utility::getClassNamePartsForResourceType(
$this->getRequest()->getResourceType()
$this->getCurrentResourceType()
);

// Check if an extension provides a Authentication Provider
Expand All @@ -172,8 +178,8 @@ public function getAccessController(): AccessControllerInterface

public function getHandler(): HandlerInterface
{
$resourceType = $this->getRequest()->getResourceType();
$handler = $this->getHandlerFromResourceConfiguration($resourceType);
$resourceType = $this->getCurrentResourceType();
$handler = $this->getImplementationFromResourceConfiguration($resourceType, 'Handler');
if ($handler) {
return $handler;
}
Expand Down Expand Up @@ -222,10 +228,16 @@ public function reassignRequest()
$this->accessController = null;
}

public function __call($name, $arguments)
{
return call_user_func_array([$this->container, $name], $arguments);
}

/**
* Returns the current request
*
* @return RestRequestInterface
* @deprecated
*/
protected function getRequest()
{
Expand All @@ -238,7 +250,7 @@ protected function getRequest()
* @param string[] $classes
* @param string $default
* @return string
* @throws \LogicException
* @throws LogicException
*/
private function getFirstExistingClass(array $classes, $default = '')
{
Expand All @@ -249,17 +261,18 @@ private function getFirstExistingClass(array $classes, $default = '')
}

if ($default === '') {
throw new \LogicException('No existing class found');
throw new LogicException('No existing class found');
}

return $default;
}

/**
* @param ResourceType $resourceType
* @return HandlerInterface|null
* @param string $type
* @return object|null|mixed
*/
private function getHandlerFromResourceConfiguration(ResourceType $resourceType)
private function getImplementationFromResourceConfiguration(ResourceType $resourceType, string $type)
{
$resourceConfiguration = $this->getConfigurationProvider()->getResourceConfiguration($resourceType);
if (!$resourceConfiguration) {
Expand All @@ -268,26 +281,31 @@ private function getHandlerFromResourceConfiguration(ResourceType $resourceType)
sprintf('Resource "%s" is not configured', (string)$resourceType)
);
}
$handlerClass = $resourceConfiguration->getHandlerClass();
if (!$handlerClass) {

$getter = 'get' . ucfirst($type) . 'Class';
$implementation = $resourceConfiguration->$getter();
if (!$implementation) {
return null;
}

if (!class_exists($handlerClass)) {
if (!class_exists($implementation)) {
throw new InvalidConfigurationException(
sprintf('Configured Handler "%s" does not exist', $handlerClass)
sprintf('Configured %s "%s" does not exist', $type, $implementation)
);
}

if ($handlerClass[0] === '\\') {
$handlerClass = substr($handlerClass, 1);
if ($implementation[0] === '\\') {
$implementation = substr($implementation, 1);
}

return $this->get($handlerClass);
return $this->get($implementation);
}

public function __call($name, $arguments)
/**
* @return ResourceType
*/
private function getCurrentResourceType(): ResourceType
{
return call_user_func_array([$this->container, $name], $arguments);
return $this->getRequestFactory()->getRequest()->getResourceType();
}
}
30 changes: 18 additions & 12 deletions Tests/ClassBuilderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
namespace Cundd\Rest\Tests;


use Exception;
use InvalidArgumentException;

trait ClassBuilderTrait
{
/**
Expand All @@ -12,9 +15,10 @@ trait ClassBuilderTrait
* @param string|array $className
* @param string $namespace
* @param string $extends
* @throws \Exception
* @param bool $silent
* @throws Exception
*/
public static function buildClass($className, $namespace = '', $extends = '')
public static function buildClass($className, string $namespace = '', string $extends = '', bool $silent = false)
{
list($preparedClassName, $preparedNamespace, $preparedExtends) = self::buildClassSignature(
$className,
Expand All @@ -23,15 +27,17 @@ public static function buildClass($className, $namespace = '', $extends = '')
);

if (class_exists("$preparedNamespace\\$preparedClassName")) {
printf('Class %s already exists' . PHP_EOL, "$preparedNamespace\\$preparedClassName");
if (!$silent) {
printf('Class %s already exists' . PHP_EOL, "$preparedNamespace\\$preparedClassName");
}

return;
}

static::buildCode('class', $preparedClassName, $preparedNamespace, $preparedExtends);

if (!class_exists("$preparedNamespace\\$preparedClassName")) {
throw new \Exception(sprintf('Could not create class %s', "$preparedNamespace\\$preparedClassName"));
throw new Exception(sprintf('Could not create class %s', "$preparedNamespace\\$preparedClassName"));
}
}

Expand All @@ -41,7 +47,7 @@ public static function buildClass($className, $namespace = '', $extends = '')
* @param string $className
* @param string $namespace
* @param string $extends
* @throws \Exception
* @throws Exception
*/
public static function buildClassIfNotExists($className, $namespace = '', $extends = '')
{
Expand All @@ -62,7 +68,7 @@ public static function buildClassIfNotExists($className, $namespace = '', $exten
* @param string $interfaceName
* @param string $namespace
* @param string $extends
* @throws \Exception
* @throws Exception
*/
public static function buildInterface($interfaceName, $namespace = '', $extends = '')
{
Expand All @@ -81,7 +87,7 @@ public static function buildInterface($interfaceName, $namespace = '', $extends
static::buildCode('interface', $preparedClassName, $preparedNamespace, $preparedExtends);

if (!interface_exists("$preparedNamespace\\$preparedClassName")) {
throw new \Exception(sprintf('Could not create interface %s', "$preparedNamespace\\$preparedClassName"));
throw new Exception(sprintf('Could not create interface %s', "$preparedNamespace\\$preparedClassName"));
}
}

Expand All @@ -91,7 +97,7 @@ public static function buildInterface($interfaceName, $namespace = '', $extends
* @param string $className
* @param string $namespace
* @param string $extends
* @throws \Exception
* @throws Exception
*/
public static function buildInterfaceIfNotExists($className, $namespace = '', $extends = '')
{
Expand All @@ -113,7 +119,7 @@ public static function buildInterfaceIfNotExists($className, $namespace = '', $e
* @param string $preparedClassName
* @param string $preparedNamespace
* @param string $preparedExtends
* @throws \Exception
* @throws Exception
*/
protected static function buildCode($type, $preparedClassName, $preparedNamespace, $preparedExtends)
{
Expand Down Expand Up @@ -147,13 +153,13 @@ protected static function buildClassSignature($className, $namespace = '', $exte
}

if (!is_string($className)) {
throw new \InvalidArgumentException('$className must be a string');
throw new InvalidArgumentException('$className must be a string');
}
if (!is_string($namespace)) {
throw new \InvalidArgumentException('$namespace must be a string');
throw new InvalidArgumentException('$namespace must be a string');
}
if (!is_string($extends)) {
throw new \InvalidArgumentException('$extends must be a string');
throw new InvalidArgumentException('$extends must be a string');
}

$preparedClassName = $className;
Expand Down
Loading

0 comments on commit 7e4c93a

Please sign in to comment.