|
@@ -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;
|
|
|
+ }
|
|
|
}
|