Skip to content

Commit

Permalink
Refactor: add more types
Browse files Browse the repository at this point in the history
  • Loading branch information
f3l1x committed Jul 4, 2023
1 parent c9a9b1b commit 276791b
Show file tree
Hide file tree
Showing 125 changed files with 808 additions and 1,040 deletions.
21 changes: 19 additions & 2 deletions ruleset.xml
Expand Up @@ -3,7 +3,7 @@
<description>Contributte</description>

<!-- Extending rulesets -->
<rule ref="./vendor/contributte/qa/ruleset.xml"/>
<rule ref="./vendor/contributte/qa/ruleset-8.0.xml"/>

<!-- Specific rules -->
<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
Expand All @@ -25,6 +25,15 @@
<exclude-pattern>*tests/Cases/*</exclude-pattern>
</rule>

<rule ref="SlevomatCodingStandard.PHP.DisallowReference">
<exclude-pattern>src/Core/Schema/Serialization/ArraySerializator.php</exclude-pattern>
<exclude-pattern>tests/Cases/OpenApi/Schema/ExamplesTest.php</exclude-pattern>
</rule>

<rule ref="SlevomatCodingStandard.Classes.SuperfluousErrorNaming">
<exclude-pattern>src/Core/Dispatcher/DispatchError.php</exclude-pattern>
</rule>

<rule ref="Squiz.Classes.ClassFileName.NoMatch">
<exclude-pattern>*tests/Cases/*</exclude-pattern>
</rule>
Expand All @@ -33,7 +42,15 @@
<exclude-pattern>*tests/Cases/*</exclude-pattern>
</rule>

<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.PartialUse">
<exclude-pattern>tests</exclude-pattern>
</rule>

<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint">
<exclude-pattern>tests</exclude-pattern>
</rule>

<!-- Exclude folders -->
<exclude-pattern>/tests</exclude-pattern>
<exclude-pattern>/tests/tmp</exclude-pattern>
</ruleset>

2 changes: 1 addition & 1 deletion src/Core/Annotation/Controller/Method.php
Expand Up @@ -22,7 +22,7 @@ final class Method
/**
* @param string[]|string $methods
*/
public function __construct($methods)
public function __construct(array|string $methods)
{
if (empty($methods)) {
throw new AnnotationException('Empty @Method given');
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Annotation/Controller/Negotiations.php
Expand Up @@ -20,7 +20,7 @@ final class Negotiations
/**
* @param Negotiation[]|Negotiation $negotiations
*/
public function __construct($negotiations)
public function __construct(array|Negotiation $negotiations)
{
if (empty($negotiations)) {
throw new AnnotationException('Empty @Negotiations given');
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Annotation/Controller/RequestParameters.php
Expand Up @@ -20,7 +20,7 @@ class RequestParameters
/**
* @param RequestParameter[]|RequestParameter $parameters
*/
public function __construct($parameters)
public function __construct(array|RequestParameter $parameters)
{
if (empty($parameters)) {
throw new AnnotationException('Empty @RequestParameters given');
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Annotation/Controller/Responses.php
Expand Up @@ -20,7 +20,7 @@ final class Responses
/**
* @param Response[]|Response $responses
*/
public function __construct($responses)
public function __construct(array|Response $responses)
{
if (empty($responses)) {
throw new AnnotationException('Empty @Responses given');
Expand Down
1 change: 1 addition & 0 deletions src/Core/Application/Application.php
Expand Up @@ -16,6 +16,7 @@ class Application extends BaseApplication
public function __construct(IErrorHandler $errorHandler, IDispatcher $dispatcher)
{
parent::__construct($errorHandler);

$this->dispatcher = $dispatcher;
}

Expand Down
12 changes: 6 additions & 6 deletions src/Core/DI/ApiExtension.php
Expand Up @@ -24,12 +24,17 @@ class ApiExtension extends CompilerExtension
public const NEGOTIATION_NEGOTIATOR_TAG = 'apitte.negotiation.negotiator';
public const NEGOTIATION_RESOLVER_TAG = 'apitte.negotiation.resolver';

/** @var PluginManager */
private PluginManager $pm;

public function __construct()
{
$this->pm = new PluginManager($this);
}

public function getConfigSchema(): Schema
{
$parameters = $this->getContainerBuilder()->parameters;

return Expect::structure([
'catchException' => Expect::bool(true),
'debug' => Expect::bool($parameters['debugMode'] ?? false),
Expand All @@ -40,11 +45,6 @@ public function getConfigSchema(): Schema
]);
}

public function __construct()
{
$this->pm = new PluginManager($this);
}

public function loadConfiguration(): void
{
$config = $this->config;
Expand Down
11 changes: 11 additions & 0 deletions src/Core/DI/Loader/DoctrineAnnotationLoader.php
Expand Up @@ -98,6 +98,7 @@ protected function analyseClass(string $class): ReflectionClass
if (isset($this->meta['services'][$parentClass])) {
// Just reference it in reflections
$reflections[$parentClass] = $this->meta['services'][$parentClass]['reflection'];

continue;
}

Expand Down Expand Up @@ -136,6 +137,7 @@ protected function parseControllerClassAnnotations(Controller $controller, Refle
// Parse @Path =======================
if ($annotation instanceof Path) {
$controller->setPath($annotation->getPath());

continue;
}

Expand All @@ -152,6 +154,7 @@ protected function parseControllerClassAnnotations(Controller $controller, Refle
// Parse @OpenApi ============================
if ($annotation instanceof OpenApi) {
$controller->setOpenApi(Neon::decode($annotation->getData()) ?? []);

continue;
}
}
Expand Down Expand Up @@ -204,24 +207,28 @@ protected function parseControllerMethodsAnnotations(Controller $controller, Ref
// Parse @Path =============================
if ($annotation instanceof Path) {
$schemaMethod->setPath($annotation->getPath());

continue;
}

// Parse @Method ===========================
if ($annotation instanceof Method) {
$schemaMethod->addHttpMethods($annotation->getMethods());

continue;
}

// Parse @Tag ==============================
if ($annotation instanceof Tag) {
$schemaMethod->addTag($annotation->getName(), $annotation->getValue());

continue;
}

// Parse @Id ===============================
if ($annotation instanceof Id) {
$schemaMethod->setId($annotation->getName());

continue;
}

Expand All @@ -237,6 +244,7 @@ protected function parseControllerMethodsAnnotations(Controller $controller, Ref
// Parse #[RequestParameter] ================
if ($annotation instanceof RequestParameter) {
$this->addEndpointParameterToSchemaMethod($schemaMethod, $annotation);

continue;
}

Expand All @@ -252,6 +260,7 @@ protected function parseControllerMethodsAnnotations(Controller $controller, Ref
// Parse #[Response] attribute
if ($annotation instanceof Response) {
$this->addResponseToSchemaMethod($schemaMethod, $annotation);

continue;
}

Expand All @@ -263,12 +272,14 @@ protected function parseControllerMethodsAnnotations(Controller $controller, Ref
$requestBody->setRequired($annotation->isRequired());
$requestBody->setValidation($annotation->isValidation());
$schemaMethod->setRequestBody($requestBody);

continue;
}

// Parse @OpenApi ================
if ($annotation instanceof OpenApi) {
$schemaMethod->setOpenApi(Neon::decode($annotation->getData()) ?? []);

continue;
}

Expand Down
1 change: 1 addition & 0 deletions src/Core/DI/LoaderFactory/DualReaderFactory.php
Expand Up @@ -20,6 +20,7 @@ public function create(): Reader
AnnotationRegistry::registerUniqueLoader('class_exists');

$attributeReader = new AttributeReader();

return new DualReader($annotationReader, $attributeReader);
}

Expand Down
21 changes: 11 additions & 10 deletions src/Core/DI/Plugin/CoreMappingPlugin.php
Expand Up @@ -40,16 +40,6 @@ public static function getName(): string
return 'mapping';
}

protected function getConfigSchema(): Schema
{
return Expect::structure([
'types' => Expect::arrayOf('string', 'string'),
'request' => Expect::structure([
'validator' => Expect::type('string|array|' . Statement::class)->default(NullValidator::class),
]),
]);
}

/**
* Register services
*/
Expand Down Expand Up @@ -95,7 +85,18 @@ public function getAllowedTypes(): array
{
/** @var array<string> $configuredTypes */
$configuredTypes = array_keys($this->config->types);

return array_merge(EndpointParameter::TYPES, $configuredTypes);
}

protected function getConfigSchema(): Schema
{
return Expect::structure([
'types' => Expect::arrayOf('string', 'string'),
'request' => Expect::structure([
'validator' => Expect::type('string|array|' . Statement::class)->default(NullValidator::class),
]),
]);
}

}
35 changes: 18 additions & 17 deletions src/Core/DI/Plugin/CoreSchemaPlugin.php
Expand Up @@ -40,6 +40,23 @@ public static function getName(): string
return 'schema';
}

/**
* Decorate services
*/
public function beforePluginCompile(): void
{
// Receive container builder
$builder = $this->getContainerBuilder();

// Register services
$builder->addDefinition($this->extensionPrefix('core.schema.hydrator'))
->setFactory(ArrayHydrator::class);

$schemaDefinition = $builder->getDefinition($this->extensionPrefix('core.schema'));
assert($schemaDefinition instanceof ServiceDefinition);
$schemaDefinition->setFactory('@' . $this->extensionPrefix('core.schema.hydrator') . '::hydrate', [$this->compileSchema()]);
}

protected function getConfigSchema(): Schema
{
return Expect::structure([
Expand All @@ -66,23 +83,6 @@ protected function getConfigSchema(): Schema
]);
}

/**
* Decorate services
*/
public function beforePluginCompile(): void
{
// Receive container builder
$builder = $this->getContainerBuilder();

// Register services
$builder->addDefinition($this->extensionPrefix('core.schema.hydrator'))
->setFactory(ArrayHydrator::class);

$schemaDefinition = $builder->getDefinition($this->extensionPrefix('core.schema'));
assert($schemaDefinition instanceof ServiceDefinition);
$schemaDefinition->setFactory('@' . $this->extensionPrefix('core.schema.hydrator') . '::hydrate', [$this->compileSchema()]);
}

/**
* @return mixed[]
*/
Expand All @@ -104,6 +104,7 @@ protected function compileSchema(): array

// Convert schema to array (for DI)
$generator = new ArraySerializator();

return $generator->serialize($builder);
}

Expand Down
45 changes: 24 additions & 21 deletions src/Core/DI/Plugin/Plugin.php
Expand Up @@ -18,20 +18,15 @@ abstract class Plugin
protected PluginCompiler $compiler;

/** @var stdClass|mixed[] */
protected $config;

abstract public static function getName(): string;

protected function getConfigSchema(): Schema
{
return Expect::structure([]);
}
protected stdClass|array $config;

public function __construct(PluginCompiler $compiler)
{
$this->compiler = $compiler;
}

abstract public static function getName(): string;

/**
* Process and validate config
*
Expand All @@ -43,6 +38,26 @@ public function setupPlugin(array $config = []): void
$this->setupConfig($this->getConfigSchema(), $config, $name);
}

public function loadPluginConfiguration(): void
{
// Override in child
}

public function beforePluginCompile(): void
{
// Override in child
}

public function afterPluginCompile(ClassType $class): void
{
// Override in child
}

protected function getConfigSchema(): Schema
{
return Expect::structure([]);
}

/**
* @param mixed[] $config
*/
Expand All @@ -55,22 +70,10 @@ protected function setupConfig(Schema $schema, array $config, string $name): voi
try {
$this->config = $processor->process($schema, $config);
} catch (ValidationException $exception) {
throw new InvalidConfigurationException($exception->getMessage());
throw new InvalidConfigurationException($exception->getMessage());
}
}

public function loadPluginConfiguration(): void
{
}

public function beforePluginCompile(): void
{
}

public function afterPluginCompile(ClassType $class): void
{
}

protected function prefix(string $id): string
{
return $this->compiler->getExtension()->prefix(static::getName() . '.' . $id);
Expand Down
3 changes: 3 additions & 0 deletions src/Core/Decorator/DecoratorManager.php
Expand Up @@ -24,6 +24,7 @@ class DecoratorManager
public function addRequestDecorator(IRequestDecorator $decorator): self
{
$this->requestDecorators[] = $decorator;

return $this;
}

Expand All @@ -42,6 +43,7 @@ public function decorateRequest(ApiRequest $request, ApiResponse $response): Api
public function addResponseDecorator(IResponseDecorator $decorator): self
{
$this->responseDecorators[] = $decorator;

return $this;
}

Expand All @@ -60,6 +62,7 @@ public function decorateResponse(ApiRequest $request, ApiResponse $response): Ap
public function addErrorDecorator(IErrorDecorator $decorator): self
{
$this->errorDecorators[] = $decorator;

return $this;
}

Expand Down

0 comments on commit 276791b

Please sign in to comment.