Skip to content

Commit

Permalink
Merge pull request #32 from sunrise-php/release/v1.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
fenric authored Sep 24, 2021
2 parents b4d0244 + 6569723 commit 6b9158c
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 14 deletions.
7 changes: 6 additions & 1 deletion src/AbstractAnnotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
abstract class AbstractAnnotation extends AbstractObject
{

/**
* @var \ReflectionClass
*/
public $_holder = null;

/**
* Recursively collects all annotations referenced by this object or its children
*
Expand All @@ -44,7 +49,7 @@ public function getReferencedObjects(AnnotationReader $annotationReader) : array
if ($value instanceof AbstractAnnotation) {
$objects = array_merge($objects, $value->getReferencedObjects($annotationReader));
} elseif ($value instanceof AbstractAnnotationReference) {
$object = $value->getAnnotation($annotationReader);
$object = $value->getAnnotation($annotationReader, $this->_holder);
$objects[] = $object;

if ($object instanceof AbstractAnnotation) {
Expand Down
56 changes: 43 additions & 13 deletions src/AbstractAnnotationReference.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,28 @@ abstract public function getAnnotationName() : string;
* Tries to find a referenced object that implements the `ComponentObjectInterface` interface
*
* @param AnnotationReader $annotationReader
* @param ReflectionClass $holder
*
* @return ComponentObjectInterface
*
* @throws InvalidReferenceException
*/
public function getAnnotation(AnnotationReader $annotationReader) : ComponentObjectInterface
public function getAnnotation(AnnotationReader $annotationReader, ReflectionClass $holder = null) : ComponentObjectInterface
{
if (false !== \strpos($this->class, '.')) {
list($this->class, $this->property) = \explode('.', $this->class, 2);
} elseif (false !== \strpos($this->class, '@')) {
list($this->class, $this->method) = \explode('@', $this->class, 2);
}

if (isset($holder)) {
if ('' === $this->class) {
$this->class = $holder->getName();
} elseif (false === \strpos($this->class, '\\') && $holder->getNamespaceName()) {
$this->class = $holder->getNamespaceName() . '\\' . $this->class;
}
}

$key = hash(
'md5',
$this->class .
Expand Down Expand Up @@ -147,10 +162,9 @@ private function getMethodAnnotation(AnnotationReader $annotationReader) : Compo
);
}

$object = $annotationReader->getMethodAnnotation(
new ReflectionMethod($this->class, $this->method),
$this->getAnnotationName()
);
$reflection = new ReflectionMethod($this->class, $this->method);

$object = $annotationReader->getMethodAnnotation($reflection, $this->getAnnotationName());

if (null === $object) {
$message = 'Method %s::%s() does not contain the annotation %s';
Expand All @@ -159,6 +173,12 @@ private function getMethodAnnotation(AnnotationReader $annotationReader) : Compo
);
}

$object->_holder = $reflection->getDeclaringClass();

if (null === $object->refName) {
$object->refName = $reflection->getDeclaringClass()->getShortName() . '.fn_' . $reflection->getName();
}

return $object;
}

Expand All @@ -182,10 +202,9 @@ private function getPropertyAnnotation(AnnotationReader $annotationReader) : Com
);
}

$object = $annotationReader->getPropertyAnnotation(
new ReflectionProperty($this->class, $this->property),
$this->getAnnotationName()
);
$reflection = new ReflectionProperty($this->class, $this->property);

$object = $annotationReader->getPropertyAnnotation($reflection, $this->getAnnotationName());

if (null === $object) {
$message = 'Property %s::$%s does not contain the annotation %s';
Expand All @@ -194,6 +213,12 @@ private function getPropertyAnnotation(AnnotationReader $annotationReader) : Com
);
}

$object->_holder = $reflection->getDeclaringClass();

if (null === $object->refName) {
$object->refName = $reflection->getDeclaringClass()->getShortName() . '.' . $reflection->getName();
}

return $object;
}

Expand All @@ -217,10 +242,9 @@ private function getClassAnnotation(AnnotationReader $annotationReader) : Compon
);
}

$object = $annotationReader->getClassAnnotation(
new ReflectionClass($this->class),
$this->getAnnotationName()
);
$reflection = new ReflectionClass($this->class);

$object = $annotationReader->getClassAnnotation($reflection, $this->getAnnotationName());

if (null === $object) {
$message = 'Class %s does not contain the annotation %s';
Expand All @@ -229,6 +253,12 @@ private function getClassAnnotation(AnnotationReader $annotationReader) : Compon
);
}

$object->_holder = $reflection;

if (null === $object->refName) {
$object->refName = $reflection->getShortName();
}

return $object;
}
}
5 changes: 5 additions & 0 deletions src/AbstractObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ protected function getFields() : array
$fields = [];

foreach ($this as $name => $value) {
// the internal field (property) should be ignored...
if ('_' === $name[0]) {
continue;
}

// the field (property) doesn't matter or is NULL...
if (null === $value) {
continue;
Expand Down
68 changes: 68 additions & 0 deletions tests/AbstractAnnotationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,72 @@ public function getAnnotationName() : string

], reset($referencedObjects)->toArray());
}

/**
* @return void
*/
public function testSimplifiedReferencing() : void
{
$annotation = new class extends AbstractAnnotation
{
public $child;
public $reference;

public function __construct()
{
$this->child = clone $this;

$this->child->reference = new class extends AbstractAnnotationReference
{
public $class = Fixture\SimplifiedReferencing\Foo::class;

public function getAnnotationName() : string
{
return Schema::class;
}
};
}
};

$referencedObjects = $annotation->getReferencedObjects($this->createSimpleAnnotationReader());
foreach ($referencedObjects as &$referencedObject) {
$referencedObject = $referencedObject->toArray();
}

$this->assertSame([
[
'properties' => [
'bar' => [
'$ref' => '#/components/schemas/Bar',
],
'baz' => [
'$ref' => '#/components/schemas/Baz',
],
],
'type' => 'object',
],
[
'properties' => [
'value' => [
'$ref' => '#/components/schemas/Bar.value',
],
],
'type' => 'object',
],
[
'type' => 'string',
],
[
'properties' => [
'value' => [
'$ref' => '#/components/schemas/Baz.fn_value',
],
],
'type' => 'object',
],
[
'type' => 'string',
],
], $referencedObjects);
}
}
22 changes: 22 additions & 0 deletions tests/Fixture/SimplifiedReferencing/Bar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php declare(strict_types=1);

namespace Sunrise\Http\Router\OpenApi\Tests\Fixture\SimplifiedReferencing;

/**
* @OpenApi\Schema(
* type="object",
* properties={
* "value": @OpenApi\SchemaReference(".value"),
* },
* )
*/
class Bar
{

/**
* @OpenApi\Schema(
* type="string",
* )
*/
public $value;
}
24 changes: 24 additions & 0 deletions tests/Fixture/SimplifiedReferencing/Baz.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php declare(strict_types=1);

namespace Sunrise\Http\Router\OpenApi\Tests\Fixture\SimplifiedReferencing;

/**
* @OpenApi\Schema(
* type="object",
* properties={
* "value": @OpenApi\SchemaReference("@value"),
* },
* )
*/
class Baz
{

/**
* @OpenApi\Schema(
* type="string",
* )
*/
public function value()
{
}
}
16 changes: 16 additions & 0 deletions tests/Fixture/SimplifiedReferencing/Foo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php declare(strict_types=1);

namespace Sunrise\Http\Router\OpenApi\Tests\Fixture\SimplifiedReferencing;

/**
* @OpenApi\Schema(
* type="object",
* properties={
* "bar": @OpenApi\SchemaReference("Bar"),
* "baz": @OpenApi\SchemaReference("Baz"),
* },
* )
*/
class Foo
{
}

0 comments on commit 6b9158c

Please sign in to comment.