RawPageContext::resolvePagePath()   A
last analyzed

Complexity

Conditions 6
Paths 12

Size

Total Lines 35
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 18
c 1
b 0
f 0
dl 0
loc 35
rs 9.0444
cc 6
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)
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)
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)
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)
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];
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