mirror of
https://github.com/barryvdh/laravel-ide-helper.git
synced 2026-08-20 11:03:09 +00:00
Merge branch 'barry-backport' into @fix/collection-with-template-types
This commit is contained in:
+2
-2
@@ -329,7 +329,7 @@ class Alias
|
||||
continue;
|
||||
}
|
||||
$method = new \ReflectionMethod($className, $name);
|
||||
$class = new \ReflectionClass($className);
|
||||
$class = new ReflectionClass($className);
|
||||
|
||||
if (!in_array($magic, $this->usedMethods)) {
|
||||
if ($class !== $this->root) {
|
||||
@@ -348,7 +348,7 @@ class Alias
|
||||
protected function detectMethods()
|
||||
{
|
||||
foreach ($this->classes as $class) {
|
||||
$reflection = new \ReflectionClass($class);
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
$methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
|
||||
if ($methods) {
|
||||
|
||||
@@ -42,7 +42,7 @@ class GeneratorCommand extends Command
|
||||
/** @var \Illuminate\Config\Repository */
|
||||
protected $config;
|
||||
|
||||
/** @var \Illuminate\Filesystem\Filesystem */
|
||||
/** @var Filesystem */
|
||||
protected $files;
|
||||
|
||||
/** @var \Illuminate\View\Factory */
|
||||
@@ -54,7 +54,7 @@ class GeneratorCommand extends Command
|
||||
/**
|
||||
*
|
||||
* @param \Illuminate\Config\Repository $config
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @param Filesystem $files
|
||||
* @param \Illuminate\View\Factory $view
|
||||
*/
|
||||
public function __construct(
|
||||
|
||||
+120
-149
@@ -18,12 +18,12 @@ use Barryvdh\Reflection\DocBlock\Context;
|
||||
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
|
||||
use Barryvdh\Reflection\DocBlock\Tag;
|
||||
use Composer\ClassMapGenerator\ClassMapGenerator;
|
||||
use Doctrine\DBAL\Exception as DBALException;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;
|
||||
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
|
||||
use Illuminate\Database\Eloquent\Casts\AsCollection;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@@ -38,7 +38,9 @@ use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use Illuminate\Database\Schema\Builder;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
use phpDocumentor\Reflection\Types\ContextFactory;
|
||||
@@ -104,7 +106,6 @@ class ModelsCommand extends Command
|
||||
protected $write_mixin = false;
|
||||
protected $dirs = [];
|
||||
protected $reset;
|
||||
protected $keep_text;
|
||||
protected $phpstorm_noinspections;
|
||||
protected $write_model_external_builder_methods;
|
||||
/**
|
||||
@@ -152,9 +153,6 @@ class ModelsCommand extends Command
|
||||
$ignore = $this->option('ignore');
|
||||
$this->reset = $this->option('reset');
|
||||
$this->phpstorm_noinspections = $this->option('phpstorm-noinspections');
|
||||
if ($this->option('smart-reset')) {
|
||||
$this->keep_text = $this->reset = true;
|
||||
}
|
||||
$this->write_model_magic_where = $this->laravel['config']->get('ide-helper.write_model_magic_where', true);
|
||||
$this->write_model_external_builder_methods = $this->laravel['config']->get('ide-helper.write_model_external_builder_methods', true);
|
||||
$this->write_model_relation_count_properties =
|
||||
@@ -211,7 +209,7 @@ class ModelsCommand extends Command
|
||||
return [
|
||||
['filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file'],
|
||||
['dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
|
||||
'The model dir, supports glob patterns', [],],
|
||||
'The model dir, supports glob patterns', [], ],
|
||||
['write', 'W', InputOption::VALUE_NONE, 'Write to Model file'],
|
||||
['write-mixin', 'M', InputOption::VALUE_NONE,
|
||||
"Write models to {$this->filename} and adds @mixin to each model, avoiding IDE duplicate declaration warnings",
|
||||
@@ -242,8 +240,6 @@ class ModelsCommand extends Command
|
||||
*/
|
||||
\n\n";
|
||||
|
||||
$hasDoctrine = interface_exists('Doctrine\DBAL\Driver');
|
||||
|
||||
if (empty($loadModels)) {
|
||||
$models = $this->loadModels();
|
||||
} else {
|
||||
@@ -267,6 +263,7 @@ class ModelsCommand extends Command
|
||||
}
|
||||
$this->properties = [];
|
||||
$this->methods = [];
|
||||
$this->foreignKeyConstraintsColumns = [];
|
||||
if (class_exists($name)) {
|
||||
try {
|
||||
// handle abstract classes, interfaces, ...
|
||||
@@ -285,9 +282,7 @@ class ModelsCommand extends Command
|
||||
|
||||
$model = $this->laravel->make($name);
|
||||
|
||||
if ($hasDoctrine) {
|
||||
$this->getPropertiesFromTable($model);
|
||||
}
|
||||
$this->getPropertiesFromTable($model);
|
||||
|
||||
if (method_exists($model, 'getCasts')) {
|
||||
$this->castPropertiesType($model);
|
||||
@@ -311,13 +306,6 @@ class ModelsCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasDoctrine) {
|
||||
$this->error(
|
||||
'Warning: `"doctrine/dbal": "~2.3"` is required to load database information. ' .
|
||||
'Please require that in your composer.json and run `composer update`.'
|
||||
);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
@@ -355,7 +343,7 @@ class ModelsCommand extends Command
|
||||
/**
|
||||
* cast the properties's type from $casts.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param Model $model
|
||||
*/
|
||||
public function castPropertiesType($model)
|
||||
{
|
||||
@@ -387,7 +375,7 @@ class ModelsCommand extends Command
|
||||
break;
|
||||
case 'boolean':
|
||||
case 'bool':
|
||||
$realType = 'boolean';
|
||||
$realType = 'bool';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'string':
|
||||
@@ -403,7 +391,7 @@ class ModelsCommand extends Command
|
||||
case 'int':
|
||||
case 'integer':
|
||||
case 'timestamp':
|
||||
$realType = 'integer';
|
||||
$realType = 'int';
|
||||
break;
|
||||
case 'real':
|
||||
case 'double':
|
||||
@@ -418,9 +406,13 @@ class ModelsCommand extends Command
|
||||
case 'immutable_datetime':
|
||||
$realType = '\Carbon\CarbonImmutable';
|
||||
break;
|
||||
case AsCollection::class:
|
||||
case 'collection':
|
||||
$realType = '\Illuminate\Support\Collection';
|
||||
break;
|
||||
case AsArrayObject::class:
|
||||
$realType = '\ArrayObject';
|
||||
break;
|
||||
default:
|
||||
// In case of an optional custom cast parameter , only evaluate
|
||||
// the `$type` until the `:`
|
||||
@@ -499,33 +491,16 @@ class ModelsCommand extends Command
|
||||
/**
|
||||
* Load the properties from the database table.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param Model $model
|
||||
*
|
||||
* @throws DBALException If custom field failed to register
|
||||
*/
|
||||
public function getPropertiesFromTable($model)
|
||||
{
|
||||
$database = $model->getConnection()->getDatabaseName();
|
||||
$table = $model->getConnection()->getTablePrefix() . $model->getTable();
|
||||
$schema = $model->getConnection()->getDoctrineSchemaManager();
|
||||
$databasePlatform = $schema->getDatabasePlatform();
|
||||
$databasePlatform->registerDoctrineTypeMapping('enum', 'string');
|
||||
$table = $model->getTable();
|
||||
$schema = $model->getConnection()->getSchemaBuilder();
|
||||
$columns = $schema->getColumns($table);
|
||||
$driverName = $model->getConnection()->getDriverName();
|
||||
|
||||
$platformName = $databasePlatform->getName();
|
||||
$customTypes = $this->laravel['config']->get("ide-helper.custom_db_types.{$platformName}", []);
|
||||
foreach ($customTypes as $yourTypeName => $doctrineTypeName) {
|
||||
try {
|
||||
if (!Type::hasType($yourTypeName)) {
|
||||
Type::addType($yourTypeName, get_class(Type::getType($doctrineTypeName)));
|
||||
}
|
||||
} catch (DBALException $exception) {
|
||||
$this->error("Failed registering custom db type \"$yourTypeName\" as \"$doctrineTypeName\"");
|
||||
throw $exception;
|
||||
}
|
||||
$databasePlatform->registerDoctrineTypeMapping($yourTypeName, $doctrineTypeName);
|
||||
}
|
||||
|
||||
$columns = $schema->listTableColumns($table, $database);
|
||||
|
||||
if (!$columns) {
|
||||
return;
|
||||
@@ -533,49 +508,28 @@ class ModelsCommand extends Command
|
||||
|
||||
$this->setForeignKeys($schema, $table);
|
||||
foreach ($columns as $column) {
|
||||
$name = $column->getName();
|
||||
$name = $column['name'];
|
||||
if (in_array($name, $model->getDates())) {
|
||||
$type = $this->dateClass;
|
||||
} else {
|
||||
$type = $column->getType()->getName();
|
||||
switch ($type) {
|
||||
case 'string':
|
||||
case 'text':
|
||||
case 'date':
|
||||
case 'time':
|
||||
case 'guid':
|
||||
case 'datetimetz':
|
||||
case 'datetime':
|
||||
case 'decimal':
|
||||
$type = 'string';
|
||||
break;
|
||||
case 'integer':
|
||||
case 'bigint':
|
||||
case 'smallint':
|
||||
$type = 'integer';
|
||||
break;
|
||||
case 'boolean':
|
||||
switch ($platformName) {
|
||||
case 'sqlite':
|
||||
case 'mysql':
|
||||
$type = 'integer';
|
||||
break;
|
||||
default:
|
||||
$type = 'boolean';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'float':
|
||||
$type = 'float';
|
||||
break;
|
||||
default:
|
||||
$type = 'mixed';
|
||||
break;
|
||||
}
|
||||
// Match types to php equivalent
|
||||
$type = match ($column['type_name']) {
|
||||
'tinyint', 'bit',
|
||||
'integer', 'int', 'int4',
|
||||
'smallint', 'int2',
|
||||
'mediumint',
|
||||
'bigint', 'int8' => 'int',
|
||||
|
||||
'boolean', 'bool' => 'bool',
|
||||
|
||||
'float', 'real', 'float4',
|
||||
'double', 'float8' => 'float',
|
||||
|
||||
default => 'string',
|
||||
};
|
||||
}
|
||||
|
||||
$comment = $column->getComment();
|
||||
if (!$column->getNotnull()) {
|
||||
if ($column['nullable']) {
|
||||
$this->nullableColumns[$name] = true;
|
||||
}
|
||||
$this->setProperty(
|
||||
@@ -583,8 +537,8 @@ class ModelsCommand extends Command
|
||||
$this->getTypeInModel($model, $type),
|
||||
true,
|
||||
true,
|
||||
$comment,
|
||||
!$column->getNotnull()
|
||||
$column['comment'],
|
||||
$column['nullable']
|
||||
);
|
||||
if ($this->write_model_magic_where) {
|
||||
$builderClass = $this->write_model_external_builder_methods
|
||||
@@ -603,7 +557,7 @@ class ModelsCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param Model $model
|
||||
*/
|
||||
public function getPropertiesFromMethods($model)
|
||||
{
|
||||
@@ -614,10 +568,7 @@ class ModelsCommand extends Command
|
||||
// methods that resemble mutators but aren't.
|
||||
$reflections = array_filter($reflections, function (\ReflectionMethod $methodReflection) {
|
||||
return !$methodReflection->isPrivate() && !(
|
||||
in_array(
|
||||
\Illuminate\Database\Eloquent\Concerns\HasAttributes::class,
|
||||
$methodReflection->getDeclaringClass()->getTraitNames()
|
||||
) && (
|
||||
$methodReflection->getDeclaringClass()->getName() === Model::class && (
|
||||
$methodReflection->getName() === 'setClassCastableAttribute' ||
|
||||
$methodReflection->getName() === 'setEnumCastableAttribute'
|
||||
)
|
||||
@@ -643,18 +594,15 @@ class ModelsCommand extends Command
|
||||
$this->setProperty($name, $type, true, null, $comment);
|
||||
}
|
||||
} elseif ($isAttribute) {
|
||||
$name = Str::snake($method);
|
||||
$types = $this->getAttributeReturnType($model, $reflection);
|
||||
$comment = $this->getCommentFromDocBlock($reflection);
|
||||
|
||||
if ($types->has('get')) {
|
||||
$type = $this->getTypeInModel($model, $types['get']);
|
||||
$this->setProperty($name, $type, true, null, $comment);
|
||||
}
|
||||
|
||||
if ($types->has('set')) {
|
||||
$this->setProperty($name, null, null, true, $comment);
|
||||
}
|
||||
$types = $this->getAttributeTypes($model, $reflection);
|
||||
$type = $this->getTypeInModel($model, $types->get('get') ?: $types->get('set')) ?: null;
|
||||
$this->setProperty(
|
||||
Str::snake($method),
|
||||
$type,
|
||||
$types->has('get'),
|
||||
$types->has('set'),
|
||||
$this->getCommentFromDocBlock($reflection)
|
||||
);
|
||||
} elseif (
|
||||
Str::startsWith($method, 'set') && Str::endsWith(
|
||||
$method,
|
||||
@@ -667,7 +615,7 @@ class ModelsCommand extends Command
|
||||
$comment = $this->getCommentFromDocBlock($reflection);
|
||||
$this->setProperty($name, null, null, true, $comment);
|
||||
}
|
||||
} elseif (Str::startsWith($method, 'scope') && $method !== 'scopeQuery') {
|
||||
} elseif (Str::startsWith($method, 'scope') && $method !== 'scopeQuery' && $method !== 'scope' && $method !== 'scopes') {
|
||||
//Magic set<name>Attribute
|
||||
$name = Str::camel(substr($method, 5));
|
||||
if (!empty($name)) {
|
||||
@@ -753,9 +701,14 @@ class ModelsCommand extends Command
|
||||
get_class($relationObj->getRelated())
|
||||
);
|
||||
|
||||
$relationReturnType = $this->getRelationReturnTypes()[$relation] ?? false;
|
||||
|
||||
if (
|
||||
strpos(get_class($relationObj), 'Many') !== false ||
|
||||
($this->getRelationReturnTypes()[$relation] ?? '') === 'many'
|
||||
$relationReturnType === 'many' ||
|
||||
(
|
||||
!$relationReturnType &&
|
||||
strpos(get_class($relationObj), 'Many') !== false
|
||||
)
|
||||
) {
|
||||
//Collection or array of models (because Collection is Arrayable)
|
||||
$relatedClass = '\\' . get_class($relationObj->getRelated());
|
||||
@@ -778,12 +731,15 @@ class ModelsCommand extends Command
|
||||
'int|null',
|
||||
true,
|
||||
false
|
||||
// What kind of comments should be added to the relation count here?
|
||||
// What kind of comments should be added to the relation count here?
|
||||
);
|
||||
}
|
||||
} elseif (
|
||||
$relation === 'morphTo' ||
|
||||
($this->getRelationReturnTypes()[$relation] ?? '') === 'morphTo'
|
||||
$relationReturnType === 'morphTo' ||
|
||||
(
|
||||
!$relationReturnType &&
|
||||
$relation === 'morphTo'
|
||||
)
|
||||
) {
|
||||
// Model isn't specified because relation is polymorphic
|
||||
$this->setProperty(
|
||||
@@ -838,12 +794,17 @@ class ModelsCommand extends Command
|
||||
$fkProp = $reflectionObj->getProperty('foreignKey');
|
||||
$fkProp->setAccessible(true);
|
||||
|
||||
if ($relation === 'belongsTo') {
|
||||
return isset($this->nullableColumns[$fkProp->getValue($relationObj)]) ||
|
||||
!in_array($fkProp->getValue($relationObj), $this->foreignKeyConstraintsColumns, true);
|
||||
foreach (Arr::wrap($fkProp->getValue($relationObj)) as $foreignKey) {
|
||||
if (isset($this->nullableColumns[$foreignKey])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!in_array($foreignKey, $this->foreignKeyConstraintsColumns, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return isset($this->nullableColumns[$fkProp->getValue($relationObj)]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -892,7 +853,12 @@ class ModelsCommand extends Command
|
||||
|
||||
public function unsetMethod($name)
|
||||
{
|
||||
unset($this->methods[strtolower($name)]);
|
||||
foreach ($this->methods as $k => $v) {
|
||||
if (strtolower($k) === strtolower($name)) {
|
||||
unset($this->methods[$k]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getMethodType(Model $model, string $classType)
|
||||
@@ -920,19 +886,13 @@ class ModelsCommand extends Command
|
||||
|
||||
if ($this->reset) {
|
||||
$phpdoc = new DocBlock('', new Context($namespace));
|
||||
if ($this->keep_text) {
|
||||
$phpdoc->setText(
|
||||
(new DocBlock($reflection, new Context($namespace)))->getText()
|
||||
);
|
||||
}
|
||||
$phpdoc->setText(
|
||||
(new DocBlock($reflection, new Context($namespace)))->getText()
|
||||
);
|
||||
} else {
|
||||
$phpdoc = new DocBlock($reflection, new Context($namespace));
|
||||
}
|
||||
|
||||
if (!$phpdoc->getText()) {
|
||||
$phpdoc->setText($class);
|
||||
}
|
||||
|
||||
$properties = [];
|
||||
$methods = [];
|
||||
foreach ($phpdoc->getTags() as $tag) {
|
||||
@@ -1059,9 +1019,9 @@ class ModelsCommand extends Command
|
||||
$classname = $this->write_mixin ? $mixinClassName : $classname;
|
||||
|
||||
$allowDynamicAttributes = $this->write_mixin ? "#[\AllowDynamicProperties]\n\t" : '';
|
||||
$output = "namespace {$namespace}{\n{$docComment}\n\t{$keyword}{$allowDynamicAttributes}class {$classname} ";
|
||||
$output = "namespace {$namespace}{\n{$docComment}\n\t{$allowDynamicAttributes}{$keyword}class {$classname} ";
|
||||
|
||||
if (! $this->write_mixin) {
|
||||
if (!$this->write_mixin) {
|
||||
$output .= "extends \Eloquent ";
|
||||
|
||||
if ($interfaceNames) {
|
||||
@@ -1102,6 +1062,8 @@ class ModelsCommand extends Command
|
||||
$default = 'null';
|
||||
} elseif (is_int($default)) {
|
||||
//$default = $default;
|
||||
} elseif ($default instanceof \UnitEnum) {
|
||||
$default = '\\' . get_class($default) . '::' . $default->name;
|
||||
} else {
|
||||
$default = "'" . trim($default) . "'";
|
||||
}
|
||||
@@ -1129,7 +1091,7 @@ class ModelsCommand extends Command
|
||||
return '\Illuminate\Database\Eloquent\Collection';
|
||||
}
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Model $model */
|
||||
/** @var Model $model */
|
||||
$model = new $className();
|
||||
return '\\' . get_class($model->newCollection());
|
||||
}
|
||||
@@ -1176,7 +1138,10 @@ class ModelsCommand extends Command
|
||||
return $this->laravel['config']->get('ide-helper.model_camel_case_properties', false);
|
||||
}
|
||||
|
||||
protected function getAttributeReturnType(Model $model, \ReflectionMethod $reflectionMethod): Collection
|
||||
/**
|
||||
* @psalm-suppress NoValue
|
||||
*/
|
||||
protected function getAttributeTypes(Model $model, \ReflectionMethod $reflectionMethod): Collection
|
||||
{
|
||||
// Private/protected ReflectionMethods require setAccessible prior to PHP 8.1
|
||||
$reflectionMethod->setAccessible(true);
|
||||
@@ -1184,13 +1149,25 @@ class ModelsCommand extends Command
|
||||
/** @var Attribute $attribute */
|
||||
$attribute = $reflectionMethod->invoke($model);
|
||||
|
||||
return collect([
|
||||
'get' => $attribute->get ? optional(new \ReflectionFunction($attribute->get))->getReturnType() : null,
|
||||
'set' => $attribute->set ? optional(new \ReflectionFunction($attribute->set))->getReturnType() : null,
|
||||
])
|
||||
->filter()
|
||||
$methods = new Collection();
|
||||
|
||||
if ($attribute->get) {
|
||||
$methods['get'] = optional(new \ReflectionFunction($attribute->get))->getReturnType();
|
||||
}
|
||||
if ($attribute->set) {
|
||||
$function = optional(new \ReflectionFunction($attribute->set));
|
||||
if ($function->getNumberOfParameters() === 0) {
|
||||
$methods['set'] = null;
|
||||
} else {
|
||||
$methods['set'] = $function->getParameters()[0]->getType();
|
||||
}
|
||||
}
|
||||
|
||||
return $methods
|
||||
->map(function ($type) {
|
||||
if ($type instanceof \ReflectionUnionType) {
|
||||
if ($type === null) {
|
||||
$types = collect([]);
|
||||
} elseif ($type instanceof \ReflectionUnionType) {
|
||||
$types = collect($type->getTypes())
|
||||
/** @var ReflectionType $reflectionType */
|
||||
->map(function ($reflectionType) {
|
||||
@@ -1201,7 +1178,7 @@ class ModelsCommand extends Command
|
||||
$types = collect($this->extractReflectionTypes($type));
|
||||
}
|
||||
|
||||
if ($type->allowsNull()) {
|
||||
if ($type && $type->allowsNull()) {
|
||||
$types->push('null');
|
||||
}
|
||||
|
||||
@@ -1295,7 +1272,7 @@ class ModelsCommand extends Command
|
||||
|
||||
/**
|
||||
* Generates methods provided by the SoftDeletes trait
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param Model $model
|
||||
*/
|
||||
protected function getSoftDeleteMethods($model)
|
||||
{
|
||||
@@ -1312,7 +1289,7 @@ class ModelsCommand extends Command
|
||||
/**
|
||||
* Generate factory method from "HasFactory" trait.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param Model $model
|
||||
*/
|
||||
protected function getFactoryMethods($model)
|
||||
{
|
||||
@@ -1340,16 +1317,12 @@ class ModelsCommand extends Command
|
||||
return;
|
||||
}
|
||||
|
||||
if (version_compare($this->laravel->version(), '9', '>=')) {
|
||||
$this->setMethod('factory', $factory, ['$count = null, $state = []']);
|
||||
} else {
|
||||
$this->setMethod('factory', $factory, ['...$parameters']);
|
||||
}
|
||||
$this->setMethod('factory', $factory, ['$count = null, $state = []']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates methods that return collections
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param Model $model
|
||||
*/
|
||||
protected function getCollectionMethods($model)
|
||||
{
|
||||
@@ -1392,7 +1365,7 @@ class ModelsCommand extends Command
|
||||
return $type;
|
||||
}
|
||||
|
||||
$reflection = new \ReflectionClass($type);
|
||||
$reflection = new ReflectionClass($type);
|
||||
|
||||
if (!$reflection->implementsInterface(Castable::class)) {
|
||||
return $type;
|
||||
@@ -1424,7 +1397,7 @@ class ModelsCommand extends Command
|
||||
return $type;
|
||||
}
|
||||
|
||||
$reflection = new \ReflectionClass($type);
|
||||
$reflection = new ReflectionClass($type);
|
||||
|
||||
if (!$reflection->implementsInterface(CastsAttributes::class)) {
|
||||
return $type;
|
||||
@@ -1462,8 +1435,7 @@ class ModelsCommand extends Command
|
||||
{
|
||||
$reflection = $model instanceof ReflectionClass
|
||||
? $model
|
||||
: new ReflectionObject($model)
|
||||
;
|
||||
: new ReflectionObject($model);
|
||||
|
||||
$className = trim($className, '\\');
|
||||
$writingToExternalFile = !$this->write || $this->write_mixin;
|
||||
@@ -1630,7 +1602,7 @@ class ModelsCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param Model $model
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
@@ -1652,14 +1624,13 @@ class ModelsCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema
|
||||
* @param Builder $schema
|
||||
* @param string $table
|
||||
* @throws DBALException
|
||||
*/
|
||||
protected function setForeignKeys($schema, $table)
|
||||
{
|
||||
foreach ($schema->listTableForeignKeys($table) as $foreignKeyConstraint) {
|
||||
foreach ($foreignKeyConstraint->getLocalColumns() as $columnName) {
|
||||
foreach ($schema->getForeignKeys($table) as $foreignKeyConstraint) {
|
||||
foreach ($foreignKeyConstraint['columns'] as $columnName) {
|
||||
$this->foreignKeyConstraintsColumns[] = $columnName;
|
||||
}
|
||||
}
|
||||
|
||||
+61
-3
@@ -13,8 +13,13 @@ namespace Barryvdh\LaravelIdeHelper;
|
||||
|
||||
use Illuminate\Foundation\AliasLoader;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use PhpParser\Lexer\Emulative;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Namespace_;
|
||||
use PhpParser\Parser\Php7;
|
||||
use ReflectionClass;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
@@ -26,7 +31,7 @@ class Generator
|
||||
/** @var \Illuminate\View\Factory */
|
||||
protected $view;
|
||||
|
||||
/** @var \Symfony\Component\Console\Output\OutputInterface */
|
||||
/** @var OutputInterface */
|
||||
protected $output;
|
||||
|
||||
protected $extra = [];
|
||||
@@ -37,7 +42,7 @@ class Generator
|
||||
/**
|
||||
* @param \Illuminate\Config\Repository $config
|
||||
* @param \Illuminate\View\Factory $view
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @param OutputInterface $output
|
||||
* @param string $helpers
|
||||
*/
|
||||
public function __construct(
|
||||
@@ -75,6 +80,7 @@ class Generator
|
||||
return $this->view->make('helper')
|
||||
->with('namespaces_by_extends_ns', $this->getAliasesByExtendsNamespace())
|
||||
->with('namespaces_by_alias_ns', $this->getAliasesByAliasNamespace())
|
||||
->with('real_time_facades', $this->getRealTimeFacades())
|
||||
->with('helpers', $this->helpers)
|
||||
->with('version', $app->version())
|
||||
->with('include_fluent', $this->config->get('ide-helper.include_fluent', true))
|
||||
@@ -153,6 +159,11 @@ class Generator
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip the swoole
|
||||
if ($facade == 'SwooleTW\Http\Server\Facades\Server' && $name == 'Server' && !class_exists('Swoole\Http\Server')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : [];
|
||||
$alias = new Alias($this->config, $name, $facade, $magicMethods, $this->interfaces);
|
||||
if ($alias->isValid()) {
|
||||
@@ -168,6 +179,51 @@ class Generator
|
||||
return $aliases;
|
||||
}
|
||||
|
||||
protected function getRealTimeFacades()
|
||||
{
|
||||
$facades = [];
|
||||
$realTimeFacadeFiles = glob(storage_path('framework/cache/facade-*.php'));
|
||||
foreach ($realTimeFacadeFiles as $file) {
|
||||
try {
|
||||
$name = $this->getFullyQualifiedClassNameInFile($file);
|
||||
$facades[$name] = $name;
|
||||
} catch (\Exception $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $facades;
|
||||
}
|
||||
|
||||
protected function getFullyQualifiedClassNameInFile(string $path)
|
||||
{
|
||||
$contents = file_get_contents($path);
|
||||
|
||||
$parsers = new Php7(new Emulative());
|
||||
|
||||
$parsed = collect($parsers->parse($contents) ?: []);
|
||||
|
||||
$namespace = $parsed->first(function ($node) {
|
||||
return $node instanceof Namespace_;
|
||||
});
|
||||
|
||||
if ($namespace) {
|
||||
$name = $namespace->name->toString();
|
||||
|
||||
$class = collect($namespace->stmts)->first(function ($node) {
|
||||
return $node instanceof Class_;
|
||||
});
|
||||
|
||||
if ($class) {
|
||||
$name .= '\\' . $class->name->toString();
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Regroup aliases by namespace of extended classes
|
||||
*
|
||||
@@ -175,7 +231,9 @@ class Generator
|
||||
*/
|
||||
protected function getAliasesByExtendsNamespace()
|
||||
{
|
||||
$aliases = $this->getValidAliases();
|
||||
$aliases = $this->getValidAliases()->filter(static function (Alias $alias) {
|
||||
return is_subclass_of($alias->getExtends(), Facade::class);
|
||||
});
|
||||
|
||||
$this->addMacroableClasses($aliases);
|
||||
|
||||
|
||||
@@ -16,15 +16,15 @@ class GenerateModelHelper
|
||||
*/
|
||||
public static $shouldRun = false;
|
||||
|
||||
/** @var \Illuminate\Contracts\Console\Kernel */
|
||||
/** @var Artisan */
|
||||
protected $artisan;
|
||||
|
||||
/** @var \Illuminate\Contracts\Config\Repository */
|
||||
/** @var Config */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @param \Illuminate\Contracts\Console\Kernel $artisan
|
||||
* @param \Illuminate\Contracts\Config\Repository $config
|
||||
* @param Artisan $artisan
|
||||
* @param Config $config
|
||||
*/
|
||||
public function __construct(Artisan $artisan, Config $config)
|
||||
{
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ use Illuminate\Support\Str;
|
||||
|
||||
class Method
|
||||
{
|
||||
/** @var \Barryvdh\Reflection\DocBlock */
|
||||
/** @var DocBlock */
|
||||
protected $phpdoc;
|
||||
|
||||
/** @var \ReflectionMethod */
|
||||
|
||||
@@ -64,7 +64,7 @@ class UsesResolver
|
||||
'\\'
|
||||
);
|
||||
|
||||
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
|
||||
$parser = (new ParserFactory())->createForHostVersion();
|
||||
$namespaceData = null;
|
||||
|
||||
foreach ($parser->parse($code) as $node) {
|
||||
|
||||
Reference in New Issue
Block a user