Passed
Pull Request — master (#5614)
by Angel Fernando Quiroz
11:40
created

ChamiloExtension::getThemeAssetUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 1
b 0
f 0
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
        ];
78
    }
79
80
    public function completeUserNameWithLink(User $user): string
81
    {
82
        $url = $this->router->generate(
83
            'legacy_main',
84
            [
85
                'name' => '/inc/ajax/user_manager.ajax.php?a=get_user_popup&user_id='.$user->getId(),
86
            ]
87
        );
88
89
        $name = $this->nameConvention->getPersonName($user);
90
91
        return "<a href=\"$url\" class=\"ajax\">$name</a>";
92
    }
93
94
    public function getIllustration(ResourceIllustrationInterface $resource): string
95
    {
96
        return $this->illustrationRepository->getIllustrationUrl($resource);
97
    }
98
99
    public function getSettings($namespace): SettingsInterface
100
    {
101
        return $this->helper->getSettings($namespace);
102
    }
103
104
    public function getSettingsParameter($name)
105
    {
106
        return $this->helper->getSettingsParameter($name);
107
    }
108
109
    /**
110
     * Generates and returns JavaScript code for a password strength checker.
111
     */
112
    public function getPasswordCheckerJs(string $passwordInputId): ?string
113
    {
114
        $checkPass = api_get_setting('allow_strength_pass_checker');
115
        $useStrengthPassChecker = 'true' === $checkPass;
116
117
        if (false === $useStrengthPassChecker) {
118
            return null;
119
        }
120
121
        $minRequirements = Security::getPasswordRequirements()['min'];
122
123
        $options = [
124
            'rules' => [],
125
        ];
126
127
        if ($minRequirements['length'] > 0) {
128
            $options['rules'][] = [
129
                'minChar' => $minRequirements['length'],
130
                'pattern' => '.',
131
                'helpText' => sprintf(
132
                    get_lang('Minimum %s characters in total'),
133
                    $minRequirements['length']
134
                ),
135
            ];
136
        }
137
138
        if ($minRequirements['lowercase'] > 0) {
139
            $options['rules'][] = [
140
                'minChar' => $minRequirements['lowercase'],
141
                'pattern' => '[a-z]',
142
                'helpText' => sprintf(
143
                    get_lang('Minimum %s lowercase characters'),
144
                    $minRequirements['lowercase']
145
                ),
146
            ];
147
        }
148
149
        if ($minRequirements['uppercase'] > 0) {
150
            $options['rules'][] = [
151
                'minChar' => $minRequirements['uppercase'],
152
                'pattern' => '[A-Z]',
153
                'helpText' => sprintf(
154
                    get_lang('Minimum %s uppercase characters'),
155
                    $minRequirements['uppercase']
156
                ),
157
            ];
158
        }
159
160
        if ($minRequirements['numeric'] > 0) {
161
            $options['rules'][] = [
162
                'minChar' => $minRequirements['numeric'],
163
                'pattern' => '[0-9]',
164
                'helpText' => sprintf(
165
                    get_lang('Minimum %s numerical (0-9) characters'),
166
                    $minRequirements['numeric']
167
                ),
168
            ];
169
        }
170
171
        if ($minRequirements['specials'] > 0) {
172
            $options['rules'][] = [
173
                'minChar' => $minRequirements['specials'],
174
                'pattern' => '[!"#$%&\'()*+,\-./\\\:;<=>?@[\\]^_`{|}~]',
175
                'helpText' => sprintf(
176
                    get_lang('Minimum %s special characters'),
177
                    $minRequirements['specials']
178
                ),
179
            ];
180
        }
181
182
        return "<script>
183
        (function($) {
184
            $.fn.passwordCheckerChange = function(options) {
185
                var settings = $.extend({
186
                    rules: []
187
                }, options );
188
189
                return this.each(function() {
190
                    var \$passwordInput = $(this);
191
                    var \$requirements = $('#password-requirements');
192
193
                    function validatePassword(password) {
194
                        var html = '';
195
196
                        settings.rules.forEach(function(rule) {
197
                            var isValid = new RegExp(rule.pattern).test(password) && password.length >= rule.minChar;
198
                            var color = isValid ? 'green' : 'red';
199
                            html += '<li style=\"color:' + color + '\">' + rule.helpText + '</li>';
200
                        });
201
202
                        \$requirements.html(html);
203
                    }
204
205
                    \$passwordInput.on('input', function() {
206
                        validatePassword(\$passwordInput.val());
207
                        \$requirements.show();
208
                    });
209
210
                    \$passwordInput.on('blur', function() {
211
                        \$requirements.hide();
212
                    });
213
                });
214
            };
215
        }(jQuery));
216
217
        $(function() {
218
            $('".$passwordInputId."').passwordCheckerChange(".json_encode($options).');
219
        });
220
        </script>';
221
    }
222
223
    /**
224
     * Returns the name of the extension.
225
     */
226
    public function getName(): string
227
    {
228
        return 'chamilo_extension';
229
    }
230
231
    public function getThemeAssetUrl(string $path, bool $absolute = false): string
232
    {
233
        return $this->themeHelper->getThemeAssetUrl($path, $absolute);
234
    }
235
236
    public function getThemeAssetLinkTag(string $path, bool $absoluteUrl = false): string
237
    {
238
        return $this->themeHelper->getThemeAssetLinkTag($path, $absoluteUrl);
239
    }
240
}
241