ViewResolver::renderMany()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 0
cts 12
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 3
nop 3
crap 12
1
<?php
2
3
namespace Thruster\Bundle\ViewBundle\View;
4
5
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
6
use Symfony\Component\DependencyInjection\ContainerInterface;
7
8
/**
9
 * Class ViewResolver
10
 *
11
 * @package Thruster\Bundle\ViewsBundle\View
12
 * @author  Aurimas Niekis <[email protected]>
13
 */
14
class ViewResolver
15
{
16
    /**
17
     * @var ContainerInterface
18
     */
19
    protected $container;
20
21
    /**
22
     * @var ViewNameParser
23
     */
24
    protected $parser;
25
26
    public function __construct(ContainerInterface $container, ViewNameParser $parser)
27
    {
28
        $this->container = $container;
29
        $this->parser = $parser;
30
    }
31
32
    /**
33
     * @param string $view A short notation view (a:b:c) AppBundle:Default:homepage
34
     * @param mixed  $data
35
     *
36
     * @return mixed
37
     */
38
    public function renderOne($view, $data)
39
    {
40
        return call_user_func(
41
            $this->getView($view),
42
            $data
43
        );
44
    }
45
46
    /**
47
     * @param string $view A short notation view (a:b:c) AppBundle:Default:homepage
48
     * @param array  $data
49
     * @param bool   $preserveKeys
50
     *
51
     * @return array
52
     */
53
    public function renderMany($view, $data, $preserveKeys = false)
54
    {
55
        $result = [];
56
57
        foreach ($data as $key => $item) {
58
            if (true === $preserveKeys) {
59
                $result[$key] = $this->renderOne($view, $item);
60
            } else {
61
                $result[] = $this->renderOne($view, $item);
62
            }
63
        }
64
65
        return $result;
66
    }
67
68
    /**
69
     * @param string $view A short notation view (a:b:c) AppBundle:Default:homepage
70
     *
71
     * @return callable
72
     */
73
    public function getView($view)
74
    {
75
        if (is_array($view)) {
76
            return $view;
77
        }
78
79
        if (is_object($view)) {
80
            if (method_exists($view, '__invoke')) {
81
                return $view;
82
            }
83
84
            throw new \InvalidArgumentException(sprintf('View "%s" is not callable.', get_class($view)));
85
        }
86
87
        if (false === strpos($view, ':')) {
88
            if (method_exists($view, '__invoke')) {
89
                return $this->instantiateView($view);
90
            } elseif (function_exists($view)) {
91
                return $view;
92
            }
93
        }
94
95
        $callable = $this->createView($view);
96
97
        if (false === is_callable($callable)) {
98
            throw new \InvalidArgumentException(sprintf('View "%s" is not callable.', $view));
99
        }
100
101
        return $callable;
102
    }
103
104
    protected function createView($view)
105
    {
106
        if (false === strpos($view, '::')) {
107
            $view = $this->parser->parse($view);
108
        }
109
110
        list($class, $method) = explode('::', $view, 2);
111
112
        if (false === class_exists($class)) {
113
            throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
114
        }
115
116
        return [$this->instantiateView($class), $method];
117
    }
118
119
    protected function instantiateView($class)
120
    {
121
        if ($this->container->has($class)) {
122
            return $this->container->get($class);
123
        }
124
125
        $view = new $class();
126
127
        if ($view instanceof ContainerAwareInterface) {
128
            $view->setContainer($this->container);
129
        }
130
131
        return $view;
132
    }
133
134
}
135