/** * Parses the annotations from the given doc block * * @param string $doc * @return \PSX\Util\Annotation\DocBlock */ public static function parse($doc) { $block = new DocBlock(); $lines = explode("\n", $doc); // remove first line unset($lines[0]); foreach ($lines as $line) { $line = trim($line); $line = substr($line, 2); if (isset($line[0]) && $line[0] == '@') { $line = substr($line, 1); $sp = strpos($line, ' '); $bp = strpos($line, '('); if ($sp !== false || $bp !== false) { if ($sp !== false && $bp === false) { $pos = $sp; } elseif ($sp === false && $bp !== false) { $pos = $bp; } else { $pos = $sp < $bp ? $sp : $bp; } $key = substr($line, 0, $pos); $value = substr($line, $pos); } else { $key = $line; $value = null; } $key = trim($key); $value = trim($value); if (!empty($key)) { // if key contains backslashes its a namespace use only the // short name $pos = strrpos($key, '\\'); if ($pos !== false) { $key = substr($key, $pos + 1); } $block->addAnnotation($key, $value); } } } return $block; }
/** * This method returns all annotation wich are defined in this or any parent * class. If an annotation type is present it overwrites all other defined * types if not the annotations from the parent class will be used * * @param ReflectionClass $class * @param string $methodName * @return DocBlock */ private function getAnnotations(ReflectionClass $class, $methodName) { // get hierarchy $parents[] = $class; while ($parent = $class->getParentClass()) { $parents[] = $parent; $class = $parent; } // parse doc comments $block = new DocBlock(); foreach ($parents as $class) { try { $method = $class->getMethod($methodName); if ($method) { $comment = $method->getDocComment(); if (!empty($comment)) { $doc = Annotation::parse($comment); $params = $doc->getAnnotations(); $text = $doc->getText(); foreach ($params as $k => $v) { $block->setAnnotations($k, $v); } if (!empty($text)) { $block->setText($text); } } } } catch (\Exception $e) { // method probably doesnt exist } } return $block; }