Passed
Push — master ( 598273...990b98 )
by Michael
04:11
created

AbstractProcessor   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 87.18%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 3
dl 0
loc 118
ccs 34
cts 39
cp 0.8718
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A registerAnnotations() 0 11 2
A createLink() 0 17 2
A resolveGetter() 0 20 4
A resolveSetter() 0 11 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Mikemirten\Component\JsonApi\Mapper\Definition\AnnotationProcessor;
5
6
use Mikemirten\Component\JsonApi\Mapper\Definition\Annotation\Link as LinkAnnotation;
7
use Mikemirten\Component\JsonApi\Mapper\Definition\Link;
8
use Doctrine\Common\Annotations\AnnotationRegistry;
9
use Doctrine\Common\Annotations\Reader;
10
11
/**
12
 * Abstract processor
13
 * Contains shared methods and annotations registration
14
 *
15
 * @package Mikemirten\Component\JsonApi\Mapper\Definition\AnnotationProcessor
16
 */
17
abstract class AbstractProcessor implements AnnotationProcessorInterface
18
{
19
    /**
20
     * Pattern of "resource" parameter of link annotation
21
     */
22
    const RESOURCE_PATTERN = '~^(?<repository>[a-z_][a-z0-9_]*)\.(?<link>[a-z_][a-z0-9_]*)$~i';
23
24
    /**
25
     * Annotation classes ha been registered.
26
     *
27
     * @var bool
28
     */
29
    static private $annotationsRegistered = false;
30
31
    /**
32
     * Doctrine annotation reader
33
     *
34
     * @var Reader
35
     */
36
    protected $reader;
37
38
    /**
39
     * AnnotationDefinitionProvider constructor.
40
     *
41
     * @param Reader $reader
42
     */
43 8
    public function __construct(Reader $reader)
44
    {
45 8
        self::registerAnnotations();
46
47 8
        $this->reader = $reader;
48 8
    }
49
50
    /**
51
     * Register annotation classes.
52
     * Supports a medieval-aged way of "autoloading" for the Doctrine Annotation library.
53
     */
54 8
    static protected function registerAnnotations()
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
55
    {
56 8
        if (self::$annotationsRegistered === false) {
57 1
            AnnotationRegistry::registerFile(__DIR__ . '/../Annotation/ResourceIdentifier.php');
0 ignored issues
show
Deprecated Code introduced by
The method Doctrine\Common\Annotati...egistry::registerFile() has been deprecated with message: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists')

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
58 1
            AnnotationRegistry::registerFile(__DIR__ . '/../Annotation/Relationship.php');
0 ignored issues
show
Deprecated Code introduced by
The method Doctrine\Common\Annotati...egistry::registerFile() has been deprecated with message: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists')

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
59 1
            AnnotationRegistry::registerFile(__DIR__ . '/../Annotation/Attribute.php');
0 ignored issues
show
Deprecated Code introduced by
The method Doctrine\Common\Annotati...egistry::registerFile() has been deprecated with message: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists')

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
60 1
            AnnotationRegistry::registerFile(__DIR__ . '/../Annotation/Link.php');
0 ignored issues
show
Deprecated Code introduced by
The method Doctrine\Common\Annotati...egistry::registerFile() has been deprecated with message: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists')

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
61
62 1
            self::$annotationsRegistered = true;
63
        }
64 8
    }
65
66
    /**
67
     * Create link by link's annotation
68
     *
69
     * @param  LinkAnnotation $annotation
70
     * @return Link
71
     */
72 3
    protected function createLink(LinkAnnotation $annotation): Link
73
    {
74 3
        if (! preg_match(self::RESOURCE_PATTERN, $annotation->resource, $matches)) {
75
            throw new \LogicException(sprintf('Invalid resource definition: "%s"', $annotation->resource));
76
        }
77
78 3
        $link = new Link(
79 3
            $annotation->name,
80 3
            $matches['repository'],
81 3
            $matches['link']
82
        );
83
84 3
        $link->setParameters($annotation->parameters);
85 3
        $link->setMetadata($annotation->metadata);
86
87 3
        return $link;
88
    }
89
90
    /**
91
     * Resolve getter of related object
92
     *
93
     * @param  \ReflectionProperty $property
94
     * @return string
95
     */
96 2
    protected function resolveGetter(\ReflectionProperty $property)
97
    {
98 2
        $name  = $property->getName();
99 2
        $class = $property->getDeclaringClass();
100
101 2
        foreach (['get', 'is'] as $prefix)
102
        {
103 2
            $getter = $prefix . ucfirst($name);
104
105 2
            if ($class->hasMethod($getter) && $class->getMethod($getter)->isPublic()) {
106 2
                return $getter;
107
            }
108
        }
109
110
        throw new \LogicException(sprintf(
111
            'Getter-method for the property "%s" cannot be resolved automatically. ' .
112
            'Probably there is no get%2$s() or is%2$s() method or it is not public.',
113
            $name, ucfirst($name)
114
        ));
115
    }
116
117
    /**
118
     * Resolve getter of related object
119
     *
120
     * @param  \ReflectionProperty $property
121
     * @return string | null
122
     */
123 2
    protected function resolveSetter(\ReflectionProperty $property)
124
    {
125 2
        $name  = $property->getName();
126 2
        $class = $property->getDeclaringClass();
127
128 2
        $setter = 'set' . ucfirst($name);
129
130 2
        if ($class->hasMethod($setter) && $class->getMethod($setter)->isPublic()) {
131 2
            return $setter;
132
        }
133
    }
134
}