Completed
Push — master ( bd4c23...b341c0 )
by Filipe
10:29
created

HtmlExtension   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 3
dl 0
loc 135
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getFunctions() 0 8 1
A location() 0 4 1
A css() 0 13 2
A attributesStr() 0 8 2
A urlClosure() 0 6 1
A cssClosure() 0 6 1
A jsClosure() 0 15 2
1
<?php
2
3
/**
4
 * This file is part of slick/mvc package
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\Mvc\Http\Renderer\TemplateExtension;
11
12
use Slick\Mvc\Service\UriGeneratorInterface;
13
use Slick\Template\EngineExtensionInterface;
14
use Slick\Template\Extension\AbstractTwigExtension;
15
use Twig_SimpleFunction as TwigFunction;
16
17
/**
18
 * HtmlExtension
19
 *
20
 * @package Slick\Mvc\Http\Renderer\TemplateExtension
21
 * @author  Filipe Silva <[email protected]>
22
 */
23
class HtmlExtension extends AbstractTwigExtension implements
24
    EngineExtensionInterface
25
{
26
27
    /**
28
     * @var UriGeneratorInterface
29
     */
30
    private $generator;
31
32
    /**
33
     * @var array Default options for addCss and addJs template functions
34
     */
35
    private static $options = [
36
        'is_safe' => ['html']
37
    ];
38
39
    /**
40
     * Creates an HTML template extension
41
     *
42
     * @param UriGeneratorInterface $generator
43
     */
44
    public function __construct(UriGeneratorInterface $generator)
45
    {
46
        $this->generator = $generator;
47
    }
48
49
    /**
50
     * @return \Twig_SimpleFunction[]
51
     */
52
    public function getFunctions()
53
    {
54
        return [
55
            'url'    => new TwigFunction('url', $this->urlClosure()),
56
            'addCss' => new TwigFunction('addCss', $this->cssClosure(), self::$options),
57
            'addJs'  => new TwigFunction('addJs', $this->jsClosure(), self::$options)
58
        ];
59
    }
60
61
    /**
62
     * Generates URI for provided location
63
     *
64
     * @param string $location Location name, path or identifier
65
     * @param array $options Filter options
66
     *
67
     * @return null|\Psr\Http\Message\UriInterface
68
     */
69
    private function location($location, array $options = [])
70
    {
71
        return $this->generator->generate($location, $options);
72
    }
73
74
    /**
75
     * Creates a css link tag for provided css file
76
     *
77
     * @param string $file
78
     * @param string $path
79
     * @param array $options
80
     *
81
     * @return string
82
     */
83
    private function css($file, $path = 'css', array $options = [])
84
    {
85
        $attr = array_key_exists('attr', $options) ? $options['attr'] : [];
86
        $attr = array_merge(['rel' => 'stylesheet'], $attr);
87
88
        $location = $this->location("{$path}/{$file}", $options);
89
90
        return sprintf(
91
            '<link href="%s" %s>',
92
            $location,
93
            $this->attributesStr($attr)
94
        );
95
    }
96
97
    /**
98
     * Converts an attributes key/value array to its string representation
99
     *
100
     * @param array $attr
101
     *
102
     * @return string
103
     */
104
    private function attributesStr(array $attr)
105
    {
106
        $output = [];
107
        foreach ($attr as $name => $value) {
108
            $output[] = "{$name}=\"{$value}\"";
109
        }
110
        return implode(' ', $output);
111
    }
112
113
    /**
114
     * Creates the url() template function closure
115
     *
116
     * @return \Closure
117
     */
118
    private function urlClosure()
119
    {
120
        return function ($location, array $options = []) {
121
            return $this->location($location, $options);
122
        };
123
    }
124
125
    /**
126
     * Creates the addCss() template function closure
127
     *
128
     * @return \Closure
129
     */
130
    private function cssClosure()
131
    {
132
        return function ($file, $path = 'css', array $options = []) {
133
            return $this->css($file, $path, $options);
134
        };
135
    }
136
137
    /**
138
     * Creates the addJs() template function closure
139
     *
140
     * @return \Closure
141
     */
142
    private function jsClosure()
143
    {
144
        return function ($file, $path = 'js', array $options = []) {
145
            $attr = array_key_exists('attr', $options)
146
                ? $options['attr']
147
                : [];
148
149
            $location = $this->location("{$path}/{$file}", $options);
150
            return sprintf(
151
                '<script src="%s" %s></script>',
152
                $location,
153
                $this->attributesStr($attr)
154
            );
155
        };
156
    }
157
}