예제 #1
0
파일: Emmet.php 프로젝트: Samara94/dolibarr
 /**
  * Create the needed tag hierarchy from emmet string
  *
  * @param string       $string
  *
  * @param array|string $data
  *
  * @return array|T
  */
 public static function make($string, $data = null)
 {
     if (!strlen($string)) {
         return array();
     }
     $implicitTag = function () use(&$tag) {
         if (empty($tag->tag)) {
             switch ($tag->parent->tag) {
                 case 'ul':
                 case 'ol':
                     $tag->tag = 'li';
                     break;
                 case 'em':
                     $tag->tag = 'span';
                     break;
                 case 'table':
                 case 'tbody':
                 case 'thead':
                 case 'tfoot':
                     $tag->tag = 'tr';
                     break;
                 case 'tr':
                     $tag->tag = 'td';
                     break;
                 case 'select':
                 case 'optgroup':
                     $tag->tag = 'option';
                     break;
                 default:
                     $tag->tag = 'div';
             }
         }
     };
     $parseText = function ($text, $round, $total, $data, $delimiter = null) use(&$tokens, &$tag) {
         $digits = 0;
         if ($delimiter == null) {
             $delimiter = array('.' => true, '#' => true, '*' => true, '>' => true, '+' => true, '^' => true, '[' => true, ']' => true, '=' => true);
         }
         while (!empty($tokens) && !isset($delimiter[$t = array_shift($tokens)])) {
             while ('$' === $t) {
                 $digits++;
                 $t = array_shift($tokens);
             }
             if ($digits) {
                 $negative = false;
                 $offset = 0;
                 if ('@' == $t) {
                     if ('-' == ($t = array_shift($tokens))) {
                         $negative = true;
                         if (is_numeric(reset($tokens))) {
                             $offset = array_shift($tokens);
                         }
                     } elseif (is_numeric($t)) {
                         $offset = $t;
                     } else {
                         array_unshift($tokens, $t);
                     }
                 } elseif ('#' == ($h = array_shift($tokens))) {
                     if (!empty($t)) {
                         $data = Util::nestedValue($data, $t);
                         if (is_null($data)) {
                             return null;
                         }
                     }
                     if (is_numeric($data)) {
                         $text .= sprintf("%0{$digits}d", (int) $data);
                     } elseif (is_string($data)) {
                         $text .= $data;
                     }
                     $digits = 0;
                     continue;
                 } else {
                     array_unshift($tokens, $t, $h);
                 }
                 if ($negative) {
                     $n = $total + 1 - $round + $offset;
                 } else {
                     $n = $round + $offset;
                 }
                 $text .= sprintf("%0{$digits}d", $n);
                 $digits = 0;
             } else {
                 $text .= $t;
             }
         }
         if (isset($t)) {
             array_unshift($tokens, $t);
         }
         return $text;
     };
     $parseAttributes = function (callable $self, $round, $total, $data) use(&$tokens, &$tag, $parseText) {
         $a = $parseText('', $round, $total, $data);
         if (is_null($a)) {
             return;
         }
         if ('=' == ($v = array_shift($tokens))) {
             //value
             if ('"' == ($v = array_shift($tokens))) {
                 $text = '';
                 $tag->{$a}($parseText($text, $round, $total, $data, array('"' => true)));
             } else {
                 array_unshift($tokens, $v);
                 $text = '';
                 $tag->{$a}($parseText($text, $round, $total, $data, array(' ' => true, ']' => true)));
             }
             if (' ' == ($v = array_shift($tokens))) {
                 $self($self, $round, $total, $data);
             }
         } elseif (']' == $v) {
             //end
             $tag->{$a}('');
             return;
         } elseif (' ' == $v) {
             $tag->{$a}('');
             $self($self, $round, $total, $data);
         }
     };
     $tokens = static::tokenize($string);
     $tag = new T(array_shift($tokens));
     $parent = $root = new T();
     $parse = function (callable $self, $round = 1, $total = 1) use(&$tokens, &$parent, &$tag, &$data, $parseAttributes, $implicitTag, $parseText) {
         $offsetTokens = null;
         $parent[] = $tag;
         $isInChild = false;
         while ($tokens) {
             switch (array_shift($tokens)) {
                 //class
                 case '.':
                     $offsetTokens = array_values($tokens);
                     array_unshift($offsetTokens, '.');
                     $implicitTag();
                     $e = array_filter(explode(' ', $tag->class));
                     $e[] = $parseText('', $round, $total, $data);
                     $tag->class(implode(' ', array_unique($e)));
                     break;
                     //id
                 //id
                 case '#':
                     $offsetTokens = array_values($tokens);
                     array_unshift($offsetTokens, '#');
                     $implicitTag();
                     $tag->id($parseText(array_shift($tokens), $round, $total, $data));
                     break;
                     //attributes
                 //attributes
                 case '[':
                     $offsetTokens = array_values($tokens);
                     array_unshift($offsetTokens, '[');
                     $implicitTag();
                     $parseAttributes($parseAttributes, $round, $total, $data);
                     break;
                     //child
                 //child
                 case '{':
                     $text = '';
                     $tag[] = $parseText($text, $round, $total, $data, array('}' => true));
                     break;
                 case '>':
                     $isInChild = true;
                     $offsetTokens = null;
                     if ('{' == ($t = array_shift($tokens))) {
                         array_unshift($tokens, $t);
                         $child = new T();
                         $tag[] = $child;
                         $parent = $tag;
                         $tag = $child;
                     } elseif ('[' == $t) {
                         array_unshift($tokens, $t);
                     } else {
                         $child = new T($t);
                         $tag[] = $child;
                         $parent = $tag;
                         $tag = $child;
                     }
                     break;
                     //sibling
                 //sibling
                 case '+':
                     $offsetTokens = null;
                     if (!$isInChild && $round != $total) {
                         $tokens = array();
                         break;
                     }
                     if ('{' == ($t = array_shift($tokens))) {
                         $tag = $tag->parent;
                         array_unshift($tokens, $t);
                         break;
                     } elseif ('[' == $t) {
                         array_unshift($tokens, $t);
                     } else {
                         $child = new T($t);
                         $tag = $tag->parent;
                         $tag[] = $child;
                         $tag = $child;
                     }
                     break;
                     //sibling of parent
                 //sibling of parent
                 case '^':
                     if ($round != $total) {
                         $tokens = array();
                         break;
                     }
                     $tag = $tag->parent;
                     if ($tag->parent) {
                         $tag = $tag->parent;
                     }
                     while ('^' == ($t = array_shift($tokens))) {
                         if ($tag->parent) {
                             $tag = $tag->parent;
                         }
                     }
                     $child = new T($t);
                     $tag[] = $child;
                     $tag = $child;
                     break;
                     //clone
                 //clone
                 case '*':
                     $times = array_shift($tokens);
                     $removeCount = 2;
                     $delimiter = array('.' => true, '#' => true, '*' => true, '>' => true, '+' => true, '^' => true, '[' => true, ']' => true, '=' => true);
                     if (!is_numeric($times)) {
                         if (is_string($times)) {
                             if (!isset($delimiter[$times])) {
                                 $data = Util::nestedValue($data, $times) ?: $data;
                             } else {
                                 array_unshift($tokens, $times);
                                 $removeCount = 1;
                             }
                         }
                         $indexed = array_values($data);
                         $times = is_array($data) && $indexed == $data ? count($data) : 0;
                     }
                     $source = $tag;
                     if (!empty($offsetTokens)) {
                         if (false !== strpos($source->class, ' ')) {
                             $class = explode(' ', $source->class);
                             array_pop($class);
                             $class = implode(' ', $class);
                         } else {
                             $class = null;
                         }
                         $tag->class($class);
                         $star = array_search('*', $offsetTokens);
                         array_splice($offsetTokens, $star, $removeCount);
                         $remainingTokens = $offsetTokens;
                     } else {
                         $remainingTokens = $tokens;
                     }
                     $source->parent = null;
                     $sourceData = $data;
                     $currentParent = $parent;
                     for ($i = 1; $i <= $times; $i++) {
                         $tag = clone $source;
                         $parent = $currentParent;
                         $data = is_array($sourceData) && isset($sourceData[$i - 1]) ? $sourceData[$i - 1] : @(string) $sourceData;
                         $tokens = array_values($remainingTokens);
                         $self($self, $i, $times);
                     }
                     $round = 1;
                     $offsetTokens = null;
                     $tag = $source;
                     $tokens = array();
                     //$remainingTokens;
                     break;
             }
         }
     };
     $parse($parse);
     return count($root) == 1 ? $root[0] : $root;
 }
예제 #2
0
파일: Forms.php 프로젝트: Samara94/dolibarr
 /**
  * Get the form
  *
  * @param string $method   http method to submit the form
  * @param string $action   relative path from the web root. When set to null
  *                         it uses the current api method's path
  * @param bool   $dataOnly if you want to render the form yourself use this
  *                         option
  * @param string $prefix   used for adjusting the spacing in front of
  *                         form elements
  * @param string $indent   used for adjusting indentation
  *
  * @return array|T
  *
  * @throws \Luracast\Restler\RestException
  */
 public static function get($method = 'POST', $action = null, $dataOnly = false, $prefix = '', $indent = '    ')
 {
     if (!static::$style) {
         static::$style = FormStyles::$html;
     }
     try {
         /** @var Restler $restler */
         $restler = Scope::get('Restler');
         if (is_null($action)) {
             $action = $restler->url;
         }
         $info = $restler->url == $action && Util::getRequestMethod() == $method ? $restler->apiMethodInfo : Routes::find(trim($action, '/'), $method, $restler->getRequestedApiVersion(), static::$preFill || $restler->requestMethod == $method && $restler->url == $action ? $restler->getRequestData() : array());
     } catch (RestException $e) {
         //echo $e->getErrorMessage();
         $info = false;
     }
     if (!$info) {
         throw new RestException(500, 'invalid action path for form `' . $method . ' ' . $action . '`');
     }
     static::$info = $info;
     $m = $info->metadata;
     $r = static::fields($dataOnly);
     if ($method != 'GET' && $method != 'POST') {
         if (empty(Defaults::$httpMethodOverrideProperty)) {
             throw new RestException(500, 'Forms require `Defaults::\\$httpMethodOverrideProperty`' . "for supporting HTTP {$method}");
         }
         if ($dataOnly) {
             $r[] = array('tag' => 'input', 'name' => Defaults::$httpMethodOverrideProperty, 'type' => 'hidden', 'value' => 'method');
         } else {
             $r[] = T::input()->name(Defaults::$httpMethodOverrideProperty)->value($method)->type('hidden');
         }
         $method = 'POST';
     }
     if (session_id() != '') {
         $form_key = static::key($method, $action);
         if ($dataOnly) {
             $r[] = array('tag' => 'input', 'name' => static::FORM_KEY, 'type' => 'hidden', 'value' => 'hidden');
         } else {
             $key = T::input()->name(static::FORM_KEY)->type('hidden')->value($form_key);
             $r[] = $key;
         }
     }
     $s = array('tag' => 'button', 'type' => 'submit', 'label' => Util::nestedValue($m, 'return', CommentParser::$embeddedDataName, 'label') ?: 'Submit');
     if (!$dataOnly) {
         $s = Emmet::make(static::style('submit', $m), $s);
     }
     $r[] = $s;
     $t = array('action' => $restler->getBaseUrl() . '/' . rtrim($action, '/'), 'method' => $method);
     if (static::$fileUpload) {
         static::$fileUpload = false;
         $t['enctype'] = 'multipart/form-data';
     }
     if (!$dataOnly) {
         $t = Emmet::make(static::style('form', $m), $t);
         $t->prefix = $prefix;
         $t->indent = $indent;
         $t[] = $r;
     } else {
         $t['fields'] = $r;
     }
     return $t;
 }