Completed
Push — master ( 6f192c...533974 )
by André
26:16
created

AnnotationArgumentResolver::parseAnnotations()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 19
rs 9.2
c 1
b 0
f 1
cc 4
eloc 11
nc 4
nop 1
1
<?php
2
3
namespace EzSystems\PlatformBehatBundle\Context\Argument;
4
5
use Behat\Behat\Context\Argument\ArgumentResolver;
6
use ReflectionClass;
7
8
/**
9
 * Behat Context Argument Resolver.
10
 */
11
class AnnotationArgumentResolver implements ArgumentResolver
12
{
13
    /**
14
     * Service annotation tag.
15
     */
16
    const SERVICE_DOC_TAG = 'injectService';
17
18
    /**
19
     * Resolve service arguments for Behat Context constructor thru annotation.
20
     * Symfony2Extension ArgumentResoler will convert service names to actual instances.
21
     *
22
     * @param ReflectionClass $classReflection
23
     * @param array $arguments
24
     */
25
    public function resolveArguments(ReflectionClass $classReflection, array $arguments = [])
26
    {
27
        $injArguments = $this->parseAnnotations(
28
            $this->getMethodAnnotations($classReflection)
29
        );
30
31
        if (!empty($injArguments)) {
32
            $arguments = [];
33
            foreach ($injArguments as $name => $service) {
34
                $arguments[$name] = $service;
35
            }
36
        }
37
38
        return $arguments;
39
    }
40
41
    /**
42
     * Returns a array with the method annotations.
43
     *
44
     * @return array array annotations
45
     */
46
    private function getMethodAnnotations($refClass, $method = '__construct')
47
    {
48
        if ($refClass->hasMethod($method)) {
49
            $refMethod = $refClass->getMethod($method);
50
            preg_match_all('#@(.*?)\n#s', $refMethod->getDocComment(), $matches);
51
52
            return $matches[1];
53
        } else {
54
            return [];
55
        }
56
    }
57
58
    /**
59
     * Returns an array with the method arguments service requirements,
60
     * if the methods use the service Annotation.
61
     *
62
     * @return array array of methods and their service dependencies
63
     */
64
    private function parseAnnotations($annotations)
65
    {
66
        // parse array from (numeric key => 'annotation <value>') to (annotation => value)
67
        $methodServices = [];
68
        foreach ($annotations as $annotation) {
69
            if (!preg_match('/^(\w+)\s+\$(\w+)\s+([\w\.\@\%]+)/', $annotation, $matches)) {
70
                continue;
71
            }
72
73
            array_shift($matches);
74
            $tag = array_shift($matches);
75
            if ($tag == self::SERVICE_DOC_TAG) {
76
                list($argument, $service) = $matches;
77
                $methodServices[$argument] = $service;
78
            }
79
        }
80
81
        return $methodServices;
82
    }
83
}
84