private function parseMethod($class, $method) { $refl = new \ReflectionMethod($class, $method); // var_dump($refl->getFileName()); // var_dump($refl->getStartLine()); // var_dump($refl->getEndLine()); $body = trim(implode(array_slice(file($refl->getFileName()), $refl->getStartLine(), $refl->getEndLine() - $refl->getStartLine() - 1))); $spec = $this->createSpecification($body, $refl->getFileName(), $refl->getStartLine(), $refl->getEndLine()); return $spec; }
public function getMethod($filePath, $ext = '') { $fileName = dirname($filePath); $className = basename(dirname(dirname($filePath))); if (!class_exists($className)) { helper::import($fileName); } $methodName = basename($filePath); $method = new ReflectionMethod($className . $ext, $methodName); $data = new stdClass(); $data->startLine = $method->getStartLine(); $data->endLine = $method->getEndLine(); $data->comment = $method->getDocComment(); $data->parameters = $method->getParameters(); $data->className = $className; $data->methodName = $methodName; $data->fileName = $fileName; $data->post = false; $file = file($fileName); for ($i = $data->startLine - 1; $i <= $data->endLine; $i++) { if (strpos($file[$i], '$this->post') or strpos($file[$i], 'fixer::input') or strpos($file[$i], '$_POST')) { $data->post = true; } } return $data; }
/** * Process the exception. Calls the Exception::getTrace() method to * get the backtrace. Gets the relevant lines of code for each step * in the backtrace. */ public function getTrace($e) { $trace = $e->getTrace(); foreach ($trace as $i => &$entry) { if (isset($entry['class'])) { try { $refl = new ReflectionMethod($entry['class'], $entry['function']); if (isset($trace[$i - 1]) && isset($trace[$i - 1]['line'])) { $entry['caller'] = (int) $trace[$i - 1]['line'] - 1; } else { if ($i === 0) { $entry['caller'] = (int) $e->getLine() - 1; } } $start = $entry['caller'] - self::BACKTRACE_CONTEXT; if ($start < $refl->getStartLine()) { $start = $refl->getStartLine() - 1; } $end = $entry['caller'] + self::BACKTRACE_CONTEXT; if ($end > $refl->getEndLine()) { $end = $refl->getEndLine(); } $entry['source'] = $this->getSourceFromFile($refl->getFileName(), $start, $end); } catch (Exception $e) { $entry['caller'] = null; $entry['source'] = ''; } } if (isset($entry['args'])) { // Duplicate so we don't overwrite by-reference variables $args = array(); foreach ($entry['args'] as $i => $arg) { $args[$i] = gettype($arg); } $entry['args'] = $args; } } $exceptionParams = array(); if (method_exists($e, 'getParams')) { $exceptionParams = $e->getParams(); } $d = array('backtrace' => $trace, 'message' => $e->getMessage(), 'code' => $e->getCode(), 'file' => $e->getFile(), 'line' => $e->getLine(), 'name' => api_helpers_class::getBaseName($e), 'params' => $exceptionParams); if (!empty($e->userInfo)) { $d['userInfo'] = $e->userInfo; } return $d; }
/** * @param \ReflectionMethod $reflectionMethod * * @return string */ private function getCodeBody(\ReflectionMethod $reflectionMethod) { $reflectionClass = $reflectionMethod->getDeclaringClass(); $length = $reflectionMethod->getEndLine() - $reflectionMethod->getStartLine(); $lines = file($reflectionClass->getFileName()); $code = join(PHP_EOL, array_slice($lines, $reflectionMethod->getStartLine() - 1, $length + 1)); return preg_replace('/.*function[^{]+{/s', '', $code); }
/** * Returns the line this method's declaration ends at * * @return integer Line this methods's declaration ends at */ public function getEndLine() { if ($this->reflectionSource instanceof ReflectionMethod) { return $this->reflectionSource->getEndLine(); } else { return parent::getEndLine(); } }
public static function getMethodBodyAndDocComment($cls, $mtd) { $func = new \ReflectionMethod($cls, $mtd); $start_line = $func->getStartLine() + 1; $length = $func->getEndLine() - $start_line - 1; $lines = array_slice(file($func->getFileName()), $start_line, $length); return array(implode('', $lines), $func->getDocComment()); }
public function getRawBody() { $method = new \ReflectionMethod($this->testClassInstance, $this->testMethod); $start_line = $method->getStartLine() - 1; // it's actually - 1, otherwise you wont get the function() block $end_line = $method->getEndLine(); $source = file($method->getFileName()); return implode("", array_slice($source, $start_line, $end_line - $start_line)); }
static function getMethodSource(ReflectionMethod $method) { $path = $method->getFileName(); $lines = @file($path); $from = $method->getStartLine(); $to = $method->getEndLine(); $len = $to - $from + 1; return implode(array_slice($lines, $from - 1, $len)); }
/** * Get the source code for the method * * @param \ReflectionMethod $method * * @return string */ protected function _getCode(\ReflectionMethod $method) { $filename = $method->getFileName(); $start_line = $method->getStartLine() + 1; $end_line = $method->getEndLine() - 1; $length = $end_line - $start_line; $source = file($filename); return preg_replace('/^\\s{4}/m', '', implode("", array_slice($source, $start_line, $length))); }
/** * @param \ReflectionMethod $reflectionMethod * * @return string */ private function getCodeBody(\ReflectionMethod $reflectionMethod) { $endLine = $reflectionMethod->getEndLine(); $startLine = $reflectionMethod->getStartLine(); $reflectionClass = $this->getMethodOwner($reflectionMethod, $startLine, $endLine); $length = $endLine - $startLine; $lines = file(StreamWrapper::wrapPath($reflectionClass->getFileName())); $code = join(PHP_EOL, array_slice($lines, $startLine - 1, $length + 1)); return preg_replace('/.*function[^{]+{/s', '', $code); }
/** * @param ReflectionMethod $reflectionMethod * * @return string */ private function getCodeBody(\ReflectionMethod $reflectionMethod) { $reflectionClass = $reflectionMethod->getDeclaringClass(); $length = $reflectionMethod->getEndLine() - $reflectionMethod->getStartLine(); $lines = file($reflectionClass->getFileName()); if ($length == 0) { return preg_replace('/.*function.*{/', '', $lines[$reflectionMethod->getStartLine() - 1]); } return join("\n", array_slice($lines, $reflectionMethod->getStartLine(), $length)); }
function sourceMethod(\ReflectionMethod $method) { $filename = $method->getFileName(); $start_line = $method->getStartLine() - 1; // it's actually - 1, otherwise you wont get the function() block $end_line = $method->getEndLine(); $length = $end_line - $start_line; $source = file($filename); $body = implode("", array_slice($source, $start_line, $length)); return $method->getDocComment() . PHP_EOL . $body; }
public function testImplementationsAreSynchronized() { $adapterReflector = new ReflectionMethod('ehough_finder_adapter_PhpAdapter', 'searchInDirectory'); $finderReflector = new ReflectionMethod('ehough_finder_Finder', 'searchInDirectory'); $adapterSource = array_slice(file($adapterReflector->getFileName()), $adapterReflector->getStartLine() + 1, $adapterReflector->getEndLine() - $adapterReflector->getStartLine() - 1); $adapterSource = implode('', $adapterSource); $adapterSource = str_replace(array('$this->minDepth', '$this->maxDepth'), array('$minDepth', '$maxDepth'), $adapterSource); $finderSource = array_slice(file($finderReflector->getFileName()), $finderReflector->getStartLine() + 1, $finderReflector->getEndLine() - $finderReflector->getStartLine() - 1); $finderSource = implode('', $finderSource); $this->assertStringEndsWith($adapterSource, $finderSource); }
/** * @param ReflectionMethod $method * @return string */ function generateMethodArguments(ReflectionMethod $method) { if ($method->isInternal()) { // This code can`t handle constants, it replaces its with value return implode(', ', array_map(array($this, 'generateMethodArgument'), $method->getParameters())); } else { $lines = $this->getFileLines($method->getFileName()); $start_line = $method->getStartLine() - 1; $function_lines = array_slice($lines, $start_line, $method->getEndLine() - $start_line); // todo: use code beautifier? return $this->parseFunctionArgs(implode(PHP_EOL, $function_lines)); } }
/** * Called by the DebugBar when data needs to be collected * @return array Collected data */ function collect() { $dispatcher = $this->di['dispatcher']; $router = $this->di['router']; $route = $router->getMatchedRoute(); if (!$route) { return array(); } $uri = $route->getPattern(); $paths = $route->getPaths(); $result['uri'] = $uri ?: '-'; $result['paths'] = $this->formatVar($paths); if ($params = $router->getParams()) { $result['params'] = $this->formatVar($params); } $result['HttpMethods'] = $route->getHttpMethods(); $result['RouteName'] = $route->getName(); $result['hostname'] = $route->getHostname(); if ($this->di->has('app') && ($app = $this->di['app']) instanceof Micro) { if (($handler = $app->getActiveHandler()) instanceof \Closure || is_string($handler)) { $reflector = new \ReflectionFunction($handler); } elseif (is_array($handler)) { $reflector = new \ReflectionMethod($handler[0], $handler[1]); } } else { $result['Moudle'] = $router->getModuleName(); $result['Controller'] = get_class($controller_instance = $dispatcher->getActiveController()); $result['Action'] = $dispatcher->getActiveMethod(); $reflector = new \ReflectionMethod($controller_instance, $result['Action']); } if (isset($reflector)) { $start = $reflector->getStartLine() - 1; $stop = $reflector->getEndLine(); $filename = substr($reflector->getFileName(), mb_strlen(realpath(dirname($_SERVER['DOCUMENT_ROOT'])))); $code = array_slice(file($reflector->getFileName()), $start, $stop - $start); $result['file'] = $filename . ':' . $reflector->getStartLine() . '-' . $reflector->getEndLine() . " [CODE]: \n" . implode("", $code); } return array_filter($result); }
function reflectMethod($class, $method) { $methodInfo = new ReflectionMethod($class, $method); echo "**********************************\n"; echo "Reflecting on method {$class}::{$method}()\n\n"; echo "\ngetFileName():\n"; var_dump($methodInfo->getFileName()); echo "\ngetStartLine():\n"; var_dump($methodInfo->getStartLine()); echo "\ngetEndLine():\n"; var_dump($methodInfo->getEndLine()); echo "\n**********************************\n"; }
protected function _getMethodSource($fileSource) { $className = $this->_findDefinedClasses(); //find method name to copy $matches = []; preg_match_all('/function(.*?)\\(/', $this->file->current(), $matches); $fnName = trim($matches[1][0]); $rc = new \ReflectionMethod($className, $fnName); //zero-indexed start line of function $startLine = $rc->getStartLine() - 1; $endLine = $rc->getEndLine(); $length = $endLine - $startLine; return implode("", array_slice($fileSource, $startLine, $length)); }
protected function getOriginalBody(\ReflectionMethod $originalMethod) { $lines = array_slice(file($originalMethod->getDeclaringClass()->getFileName(), FILE_IGNORE_NEW_LINES), $originalMethod->getStartLine(), $originalMethod->getEndLine() - $originalMethod->getStartLine(), true); $firstLine = array_shift($lines); if (trim($firstLine) !== '{') { array_unshift($lines, $firstLine); } $lastLine = array_pop($lines); if (trim($lastLine) !== '}') { array_push($lines, $lastLine); } $body = rtrim(ltrim(implode("\n", $lines), '{'), '}'); return $body; }
static function getMethodSource(ReflectionMethod $method) { // принимаем объект класса ReflectionMethod $path = $method->getFileName(); // получаем путь к файлу $lines = @file($path); // получаем массив с кодом $from = $method->getStartLine(); // получаем строку где начинается нужный код $to = $method->getEndLine(); //получаем строку где заканчивается нужный код $len = $to - $from + 1; // получаем длинну return implode(array_slice($lines, $from - 1, $len)); // обрезаем массив, и переводим в строку }
/** * @return string */ public function getCode() { // Getting class code $class_code = explode(PHP_EOL, $this->getOriginalClass()->getCode()); // Getting start and end lines $start_line = $this->reflector->getStartLine(); $end_line = $this->reflector->getEndLine(); $method_code = ""; for ($line = $start_line; $line <= $end_line; $line++) { if (trim($class_code[$line - 1]) === "") { continue; } $method_code .= $class_code[$line - 1] . PHP_EOL; } return rtrim($method_code); }
/** * Displays the source code of the given action name. * * @param string $actionName Name of the controller's action method. */ public function doDebugViewAction($actionName) { if (RPG::config('debug') === true and strpos($actionName, 'do') === 0) { $method = new ReflectionMethod($this, $actionName); $out = '<h2>' . $method->getDeclaringClass()->getName() . "::{$actionName}()</h2>\n" . '<a href="' . RPG::url('*/debug-list-actions') . '">« Action List</a><br /><br />'; $start = $method->getStartLine() - 1; $end = $method->getEndLine(); $file = file($method->getFileName()); $lines = array_slice($file, $start, $end - $start); $out .= "<pre>\n " . str_replace("\t", ' ', $method->getDocComment()) . "\n"; foreach ($lines as $line) { $out .= htmlentities(str_replace("\t", ' ', $line)); } $out .= '</pre>'; RPG::view()->setLayout('layouts/empty.php')->setContent($out); } }
public function getRankCodeAction() { try { $scoreMethod = new \ReflectionMethod('Application\\S2bBundle\\Entity\\Repo', 'recalculateScore'); $scoreMethodDefinition = $scoreMethod->getDocComment() . "\n"; $contents = file($scoreMethod->getDeclaringClass()->getFileName()); for ($i = $scoreMethod->getStartLine() - 1; $i < $scoreMethod->getEndLine(); $i++) { $scoreMethodDefinition .= $contents[$i]; } } catch (Exception $e) { $scoreMethodDefinition = ''; } $response = $this->createResponse($scoreMethodDefinition); // TODO: how could we ensure the cache is cleared if the code changes? $response->setTtl(3600); return $response; }
public function __construct($class, $method) { $method = new ReflectionMethod($class, $method); $this->name = $method->name; $class = $parent = $method->getDeclaringClass(); if ($modifiers = $method->getModifiers()) { $this->modifiers = '<small>' . implode(' ', Reflection::getModifierNames($modifiers)) . '</small> '; } $comment = ''; do { if ($parent->hasMethod($this->name)) { $comment = $parent->getMethod($this->name)->getDocComment(); // Found a description for this method break; } } while ($parent = $parent->getParentClass()); list($this->description, $tags) = Kodoc::parse($comment); if ($file = $class->getFileName()) { $this->source = Kodoc::source($file, $method->getStartLine(), $method->getEndLine()); } if (isset($tags['param'])) { $params = array(); foreach ($method->getParameters() as $i => $param) { $param = new Kodoc_Method_Param(array($method->class, $method->name), $i); if (isset($tags['param'][$i])) { if (preg_match('/^(\\S*)\\s*(\\$\\w+)?(?:\\s*(.+?))?$/', $tags['param'][$i], $matches)) { $param->type = $matches[1]; $param->description = arr::get($matches, 3); } } $params[] = $param; } $this->params = $params; unset($tags['param']); } if (isset($tags['return'])) { foreach ($tags['return'] as $return) { if (preg_match('/^(\\S*)(?:\\s*(.+?))?$/', $return, $matches)) { $this->return[] = array($matches[1], isset($matches[2]) ? $matches[2] : ''); } } unset($tags['return']); } $this->tags = $tags; }
/** * @param $methodName * * @return array|string */ protected function getMethodCode($methodName) { $method = is_a($methodName, '\\ReflectionMethod') ? $methodName : new \ReflectionMethod($this->targetClass, $methodName); $declaringClass = $method->getDeclaringClass(); $notTargetClass = $declaringClass->name != $this->targetClass; if ($notTargetClass) { $method = new \ReflectionMethod($declaringClass->name, $methodName); $contents = file_get_contents($method->getFileName()); } else { $contents = $this->contents; } $startLine = $method->getStartLine(); $endLine = $method->getEndLine(); $classAliases = []; $lines = explode(PHP_EOL, $contents); foreach ($lines as $line) { $frags = explode(' ', $line); if (!empty($frags) && $frags[0] == 'use') { $fullClassName = $frags[1]; // use Acme\Class as Alias if (count($frags) > 2) { $alias = $frags[3]; } else { if (strpos($frags[1], '\\')) { $classNameFrags = explode('\\', $frags[1]); $alias = array_pop($classNameFrags); } else { $alias = $frags[1]; } } $alias = trim($alias, ';'); $classAliases[$alias] = trim($fullClassName, ';'); } } $lines = array_map(function ($line) use($classAliases) { foreach ($classAliases as $classAlias => $fullClassName) { $line = str_replace($classAlias, $fullClassName, $line); } return trim($line); }, $lines); $code = array_splice($lines, $startLine - 1, $endLine - $startLine + 1); $code[0] = preg_replace('/\\s*abstract\\s*/', '', $code[0]); $code = implode(" ", $code); return $code; }
/** * Returns signature for the method * * @param \ReflectionMethod $method * @return string */ protected function getSignature(\ReflectionMethod $method) { $startLine = $method->getStartLine(); $endLine = $method->getEndLine(); $lines = $endLine - $startLine + 1; $strMethod = ''; $file = new \SplFileObject($method->getFileName()); $file->seek($startLine - 2); while ($lines) { $strMethod .= $file->fgets(); $lines--; } $signature = ''; if (preg_match('#^(.*\\))\\s*{#sU', $strMethod, $m)) { $signature = $m[1]; } // do not cut static keyword $signature = trim(preg_replace('#^\\s*public\\s+(static\\s+)?function\\s+#', '$1', $signature)); // replace first indent in multiline signature $signature = preg_replace('#^ {4}#m', '', $signature); return $signature; }
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>"; }
/** * Checks if the method is a short identifier getter. * * What does this mean? For proxy objects the identifier is already known, * however accessing the getter for this identifier usually triggers the * lazy loading, leading to a query that may not be necessary if only the * ID is interesting for the userland code (for example in views that * generate links to the entity, but do not display anything else). * * @param \ReflectionMethod $method * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class * * @return boolean */ private function isShortIdentifierGetter($method, ClassMetadata $class) { $identifier = lcfirst(substr($method->getName(), 3)); $startLine = $method->getStartLine(); $endLine = $method->getEndLine(); $cheapCheck = $method->getNumberOfParameters() == 0 && substr($method->getName(), 0, 3) == 'get' && in_array($identifier, $class->getIdentifier(), true) && $class->hasField($identifier) && $endLine - $startLine <= 4; if ($cheapCheck) { $code = file($method->getDeclaringClass()->getFileName()); $code = trim(implode(' ', array_slice($code, $startLine - 1, $endLine - $startLine + 1))); $pattern = sprintf(self::PATTERN_MATCH_ID_METHOD, $method->getName(), $identifier); if (preg_match($pattern, $code)) { return true; } } return false; }
/** * Check if the method is a short identifier getter. * * What does this mean? For proxy objects the identifier is already known, * however accessing the getter for this identifier usually triggers the * lazy loading, leading to a query that may not be necessary if only the * ID is interesting for the userland code (for example in views that * generate links to the entity, but do not display anything else). * * @param ReflectionMethod $method * @param ClassMetadata $class * @return bool */ private function isShortIdentifierGetter($method, ClassMetadata $class) { $identifier = lcfirst(substr($method->getName(), 3)); $cheapCheck = $method->getNumberOfParameters() == 0 && substr($method->getName(), 0, 3) == "get" && in_array($identifier, $class->identifier, true) && $class->hasField($identifier) && $method->getEndLine() - $method->getStartLine() <= 4 && in_array($class->fieldMappings[$identifier]['type'], array('integer', 'bigint', 'smallint', 'string')); if ($cheapCheck) { $code = file($method->getDeclaringClass()->getFileName()); $code = trim(implode(" ", array_slice($code, $method->getStartLine() - 1, $method->getEndLine() - $method->getStartLine() + 1))); $pattern = sprintf(self::PATTERN_MATCH_ID_METHOD, $method->getName(), $identifier); if (preg_match($pattern, $code)) { return true; } } return false; }
/** * @param \Illuminate\Database\Eloquent\Model $model */ protected function getPropertiesFromMethods($model) { $methods = get_class_methods($model); if ($methods) { foreach ($methods as $method) { if (Str::startsWith($method, 'get') && Str::endsWith($method, 'Attribute') && $method !== 'getAttribute') { //Magic get<name>Attribute $name = Str::snake(substr($method, 3, -9)); if (!empty($name)) { $this->setProperty($name, null, true, null); } } elseif (Str::startsWith($method, 'set') && Str::endsWith($method, 'Attribute') && $method !== 'setAttribute') { //Magic set<name>Attribute $name = Str::snake(substr($method, 3, -9)); if (!empty($name)) { $this->setProperty($name, null, null, true); } } elseif (Str::startsWith($method, 'scope') && $method !== 'scopeQuery') { //Magic set<name>Attribute $name = Str::camel(substr($method, 5)); if (!empty($name)) { $reflection = new \ReflectionMethod($model, $method); $args = $this->getParameters($reflection); //Remove the first ($query) argument array_shift($args); $this->setMethod($name, '\\Illuminate\\Database\\Query\\Builder|\\' . $reflection->class, $args); } } elseif (!method_exists('Eloquent', $method) && !Str::startsWith($method, 'get')) { //Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php $reflection = new \ReflectionMethod($model, $method); $file = new \SplFileObject($reflection->getFileName()); $file->seek($reflection->getStartLine() - 1); $code = ''; while ($file->key() < $reflection->getEndLine()) { $code .= $file->current(); $file->next(); } $begin = strpos($code, 'function('); $code = substr($code, $begin, strrpos($code, '}') - $begin + 1); foreach (array('hasMany', 'belongsToMany', 'hasOne', 'belongsTo', 'morphTo', 'morphMany', 'morphToMany') as $relation) { $search = '$this->' . $relation . '('; if ($pos = stripos($code, $search)) { $code = substr($code, $pos + strlen($search)); $arguments = explode(',', substr($code, 0, strpos($code, ')'))); //Remove quotes, ensure 1 \ in front of the model $returnModel = $this->getClassName($arguments[0], $model); if ($relation === "belongsToMany" or $relation === 'hasMany' or $relation === 'morphMany' or $relation === 'morphToMany') { //Collection or array of models (because Collection is Arrayable) $this->setProperty($method, '\\Illuminate\\Database\\Eloquent\\Collection|' . $returnModel . '[]', true, null); } else { //Single model is returned $this->setProperty($method, $returnModel, true, null); } } } } } } }
/** * @param \Illuminate\Database\Eloquent\Model $model */ protected function getPropertiesFromMethods($model) { $methods = get_class_methods($model); if ($methods) { foreach ($methods as $method) { if (Str::startsWith($method, 'get') && Str::endsWith($method, 'Attribute') && $method !== 'getAttribute') { //Magic get<name>Attribute $name = Str::snake(substr($method, 3, -9)); if (!empty($name)) { $this->setProperty($name, null, true, null); } } elseif (Str::startsWith($method, 'set') && Str::endsWith($method, 'Attribute') && $method !== 'setAttribute') { //Magic set<name>Attribute $name = Str::snake(substr($method, 3, -9)); if (!empty($name)) { $this->setProperty($name, null, null, true); } } elseif (Str::startsWith($method, 'scope') && $method !== 'scopeQuery') { //Magic set<name>Attribute $name = Str::camel(substr($method, 5)); if (!empty($name)) { $reflection = new \ReflectionMethod($model, $method); $args = $this->getParameters($reflection); //Remove the first ($query) argument array_shift($args); $this->setMethod($name, '\\Illuminate\\Database\\Query\\Builder|\\' . $reflection->class, $args); } } elseif (!method_exists('Illuminate\\Database\\Eloquent\\Model', $method) && !Str::startsWith($method, 'get')) { //Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php $reflection = new \ReflectionMethod($model, $method); $file = new \SplFileObject($reflection->getFileName()); $file->seek($reflection->getStartLine() - 1); $code = ''; while ($file->key() < $reflection->getEndLine()) { $code .= $file->current(); $file->next(); } $code = trim(preg_replace('/\\s\\s+/', '', $code)); $begin = strpos($code, 'function('); $code = substr($code, $begin, strrpos($code, '}') - $begin + 1); foreach (array('hasMany', 'hasManyThrough', 'belongsToMany', 'hasOne', 'belongsTo', 'morphOne', 'morphTo', 'morphMany', 'morphToMany') as $relation) { $search = '$this->' . $relation . '('; if ($pos = stripos($code, $search)) { //Resolve the relation's model to a Relation object. $relationObj = $model->{$method}(); if ($relationObj instanceof Relation) { $relatedModel = '\\' . get_class($relationObj->getRelated()); $relations = ['hasManyThrough', 'belongsToMany', 'hasMany', 'morphMany', 'morphToMany']; if (in_array($relation, $relations)) { //Collection or array of models (because Collection is Arrayable) $this->setProperty($method, $this->getCollectionClass($relatedModel) . '|' . $relatedModel . '[]', true, null); } elseif ($relation === "morphTo") { // Model isn't specified because relation is polymorphic $this->setProperty($method, '\\Illuminate\\Database\\Eloquent\\Model|\\Eloquent', true, null); } else { //Single model is returned $this->setProperty($method, $relatedModel, true, null); } } } } } } } }