Dotclear

source: inc/admin/lib.themeconfig.php @ 3923:a3f699582de4

Revision 3923:a3f699582de4, 13.0 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

Fix some system constants

Line 
1<?php
2/**
3 * @package Dotclear
4 * @subpackage Backend
5 *
6 * @copyright Olivier Meunier & Association Dotclear
7 * @copyright GPL-2.0-only
8 */
9
10if (!defined('DC_CONTEXT_ADMIN')) {return;}
11
12/**
13 * @brief Helper for theme configurators.
14 * @since 2.7
15 *
16 * Provides helper tools for theme configurators.
17 */
18class dcThemeConfig
19{
20
21/**
22 * Compute contrast ratio between two colors
23 *
24 * @param  string $color      text color
25 * @param  string $background background color
26 *
27 * @return float             computed ratio
28 */
29    public static function computeContrastRatio($color, $background)
30    {
31        // Compute contrast ratio between two colors
32
33        $color = self::adjustColor($color);
34        if (($color == '') || (strlen($color) != 7)) {
35            return 0;
36        }
37
38        $background = self::adjustColor($background);
39        if (($background == '') || (strlen($background) != 7)) {
40            return 0;
41        }
42
43        $l1 = (0.2126 * pow(hexdec(substr($color, 1, 2)) / 255, 2.2)) +
44            (0.7152 * pow(hexdec(substr($color, 3, 2)) / 255, 2.2)) +
45            (0.0722 * pow(hexdec(substr($color, 5, 2)) / 255, 2.2));
46
47        $l2 = (0.2126 * pow(hexdec(substr($background, 1, 2)) / 255, 2.2)) +
48            (0.7152 * pow(hexdec(substr($background, 3, 2)) / 255, 2.2)) +
49            (0.0722 * pow(hexdec(substr($background, 5, 2)) / 255, 2.2));
50
51        if ($l1 > $l2) {
52            $ratio = ($l1 + 0.05) / ($l2 + 0.05);
53        } else {
54            $ratio = ($l2 + 0.05) / ($l1 + 0.05);
55        }
56        return $ratio;
57    }
58
59/**
60 * Compute WCAG contrast ration level
61 *
62 * @param  float  $ratio computed ratio between foreground and backround color
63 * @param  string  $size  font size as defined in CSS
64 * @param  boolean $bold  true if bold font
65 *
66 * @return string         WCAG contrast ratio level (AAA, AA or <nothing>)
67 */
68    public static function contrastRatioLevel($ratio, $size, $bold = false)
69    {
70        if ($size == '') {
71            return '';
72        }
73
74        // Eval font size in em (assume base font size in pixels equal to 16)
75        if (preg_match('/^([0-9.]+)\s*(%|pt|px|em|ex|rem)?$/', $size, $m)) {
76            if (empty($m[2])) {
77                $m[2] = 'em';
78            }
79        } else {
80            return '';
81        }
82        switch ($m[2]) {
83            case '%':
84                $s = (float) $m[1] / 100;
85                break;
86            case 'pt':
87                $s = (float) $m[1] / 12;
88                break;
89            case 'px':
90                $s = (float) $m[1] / 16;
91                break;
92            case 'em':
93                $s = (float) $m[1];
94                break;
95            case 'ex':
96                $s = (float) $m[1] / 2;
97                break;
98            default:
99                return '';
100        }
101
102        $large = ((($s > 1.5) && ($bold == false)) || (($s > 1.2) && ($bold == true)));
103
104        // Check ratio
105        if ($ratio > 7) {
106            return 'AAA';
107        } elseif (($ratio > 4.5) && $large) {
108            return 'AAA';
109        } elseif ($ratio > 4.5) {
110            return 'AA';
111        } elseif (($ratio > 3) && $large) {
112            return 'AA';
113        }
114        return '';
115    }
116
117/**
118 * Return full information about constrat ratio
119 *
120 * @param  string  $color      text color
121 * @param  string  $background background color
122 * @param  string  $size       font size
123 * @param  boolean $bold       bold font
124 *
125 * @return string              contrast ratio including WCAG level
126 */
127    public static function contrastRatio($color, $background, $size = '', $bold = false)
128    {
129        if (($color != '') && ($background != '')) {
130            $ratio = self::computeContrastRatio($color, $background);
131            $level = self::contrastRatioLevel($ratio, $size, $bold);
132            return
133            sprintf(__('ratio %.1f'), $ratio) .
134                ($level != '' ? ' ' . sprintf(__('(%s)'), $level) : '');
135        }
136        return '';
137    }
138
139/**
140 * Check font size
141 *
142 * @param  string $s font size
143 *
144 * @return string    checked font size
145 */
146    public static function adjustFontSize($s)
147    {
148        if (preg_match('/^([0-9.]+)\s*(%|pt|px|em|ex|rem)?$/', $s, $m)) {
149            if (empty($m[2])) {
150                $m[2] = 'em';
151            }
152            return $m[1] . $m[2];
153        }
154        return;
155    }
156
157/**
158 * Check object position, should be x:y
159 *
160 * @param  string $p position
161 *
162 * @return string    checked position
163 */
164    public static function adjustPosition($p)
165    {
166        if (!preg_match('/^[0-9]+(:[0-9]+)?$/', $p)) {
167            return;
168        }
169        $p = explode(':', $p);
170
171        return $p[0] . (count($p) == 1 ? ':0' : ':' . $p[1]);
172    }
173
174/**
175 * Check a CSS color
176 *
177 * @param  string $c CSS color
178 *
179 * @return string    checked CSS color
180 */
181    public static function adjustColor($c)
182    {
183        if ($c === '') {
184            return '';
185        }
186
187        $c = strtoupper($c);
188
189        if (preg_match('/^[A-F0-9]{3,6}$/', $c)) {
190            $c = '#' . $c;
191        }
192        if (preg_match('/^#[A-F0-9]{6}$/', $c)) {
193            return $c;
194        }
195        if (preg_match('/^#[A-F0-9]{3,}$/', $c)) {
196            return '#' . substr($c, 1, 1) . substr($c, 1, 1) . substr($c, 2, 1) . substr($c, 2, 1) . substr($c, 3, 1) . substr($c, 3, 1);
197        }
198
199        return '';
200    }
201
202/**
203 * Check and clean CSS
204 *
205 * @param  string $css CSS to be checked
206 *
207 * @return string      checked CSS
208 */
209    public static function cleanCSS($css)
210    {
211        // TODO ?
212        return $css;
213    }
214
215/**
216 * Return real path of a user defined CSS
217 *
218 * @param  string $folder CSS folder
219 *
220 * @return string         real path of CSS
221 */
222    public static function cssPath($folder)
223    {
224        global $core;
225        return path::real($core->blog->public_path) . '/' . $folder;
226    }
227
228/**
229 * Retirn URL of a user defined CSS
230 *
231 * @param  string $folder CSS folder
232 *
233 * @return string         CSS URL
234 */
235    public static function cssURL($folder)
236    {
237        global $core;
238        return $core->blog->settings->system->public_url . '/' . $folder;
239    }
240
241/**
242 * Check if user defined CSS may be written
243 *
244 * @param  string  $folder CSS folder
245 * @param  boolean $create create CSS folder if necessary
246 *
247 * @return boolean          true if CSS folder exists and may be written, else false
248 */
249    public static function canWriteCss($folder, $create = false)
250    {
251        global $core;
252
253        $public = path::real($core->blog->public_path);
254        $css    = self::cssPath($folder);
255
256        if (!is_dir($public)) {
257            $core->error->add(__('The \'public\' directory does not exist.'));
258            return false;
259        }
260
261        if (!is_dir($css)) {
262            if (!is_writable($public)) {
263                $core->error->add(sprintf(__('The \'%s\' directory cannot be modified.'), 'public'));
264                return false;
265            }
266            if ($create) {
267                files::makeDir($css);
268            }
269            return true;
270        }
271
272        if (!is_writable($css)) {
273            $core->error->add(sprintf(__('The \'%s\' directory cannot be modified.'), 'public/' . $folder));
274            return false;
275        }
276
277        return true;
278    }
279
280/**
281 * Store CSS property value in associated array
282 *
283 * @param  array $css       CSS associated array
284 * @param  string $selector selector
285 * @param  string $prop     property
286 * @param  string $value    value
287 */
288    public static function prop(&$css, $selector, $prop, $value)
289    {
290        if ($value) {
291            $css[$selector][$prop] = $value;
292        }
293    }
294
295/**
296 * Store background image property in CSS associated array
297 *
298 * @param  string $folder   image folder
299 * @param  array $css       CSS associated array
300 * @param  string $selector selector
301 * @param  boolean $value   false for default, true if image should be set
302 * @param  string $image    image filename
303 */
304    public static function backgroundImg($folder, &$css, $selector, $value, $image)
305    {
306        $file = self::imagesPath($folder) . '/' . $image;
307        if ($value && file_exists($file)) {
308            $css[$selector]['background-image'] = 'url(' . self::imagesURL($folder) . '/' . $image . ')';
309        }
310    }
311
312/**
313 * Write CSS file
314 *
315 * @param  string $folder CSS folder
316 * @param  string $theme  CSS filename
317 * @param  string $css    CSS file content
318 */
319    public static function writeCss($folder, $theme, $css)
320    {
321        file_put_contents(self::cssPath($folder) . '/' . $theme . '.css', $css);
322    }
323
324/**
325 * Delete CSS file
326 *
327 * @param  string $folder CSS folder
328 * @param  string $theme  CSS filename to be removed
329 */
330    public static function dropCss($folder, $theme)
331    {
332        $file = path::real(self::cssPath($folder) . '/' . $theme . '.css');
333        if (is_writable(dirname($file))) {
334            @unlink($file);
335        }
336    }
337
338/**
339 * Return public URL of user defined CSS
340 *
341 * @param  string $folder CSS folder
342 *
343 * @return string         CSS file URL
344 */
345    public static function publicCssUrlHelper($folder)
346    {
347        $theme = $GLOBALS['core']->blog->settings->system->theme;
348        $url   = self::cssURL($folder);
349        $path  = self::cssPath($folder);
350
351        if (file_exists($path . '/' . $theme . '.css')) {
352            return $url . '/' . $theme . '.css';
353        }
354
355        return;
356    }
357
358/**
359 * Return real path of folder images
360 *
361 * @param  string $folder images folder
362 *
363 * @return string         real path of folder
364 */
365    public static function imagesPath($folder)
366    {
367        global $core;
368        return path::real($core->blog->public_path) . '/' . $folder;
369    }
370
371/**
372 * Return URL of images folder
373 *
374 * @param  string $folder images folder
375 *
376 * @return string         URL of images folder
377 */
378    public static function imagesURL($folder)
379    {
380        global $core;
381        return $core->blog->settings->system->public_url . '/' . $folder;
382    }
383
384/**
385 * Check if images folder exists and may be written
386 *
387 * @param  string  $folder images folder
388 * @param  boolean $create create the folder if not exists
389 *
390 * @return boolean          true if folder exists and may be written
391 */
392    public static function canWriteImages($folder, $create = false)
393    {
394        global $core;
395
396        $public = path::real($core->blog->public_path);
397        $imgs   = self::imagesPath($folder);
398
399        if (!function_exists('imagecreatetruecolor') || !function_exists('imagepng') || !function_exists('imagecreatefrompng')) {
400            $core->error->add(__('At least one of the following functions is not available: ' .
401                'imagecreatetruecolor, imagepng & imagecreatefrompng.'));
402            return false;
403        }
404
405        if (!is_dir($public)) {
406            $core->error->add(__('The \'public\' directory does not exist.'));
407            return false;
408        }
409
410        if (!is_dir($imgs)) {
411            if (!is_writable($public)) {
412                $core->error->add(sprintf(__('The \'%s\' directory cannot be modified.'), 'public'));
413                return false;
414            }
415            if ($create) {
416                files::makeDir($imgs);
417            }
418            return true;
419        }
420
421        if (!is_writable($imgs)) {
422            $core->error->add(sprintf(__('The \'%s\' directory cannot be modified.'), 'public/' . $folder));
423            return false;
424        }
425
426        return true;
427    }
428
429/**
430 * Upload an image in images folder
431 *
432 * @param  string $folder images folder
433 * @param  string $f      selected image file (as $_FILES[<file input fieldname>])
434 * @param  int    $width  check accurate width of uploaded image if <> 0
435 *
436 * @return string         full pathname of uploaded image
437 */
438    public static function uploadImage($folder, $f, $width = 0)
439    {
440        if (!self::canWriteImages($folder, true)) {
441            throw new Exception(__('Unable to create images.'));
442        }
443
444        $name = $f['name'];
445        $type = files::getMimeType($name);
446
447        if ($type != 'image/jpeg' && $type != 'image/png') {
448            throw new Exception(__('Invalid file type.'));
449        }
450
451        $dest = self::imagesPath($folder) . '/uploaded' . ($type == 'image/png' ? '.png' : '.jpg');
452
453        if (@move_uploaded_file($f['tmp_name'], $dest) === false) {
454            throw new Exception(__('An error occurred while writing the file.'));
455        }
456
457        if ($width) {
458            $s = getimagesize($dest);
459            if ($s[0] != $width) {
460                throw new Exception(sprintf(__('Uploaded image is not %s pixels wide.'), $width));
461            }
462        }
463
464        return $dest;
465    }
466
467/**
468 * Delete an image from images folder (with its thumbnails if any)
469 *
470 * @param  string $folder images folder
471 * @param  string $img    image filename
472 */
473    public static function dropImage($folder, $img)
474    {
475        global $core;
476
477        $img = path::real(self::imagesPath($folder) . '/' . $img);
478        if (is_writable(dirname($img))) {
479            // Delete thumbnails if any
480            try {
481                $media = new dcMedia($core);
482                $media->imageThumbRemove($img);
483            } catch (Exception $e) {
484                $core->error->add($e->getMessage());
485            }
486            // Delete image
487            @unlink($img);
488        }
489    }
490}
Note: See TracBrowser for help on using the repository browser.

Sites map