diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index 204988c5442..cbfecbbc19f 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -275,6 +275,13 @@ RESTLER: with $loaders = array_unique(static::$rogueLoaders, SORT_REGULAR); + +* Replace CommentParser.php line 423 + elseif (count($value) && is_numeric($value[0])) + + with + + elseif (count($value) && isset($value[0]) && is_numeric($value[0])) +With swagger 2 provided into /explorer: diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 10ab441f442..177410622c4 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -124,7 +124,7 @@ $usercancreateorder = $user->rights->commande->creer; $usercancreateinvoice = $user->rights->facture->creer; $usercancreatecontract = $user->rights->contrat->creer; $usercancreateintervention = $user->hasRight('ficheinter', 'creer'); -$usercancreatepurchaseorder = ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer); +$usercancreatepurchaseorder = ($user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer')); $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php diff --git a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php index 6b8b9178f6b..ce148874d02 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php @@ -19,505 +19,504 @@ use Luracast\Restler\Data\Text; */ class CommentParser { - /** - * name for the embedded data - * - * @var string - */ - public static $embeddedDataName = 'properties'; - /** - * Regular Expression pattern for finding the embedded data and extract - * the inner information. It is used with preg_match. - * - * @var string - */ - public static $embeddedDataPattern - = '/```(\w*)[\s]*(([^`]*`{0,2}[^`]+)*)```/ms'; - /** - * Pattern will have groups for the inner details of embedded data - * this index is used to locate the data portion. - * - * @var int - */ - public static $embeddedDataIndex = 2; - /** - * Delimiter used to split the array data. - * - * When the name portion is of the embedded data is blank auto detection - * will be used and if URLEncodedFormat is detected as the data format - * the character specified will be used as the delimiter to find split - * array data. - * - * @var string - */ - public static $arrayDelimiter = ','; + /** + * name for the embedded data + * + * @var string + */ + public static $embeddedDataName = 'properties'; + /** + * Regular Expression pattern for finding the embedded data and extract + * the inner information. It is used with preg_match. + * + * @var string + */ + public static $embeddedDataPattern + = '/```(\w*)[\s]*(([^`]*`{0,2}[^`]+)*)```/ms'; + /** + * Pattern will have groups for the inner details of embedded data + * this index is used to locate the data portion. + * + * @var int + */ + public static $embeddedDataIndex = 2; + /** + * Delimiter used to split the array data. + * + * When the name portion is of the embedded data is blank auto detection + * will be used and if URLEncodedFormat is detected as the data format + * the character specified will be used as the delimiter to find split + * array data. + * + * @var string + */ + public static $arrayDelimiter = ','; - /** - * @var array annotations that support array value - */ - public static $allowsArrayValue = array( - 'choice' => true, - 'select' => true, - 'properties' => true, - ); + /** + * @var array annotations that support array value + */ + public static $allowsArrayValue = array( + 'choice' => true, + 'select' => true, + 'properties' => true, + ); - /** - * character sequence used to escape \@ - */ - const escapedAtChar = '\\@'; + /** + * character sequence used to escape \@ + */ + const escapedAtChar = '\\@'; - /** - * character sequence used to escape end of comment - */ - const escapedCommendEnd = '{@*}'; + /** + * character sequence used to escape end of comment + */ + const escapedCommendEnd = '{@*}'; - /** - * Instance of Restler class injected at runtime. - * - * @var Restler - */ - public $restler; - /** - * Comment information is parsed and stored in to this array. - * - * @var array - */ - private $_data = array(); + /** + * Instance of Restler class injected at runtime. + * + * @var Restler + */ + public $restler; + /** + * Comment information is parsed and stored in to this array. + * + * @var array + */ + private $_data = array(); - /** - * Parse the comment and extract the data. - * - * @static - * - * @param $comment - * @param bool $isPhpDoc - * - * @return array associative array with the extracted values - */ - public static function parse($comment, $isPhpDoc = true) - { - $p = new self(); - if (empty($comment)) { - return $p->_data; - } + /** + * Parse the comment and extract the data. + * + * @static + * + * @param $comment + * @param bool $isPhpDoc + * + * @return array associative array with the extracted values + */ + public static function parse($comment, $isPhpDoc = true) + { + $p = new self(); + if (empty($comment)) { + return $p->_data; + } - if ($isPhpDoc) { - $comment = self::removeCommentTags($comment); - } + if ($isPhpDoc) { + $comment = self::removeCommentTags($comment); + } - $p->extractData($comment); - return $p->_data; + $p->extractData($comment); + return $p->_data; + } - } + /** + * Removes the comment tags from each line of the comment. + * + * @static + * + * @param string $comment PhpDoc style comment + * + * @return string comments with out the tags + */ + public static function removeCommentTags($comment) + { + $pattern = '/(^\/\*\*)|(^\s*\**[ \/]?)|\s(?=@)|\s\*\//m'; + return preg_replace($pattern, '', $comment); + } - /** - * Removes the comment tags from each line of the comment. - * - * @static - * - * @param string $comment PhpDoc style comment - * - * @return string comments with out the tags - */ - public static function removeCommentTags($comment) - { - $pattern = '/(^\/\*\*)|(^\s*\**[ \/]?)|\s(?=@)|\s\*\//m'; - return preg_replace($pattern, '', $comment); - } + /** + * Extracts description and long description, uses other methods to get + * parameters. + * + * @param $comment + * + * @return array + */ + private function extractData($comment) + { + //to use @ as part of comment we need to + $comment = str_replace( + array(self::escapedCommendEnd, self::escapedAtChar), + array('*/', '@'), + $comment); - /** - * Extracts description and long description, uses other methods to get - * parameters. - * - * @param $comment - * - * @return array - */ - private function extractData($comment) - { - //to use @ as part of comment we need to - $comment = str_replace( - array(self::escapedCommendEnd, self::escapedAtChar), - array('*/', '@'), - $comment); + $description = array(); + $longDescription = array(); + $params = array(); - $description = array(); - $longDescription = array(); - $params = array(); + $mode = 0; // extract short description; + $comments = preg_split("/(\r?\n)/", $comment); + // remove first blank line; + array_shift($comments); + $addNewline = false; + foreach ($comments as $line) { + $line = trim($line); + $newParam = false; + if (empty($line)) { + if ($mode == 0) { + $mode++; + } else { + $addNewline = true; + } + continue; + } elseif ($line[0] == '@') { + $mode = 2; + $newParam = true; + } + switch ($mode) { + case 0 : + $description[] = $line; + if (count($description) > 3) { + // if more than 3 lines take only first line + $longDescription = $description; + $description[] = array_shift($longDescription); + $mode = 1; + } elseif (substr($line, -1) == '.') { + $mode = 1; + } + break; + case 1 : + if ($addNewline) { + $line = ' ' . $line; + } + $longDescription[] = $line; + break; + case 2 : + $newParam + ? $params[] = $line + : $params[count($params) - 1] .= ' ' . $line; + } + $addNewline = false; + } + $description = implode(' ', $description); + $longDescription = implode(' ', $longDescription); + $description = preg_replace('/\s+/msu', ' ', $description); + $longDescription = preg_replace('/\s+/msu', ' ', $longDescription); + list($description, $d1) + = $this->parseEmbeddedData($description); + list($longDescription, $d2) + = $this->parseEmbeddedData($longDescription); + $this->_data = compact('description', 'longDescription'); + $d2 += $d1; + if (!empty($d2)) { + $this->_data[self::$embeddedDataName] = $d2; + } + foreach ($params as $key => $line) { + list(, $param, $value) = preg_split('/\@|\s/', $line, 3) + + array('', '', ''); + list($value, $embedded) = $this->parseEmbeddedData($value); + $value = array_filter(preg_split('/\s+/msu', $value), 'strlen'); + $this->parseParam($param, $value, $embedded); + } + return $this->_data; + } - $mode = 0; // extract short description; - $comments = preg_split("/(\r?\n)/", $comment); - // remove first blank line; - array_shift($comments); - $addNewline = false; - foreach ($comments as $line) { - $line = trim($line); - $newParam = false; - if (empty ($line)) { - if ($mode == 0) { - $mode++; - } else { - $addNewline = true; - } - continue; - } elseif ($line[0] == '@') { - $mode = 2; - $newParam = true; - } - switch ($mode) { - case 0 : - $description[] = $line; - if (count($description) > 3) { - // if more than 3 lines take only first line - $longDescription = $description; - $description[] = array_shift($longDescription); - $mode = 1; - } elseif (substr($line, -1) == '.') { - $mode = 1; - } - break; - case 1 : - if ($addNewline) { - $line = ' ' . $line; - } - $longDescription[] = $line; - break; - case 2 : - $newParam - ? $params[] = $line - : $params[count($params) - 1] .= ' ' . $line; - } - $addNewline = false; - } - $description = implode(' ', $description); - $longDescription = implode(' ', $longDescription); - $description = preg_replace('/\s+/msu', ' ', $description); - $longDescription = preg_replace('/\s+/msu', ' ', $longDescription); - list($description, $d1) - = $this->parseEmbeddedData($description); - list($longDescription, $d2) - = $this->parseEmbeddedData($longDescription); - $this->_data = compact('description', 'longDescription'); - $d2 += $d1; - if (!empty($d2)) { - $this->_data[self::$embeddedDataName] = $d2; - } - foreach ($params as $key => $line) { - list(, $param, $value) = preg_split('/\@|\s/', $line, 3) - + array('', '', ''); - list($value, $embedded) = $this->parseEmbeddedData($value); - $value = array_filter(preg_split('/\s+/msu', $value), 'strlen'); - $this->parseParam($param, $value, $embedded); - } - return $this->_data; - } + /** + * Parse parameters that begin with (at) + * + * @param $param + * @param array $value + * @param array $embedded + */ + private function parseParam($param, array $value, array $embedded) + { + $data = &$this->_data; + $allowMultiple = false; + switch ($param) { + case 'param' : + case 'property' : + case 'property-read' : + case 'property-write' : + $value = $this->formatParam($value); + $allowMultiple = true; + break; + case 'var' : + $value = $this->formatVar($value); + break; + case 'return' : + $value = $this->formatReturn($value); + break; + case 'class' : + $data = &$data[$param]; + list ($param, $value) = $this->formatClass($value); + break; + case 'access' : + $value = reset($value); + break; + case 'expires' : + case 'status' : + $value = intval(reset($value)); + break; + case 'throws' : + $value = $this->formatThrows($value); + $allowMultiple = true; + break; + case 'author': + $value = $this->formatAuthor($value); + $allowMultiple = true; + break; + case 'header' : + case 'link': + case 'example': + case 'todo': + $allowMultiple = true; + //don't break, continue with code for default: + default : + $value = implode(' ', $value); + } + if (!empty($embedded)) { + if (is_string($value)) { + $value = array('description' => $value); + } + $value[self::$embeddedDataName] = $embedded; + } + if (empty($data[$param])) { + if ($allowMultiple) { + $data[$param] = array( + $value + ); + } else { + $data[$param] = $value; + } + } elseif ($allowMultiple) { + $data[$param][] = $value; + } elseif ($param == 'param') { + $arr = array( + $data[$param], + $value + ); + $data[$param] = $arr; + } else { + if (!is_string($value) && isset($value[self::$embeddedDataName]) + && isset($data[$param][self::$embeddedDataName]) + ) { + $value[self::$embeddedDataName] + += $data[$param][self::$embeddedDataName]; + } + if (!is_array($data[$param])) { + $data[$param] = array('description' => (string) $data[$param]); + } + if (is_array($value)) { + $data[$param] = $value + $data[$param]; + } + } + } - /** - * Parse parameters that begin with (at) - * - * @param $param - * @param array $value - * @param array $embedded - */ - private function parseParam($param, array $value, array $embedded) - { - $data = &$this->_data; - $allowMultiple = false; - switch ($param) { - case 'param' : - case 'property' : - case 'property-read' : - case 'property-write' : - $value = $this->formatParam($value); - $allowMultiple = true; - break; - case 'var' : - $value = $this->formatVar($value); - break; - case 'return' : - $value = $this->formatReturn($value); - break; - case 'class' : - $data = &$data[$param]; - list ($param, $value) = $this->formatClass($value); - break; - case 'access' : - $value = reset($value); - break; - case 'expires' : - case 'status' : - $value = intval(reset($value)); - break; - case 'throws' : - $value = $this->formatThrows($value); - $allowMultiple = true; - break; - case 'author': - $value = $this->formatAuthor($value); - $allowMultiple = true; - break; - case 'header' : - case 'link': - case 'example': - case 'todo': - $allowMultiple = true; - //don't break, continue with code for default: - default : - $value = implode(' ', $value); - } - if (!empty($embedded)) { - if (is_string($value)) { - $value = array('description' => $value); - } - $value[self::$embeddedDataName] = $embedded; - } - if (empty ($data[$param])) { - if ($allowMultiple) { - $data[$param] = array( - $value - ); - } else { - $data[$param] = $value; - } - } elseif ($allowMultiple) { - $data[$param][] = $value; - } elseif ($param == 'param') { - $arr = array( - $data[$param], - $value - ); - $data[$param] = $arr; - } else { - if (!is_string($value) && isset($value[self::$embeddedDataName]) - && isset($data[$param][self::$embeddedDataName]) - ) { - $value[self::$embeddedDataName] - += $data[$param][self::$embeddedDataName]; - } - if (!is_array($data[$param])) { - $data[$param] = array('description' => (string)$data[$param]); - } - if (is_array($value)) { - $data[$param] = $value + $data[$param]; - } - } - } + /** + * Parses the inline php doc comments and embedded data. + * + * @param $subject + * + * @return array + * @throws Exception + */ + private function parseEmbeddedData($subject) + { + $data = array(); - /** - * Parses the inline php doc comments and embedded data. - * - * @param $subject - * - * @return array - * @throws Exception - */ - private function parseEmbeddedData($subject) - { - $data = array(); + //parse {@pattern } tags specially + while (preg_match('|(?s-m)({@pattern (/.+/[imsxuADSUXJ]*)})|', $subject, $matches)) { + $subject = str_replace($matches[0], '', $subject); + $data['pattern'] = $matches[2]; + } + while (preg_match('/{@(\w+)\s?([^}]*)}/ms', $subject, $matches)) { + $name = $matches[1]; + $value = $matches[2]; + $subject = str_replace($matches[0], '', $subject); + if ($name == 'pattern') { + throw new Exception('Inline pattern tag should follow {@pattern /REGEX_PATTERN_HERE/} format and can optionally include PCRE modifiers following the ending `/`'); + } elseif (isset(static::$allowsArrayValue[$name])) { + $value = explode(static::$arrayDelimiter, $value); + } elseif ($value == 'true' || $value == 'false') { + $value = $value == 'true'; + } elseif ($value == '') { + $value = true; + } elseif ($name == 'required') { + $value = explode(static::$arrayDelimiter, $value); + } + if (defined('Luracast\\Restler\\UI\\HtmlForm::'.$name)) { + $value = constant($value); + } + $data[$name] = $value; + } - //parse {@pattern } tags specially - while (preg_match('|(?s-m)({@pattern (/.+/[imsxuADSUXJ]*)})|', $subject, $matches)) { - $subject = str_replace($matches[0], '', $subject); - $data['pattern'] = $matches[2]; - } - while (preg_match('/{@(\w+)\s?([^}]*)}/ms', $subject, $matches)) { - $name = $matches[1]; - $value = $matches[2]; - $subject = str_replace($matches[0], '', $subject); - if ($name == 'pattern') { - throw new Exception('Inline pattern tag should follow {@pattern /REGEX_PATTERN_HERE/} format and can optionally include PCRE modifiers following the ending `/`'); - } elseif (isset(static::$allowsArrayValue[$name])) { - $value = explode(static::$arrayDelimiter, $value); - } elseif ($value == 'true' || $value == 'false') { - $value = $value == 'true'; - } elseif ($value == '') { - $value = true; - } elseif ($name == 'required') { - $value = explode(static::$arrayDelimiter, $value); - } - if (defined('Luracast\\Restler\\UI\\HtmlForm::'.$name)) { - $value = constant($value); - } - $data[$name] = $value; - } + while (preg_match(self::$embeddedDataPattern, $subject, $matches)) { + $subject = str_replace($matches[0], '', $subject); + $str = $matches[self::$embeddedDataIndex]; + if (isset($this->restler) + && self::$embeddedDataIndex > 1 + && !empty($name) + ) { + $extension = $name; + $formatMap = $this->restler->getFormatMap(); + if (isset($formatMap[$extension])) { + /** + * @var \Luracast\Restler\Format\iFormat + */ + $format = $formatMap[$extension]; + $format = new $format(); + $data = $format->decode($str); + } + } else { // auto detect + if ($str[0] == '{') { + $d = json_decode($str, true); + if (json_last_error() != JSON_ERROR_NONE) { + throw new Exception('Error parsing embedded JSON data' + . " $str"); + } + $data = $d + $data; + } else { + parse_str($str, $d); + //clean up + $d = array_filter($d); + foreach ($d as $key => $val) { + $kt = trim($key); + if ($kt != $key) { + unset($d[$key]); + $key = $kt; + $d[$key] = $val; + } + if (is_string($val)) { + if ($val == 'true' || $val == 'false') { + $d[$key] = $val == 'true' ? true : false; + } else { + $val = explode(self::$arrayDelimiter, $val); + if (count($val) > 1) { + $d[$key] = $val; + } else { + $d[$key] = + preg_replace('/\s+/msu', ' ', + $d[$key]); + } + } + } + } + $data = $d + $data; + } + } + } + return array($subject, $data); + } - while (preg_match(self::$embeddedDataPattern, $subject, $matches)) { - $subject = str_replace($matches[0], '', $subject); - $str = $matches[self::$embeddedDataIndex]; - if (isset ($this->restler) - && self::$embeddedDataIndex > 1 - && !empty ($name) - ) { - $extension = $name; - $formatMap = $this->restler->getFormatMap(); - if (isset ($formatMap[$extension])) { - /** - * @var \Luracast\Restler\Format\iFormat - */ - $format = $formatMap[$extension]; - $format = new $format(); - $data = $format->decode($str); - } - } else { // auto detect - if ($str[0] == '{') { - $d = json_decode($str, true); - if (json_last_error() != JSON_ERROR_NONE) { - throw new Exception('Error parsing embedded JSON data' - . " $str"); - } - $data = $d + $data; - } else { - parse_str($str, $d); - //clean up - $d = array_filter($d); - foreach ($d as $key => $val) { - $kt = trim($key); - if ($kt != $key) { - unset($d[$key]); - $key = $kt; - $d[$key] = $val; - } - if (is_string($val)) { - if ($val == 'true' || $val == 'false') { - $d[$key] = $val == 'true' ? true : false; - } else { - $val = explode(self::$arrayDelimiter, $val); - if (count($val) > 1) { - $d[$key] = $val; - } else { - $d[$key] = - preg_replace('/\s+/msu', ' ', - $d[$key]); - } - } - } - } - $data = $d + $data; - } - } - } - return array($subject, $data); - } + private function formatThrows(array $value) + { + $code = 500; + $exception = 'Exception'; + if (count($value) > 1) { + $v1 = $value[0]; + $v2 = $value[1]; + if (is_numeric($v1)) { + $code = $v1; + $exception = $v2; + array_shift($value); + array_shift($value); + } elseif (is_numeric($v2)) { + $code = $v2; + $exception = $v1; + array_shift($value); + array_shift($value); + } else { + $exception = $v1; + array_shift($value); + } + } elseif (count($value) && isset($value[0]) && is_numeric($value[0])) { + $code = $value[0]; + array_shift($value); + } + $message = implode(' ', $value); + if (!isset(RestException::$codes[$code])) { + $code = 500; + } elseif (empty($message)) { + $message = RestException::$codes[$code]; + } + return compact('code', 'message', 'exception'); + } - private function formatThrows(array $value) - { - $code = 500; - $exception = 'Exception'; - if (count($value) > 1) { - $v1 = $value[0]; - $v2 = $value[1]; - if (is_numeric($v1)) { - $code = $v1; - $exception = $v2; - array_shift($value); - array_shift($value); - } elseif (is_numeric($v2)) { - $code = $v2; - $exception = $v1; - array_shift($value); - array_shift($value); - } else { - $exception = $v1; - array_shift($value); - } - } elseif (count($value) && is_numeric($value[0])) { - $code = $value[0]; - array_shift($value); - } - $message = implode(' ', $value); - if (!isset(RestException::$codes[$code])) { - $code = 500; - } elseif (empty($message)) { - $message = RestException::$codes[$code]; - } - return compact('code', 'message', 'exception'); - } + private function formatClass(array $value) + { + $param = array_shift($value); - private function formatClass(array $value) - { - $param = array_shift($value); + if (empty($param)) { + $param = 'Unknown'; + } + $value = implode(' ', $value); + return array( + ltrim($param, '\\'), + array('description' => $value) + ); + } - if (empty($param)) { - $param = 'Unknown'; - } - $value = implode(' ', $value); - return array( - ltrim($param, '\\'), - array('description' => $value) - ); - } + private function formatAuthor(array $value) + { + $r = array(); + $email = end($value); + if ($email[0] == '<') { + $email = substr($email, 1, -1); + array_pop($value); + $r['email'] = $email; + } + $r['name'] = implode(' ', $value); + return $r; + } - private function formatAuthor(array $value) - { - $r = array(); - $email = end($value); - if ($email[0] == '<') { - $email = substr($email, 1, -1); - array_pop($value); - $r['email'] = $email; - } - $r['name'] = implode(' ', $value); - return $r; - } + private function formatReturn(array $value) + { + $data = explode('|', array_shift($value)); + $r = array( + 'type' => count($data) == 1 ? $data[0] : $data + ); + $r['description'] = implode(' ', $value); + return $r; + } - private function formatReturn(array $value) - { - $data = explode('|', array_shift($value)); - $r = array( - 'type' => count($data) == 1 ? $data[0] : $data - ); - $r['description'] = implode(' ', $value); - return $r; - } + private function formatParam(array $value) + { + $r = array(); + $data = array_shift($value); + if (empty($data)) { + $r['type'] = 'mixed'; + } elseif ($data[0] == '$') { + $r['name'] = substr($data, 1); + $r['type'] = 'mixed'; + } else { + $data = explode('|', $data); + $r['type'] = count($data) == 1 ? $data[0] : $data; - private function formatParam(array $value) - { - $r = array(); - $data = array_shift($value); - if (empty($data)) { - $r['type'] = 'mixed'; - } elseif ($data[0] == '$') { - $r['name'] = substr($data, 1); - $r['type'] = 'mixed'; - } else { - $data = explode('|', $data); - $r['type'] = count($data) == 1 ? $data[0] : $data; + $data = array_shift($value); + if (!empty($data) && $data[0] == '$') { + $r['name'] = substr($data, 1); + } + } + if (isset($r['type']) && is_string($r['type']) && Text::endsWith($r['type'], '[]')) { + $r[static::$embeddedDataName]['type'] = substr($r['type'], 0, -2); + $r['type'] = 'array'; + } + if ($value) { + $r['description'] = implode(' ', $value); + } + return $r; + } - $data = array_shift($value); - if (!empty($data) && $data[0] == '$') { - $r['name'] = substr($data, 1); - } - } - if (isset($r['type']) && is_string($r['type']) && Text::endsWith($r['type'], '[]')) { - $r[static::$embeddedDataName]['type'] = substr($r['type'], 0, -2); - $r['type'] = 'array'; - } - if ($value) { - $r['description'] = implode(' ', $value); - } - return $r; - } - - private function formatVar(array $value) - { - $r = array(); - $data = array_shift($value); - if (empty($data)) { - $r['type'] = 'mixed'; - } elseif ($data[0] == '$') { - $r['name'] = substr($data, 1); - $r['type'] = 'mixed'; - } else { - $data = explode('|', $data); - $r['type'] = count($data) == 1 ? $data[0] : $data; - } - if (isset($r['type']) && Text::endsWith($r['type'], '[]')) { - $r[static::$embeddedDataName]['type'] = substr($r['type'], 0, -2); - $r['type'] = 'array'; - } - if ($value) { - $r['description'] = implode(' ', $value); - } - return $r; - } + private function formatVar(array $value) + { + $r = array(); + $data = array_shift($value); + if (empty($data)) { + $r['type'] = 'mixed'; + } elseif ($data[0] == '$') { + $r['name'] = substr($data, 1); + $r['type'] = 'mixed'; + } else { + $data = explode('|', $data); + $r['type'] = count($data) == 1 ? $data[0] : $data; + } + if (isset($r['type']) && Text::endsWith($r['type'], '[]')) { + $r[static::$embeddedDataName]['type'] = substr($r['type'], 0, -2); + $r['type'] = 'array'; + } + if ($value) { + $r['description'] = implode(' ', $value); + } + return $r; + } }