/** * クラスのドキュメント * @param string $class */ public static function class_info($class) { $r = new \ReflectionClass('\\' . str_replace(array('.', '/'), array('\\', '\\'), $class)); if ($r->getFilename() === false || !is_file($r->getFileName())) { throw new \InvalidArgumentException('`' . $class . '` file not found.'); } $src = implode(array_slice(file($r->getFileName()), $r->getStartLine(), $r->getEndLine() - $r->getStartLine() - 1)); $document = trim(preg_replace("/^[\\s]*\\*[\\s]{0,1}/m", "", str_replace(array("/" . "**", "*" . "/"), "", $r->getDocComment()))); $extends = $r->getParentClass() === false ? null : $r->getParentClass()->getName(); $updated = filemtime($r->getFilename()); if (substr(basename($r->getFilename()), 0, -4) === basename(dirname($r->getFilename()))) { foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(dirname($r->getFilename()), \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS)) as $f) { if (($u = filemtime($f->getPathname())) > $updated) { $updated = $u; } } } $methods = $static_methods = $protected_methods = $protected_static_methods = array(array(), array()); $module_method = array(); foreach ($r->getMethods() as $method) { if (substr($method->getName(), 0, 1) != '_' && ($method->isPublic() || $method->isProtected())) { $method_document = preg_replace("/^[\\s]*\\*[\\s]{0,1}/m", '', str_replace(array('/' . '**', '*' . '/'), '', $method->getDocComment())); list($method_description) = explode("\n", trim(preg_replace('/@.+/', '', $method_document))); if (strpos($method_description, 'non-PHPdoc') !== false) { if (preg_match("/@see\\s+(.*)/", $method_document, $match)) { $method_description = str_replace("\\", '.', trim($match[1])); if (preg_match("/^.+\\/([^\\/]+)\$/", $method_description, $m)) { $method_description = trim($m[1]); } if (substr($method_description, 0, 1) == '.') { $method_description = substr($method_description, 1); } if (strpos($method_description, '::') !== false) { list($c, $m) = explode('::', str_replace(array('(', ')'), '', $method_description)); try { $i = self::method_info($c, $m); list($method_description) = explode("\n", $i['description']); } catch (\Exception $e) { $method_description = '@see ' . $method_description; } } } } if (preg_match_all("/@module\\s+([\\w\\.\\\\]+)/", $method_document, $match)) { foreach ($match[1] as $v) { $module_method[trim($v)][] = $method->getName(); } } $dec = $method->getDeclaringClass()->getFileName() == $r->getFileName() ? 0 : 1; if ($method->isStatic()) { if ($method->getDeclaringClass()->getName() == $r->getName()) { if ($method->isPublic()) { $static_methods[$dec][$method->getName()] = $method_description; } else { $protected_static_methods[$dec][$method->getName()] = $method_description; } } } else { if ($method->isPublic()) { $methods[$dec][$method->getName()] = $method_description; } else { $protected_methods[$dec][$method->getName()] = $method_description; } } } } $tasks = array(); if (preg_match_all("/T" . "ODO[ \t](.+)/", $src, $match)) { foreach ($match[1] as $t) { $tasks[] = trim($t); } } $modules = array(); if (preg_match_all("/->object_module\\(([\"\\'])(.+?)\\1/", $src, $match, PREG_OFFSET_CAPTURE)) { foreach ($match[2] as $k => $v) { self::get_desc($modules, $match, $k, $v[0], $src, $class); } } if (preg_match_all("/::module\\(([\"\\'])(.+?)\\1/", $src, $match, PREG_OFFSET_CAPTURE)) { foreach ($match[2] as $k => $v) { self::get_desc($modules, $match, $k, $v[0], $src, $class); } } $properties = array(); $ref = new \ReflectionClass('\\' . str_replace(array('.', '/'), array('\\', '\\'), $class)); $d = ''; while (true) { $d = $ref->getDocComment() . $d; if (($ref = $ref->getParentClass()) === false) { break; } } $d = preg_replace("/^[\\s]*\\*[\\s]{0,1}/m", '', str_replace(array('/' . '**', '*' . '/'), '', $d)); $anon = \org\rhaco\Object::anon_decode($d, 'var', $r->getNamespaceName(), 'summary'); foreach ($r->getProperties() as $prop) { if (!$prop->isPrivate()) { $name = $prop->getName(); if ($name[0] != '_' && !$prop->isStatic()) { $properties[$name] = array(isset($anon[$name]['type']) ? self::type($anon[$name]['type'], $class) : 'mixed', isset($anon[$name]['summary']) ? $anon[$name]['summary'] : null, !(isset($anon[$name]['hash']) && $anon[$name]['hash'] === false)); } } } $description = trim(preg_replace('/@.+/', '', $document)); ksort($static_methods[0]); ksort($methods[0]); ksort($protected_methods[0]); ksort($protected_static_methods[0]); ksort($static_methods[1]); ksort($methods[1]); ksort($protected_methods[1]); ksort($protected_static_methods[1]); ksort($properties); ksort($modules); return array('filename' => $r->getFileName(), 'extends' => $extends, 'abstract' => $r->isAbstract(), 'version' => date('Ymd', $updated), 'static_methods' => $static_methods[0], 'methods' => $methods[0], 'protected_static_methods' => $protected_static_methods[0], 'protected_methods' => $protected_methods[0], 'inherited_static_methods' => $static_methods[1], 'inherited_methods' => $methods[1], 'inherited_protected_static_methods' => $protected_static_methods[1], 'inherited_protected_methods' => $protected_methods[1], 'module_method' => $module_method, 'properties' => $properties, 'tasks' => $tasks, 'package' => $class, 'description' => $description, 'modules' => $modules); }