Dotclear

source: inc/admin/lib.themeconfig.php @ 2660:b35e83d4865e

Revision 2660:b35e83d4865e, 11.3 KB checked in by franck <carnet.franck.paul@…>, 11 years ago (diff)

Some refinements in doc, addresses #904

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

Sites map