Completed
Pull Request — develop (#487)
by Lucas
100:12 queued 61:52
created

ExtReferenceConverter::getUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2.5

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 17
ccs 6
cts 12
cp 0.5
rs 9.4285
cc 2
eloc 10
nc 2
nop 1
crap 2.5
1
<?php
2
/**
3
 * ExtReferenceConverter class file
4
 */
5
6
namespace Graviton\DocumentBundle\Service;
7
8
use Graviton\DocumentBundle\Entity\ExtReference;
9
use Symfony\Component\Routing\RouterInterface;
10
use Symfony\Component\Routing\Route;
11
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
12
13
/**
14
 * Extref converter
15
 *
16
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
17
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
18
 * @link     http://swisscom.ch
19
 */
20
class ExtReferenceConverter implements ExtReferenceConverterInterface
21
{
22
    /**
23
     * @var RouterInterface
24
     */
25
    private $router;
26
    /**
27
     * @var array
28
     */
29
    private $mapping;
30
    /**
31
     * @var Route[]
32
     */
33
    private $resolvingCache;
34
35
    /**
36
     * Constructor
37
     *
38
     * @param RouterInterface $router  Router
39
     * @param array           $mapping colleciton_name => service_id mapping
40
     */
41 14
    public function __construct(RouterInterface $router, array $mapping)
42
    {
43 14
        $this->router = $router;
44 14
        $this->mapping = $mapping;
45 14
    }
46
47
    /**
48
     * return the extref from URL
49
     *
50
     * @param string $url Extref URL
51
     * @return ExtReference
52
     * @throws \InvalidArgumentException
53
     */
54 6
    public function getExtReference($url)
55
    {
56 6
        $path = parse_url($url, PHP_URL_PATH);
57 6
        if ($path === false) {
58
            throw new \InvalidArgumentException(sprintf('URL %s', $url));
59
        }
60
61 6
        $id = null;
62 6
        $collection = null;
63
64 6
        if (!isset($this->resolvingCache[$path])) {
65 6
            foreach ($this->router->getRouteCollection()->all() as $route) {
66 6
                list($collection, $id) = $this->getDataFromRoute($route, $path);
67 6
                if ($collection !== null && $id !== null) {
68 6
                    $this->resolvingCache[$path] = $route;
69 6
                    return ExtReference::create($collection, $id);
70
                }
71 2
            }
72
        } else {
73
            list($collection, $id) = $this->getDataFromRoute($this->resolvingCache[$path], $path);
74
            return ExtReference::create($collection, $id);
75
        }
76
77
        throw new \InvalidArgumentException(sprintf('Could not read URL %s', $url));
78
    }
79
80
    /**
81
     * return the URL from extref
82
     *
83
     * @param ExtReference $extReference Extref
84
     * @return string
85
     * @throws \InvalidArgumentException
86
     */
87 4
    public function getUrl(ExtReference $extReference)
88
    {
89 4
        if (!isset($this->mapping[$extReference->getRef()])) {
90
            throw new \InvalidArgumentException(
91
                sprintf(
92
                    'Could not create URL from extref "%s"',
93
                    json_encode($extReference)
94
                )
95
            );
96
        }
97
98 4
        return $this->router->generate(
99 4
            $this->mapping[$extReference->getRef()].'.get',
100 4
            ['id' => $extReference->getId()],
101
            UrlGeneratorInterface::ABSOLUTE_URL
102 4
        );
103
    }
104
105
    /**
106
     * get collection and id from route
107
     *
108
     * @param Route  $route route to look at
109
     * @param string $value value of reference as URI
110
     *
111
     * @return array
112
     */
113 6
    private function getDataFromRoute(Route $route, $value)
114
    {
115 6
        if ($route->getRequirement('id') !== null &&
116 6
            $route->getMethods() === ['GET'] &&
117 6
            preg_match($route->compile()->getRegex(), $value, $matches)
118 6
        ) {
119 6
            $id = $matches['id'];
120
121 6
            list($routeService) = explode(':', $route->getDefault('_controller'));
122 6
            list($core, $bundle,,$name) = explode('.', $routeService);
123 6
            $serviceName = implode('.', [$core, $bundle, 'rest', $name]);
124 6
            $collection = array_search($serviceName, $this->mapping);
125
126 6
            return [$collection, $id];
127
        }
128
129 2
        return [null, null];
130
    }
131
}
132