Autodoc
  • Namespace
  • Class
  • 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

  • Compiler
  • ControlNode
  • Engine
  • EvaluateNode
  • ExpressionNode
  • Hook
  • Hooks
  • HTMLParser
  • Node
  • Template
  • TextHole
  • TextNode
  • TranslateNode
  • URLNode

Functions

  • by_columns
  • render
  • tr
  1 <?php
  2 
  3 /*
  4  * This file is part of the Patron 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 Patron;
 13 
 14 use ICanBoogie\Exception;
 15 use BlueTihi\Context;
 16 
 17 class EvaluateNode extends ExpressionNode
 18 {
 19     protected $original_expression;
 20     protected $engine_context;
 21 
 22     public function __construct($expression, $escape)
 23     {
 24         $this->original_expression = $expression;
 25 
 26         parent::__construct($this->tokenize($expression), $escape);
 27     }
 28 
 29     private $engine;
 30 
 31     public function __invoke(Engine $engine, $context)
 32     {
 33         $this->engine = $engine;
 34         $this->engine_context = $context;
 35 
 36         return parent::__invoke($engine, $context);
 37     }
 38 
 39     protected function render($parts)
 40     {
 41         $value = $this->engine_context;
 42         $expression = $this->original_expression;
 43         $silent = false;
 44         $previous_identifier = '__context__';
 45 
 46         foreach ($parts as $i => $part)
 47         {
 48             $identifier = $part[self::TOKEN_VALUE];
 49 
 50             switch ($part[self::TOKEN_TYPE])
 51             {
 52                 case self::TOKEN_TYPE_IDENTIFIER:
 53                 {
 54                     if (!is_array($value) && !is_object($value))
 55                     {
 56                         throw new \InvalidArgumentException(\ICanBoogie\format
 57                         (
 58                             'Unexpected variable type: %type (%value) for %identifier in expression %expression, should be either an array or an object', array
 59                             (
 60                                 '%type' => gettype($value),
 61                                 '%value' => $value,
 62                                 '%identifier' => $identifier,
 63                                 '%expression' => $expression
 64                             )
 65                         ));
 66                     }
 67 
 68                     $exists = false;
 69 
 70                     if (is_array($value))
 71                     {
 72                         $exists = array_key_exists($identifier, $value);
 73                     }
 74                     else
 75                     {
 76                         $exists = property_exists($value, $identifier);
 77 
 78                         if (!$exists && method_exists($value, 'has_property'))
 79                         {
 80                             $exists = $value->has_property($identifier);
 81                         }
 82                         else
 83                         {
 84                             if (!$exists && method_exists($value, 'offsetExists'))
 85                             {
 86                                 $exists = $value->offsetExists($identifier);
 87                             }
 88 
 89                             if (!$exists && method_exists($value, '__get'))
 90                             {
 91                                 $exists = true;
 92                             }
 93                         }
 94                     }
 95 
 96                     if (!$exists)
 97                     {
 98                         if (!$silent)
 99                         {
100                             throw new Exception
101                             (
102                                 '%identifier of expression %expression does not exists in %var (defined: :keys) in: :value', array
103                                 (
104                                     'identifier' => $identifier,
105                                     'expression' => $expression,
106                                     'var' => $previous_identifier,
107                                     'keys' => implode(', ', $value instanceof Context ? $value->keys() : array_keys((array) $value)),
108                                     'value' => $value
109                                 )
110                             );
111                         }
112 
113                         return;
114                     }
115 
116                     $value = (is_array($value) || method_exists($value, 'offsetExists')) ? $value[$identifier] : $value->$identifier;
117                     $previous_identifier = $identifier;
118                 }
119                 break;
120 
121                 case self::TOKEN_TYPE_FUNCTION:
122                 {
123                     $method = $identifier;
124                     $args = $part[self::TOKEN_ARGS];
125                     $args_evaluate = $part[self::TOKEN_ARGS_EVALUATE];
126 
127                     if ($args_evaluate)
128                     {
129                         $this->error('we should evaluate %eval', array('%eval' => $args_evaluate));
130                     }
131 
132                     #
133                     # if value is an object, we check if the object has the method
134                     #
135 
136                     if (is_object($value) && method_exists($value, $method))
137                     {
138                         $value = call_user_func_array(array($value, $method), $args);
139 
140                         break;
141                     }
142 
143                     #
144                     # well, the object didn't have the method,
145                     # we check internal functions
146                     #
147 
148                     $callback = $this->findFunction($this->engine, $method);
149 
150                     #
151                     # if no internal function matches, we try string and array functions
152                     # depending on the type of the value
153                     #
154 
155                     if (!$callback)
156                     {
157                         if (is_string($value))
158                         {
159                             if (function_exists('str' . $method))
160                             {
161                                 $callback = 'str' . $method;
162                             }
163                             else if (function_exists('str_' . $method))
164                             {
165                                 $callback = 'str_' . $method;
166                             }
167                         }
168                         else if (is_array($value) || is_object($value))
169                         {
170                             if (function_exists('ICanBoogie\array_' . $method))
171                             {
172                                 $callback = 'ICanBoogie\array_' . $method;
173                             }
174                             else if (function_exists('array_' . $method))
175                             {
176                                 $callback = 'array_' . $method;
177                             }
178                         }
179                     }
180 
181                     #
182                     # our last hope is to try the function "as is"
183                     #
184 
185                     if (!$callback)
186                     {
187                         if (function_exists($method))
188                         {
189                             $callback = $method;
190                         }
191                     }
192 
193                     if (!$callback)
194                     {
195                         if (is_object($value) && method_exists($value, '__call'))
196                         {
197                             $value = call_user_func_array(array($value, $method), $args);
198 
199                             break;
200                         }
201                     }
202 
203                     #
204                     #
205                     #
206 
207                     if (!$callback)
208                     {
209                         throw new Exception
210                         (
211                             'Unknown method %method for expression %expression.', array
212                             (
213                                 '%method' => $method,
214                                 '%expression' => $expression
215                             )
216                         );
217                     }
218 
219                     #
220                     # create evaluation
221                     #
222 
223                     array_unshift($args, $value);
224 
225                     if (PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2))
226                     {
227                         if ($callback == 'array_shift')
228                         {
229                             $value = array_shift($value);
230                         }
231                         else
232                         {
233                             $value = call_user_func_array($callback, $args);
234                         }
235                     }
236                     else
237                     {
238                         $value = call_user_func_array($callback, $args);
239                     }
240                 }
241                 break;
242             }
243         }
244 
245         return $value;
246     }
247 
248     const TOKEN_TYPE = 1;
249     const TOKEN_TYPE_FUNCTION = 2;
250     const TOKEN_TYPE_IDENTIFIER = 3;
251     const TOKEN_VALUE = 4;
252     const TOKEN_ARGS = 5;
253     const TOKEN_ARGS_EVALUATE = 6;
254 
255     /*
256      * Tokenize Javascript style function chain into an array of identifiers and functions
257      */
258     protected function tokenize($str)
259     {
260         if ($str{0} == '@')
261         {
262             $str = 'this.' . substr($str, 1);
263         }
264 
265         $str .= '.';
266 
267         $length = strlen($str);
268 
269         $quote = null;
270         $quote_closed = null;
271         $part = null;
272         $escape = false;
273 
274         $function = null;
275         $args = array();
276         $args_evaluate = array();
277         $args_count = 0;
278 
279         $parts = array();
280 
281         for ($i = 0 ; $i < $length ; $i++)
282         {
283             $c = $str{$i};
284 
285             if ($escape)
286             {
287                 $part .= $c;
288 
289                 $escape = false;
290 
291                 continue;
292             }
293 
294             if ($c == '\\')
295             {
296                 //echo "found escape: [$c] @$i<br />";
297 
298                 $escape = true;
299 
300                 continue;
301             }
302 
303             if ($c == '"' || $c == '\'' || $c == '`')
304             {
305                 if ($quote && $quote == $c)
306                 {
307                     //echo "found closing quote: [$c]<br />";
308 
309                     $quote = null;
310                     $quote_closed = $c;
311 
312                     if ($function)
313                     {
314                         continue;
315                     }
316                 }
317                 else if (!$quote)
318                 {
319                     //echo "found opening quote: [$c]<br />";
320 
321                     $quote = $c;
322 
323                     if ($function)
324                     {
325                         continue;
326                     }
327                 }
328             }
329 
330             if ($quote)
331             {
332                 $part .= $c;
333 
334                 continue;
335             }
336 
337             #
338             # we are not in a quote
339             #
340 
341             if ($c == '.')
342             {
343                 //echo "end of part: [$part]<br />";
344 
345                 // FIXME: added strlen() because of '0' e.g. items.0.price
346                 // could a part be null ??
347 
348                 if (strlen($part))
349                 {
350                     $parts[] = array
351                     (
352                         self::TOKEN_TYPE => self::TOKEN_TYPE_IDENTIFIER,
353                         self::TOKEN_VALUE => $part
354                     );
355                 }
356 
357                 $part = null;
358 
359                 continue;
360             }
361 
362             if ($c == '(')
363             {
364                 //echo "function [$part] begin: @$i<br />";
365 
366                 $function = $part;
367 
368                 $args = array();
369                 $args_count = 0;
370 
371                 $part = null;
372 
373                 continue;
374             }
375 
376             if (($c == ',' || $c == ')') && $function)
377             {
378                 //echo "function push argument [$part] q=[$quote_closed]<br />";
379 
380                 if ($part !== null)
381                 {
382                     if ($quote_closed == '`')
383                     {
384                         //echo "we should evaluate [$part][$args_count]<br />";
385 
386                         $args_evaluate[] = $args_count;
387                     }
388 
389                     if (!$quote_closed)
390                     {
391                         #
392                         # end of an unquoted part.
393                         # it might be an integer, a float, or maybe a constant !
394                         #
395 
396                         $part_back = $part;
397 
398                         switch ($part)
399                         {
400                             case 'true':
401                             case 'TRUE':
402                             {
403                                 $part = true;
404                             }
405                             break;
406 
407                             case 'false':
408                             case 'FALSE':
409                             {
410                                 $part = false;
411                             }
412                             break;
413 
414                             case 'null':
415                             case 'NULL':
416                             {
417                                 $part = null;
418                             }
419                             break;
420 
421                             default:
422                             {
423                                 if (is_numeric($part))
424                                 {
425                                     $part = (int) $part;
426                                 }
427                                 else if (is_float($part))
428                                 {
429                                     $part = (float) $part;
430                                 }
431                                 else
432                                 {
433                                     $part = constant($part);
434                                 }
435                             }
436                             break;
437                         }
438 
439                         //\ICanBoogie\log('part: [\1] == [\2]', $part_back, $part);
440                     }
441 
442                     $args[] = $part;
443                     $args_count++;
444 
445                     $part = null;
446                 }
447 
448                 $quote_closed = null;
449 
450                 if ($c != ')')
451                 {
452                     continue;
453                 }
454             }
455 
456             if ($c == ')' && $function)
457             {
458                 //echo "function end: [$part] @$i<br />";
459 
460                 $parts[] = array
461                 (
462                     self::TOKEN_TYPE => self::TOKEN_TYPE_FUNCTION,
463                     self::TOKEN_VALUE => $function,
464                     self::TOKEN_ARGS => $args,
465                     self::TOKEN_ARGS_EVALUATE => $args_evaluate
466                 );
467 
468                 continue;
469             }
470 
471             if ($c == ' ' && $function)
472             {
473                 continue;
474             }
475 
476             $part .= $c;
477         }
478 
479         return $parts;
480     }
481 
482     public function findFunction(Engine $engine, $name)
483     {
484         return $engine->findFunction($name);
485         /*
486         $function = $engine->findFunction($name);
487 
488         if ($function)
489         {
490             return $function;
491         }
492 
493         $try = 'ICanBoogie\\' . $name;
494 
495         if (function_exists($try))
496         {
497             return $try;
498         }
499 
500         $try = 'ICanBoogie\I18n\\' . $name;
501 
502         if (function_exists($try))
503         {
504             return $try;
505         }
506 
507         #
508         # 'wd' pseudo namespace // COMPAT
509         #
510 
511         $try = 'wd_' . str_replace('-', '_', $name);
512 
513         if (function_exists($try))
514         {
515             return $try;
516         }
517 
518         $try = 'Patron\\' . $name;
519 
520         if (function_exists($try))
521         {
522             return $try;
523         }
524         */
525     }
526 }
Autodoc API documentation generated by ApiGen 2.8.0