ClassMapObjectTransformer::supports()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 12
ccs 6
cts 6
cp 1
rs 9.4286
cc 3
eloc 6
nc 3
nop 2
crap 3
1
<?php
2
3
namespace Zenstruck\ObjectRoutingBundle\ObjectTransformer;
4
5
use Symfony\Component\PropertyAccess\PropertyAccess;
6
use Zenstruck\ObjectRoutingBundle\RouteContext;
7
8
/**
9
 * @author Kevin Bond <[email protected]>
10
 */
11
class ClassMapObjectTransformer implements ObjectTransformer
12
{
13
    private $classMap;
14
15 26
    public function __construct(array $classMap)
16
    {
17 26
        $this->classMap = $classMap;
18 26
    }
19
20
    /**
21
     * {@inheritdoc}
22
     */
23 14
    public function transform($object, $routeName = null)
24
    {
25 14
        $objectClass = get_class($object);
26
27 14
        foreach ($this->classMap as $class => $config) {
28 13
            if (!$this->isSupported($objectClass, $class, $routeName, $config)) {
29 3
                continue;
30
            }
31
32 13
            $routeName = null === $routeName ? $config['default_route'] : $routeName;
33 13
            $routeParameters = (isset($config['routes'][$routeName]) && count($config['routes'][$routeName])) ?
34 13
                $config['routes'][$routeName] : $config['default_parameters'];
35
36 13
            $accessor = PropertyAccess::createPropertyAccessor();
37 13
            $parameters = array();
38
39 13
            foreach ($routeParameters as $key => $value) {
40
                // when array isn't assoc, use value as both parameter and accessor
41 13
                $parameters[is_numeric($key) ? $value : $key] = $accessor->getValue($object, $value);
42
            }
43
44 13
            return new RouteContext($routeName, $parameters);
45
        }
46
47 1
        throw new \InvalidArgumentException(sprintf('Could not transform class "%s"', $objectClass));
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 17
    public function supports($object, $routeName = null)
54
    {
55 17
        $objectClass = get_class($object);
56
57 17
        foreach ($this->classMap as $class => $config) {
58 15
            if ($this->isSupported($objectClass, $class, $routeName, $config)) {
59 15
                return true;
60
            }
61
        }
62
63 5
        return false;
64
    }
65
66
    /**
67
     * @param string      $objectClass
68
     * @param string      $class
69
     * @param null|string $routeName
70
     * @param array       $config
71
     *
72
     * @return bool
73
     */
74 21
    private function isSupported($objectClass, $class, $routeName, $config)
75
    {
76 21
        if ($objectClass !== $class && !is_subclass_of($objectClass, $class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if $class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
77 5
            return false;
78
        }
79
80 19
        if (null === $routeName && null !== $config['default_route']) {
81 8
            return true;
82
        }
83
84 11
        if ($routeName === $config['default_route'] || isset($config['routes'][$routeName])) {
85 10
            return true;
86
        }
87
88 1
        return false;
89
    }
90
}
91