Passed
Push — master ( 4234e3...bd08a9 )
by Angel Fernando Quiroz
07:04
created

ChamiloExtension   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 220
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 91
dl 0
loc 220
rs 10
c 2
b 0
f 0
wmc 18

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getFilters() 0 20 1
A __construct() 0 11 1
A getSettingsParameter() 0 3 1
A getThemeAssetLinkTag() 0 3 1
A completeUserNameWithLink() 0 12 1
A getThemeAssetBase64Encoded() 0 3 1
A getIllustration() 0 3 1
A getFunctions() 0 10 1
A getSettings() 0 3 1
B getPasswordCheckerJs() 0 107 7
A getName() 0 3 1
A getThemeAssetUrl() 0 3 1
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Twig\Extension;
8
9
use Chamilo\CoreBundle\Component\Utils\NameConvention;
10
use Chamilo\CoreBundle\Entity\ResourceIllustrationInterface;
11
use Chamilo\CoreBundle\Entity\User;
12
use Chamilo\CoreBundle\Repository\Node\IllustrationRepository;
13
use Chamilo\CoreBundle\ServiceHelper\ThemeHelper;
14
use Chamilo\CoreBundle\Twig\SettingsHelper;
15
use Security;
16
use Sylius\Bundle\SettingsBundle\Model\SettingsInterface;
17
use Symfony\Component\Routing\RouterInterface;
18
use Twig\Extension\AbstractExtension;
19
use Twig\TwigFilter;
20
use Twig\TwigFunction;
21
22
/**
23
 * Extend Twig with specifics from Chamilo. For globals, look into TwigListener.php.
24
 */
25
class ChamiloExtension extends AbstractExtension
26
{
27
    private IllustrationRepository $illustrationRepository;
28
    private SettingsHelper $helper;
29
    private RouterInterface $router;
30
    private NameConvention $nameConvention;
31
32
    public function __construct(
33
        IllustrationRepository $illustrationRepository,
34
        SettingsHelper $helper,
35
        RouterInterface $router,
36
        NameConvention $nameConvention,
37
        private readonly ThemeHelper $themeHelper
38
    ) {
39
        $this->illustrationRepository = $illustrationRepository;
40
        $this->helper = $helper;
41
        $this->router = $router;
42
        $this->nameConvention = $nameConvention;
43
    }
44
45
    public function getFilters(): array
46
    {
47
        return [
48
            new TwigFilter('var_dump', 'var_dump'),
49
            new TwigFilter('icon', 'Display::get_icon_path'),
50
            new TwigFilter('mdi_icon', 'Display::getMdiIconSimple'),
51
            new TwigFilter('mdi_icon_t', 'Display::getMdiIconTranslate'),
52
            new TwigFilter('get_lang', 'get_lang'),
53
            new TwigFilter('get_plugin_lang', 'get_plugin_lang'),
54
            new TwigFilter('api_get_local_time', 'api_get_local_time'),
55
            new TwigFilter('api_convert_and_format_date', 'api_convert_and_format_date'),
56
            new TwigFilter('format_date', 'api_format_date'),
57
            new TwigFilter('format_file_size', 'format_file_size'),
58
            new TwigFilter('date_to_time_ago', 'Display::dateToStringAgoAndLongDate'),
59
            new TwigFilter('api_get_configuration_value', 'api_get_configuration_value'),
60
            new TwigFilter('remove_xss', 'Security::remove_XSS'),
61
            new TwigFilter('user_complete_name', 'UserManager::formatUserFullName'),
62
            new TwigFilter('user_complete_name_with_link', $this->completeUserNameWithLink(...)),
63
            new TwigFilter('illustration', $this->getIllustration(...)),
64
            new TwigFilter('api_get_setting', $this->getSettingsParameter(...)),
65
        ];
66
    }
67
68
    public function getFunctions(): array
69
    {
70
        return [
71
            new TwigFunction('chamilo_settings_all', $this->getSettings(...)),
72
            new TwigFunction('chamilo_settings_get', $this->getSettingsParameter(...)),
73
            new TwigFunction('chamilo_settings_has', [$this, 'hasSettingsParameter']),
74
            new TwigFunction('password_checker_js', [$this, 'getPasswordCheckerJs'], ['is_safe' => ['html']]),
75
            new TwigFunction('theme_asset', $this->getThemeAssetUrl(...)),
76
            new TwigFunction('theme_asset_link_tag', $this->getThemeAssetLinkTag(...), ['is_safe' => ['html']]),
77
            new TwigFunction('theme_asset_base64', $this->getThemeAssetBase64Encoded(...)),
78
        ];
79
    }
80
81
    public function completeUserNameWithLink(User $user): string
82
    {
83
        $url = $this->router->generate(
84
            'legacy_main',
85
            [
86
                'name' => '/inc/ajax/user_manager.ajax.php?a=get_user_popup&user_id='.$user->getId(),
87
            ]
88
        );
89
90
        $name = $this->nameConvention->getPersonName($user);
91
92
        return "<a href=\"$url\" class=\"ajax\">$name</a>";
93
    }
94
95
    public function getIllustration(ResourceIllustrationInterface $resource): string
96
    {
97
        return $this->illustrationRepository->getIllustrationUrl($resource);
98
    }
99
100
    public function getSettings($namespace): SettingsInterface
101
    {
102
        return $this->helper->getSettings($namespace);
103
    }
104
105
    public function getSettingsParameter($name)
106
    {
107
        return $this->helper->getSettingsParameter($name);
108
    }
109
110
    /**
111
     * Generates and returns JavaScript code for a password strength checker.
112
     */
113
    public function getPasswordCheckerJs(string $passwordInputId): ?string
114
    {
115
        $checkPass = api_get_setting('allow_strength_pass_checker');
116
        $useStrengthPassChecker = 'true' === $checkPass;
117
118
        if (false === $useStrengthPassChecker) {
119
            return null;
120
        }
121
122
        $minRequirements = Security::getPasswordRequirements()['min'];
123
124
        $options = [
125
            'rules' => [],
126
        ];
127
128
        if ($minRequirements['length'] > 0) {
129
            $options['rules'][] = [
130
                'minChar' => $minRequirements['length'],
131
                'pattern' => '.',
132
                'helpText' => sprintf(
133
                    get_lang('Minimum %s characters in total'),
134
                    $minRequirements['length']
135
                ),
136
            ];
137
        }
138
139
        if ($minRequirements['lowercase'] > 0) {
140
            $options['rules'][] = [
141
                'minChar' => $minRequirements['lowercase'],
142
                'pattern' => '[a-z]',
143
                'helpText' => sprintf(
144
                    get_lang('Minimum %s lowercase characters'),
145
                    $minRequirements['lowercase']
146
                ),
147
            ];
148
        }
149
150
        if ($minRequirements['uppercase'] > 0) {
151
            $options['rules'][] = [
152
                'minChar' => $minRequirements['uppercase'],
153
                'pattern' => '[A-Z]',
154
                'helpText' => sprintf(
155
                    get_lang('Minimum %s uppercase characters'),
156
                    $minRequirements['uppercase']
157
                ),
158
            ];
159
        }
160
161
        if ($minRequirements['numeric'] > 0) {
162
            $options['rules'][] = [
163
                'minChar' => $minRequirements['numeric'],
164
                'pattern' => '[0-9]',
165
                'helpText' => sprintf(
166
                    get_lang('Minimum %s numerical (0-9) characters'),
167
                    $minRequirements['numeric']
168
                ),
169
            ];
170
        }
171
172
        if ($minRequirements['specials'] > 0) {
173
            $options['rules'][] = [
174
                'minChar' => $minRequirements['specials'],
175
                'pattern' => '[!"#$%&\'()*+,\-./\\\:;<=>?@[\\]^_`{|}~]',
176
                'helpText' => sprintf(
177
                    get_lang('Minimum %s special characters'),
178
                    $minRequirements['specials']
179
                ),
180
            ];
181
        }
182
183
        return "<script>
184
        (function($) {
185
            $.fn.passwordCheckerChange = function(options) {
186
                var settings = $.extend({
187
                    rules: []
188
                }, options );
189
190
                return this.each(function() {
191
                    var \$passwordInput = $(this);
192
                    var \$requirements = $('#password-requirements');
193
194
                    function validatePassword(password) {
195
                        var html = '';
196
197
                        settings.rules.forEach(function(rule) {
198
                            var isValid = new RegExp(rule.pattern).test(password) && password.length >= rule.minChar;
199
                            var color = isValid ? 'green' : 'red';
200
                            html += '<li style=\"color:' + color + '\">' + rule.helpText + '</li>';
201
                        });
202
203
                        \$requirements.html(html);
204
                    }
205
206
                    \$passwordInput.on('input', function() {
207
                        validatePassword(\$passwordInput.val());
208
                        \$requirements.show();
209
                    });
210
211
                    \$passwordInput.on('blur', function() {
212
                        \$requirements.hide();
213
                    });
214
                });
215
            };
216
        }(jQuery));
217
218
        $(function() {
219
            $('".$passwordInputId."').passwordCheckerChange(".json_encode($options).');
220
        });
221
        </script>';
222
    }
223
224
    /**
225
     * Returns the name of the extension.
226
     */
227
    public function getName(): string
228
    {
229
        return 'chamilo_extension';
230
    }
231
232
    public function getThemeAssetUrl(string $path, bool $absoluteUrl = false): string
233
    {
234
        return $this->themeHelper->getThemeAssetUrl($path, $absoluteUrl);
235
    }
236
237
    public function getThemeAssetLinkTag(string $path, bool $absoluteUrl = false): string
238
    {
239
        return $this->themeHelper->getThemeAssetLinkTag($path, $absoluteUrl);
240
    }
241
242
    public function getThemeAssetBase64Encoded(string $path): string
243
    {
244
        return $this->themeHelper->getAssetBase64Encoded($path);
245
    }
246
}
247