Esempio n. 1
0
 protected function evaluate($context, $expression, $tokens, $silent)
 {
     $expression_path = [];
     foreach ($tokens as $i => $part) {
         $identifier = $part[self::TOKEN_VALUE];
         $expression_path[] = $identifier;
         switch ($part[self::TOKEN_TYPE]) {
             case self::TOKEN_TYPE_IDENTIFIER:
                 if (!is_array($context) && !is_object($context)) {
                     throw new \InvalidArgumentException(\ICanBoogie\format('Unexpected variable type: %type (%value) for %identifier in expression %expression, should be either an array or an object', ['%type' => gettype($context), '%value' => $context, '%identifier' => $identifier, '%expression' => $expression]));
                 }
                 $exists = false;
                 $next_value = $this->extract_value($context, $identifier, $exists);
                 if (!$exists) {
                     if ($silent) {
                         return null;
                     }
                     throw new ReferenceError(\ICanBoogie\format('Reference to undefined property %path of expression %expression (defined: :keys) in: :value', ['path' => implode('.', $expression_path), 'expression' => $expression, 'keys' => implode(', ', $context instanceof Context ? $context->keys() : array_keys((array) $context)), 'value' => \ICanBoogie\dump($context)]));
                 }
                 $context = $next_value;
                 break;
             case self::TOKEN_TYPE_FUNCTION:
                 $method = $identifier;
                 $args = $part[self::TOKEN_ARGS];
                 $args_evaluate = $part[self::TOKEN_ARGS_EVALUATE];
                 if ($args_evaluate) {
                     $this->engine->error('we should evaluate %eval', ['%eval' => $args_evaluate]);
                 }
                 #
                 # if value is an object, we check if the object has the method
                 #
                 if (is_object($context) && method_exists($context, $method)) {
                     $context = call_user_func_array([$context, $method], $args);
                     break;
                 }
                 #
                 # well, the object didn't have the method,
                 # we check internal functions
                 #
                 $callback = $this->engine->functions->find($method);
                 #
                 # if no internal function matches, we try string and array functions
                 # depending on the type of the value
                 #
                 if (!$callback) {
                     if (is_string($context)) {
                         if (function_exists('str' . $method)) {
                             $callback = 'str' . $method;
                         } else {
                             if (function_exists('str_' . $method)) {
                                 $callback = 'str_' . $method;
                             }
                         }
                     } else {
                         if (is_array($context) || is_object($context)) {
                             if (function_exists('ICanBoogie\\array_' . $method)) {
                                 $callback = 'ICanBoogie\\array_' . $method;
                             } else {
                                 if (function_exists('array_' . $method)) {
                                     $callback = 'array_' . $method;
                                 }
                             }
                         }
                     }
                 }
                 #
                 # our last hope is to try the function "as is"
                 #
                 if (!$callback) {
                     if (function_exists($method)) {
                         $callback = $method;
                     }
                 }
                 if (!$callback) {
                     if (is_object($context) && method_exists($context, '__call')) {
                         $context = call_user_func_array([$context, $method], $args);
                         break;
                     }
                 }
                 #
                 #
                 #
                 if (!$callback) {
                     throw new \Exception(\ICanBoogie\format('Unknown method %method for expression %expression.', ['%method' => $method, '%expression' => $expression]));
                 }
                 #
                 # create evaluation
                 #
                 array_unshift($args, $context);
                 if (PHP_MAJOR_VERSION > 5 || PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2) {
                     if ($callback == 'array_shift') {
                         $context = array_shift($context);
                     } else {
                         $context = call_user_func_array($callback, $args);
                     }
                 } else {
                     $context = call_user_func_array($callback, $args);
                 }
                 break;
         }
     }
     return $context;
 }
Esempio n. 2
0
 /**
  * Parses a template with a bounded value.
  *
  * <pre>
  * <p:with
  *     select = expression>
  *     <!-- Content: p:with-param*, template -->
  * </p:with>
  * </pre>
  *
  * Example:
  *
  * <pre>
  * <p:with select="articles.first().comments.last()">
  * Last comment: <a href="#{@url}">#{@title}</a>
  * </p:with>
  * </pre>
  *
  * @param array $args
  * @param Engine $patron
  * @param mixed $template
  *
  * @return string
  */
 public static function markup_with(array $args, Engine $patron, $template)
 {
     if ($template === null) {
         $patron->error('A template is required.');
         return null;
     }
     $select = $args['select'];
     return $patron($template, $select);
 }