Completed
Push — master ( e52670...48cc3d )
by Craig
08:32
created

CoreExtension::protectMailAddress()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Zikula package.
5
 *
6
 * Copyright Zikula Foundation - http://zikula.org/
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Zikula\Bundle\CoreBundle\Twig\Extension;
13
14
use Symfony\Component\DependencyInjection\ContainerInterface;
15
use Symfony\Component\Intl\Intl;
16
use Zikula\Bundle\CoreBundle\Twig;
17
use Zikula\Bundle\CoreBundle\Twig\Extension\SimpleFunction\DefaultPathSimpleFunction;
18
use Zikula\Bundle\CoreBundle\Twig\Extension\SimpleFunction\DispatchEventSimpleFunction;
19
use Zikula\Common\Translator\TranslatorInterface;
20
use Zikula\ThemeModule\Engine\AssetBag;
21
22
class CoreExtension extends \Twig_Extension
23
{
24
    /**
25
     * @var ContainerInterface
26
     */
27
    private $container;
28
29
    /**
30
     * @var TranslatorInterface
31
     */
32
    private $translator;
33
34
    public function __construct(ContainerInterface $container = null)
35
    {
36
        $this->container = $container;
37
        $this->translator = $container->get('translator.default');
38
    }
39
40
    /**
41
     * @return ContainerInterface
42
     */
43
    public function getContainer()
44
    {
45
        return $this->container;
46
    }
47
48
    public function getTokenParsers()
49
    {
50
        return [
51
            new Twig\TokenParser\SwitchTokenParser()
52
        ];
53
    }
54
55
    /**
56
     * Returns a list of functions to add to the existing list.
57
     *
58
     * @return array An array of functions
59
     */
60
    public function getFunctions()
61
    {
62
        $functions = [
63
            new \Twig_SimpleFunction('button', [$this, 'button']),
64
            new \Twig_SimpleFunction('img', [$this, 'img']),
65
            new \Twig_SimpleFunction('icon', [$this, 'icon']),
66
            new \Twig_SimpleFunction('lang', [$this, 'lang']),
67
            new \Twig_SimpleFunction('langdirection', [$this, 'langDirection']),
68
            new \Twig_SimpleFunction('zasset', [$this, 'getAssetPath']),
69
            new \Twig_SimpleFunction('showflashes', [$this, 'showFlashes'], ['is_safe' => ['html']]),
70
            new \Twig_SimpleFunction('array_unset', [$this, 'arrayUnset']),
71
            new \Twig_SimpleFunction('pageSetVar', [$this, 'pageSetVar']),
72
            new \Twig_SimpleFunction('pageAddAsset', [$this, 'pageAddAsset']),
73
            new \Twig_SimpleFunction('pageGetVar', [$this, 'pageGetVar']),
74
            new \Twig_SimpleFunction('getModVar', [$this, 'getModVar']),
75
            new \Twig_SimpleFunction('getSystemVar', [$this, 'getSystemVar']),
76
            new \Twig_SimpleFunction('setMetaTag', [$this, 'setMetaTag']),
77
            new \Twig_SimpleFunction('defaultPath', [new DefaultPathSimpleFunction($this), 'getDefaultPath']),
78
            new \Twig_SimpleFunction('modAvailable', [$this, 'modAvailable']),
79
            new \Twig_SimpleFunction('callFunc', [$this, 'callFunc']),
80
        ];
81
        if (is_object($this->container)) {
82
            $functions[] = new \Twig_SimpleFunction('dispatchEvent', [new DispatchEventSimpleFunction($this->container->get('event_dispatcher')), 'dispatchEvent']);
83
        }
84
85
        return $functions;
86
    }
87
88
    public function getFilters()
89
    {
90
        return [
91
            new \Twig_SimpleFilter('languageName', [$this, 'languageName']),
92
            new \Twig_SimpleFilter('yesNo', [$this, 'yesNo']),
93
            new \Twig_SimpleFilter('php', [$this, 'applyPhp']),
94
            new \Twig_SimpleFilter('protectMail', [$this, 'protectMailAddress'], ['is_safe' => ['html']]),
95
        ];
96
    }
97
98
    public function getAssetPath($path)
99
    {
100
        return $this->container->get('zikula_core.common.theme.asset_helper')->resolve($path);
101
    }
102
103
    public function button()
104
    {
105
    }
106
107
    public function img()
108
    {
109
    }
110
111
    public function icon()
112
    {
113
    }
114
115
    /**
116
     * Display flash messages in twig template. Defaults to bootstrap alert classes.
117
     *
118
     * <pre>
119
     *  {{ showflashes() }}
120
     *  {{ showflashes({'class': 'custom-class', 'tag': 'span'}) }}
121
     * </pre>
122
     *
123
     * @param array $params
124
     * @return string
125
     */
126
    public function showFlashes(array $params = [])
127
    {
128
        $result = '';
129
        $total_messages = [];
130
        $messageTypeMap = [
131
            'error' => 'danger',
132
            'warning' => 'warning',
133
            'status' => 'success',
134
            'danger' => 'danger',
135
            'success' => 'success',
136
            'info' => 'info'
137
            // @todo provide some class constants to use instead of direct strings
138
        ];
139
140
        foreach ($messageTypeMap as $messageType => $bootstrapClass) {
141
            $session = $this->container->get('session');
142
            $messages = $session->isStarted() ? $session->getFlashBag()->get($messageType) : [];
143
            if (count($messages) > 0) {
144
                // Set class for the messages.
145
                $class = (!empty($params['class'])) ? $params['class'] : "alert alert-$bootstrapClass";
146
                $total_messages = $total_messages + $messages;
147
                // Build output of the messages.
148
                if (empty($params['tag']) || ($params['tag'] != 'span')) {
149
                    $params['tag'] = 'div';
150
                }
151
                $result .= '<' . $params['tag'] . ' class="' . $class . '"';
152
                if (!empty($params['style'])) {
153
                    $result .= ' style="' . $params['style'] . '"';
154
                }
155
                $result .= '>';
156
                $result .= implode('<hr />', $messages);
157
                $result .= '</' . $params['tag'] . '>';
158
            }
159
        }
160
161
        if (empty($total_messages)) {
162
            return "";
163
        }
164
165
        return $result;
166
    }
167
168
    /**
169
     * Delete a key of an array
170
     *
171
     * @param array  $array Source array
172
     * @param string $key   The key to remove
173
     *
174
     * @return array
175
     */
176
    public function arrayUnset($array, $key)
177
    {
178
        unset($array[$key]);
179
180
        return $array;
181
    }
182
183
    /**
184
     * @param string $code
185
     * @return string
186
     */
187
    public function languageName($code)
188
    {
189
        return Intl::getLanguageBundle()->getLanguageName($code);
190
    }
191
192
    public function yesNo($string)
193
    {
194
        if ($string != '0' && $string != '1') {
195
            return $string;
196
        }
197
198
        return (bool)$string ? $this->translator->__('Yes') : $this->translator->__('No');
199
    }
200
201
    /**
202
     * Apply an existing function (e.g. php's `md5`) to a string.
203
     *
204
     * @param $string
205
     * @param $func
206
     * @return mixed
207
     */
208
    public function applyPhp($string, $func)
209
    {
210
        if (function_exists($func)) {
211
            return $func($string);
212
        }
213
214
        return $string;
215
    }
216
217
    /**
218
     * Protect a given mail address by finding the text 'x@y' and replacing
219
     * it with HTML entities. This provides protection against email harvesters.
220
     *
221
     * @param string
222
     * @return string
223
     */
224
    public function protectMailAddress($string)
225
    {
226
        $string = preg_replace_callback(
227
            '/(.)@(.)/s',
228
            function ($m) {
229
                return "&#" . sprintf("%03d", ord($m[1])) . ";&#064;&#" .sprintf("%03d", ord($m[2])) . ";";
230
            },
231
            $string
232
        );
233
234
        return $string;
235
    }
236
237
    /**
238
     * Zikula imposes no restriction on page variable names.
239
     * Typical usage is to set `title` `meta.charset` `lang` etc.
240
     * array values are set using `.` in the `$name` string (e.g. `meta.charset`)
241
     * @param string $name
242
     * @param string $value
243
     */
244 View Code Duplication
    public function pageSetVar($name, $value)
0 ignored issues
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...
245
    {
246
        if (empty($name) || empty($value)) {
247
            throw new \InvalidArgumentException($this->translator->__('Empty argument at') . ':' . __FILE__ . '::' . __LINE__);
248
        }
249
250
        $this->container->get('zikula_core.common.theme.pagevars')->set($name, $value);
251
    }
252
253
    /**
254
     * Zikula allows only the following asset types
255
     * <ul>
256
     *  <li>stylesheet</li>
257
     *  <li>javascript</li>
258
     *  <li>header</li>
259
     *  <li>footer</li>
260
     * </ul>
261
     *
262
     * @param string $type
263
     * @param string $value
264
     * @param int $weight
265
     */
266
    public function pageAddAsset($type, $value, $weight = AssetBag::WEIGHT_DEFAULT)
267
    {
268
        if (empty($type) || empty($value)) {
269
            throw new \InvalidArgumentException($this->translator->__('Empty argument at') . ':' . __FILE__ . '::' . __LINE__);
270
        }
271
        if (!in_array($type, ['stylesheet', 'javascript', 'header', 'footer']) || !is_numeric($weight)) {
272
            throw new \InvalidArgumentException($this->translator->__('Empty argument at') . ':' . __FILE__ . '::' . __LINE__);
273
        }
274
275
        // ensure proper variable types
276
        $value = (string) $value;
277
        $type = (string) $type;
278
        $weight = (int) $weight;
279
280
        if ('stylesheet' == $type) {
281
            $this->container->get('zikula_core.common.theme.assets_css')->add([$value => $weight]);
282
        } elseif ('javascript' == $type) {
283
            $this->container->get('zikula_core.common.theme.assets_js')->add([$value => $weight]);
284
        } elseif ('header' == $type) {
285
            $this->container->get('zikula_core.common.theme.assets_header')->add([$value => $weight]);
286
        } elseif ('footer' == $type) {
287
            $this->container->get('zikula_core.common.theme.assets_footer')->add([$value => $weight]);
288
        }
289
    }
290
291
    /**
292
     * @param $name
293
     * @param null $default
294
     * @return mixed
295
     */
296 View Code Duplication
    public function pageGetVar($name, $default = null)
0 ignored issues
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...
297
    {
298
        if (empty($name)) {
299
            throw new \InvalidArgumentException($this->translator->__('Empty argument at') . ':' . __FILE__ . '::' . __LINE__);
300
        }
301
302
        return $this->container->get('zikula_core.common.theme.pagevars')->get($name, $default);
303
    }
304
305
    /**
306
     * @param $module
307
     * @param $name
308
     * @param null $default
309
     * @return mixed
310
     */
311 View Code Duplication
    public function getModVar($module, $name, $default = null)
0 ignored issues
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...
312
    {
313
        if (empty($module) || empty($name)) {
314
            throw new \InvalidArgumentException($this->translator->__('Empty argument at') . ':' . __FILE__ . '::' . __LINE__);
315
        }
316
317
        return $this->container->get('zikula_extensions_module.api.variable')->get($module, $name, $default);
318
    }
319
320
    /**
321
     * @param $name
322
     * @param null $default
323
     * @return mixed
324
     */
325 View Code Duplication
    public function getSystemVar($name, $default = null)
0 ignored issues
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...
326
    {
327
        if (empty($name)) {
328
            throw new \InvalidArgumentException($this->translator->__('Empty argument at') . ':' . __FILE__ . '::' . __LINE__);
329
        }
330
331
        return $this->container->get('zikula_extensions_module.api.variable')->getSystemVar($name, $default);
332
    }
333
334
    /**
335
     * @param string $name
336
     * @param string $value
337
     */
338
    public function setMetaTag($name, $value)
339
    {
340
        if (empty($name) || empty($value)) {
341
            throw new \InvalidArgumentException($this->translator->__('Empty argument at') . ':' . __FILE__ . '::' . __LINE__);
342
        }
343
344
        $metaTags = $this->container->hasParameter('zikula_view.metatags') ? $this->container->getParameter('zikula_view.metatags') : [];
345
        $metaTags[$name] = htmlspecialchars($value, ENT_QUOTES);
346
        $this->container->setParameter('zikula_view.metatags', $metaTags);
347
    }
348
349
    /**
350
     * Call a php callable with parameters.
351
     * @param callable $callable
352
     * @param array $params
353
     * @return mixed
354
     */
355
    public function callFunc(callable $callable, array $params = [])
356
    {
357
        if (function_exists($callable)) {
358
            return call_user_func_array($callable, $params);
359
        }
360
        throw new \InvalidArgumentException($this->translator->__('Function does not exist or is not callable.') . ':' . __FILE__ . '::' . __LINE__);
361
    }
362
}
363