FQCN bugfix when writing external eloquent builder methods inside models. (#1113)

* Fix code that was causing the test to break and fix bug with not built in types

* Run cs fixer

* Remove fetching the doc block type and the putting it as a type hint as a php doc block is sufficient

* Revert doc block type hinting

* Enchance doc block type hinting

* Combine replacements

* Use the full builder class instead of the parsed one after the getClassName function and remove in array check

* Get the builder from the model itself instead of passing a string directly the function

* Use the full builder class to get the builder methods and reflection, but use the parsed builder class after setting its method in the doc

* Add test for fqn support on external eloquent builder

* Use the external builder if necessary when building the magic wheres

* Use the default eloquent builder if the user has disabled the external builder option
This commit is contained in:
Kaloqn
2020-12-06 09:55:05 +01:00
committed by GitHub
parent 9859958cfa
commit 5515cabea3
7 changed files with 498 additions and 156 deletions
+19 -10
View File
@@ -490,9 +490,13 @@ class ModelsCommand extends Command
!$column->getNotnull()
);
if ($this->write_model_magic_where) {
$builderClass = $this->write_model_external_builder_methods
? get_class($model->newModelQuery())
: '\Illuminate\Database\Eloquent\Builder';
$this->setMethod(
Str::camel('where_' . $name),
$this->getClassNameInDestinationFile($model, \Illuminate\Database\Eloquent\Builder::class)
$this->getClassNameInDestinationFile($model, $builderClass)
. '|'
. $this->getClassNameInDestinationFile($model, get_class($model)),
['$value']
@@ -562,7 +566,7 @@ class ModelsCommand extends Command
);
if ($this->write_model_external_builder_methods) {
$this->writeModelExternalBuilderMethods($builder, $model);
$this->writeModelExternalBuilderMethods($model);
}
} elseif (
!method_exists('Illuminate\Database\Eloquent\Model', $method)
@@ -1149,26 +1153,31 @@ class ModelsCommand extends Command
return $namespaceAliases;
}
protected function writeModelExternalBuilderMethods(string $builder, Model $model): void
protected function writeModelExternalBuilderMethods(Model $model): void
{
if (in_array($builder, ['\Illuminate\Database\Eloquent\Builder', 'EloquentBuilder'])) {
return;
}
$newBuilderMethods = get_class_methods($builder);
$fullBuilderClass = '\\' . get_class($model->newModelQuery());
$newBuilderMethods = get_class_methods($fullBuilderClass);
$originalBuilderMethods = get_class_methods('\Illuminate\Database\Eloquent\Builder');
// diff the methods between the new builder and original one
// and create helpers for the ones that are new
$newMethodsFromNewBuilder = array_diff($newBuilderMethods, $originalBuilderMethods);
if (!$newMethodsFromNewBuilder) {
return;
}
// after we have retrieved the builder's methods
// get the class of the builder based on the FQCN option
$builderClassBasedOnFQCNOption = $this->getClassNameInDestinationFile($model, get_class($model->newModelQuery()));
foreach ($newMethodsFromNewBuilder as $builderMethod) {
$reflection = new \ReflectionMethod($builder, $builderMethod);
$reflection = new \ReflectionMethod($fullBuilderClass, $builderMethod);
$args = $this->getParameters($reflection);
$this->setMethod(
$builderMethod,
$builder . '|' . $this->getClassNameInDestinationFile($model, get_class($model)),
$builderClassBasedOnFQCNOption . '|' . $this->getClassNameInDestinationFile($model, get_class($model)),
$args
);
}