name = $name; $this->class = $class; $this->doc = $doc; } /** * @return string */ public function getName(): string { return $this->name; } /** * @return string */ public function getClass(): string { return $this->class; } /** * @return DocBlock */ public function getDoc(): DocBlock { return $this->doc; } /** * @return MethodsDoc[] */ public function getMethods(): array { return $this->methods; } /** * @param MethodsDoc $method */ public function addMethod(MethodsDoc $method) { $this->methods[] = $method; } } class MethodsDoc { /** @var string */ protected $name; /** @var DocBlock */ protected $doc; /** * @param string $name * @param DocBlock $doc */ public function __construct($name, DocBlock $doc) { $this->name = $name; $this->doc = $doc; } /** * @return string */ public function getName(): string { return $this->name; } /** * @return DocBlock */ public function getDoc(): DocBlock { return $this->doc; } } class DocBlock { protected $text; protected $params; public function __construct($text, array $params) { $this->text = $text; $this->params = $params; } /** * @return mixed */ public function getText() { return $this->text; } /** * @return array */ public function getParams(): array { return $this->params; } } function parseReturn(array $params) { $return = array_shift($params); if (strpos($return, ' ') !== false) { $type = strstr($return, ' ', true); $desc = trim(strstr($return, ' ')); } else { $type = $return; $desc = null; } $result = [ 'type' => $type, ]; if (!empty($desc)) { $result['description'] = $desc; } return $result; } function parseArguments(array $params) { $result = []; foreach ($params as $param) { $parts = array_values(array_filter(explode(' ', $param))); $type = array_shift($parts); $name = array_shift($parts); $desc = implode(' ', $parts); $argument = [ 'name' => $name, ]; if (!empty($type)) { $argument['type'] = $type; } if (!empty($desc)) { $argument['description'] = $desc; } $result[] = $argument; } return $result; } function parseClass($class) { $reflection = new ReflectionClass($class); $code = file_get_contents($reflection->getFileName()); $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); return $parser->parse($code); } /** * @param array $ast * @return ClassDoc */ function getDoc($name, $class, $ast) { /** @var \PhpParser\Node\Stmt\Namespace_ $namespace */ $namespace = $ast[0]; /** @var \PhpParser\Node\Stmt\Interface_ $interface */ $interface = null; foreach ($namespace->stmts as $stmt) { if ($stmt instanceof PhpParser\Node\Stmt\Interface_) { $interface = $stmt; break; } } if (empty($interface)) { throw new RuntimeException('Could not find interface'); } $doc = new ClassDoc($name, $class, getDocComment($interface)); /** @var PhpParser\Node\Stmt\ClassMethod[] $methods */ $methods = $interface->stmts; foreach ($methods as $method) { $doc->addMethod(new MethodsDoc($method->name, getDocComment($method))); } return $doc; } function getDocComment(PhpParser\Node $node) { $comments = $node->getAttribute('comments'); /** @var \PhpParser\Comment\Doc $comment */ $comment = $comments[0]; if ($comment instanceof PhpParser\Comment\Doc) { return parseDoc($comment->getText()); } return new DocBlock("", []); } function parseDoc($doc) { $doc = str_replace(["\r\n", "\n", "\r"], "\n", $doc); $lines = explode("\n", $doc); // remove first and last line array_pop($lines); array_shift($lines); $text = []; $params = []; foreach ($lines as $line) { $line = substr(trim($line), 2); if (empty($line)) { continue; } if ($line[0] == '@') { $key = strstr($line, ' ', true); $value = trim(strstr($line, ' ')); if (!isset($params[$key])) { $params[$key] = []; } $params[$key][] = $value; } else { $text[] = $line; } } return new DocBlock(implode("\n", $text), $params); } __halt_compiler();----SIGNATURE:----JT7n2CtL6oQVLWalxFoFFlJN1Ka/hqRV4eEqXBCEI73x+MiMbTC8lyjhih/8NmcbAXZ0nJOcymEWXblTDJ3hacKuTyoDTUXLMSFURmQL7mhemTcXY0/yVqtUheE/FQ0O5trMu/0p54bcjNXAuMb9CpY9WT0wKW/4y1qiQZjfHITFf0bfKELAGpVFr6tywz5OQA2xL3yfBbBkeTzIZyCRUsAoibOyEyVYK1Y8E2D5mBEHkySiWjT/21Y5QsYPF018M5kkUU1AARj3cG3nOu1q2XWEMieolwVL9zqRs6hpkL7i1ZVB/0H+2oyRPAvZnwk3fojNR0E+T5fh8Yi3hiSG8IFPptJ/KnrLAJSLev7eBKvnfvRZg+QqzGGBjnUBUToPSYFCaIsVNDDKF1AYrP3XByqCcVWF+Z5/fRUF2BrM6PI5KkgvvGyhW+W5buZsUsOqngI1J7MfWEeoop5q++xEoqCxIdDNLNerPczmSytdWU4uKCI5KM55Fb53UR7Cl9zwpTfXlQFxwa9+v0V0BCKEPyII3FTLe43KO2KnCc5MsVomfUEw1iMqVlin1DD31lIPXZjEMZurhC5ShHNY7bAkCN8hbZNPYpF20wtpwLuzJXCwxxdZN+SxQVlbiLT+ma3A6sqs5DCfR7C3FTnArKDDg4RtCzsCX8riJpDQDJGtkYo=----ATTACHMENT:----NTk0NTgwODQzNzUzNjQ1NyA3Mzg3MTk5MDk5ODU3NDcyIDMxOTI2MjgzNzA4NjA2MTY=