HookAnnotation::validateMethodName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * HookAnnotation.php
5
 *
6
 * Common base class for before and after annotations.
7
 *
8
 * @package jaxon-annotations
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2022 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-annotations
13
 */
14
15
namespace Jaxon\Annotations\Annotation;
16
17
use mindplay\annotations\AnnotationException;
18
19
use function array_key_exists;
20
use function array_keys;
21
use function count;
22
use function is_array;
23
use function is_string;
24
use function json_decode;
25
use function preg_match;
26
use function preg_split;
27
use function rtrim;
28
29
abstract class HookAnnotation extends AbstractAnnotation
30
{
31
    /**
32
     * @var string
33
     */
34
    protected $sMethodName = '';
35
36
    /**
37
     * @var array
38
     */
39
    protected $sMethodParams = [];
40
41
    /**
42
     *
43
     */
44
    abstract protected static function getType(): string;
45
46
    /**
47
     * @inheritDoc
48
     */
49
    public function getName(): string
50
    {
51
        return '__' . $this->getType();
52
    }
53
54
    /**
55
     * @inheritDoc
56
     */
57
    public static function parseAnnotation($value)
58
    {
59
        $aParams = preg_split('/[\s]+/', $value, 2);
60
        if(count($aParams) === 1)
61
        {
62
            return ['call' => rtrim($aParams[0])];
63
        }
64
        // The second parameter must be an array of callback parameter in json format.
65
        return ['call' => rtrim($aParams[0]), 'with' => json_decode($aParams[1], false)];
66
    }
67
68
    /**
69
     * @param string $sMethodName
70
     *
71
     * @return bool
72
     */
73
    protected function validateMethodName(string $sMethodName): bool
74
    {
75
        return preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $sMethodName) > 0;
76
    }
77
78
    /**
79
     * @inheritDoc
80
     * @throws AnnotationException
81
     */
82
    public function initAnnotation(array $properties)
83
    {
84
        if(!isset($properties['call']) || !is_string($properties['call']))
85
        {
86
            throw new AnnotationException('The @' . $this->getType() .
87
                ' annotation requires a property "call" of type string');
88
        }
89
        if(!$this->validateMethodName($properties['call']))
90
        {
91
            throw new AnnotationException($properties['call'] .
92
                ' is not a valid "call" value for the @' . $this->getType() . ' annotation');
93
        }
94
        foreach(array_keys($properties) as $propName)
95
        {
96
            if($propName !== 'call' && $propName !== 'with')
97
            {
98
                throw new AnnotationException('Unknown property "' . $propName .
99
                    '" in the @' . $this->getType() . ' annotation');
100
            }
101
        }
102
        // Cannot use isset here, because it will return false in case $properties['with'] === null
103
        if(array_key_exists('with', $properties))
104
        {
105
            if(!is_array($properties['with']))
106
            {
107
                throw new AnnotationException('The "with" property of the @' .
108
                    $this->getType() . ' annotation must be of type array');
109
            }
110
            $this->sMethodParams = $properties['with'];
111
        }
112
        $this->sMethodName = $properties['call'];
113
    }
114
115
    /**
116
     * @inheritDoc
117
     */
118
    public function getValue()
119
    {
120
        if(is_array($this->xPrevValue))
121
        {
122
            // Add the current value to the array
123
            $this->xPrevValue[$this->sMethodName] = $this->sMethodParams;
124
            return $this->xPrevValue;
125
        }
126
        // Return the current value in an array
127
        return [$this->sMethodName => $this->sMethodParams];
128
    }
129
}
130