/** * Gets the line where the class definition starts * @return Integer */ public function getStartLine() { $s = $this->reflection->getStartLine(); if (!$s || !$this->getFileName()) { return NULL; } return $s; }
/** * Возвращает тело класса/интерфейса */ public function getClassBody() { $lines = $this->di->getFileLines(true, true); $firstLine = $this->rc->getStartLine(); $endLine = $this->rc->getEndLine(); if ($endLine <= $firstLine + 1) { return ''; } return trim(implode('', array_slice($lines, $firstLine, $endLine - $firstLine - 1))); }
private function createMockClass($className, $mockData = []) { $shortName = $this->reflection->getShortName(); $classStart = self::reflectionContent($this->reflection, 1, $this->reflection->getStartLine() - 1); $classStart .= PHP_EOL . "class {$className} extends {$shortName}" . PHP_EOL; $this->body = self::reflectionBody($this->reflection, false); foreach ($mockData as $attribute => $value) { if (is_callable($value)) { $this->insertMethod($attribute, $value); } else { $this->insertAttribute($attribute, $value); } } eval($classStart . $this->body); }
public function reflect() { $this->load->library('calendar'); $reflect = new ReflectionClass('CI_Calendar'); echo $reflect->getStartLine(); $path = $reflect->getFileName(); $temp = @file($path); echo $reflect->getEndLine(); $len = $reflect->getEndLine() - $reflect->getStartLine() + 1; echo implode(array_slice($temp, $reflect->getStartLine() - 1, $len)); // foreach ($func->getParameters() as $param) // { // echo $param,'<br>'; // } }
/** * * @return type */ public static function applyTable() { // if (static::isAdamantTable()) { return; } // $attribute = 'ApplyTableExecuted'; // avoid re-update by check the cache if (!static::hasClassAttribute($attribute)) { // retrieve database $database = static::getDatabase(); // if model is not connectect to any db return if (!$database) { static::error('Database not found', debug_backtrace(), 2); } // retrieve class model schema $schema = static::getSchema(); // if (!$schema) { // $reflector = new \ReflectionClass(static::getClass()); // static::error('Model class without attributes', [['file' => $reflector->getFileName(), 'line' => $reflector->getStartLine()]]); } // get table name $table = static::getTable(); // have a valid schema update db table $database->applyTable($table, $schema, false); // cache last update avoid multiple call static::setClassAttribute($attribute, time()); } }
public function handleRequestExit($context, &$storage) { $request = $context['functionArgs'][0]; if (empty($request)) { return; } $ctrl = $request->get('_controller'); if (empty($ctrl)) { return; } if (empty($ctrl) || !(is_array($ctrl) || is_string($ctrl))) { return; } elseif (is_string($ctrl)) { $ctrl = explode(':', $ctrl); } $controller = $ctrl[0]; if (!empty($ctrl[2])) { $action = $ctrl[2]; } else { $action = $ctrl[1]; } try { $refclass = new \ReflectionClass($controller); $filename = $refclass->getFileName(); $lineno = $refclass->getStartLine(); } catch (\Exception $e) { $filename = $lineno = ''; } $storage['request'][] = @array('Controller' => $controller, 'Action' => $action, 'Filename' => $filename, 'Line Number' => $lineno, 'Route' => array('Name' => $request->get('_route'), 'Params' => $request->get('_routeparams')), 'Session' => $request->getSession() ? 'yes' : 'no', 'Locale' => $request->getLocale()); }
/** * Constructor. * * @param string A PHP identifier, e.g. a class, method, interface, etc. name * @param callable The callable targeted by the identifier when it is ambiguous or not a real PHP identifier */ public function __construct($identifier, $callable = null) { $this->value = $identifier; if (0 < ($i = strrpos($identifier, '\\'))) { $this->attr['ellipsis'] = strlen($identifier) - $i; } if (null !== $callable) { if ($callable instanceof \Closure) { $r = new \ReflectionFunction($callable); } elseif (is_object($callable)) { $r = new \ReflectionMethod($callable, '__invoke'); } elseif (is_array($callable)) { $r = new \ReflectionMethod($callable[0], $callable[1]); } elseif (false !== ($i = strpos($callable, '::'))) { $r = new \ReflectionMethod(substr($callable, 0, $i), substr($callable, 2 + $i)); } else { $r = new \ReflectionFunction($callable); } } elseif (false !== ($i = strpos($identifier, '::'))) { $r = new \ReflectionMethod(substr($identifier, 0, $i), substr($identifier, 2 + $i)); } else { $r = new \ReflectionClass($identifier); } if ($f = $r->getFileName()) { $this->attr['file'] = $f; $this->attr['line'] = $r->getStartLine() - substr_count($r->getDocComment(), "\n"); } }
public static function getUseStatements(\ReflectionClass $class) { $content = ''; $file = file($class->getFileName()); for ($i = 0; $i < $class->getStartLine(); $i++) { $content .= $file[$i]; } $tokenizer = new PhpTokenizer(); $tokens = $tokenizer->tokenize($content); $tokens = $tokens->filter(function ($token) { return $token->type !== T_WHITESPACE && $token->type !== T_COMMENT && $token->type !== T_DOC_COMMENT; }); $statements = []; while ($token = $tokens->next()) { if ($token->type === T_USE) { $explicitAlias = false; $alias = ''; $class = ''; while ($token = $tokens->next()) { $isNameToken = $token->type === T_STRING || $token->type === T_NS_SEPARATOR; if (!$explicitAlias && $isNameToken) { $class .= $token->contents; } else { if ($explicitAlias && $isNameToken) { $alias .= $token->contents; } else { if ($token->type === T_AS) { $explicitAlias = true; $alias = ''; } else { if ($token->contents === ',') { if ($explicitAlias) { $statements[$alias] = $class; } else { $statements[] = $class; } $class = ''; $alias = ''; $explicitAlias = false; } else { if ($token->contents === ';') { if ($explicitAlias) { $statements[$alias] = $class; } else { $statements[] = $class; } break; } else { break; } } } } } } } } return $statements; }
static function getClassSource(ReflectionClass $class) { $path = $class->getFileName(); $lines = @file($path); $from = $class->getStartLine(); $to = $class->getEndLine(); $len = $to - $from + 1; return implode(array_slice($lines, $from - 1, $len)); }
/** * Return the start line of the class * * @param bool $includeDocComment * @return int */ public function getStartLine($includeDocComment = false) { if ($includeDocComment) { if ($this->getDocComment() != '') { return $this->getDocblock()->getStartLine(); } } return parent::getStartLine(); }
public function provideControllerCallables() { // make sure we always match the line number $r1 = new \ReflectionMethod($this, 'testControllerInspection'); $r2 = new \ReflectionMethod($this, 'staticControllerMethod'); $r3 = new \ReflectionClass($this); // test name, callable, expected return array(array('"Regular" callable', array($this, 'testControllerInspection'), array('class' => __NAMESPACE__ . '\\RequestDataCollectorTest', 'method' => 'testControllerInspection', 'file' => __FILE__, 'line' => $r1->getStartLine())), array('Closure', function () { return 'foo'; }, array('class' => __NAMESPACE__ . '\\{closure}', 'method' => null, 'file' => __FILE__, 'line' => __LINE__ - 5)), array('Static callback as string', __NAMESPACE__ . '\\RequestDataCollectorTest::staticControllerMethod', array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'staticControllerMethod', 'file' => __FILE__, 'line' => $r2->getStartLine())), array('Static callable with instance', array($this, 'staticControllerMethod'), array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'staticControllerMethod', 'file' => __FILE__, 'line' => $r2->getStartLine())), array('Static callable with class name', array('Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'staticControllerMethod'), array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'staticControllerMethod', 'file' => __FILE__, 'line' => $r2->getStartLine())), array('Callable with instance depending on __call()', array($this, 'magicMethod'), array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'magicMethod', 'file' => 'n/a', 'line' => 'n/a')), array('Callable with class name depending on __callStatic()', array('Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'magicMethod'), array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'magicMethod', 'file' => 'n/a', 'line' => 'n/a')), array('Invokable controller', $this, array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => null, 'file' => __FILE__, 'line' => $r3->getStartLine()))); }
public function getCodeInClass($className) { $class = new \ReflectionClass($className); $startLine = $class->getStartLine() - 1; // getStartLine() seems to start after the {, we want to include the signature $endLine = $class->getEndLine(); $numLines = $endLine - $startLine; $namespace = $this->getNamespaceOfClass($className); $classCode = "namespace {$namespace};\n\n" . implode("\n", array_slice(explode("\n", $this->fileContent), $startLine, $numLines)) . "\n"; return $classCode; }
/** * Parse the class file and extract the use statements. * * @param string $fileName The name of the file to parse. * @return array A list with use statements or an empty array if no use statements exists. */ private function parse($fileName) { if (!$fileName) { return array(); } $content = $this->getFileContent($fileName, $this->class->getStartLine()); $namespace = str_replace('\\', '\\\\', $this->class->getNamespaceName()); $content = preg_replace('/^.*?(\\bnamespace\\s+' . $namespace . '\\s*[;|{].*)$/s', '\\1', $content); $this->tokens = token_get_all('<?php ' . $content); $this->numTokens = count($this->tokens); $statements = $this->parseUseStatements(); return $statements; }
/** * Parses a class. * * @param \ReflectionClass $class A <code>ReflectionClass</code> object. * @return array A list with use statements in the form (Alias => FQN). */ public function parseClass(\ReflectionClass $class) { if (false === ($filename = $class->getFilename())) { return array(); } $content = $this->getFileContent($filename, $class->getStartLine()); $namespace = str_replace('\\', '\\\\', $class->getNamespaceName()); $content = preg_replace('/^.*?(\\bnamespace\\s+' . $namespace . '\\s*[;{].*)$/s', '\\1', $content); $this->tokens = token_get_all('<?php ' . $content); $this->numTokens = count($this->tokens); $this->pointer = 0; $statements = $this->parseUseStatements($class->getNamespaceName()); return $statements; }
/** * @return array A list with use statements in the form (Alias => FQN). */ public function parseUseStatements(\ReflectionClass $class) { if (false === ($filename = $class->getFilename())) { return array(); } $content = $this->getFileContent($filename, $class->getStartLine()); if (null === $content) { return array(); } $namespace = preg_quote($class->getNamespaceName()); $content = preg_replace('/^.*?(\\bnamespace\\s+' . $namespace . '\\s*[;{].*)$/s', '\\1', $content); $tokenizer = new TokenParser('<?php ' . $content); $statements = $tokenizer->parseUseStatements($class->getNamespaceName()); return $statements; }
static function getClassSource(ReflectionClass $class) { // принимаем объект класса ReflectionClass $path = $class->getFileName(); // получаем путь к файлу $lines = @file($path); // получаем массив с кодом $from = $class->getStartLine(); // получаем строку где начинается нужный код $to = $class->getEndLine(); //получаем строку где заканчивается нужный код $len = $to - $from + 1; // получаем длинну return implode(array_slice($lines, $from - 1, $len)); // обрезаем массив, и переводим в строку }
/** * method for making a single file of most used doctrine runtime components * including the compiled file instead of multiple files (in worst * cases dozens of files) can improve performance by an order of magnitude * * @throws Doctrine_Compiler_Exception if something went wrong during the compile operation * @return void */ public static function compile($target = null) { $path = Doctrine::getPath(); $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::LEAVES_ONLY); foreach ($it as $file) { $e = explode('.', $file->getFileName()); // we don't want to require versioning files if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) { require_once $file->getPathName(); } } $classes = array_merge(get_declared_classes(), get_declared_interfaces()); $ret = array(); foreach ($classes as $class) { $e = explode('_', $class); if ($e[0] !== 'Doctrine') { continue; } $refl = new ReflectionClass($class); $file = $refl->getFileName(); print 'Adding ' . $file . PHP_EOL; $lines = file($file); $start = $refl->getStartLine() - 1; $end = $refl->getEndLine(); $ret = array_merge($ret, array_slice($lines, $start, $end - $start)); } if ($target == null) { $target = $path . DIRECTORY_SEPARATOR . 'Doctrine.compiled.php'; } // first write the 'compiled' data to a text file, so // that we can use php_strip_whitespace (which only works on files) $fp = @fopen($target, 'w'); if ($fp === false) { throw new Doctrine_Compiler_Exception("Couldn't write compiled data. Failed to open {$target}"); } fwrite($fp, "<?php " . implode('', $ret)); fclose($fp); $stripped = php_strip_whitespace($target); $fp = @fopen($target, 'w'); if ($fp === false) { throw new Doctrine_Compiler_Exception("Couldn't write compiled data. Failed to open {$file}"); } fwrite($fp, $stripped); fclose($fp); }
/** * Test various types of controller callables. */ public function testControllerInspection() { // make sure we always match the line number $r1 = new \ReflectionMethod($this, 'testControllerInspection'); $r2 = new \ReflectionMethod($this, 'staticControllerMethod'); $r3 = new \ReflectionClass($this); // test name, callable, expected $controllerTests = array(array('"Regular" callable', array($this, 'testControllerInspection'), array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'testControllerInspection', 'file' => __FILE__, 'line' => $r1->getStartLine())), array('Closure', function () { return 'foo'; }, array('class' => __NAMESPACE__ . '\\{closure}', 'method' => null, 'file' => __FILE__, 'line' => __LINE__ - 5)), array('Static callback as string', 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest::staticControllerMethod', 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest::staticControllerMethod'), array('Static callable with instance', array($this, 'staticControllerMethod'), array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'staticControllerMethod', 'file' => __FILE__, 'line' => $r2->getStartLine())), array('Static callable with class name', array('Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'staticControllerMethod'), array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'staticControllerMethod', 'file' => __FILE__, 'line' => $r2->getStartLine())), array('Callable with instance depending on __call()', array($this, 'magicMethod'), array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'magicMethod', 'file' => 'n/a', 'line' => 'n/a')), array('Callable with class name depending on __callStatic()', array('Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'magicMethod'), array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => 'magicMethod', 'file' => 'n/a', 'line' => 'n/a')), array('Invokable controller', $this, array('class' => 'Symfony\\Component\\HttpKernel\\Tests\\DataCollector\\RequestDataCollectorTest', 'method' => null, 'file' => __FILE__, 'line' => $r3->getStartLine()))); $c = new RequestDataCollector(); $request = $this->createRequest(); $response = $this->createResponse(); foreach ($controllerTests as $controllerTest) { $this->injectController($c, $controllerTest[1], $request); $c->collect($request, $response); $this->assertSame($controllerTest[2], $c->getController(), sprintf('Testing: %s', $controllerTest[0])); } }
protected function buildForClass($className) { $r = new \ReflectionClass($className); $file = new \SplFileObject($r->getFileName()); $classLineNumber = $r->getStartLine(); $uses = array(); for ($i = 0; $i < $classLineNumber; $i++) { $line = $file->fgets(); if (preg_match('/^\\s*use\\s([a-zA-Z_][a-zA-Z0-9_\\\\]*)(\\sas\\s([a-zA-Z_][a-zA-Z0-9_]*))?/i', $line, $match)) { $usedClassName = $match[1]; if (isset($match[3])) { $classAlias = $match[3]; } else { $explodedClassName = explode('\\', $usedClassName); $classAlias = $explodedClassName[count($explodedClassName) - 1]; } $uses[$classAlias] = $usedClassName; } } $this->uses[$className] = $uses; }
/** * Constructor. * * @param string A PHP identifier, e.g. a class, method, interface, etc. name * @param callable The callable targeted by the identifier when it is ambiguous or not a real PHP identifier */ public function __construct($identifier, $callable = null) { $this->value = $identifier; if (0 < ($i = strrpos($identifier, '\\'))) { $this->attr['ellipsis'] = strlen($identifier) - $i; } try { if (null !== $callable) { if ($callable instanceof \Closure) { $r = new \ReflectionFunction($callable); } elseif (is_object($callable)) { $r = array($callable, '__invoke'); } elseif (is_array($callable)) { $r = $callable; } elseif (false !== ($i = strpos($callable, '::'))) { $r = array(substr($callable, 0, $i), substr($callable, 2 + $i)); } else { $r = new \ReflectionFunction($callable); } } elseif (false !== ($i = strpos($identifier, '::'))) { $r = array(substr($identifier, 0, $i), substr($identifier, 2 + $i)); } else { $r = new \ReflectionClass($identifier); } if (is_array($r)) { try { $r = new \ReflectionMethod($r[0], $r[1]); } catch (\ReflectionException $e) { $r = new \ReflectionClass($r[0]); } } } catch (\ReflectionException $e) { return; } if ($f = $r->getFileName()) { $this->attr['file'] = $f; $this->attr['line'] = $r->getStartLine(); } }
function document_method($class, $methods) { $rclass = new ReflectionClass($class); $definition = implode("", array_slice(file($rclass->getFileName()), $rclass->getStartLine() - 1, 1)); $code = "\n" . $definition . "\n....\n\n"; if (!is_array($methods)) { $methods = array($methods); } foreach ($methods as $method) { $method = new ReflectionMethod($class, $method); $filename = $method->getFileName(); $start_line = $method->getStartLine() - 1; $end_line = $method->getEndLine(); $length = $end_line - $start_line; $source = file($filename); $content = implode("", array_slice($source, $start_line, $length)); $code .= $content . "\n\n"; } $code = highlight_string("<?php " . $code, true); $code = str_replace('<?php ', '', $code); return "<pre>\n" . $code . "\n</pre>"; }
/** * Loads a class and uses [reflection](http://php.net/reflection) to parse * the class. Reads the class modifiers, constants and comment. Parses the * comment to find the description and tags. * * @param string class name * @return void */ public function __construct($class) { $this->class = new ReflectionClass($class); if ($modifiers = $this->class->getModifiers()) { $this->data['modifiers'] = implode(' ', Reflection::getModifierNames($modifiers)); } $this->data['constants'] = array(); if ($constants = $this->class->getConstants()) { foreach ($constants as $name => $value) { $this->data['constants'][$name] = self::dump($value); } } $parent = $this->class; do { if ($comment = $parent->getDocComment()) { // Found a description for this class break; } } while ($parent = $parent->getParentClass()); list($description, $this->data['tags']) = self::parse($comment); $parent = $this->class; $parents = array(); while ($parent = $parent->getParentClass()) { if (substr(strtolower($parent->name), 0, 3) == 'ex_') { # 扩展类或略 continue; } $rf = new ReflectionClass($parent->name); $parents[] = array('class_name' => $parent->name, 'is_php_class' => $rf->getStartLine() ? 0 : 1); } $this->data['parents'] = $parents; $this->data['class_name'] = $this->class->getName(); $this->data['title'] = $description[0]; $this->data['is_php_class'] = $this->class->getStartLine() ? 0 : 1; $this->data['description'] = trim(implode("\n", $description)); $this->data['properties'] = $this->properties(); $this->data['methods'] = $this->methods(); $this->data['dir_type'] = _DOC_DIR_TYPE; }
protected function prepareLineForProperty() { ## get first line of the class $reflector = new ReflectionClass($this->class); $line = $reflector->getStartLine(); ## when last line is like "{}" then separate it to new line $lastline = trim($this->file[count($this->file) - 1]); if (substr($lastline, 0, 5) == "class" && substr($lastline, -1) == "}") { $lastline[strlen($lastline) - 1] = " "; $this->file[$line - 1] = $lastline; $this->file[] = ""; $this->file[] = "}"; } if (substr($lastline, -1) == "}" && substr(trim($this->file[count($this->file) - 2]), -1) == "{") { array_splice($this->file, count($this->file) - 1, 0, ''); foreach ($this->methods as $k => $m) { if ($m['line'] >= count($this->file) - 1) { $this->methods[$k]['line'] += 1; } } } return $line; }
/** * {@inheritdoc} */ public function collect(Request $request, Response $response, \Exception $exception = null) { $responseHeaders = $response->headers->all(); $cookies = array(); foreach ($response->headers->getCookies() as $cookie) { $cookies[] = $this->getCookieHeader($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); } if (count($cookies) > 0) { $responseHeaders['Set-Cookie'] = $cookies; } // attributes are serialized and as they can be anything, they need to be converted to strings. $attributes = array(); foreach ($request->attributes->all() as $key => $value) { if ('_route' === $key && is_object($value)) { $attributes[$key] = $this->varToString($value->getPath()); } elseif ('_route_params' === $key) { // we need to keep route params as an array (see getRouteParams()) foreach ($value as $k => $v) { $value[$k] = $this->varToString($v); } $attributes[$key] = $value; } else { $attributes[$key] = $this->varToString($value); } } $content = null; try { $content = $request->getContent(); } catch (\LogicException $e) { // the user already got the request content as a resource $content = false; } $sessionMetadata = array(); $sessionAttributes = array(); $flashes = array(); if ($request->hasSession()) { $session = $request->getSession(); if ($session->isStarted()) { $sessionMetadata['Created'] = date(DATE_RFC822, $session->getMetadataBag()->getCreated()); $sessionMetadata['Last used'] = date(DATE_RFC822, $session->getMetadataBag()->getLastUsed()); $sessionMetadata['Lifetime'] = $session->getMetadataBag()->getLifetime(); $sessionAttributes = $session->all(); $flashes = $session->getFlashBag()->peekAll(); } } $statusCode = $response->getStatusCode(); $this->data = array('format' => $request->getRequestFormat(), 'content' => $content, 'content_type' => $response->headers->get('Content-Type') ? $response->headers->get('Content-Type') : 'text/html', 'status_text' => isset(Response::$statusTexts[$statusCode]) ? Response::$statusTexts[$statusCode] : '', 'status_code' => $statusCode, 'request_query' => $request->query->all(), 'request_request' => $request->request->all(), 'request_headers' => $request->headers->all(), 'request_server' => $request->server->all(), 'request_cookies' => $request->cookies->all(), 'request_attributes' => $attributes, 'response_headers' => $responseHeaders, 'session_metadata' => $sessionMetadata, 'session_attributes' => $sessionAttributes, 'flashes' => $flashes, 'path_info' => $request->getPathInfo(), 'controller' => 'n/a', 'locale' => $request->getLocale()); if (isset($this->data['request_headers']['php-auth-pw'])) { $this->data['request_headers']['php-auth-pw'] = '******'; } if (isset($this->data['request_server']['PHP_AUTH_PW'])) { $this->data['request_server']['PHP_AUTH_PW'] = '******'; } if (isset($this->controllers[$request])) { $controller = $this->controllers[$request]; if (is_array($controller)) { try { $r = new \ReflectionMethod($controller[0], $controller[1]); $this->data['controller'] = array('class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0], 'method' => $controller[1], 'file' => $r->getFilename(), 'line' => $r->getStartLine()); } catch (\ReflectionException $re) { if (is_callable($controller)) { // using __call or __callStatic $this->data['controller'] = array('class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0], 'method' => $controller[1], 'file' => 'n/a', 'line' => 'n/a'); } } } elseif ($controller instanceof \Closure) { $r = new \ReflectionFunction($controller); $this->data['controller'] = array('class' => $r->getName(), 'method' => null, 'file' => $r->getFilename(), 'line' => $r->getStartLine()); } elseif (is_object($controller)) { $r = new \ReflectionClass($controller); $this->data['controller'] = array('class' => $r->getName(), 'method' => null, 'file' => $r->getFileName(), 'line' => $r->getStartLine()); } else { $this->data['controller'] = (string) $controller ?: 'n/a'; } unset($this->controllers[$request]); } }
/** * method for making a single file of most used doctrine runtime components * including the compiled file instead of multiple files (in worst * cases dozens of files) can improve performance by an order of magnitude * * @throws Doctrine_Compiler_Exception if something went wrong during the compile operation * @return $target Path the compiled file was written to */ public static function compile($target = null, $includedDrivers = array()) { if (!is_array($includedDrivers)) { $includedDrivers = array($includedDrivers); } $excludedDrivers = array(); // If we have an array of specified drivers then lets determine which drivers we should exclude if (!empty($includedDrivers)) { $drivers = array('db2', 'mssql', 'mysql', 'oracle', 'pgsql', 'sqlite'); $excludedDrivers = array_diff($drivers, $includedDrivers); } $path = Doctrine_Core::getPath(); $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path . '/Doctrine'), RecursiveIteratorIterator::LEAVES_ONLY); foreach ($it as $file) { $e = explode('.', $file->getFileName()); //@todo what is a versioning file? do we have these anymore? None //exists in my version of doctrine from svn. // we don't want to require versioning files if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false && strpos($file->getFileName(), 'sfYaml') === false) { require_once $file->getPathName(); } } $classes = array_merge(get_declared_classes(), get_declared_interfaces()); $ret = array(); foreach ($classes as $class) { $e = explode('_', $class); if ($e[0] !== 'Doctrine') { continue; } // Exclude drivers if (!empty($excludedDrivers)) { foreach ($excludedDrivers as $excludedDriver) { $excludedDriver = ucfirst($excludedDriver); if (in_array($excludedDriver, $e)) { continue 2; } } } $refl = new ReflectionClass($class); $file = $refl->getFileName(); $lines = file($file); $start = $refl->getStartLine() - 1; $end = $refl->getEndLine(); $ret = array_merge($ret, array_slice($lines, $start, $end - $start)); } if ($target == null) { $target = $path . DIRECTORY_SEPARATOR . 'Doctrine.compiled.php'; } // first write the 'compiled' data to a text file, so // that we can use php_strip_whitespace (which only works on files) $fp = @fopen($target, 'w'); if ($fp === false) { throw new Doctrine_Compiler_Exception("Couldn't write compiled data. Failed to open {$target}"); } fwrite($fp, "<?php " . implode('', $ret)); fclose($fp); $stripped = php_strip_whitespace($target); $fp = @fopen($target, 'w'); if ($fp === false) { throw new Doctrine_Compiler_Exception("Couldn't write compiled data. Failed to open {$file}"); } fwrite($fp, $stripped); fclose($fp); return $target; }
/** * Applies the @covers annotation filtering. * * @param array $data * @param mixed $id */ protected function applyCoversAnnotationFilter(&$data, $id) { if ($id instanceof PHPUnit_Framework_TestCase) { $testClassName = get_class($id); $linesToBeCovered = PHP_CodeCoverage_Util::getLinesToBeCovered($testClassName, $id->getName()); if ($this->mapTestClassNameToCoveredClassName && empty($linesToBeCovered)) { $testedClass = substr($testClassName, 0, -4); if (class_exists($testedClass)) { $class = new ReflectionClass($testedClass); $linesToBeCovered = array($class->getFileName() => range($class->getStartLine(), $class->getEndLine())); } } } else { $linesToBeCovered = array(); } if (!empty($linesToBeCovered)) { $data = array_intersect_key($data, $linesToBeCovered); foreach (array_keys($data) as $filename) { $data[$filename] = array_intersect_key($data[$filename], array_flip($linesToBeCovered[$filename])); } } else { if ($this->forceCoversAnnotation) { $data = array(); } } }
private static function dodump($value, $start = true, $key = false, $silent = false) { if ($start) { echo self::open_ul(); } if (is_array($value)) { echo self::open_li(); echo self::get_key_headline($key); echo ' '; echo self::get_item_headline($value); echo self::open_ul(); $color = self::get_random_color(); foreach ($value as $key => $val) { self::dodump($val, false, self::output($key, '<span style="color:' . $color . ';">', '</span>', false)); } echo self::close_ul(); echo self::close_li(); } elseif (is_object($value)) { echo self::open_li(); echo self::get_key_headline($key); echo self::get_item_headline($value); echo self::open_ul(); $color = self::get_random_color(); foreach ((array) $value as $key => $val) { self::dodump($val, false, self::output($key, '<span style="color:' . $color . ';">', '</span>')); } if (get_class($value) != 'stdClass') { $reflect = new ReflectionClass($value); $methods = $reflect->getMethods(); echo self::open_li() . self::output('Show class info (' . count($methods) . ' methods)', '<a href="#" onclick="var kid=this.parentNode.childNodes[1];if(kid.style.display==\'block\'){kid.style.display=\'none\';}else{kid.style.display=\'block\';};return false;">', '</a>', false); echo self::open_ul('<ul class="methods" style="display:none;">'); echo self::open_li() . self::output('Methods', '<strong>', '</strong>', false); echo self::open_ul(); foreach ($methods as $m) { echo self::open_li(); if ($m->isPrivate()) { echo self::output('private', '<span style="color:red;">', '</span> '); } if ($m->isProtected()) { echo self::output('protected', '<span style="color:blue;">', '</span> '); } if ($m->isPublic()) { echo self::output('public', '<span style="color:green;">', '</span> '); } if ($m->isStatic()) { echo self::output('static', '<em>', '</em> '); } echo $m->name . '('; $params = $m->getParameters(); $numParams = count($params); $i = 1; foreach ($params as $param) { echo '<em>' . $param->getName() . '</em>'; if ($i < $numParams) { echo ', '; } $i++; } echo ')'; echo self::close_li(); } echo self::close_ul(); echo self::close_li(); echo self::open_li() . self::output('Defined in', '<strong>', '</strong>'); echo self::open_ul(); echo self::open_li() . $reflect->getFileName() . ' at line ' . $reflect->getStartLine() . '</li>'; echo self::close_ul(); echo self::close_li(); echo self::close_ul(); echo self::close_li(); } echo self::close_ul(); echo self::close_li(); } else { echo self::open_li(); echo self::get_key_headline($key); echo self::get_item_headline($value); if (is_bool($value)) { if ($value) { echo 'true'; } else { echo 'false'; } } else { echo $value; } echo self::close_li(); } if ($start) { echo self::close_ul(); } }
{ const START = 0; private static $c = Counter::START; /** * Invoke counter * * @access public * @return int */ public function count() { return self::$c++; } } $class = new ReflectionClass('Counter'); printf("===> The %s%s%s %s '%s' [extends %s]" . " declared in %s" . " lines %d to %d" . " having the modifiers %d [%s]<br/>", $class->isInternal() ? 'internal' : 'user-defined', $class->isAbstract() ? ' abstract' : '', $class->isFinal() ? ' final' : '', $class->isInterface() ? 'interface' : 'class', $class->getName(), var_export($class->getParentClass(), 1), $class->getFileName(), $class->getStartLine(), $class->getEndline(), $class->getModifiers(), implode(' ', Reflection::getModifierNames($class->getModifiers()))); // output: ===> The user-defined class 'Counter' [extends ReflectionClass::__set_state(array( 'name' => 'Object', ))] declared in /home/cg/root/main.php lines 15 to 31 having the modifiers 524288 [] printf("===> Documentation:%s<br/>", var_export($class->getDocComment(), 1)); // output: ===> Documentation:'/** * A counter class */' printf("===> Implements:%s<br/>", var_export($class->getInterfaces(), 1)); // output: ===> Implements:array ( 'NSerializable' => ReflectionClass::__set_state(array( 'name' => 'NSerializable', )), ) printf("===> Constants: %s<br/>", var_export($class->getConstants(), 1)); // output: ===> Constants: array ( 'START' => 0, ) printf("===> Properties: %s<br/>", var_export($class->getProperties(), 1)); // output: ===> Properties: array ( 0 => ReflectionProperty::__set_state(array( 'name' => 'c', 'class' => 'Counter', )), ) printf("===> Methods: %s<br/>", var_export($class->getMethods(), 1)); // output: ===> Methods: array ( 0 => ReflectionMethod::__set_state(array( 'name' => 'count', 'class' => 'Counter', )), ) if ($class->isInstantiable()) { $counter = $class->newInstance(); echo '===> $counter is instance? '; echo $class->isInstance($counter) ? 'yes' : 'no';
protected function transformCoverageInformation($filename, $coverageInformation) { $classes = PHPUnitUtil::getDefinedClasses($filename, $this->classpath); if (is_array($classes)) { foreach ($classes as $classname) { $reflection = new ReflectionClass($classname); $methods = $reflection->getMethods(); $classElement = $this->doc->createElement('class'); $classElement->setAttribute('name', $reflection->getName()); $this->addClassToPackage($reflection->getName(), $classElement); $classStartLine = $reflection->getStartLine(); $methodscovered = 0; $methodcount = 0; // Strange PHP5 reflection bug, classes without parent class or implemented interfaces seem to start one line off if ($reflection->getParentClass() == NULL && count($reflection->getInterfaces()) == 0) { unset($coverageInformation[$classStartLine + 1]); } else { unset($coverageInformation[$classStartLine]); } reset($coverageInformation); foreach ($methods as $method) { // PHP5 reflection considers methods of a parent class to be part of a subclass, we don't if ($method->getDeclaringClass()->getName() != $reflection->getName()) { continue; } // small fix for XDEBUG_CC_UNUSED if (isset($coverageInformation[$method->getStartLine()])) { unset($coverageInformation[$method->getStartLine()]); } if (isset($coverageInformation[$method->getEndLine()])) { unset($coverageInformation[$method->getEndLine()]); } if ($method->isAbstract()) { continue; } $linenr = key($coverageInformation); while ($linenr !== null && $linenr < $method->getStartLine()) { next($coverageInformation); $linenr = key($coverageInformation); } if (current($coverageInformation) > 0 && $method->getStartLine() <= $linenr && $linenr <= $method->getEndLine()) { $methodscovered++; } $methodcount++; } $statementcount = count($coverageInformation); $statementscovered = count(array_filter($coverageInformation, array($this, 'filterCovered'))); $classElement->appendChild($this->transformSourceFile($filename, $coverageInformation, $classStartLine)); $classElement->setAttribute('methodcount', $methodcount); $classElement->setAttribute('methodscovered', $methodscovered); $classElement->setAttribute('statementcount', $statementcount); $classElement->setAttribute('statementscovered', $statementscovered); $classElement->setAttribute('totalcount', $methodcount + $statementcount); $classElement->setAttribute('totalcovered', $methodscovered + $statementscovered); } } }
/** * Calculates the coverage threshold * * @param string $filename The filename to analyse * @param array $coverageInformation Array with coverage information * @throws BuildException */ protected function calculateCoverageThreshold($filename, $coverageInformation) { $classes = PHPUnitUtil::getDefinedClasses($filename, $this->_classpath); if (is_array($classes)) { foreach ($classes as $className) { // Skip class if excluded from coverage threshold validation if ($this->_excludes !== null) { if (in_array($className, $this->_excludes->getExcludedClasses())) { continue; } } $reflection = new ReflectionClass($className); $classStartLine = $reflection->getStartLine(); // Strange PHP5 reflection bug, classes without parent class // or implemented interfaces seem to start one line off if ($reflection->getParentClass() === null && count($reflection->getInterfaces()) === 0) { unset($coverageInformation[$classStartLine + 1]); } else { unset($coverageInformation[$classStartLine]); } reset($coverageInformation); $methods = $reflection->getMethods(); foreach ($methods as $method) { // PHP5 reflection considers methods of a parent class // to be part of a subclass, we don't if ($method->getDeclaringClass()->getName() != $reflection->getName()) { continue; } // Skip method if excluded from coverage threshold validation if ($this->_excludes !== null) { $excludedMethods = $this->_excludes->getExcludedMethods(); if (isset($excludedMethods[$className])) { if (in_array($method->getName(), $excludedMethods[$className]) || in_array($method->getName() . '()', $excludedMethods[$className])) { continue; } } } $methodStartLine = $method->getStartLine(); $methodEndLine = $method->getEndLine(); // small fix for XDEBUG_CC_UNUSED if (isset($coverageInformation[$methodStartLine])) { unset($coverageInformation[$methodStartLine]); } if (isset($coverageInformation[$methodEndLine])) { unset($coverageInformation[$methodEndLine]); } if ($method->isAbstract()) { continue; } $lineNr = key($coverageInformation); while ($lineNr !== null && $lineNr < $methodStartLine) { next($coverageInformation); $lineNr = key($coverageInformation); } $methodStatementsCovered = 0; $methodStatementCount = 0; while ($lineNr !== null && $lineNr <= $methodEndLine) { $methodStatementCount++; $lineCoverageInfo = $coverageInformation[$lineNr]; // set covered when CODE is other than -1 (not executed) if ($lineCoverageInfo > 0 || $lineCoverageInfo === -2) { $methodStatementsCovered++; } next($coverageInformation); $lineNr = key($coverageInformation); } if ($methodStatementCount > 0) { $methodCoverage = $methodStatementsCovered / $methodStatementCount * 100; } else { $methodCoverage = 0; } if ($methodCoverage < $this->_perMethod && !$method->isAbstract()) { throw new BuildException('The coverage (' . round($methodCoverage, 2) . '%) ' . 'for method "' . $method->getName() . '" is lower' . ' than the specified threshold (' . $this->_perMethod . '%), see file: "' . $filename . '"'); } elseif ($methodCoverage < $this->_perMethod && $method->isAbstract() && $this->_verbose === true) { $this->log('Skipped coverage threshold for abstract method "' . $method->getName() . '"'); } // store the minimum coverage value for logging (see #466) if ($this->_minMethodCoverageFound !== null) { if ($this->_minMethodCoverageFound > $methodCoverage) { $this->_minMethodCoverageFound = $methodCoverage; } } else { $this->_minMethodCoverageFound = $methodCoverage; } } $classStatementCount = count($coverageInformation); $classStatementsCovered = count(array_filter($coverageInformation, array($this, 'filterCovered'))); if ($classStatementCount > 0) { $classCoverage = $classStatementsCovered / $classStatementCount * 100; } else { $classCoverage = 0; } if ($classCoverage < $this->_perClass && !$reflection->isAbstract()) { throw new BuildException('The coverage (' . round($classCoverage, 2) . '%) for class "' . $reflection->getName() . '" is lower than the ' . 'specified threshold (' . $this->_perClass . '%), ' . 'see file: "' . $filename . '"'); } elseif ($classCoverage < $this->_perClass && $reflection->isAbstract() && $this->_verbose === true) { $this->log('Skipped coverage threshold for abstract class "' . $reflection->getName() . '"'); } // store the minimum coverage value for logging (see #466) if ($this->_minClassCoverageFound !== null) { if ($this->_minClassCoverageFound > $classCoverage) { $this->_minClassCoverageFound = $classCoverage; } } else { $this->_minClassCoverageFound = $classCoverage; } $this->_projectStatementCount += $classStatementCount; $this->_projectStatementsCovered += $classStatementsCovered; } } }