Compare commits

..
Author SHA1 Message Date
barryvdh 8d441ec99f normalize composer.json 2025-02-11 13:59:46 +00:00
dba153f1e0 Laravel 12 support (#1672)
* Laravel 12 support

* Update run-integration-tests.yml to include Laravel 12

* Update run-tests.yml to include Laravel 12

* allow testbench ^10

* Update run-integration-tests.yml

* Update run-tests.yml

* Update composer.json

Co-authored-by: KentarouTakeda <[email protected]>

* Update run-integration-tests.yml

* Update run-tests.yml

---------

Co-authored-by: KentarouTakeda <[email protected]>
Co-authored-by: Barry vd. Heuvel <[email protected]>
2025-02-11 14:59:28 +01:00
yparitcher 40485e7350 Fix MorphTo Model Doc Generation (#1668)
fix:
```php
    /**
     * @return MorphTo<contravariant ModelA|ModelB, $this>
     */
    public function reminderable(): MorphTo {
        return $this->morphTo(__FUNCTION__, 'entity', 'entity_id');
    }
```
From:
```php
* @property-read contravariant ModelA|ModelB $reminderable
 ```
To:
```php
* @property-read ModelA|ModelB $reminderable
 ```
Fixes: #1667
2025-02-04 17:49:42 +01:00
skyler544andSkyler Mayfield ead24b10f6 prevent generation of incorrect property annotation (#1665)
Co-authored-by: Skyler Mayfield <[email protected]>
2025-01-29 22:43:43 +01:00
Kristijan 187ce9beeb Update configs.php (#1662)
Fixes config items incorectlly set as `string` due to `'array(...)'` value passed to `gettype` instead of real array
2025-01-23 18:56:10 +01:00
barryvdh 6b43ac616d Update CHANGELOG 2025-01-14 09:07:42 +00:00
Barry vd. Heuvel 980a87e250 Check if returnType from docblock is not null (#1658) 2025-01-14 10:07:00 +01:00
Barry vd. Heuvelandlaravel-ide-helper 299a81b9bb Convert auth() helper to use Auth facade (#1656)
* Convert auth() helper to use Auth facade

* composer fix-style

---------

Co-authored-by: laravel-ide-helper <[email protected]>
2025-01-08 13:50:47 +01:00
barryvdh 06c1fab9b5 Update CHANGELOG 2025-01-08 10:03:44 +00:00
Casper Bloemendaal 271682a2a6 feat: use generics of return type to determine resulting models (#1653) 2025-01-08 11:01:30 +01:00
Barry vd. Heuvelandlaravel-ide-helper bb1caed698 Check if macro is valid (#1655)
* Check if macro is valid

* composer fix-style

---------

Co-authored-by: laravel-ide-helper <[email protected]>
2025-01-08 11:00:53 +01:00
Barry vd. Heuvelandlaravel-ide-helper 55268cd47a Catch meta, tweak auth (#1654)
* Catch meta, tweak auth

* composer fix-style

* Catch meta, tweak auth

---------

Co-authored-by: laravel-ide-helper <[email protected]>
2025-01-08 11:00:41 +01:00
barryvdh 088968c3fc Update CHANGELOG 2025-01-06 15:42:30 +00:00
Barry vd. Heuvel 655e057626 Fix empty closure 2025-01-06 16:29:58 +01:00
barryvdh c8d85a0d34 Update CHANGELOG 2025-01-06 14:09:45 +00:00
Barry vd. Heuvel 4c656cc71d Remove duplicate config, fix ->can() (#1650) 2025-01-06 15:08:47 +01:00
barryvdh 0fe9774dfb Update CHANGELOG 2025-01-06 13:53:52 +00:00
Jesper Noordsij 030f6f1f35 Add special 'dev' to composer keywords (#1649) 2025-01-03 15:21:18 +01:00
laravel-ide-helper 154300fb06 composer fix-style 2025-01-01 12:17:43 +00:00
Mathieu TUDISCOandBarry vd. Heuvel 05d9c3cd65 Allow adding custom Macroable classes. (#1629)
* Allow adding custom Macroable classes.

* Remove duplication, tweak config

* Remove test

---------

Co-authored-by: Barry vd. Heuvel <[email protected]>
2025-01-01 13:17:20 +01:00
Barry vd. Heuvelandlaravel-ide-helper beda399e7e Feat guess macro types (#1648)
* Add default class for HttpClient macro

* composer fix-style

---------

Co-authored-by: laravel-ide-helper <[email protected]>
2025-01-01 10:44:43 +01:00
13 changed files with 164 additions and 55 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
fail-fast: false
matrix:
php: [8.4, 8.3, 8.2]
laravel: [^11.15]
laravel: [11.x, 12.x]
name: P${{ matrix.php }} - Laravel${{ matrix.laravel }}
steps:
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
matrix:
os: [ubuntu-22.04, windows-2019]
php: [8.4, 8.3, 8.2]
laravel: [^11.15]
laravel: [~11.15, 12.x]
stability: [prefer-lowest, prefer-stable]
steps:
- name: Set git to use LF
+62
View File
@@ -1,5 +1,67 @@
# Changelog
## v3.5.4 - 2025-01-14
### What's Changed
* Convert auth() helper to use Auth facade by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1656
* Check if returnType from docblock is not null by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1658
**Full Changelog**: https://github.com/barryvdh/laravel-ide-helper/compare/v3.5.3...v3.5.4
## v3.5.3 - 2025-01-08
### What's Changed
* Catch meta, tweak auth by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1654
* Check if macro is valid by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1655
* feat: use generics of return type to determine resulting models by @Bloemendaal in https://github.com/barryvdh/laravel-ide-helper/pull/1653
### New Contributors
* @Bloemendaal made their first contribution in https://github.com/barryvdh/laravel-ide-helper/pull/1653
**Full Changelog**: https://github.com/barryvdh/laravel-ide-helper/compare/v3.5.2...v3.5.3
## v3.5.2 - 2025-01-06
### Fixes
Fix empty/anonymous closure in meta command.
**Full Changelog**: https://github.com/barryvdh/laravel-ide-helper/compare/v3.5.1...v3.5.2
## v3.5.1 - 2025-01-06
### What's Changed
* Remove duplicate config, fix ->can() by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1650
**Full Changelog**: https://github.com/barryvdh/laravel-ide-helper/compare/v3.5.0...v3.5.1
## v3.5.0 - 2025-01-06
### What's Changed
* Add phpstorm meta argument hints by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1640
* Add meta override for user return types by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1642
* Use forked ContextFactory by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1643
* Remove php parser by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1644
* Also add eloquent template tags from base class by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1645
* Add more metadata by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1646
* Fixed generating PHPDoc for methods with class templates by @chack1172 in https://github.com/barryvdh/laravel-ide-helper/pull/1647
* Feat guess macro types by @barryvdh in https://github.com/barryvdh/laravel-ide-helper/pull/1648
* Allow adding custom Macroable classes. by @mathieutu in https://github.com/barryvdh/laravel-ide-helper/pull/1629
* Add special `dev` to composer keywords by @jnoordsij in https://github.com/barryvdh/laravel-ide-helper/pull/1649
### New Contributors
* @chack1172 made their first contribution in https://github.com/barryvdh/laravel-ide-helper/pull/1647
* @mathieutu made their first contribution in https://github.com/barryvdh/laravel-ide-helper/pull/1629
* @jnoordsij made their first contribution in https://github.com/barryvdh/laravel-ide-helper/pull/1649
**Full Changelog**: https://github.com/barryvdh/laravel-ide-helper/compare/v3.4.0...v3.5.0
## v3.4.0 - 2024-12-29
### What's Changed
+2
View File
@@ -115,6 +115,8 @@ Str::macro('concat', function(string $str1, string $str2) : string {
});
```
You can add any custom Macroable traits to detect in the `macroable_traits` config option.
### Automatic PHPDocs for models
If you don't want to write your properties yourself, you can use the command `php artisan ide-helper:models` to generate
+10 -9
View File
@@ -11,7 +11,8 @@
"netbeans",
"sublime",
"codeintel",
"phpdoc"
"phpdoc",
"dev"
],
"authors": [
{
@@ -24,19 +25,19 @@
"ext-json": "*",
"barryvdh/reflection-docblock": "^2.3",
"composer/class-map-generator": "^1.0",
"illuminate/console": "^11.15",
"illuminate/database": "^11.15",
"illuminate/filesystem": "^11.15",
"illuminate/support": "^11.15"
"illuminate/console": "^11.15 || ^12",
"illuminate/database": "^11.15 || ^12",
"illuminate/filesystem": "^11.15 || ^12",
"illuminate/support": "^11.15 || ^12"
},
"require-dev": {
"ext-pdo_sqlite": "*",
"friendsofphp/php-cs-fixer": "^3",
"illuminate/config": "^11.15",
"illuminate/view": "^11.15",
"illuminate/config": "^11.15 || ^12",
"illuminate/view": "^11.15 || ^12",
"mockery/mockery": "^1.4",
"orchestra/testbench": "^9.2",
"phpunit/phpunit": "^10.5",
"orchestra/testbench": "^9.2 || ^10",
"phpunit/phpunit": "^10.5 || ^11.5.3",
"spatie/phpunit-snapshot-assertions": "^4 || ^5",
"vimeo/psalm": "^5.4",
"vlucas/phpdotenv": "^5"
+15
View File
@@ -123,6 +123,7 @@ return [
'helper_files' => [
base_path() . '/vendor/laravel/framework/src/Illuminate/Support/helpers.php',
base_path() . '/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php',
],
/*
@@ -334,4 +335,18 @@ return [
// 'ide-helper:models --nowrite',
],
/*
|--------------------------------------------------------------------------
| Macroable Traits
|--------------------------------------------------------------------------
|
| Define which traits should be considered capable of adding Macro.
| You can add any custom trait that behaves like the original Laravel one.
|
*/
'macroable_traits' => [
Filament\Support\Concerns\Macroable::class,
Spatie\Macroable\Macroable::class,
],
];
+2 -1
View File
@@ -6,7 +6,8 @@ return collect(Illuminate\Support\Facades\Gate::abilities())
$policyClass = null;
if (get_class($reflection->getClosureThis()) === Illuminate\Auth\Access\Gate::class) {
$closureThis = $reflection->getClosureThis();
if ($closureThis && get_class($closureThis) === Illuminate\Auth\Access\Gate::class) {
$vars = $reflection->getClosureUsedVariables();
if (isset($vars['callback'])) {
+1 -1
View File
@@ -72,7 +72,7 @@ function vsCodeGetConfigValue($value, $key, $configPaths)
$key = collect(explode('.', $key));
$key->pop();
$key = $key->implode('.');
$value = 'array(...)';
$value = [];
}
$nextKey = $keysToFind->shift();
+12 -4
View File
@@ -46,6 +46,8 @@ class Alias
protected $phpdoc = null;
protected $classAliases = [];
protected $isMacroable = false;
/** @var ConfigRepository */
protected $config;
@@ -60,12 +62,13 @@ class Alias
* @param array $magicMethods
* @param array $interfaces
*/
public function __construct($config, $alias, $facade, $magicMethods = [], $interfaces = [])
public function __construct($config, $alias, $facade, $magicMethods = [], $interfaces = [], $isMacroable = false)
{
$this->alias = $alias;
$this->magicMethods = $magicMethods;
$this->interfaces = $interfaces;
$this->config = $config;
$this->isMacroable = $isMacroable;
// Make the class absolute
$facade = '\\' . ltrim($facade, '\\');
@@ -395,15 +398,20 @@ class Alias
// Check if the class is macroable
// (Eloquent\Builder is also macroable but doesn't use Macroable trait)
$traits = collect($reflection->getTraitNames());
if ($traits->contains('Illuminate\Support\Traits\Macroable') || $class === EloquentBuilder::class) {
if ($this->isMacroable || $class === EloquentBuilder::class) {
$properties = $reflection->getStaticProperties();
$macros = isset($properties['macros']) ? $properties['macros'] : [];
foreach ($macros as $macro_name => $macro_func) {
if (!in_array($macro_name, $this->usedMethods)) {
try {
$method = $this->getMacroFunction($macro_func);
} catch (Throwable $e) {
// Invalid method, skip
continue;
}
// Add macros
$this->methods[] = new Macro(
$this->getMacroFunction($macro_func),
$method,
$this->alias,
$reflection,
$macro_name,
+13 -6
View File
@@ -232,18 +232,19 @@ class MetaCommand extends Command
'argumentSet' => 'auth',
],
[
'class' => ['\Illuminate\Support\Facades\Route', '\Illuminate\Support\Facades\Auth'],
'method' => ['can', 'cannot'],
'class' => ['\Illuminate\Support\Facades\Route', '\Illuminate\Support\Facades\Auth', 'Illuminate\Foundation\Auth\Access\Authorizable'],
'method' => ['can', 'cannot', 'cant'],
'argumentSet' => 'auth',
],
[
'method' => 'config',
'argumentSet' => 'configs',
'class' => ['Illuminate\Contracts\Auth\Access\Authorizable'],
'method' => ['can'],
'argumentSet' => 'auth',
],
[
'class' => ['\Illuminate\Config\Repository', '\Illuminate\Support\Facades\Config'],
'method' => [
'get',
// 'get', // config() and Config::Get() are added with return type hints already
'getMany',
'set',
'string',
@@ -312,7 +313,13 @@ class MetaCommand extends Command
{
if (!isset($this->templateCache[$name])) {
$file = __DIR__ . '/../../php-templates/' . basename($name) . '.php';
$value = $this->files->requireOnce($file) ?: [];
try {
$value = $this->files->requireOnce($file) ?: [];
} catch (\Throwable $e) {
$value = [];
$this->warn('Cannot load template for ' . $name . ': ' . $e->getMessage());
}
if (!$value instanceof Collection) {
$value = collect($value);
}
+11 -1
View File
@@ -628,6 +628,10 @@ class ModelsCommand extends Command
)
);
});
// https://github.com/barryvdh/laravel-ide-helper/issues/1664
$reflections = array_filter($reflections, function (\ReflectionMethod $methodReflection) {
return !($methodReflection->getName() === 'getUseFactoryAttribute');
});
sort($reflections);
foreach ($reflections as $reflection) {
$type = $this->getReturnTypeFromReflection($reflection);
@@ -819,10 +823,16 @@ class ModelsCommand extends Command
$relation === 'morphTo'
)
) {
$matches = [];
$returnType = $this->getReturnTypeFromDocBlock($reflection);
if ($returnType !== null) {
preg_match('/MorphTo<(?:contravariant\s+)?(.+?)(?:,|>)/i', $returnType, $matches);
}
// Model isn't specified because relation is polymorphic
$this->setProperty(
$method,
$this->getClassNameInDestinationFile($model, Model::class) . '|\Eloquent',
$matches[1] ?? $this->getClassNameInDestinationFile($model, Model::class) . '|\Eloquent',
true,
null,
$comment,
+33 -4
View File
@@ -35,6 +35,7 @@ class Generator
protected $magic = [];
protected $interfaces = [];
protected $helpers;
protected array $macroableTraits = [];
/**
* @param \Illuminate\Config\Repository $config
@@ -79,7 +80,7 @@ class Generator
->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('helpers', $this->detectHelpers())
->with('include_fluent', $this->config->get('ide-helper.include_fluent', true))
->with('factories', $this->config->get('ide-helper.include_factory_builders') ? Factories::all() : [])
->render();
@@ -111,6 +112,24 @@ class Generator
->render();
}
protected function detectHelpers()
{
$helpers = $this->helpers;
$replacements = [
'($guard is null ? \Illuminate\Contracts\Auth\Factory : \Illuminate\Contracts\Auth\StatefulGuard)' => '\\Auth',
];
foreach ($replacements as $search => $replace) {
$helpers = Str::replace(
"@return {$search}",
"@return $replace|$search",
$helpers
);
}
return $helpers;
}
protected function detectDrivers()
{
$defaultUserModel = config('auth.providers.users.model', config('auth.model', 'App\User'));
@@ -341,7 +360,7 @@ class Generator
continue;
}
$aliases[] = new Alias($this->config, $class, $class, [], $this->interfaces);
$aliases[] = new Alias($this->config, $class, $class, [], $this->interfaces, true);
}
}
@@ -363,8 +382,18 @@ class Generator
->filter(function ($class) {
$traits = class_uses_recursive($class);
// Filter only classes with the macroable trait
return isset($traits[Macroable::class]);
if (isset($traits[Macroable::class])) {
return true;
}
// Filter only classes with a macroable trait
foreach ($this->config->get('ide-helper.macroable_traits', []) as $trait) {
if (isset($traits[$trait])) {
return true;
}
}
return false;
})
->filter(function ($class) use ($aliases) {
$class = Str::start($class, '\\');
+1 -27
View File
@@ -7,7 +7,6 @@ namespace Barryvdh\LaravelIdeHelper\Tests;
use Barryvdh\LaravelIdeHelper\Alias;
use Barryvdh\LaravelIdeHelper\Macro;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Arr;
/**
@@ -16,31 +15,6 @@ use Illuminate\Support\Arr;
*/
class AliasTest extends TestCase
{
/**
* @covers ::detectMethods
*/
public function testDetectMethodsMacroableMacros(): void
{
// Mock
$macro = __FUNCTION__;
$alias = new AliasMock();
// Macros
Builder::macro(
$macro,
function () {
// empty
}
);
// Prepare
$alias->setClasses([Builder::class]);
$alias->detectMethods();
// Test
$this->assertNotNull($this->getAliasMacro($alias, Builder::class, $macro));
}
/**
* @covers ::detectMethods
*/
@@ -50,7 +24,7 @@ class AliasTest extends TestCase
$macro = __FUNCTION__;
$alias = new AliasMock();
// Macros
// Macrosx
EloquentBuilder::macro(
$macro,
function () {