Completed
Push — master ( 925007...3a5a19 )
by Alex
07:43
created

ReflectionAnnotatedTrait::findAnnotationPattern()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 31 and the first side effect is on line 22.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
/**
4
 * Codeburner Framework.
5
 *
6
 * @author Alex Rohleder <[email protected]>
7
 * @copyright 2016 Alex Rohleder
8
 * @license http://opensource.org/licenses/MIT
9
 */
10
11
namespace Codeburner\Annotator\Reflection;
12
13
use Codeburner\Annotator\Annotation;
14
use Codeburner\Annotator\Exceptions\GroupingNotAllowedException;
15
16
/**
17
 * Avoid the autoload by manually including the required files.
18
 * This bust significantly the performance.
19
 */
20
21
if (!class_exists('Codeburner\Annotator\Annotation', false)) {
22
	include __DIR__ . '/../Annotation.php';
23
}
24
25
/**
26
 * Implements the annotation methods into a reflection.
27
 *
28
 * @author Alex Rohleder <[email protected]>
29
 */
30
31
trait ReflectionAnnotatedTrait
32
{
33
34
    /**
35
     * As this trait must be used in a Reflection object, this method
36
     * must return the doc from a class, method or function.
37
     *
38
     * @return string
39
     */
40
41
	abstract public function getDocComment();
42
43
    /**
44
     * A simple cache of getDocComment
45
     *
46
     * @var string
47
     */
48
49
	protected $docComment;
50
51
    /**
52
     * Get an annotation by it literal name.
53
     * 
54
     * @param Annotation|null
55
     *
56
     * @throws MultipleAnnotationException
57
     * @return string
58
     */
59
60
	public function getAnnotation($name)
61
	{
62
        $annotations = $this->findAnnotationPattern($name);
63
64
		if (empty($annotations)) {
65
			return null;
66
		}
67
68
        if (count($annotations) > 1) {
69
            throw new GroupingNotAllowedException("getAnnotation");
70
        }
71
72
        return new Annotation($annotations[0]);
73
	}
74
75
    /**
76
     * Get all annotations, or several of then. Note that here annotations can
77
     * have regex on they name.
78
     *
79
     * @param array $names if empty will return all annotations. Can have regex.
80
     * @return array ["AnnotationName" => Annotation]
81
     */
82
83
	public function getAnnotations(array $names = array())
84
	{
85
        if (empty($names)) {
86
               $annotations = $this->findAnnotationPattern("[\w]+");
87
        } else $annotations = $this->findAnnotationPattern(implode("|", $names));
88
89
        $bucket = [];
90
91
        foreach ($annotations as $annotation) {
0 ignored issues
show
Bug introduced by
The expression $annotations of type null|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
92
            $bucket[$annotation[1]] = new Annotation($annotation);
93
        }
94
95
        return $bucket;
96
	}
97
98
    /**
99
     * @param string $name
100
     * @return bool
101
     */
102
103
	public function hasAnnotation($name)
104
	{
105
		return (bool) preg_match("~@$name~", $this->getDoc());
106
	}
107
108
    /**
109
     * @return string
110
     */
111
112
	protected function getDoc()
113
	{
114
		if ($this->docComment) {
115
			   return $this->docComment;
116
		} else return $this->docComment = $this->getDocComment();
117
	}
118
119
    /**
120
     * @param string $pattern
121
     * @return array|null
122
     */
123
124
    protected function findAnnotationPattern($pattern)
125
    {
126
        preg_match_all("~@(" . str_replace("\\", "\\\\", $pattern) . ")\s?(.*)?~i", $this->getDoc(), $annotations, PREG_SET_ORDER);
127
        return $annotations;
128
    }
129
130
}
131