Passed
Pull Request — master (#6396)
by Angel Fernando Quiroz
08:39
created

ChamiloHelper::getPlatformLogoPath()   F

Complexity

Conditions 17
Paths 250

Size

Total Lines 66
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 36
nc 250
nop 3
dl 0
loc 66
rs 3.7583
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Helpers;
8
9
use Chamilo\CoreBundle\Framework\Container;
10
use ChamiloSession as Session;
11
use Database;
12
use DateInterval;
13
use DateTime;
14
use DateTimeZone;
15
use Display;
16
use Exception;
17
use Template;
18
19
use const PHP_SAPI;
20
21
class ChamiloHelper
22
{
23
    public const COURSE_MANAGER = 1;
24
    public const SESSION_ADMIN = 3;
25
    public const DRH = 4;
26
    public const STUDENT = 5;
27
    public const ANONYMOUS = 6;
28
29
    private static array $configuration;
30
31
    public function setConfiguration(array $configuration)
32
    {
33
        self::$configuration = $configuration;
34
    }
35
36
    public static function getConfigurationArray(): array
37
    {
38
        return self::$configuration;
39
    }
40
41
    public static function getConfigurationValue(string $variable): mixed
42
    {
43
        $configuration = self::getConfigurationArray();
44
        if (\array_key_exists($variable, $configuration)) {
45
            return $configuration[$variable];
46
        }
47
48
        return false;
49
    }
50
51
    /**
52
     * Returns an array of resolutions that can be used for the conversion of documents to images.
53
     */
54
    public static function getDocumentConversionSizes(): array
55
    {
56
        return [
57
            '540x405' => '540x405 (3/4)',
58
            '640x480' => '640x480 (3/4)',
59
            '720x540' => '720x540 (3/4)',
60
            '800x600' => '800x600 (3/4)',
61
            '1024x576' => '1024x576 (16/9)',
62
            '1024x768' => '1000x750 (3/4)',
63
            '1280x720' => '1280x720 (16/9)',
64
            '1280x860' => '1280x960 (3/4)',
65
            '1400x1050' => '1400x1050 (3/4)',
66
            '1600x900' => '1600x900 (16/9)',
67
        ];
68
    }
69
70
    /**
71
     * Get the platform logo path.
72
     *
73
     * @deprecated
74
     *
75
     * @throws Exception
76
     */
77
    public static function getPlatformLogoPath(
78
        string $theme = '',
79
        bool $getSysPath = false,
80
        bool $forcedGetter = false
81
    ): ?string {
82
        static $logoPath;
83
84
        // If call from CLI it should be reloaded.
85
        if ('cli' === PHP_SAPI) {
86
            $logoPath = null;
87
        }
88
89
        if (!isset($logoPath) || $forcedGetter) {
90
            $theme = empty($theme) ? api_get_visual_theme() : $theme;
91
            $accessUrlId = api_get_current_access_url_id();
92
            if ('cli' === PHP_SAPI) {
93
                $accessUrl = api_get_configuration_value('access_url');
94
                if (!empty($accessUrl)) {
95
                    $accessUrlId = $accessUrl;
96
                }
97
            }
98
            $themeDir = Template::getThemeDir($theme);
99
            $customLogoPath = $themeDir.\sprintf('images/header-logo-custom%s.png', $accessUrlId);
100
101
            $svgIcons = api_get_setting('icons_mode_svg');
102
            if ('true' === $svgIcons) {
103
                $customLogoPathSVG = substr($customLogoPath, 0, -3).'svg';
104
                if (file_exists(api_get_path(SYS_PUBLIC_PATH).\sprintf('css/%s', $customLogoPathSVG))) {
105
                    if ($getSysPath) {
106
                        return api_get_path(SYS_PUBLIC_PATH).\sprintf('css/%s', $customLogoPathSVG);
107
                    }
108
109
                    return api_get_path(WEB_CSS_PATH).$customLogoPathSVG;
110
                }
111
            }
112
            if (file_exists(api_get_path(SYS_PUBLIC_PATH).\sprintf('css/%s', $customLogoPath))) {
113
                if ($getSysPath) {
114
                    return api_get_path(SYS_PUBLIC_PATH).\sprintf('css/%s', $customLogoPath);
115
                }
116
117
                return api_get_path(WEB_CSS_PATH).$customLogoPath;
118
            }
119
120
            $originalLogoPath = $themeDir.'images/header-logo.png';
121
            if ('true' === $svgIcons) {
122
                $originalLogoPathSVG = $themeDir.'images/header-logo.svg';
123
                if (file_exists(api_get_path(SYS_CSS_PATH).$originalLogoPathSVG)) {
124
                    if ($getSysPath) {
125
                        return api_get_path(SYS_CSS_PATH).$originalLogoPathSVG;
126
                    }
127
128
                    return api_get_path(WEB_CSS_PATH).$originalLogoPathSVG;
129
                }
130
            }
131
132
            if (file_exists(api_get_path(SYS_CSS_PATH).$originalLogoPath)) {
133
                if ($getSysPath) {
134
                    return api_get_path(SYS_CSS_PATH).$originalLogoPath;
135
                }
136
137
                return api_get_path(WEB_CSS_PATH).$originalLogoPath;
138
            }
139
            $logoPath = '';
140
        }
141
142
        return $logoPath;
143
    }
144
145
    /**
146
     * Get the platform logo.
147
     * Return a <img> if the logo image exists.
148
     * Otherwise, return a <h2> with the institution name.
149
     *
150
     * @throws Exception
151
     */
152
    public static function getPlatformLogo(
153
        string $theme = '',
154
        array $imageAttributes = [],
155
        bool $getSysPath = false,
156
        bool $forcedGetter = false
157
    ): string {
158
        $logoPath = Container::getThemeHelper()->getThemeAssetUrl('images/header-logo.svg');
159
160
        if (empty($logoPath)) {
161
            $logoPath = Container::getThemeHelper()->getThemeAssetUrl('images/header-logo.png');
162
        }
163
164
        $institution = api_get_setting('Institution');
165
        $institutionUrl = api_get_setting('InstitutionUrl');
166
        $siteName = api_get_setting('siteName');
167
168
        if (null === $logoPath) {
169
            $headerLogo = Display::url($siteName, api_get_path(WEB_PATH).'index.php');
170
171
            if (!empty($institutionUrl) && !empty($institution)) {
172
                $headerLogo .= ' - '.Display::url($institution, $institutionUrl);
173
            }
174
175
            $courseInfo = api_get_course_info();
176
            if (isset($courseInfo['extLink']) && !empty($courseInfo['extLink']['name'])) {
177
                $headerLogo .= '<span class="extLinkSeparator"> - </span>';
178
179
                if (!empty($courseInfo['extLink']['url'])) {
180
                    $headerLogo .= Display::url(
181
                        $courseInfo['extLink']['name'],
182
                        $courseInfo['extLink']['url'],
183
                        [
184
                            'class' => 'extLink',
185
                        ]
186
                    );
187
                } elseif (!empty($courseInfo['extLink']['url'])) {
188
                    $headerLogo .= $courseInfo['extLink']['url'];
189
                }
190
            }
191
192
            return Display::tag('h2', $headerLogo, [
193
                'class' => 'text-left',
194
            ]);
195
        }
196
197
        $image = Display::img($logoPath, $institution, $imageAttributes);
198
199
        return Display::url($image, api_get_path(WEB_PATH).'index.php');
200
    }
201
202
    /**
203
     * Like strip_tags(), but leaves an additional space and removes only the given tags.
204
     *
205
     * @param array $tags Tags to be removed
206
     *
207
     * @return string The original string without the given tags
208
     */
209
    public static function stripGivenTags(string $string, array $tags): string
210
    {
211
        foreach ($tags as $tag) {
212
            $string2 = preg_replace('#</\b'.$tag.'\b[^>]*>#i', ' ', $string);
213
            if ($string2 !== $string) {
214
                $string = preg_replace('/<\b'.$tag.'\b[^>]*>/i', ' ', $string2);
215
            }
216
        }
217
218
        return $string;
219
    }
220
221
    /**
222
     * Adds or Subtract a time in hh:mm:ss to a datetime.
223
     *
224
     * @param string $time      Time to add or substract in hh:mm:ss format
225
     * @param string $datetime  Datetime to be modified as accepted by the Datetime class constructor
226
     * @param bool   $operation True for Add, False to Subtract
227
     *
228
     * @throws Exception
229
     */
230
    public static function addOrSubTimeToDateTime(
231
        string $time,
232
        string $datetime = 'now',
233
        bool $operation = true
234
    ): string {
235
        $date = new DateTime($datetime);
236
        $hours = 0;
237
        $minutes = 0;
238
        $seconds = 0;
239
        sscanf($time, '%d:%d:%d', $hours, $minutes, $seconds);
240
        $timeSeconds = isset($seconds) ? $hours * 3600 + $minutes * 60 + $seconds : $hours * 60 + $minutes;
241
        if ($operation) {
242
            $date->add(new DateInterval('PT'.$timeSeconds.'S'));
243
        } else {
244
            $date->sub(new DateInterval('PT'.$timeSeconds.'S'));
245
        }
246
247
        return $date->format('Y-m-d H:i:s');
248
    }
249
250
    /**
251
     * Returns the course id (integer) for the given course directory or the current ID if no directory is defined.
252
     *
253
     * @param string|null $directory The course directory/path that appears in the URL
254
     *
255
     * @throws Exception
256
     */
257
    public static function getCourseIdByDirectory(?string $directory = null): int
258
    {
259
        if (!empty($directory)) {
260
            $directory = Database::escape_string($directory);
261
            $row = Database::select(
262
                'id',
263
                Database::get_main_table(TABLE_MAIN_COURSE),
264
                [
265
                    'where' => [
266
                        'directory = ?' => [$directory],
267
                    ],
268
                ],
269
                'first'
270
            );
271
272
            if (\is_array($row) && isset($row['id'])) {
273
                return $row['id'];
274
            }
275
276
            return 0;
277
        }
278
279
        return (int) Session::read('_real_cid', 0);
280
    }
281
282
    /**
283
     * Check if the current HTTP request is by AJAX.
284
     */
285
    public static function isAjaxRequest(): bool
286
    {
287
        $requestedWith = $_SERVER['HTTP_X_REQUESTED_WITH'] ?? null;
288
289
        return 'XMLHttpRequest' === $requestedWith;
290
    }
291
292
    /**
293
     * Get a variable name for language file from a text.
294
     */
295
    public static function getLanguageVar(string $text, string $prefix = ''): string
296
    {
297
        $text = api_replace_dangerous_char($text);
298
        $text = str_replace(['-', ' ', '.'], '_', $text);
299
        $text = preg_replace('/_+/', '_', $text);
300
        // $text = str_replace('_', '', $text);
301
        $text = api_underscore_to_camel_case($text);
302
303
        return $prefix.$text;
304
    }
305
306
    /**
307
     * Get the stylesheet path for HTML blocks created with CKEditor.
308
     */
309
    public static function getEditorBlockStylePath(): string
310
    {
311
        $visualTheme = api_get_visual_theme();
312
313
        $cssFile = api_get_path(SYS_CSS_PATH).\sprintf('themes/%s/editor_content.css', $visualTheme);
314
315
        if (is_file($cssFile)) {
316
            return api_get_path(WEB_CSS_PATH).\sprintf('themes/%s/editor_content.css', $visualTheme);
317
        }
318
319
        return api_get_path(WEB_CSS_PATH).'editor_content.css';
320
    }
321
322
    /**
323
     * Get a list of colors from the palette at main/palette/pchart/default.color
324
     * and return it as an array of strings.
325
     *
326
     * @param bool     $decimalOpacity Whether to return the opacity as 0..100 or 0..1
327
     * @param bool     $wrapInRGBA     Whether to return it as 1,1,1,100 or rgba(1,1,1,100)
328
     * @param int|null $fillUpTo       If the number of colors is smaller than this number, generate more colors
329
     *
330
     * @return array An array of string colors
331
     */
332
    public static function getColorPalette(
333
        bool $decimalOpacity = false,
334
        bool $wrapInRGBA = false,
335
        ?int $fillUpTo = null
336
    ): array {
337
        // Get the common colors from the palette used for pchart
338
        $paletteFile = api_get_path(SYS_CODE_PATH).'palettes/pchart/default.color';
339
        $palette = file($paletteFile);
340
        if ($decimalOpacity) {
341
            // Because the pchart palette has transparency as integer values
342
            // (0..100) and chartjs uses percentage (0.0..1.0), we need to divide
343
            // the last value by 100, which is a bit overboard for just one chart
344
            foreach ($palette as $index => $color) {
345
                $components = explode(',', trim($color));
346
                $components[3] = round((int) $components[3] / 100, 1);
347
                $palette[$index] = implode(',', $components);
348
            }
349
        }
350
        if ($wrapInRGBA) {
351
            foreach ($palette as $index => $color) {
352
                $color = trim($color);
353
                $palette[$index] = 'rgba('.$color.')';
354
            }
355
        }
356
        // If we want more colors, loop through existing colors
357
        $count = \count($palette);
358
        if (isset($fillUpTo) && $fillUpTo > $count) {
359
            for ($i = $count; $i < $fillUpTo; $i++) {
360
                $palette[$i] = $palette[$i % $count];
361
            }
362
        }
363
364
        return $palette;
365
    }
366
367
    /**
368
     * Get the local time for the midnight.
369
     *
370
     * @param null|string $utcTime Optional. The time to ve converted.
371
     *                             See api_get_local_time.
372
     *
373
     * @throws Exception
374
     */
375
    public static function getServerMidnightTime(?string $utcTime = null): DateTime
376
    {
377
        $localTime = api_get_local_time($utcTime);
378
        $localTimeZone = api_get_timezone();
379
380
        $localMidnight = new DateTime($localTime, new DateTimeZone($localTimeZone));
381
        $localMidnight->modify('midnight');
382
383
        return $localMidnight;
384
    }
385
386
    /**
387
     * Get JavaScript code necessary to load quiz markers-rolls in medialement's Markers Rolls plugin.
388
     */
389
    public static function getQuizMarkersRollsJS(): string
390
    {
391
        $webCodePath = api_get_path(WEB_CODE_PATH);
392
        $cidReq = api_get_cidreq(true, true, 'embeddable');
393
        $colorPalette = self::getColorPalette(false, true);
394
395
        return "
396
            var \$originalNode = $(originalNode),
397
                    qMarkersRolls = \$originalNode.data('q-markersrolls') || [],
398
                    qMarkersColor = \$originalNode.data('q-markersrolls-color') || '$colorPalette[0]';
399
400
                if (0 == qMarkersRolls.length) {
401
                    return;
402
                }
403
404
                instance.options.markersRollsColor = qMarkersColor;
405
                instance.options.markersRollsWidth = 2;
406
                instance.options.markersRolls = {};
407
408
                qMarkersRolls.forEach(function (qMarkerRoll) {
409
                    var url = '{$webCodePath}exercise/exercise_submit.php?$cidReq&'
410
                        + $.param({
411
                            exerciseId: qMarkerRoll[1],
412
                            learnpath_id: 0,
413
                            learnpath_item_id: 0,
414
                            learnpath_item_view_id: 0
415
                        });
416
417
                    instance.options.markersRolls[qMarkerRoll[0]] = url;
418
                });
419
420
                instance.buildmarkersrolls(instance, instance.controls, instance.layers, instance.media);
421
        ";
422
    }
423
424
    /**
425
     * Performs a redirection to the specified URL.
426
     *
427
     * This method sends a direct HTTP Location header to the client,
428
     * causing the browser to navigate to the specified URL. It should be
429
     * used with caution and only in scenarios where Symfony's standard
430
     * response handling is not applicable. The method terminates script
431
     * execution after sending the header.
432
     */
433
    public static function redirectTo(string $url): void
434
    {
435
        if (!empty($url)) {
436
            header("Location: $url");
437
438
            exit;
439
        }
440
    }
441
}
442