mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-04 20:58:13 +08:00
Optimized command gen:command
.
This commit is contained in:
parent
f5033e9cc8
commit
25c4abb4cb
@ -30,7 +30,7 @@
|
|||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"doctrine/dbal": "Required to rename columns (^2.6).",
|
"doctrine/dbal": "Required to rename columns (^2.6).",
|
||||||
"nikic/php-parser": "Required to use ModelCommand (^4.1)."
|
"roave/better-reflection": "Required to use ModelCommand (^4.0)."
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
@ -11,7 +11,6 @@ declare(strict_types=1);
|
|||||||
*/
|
*/
|
||||||
namespace Hyperf\Database\Commands\Ast;
|
namespace Hyperf\Database\Commands\Ast;
|
||||||
|
|
||||||
use Barryvdh\Reflection\DocBlock;
|
|
||||||
use Hyperf\Database\Commands\ModelOption;
|
use Hyperf\Database\Commands\ModelOption;
|
||||||
use Hyperf\Database\Model\Builder;
|
use Hyperf\Database\Model\Builder;
|
||||||
use Hyperf\Database\Model\Collection;
|
use Hyperf\Database\Model\Collection;
|
||||||
@ -31,9 +30,28 @@ use Hyperf\Utils\Str;
|
|||||||
use PhpParser\Comment\Doc;
|
use PhpParser\Comment\Doc;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\NodeVisitorAbstract;
|
use PhpParser\NodeVisitorAbstract;
|
||||||
|
use Roave\BetterReflection\BetterReflection;
|
||||||
|
use Roave\BetterReflection\Reflection\ReflectionClass;
|
||||||
|
use Roave\BetterReflection\Reflection\ReflectionMethod;
|
||||||
|
use Roave\BetterReflection\Reflector\ClassReflector;
|
||||||
|
use Roave\BetterReflection\TypesFinder\FindReturnType;
|
||||||
|
|
||||||
class ModelUpdateVisitor extends NodeVisitorAbstract
|
class ModelUpdateVisitor extends NodeVisitorAbstract
|
||||||
{
|
{
|
||||||
|
const RELATION_METHODS = [
|
||||||
|
'hasMany' => HasMany::class,
|
||||||
|
'hasManyThrough' => HasManyThrough::class,
|
||||||
|
'hasOneThrough' => HasOneThrough::class,
|
||||||
|
'belongsToMany' => BelongsToMany::class,
|
||||||
|
'hasOne' => HasOne::class,
|
||||||
|
'belongsTo' => BelongsTo::class,
|
||||||
|
'morphOne' => MorphOne::class,
|
||||||
|
'morphTo' => MorphTo::class,
|
||||||
|
'morphMany' => MorphMany::class,
|
||||||
|
'morphToMany' => MorphToMany::class,
|
||||||
|
'morphedByMany' => MorphToMany::class,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
@ -59,21 +77,33 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
|||||||
*/
|
*/
|
||||||
protected $properties = [];
|
protected $properties = [];
|
||||||
|
|
||||||
public function __construct($class,$columns, ModelOption $option)
|
/**
|
||||||
|
* @deprecated v2.0
|
||||||
|
* @var ClassReflector
|
||||||
|
*/
|
||||||
|
protected static $reflector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated v2.0
|
||||||
|
* @var FindReturnType
|
||||||
|
*/
|
||||||
|
protected static $return;
|
||||||
|
|
||||||
|
public function __construct($class, $columns, ModelOption $option)
|
||||||
{
|
{
|
||||||
$this->class = $class;
|
$this->class = $class;
|
||||||
$this->columns = $columns;
|
$this->columns = $columns;
|
||||||
$this->option = $option;
|
$this->option = $option;
|
||||||
$this->getPropertiesFromMethods(new $this->class);
|
$this->initPropertiesFromMethods();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function leaveNode(Node $node)
|
public function leaveNode(Node $node)
|
||||||
{
|
{
|
||||||
switch ($node) {
|
switch ($node) {
|
||||||
case $node instanceof Node\Stmt\PropertyProperty:
|
case $node instanceof Node\Stmt\PropertyProperty:
|
||||||
if ((string)$node->name === 'fillable' && $this->option->isRefreshFillable()) {
|
if ((string) $node->name === 'fillable' && $this->option->isRefreshFillable()) {
|
||||||
$node = $this->rewriteFillable($node);
|
$node = $this->rewriteFillable($node);
|
||||||
} elseif ((string)$node->name === 'casts') {
|
} elseif ((string) $node->name === 'casts') {
|
||||||
$node = $this->rewriteCasts($node);
|
$node = $this->rewriteCasts($node);
|
||||||
}
|
}
|
||||||
return $node;
|
return $node;
|
||||||
@ -116,7 +146,7 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
|||||||
return $node;
|
return $node;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function parseProperty() :string
|
protected function parseProperty(): string
|
||||||
{
|
{
|
||||||
$doc = '/**' . PHP_EOL;
|
$doc = '/**' . PHP_EOL;
|
||||||
foreach ($this->columns as $column) {
|
foreach ($this->columns as $column) {
|
||||||
@ -124,15 +154,15 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
|||||||
$doc .= sprintf(' * @property %s $%s %s', $type, $name, $comment) . PHP_EOL;
|
$doc .= sprintf(' * @property %s $%s %s', $type, $name, $comment) . PHP_EOL;
|
||||||
}
|
}
|
||||||
foreach ($this->properties as $name => $property) {
|
foreach ($this->properties as $name => $property) {
|
||||||
if($property['read'] && $property['write']) {
|
if ($property['read'] && $property['write']) {
|
||||||
$doc .= sprintf(' * @property %s $%s', $property['type'], $name) . PHP_EOL;
|
$doc .= sprintf(' * @property %s $%s', $property['type'], $name) . PHP_EOL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if($property['read']) {
|
if ($property['read']) {
|
||||||
$doc .= sprintf(' * @property-read %s $%s', $property['type'], $name) . PHP_EOL;
|
$doc .= sprintf(' * @property-read %s $%s', $property['type'], $name) . PHP_EOL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if($property['write']) {
|
if ($property['write']) {
|
||||||
$doc .= sprintf(' * @property-write %s $%s', $property['type'], $name) . PHP_EOL;
|
$doc .= sprintf(' * @property-write %s $%s', $property['type'], $name) . PHP_EOL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -141,158 +171,81 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
|||||||
return $doc;
|
return $doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function initPropertiesFromMethods()
|
||||||
* @author Barry vd. Heuvel <barryvdh@gmail.com>
|
|
||||||
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link https://github.com/barryvdh/laravel-ide-helper
|
|
||||||
*/
|
|
||||||
protected function getPropertiesFromMethods($model)
|
|
||||||
{
|
{
|
||||||
/** @var Model $model */
|
/** @var ReflectionClass $reflection */
|
||||||
$methods = get_class_methods($model);
|
$reflection = self::getReflector()->reflect($this->class);
|
||||||
if ($methods) {
|
$methods = $reflection->getImmediateMethods();
|
||||||
sort($methods);
|
$namespace = $reflection->getDeclaringNamespaceAst();
|
||||||
foreach ($methods as $method) {
|
if (empty($methods)) {
|
||||||
if (Str::startsWith($method, 'get') && Str::endsWith(
|
return;
|
||||||
$method,
|
}
|
||||||
'Attribute'
|
|
||||||
) && $method !== 'getAttribute'
|
sort($methods);
|
||||||
|
/** @var ReflectionMethod $method */
|
||||||
|
foreach ($methods as $method) {
|
||||||
|
if (Str::startsWith($method->getName(), 'get') && Str::endsWith($method->getName(), 'Attribute')) {
|
||||||
|
// Magic get<name>Attribute
|
||||||
|
$name = Str::snake(substr($method->getName(), 3, -9));
|
||||||
|
if (! empty($name)) {
|
||||||
|
$type = self::getReturnFinder()->__invoke($method, $namespace);
|
||||||
|
$this->setProperty($name, $type, true, null);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Str::startsWith($method->getName(), 'set') && Str::endsWith($method->getName(), 'Attribute')) {
|
||||||
|
// Magic set<name>Attribute
|
||||||
|
$name = Str::snake(substr($method->getName(), 3, -9));
|
||||||
|
if (! empty($name)) {
|
||||||
|
$this->setProperty($name, null, null, true);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Str::startsWith($method->getName(), 'scope') && $method->getName() !== 'scopeQuery') {
|
||||||
|
$name = Str::camel(substr($method->getName(), 5));
|
||||||
|
if (! empty($name)) {
|
||||||
|
$args = $method->getParameters();
|
||||||
|
// Remove the first ($query) argument
|
||||||
|
array_shift($args);
|
||||||
|
$this->setMethod($name, [Builder::class, $method->getDeclaringClass()->getName()], $args);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method->getNumberOfParameters() > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = $method->getReturnStatementsAst();
|
||||||
|
// Magic Relation
|
||||||
|
if (count($return) === 1 && $return[0] instanceof Node\Stmt\Return_) {
|
||||||
|
$expr = $return[0]->expr;
|
||||||
|
if (
|
||||||
|
$expr instanceof Node\Expr\MethodCall
|
||||||
|
&& $expr->name instanceof Node\Identifier
|
||||||
|
&& is_string($expr->name->name)
|
||||||
|
&& isset($expr->args[0])
|
||||||
|
&& $expr->args[0] instanceof Node\Arg
|
||||||
) {
|
) {
|
||||||
//Magic get<name>Attribute
|
$name = $expr->name->name;
|
||||||
$name = Str::snake(substr($method, 3, -9));
|
if (array_key_exists($name, self::RELATION_METHODS)) {
|
||||||
if (!empty($name)) {
|
if ($expr->args[0]->value instanceof Node\Expr\ClassConstFetch) {
|
||||||
$reflection = new \ReflectionMethod($model, $method);
|
$related = $expr->args[0]->value->class->toCodeString();
|
||||||
$type = $this->getReturnTypeFromDocBlock($reflection);
|
} else {
|
||||||
$this->setProperty($name, $type, true, null);
|
$related = (string) ($expr->args[0]->value);
|
||||||
}
|
}
|
||||||
} 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, Builder::class .'|\\' . $reflection->class, $args);
|
|
||||||
}
|
|
||||||
} elseif (in_array($method, ['query', 'newQuery', 'newModelQuery'])) {
|
|
||||||
$reflection = new \ReflectionClass($model);
|
|
||||||
$builder = get_class($model->newModelQuery());
|
|
||||||
|
|
||||||
$this->setMethod($method, "\\{$builder}|\\" . $reflection->getName());
|
if (strpos($name, 'Many') !== false) {
|
||||||
} elseif (!method_exists(Model::class, $method)
|
// Collection or array of models (because Collection is Arrayable)
|
||||||
&& !Str::startsWith($method, 'get')
|
$this->setProperty($method->getName(), [$this->getCollectionClass($related), $related . '[]'], true);
|
||||||
) {
|
} elseif ($name === 'morphTo') {
|
||||||
//Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php
|
// Model isn't specified because relation is polymorphic
|
||||||
$reflection = new \ReflectionMethod($model, $method);
|
$this->setProperty($method->getName(), [Model::class], true);
|
||||||
|
} else {
|
||||||
if ($returnType = $reflection->getReturnType()) {
|
// Single model is returned
|
||||||
$type = $returnType instanceof \ReflectionNamedType
|
$this->setProperty($method->getName(), [$related], true);
|
||||||
? $returnType->getName()
|
|
||||||
: (string)$returnType;
|
|
||||||
} else {
|
|
||||||
// php 7.x type or fallback to docblock
|
|
||||||
$type = (string)$this->getReturnTypeFromDocBlock($reflection);
|
|
||||||
}
|
|
||||||
|
|
||||||
$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' => HasMany::class,
|
|
||||||
'hasManyThrough' => HasManyThrough::class,
|
|
||||||
'hasOneThrough' => HasOneThrough::class,
|
|
||||||
'belongsToMany' => BelongsToMany::class,
|
|
||||||
'hasOne' => HasOne::class,
|
|
||||||
'belongsTo' => BelongsTo::class,
|
|
||||||
'morphOne' => MorphOne::class,
|
|
||||||
'morphTo' => MorphTo::class,
|
|
||||||
'morphMany' => MorphMany::class,
|
|
||||||
'morphToMany' => MorphToMany::class,
|
|
||||||
'morphedByMany' => MorphToMany::class,
|
|
||||||
) as $relation => $impl) {
|
|
||||||
$search = '$this->' . $relation . '(';
|
|
||||||
if (stripos($code, $search) || $impl === (string)$type) {
|
|
||||||
//Resolve the relation's model to a Relation object.
|
|
||||||
$methodReflection = new \ReflectionMethod($model, $method);
|
|
||||||
if ($methodReflection->getNumberOfParameters()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adding constraints requires reading model properties which
|
|
||||||
// can cause errors. Since we don't need constraints we can
|
|
||||||
// disable them when we fetch the relation to avoid errors.
|
|
||||||
$relationObj = Relation::noConstraints(function () use ($model, $method) {
|
|
||||||
return $model->$method();
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($relationObj instanceof Relation) {
|
|
||||||
$relatedModel = '\\' . get_class($relationObj->getRelated());
|
|
||||||
|
|
||||||
$relations = [
|
|
||||||
'hasManyThrough',
|
|
||||||
'belongsToMany',
|
|
||||||
'hasMany',
|
|
||||||
'morphMany',
|
|
||||||
'morphToMany',
|
|
||||||
'morphedByMany',
|
|
||||||
];
|
|
||||||
if (strpos(get_class($relationObj), 'Many') !== false) {
|
|
||||||
//Collection or array of models (because Collection is Arrayable)
|
|
||||||
$this->setProperty(
|
|
||||||
$method,
|
|
||||||
$this->getCollectionClass($relatedModel) . '|' . $relatedModel . '[]',
|
|
||||||
true,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
/*
|
|
||||||
$this->setProperty(
|
|
||||||
Str::snake($method) . '_count',
|
|
||||||
'int|null',
|
|
||||||
true,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
} elseif ($relation === "morphTo") {
|
|
||||||
// Model isn't specified because relation is polymorphic
|
|
||||||
$this->setProperty(
|
|
||||||
$method,
|
|
||||||
'\\' .Model::class,
|
|
||||||
true,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
//Single model is returned
|
|
||||||
$this->setProperty(
|
|
||||||
$method,
|
|
||||||
$relatedModel,
|
|
||||||
true,
|
|
||||||
null,
|
|
||||||
'',
|
|
||||||
$this->isRelationForeignKeyNullable($relationObj)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,45 +253,20 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function setProperty(string $name, array $type = null, bool $read = null, bool $write = null, string $comment = '', bool $nullable = false)
|
||||||
* @author Barry vd. Heuvel <barryvdh@gmail.com>
|
|
||||||
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link https://github.com/barryvdh/laravel-ide-helper
|
|
||||||
*/
|
|
||||||
private function isRelationForeignKeyNullable(Relation $relation)
|
|
||||||
{
|
{
|
||||||
$reflectionObj = new \ReflectionObject($relation);
|
if (! isset($this->properties[$name])) {
|
||||||
if (!$reflectionObj->hasProperty('foreignKey')) {
|
$this->properties[$name] = [];
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$fkProp = $reflectionObj->getProperty('foreignKey');
|
|
||||||
$fkProp->setAccessible(true);
|
|
||||||
|
|
||||||
return isset($this->nullableColumns[$fkProp->getValue($relation)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Barry vd. Heuvel <barryvdh@gmail.com>
|
|
||||||
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link https://github.com/barryvdh/laravel-ide-helper
|
|
||||||
*/
|
|
||||||
protected function setProperty($name, $type = null, $read = null, $write = null, $comment = '', $nullable = false)
|
|
||||||
{
|
|
||||||
if (!isset($this->properties[$name])) {
|
|
||||||
$this->properties[$name] = array();
|
|
||||||
$this->properties[$name]['type'] = 'mixed';
|
$this->properties[$name]['type'] = 'mixed';
|
||||||
$this->properties[$name]['read'] = false;
|
$this->properties[$name]['read'] = false;
|
||||||
$this->properties[$name]['write'] = false;
|
$this->properties[$name]['write'] = false;
|
||||||
$this->properties[$name]['comment'] = (string) $comment;
|
$this->properties[$name]['comment'] = (string) $comment;
|
||||||
}
|
}
|
||||||
if ($type !== null) {
|
if ($type !== null) {
|
||||||
$newType = $this->getTypeOverride($type);
|
|
||||||
if ($nullable) {
|
if ($nullable) {
|
||||||
$newType .='|null';
|
$type[] = 'null';
|
||||||
}
|
}
|
||||||
$this->properties[$name]['type'] = $newType;
|
$this->properties[$name]['type'] = implode('|', array_unique($type));
|
||||||
}
|
}
|
||||||
if ($read !== null) {
|
if ($read !== null) {
|
||||||
$this->properties[$name]['read'] = $read;
|
$this->properties[$name]['read'] = $read;
|
||||||
@ -348,104 +276,17 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getTypeOverride($type)
|
protected function setMethod(string $name, array $type = [], array $arguments = [])
|
||||||
{
|
|
||||||
//just for compatibility
|
|
||||||
$typeOverrides = config('devtool.model.type_overrides', []);
|
|
||||||
|
|
||||||
return isset($typeOverrides[$type]) ? $typeOverrides[$type] : $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Barry vd. Heuvel <barryvdh@gmail.com>
|
|
||||||
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link https://github.com/barryvdh/laravel-ide-helper
|
|
||||||
*/
|
|
||||||
protected function setMethod($name, $type = '', $arguments = array())
|
|
||||||
{
|
{
|
||||||
$methods = array_change_key_case($this->methods, CASE_LOWER);
|
$methods = array_change_key_case($this->methods, CASE_LOWER);
|
||||||
|
|
||||||
if (!isset($methods[strtolower($name)])) {
|
if (! isset($methods[strtolower($name)])) {
|
||||||
$this->methods[$name] = array();
|
$this->methods[$name] = [];
|
||||||
$this->methods[$name]['type'] = $type;
|
$this->methods[$name]['type'] = implode('|', $type);
|
||||||
$this->methods[$name]['arguments'] = $arguments;
|
$this->methods[$name]['arguments'] = $arguments;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Barry vd. Heuvel <barryvdh@gmail.com>
|
|
||||||
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link https://github.com/barryvdh/laravel-ide-helper
|
|
||||||
*/
|
|
||||||
public function getParameters(ReflectionMethod $method)
|
|
||||||
{
|
|
||||||
//Loop through the default values for paremeters, and make the correct output string
|
|
||||||
$params = array();
|
|
||||||
$paramsWithDefault = array();
|
|
||||||
/** @var \ReflectionParameter $param */
|
|
||||||
foreach ($method->getParameters() as $param) {
|
|
||||||
$paramClass = $param->getClass();
|
|
||||||
$paramStr = (!is_null($paramClass) ? '\\' . $paramClass->getName() . ' ' : '') . '$' . $param->getName();
|
|
||||||
$params[] = $paramStr;
|
|
||||||
if ($param->isOptional() && $param->isDefaultValueAvailable()) {
|
|
||||||
$default = $param->getDefaultValue();
|
|
||||||
if (is_bool($default)) {
|
|
||||||
$default = $default ? 'true' : 'false';
|
|
||||||
} elseif (is_array($default)) {
|
|
||||||
$default = '[]';
|
|
||||||
} elseif (is_null($default)) {
|
|
||||||
$default = 'null';
|
|
||||||
} elseif (is_int($default)) {
|
|
||||||
//$default = $default;
|
|
||||||
} else {
|
|
||||||
$default = "'" . trim($default) . "'";
|
|
||||||
}
|
|
||||||
$paramStr .= " = $default";
|
|
||||||
}
|
|
||||||
$paramsWithDefault[] = $paramStr;
|
|
||||||
}
|
|
||||||
return $paramsWithDefault;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Barry vd. Heuvel <barryvdh@gmail.com>
|
|
||||||
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link https://github.com/barryvdh/laravel-ide-helper
|
|
||||||
*/
|
|
||||||
private function getCollectionClass($className)
|
|
||||||
{
|
|
||||||
// Return something in the very very unlikely scenario the model doesn't
|
|
||||||
// have a newCollection() method.
|
|
||||||
if (!method_exists($className, 'newCollection')) {
|
|
||||||
return Collection::class;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var Model $model */
|
|
||||||
$model = new $className;
|
|
||||||
return '\\' . get_class($model->newCollection());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Barry vd. Heuvel <barryvdh@gmail.com>
|
|
||||||
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link https://github.com/barryvdh/laravel-ide-helper
|
|
||||||
*/
|
|
||||||
protected function getReturnTypeFromDocBlock(\ReflectionMethod $reflection)
|
|
||||||
{
|
|
||||||
$type = null;
|
|
||||||
$phpdoc = new DocBlock($reflection);
|
|
||||||
|
|
||||||
if ($phpdoc->hasTag('return')) {
|
|
||||||
$type = $phpdoc->getTagsByName('return')[0]->getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getProperty($column): array
|
protected function getProperty($column): array
|
||||||
{
|
{
|
||||||
$name = $this->option->isCamelCase() ? Str::camel($column['column_name']) : $column['column_name'];
|
$name = $this->option->isCamelCase() ? Str::camel($column['column_name']) : $column['column_name'];
|
||||||
@ -497,4 +338,35 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
|||||||
|
|
||||||
return $cast;
|
return $cast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getCollectionClass($className): string
|
||||||
|
{
|
||||||
|
// Return something in the very very unlikely scenario the model doesn't
|
||||||
|
// have a newCollection() method.
|
||||||
|
if (! method_exists($className, 'newCollection')) {
|
||||||
|
return Collection::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var Model $model */
|
||||||
|
$model = new $className();
|
||||||
|
return '\\' . get_class($model->newCollection());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function getReturnFinder(): FindReturnType
|
||||||
|
{
|
||||||
|
if (static::$return instanceof FindReturnType) {
|
||||||
|
return static::$return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$return = new FindReturnType();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function getReflector(): ClassReflector
|
||||||
|
{
|
||||||
|
if (isset(self::$reflector)) {
|
||||||
|
return self::$reflector;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$reflector = (new BetterReflection())->classReflector();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user