Completed
Push — master ( 63e320...4eff09 )
by Mehmet
04:44
created

TwigExtensions::loadExtensions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
ccs 0
cts 7
cp 0
rs 9.4285
cc 1
eloc 5
nc 1
nop 0
crap 2
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
 * @package Selami\View\Twig
16
 */
17
class TwigExtensions extends ExtensionsAbstract
18
{
19
    private $twig;
20
    private $config;
21
    private $toCamelCase;
22
    private $toSnakeCase;
23
24
    public function __construct(Twig_Environment $twig, array $config)
25
    {
26
        $this->twig = $twig;
27
        $this->config = $config;
28
        $this->toCamelCase = new CaseTransformer(new Format\SnakeCase, new Format\StudlyCaps);
29
        $this->toSnakeCase = new CaseTransformer(new Format\CamelCase, new Format\SnakeCase);
30
        $this->loadExtensions();
31
        $this->loadFunctions();
32
    }
33
34
    protected function loadExtensions()
35
    {
36
        $this->twig->addExtension(new \Twig_Extensions_Extension_Date());
37
        $this->twig->addExtension(new \Twig_Extensions_Extension_Intl());
38
        $this->twig->addExtension(new \Twig_Extensions_Extension_Text());
39
        $this->twig->addExtension(new \Twig_Extensions_Extension_I18n());
40
    }
41
42
    protected function extendForTranslation()
43
    {
44
        $filter = new \Twig_SimpleFunction(
45
            '_t',
46
            function (
47
                $string,
48
                array $findAndReplace = null
49
            ) {
50
                $translation = _($string);
51
                if (is_array($findAndReplace)) {
52
                    $translateArray = $this->buildTranslateArray($findAndReplace);
53
                    $translation = strtr($translation, $translateArray);
54
                }
55
                return $translation;
56
            },
57
            array('is_safe' => array('html'))
58
        );
59
        $this->twig->addFunction($filter);
60
    }
61
62
    /**
63
     * Build translate array.
64
     * @param $translateArray
65
     * @return array
66
     */
67
    private function buildTranslateArray(array $translateArray)
68
    {
69
        $tmpArray = [];
70
        foreach ($translateArray as $key => $value) {
71
            $tmpArray['@'.$key] = $value;
72
        }
73
        return $tmpArray;
74
    }
75
76
    protected function extendForGetUrl()
77
    {
78
        $filter = new \Twig_SimpleFunction(
79
            'getUrl',
80
            function (
81
                $alias,
82
                $params = []
83
            ) {
84
                if (array_key_exists($alias, $this->config['aliases'])) {
85
                    $data = $this->config['aliases'][$alias];
86
                    $relative_path = $data;
87
                    foreach ($params as $param => $value) {
88
                        if (strpos($param, ':') === strlen($param)-1) {
89
                            $relative_path = preg_replace('/{'.$param.'(.*?)}/msi', $value, $relative_path);
90
                        } else {
91
                            $relative_path = str_replace('{'.$param.'}', $value, $relative_path);
92
                        }
93
                    }
94
                    return $this->config['base_url'] . '/' . $relative_path;
95
                }
96
                return '';
97
            },
98
            array('is_safe' => array('html'))
99
        );
100
        $this->twig->addFunction($filter);
101
    }
102
103
    protected function extendForWidget()
104
    {
105
        $filter = new \Twig_SimpleFunction(
106
            'Widget_*_*',
107
            function ($widgetNameStr, $widgetActionStr, $args = []) {
108
                $widgetAction = $this->toCamelCase->transform($widgetActionStr);
109
                $widgetName = $this->toCamelCase->transform($widgetNameStr);
110
                $widget = '\\' . $this->config['app_namespace'] . '\\Widget\\' . $widgetName;
111
                if (!class_exists($widget)) {
112
                    $message = 'Widget ' . $widgetName . '_' . $widgetAction . ' has not class name as ' . $widget;
113
                    throw new BadMethodCallException($message);
114
                }
115
                $widgetInstance = new $widget($args);
116
                if (!method_exists($widgetInstance, $widgetAction)) {
117
                    $message = 'Widget ' . $widget . ' has not method name as ' . $widgetAction;
118
                    throw new BadMethodCallException($message);
119
                }
120
                $templateFileBasename = $args['template'] ?? $this->toSnakeCase->transform($widgetActionStr) . '.twig';
121
                $templateFullPath = $this->config['templates_dir'] . '/_widgets/'
122
                    . $this->toSnakeCase->transform($widgetNameStr) . '/' . $templateFileBasename;
123
124
                if (!file_exists($templateFullPath)) {
125
                    $message = sprintf(
126
                        '%s  template file not found! %s needs a main template file at: %s',
127
                        $templateFileBasename,
128
                        $widgetNameStr . '_' . $widgetActionStr,
129
                        $templateFullPath
130
                    );
131
                    throw new InvalidArgumentException($message);
132
                }
133
                $templateFile =  '_widgets/'
134
                    . $this->toSnakeCase->transform($widgetNameStr) . '/' . $templateFileBasename;
135
                $widgetData = $widgetInstance->{$widgetAction}();
136
                return $this->twig->render($templateFile, $widgetData);
137
            },
138
            array('is_safe' => array('html'))
139
        );
140
        $this->twig->addFunction($filter);
141
    }
142
143
    protected function extendForQueryParams()
144
    {
145
        $filter = new \Twig_SimpleFunction(
146
            'queryParams',
147
            function ($queryParams, $prefix = '?') {
148
                return $prefix . http_build_query($queryParams);
149
            },
150
            array('is_safe' => array('html'))
151
        );
152
        $this->twig->addFunction($filter);
153
    }
154
155
    protected function extendForSiteUrl()
156
    {
157
        $filter = new \Twig_SimpleFunction(
158
            'siteUrl',
159
            function ($path = '') {
160
                return $this->config['base_url'] . $path;
161
            },
162
            array('is_safe' => array('html'))
163
        );
164
        $this->twig->addFunction($filter);
165
    }
166
167
    protected function extendForVarDump()
168
    {
169
        $filter = new \Twig_SimpleFunction(
170
            'varDump',
171
            function ($args) {
172
                /** @noinspection ForgottenDebugOutputInspection */
173
                var_dump($args);
174
            },
175
            array('is_safe' => array('html'))
176
        );
177
        $this->twig->addFunction($filter);
178
    }
179
180
    protected function extendForPagination()
181
    {
182
        /** @noinspection MoreThanThreeArgumentsInspection */
183
        $filter = new \Twig_SimpleFunction(
184
            'Pagination',
185
            function (
186
                int $total,
187
                int $current,
188
                string $linkTemplate,
189
                string $parentTemplate = '<ul class="pagination">(items)</ul>',
190
                string $itemTemplate = '<li class="(item_class)">(link)</li>',
191
                string $linkItemTemplate = '<a href="(href)" class="(link_class)">(text)</a>',
192
                string $ellipsesTemplate = '<li><a>...</a></li>'
193
            ) {
194
                $items =  '';
195
                $pageGroupLimit = 3;
196
                $useEllipses = ($total >10) ? 1 : 0;
197
                $renderedEllipses = 0;
198
                $values = [
199
                    '(item_class)'  => '',
200
                    '(href)'        => '',
201
                    '(link_class)'  => '',
202
                    '(text)'  => ''
203
                ];
204
                for ($i=1; $i <= $total; $i++) {
205
                    $values['(link_class)'] = '';
206
                    $values['(item_class)'] = '';
207
                    if ($i === $current) {
208
                        $values['(link_class)'] = 'active';
209
                        $values['(item_class)'] = 'active';
210
                    }
211
                    $values['(text)'] = $i;
212
                    $values['(href)'] = str_replace('(page_num)', $i, $linkTemplate);
213
                    $link = strtr($linkItemTemplate, $values);
214
                    $useLink = 1;
215
                    if ($useEllipses === 1) {
216
                        $useLink = 0;
217
                        if (($i <= $pageGroupLimit)
218
                            ||  ($i >= ($current-1) && $i <= ($current+1))
219
                            || ($i >= ($total-2))
220
                        ) {
221
                            $useLink = 1;
222
                            $renderedEllipses = 0;
223
                        } else {
224
                            if ($renderedEllipses === 0) {
225
                                $items .= $ellipsesTemplate;
226
                            }
227
                            $renderedEllipses = 1;
228
                        }
229
                    }
230
                    if ($useLink === 1) {
231
                        $thisItemTemplate = str_replace(
232
                            array('(link)'),
233
                            array($link),
234
                            $itemTemplate
235
                        );
236
                        $items .= strtr($thisItemTemplate, $values);
237
                    }
238
                }
239
                return str_replace('(items)', $items, $parentTemplate);
240
            },
241
            array('is_safe' => array('html'))
242
        );
243
        $this->twig->addFunction($filter);
244
    }
245
}
246