Completed
Push — master ( 69fc0f...436aa0 )
by Kirill
05:37
created

HasDirectives::hasDirective()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\Reflection\Invocation\Behaviour;
11
12
use Railt\Reflection\Contracts\Definition\Behaviour\Deprecatable;
13
use Railt\Reflection\Contracts\Invocation\Behaviour\ProvidesDirectives;
14
use Railt\Reflection\Contracts\Invocation\DirectiveInvocation;
15
use Railt\Reflection\Definition\Behaviour\HasDeprecation;
16
17
/**
18
 * Trait HasDirectives
19
 */
20
trait HasDirectives
21
{
22
    /**
23
     * @var array|DirectiveInvocation[]
24
     */
25
    protected $directives = [];
26
27
    /**
28
     * @param string $name
29
     * @return bool
30
     */
31 4
    public function hasDirective(string $name): bool
32
    {
33 4
        return \iterator_count($this->getDirectives($name)) > 0;
34
    }
35
36
    /**
37
     * @param string|null $name
38
     * @return iterable|DirectiveInvocation[]|\Generator
39
     */
40 4
    public function getDirectives(string $name = null): iterable
41
    {
42 4
        foreach ($this->directives as $directive) {
43 1
            if ($name === null || $name === $directive->getDefinition()->getName()) {
44 1
                yield $directive;
45
            }
46
        }
47 4
    }
48
49
    /**
50
     * @param DirectiveInvocation ...$invocations
51
     * @return ProvidesDirectives|$this
52
     */
53 1
    public function withDirective(DirectiveInvocation ...$invocations): ProvidesDirectives
54
    {
55 1
        foreach ($invocations as $invocation) {
56 1
            $this->directives[] = $invocation;
57
58 1
            if ($this->isDeprecatedDirective($invocation)) {
59 1
                $this->withDeprecationReason($this->getDirectiveDeprecationReason($invocation));
0 ignored issues
show
Bug introduced by
It seems like withDeprecationReason() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
60
            }
61
        }
62
63 1
        return $this;
64
    }
65
66
    /**
67
     * @param DirectiveInvocation $directive
68
     * @return bool
69
     */
70 1
    private function isDeprecatedDirective(DirectiveInvocation $directive): bool
71
    {
72 1
        return $this instanceof Deprecatable && $directive->getName() === 'deprecated';
73
    }
74
75
    /**
76
     * @param DirectiveInvocation $deprecated
77
     * @return null|string
78
     */
79
    private function getDirectiveDeprecationReason(DirectiveInvocation $deprecated): ?string
80
    {
81
        $argument = $deprecated->getArgument('reason');
82
83
        /** @var HasDeprecation $this */
84
        if ($argument) {
85
            return $argument->getValue();
86
        }
87
88
        $definition = $deprecated->getDefinition();
89
        $argument   = $definition->getArgument('reason');
90
91
        return $argument->getDefaultValue();
92
    }
93
}
94