RawPageContext::resolvePagePath()   B
last analyzed

Complexity

Conditions 6
Paths 12

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 36
rs 8.439
c 0
b 0
f 0
cc 6
eloc 19
nc 12
nop 3
1
<?php
2
3
namespace Knp\FriendlyContexts\Context;
4
5
use Symfony\Component\PropertyAccess\PropertyAccess;
6
use Knp\FriendlyContexts\Page\Page;
7
use Behat\Gherkin\Node\TableNode;
8
9
class RawPageContext extends RawMinkContext
10
{
11
    private $pages = [];
12
13
    public function visitPage($page, $arguments = null)
14
    {
15
        $this->getSession()->visit($this->locatePath($this->getPagePath($page, $arguments)));
16
    }
17
18
    public function assertPage($page, $arguments = null)
19
    {
20
        try {
21
            $this->assertSession()->addressEquals($this->getPagePath($page, $arguments));
22
        } catch (\Exception $e) {
23
            $this->assertSession()->addressEquals(sprintf(
24
                '%s/',
25
                $this->getPagePath($page, $arguments)
26
            ));
27
        }
28
    }
29
30
    public function getPage($page)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
31
    {
32
        if (isset($this->pages[$page])) {
33
            return $this->pages[$page];
34
        }
35
36
        $class = $this->getPageClassResolver()->resolveName($page);
37
38
        $this->pages[$page] = $this->getPageClassResolver()->create(
39
            $this->getSession(),
40
            $class
41
        );
42
43
        return $this->pages[$page];
44
    }
45
46
    public function getPagePath($page, $arguments = null)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
47
    {
48
        list($parameters, $entities) = $this->extractTable($arguments);
49
50
        $page = $this->getPage($page);
51
52
        return $this->resolvePagePath($page, $parameters, $entities);
53
    }
54
55
    protected function getEntityFromRecordBag($entity, $field)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
56
    {
57
        $class = $this->resolveEntity($entity)->getName();
58
59
        $record = $this
60
            ->getRecordBag()
61
            ->getCollection($class)
62
            ->search($field)
63
        ;
64
65
        if (null === $record) {
66
            throw new \Exception(sprintf(
67
                'No entity %s has been found for  "%s"',
68
                $class,
69
                $field
70
            ));
71
        }
72
73
        return $record->getEntity();
74
    }
75
76
    protected function resolvePagePath(Page $page, $parameters, $entities)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
77
    {
78
        $path = $page->getPath();
79
80
        foreach ($parameters as $key => $value) {
81
            $path = str_replace(sprintf('{%s}', $key), $value, $path);
82
        }
83
84
        if (!preg_match_all('/\{([a-zA-Z0-9]+\.[a-zA-Z0-9]+)\}/', $path, $matches)) {
85
            return $path;
86
        }
87
88
        $properties = array();
89
90
        foreach ($matches[1] as $parameter) {
91
            list($entityName, $field) = explode('.', $parameter);
92
93
            if (!isset($entities[$entityName])) {
94
                throw new \Exception(sprintf(
95
                    'No entity can be resolved for "%s"',
96
                    $entityName
97
                ));
98
            }
99
100
            $entity = $entities[$entityName];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
101
            $properties[] = PropertyAccess::createPropertyAccessor()
102
                ->getValue($entity, $field)
103
            ;
104
        }
105
106
        foreach ($matches[0] as $index => $pattern) {
107
            $path = str_replace($pattern, $properties[$index], $path);
108
        }
109
110
        return $path;
111
    }
112
113
    protected function extractTable($parameters = null)
114
    {
115
        if (null === $parameters) {
116
            return [[], []];
117
        }
118
119
        if ($parameters instanceof TableNode) {
120
            $parameters = $parameters->getRowsHash();
121
        }
122
123
        if (!is_array($parameters)) {
124
            throw new \InvalidArgumentException(
125
                'You must precised a valid array or Behat\Gherkin\Node\TableNode to extract'
126
            );
127
        }
128
129
        $entities = [];
130
131
        foreach ($parameters as $name => $value) {
132
            $matches = array();
133
            if (preg_match('/^the (.+) "([^"]+)"$/', $value, $matches)) {
134
                $entity = $this->getEntityFromRecordBag($matches[1], $matches[2]);
135
136
                $entities[$name] = $entity;
137
                unset($parameters[$name]);
138
            }
139
        }
140
141
        return array($parameters, $entities);
142
    }
143
}
144