Completed
Push — master ( 299dac...485983 )
by Mehmet
10:05
created

TwigExtensions::extendForGetUrl()   B

Complexity

Conditions 4
Paths 1

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 26
ccs 0
cts 25
cp 0
rs 8.5806
cc 4
eloc 18
nc 1
nop 0
crap 20
1
<?php
2
declare(strict_types = 1);
3
4
namespace Selami\View\Twig;
5
6
use Selami\View\ExtensionsAbstract;
7
use Twig_Environment;
8
use Camel\CaseTransformer;
9
use Camel\Format;
10
use InvalidArgumentException;
11
use BadMethodCallException;
12
13
/**
14
 * Class TwigExtensions extends ViewExtensionsAbstracts
15
 *
16
 * @package Selami\View\Twig
17
 */
18
class TwigExtensions extends ExtensionsAbstract
19
{
20
    private $twig;
21
    private $config;
22
    private $toCamelCase;
23
    private $toSnakeCase;
24
25
    public function __construct(Twig_Environment $twig, array $config)
26
    {
27
        $this->twig = $twig;
28
        $this->config = $config;
29
        $this->toCamelCase = new CaseTransformer(new Format\SnakeCase, new Format\StudlyCaps);
30
        $this->toSnakeCase = new CaseTransformer(new Format\CamelCase, new Format\SnakeCase);
31
        $this->loadExtensions();
32
        $this->loadFunctions();
33
    }
34
35
    protected function loadExtensions() : void
36
    {
37
        $this->twig->addExtension(new \Twig_Extensions_Extension_Date());
38
        $this->twig->addExtension(new \Twig_Extensions_Extension_Intl());
39
        $this->twig->addExtension(new \Twig_Extensions_Extension_Text());
40
        $this->twig->addExtension(new \Twig_Extensions_Extension_I18n());
41
    }
42
43
    protected function extendForGetUrl() : void
44
    {
45
        $filter = new \Twig_SimpleFunction(
46
            'getUrl',
47
            function (
48
                $alias,
49
                $params = []
50
            ) {
51
                if (array_key_exists($alias, $this->config['aliases'])) {
52
                    $data = $this->config['aliases'][$alias];
53
                    $relative_path = $data;
54
                    foreach ($params as $param => $value) {
55
                        if (strpos($param, ':') === strlen($param)-1) {
56
                            $relative_path = preg_replace('/{'.$param.'(.*?)}/msi', $value, $relative_path);
57
                        } else {
58
                            $relative_path = str_replace('{'.$param.'}', $value, $relative_path);
59
                        }
60
                    }
61
                    return $this->config['base_url'] . '/' . $relative_path;
62
                }
63
                return '';
64
            },
65
            array('is_safe' => array('html'))
66
        );
67
        $this->twig->addFunction($filter);
68
    }
69
70
    protected function extendForWidget() : void
71
    {
72
        $filter = new \Twig_SimpleFunction(
73
            'Widget_*_*',
74
            function ($widgetNameStr, $widgetActionStr, $args = []) {
75
                $widgetAction = $this->toCamelCase->transform($widgetActionStr);
76
                $widgetName = $this->toCamelCase->transform($widgetNameStr);
77
                $widget = '\\' . $this->config['app_namespace'] . '\\Widget\\' . $widgetName;
78
                if (!class_exists($widget)) {
79
                    $message = 'Widget ' . $widgetName . '_' . $widgetAction . ' has not class name as ' . $widget;
80
                    throw new BadMethodCallException($message);
81
                }
82
                $widgetInstance = new $widget($args);
83
                if (!method_exists($widgetInstance, $widgetAction)) {
84
                    $message = 'Widget ' . $widget . ' has not method name as ' . $widgetAction;
85
                    throw new BadMethodCallException($message);
86
                }
87
                $templateFileBasename = $args['template'] ?? $this->toSnakeCase->transform($widgetActionStr) . '.twig';
88
                $templateFullPath = $this->config['templates_dir'] . '/_widgets/'
89
                    . $this->toSnakeCase->transform($widgetNameStr) . '/' . $templateFileBasename;
90
91
                if (!file_exists($templateFullPath)) {
92
                    $message = sprintf(
93
                        '%s  template file not found! %s needs a main template file at: %s',
94
                        $templateFileBasename,
95
                        $widgetNameStr . '_' . $widgetActionStr,
96
                        $templateFullPath
97
                    );
98
                    throw new InvalidArgumentException($message);
99
                }
100
                $templateFile =  '_widgets/'
101
                    . $this->toSnakeCase->transform($widgetNameStr) . '/' . $templateFileBasename;
102
                $widgetData = $widgetInstance->{$widgetAction}();
103
                return $this->twig->render($templateFile, $widgetData);
104
            },
105
            array('is_safe' => array('html'))
106
        );
107
        $this->twig->addFunction($filter);
108
    }
109
110 View Code Duplication
    protected function extendForQueryParams() : void
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111
    {
112
        $filter = new \Twig_SimpleFunction(
113
            'queryParams',
114
            function ($queryParams, $prefix = '?') {
115
                return $prefix . http_build_query($queryParams);
116
            },
117
            array('is_safe' => array('html'))
118
        );
119
        $this->twig->addFunction($filter);
120
    }
121
122 View Code Duplication
    protected function extendForSiteUrl() : void
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
123
    {
124
        $filter = new \Twig_SimpleFunction(
125
            'siteUrl',
126
            function ($path = '') {
127
                return $this->config['base_url'] . $path;
128
            },
129
            array('is_safe' => array('html'))
130
        );
131
        $this->twig->addFunction($filter);
132
    }
133
134
    protected function extendForVarDump() : void
135
    {
136
        $filter = new \Twig_SimpleFunction(
137
            'varDump',
138
            function ($args) {
139
                /**
140
            * @noinspection ForgottenDebugOutputInspection 
141
            */
142
                var_dump($args);
1 ignored issue
show
Security Debugging Code introduced by
var_dump($args); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
143
            },
144
            array('is_safe' => array('html'))
145
        );
146
        $this->twig->addFunction($filter);
147
    }
148
149
    protected function extendForPagination() : void
150
    {
151
        /**
152
 * @noinspection MoreThanThreeArgumentsInspection 
153
*/
154
        $filter = new \Twig_SimpleFunction(
155
            'Pagination',
156
            function (
157
                int $total,
158
                int $current,
159
                string $linkTemplate,
160
                string $parentTemplate = '<ul class="pagination">(items)</ul>',
161
                string $itemTemplate = '<li class="(item_class)">(link)</li>',
162
                string $linkItemTemplate = '<a href="(href)" class="(link_class)">(text)</a>',
163
                string $ellipsesTemplate = '<li><a>...</a></li>'
164
            ) {
165
                $items =  '';
166
                $pageGroupLimit = 3;
167
                $useEllipses = ($total >10) ? 1 : 0;
168
                $renderedEllipses = 0;
169
                $values = [
170
                    '(item_class)'  => '',
171
                    '(href)'        => '',
172
                    '(link_class)'  => '',
173
                    '(text)'  => ''
174
                ];
175
                for ($i=1; $i <= $total; $i++) {
176
                    $values['(link_class)'] = '';
177
                    $values['(item_class)'] = '';
178
                    if ($i === $current) {
179
                        $values['(link_class)'] = 'active';
180
                        $values['(item_class)'] = 'active';
181
                    }
182
                    $values['(text)'] = $i;
183
                    $values['(href)'] = str_replace('(page_num)', $i, $linkTemplate);
184
                    $link = strtr($linkItemTemplate, $values);
185
                    $useLink = 1;
186
                    if ($useEllipses === 1) {
187
                        $useLink = 0;
188
                        if (($i <= $pageGroupLimit)
189
                            ||  ($i >= ($current-1) && $i <= ($current+1))
190
                            || ($i >= ($total-2))
191
                        ) {
192
                            $useLink = 1;
193
                            $renderedEllipses = 0;
194
                        } else {
195
                            if ($renderedEllipses === 0) {
196
                                $items .= $ellipsesTemplate;
197
                            }
198
                            $renderedEllipses = 1;
199
                        }
200
                    }
201
                    if ($useLink === 1) {
202
                        $thisItemTemplate = str_replace(
203
                            array('(link)'),
204
                            array($link),
205
                            $itemTemplate
206
                        );
207
                        $items .= strtr($thisItemTemplate, $values);
208
                    }
209
                }
210
                return str_replace('(items)', $items, $parentTemplate);
211
            },
212
            array('is_safe' => array('html'))
213
        );
214
        $this->twig->addFunction($filter);
215
    }
216
}
217