Autodoc
  • Namespace
  • Function
  • Tree

Namespaces

  • BlueTihi
    • Context
  • Brickrouge
    • Element
      • Nodes
    • Renderer
    • Widget
  • ICanBoogie
    • ActiveRecord
    • AutoConfig
    • CLDR
    • Composer
    • Core
    • Event
    • Exception
    • HTTP
      • Dispatcher
      • Request
    • I18n
      • Translator
    • Mailer
    • Modules
      • Taxonomy
        • Support
      • Thumbnailer
        • Versions
    • Object
    • Operation
      • Dispatcher
    • Prototype
    • Routes
    • Routing
      • Dispatcher
    • Session
  • Icybee
    • ActiveRecord
      • Model
    • ConfigOperation
    • Document
    • EditBlock
    • Element
      • ActionbarContextual
      • ActionbarSearch
      • ActionbarToolbar
    • FormBlock
    • Installer
    • ManageBlock
    • Modules
      • Articles
      • Cache
        • Collection
        • ManageBlock
      • Comments
        • ManageBlock
      • Contents
        • ManageBlock
      • Dashboard
      • Editor
        • Collection
      • Files
        • File
        • ManageBlock
      • Forms
        • Form
        • ManageBlock
      • I18n
      • Images
        • ManageBlock
      • Members
      • Modules
        • ManageBlock
      • Nodes
        • ManageBlock
        • Module
      • Pages
        • BreadcrumbElement
        • LanguagesElement
        • ManageBlock
        • NavigationBranchElement
        • NavigationElement
        • Page
        • PageController
      • Registry
      • Search
      • Seo
      • Sites
        • ManageBlock
      • Taxonomy
        • Terms
          • ManageBlock
        • Vocabulary
          • ManageBlock
      • Users
        • ManageBlock
        • NonceLogin
        • Roles
      • Views
        • ActiveRecordProvider
        • Collection
        • View
    • Operation
      • ActiveRecord
      • Constructor
      • Module
      • Widget
    • Rendering
  • None
  • Patron
  • PHP

Classes

  • A
  • Actions
  • Alert
  • AlterCSSClassNamesEvent
  • AssetsCollector
  • Button
  • CSSCollector
  • Dataset
  • Date
  • DateRange
  • DateTime
  • Decorator
  • Document
  • DropdownMenu
  • Element
  • File
  • Form
  • Group
  • Helpers
  • HTMLString
  • Iterator
  • JSCollector
  • ListView
  • ListViewColumn
  • Modal
  • Pager
  • Popover
  • PopoverWidget
  • Ranger
  • RecursiveIterator
  • Salutation
  • Searchbox
  • Section
  • SplitButton
  • Text
  • Widget

Interfaces

  • CSSClassNames
  • DecoratorInterface
  • HTMLStringInterface
  • Validator

Traits

  • CSSClassNamesProperty

Exceptions

  • ElementIsEmpty

Functions

  • _array_flatten_callback
  • array_flatten
  • array_insert
  • check_session
  • dump
  • escape
  • escape_all
  • format
  • format_size
  • get_accessible_file
  • get_document
  • normalize
  • render_css_class
  • render_exception
  • retrieve_form
  • retrieve_form_errors
  • shorten
  • stable_sort
  • store_form
  • store_form_errors
  • strip
  • t
  1 <?php
  2 
  3 /*
  4  * This file is part of the Brickrouge package.
  5  *
  6  * (c) Olivier Laviale <olivier.laviale@gmail.com>
  7  *
  8  * For the full copyright and license information, please view the LICENSE
  9  * file that was distributed with this source code.
 10  */
 11 
 12 namespace Brickrouge;
 13 
 14 /**
 15  * Inserts a value in a array before, or after, at given key.
 16  *
 17  * Numeric keys are not preserved.
 18  *
 19  * @param $array
 20  * @param $relative
 21  * @param $value
 22  * @param $key
 23  * @param $after
 24  *
 25  * @return A new array with the value inserted at the requested position.
 26  */
 27 function array_insert($array, $relative, $value, $key=null, $after=false)
 28 {
 29     $keys = array_keys($array);
 30     $pos = array_search($relative, $keys, true);
 31 
 32     if ($after)
 33     {
 34         $pos++;
 35     }
 36 
 37     $spliced = array_splice($array, $pos);
 38 
 39     if ($key !== null)
 40     {
 41         $array = array_merge($array, array($key => $value));
 42     }
 43     else
 44     {
 45         array_unshift($spliced, $value);
 46     }
 47 
 48     return array_merge($array, $spliced);
 49 }
 50 
 51 function array_flatten(array $array)
 52 {
 53     $result = $array;
 54 
 55     foreach ($array as $key => &$value)
 56     {
 57         _array_flatten_callback($result, '', $key, $value);
 58     }
 59 
 60     return $result;
 61 }
 62 
 63 function _array_flatten_callback(&$result, $pre, $key, &$value)
 64 {
 65     if (is_array($value))
 66     {
 67         foreach ($value as $vk => &$vv)
 68         {
 69             _array_flatten_callback($result, $pre ? ($pre . '[' . $key . ']') : $key, $vk, $vv);
 70         }
 71     }
 72     else if (is_object($value))
 73     {
 74         // FIXME: throw new Exception('Don\'t know what to do with objects: \1', $value);
 75     }
 76     else
 77     {
 78         /* FIXME-20100520: this has been disabled because sometime empty values (e.g. '') are
 79          * correct values. The function was first used with Brickrouge\Form which made sense at the time
 80          * but now changing values would be a rather strange behaviour.
 81         #
 82         # a trick to create undefined values
 83         #
 84 
 85         if (!strlen($value))
 86         {
 87             $value = null;
 88         }
 89         */
 90 
 91         if ($pre)
 92         {
 93             #
 94             # only arrays are flattened
 95             #
 96 
 97             $pre .= '[' . $key . ']';
 98 
 99             $result[$pre] = $value;
100         }
101         else
102         {
103             #
104             # simple values are kept intact
105             #
106 
107             $result[$key] = $value;
108         }
109     }
110 }
111 
112 /**
113  * Sorts an array using a stable sorting algorithm while preserving its keys.
114  *
115  * A stable sorting algorithm maintains the relative order of values with equal keys.
116  *
117  * The array is always sorted in ascending order but one can use the {@link array_reverse()}
118  * function to reverse the array. Also keys are preserved, even numeric ones, use the
119  * {@link array_values()} function to create an array with an ascending index.
120  *
121  * @param array $array
122  * @param callable $picker
123  */
124 function stable_sort(&$array, $picker=null)
125 {
126     static $transform, $restore;
127 
128     $i = 0;
129 
130     if (!$transform)
131     {
132         $transform = function(&$v, $k) use (&$i)
133         {
134             $v = array($v, ++$i, $k, $v);
135         };
136 
137         $restore = function(&$v, $k)
138         {
139             $v = $v[3];
140         };
141     }
142 
143     if ($picker)
144     {
145         array_walk
146         (
147             $array, function(&$v, $k) use (&$i, $picker)
148             {
149                 $v = array($picker($v), ++$i, $k, $v);
150             }
151         );
152     }
153     else
154     {
155         array_walk($array, $transform);
156     }
157 
158     asort($array);
159 
160     array_walk($array, $restore);
161 }
162 
163 /**
164  * Convert special characters to HTML entities.
165  *
166  * @param string $str The string being converted.
167  * @param string $charset Defines character set used in conversion. The default charset is
168  * {@link BrickRoute\CHARSET} (utf-8).
169  *
170  * @return string
171  */
172 function escape($str, $charset=CHARSET)
173 {
174     return htmlspecialchars($str, ENT_COMPAT, $charset);
175 }
176 
177 function escape_all($str, $charset=CHARSET)
178 {
179     return htmlentities($str, ENT_COMPAT, $charset);
180 }
181 
182 /**
183  * Shortens a string at a specified position.
184  *
185  * @param string $str The string to shorten.
186  * @param int $length The desired length of the string.
187  * @param float $position Position at which characters can be removed.
188  * @param bool $shortened `true` if the string was shortened, `false` otherwise.
189  *
190  * @return string
191  */
192 function shorten($str, $length=32, $position=.75, &$shortened=null)
193 {
194     $l = mb_strlen($str);
195 
196     if ($l <= $length)
197     {
198         return $str;
199     }
200 
201     $length--;
202     $position = (int) ($position * $length);
203 
204     if ($position == 0)
205     {
206         $str = '…' . mb_substr($str, $l - $length);
207     }
208     else if ($position == $length)
209     {
210         $str = mb_substr($str, 0, $length) . '…';
211     }
212     else
213     {
214         $str = mb_substr($str, 0, $position) . '…' . mb_substr($str, $l - ($length - $position));
215     }
216 
217     $shortened = true;
218 
219     return $str;
220 }
221 
222 function dump($value)
223 {
224     if (function_exists('xdebug_var_dump'))
225     {
226         ob_start();
227 
228         xdebug_var_dump($value);
229 
230         $value = ob_get_clean();
231     }
232     else
233     {
234         $value = '<pre>' . escape(print_r($value, true)) . '</pre>';
235     }
236 
237     return $value;
238 }
239 
240 /**
241  * Returns a web accessible path to a web inaccessible file.
242  *
243  * If the accessible file does not exists it is created.
244  *
245  * The directory where the files are copied is defined by the {@link ACCESSIBLE_ASSETS} constant.
246  *
247  * Note: Calls to this function are forwarded to {@link Helpers::get_accessible_file()}.
248  *
249  * @param string $path Absolute path to the web inaccessible file.
250  * @param string $suffix Optional suffix for the web accessible filename.
251  *
252  * @return string The pathname of the replacement.
253  *
254  * @throws \Exception if the replacement file could not be created.
255  */
256 function get_accessible_file($path, $suffix=null)
257 {
258     return Helpers::get_accessible_file($path, $suffix);
259 }
260 
261 /**
262  * Formats the given string by replacing placeholders with the given values.
263  *
264  * Note: Calls to this function are forwarded to {@link Helpers::format()}.
265  *
266  * @param string $str The string to format.
267  * @param array $args An array of replacement for the placeholders. Occurrences in `$str` of any
268  * key in `$args` are replaced with the corresponding sanitized value. The sanitization function
269  * depends on the first character of the key:
270  *
271  * - `:key`: Replace as is. Use this for text that has already been sanitized.
272  * - `!key`: Sanitize using the {@link escape()} function.
273  * - `%key`: Sanitize using the {@link escape()} function and wrap inside an `EM` markup.
274  *
275  * Numeric indexes can also be used e.g `\2` or `{2}` are replaced by the value of the index
276  * 2.
277  *
278  * @return string
279  */
280 function format($str, array $args=array())
281 {
282     return Helpers::format($str, $args);
283 }
284 
285 /**
286  * Formats a number into a size with unit (o, Ko, Mo, Go).
287  *
288  * Before the string is formatted it is localised with the {@link t()} function.
289  *
290  * Note: Calls to this function are forwarded to {@link Helpers::format_size()}.
291  *
292  * @param int $size
293  *
294  * @return string
295  */
296 function format_size($size)
297 {
298     return Helpers::format_size($size);
299 }
300 
301 /**
302  * Normalizes the input provided and returns the normalized string.
303  *
304  * Note: Calls to this function are forwarded to {@link Helpers::normalize()}.
305  *
306  * @param string $str The string to normalize.
307  * @param string $separator Whitespaces replacement.
308  * @param string $charset The charset of the input string, defaults to {@link Brickrouge\CHARSET}
309  * (utf-8).
310  *
311  * @return string
312  */
313 function normalize($str, $separator='-', $charset=CHARSET)
314 {
315     return Helpers::normalize($str, $separator, $charset);
316 }
317 
318 /**
319  * Translates a string to the current language or to a given language.
320  *
321  * The native string language is supposed to be english (en).
322  *
323  * Note: Calls to this function are forwarded to {@link Helpers::t}.
324  *
325  * @param string $str The native string to translate.
326  * @param array $args An array of replacements to make after the translation. The replacement is
327  * handled by the {@link format()} function.
328  * @param array $options An array of additional options, with the following elements:
329  * - 'default': The default string to use if the translation failed.
330  * - 'scope': The scope of the translation.
331  *
332  * @return mixed
333  *
334  * @see ICanBoogie\I18n\Translator
335  */
336 function t($str, array $args=array(), array $options=array())
337 {
338     return Helpers::t($str, $args, $options);
339 }
340 
341 /**
342  * Returns the global document object.
343  *
344  * This document is used by classes when they need to add assets. Once assets are collected one can
345  * simple echo the assets while building the response HTML.
346  *
347  * Example:
348  *
349  * <?php
350  *
351  * namespace Brickrouge;
352  *
353  * $document = get_document();
354  * $document->css->add(Brickrouge\ASSETS . 'brickrouge.css');
355  * $document->js->add(Brickrouge\ASSETS . 'brickrouge.js');
356  *
357  * ?><!DOCTYPE html>
358  * <html>
359  * <head>
360  * <?php echo $document->css ?>
361  * </head>
362  * <body>
363  * <?php echo $document->js ?>
364  * </body>
365  * </html>
366  *
367  * Note: Calls to this function are forwarded to {@link Helpers::get_document()}.
368  *
369  * @return Document
370  */
371 function get_document()
372 {
373     return Helpers::get_document();
374 }
375 
376 /**
377  * Checks if the session is started, and start it otherwise.
378  *
379  * The session is used by the {@link Form} class to store validation errors and store
380  * its forms for later validation. Take a look at the {@link Form::validate()} and
381  * {@link Form::save()} methods.
382  *
383  * Note: Calls to this function are forwarded to {@link Helpers::check_session()}.
384  */
385 function check_session()
386 {
387     Helpers::check_session();
388 }
389 
390 /**
391  * Stores of form for later validation.
392  *
393  * Note: Calls to this function are forwarded to {@link Helpers::store_form()}.
394  *
395  * @param Form $form The form to store.
396  *
397  * @return string A key that must be used to retrieve the form.
398  */
399 function store_form(Form $form)
400 {
401     return Helpers::store_form($form);
402 }
403 
404 /**
405  * Retrieve a stored form.
406  *
407  * Note: Calls to this function are forwarded to {@link Helpers::retrieve_form()}.
408  *
409  * @param string $key Key of the form to retrieve.
410  *
411  * @return Form|null The retrieved form or null if none where found for the specified key.
412  */
413 function retrieve_form($key)
414 {
415     return Helpers::retrieve_form($key);
416 }
417 
418 /**
419  * Stores the validation errors of a form.
420  *
421  * Note: Calls to this function are forwarded to {@link Helpers::store_form_errors()}.
422  *
423  * @param string $name The name of the form.
424  * @param array $errors The validation errors of the form.
425  */
426 function store_form_errors($name, $errors)
427 {
428     Helpers::store_form_errors($name, $errors);
429 }
430 
431 /**
432  * Retrieves the validation errors of a form.
433  *
434  * Note: Calls to this function are forwarded to {@link Helpers::retrieve_form_errors()}.
435  *
436  * @param string $name The name if the form.
437  *
438  * @return array
439  */
440 function retrieve_form_errors($name)
441 {
442     return Helpers::retrieve_form_errors($name);
443 }
444 
445 /**
446  * Renders an exception into a string.
447  *
448  * Note: Calls to this function are forwarded to {@link Helpers::render_exception()}.
449  *
450  * @param \Exception $exception
451  *
452  * @return string
453  */
454 function render_exception(\Exception $exception)
455 {
456     return Helpers::render_exception($exception);
457 }
458 
459 /**
460  * Brickrouge helpers.
461  *
462  * The following helpers are patchable:
463  *
464  * - {@link check_session()}
465  * - {@link format()}
466  * - {@link format_size()}
467  * - {@link get_accessible_file()}
468  * - {@link get_document()}
469  * - {@link normalize()}
470  * - {@link render_exception()}
471  * - {@link retrieve_form()}
472  * - {@link retrieve_form_errors()}
473  * - {@link store_form()}
474  * - {@link store_form_errors()}
475  * - {@link t()}
476  *
477  * @method void check_session() check_session()
478  * @method string format() format(string $str, array $args=array())
479  * @method string format_size() format_size(number $size)
480  * @method string get_accessible_file() get_accessible_file(string $path, $suffix=null)
481  * @method Document get_document() get_document()
482  * @method string normalize() normalize(string $str)
483  * @method string render_exception() render_exception(\Exception $exception)
484  * @method Form retrieve_form() retrieve_form(string $name)
485  * @method \ICanboogie\Errors retrieve_form_errors() retrieve_form_errors(string $name)
486  * @method string store_form() store_form(Form $form)
487  * @method void store_form_errors() store_form_errors(string $name, \ICanBoogie\Errors $errors)
488  * @method string t() t(string $str, array $args=array(), array $options=array())
489  */
490 class Helpers
491 {
492     static private $jumptable = array
493     (
494         'check_session' => array(__CLASS__, 'check_session'),
495         'format' => array(__CLASS__, 'format'),
496         'format_size' => array(__CLASS__, 'format_size'),
497         'get_accessible_file' => array(__CLASS__, 'get_accessible_file'),
498         'get_document' => array(__CLASS__, 'get_document'),
499         'normalize' => array(__CLASS__, 'normalize'),
500         'render_exception' => array(__CLASS__, 'render_exception'),
501         'retrieve_form' => array(__CLASS__, 'retrieve_form'),
502         'retrieve_form_errors' => array(__CLASS__, 'retrieve_form_errors'),
503         'store_form' => array(__CLASS__, 'store_form'),
504         'store_form_errors' => array(__CLASS__, 'store_form_errors'),
505         't' => array(__CLASS__, 't')
506     );
507 
508     /**
509      * Calls the callback of a patchable function.
510      *
511      * @param string $name Name of the function.
512      * @param array $arguments Arguments.
513      *
514      * @return mixed
515      */
516     static public function __callstatic($name, array $arguments)
517     {
518         return call_user_func_array(self::$jumptable[$name], $arguments);
519     }
520 
521     /**
522      * Patches a patchable function.
523      *
524      * @param string $name Name of the function.
525      * @param collable $callback Callback.
526      *
527      * @throws \RuntimeException is attempt to patch an undefined function.
528      */
529     static public function patch($name, $callback)
530     {
531         if (empty(self::$jumptable[$name]))
532         {
533             throw new \RuntimeException("Undefined patchable: $name.");
534         }
535 
536         self::$jumptable[$name] = $callback;
537     }
538 
539     /*
540      * fallbacks
541      */
542 
543     /**
544      * This method is the fallback for the {@link format()} function.
545      */
546     static private function format($str, array $args=array())
547     {
548         if (!$args)
549         {
550             return $str;
551         }
552 
553         $holders = array();
554         $i = 0;
555 
556         foreach ($args as $key => $value)
557         {
558             ++$i;
559 
560             if (is_array($value) || is_object($value))
561             {
562                 $value = dump($value);
563             }
564             else if (is_bool($value))
565             {
566                 $value = $value ? '<em>true</em>' : '<em>false</em>';
567             }
568             else if (is_null($value))
569             {
570                 $value = '<em>null</em>';
571             }
572 
573             if (is_string($key))
574             {
575                 switch ($key{0})
576                 {
577                     case ':': break;
578                     case '!': $value = escape($value); break;
579                     case '%': $value = '<q>' . escape($value) . '</q>'; break;
580 
581                     default:
582                     {
583                         $escaped_value = escape($value);
584 
585                         $holders['!' . $key] = $escaped_value;
586                         $holders['%' . $key] = '<q>' . $escaped_value . '</q>';
587 
588                         $key = ':' . $key;
589                     }
590                 }
591             }
592             else if (is_numeric($key))
593             {
594                 $key = '\\' . $i;
595                 $holders['{' . $i . '}'] = $value;
596             }
597 
598             $holders[$key] = $value;
599         }
600 
601         return strtr($str, $holders);
602     }
603 
604     /**
605      * This method is the fallback for the {@link format_size()} function.
606      */
607     static private function format_size($size)
608     {
609         if ($size < 1024)
610         {
611             $str = ":size\xC2\xA0b";
612         }
613         else if ($size < 1024 * 1024)
614         {
615             $str = ":size\xC2\xA0Kb";
616             $size = $size / 1024;
617         }
618         else if ($size < 1024 * 1024 * 1024)
619         {
620             $str = ":size\xC2\xA0Mb";
621             $size = $size / (1024 * 1024);
622         }
623         else
624         {
625             $str = ":size\xC2\xA0Gb";
626             $size = $size / (1024 * 1024 * 1024);
627         }
628 
629         return t($str, array(':size' => round($size)));
630     }
631 
632     /**
633      * This method is the fallback for the {@link normalize()} function.
634      */
635     static private function normalize($str, $separator='-', $charset=CHARSET)
636     {
637         $str = str_replace('\'', '', $str);
638 
639         $str = htmlentities($str, ENT_NOQUOTES, $charset);
640         $str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
641         $str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. '&oelig;'
642         $str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères
643 
644         $str = strtolower($str);
645         $str = preg_replace('#[^a-z0-9]+#', $separator, $str);
646         $str = trim($str, $separator);
647 
648         return $str;
649     }
650 
651     /**
652      * This method is the fallback for the {@link t()} function.
653      *
654      * We usually rely on the ICanBoogie framework I18n features to translate our string, if it is
655      * not available we simply format the string using the {@link Brickrouge\format()} function.
656      */
657     static private function t($str, array $args=array(), array $options=array())
658     {
659         return format($str, $args);
660     }
661 
662     /**
663      * This method is the fallback for the {@link get_document()} function.
664      */
665     static private function get_document()
666     {
667         if (self::$document === null)
668         {
669             self::$document = new Document();
670         }
671 
672         return self::$document;
673     }
674 
675     private static $document;
676 
677     /**
678      * This method is the fallback for the {@link check_session()} function.
679      */
680     static private function check_session()
681     {
682         if (session_id())
683         {
684             return;
685         }
686 
687         session_start();
688     }
689 
690     const STORE_KEY = 'brickrouge.stored_forms';
691     const STORE_MAX = 10;
692 
693     /**
694      * Fallback for the {@link store_form()} function.
695      *
696      * The form is saved in the session in the STORE_KEY array.
697      *
698      * @param Form $form
699      *
700      * @return string The key to use to retrieve the form.
701      */
702     static private function store_form(Form $form)
703     {
704         check_session();
705 
706         #
707         # before we store anything, we do some cleanup. in order to avoid sessions filled with
708         # used forms. We only maintain a few. The limit is set using the STORE_MAX constant.
709         #
710 
711         if (isset($_SESSION[self::STORE_KEY]))
712         {
713             $n = count($_SESSION[self::STORE_KEY]);
714 
715             if ($n > self::STORE_MAX)
716             {
717                 $_SESSION[self::STORE_KEY] = array_slice($_SESSION[self::STORE_KEY], $n - self::STORE_MAX);
718             }
719         }
720 
721         $key = md5(uniqid(mt_rand(), true));
722 
723         $_SESSION[self::STORE_KEY][$key] = serialize($form);
724 
725         return $key;
726     }
727 
728     /**
729      * Fallback for the {@link retrieve_form()} function.
730      *
731      * @param string $key
732      *
733      * @return void|Form The retrieved form or null if the key matched none.
734      */
735     static private function retrieve_form($key)
736     {
737         check_session();
738 
739         if (empty($_SESSION[self::STORE_KEY][$key]))
740         {
741             return;
742         }
743 
744         $form = unserialize($_SESSION[self::STORE_KEY][$key]);
745 
746         unset($_SESSION[self::STORE_KEY][$key]);
747 
748         return $form;
749     }
750 
751     static private $errors;
752 
753     /**
754      * This method is the fallback for the {@link store_form_errors()} function.
755      */
756     static private function store_form_errors($name, $errors)
757     {
758         self::$errors[$name] = $errors;
759     }
760 
761     /**
762      * This method is the fallback for the {@link retrieve_form_errors()} function.
763      */
764     static private function retrieve_form_errors($name)
765     {
766         return isset(self::$errors[$name]) ? self::$errors[$name] : array();
767     }
768 
769     /**
770      * This method is the fallback for the {@link render_exception()} function.
771      *
772      * @param \Exception $exception
773      *
774      * @return string
775      */
776     static private function render_exception(\Exception $exception)
777     {
778         return (string) $exception;
779     }
780 
781     /**
782      * This method is the fallback for the {@link get_accessible_file()} function.
783      *
784      * @param string $path Absolute path to the web inaccessible file.
785      * @param string $suffix Optional suffix for the web accessible filename.
786      *
787      * @return string The pathname of the replacement.
788      *
789      * @throws \Exception if the replacement file could not be created.
790      */
791     static private function get_accessible_file($path, $suffix=null)
792     {
793         $key = sprintf('%s-%04x%s.%s', md5($path), strlen($path), ($suffix ? '-' . $suffix : ''), pathinfo($path, PATHINFO_EXTENSION));
794         $replacement_path = ACCESSIBLE_ASSETS;
795         $replacement = $replacement_path . $key;
796 
797         if (!is_writable($replacement_path))
798         {
799             throw new \Exception(format('Unable to make the file %path web accessible, the destination directory %replacement_path is not writtable.', array('path' => $path, 'replacement_path' => $replacement_path)));
800         }
801 
802         if (!file_exists($replacement) || filemtime($path) > filemtime($replacement))
803         {
804             file_put_contents($replacement, file_get_contents($path));
805         }
806 
807         return $replacement;
808     }
809 }
Autodoc API documentation generated by ApiGen 2.8.0