Compare commits

...
Author SHA1 Message Date
Barry vd. Heuvel 2535f8e6ab Fix tests and CS 2024-02-07 21:44:48 +01:00
James Bhatta 16548fc878 Update README.md (#1451)
Fix intra page link for PHPDocs for models
2024-02-07 21:40:24 +01:00
Barry vd. Heuvel 872b470d9b Update CHANGELOG.md 2024-02-07 21:37:51 +01:00
Filip Iulian Pacurar 04c1a8d444 Support generating helper files for real-time facades (#1455)
* Support generating helper files for real-time facades

Add changelog entry for real-time facades support

Mention real-time facades support in readme

Fix code style

Import

* Remove useless assertions

We cannot 100% control the output file has only the real-time facades, anything else can be in the final output
2024-02-07 21:35:02 +01:00
snmatsui c290af858d reset foreignKeyConstraintsColumns on model loop start (#1461) 2024-02-07 21:31:12 +01:00
f64ff9c0b1 Add support for enum default arguments using enum cases (#1464)
* add case when default value is of type enum

* Update CHANGELOG.md

* add tests for enum arguments default values

* ignore psalm issue (built-in `\UnitEnum` class does not exists in PHP7)

* Update run-static-analysis.yml to use PHP8.1

---------

Co-authored-by: Barry vd. Heuvel <[email protected]>
Co-authored-by: Barry vd. Heuvel <[email protected]>
2024-02-07 21:27:30 +01:00
Allan LaalandBarry vd. Heuvel f3ad134242 FIX vulnerability CVE-2021-43608 (#1392)
Doctrine DBAL 3.x before 3.1.4 allows SQL Injection: https://www.cve.org/CVERecord?id=CVE-2021-43608

Co-authored-by: Barry vd. Heuvel <[email protected]>
2024-02-07 21:24:42 +01:00
PapaBearandTimo Frenzel 9d14b019f6 skip swoole, otherwise fatal error (#1477)
Co-authored-by: Timo Frenzel <[email protected]>
2024-02-07 21:19:43 +01:00
netpok f4656256fc Fix non-facade classes will result in no autocomplete (#841)
* Filter out non-facade base classes

* Remove Model as it is already skipped because it's not a facade
2024-02-07 21:06:31 +01:00
Jackey Cheung cc9ed4423b disable inspections of helper files (#1486)
* disables all jetbrains inspections

* disables all jetbrains' & phpcs' inspections
2024-02-07 19:30:35 +01:00
Markus Podar 512612f22f Remove outdated dev references to older versions (#1508) 2024-02-07 19:29:10 +01:00
Toby TwiggerandToby Twigger 115068e57b Clarify use of --reset and --smart-reset flags in documentation (#1494)
* Update README.md

Clarified model behaviour when using the --reset option

* Add --smart-reset to the documentation

---------

Co-authored-by: Toby Twigger <[email protected]>
2024-02-07 14:36:45 +01:00
Markus Podar a8b34ad228 Removed support for Laravel 8 and therefore for PHP < 8.0 (#1504)
* Removed support for Laravel 8 and therefore for PHP < 8.0

* Update php-cs-fixer to v3

* composer fix-style
2024-02-05 13:25:08 +01:00
Barry vd. Heuvel 485c756f6c Prepare 2.14.0 release 2024-02-05 09:16:36 +01:00
Markus Podar cf4687f98c Prepare 2.14.0 release (#1503) 2024-02-05 09:13:57 +01:00
Markus Podar e65d30b27a Remove doctrine/dbal:^4 support (#1507)
* Remove doctrine/dbal:^4 support

Tests fail with:
`PHP Fatal error:  Declaration of Illuminate\Database\PDO\Concerns\ConnectsToDatabase::connect(array $params, $username = null, $password = null, array $driverOptions = []) must be compatible with Doctrine\DBAL\Driver::connect(array $params): Doctrine\DBAL\Driver\Connection in /home/runner/work/laravel-ide-helper/laravel-ide-helper/vendor/laravel/framework/src/Illuminate/Database/PDO/Concerns/ConnectsToDatabase.php on line 22`

* gha: install with downgrading all dependencies

* Add note to readme
2024-02-05 06:54:43 +01:00
Markus Podar 416e0ab243 Merge pull request #1506 from olexoliinyk0/test/case-of-1505
test: case for the issue #1505;
2024-02-03 21:02:28 +01:00
Markus Podar 9374952402 Adapt snapshot testcase 2024-02-03 20:56:57 +01:00
Oleksandr Oliinyk 850fc5fe7f test: case for the issue #1505;
duplication of properties that have generic types specified and descriptions;
2024-02-02 18:37:44 +02:00
Markus Podar 726e595578 Add support for nikic/php-parser:^5 and (hopefully) doctrine/dbal:^4 (#1502)
* Add support for nikic/php-parser:^5

- `createForHostVersion` has been added to php-parse 4.18 so code can
  run with both versions [1]
- therefore also bumped the minimum required version to it

Note:
The dev dependency vimeo/psalm is **not** compatible with
php-parser:^5 currently. This does not impact usages of this library,
but sometimes cause friction when working on this library.
For our CI this isn't a problem, because we already remove that
dependency before running the test suite.

[1] https://github.com/nikic/PHP-Parser/blob/master/UPGRADE-5.0.md#changes-to-the-parser-factory

* gha: prevent cancelling of all jobs if one fails

* Update CHANGELOG.md

* gha: remove unsupported Laravel / PHP combinations

According to https://laravel.com/docs/10.x/releases

* Add dbal:^4 too
2024-01-28 19:33:31 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 6336db0548 Bump the deps group with 1 update (#1478)
Bumps the deps group with 1 update: [stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action).

- [Release notes](https://github.com/stefanzweifel/git-auto-commit-action/releases)
- [Changelog](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stefanzweifel/git-auto-commit-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: stefanzweifel/git-auto-commit-action
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: deps
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-01 10:36:20 +01:00
Markus Podar 21352a1e48 Merge pull request #1473 from sergiy-petrov/php8.3 2023-10-05 15:58:39 +02:00
Serhii Petrov 390874207f Test against php 8.2 and 8.3
Integration tests against 8.3
Unit tests against 8.2 and 8.3
2023-10-05 16:10:38 +03:00
Markus Podar 3cdd3af631 chore: add dependabot for github actions (#1470) 2023-09-29 09:26:16 +02:00
erikn69 c751d3e176 ci: Use GitHub Actions V4 (#1469) 2023-09-29 09:25:55 +02:00
Markus Podar 1a3affd4f8 Catch error and exception (#1431) (#1465)
Credit goes to @dongm2ez
2023-09-06 12:35:33 +02:00
Markus Podar 0801d002e4 Fix tests for edc422cd2e (#1457)
I just ran `composer test-regenerate`
2023-07-31 13:26:41 +02:00
Gerardo Ibarra edc422cd2e add annotation ignore for php code sniffer (#1456) 2023-07-31 11:08:02 +02:00
Markus PodarandBarry vd. Heuvel 4dc20b028a Remove offical support for Lumen (#1425)
I'm proposing to drop official suport for Lumen for the following reasons:
- Lumen itself is dead, per [1]
  > **Note:** In the years since releasing Lumen, PHP has made a variety of wonderful performance improvements. For this reason, along with the availability of [Laravel Octane](https://laravel.com/docs/octane), we no longer recommend that you begin new projects with Lumen. Instead, we recommend always beginning new projects with [Laravel](https://laravel.com).

  Laravel Octact is just Laravel and no one using ide-helper with it
  needs anything special.
- For now, the change is mostly on the logistics side (readme, run tests,
  issues). In the past we had some special code but over time this was
  already removed.
  For now people still can use it and nothing will break out of the blue,
  but eventually it might

There are a only a few Lumen related issues open currently which would
be closed by this (#1105, #1069, #438).

[1] https://github.com/laravel/lumen/commit/69b26578d2f15595ea901278434b74df459c4329

Co-authored-by: Barry vd. Heuvel <[email protected]>
2023-02-20 13:23:52 +01:00
39885645b9 Add support for protected Attribute accessors (#1339)
* Add support for protected Attribute accessors

* Fix formatting

* Prevent accessors methods marked as private from being added

* Exclude specific accessors based on trait instead of class

* Add changelog entry

* Add clarifying comment

* Fix accessor attributes not working on PHP < 8.1

* Reintroduce method variable to reduce PR clutter

* Change variable name to reduce PR clutter

* Update CHANGELOG.md

---------

Co-authored-by: Barry vd. Heuvel <[email protected]>
Co-authored-by: Barry vd. Heuvel <[email protected]>
2023-02-20 09:44:01 +01:00
Barry vd. Heuvel aa1aa66ee6 Update CHANGELOG.md 2023-02-20 09:40:08 +01:00
b70a9f5048 add immutable_date/time:* casts (#1380)
* add immutable_date/time:* casts

* fix style

* Update CHANGELOG.md

---------

Co-authored-by: Barry vd. Heuvel <[email protected]>
Co-authored-by: Barry vd. Heuvel <[email protected]>
2023-02-20 09:36:24 +01:00
Wim Reckmanandlaravel-ide-helper 9f97f7cd5f Refactor resolving of null information for custom casted attribute types (#1330)
* Refactor resolving of null information for custom casted attribute types

* composer fix-style

---------

Co-authored-by: laravel-ide-helper <[email protected]>
2023-02-20 09:29:48 +01:00
Markus Podar 97fd0e0a2d Update changelog after new release 2.13.0 (#1418) 2023-02-04 22:04:42 +01:00
Alies Lapatsin 9f5670b7e9 Bump Psalm version (#1410)
SSH facade removed from Laravel 5:
 - https://github.com/laravel/framework/tree/v8.83.27/src/Illuminate/Support/Facades
 - https://github.com/laravel/framework/tree/v9.48.0/src/Illuminate/Support/Facades
  - https://github.com/laravel/framework/tree/10.x/src/Illuminate/Support/Facades
2023-02-04 22:04:01 +01:00
Barry vd. Heuvel 1d302435ef Update composer.json 2023-02-04 16:23:19 +01:00
Bartlomiej Kwarcinski 81d5b223ff Fix Castables issue #1312 (#1388)
* Return Castable class if failed to detect it from return types

* fix-style

* Add CHANGELOG.md entry
2023-02-04 14:56:40 +01:00
Alies LapatsinandBarry vd. Heuvel ce24d4b013 Added support for Laravel 10 (+ update testing matrix) (#1407)
* Laravel 10 support

* Add events v10 to suggestions

* Exclude invalid combinations from testing matrix, test on PHP 8.2

* Update CHANGELOG.md

* Use laravel/laravel dev-master as 10.x version

* Exclude one more laravel-php combination

* Use 10.* instead if dev-master

* Update run-integration-tests.yml

---------

Co-authored-by: Barry vd. Heuvel <[email protected]>
2023-02-04 14:54:33 +01:00
Barry vd. Heuvel edfb05621c IDE Helper for Laravel 2023-02-01 17:24:13 +01:00
Taner KucukyurukandMarkus Podar f0e4cf5e78 Generics annotations support (#1298)
* option to use generics syntax, default to yes in laravel 9

* rename `use_generics_syntax` to `use_generics_annotations`

* update readme and changelog

* remove laravel 9 default override

* include key type in generics annotations

* readme rewording

* set `use_generics_annotations` to `true` by default

* update tests to reflect `use_generics_annotations` being set to `true` by default

* default `use_generics_annotations` setting to true when not set in config

Co-authored-by: Markus Podar <[email protected]>

---------

Co-authored-by: Markus Podar <[email protected]>
2023-01-28 16:48:05 +01:00
Markus Podar 5d9925bab8 gha: fix workflow by allowing the composer-normalize plugin (#1412)
* gha: fix workflow by allowing the composer-normalize plugin

We don't need to enable it in the project itself, but at least in this
workflow which explicitly uses it.

See https://github.com/barryvdh/laravel-ide-helper/actions/runs/3980013548/jobs/6822812621#step:4:34
```
Error: ergebnis/composer-normalize (installed globally) contains a Composer plugin which is blocked by your allow-plugins config. You may add it to the list if you consider it safe.
You can run "composer global config --no-plugins allow-plugins.ergebnis/composer-normalize [true|false]" to enable it (true) or disable it explicitly and suppress this exception (false)
```

* gha: also run this workflow when it is changed itself
2023-01-24 17:32:39 +01:00
Stef van EschandBarry vd. Heuvel 9e50460017 Added support for Laravel 10 (#1406)
* Added support for Laravel 10

* Update run-tests.yml

* Update run-tests.yml

* Update run-integration-tests.yml

Co-authored-by: Barry vd. Heuvel <[email protected]>
2023-01-22 15:01:32 +01:00
Barry vd. Heuvelandlaravel-ide-helper b55769213c Use dev instead of stable (#1409)
* Update run-integration-tests.yml

* composer fix-style

* Update run-integration-tests.yml

Co-authored-by: laravel-ide-helper <[email protected]>
2023-01-22 15:01:12 +01:00
Bentley O'Kane-Chase f055d42b39 Add phpstorm metadata for mock methods when testing (#1405)
* Add phpstorm metadata for testing

* Update CHANGELOG.md
2023-01-17 12:37:15 +01:00
sforwardandSimon Verwaard dda200fd34 Add support for CastsInboundAttributes (#1329)
* Add support for CastsInboundAttributes

* Update changelog

Co-authored-by: Simon Verwaard <[email protected]>
2022-09-13 10:42:06 +02:00
Markus Podar e8ecb3da88 Merge pull request #1367 from krsriq/patch-1 2022-08-21 11:42:25 +02:00
Daniel Schmelz e49c4556dd Fix typo 2022-08-21 08:40:17 +02:00
Daniel Schmelz 2c96c45d5e Fix typos 2022-08-20 10:50:21 +02:00
sforwardandSimon Verwaard 532ae5bec3 Fix database name (#1364)
Co-authored-by: Simon Verwaard <[email protected]>
2022-08-13 22:02:45 +02:00
JefemyandBarry vd. Heuvel c8f0f914e3 Fix issue where \Eloquent is not included when using write_mixin (#1352)
* Check for exact mixin name when writing

* changelog

* add mixin to test class

Co-authored-by: Barry vd. Heuvel <[email protected]>
2022-08-11 12:39:26 +02:00
KentarouTakeda 07f5eaea73 Fix return type of methods provided by SoftDeletes (#1345)
* Fix return type of methods provided by `SoftDeletes`

* Update CHANGELOG

* fix test / update snapshot
2022-08-11 12:36:43 +02:00
Corey McCormick c76fbb5b61 Allow for proper database resolve with schemas (#1349)
* Allow for proper database resolve with schemas

* Remove need to explode database and table name
2022-08-11 12:35:46 +02:00
angeljqv c40fee2a3f Update .gitattributes (#1355) 2022-08-11 12:32:48 +02:00
Wim Reckman 5eadd2c7de Fix model factory method arguments for Laravel >= 9 (#1361) 2022-08-11 12:32:14 +02:00
Barry vd. Heuvelandlaravel-ide-helper 6e26f22c76 Feat useclassmappackage (#1357)
* Use composer/class-map-generator

* composer fix-style

Co-authored-by: laravel-ide-helper <[email protected]>
2022-06-20 15:54:12 +02:00
JefemyandMarkus Podar ee9188acf1 Implement new config to specify return type of custom relations (#1300)
* Implement new config to specify return type of custom relations

* Apply suggestions from code review

Co-authored-by: Markus Podar <[email protected]>

* add test for morphed

* fix test output

* add info about how to add custom relationships

* fix wording

Co-authored-by: Markus Podar <[email protected]>
2022-05-22 20:07:54 +02:00
Markus Podar a567f73140 readme: explicitly state supported version (#1348)
Based on the discussion in https://github.com/barryvdh/laravel-ide-helper/issues/1347
2022-05-21 22:40:30 +02:00
Markus Podar 6a461a7c47 Fix integration tests by fixing a PHP 8.1+ deprecation warnings in ReflectionClass (#1351)
* gha: get more insights when/if logs exist

* Better handle cases when we can receive a concrete instance

The problem with `null` being passed to `ReflectionClass` was always
there but in PHP 8.1+ it triggers a deprecation warnings.

Since having `null` in `$concrete` doesn't make sense to reflect
anything anyway, we just throw a custom exception (which gets caught a
couple lines below) and just carry on.

When using `-v` this can be seen, example:
```
$ ./artisan ide-helper:meta -v
Cannot make 'Faker\Generator': Class 'Faker\Provider\en_US\Barcode' not found.
Cannot make 'Illuminate\Contracts\Auth\Authenticatable': Class  does not exist
Cannot make 'cache.psr6': Class 'Symfony\Component\Cache\Adapter\Psr16Adapter' not found.
Cannot make 'csp-nonce': Class 'Wza3Mf4CXIvCkcp9K3boMUGJoK6S9maO' not found.
Cannot make 'env': Class 'local' not found.
Cannot make 'filesystem.cloud': Disk [s3] does not have a configured driver.
Cannot make 'redis.connection': Redis connection [default] not configured.
A new meta file was written to .phpstorm.meta.php
```

* gha: make sure to run meta with -v to see all output

Helps when debugging things

* Add CHANGELOG.md entry
2022-05-21 22:38:28 +02:00
Barry vd. Heuvel 3ba1e2573b Update CHANGELOG.md 2022-03-06 15:33:42 +01:00
Barry vd. Heuvelandbarryvdh 6b58c23e6f Update composer.json (#1327)
* Update composer.json

* normalize composer.json

Co-authored-by: barryvdh <[email protected]>
2022-03-06 15:31:47 +01:00
FLeudts 6041681495 Add support for Carbon serialization options (#1324)
* Add Carbon serialization option handling

* Tests Added

* Add changelog

* Spellcheck
2022-03-04 09:12:42 +01:00
Barry vd. Heuvel ddb74fb5c8 Test 9.* integration (#1314) 2022-02-09 08:09:10 +01:00
Barry vd. Heuvel 7917cce7c9 Update CHANGELOG.md 2022-02-08 20:30:33 +01:00
Barry vd. Heuvel 6627cb9587 Normalize composer.json 2022-02-08 20:26:43 +01:00
Barry vd. Heuvelandlaravel-ide-helper 3b03e4055d Replace composer with copy of classmap generator (#1313)
* Replace composer with copy of classmap generator

* composer fix-style

* Remove phpcleaner

* composer fix-style

* Use filecleaner copy

* composer fix-style

Co-authored-by: laravel-ide-helper <[email protected]>
2022-02-08 20:20:22 +01:00
Barry vd. Heuvel a227fca325 Update README.md 2022-01-30 13:44:04 +01:00
Markus Podar 999167d4c2 Prepare 2.12.1 patch release (#1307)
### Fixed
- Properly handle `Castable`s without return type. [#1306 / binotaliu](https://github.com/barryvdh/laravel-ide-helper/pull/1306)
2022-01-24 22:36:43 +01:00
BinotaLIU 2673bf4889 return mixed if we failed detect castable type (#1306)
fixed #1305
2022-01-24 21:39:17 +01:00
81 changed files with 1360 additions and 374 deletions
+6
View File
@@ -5,5 +5,11 @@
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/.editorconfig export-ignore
/phpunit.xml.dist export-ignore
/tests export-ignore
/.php_cs.common.php export-ignore
/.php_cs.dist export-ignore
/.php_cs.tests.php export-ignore
/psalm.xml export-ignore
/psalm-baseline.xml export-ignore
-1
View File
@@ -8,7 +8,6 @@ labels: bug
### Versions:
- ide-helper Version: #.#.#
- Laravel Version: #.#.# <!-- remove if not applicable -->
- Lumen Version: #.#.# <!-- remove if not applicable -->
- PHP Version: #.#.#
### Description:
@@ -8,7 +8,6 @@ labels: question
### Versions:
- ide-helper Version: #.#.#
- Laravel Version: #.#.# <!-- remove if not applicable -->
- Lumen Version: #.#.# <!-- remove if not applicable -->
- PHP Version: #.#.#
### Question:
+10
View File
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
groups:
deps:
patterns:
- '*'
+4 -2
View File
@@ -3,6 +3,7 @@ name: normalize composer.json
on:
push:
paths:
- .github/workflows/composer-normalize.yml
- composer.json
jobs:
@@ -11,16 +12,17 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Git checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Validate Composer configuration
run: composer validate --strict
- name: Normalize composer.json
run: |
composer global config --no-plugins allow-plugins.ergebnis/composer-normalize true
composer global require ergebnis/composer-normalize
composer normalize
- uses: stefanzweifel/git-auto-commit-action@v4.0.0
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: normalize composer.json
+2 -2
View File
@@ -13,7 +13,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
@@ -27,7 +27,7 @@ jobs:
- run: composer fix-style
continue-on-error: true
- uses: stefanzweifel/git-auto-commit-action@v4
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: composer fix-style
commit_author: laravel-ide-helper <[email protected]>
+20 -68
View File
@@ -11,81 +11,25 @@ on:
- cron: '0 0 * * *'
jobs:
php-lumen-integration-tests:
runs-on: ubuntu-20.04
timeout-minutes: 15
env:
COMPOSER_NO_INTERACTION: 1
strategy:
matrix:
php: [8.1, 8.0, 7.4, 7.3]
lumen: [8.*]
name: P${{ matrix.php }} - Lumen${{ matrix.lumen }}
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
path: src
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
- name: Install dependencies
run: |
composer create-project --prefer-dist laravel/lumen:${{ matrix.lumen }} --no-progress sample
cd sample
composer require "league/flysystem:^1" --no-update --no-progress
composer update --prefer-stable --prefer-dist --no-progress
- name: Add package from source
run: |
cd sample
sed -e 's|"type": "project",|&\n"repositories": [ { "type": "path", "url": "../src" } ],|' -i composer.json
composer require --dev "barryvdh/laravel-ide-helper:*"
- name: Insert service provider
run: sed -e 's|// \$app->register(App\\\Providers\\\EventServiceProvider::class);|&\n$app->register(\\Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider::class);|' -i sample/bootstrap/app.php
- name: Execute generate run
run: |
cd sample
php artisan ide-helper:generate
- name: Execute meta run
run: |
cd sample
php artisan ide-helper:meta
- name: Check file existence
run: |
ls sample/_ide_helper.php
ls sample/.phpstorm.meta.php
- name: Check file count in logs
run: |
if [ `ls -1q "sample/storage/logs/" | wc -l` -gt 0 ];then exit 1;fi
php-laravel-integration-tests:
runs-on: ubuntu-20.04
timeout-minutes: 15
env:
COMPOSER_NO_INTERACTION: 1
strategy:
fail-fast: false
matrix:
php: [8.1, 8.0, 7.4, 7.3]
laravel: [8.*]
php: [8.3, 8.2, 8.1, 8.0]
laravel: [10.*, 9.*]
exclude:
- php: 7.4
laravel: 9.*
- php: 7.3
- php: 8.0
laravel: 10.*
- php: 8.3
laravel: 9.*
name: P${{ matrix.php }} - Laravel${{ matrix.laravel }}
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
path: src
@@ -97,15 +41,16 @@ jobs:
- name: Install dependencies
run: |
composer create-project --prefer-dist laravel/laravel:${{ matrix.laravel }} --no-progress sample
composer create-project --prefer-dist laravel/laravel:${{ matrix.laravel }} --stability=dev --no-progress sample
cd sample
composer config minimum-stability dev
composer update --prefer-stable --prefer-dist --no-progress
- name: Add package from source
run: |
cd sample
sed -e 's|"type": "project",|&\n"repositories": [ { "type": "path", "url": "../src" } ],|' -i composer.json
composer require --dev "barryvdh/laravel-ide-helper:*"
composer require --dev "barryvdh/laravel-ide-helper:*" --with-all-dependencies
- name: Execute generate run
run: |
@@ -115,13 +60,20 @@ jobs:
- name: Execute meta run
run: |
cd sample
php artisan ide-helper:meta
php artisan ide-helper:meta -v
- name: Check file existence
run: |
ls sample/_ide_helper.php
ls sample/.phpstorm.meta.php
- name: Check file count in logs
- name: Check logs
run: |
if [ `ls -1q "sample/storage/logs/" | wc -l` -gt 0 ];then exit 1;fi
if [ `ls -1q "sample/storage/logs/" | wc -l` -gt 0 ]; then
for logfile in sample/storage/logs/*; do
echo "-- $logfile --"
cat $logfile
done
exit 1
fi
+2 -2
View File
@@ -12,12 +12,12 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
php-version: 8.1
coverage: none
extensions: pdo_sqlite
+5 -11
View File
@@ -20,20 +20,14 @@ jobs:
strategy:
matrix:
os: [ubuntu-20.04, windows-2019]
php: [8.1, 8.0, 7.4, 7.3]
laravel: [8.*, 9.*]
php: [8.3, 8.2, 8.1, 8.0]
laravel: [9.*, 10.*]
dependency-version: [prefer-lowest, prefer-stable]
exclude:
- php: 8.0
laravel: 10.*
- php: 8.0
dependency-version: prefer-lowest
- php: 7.4
laravel: 9.*
- php: 7.3
laravel: 9.*
- os: windows-2019
php: 7.4
- os: windows-2019
php: 7.3
steps:
- name: Set git to use LF
if: ${{ matrix.os == 'windows-2019' }}
@@ -42,7 +36,7 @@ jobs:
git config --global core.eol lf
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
+3 -3
View File
@@ -1,8 +1,8 @@
.phpunit.result.cache
/.idea
/.php_cs
/.php_cs.cache
/.php_cs.tests.cache
/.php-cs-fixer.cache
/.php-cs-fixer.php
/.php-cs-fixer.tests.cache
/composer.lock
/vendor
@@ -30,7 +30,6 @@ return [
],
'return_type_declaration' => true,
'short_scalar_cast' => true,
'single_blank_line_before_namespace' => true,
'single_trait_insert_per_statement' => true,
'ternary_operator_spaces' => true,
'visibility_required' => [
@@ -56,7 +55,7 @@ return [
'no_unused_imports' => true,
'single_quote' => true,
'space_after_semicolon' => true,
'trailing_comma_in_multiline_array' => true,
'trailing_comma_in_multiline' => true,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'whitespace_after_comma_in_array' => true,
+3 -3
View File
@@ -5,10 +5,10 @@ $finder = PhpCsFixer\Finder::create()
->in(__DIR__)
->exclude('tests');
$config = require __DIR__ . '/.php_cs.common.php';
$config = require __DIR__ . '/.php-cs-fixer.common.php';
return PhpCsFixer\Config::create()
return (new PhpCsFixer\Config())
->setFinder($finder)
->setRules($config)
->setRiskyAllowed(true)
->setCacheFile(__DIR__ . '/.php_cs.cache');
->setCacheFile(__DIR__ . '/.php-cs-fixer.cache');
@@ -5,7 +5,7 @@ $finder = PhpCsFixer\Finder::create()
->in(__DIR__ . '/tests')
->exclude('__snapshots__');
$config = require __DIR__ . '/.php_cs.common.php';
$config = require __DIR__ . '/.php-cs-fixer.common.php';
// Additional rules for tests
$config = array_merge(
@@ -15,8 +15,8 @@ $config = array_merge(
]
);
return PhpCsFixer\Config::create()
return (new PhpCsFixer\Config())
->setFinder($finder)
->setRules($config)
->setRiskyAllowed(true)
->setCacheFile(__DIR__ . '/.php_cs.tests.cache');
->setCacheFile(__DIR__ . '/.php-cs-fixer.tests.cache');
+57 -1
View File
@@ -2,14 +2,70 @@
All notable changes to this project will be documented in this file.
[Next release](https://github.com/barryvdh/laravel-ide-helper/compare/v2.12.0...master)
[Next release](https://github.com/barryvdh/laravel-ide-helper/compare/v2.14.0...master)
--------------
### Changed
- Removed support for Laravel 8 and therefore for PHP < 8.0 [#1504 / mfn](https://github.com/barryvdh/laravel-ide-helper/pull/1504)
### Added
- Add support for enum default arguments using enum cases. [#1464 / d8vjork](https://github.com/barryvdh/laravel-ide-helper/pull/1464)
- Add support for real-time facades in the helper file. [#1455 / filipac](https://github.com/barryvdh/laravel-ide-helper/pull/1455)
2024-02-05, 2.14.0
------------------
### Changed
- Official support for Lumen has been dropped [#1425 / mfn](https://github.com/barryvdh/laravel-ide-helper/pull/1425)
- Refactor resolving of null information for custom casted attribute types [#1330 / wimski](https://github.com/barryvdh/laravel-ide-helper/pull/1330)
### Fixed
- Add support for attribute accessors marked as protected. [#1339 / pindab0ter](https://github.com/barryvdh/laravel-ide-helper/pull/1339)
- Catch exceptions when loading aliases [#1465 / dongm2ez](https://github.com/barryvdh/laravel-ide-helper/pull/1465)
### Added
- Add support for nikic/php-parser 5 (next to 4) [#1502 / mfn](https://github.com/barryvdh/laravel-ide-helper/pull/1502)
- Add support for `immutable_date:*` and `immutable_datetime:*` casts. [#1380 / thekonz](https://github.com/barryvdh/laravel-ide-helper/pull/1380)
2023-02-04, 2.13.0
------------------
### Fixed
- Fix return type of methods provided by `SoftDeletes` [#1345 / KentarouTakeda](https://github.com/barryvdh/laravel-ide-helper/pull/1345)
- Handle PHP 8.1 deprecation warnings when passing `null` to `new \ReflectionClass` [#1351 / mfn](https://github.com/barryvdh/laravel-ide-helper/pull/1351)
- Fix issue where \Eloquent is not included when using write_mixin [#1352 / Jefemy](https://github.com/barryvdh/laravel-ide-helper/pull/1352)
- Fix model factory method arguments for Laravel >= 9 [#1361 / wimski](https://github.com/barryvdh/laravel-ide-helper/pull/1361)
- Improve return type of mock helper methods in tests [#1405 / bentleyo](https://github.com/barryvdh/laravel-ide-helper/pull/1405)
- Fix Castable class if failed to detect it from return types [#1388 / kwarcu](https://github.com/barryvdh/laravel-ide-helper/pull/1388)
### Added
- Added Laravel 10 support [#1407 / lptn](https://github.com/barryvdh/laravel-ide-helper/pull/1407)
- Add support for custom casts that implement `CastsInboundAttributes` [#1329 / sforward](https://github.com/barryvdh/laravel-ide-helper/pull/1329)
- Add option `use_generics_annotations` for collection type hints [#1298 / tanerkay](https://github.com/barryvdh/laravel-ide-helper/pull/1298)
2022-03-06, 2.12.3
------------------
### Fixed
- Fix date and datetime handling for attributes that set a serialization format option for the Carbon instance [#1324 / FLeudts](https://github.com/barryvdh/laravel-ide-helper/pull/1324)
- Fix composer conflict with composer/pcre version 2/3. [#1327 / barryvdh](https://github.com/barryvdh/laravel-ide-helper/pull/1327)
2022-02-08, 2.12.2
------------------
### Fixed
- Remove composer dependecy, use copy of ClassMapGenerator [#1313 / barryvdh](https://github.com/barryvdh/laravel-ide-helper/pull/1313)
2022-01-24, 2.12.1
------------------
### Fixed
- Properly handle `Castable`s without return type. [#1306 / binotaliu](https://github.com/barryvdh/laravel-ide-helper/pull/1306)
2022-01-23, 2.12.0
------------------
### Added
- Add support for custom casts that using `Castable` [#1287 / binotaliu](https://github.com/barryvdh/laravel-ide-helper/pull/1287)
- Added Laravel 9 support [#1297 / rcerljenko](https://github.com/barryvdh/laravel-ide-helper/pull/1297)
- Added option `additional_relation_return_types` for custom relations that don't fit the typical naming scheme
2022-01-03, 2.11.0
------------------
+49 -83
View File
@@ -1,15 +1,18 @@
# Laravel IDE Helper Generator
# IDE Helper Generator for Laravel
[![Latest Version on Packagist][ico-version]][link-packagist]
[![Software License][ico-license]](LICENSE.md)
[![Build Status][ico-gha]][link-gha]
[![Total Downloads][ico-downloads]][link-downloads]
[![Tests](https://github.com/barryvdh/laravel-ide-helper/actions/workflows/run-tests.yml/badge.svg)](https://github.com/barryvdh/laravel-ide-helper/actions)
[![Packagist License](https://poser.pugx.org/barryvdh/laravel-ide-helper/license.png)](http://choosealicense.com/licenses/mit/)
[![Latest Stable Version](https://poser.pugx.org/barryvdh/laravel-ide-helper/version.png)](https://packagist.org/packages/barryvdh/laravel-ide-helper)
[![Total Downloads](https://poser.pugx.org/barryvdh/laravel-ide-helper/d/total.png)](https://packagist.org/packages/barryvdh/laravel-ide-helper)
[![Fruitcake](https://img.shields.io/badge/Powered%20By-Fruitcake-b2bc35.svg)](https://fruitcake.nl/)
**Complete PHPDocs, directly from the source**
This package generates helper files that enable your IDE to provide accurate autocompletion.
Generation is done based on the files in your project, so they are always up-to-date.
It supports Laravel 9+ and PHP 8.0+
- [Installation](#installation)
- [Usage](#usage)
- [Automatic PHPDoc generation for Laravel Facades](#automatic-phpdoc-generation-for-laravel-facades)
@@ -20,10 +23,6 @@ Generation is done based on the files in your project, so they are always up-to-
- [Automatic PHPDocs generation for Laravel Fluent methods](#automatic-phpdocs-generation-for-laravel-fluent-methods)
- [Auto-completion for factory builders](#auto-completion-for-factory-builders)
- [PhpStorm Meta for Container instances](#phpstorm-meta-for-container-instances)
- [Usage with Lumen](#usage-with-lumen)
- [Enabling Facades](#enabling-facades)
- [Adding the Service Provider](#adding-the-service-provider)
- [Adding Additional Facades](#adding-additional-facades)
- [License](#license)
## Installation
@@ -34,6 +33,10 @@ Require this package with composer using the following command:
composer require --dev barryvdh/laravel-ide-helper
```
> [!NOTE]
> If you encounter version conflicts with doctrine/dbal, please try:
> `composer require --dev barryvdh/laravel-ide-helper --with-all-dependencies`
This package makes use of [Laravels package auto-discovery mechanism](https://medium.com/@taylorotwell/package-auto-discovery-in-laravel-5-5-ea9e3ab20518), which means if you don't install dev dependencies in production, it also won't be loaded.
If for some reason you want manually control this:
@@ -69,7 +72,7 @@ If for some reason you want manually control this:
_Check out [this Laracasts video](https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15) for a quick introduction/explanation!_
- `php artisan ide-helper:generate` - [PHPDoc generation for Laravel Facades ](#automatic-phpdoc-generation-for-laravel-facades)
- `php artisan ide-helper:models` - [PHPDocs for models](#automatic-PHPDocs-for-models)
- `php artisan ide-helper:models` - [PHPDocs for models](#automatic-phpdocs-for-models)
- `php artisan ide-helper:meta` - [PhpStorm Meta file](#phpstorm-meta-for-container-instances)
@@ -110,6 +113,10 @@ The generator tries to identify the real class, but if it cannot be found, you c
Some classes need a working database connection. If you do not have a default working connection, some facades will not be included.
You can use an in-memory SQLite driver by adding the `-M` option.
If you use [real-time facades](https://laravel.com/docs/master/facades#real-time-facades) in your app, those will also be included in the generated file using a `@mixin` annotation and extending the original class underneath the facade.
**Note**: this feature uses the generated real-time facades files in the `storage/framework/cache` folder. Those files are generated on-demand as you use the real-time facade, so if the framework has not generated that first, it will not be included in the helper file. Run the route/command/code first and then regenerate the helper file and this time the real-time facade will be included in it.
You can choose to include helper files. This is not enabled by default, but you can override it with the `--helpers (-H)` option.
The `Illuminate/Support/helpers.php` is already set up, but you can add/remove your own files in the config file.
@@ -142,9 +149,9 @@ The class name will be different from the model, avoiding the IDE duplicate anno
> Please make sure to back up your models, before writing the info.
Writing to the models should keep the existing comments and only append new properties/methods.
The existing PHPDoc is replaced, or added if not found.
With the `--reset (-R)` option, the existing PHPDocs are ignored, and only the newly found columns/relations are saved as PHPDocs.
Writing to the models should keep the existing comments and only append new properties/methods. It will not update changed properties/methods.
With the `--reset (-R)` option, the whole existing PHPDoc is replaced, including any comments that have been made. The `--smart-reset` option will instead keep the 'text' part of the phpdoc comment, and just replace all the property/method defininitions.
```bash
php artisan ide-helper:models "App\Models\Post"
@@ -224,6 +231,12 @@ You may use the [`::withCount`](https://laravel.com/docs/master/eloquent-relatio
By default, these attributes are generated in the phpdoc. You can turn them off by setting the config `write_model_relation_count_properties` to `false`.
#### Generics annotations
Laravel 9 introduced generics annotations in DocBlocks for collections. PhpStorm 2022.3 and above support the use of generics annotations within `@property` and `@property-read` declarations in DocBlocks, e.g. `Collection<User>` instead of `Collection|User[]`.
These can be disabled by setting the config `use_generics_annotations` to `false`.
#### Support `@comment` based on DocBlock
In order to better support IDEs, relations and getters/setters can also add a comment to a property like table columns. Therefore a custom docblock `@comment` is used:
@@ -278,6 +291,26 @@ For those special cases, you can map them via the config `custom_db_types`. Exam
],
```
#### Custom Relationship Types
If you are using relationships not built into Laravel you will need to specify the name and returning class in the config to get proper generation.
```php
'additional_relation_types' => [
'externalHasMany' => \My\Package\externalHasMany::class
],
```
Found relationships will typically generate a return value based on the name of the relationship.
If your custom relationships don't follow this traditional naming scheme you can define its return type manually. The available options are `many` and `morphTo`.
```php
'additional_relation_return_types' => [
'externalHasMultiple' => 'many'
],
```
#### Model Hooks
If you need additional information on your model from sources that are not handled by default, you can hook in to the
@@ -324,7 +357,7 @@ If you need PHPDocs support for Fluent methods in migration, for example
$table->string("somestring")->nullable()->index();
```
After publishing vendor, simply change the `include_fluent` line your `config/ide-helper.php` file into:
After publishing vendor, simply change the `include_fluent` line in your `config/ide-helper.php` file into:
```php
'include_fluent' => true,
@@ -335,7 +368,7 @@ Then run `php artisan ide-helper:generate`, you will now see all Fluent methods
### Auto-completion for factory builders
If you would like the `factory()->create()` and `factory()->make()` methods to return the correct model class,
you can enable custom factory builders with the `include_factory_builders` line your `config/ide-helper.php` file.
you can enable custom factory builders with the `include_factory_builders` line in your `config/ide-helper.php` file.
Deprecated for Laravel 8 or latest.
```php
@@ -373,76 +406,9 @@ app(App\SomeClass::class);
> Note: When you receive a FatalException: class not found, check your config
> (for example, remove S3 as cloud driver when you don't have S3 configured. Remove Redis ServiceProvider when you don't use it).
You can change the generated filename via the config `meta_filename`. This can be useful for cases you want to take advantage the PhpStorm also supports the _directory_ `.phpstorm.meta.php/` which would parse any file places there, should your want provide additional files to PhpStorm.
## Usage with Lumen
This package is focused on Laravel development, but it can also be used in Lumen with some workarounds.
Because Lumen works a little different, as it is like a bare bone version of Laravel and the main configuration
parameters are instead located in `bootstrap/app.php`, some alterations must be made.
### Enabling Facades
While Laravel IDE Helper can generate automatically default Facades for code hinting,
Lumen doesn't come with Facades activated. If you plan in using them, you must enable
them under the `Create The Application` section, uncommenting this line:
```php
// $app->withFacades();
```
From there, you should be able to use the `create_alias()` function to add additional Facades into your application.
### Adding the Service Provider
You can install Laravel IDE Helper in `app/Providers/AppServiceProvider.php`,
and uncommenting this line that registers the App Service Providers, so it can properly load.
```php
// $app->register(App\Providers\AppServiceProvider::class);
```
If you are not using that line, that is usually handy to manage gracefully multiple Laravel/Lumen installations,
you will have to add this line of code under the `Register Service Providers` section of your `bootstrap/app.php`.
```php
if ($app->environment() !== 'production') {
$app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
}
```
After that, Laravel IDE Helper should work correctly. During the generation process,
the script may throw exceptions saying that some Class(s) doesn't exist or there are some undefined indexes.
This is normal, as Lumen has some default packages stripped away, like Cookies, Storage and Session.
If you plan to add these packages, you will have to add them manually and create additional Facades if needed.
### Adding Additional Facades
Currently, Lumen IDE Helper doesn't take into account additional Facades created under `bootstrap/app.php` using `create_alias()`,
so you need to create a `config/app.php` file and add your custom aliases under an `aliases` array again, like so:
```php
return [
'aliases' => [
'CustomAliasOne' => Example\Support\Facades\CustomAliasOne::class,
'CustomAliasTwo' => Example\Support\Facades\CustomAliasTwo::class,
//...
]
];
```
After you run `php artisan ide-helper:generate`, it's recommended (but not mandatory) to rename `config/app.php` to something else,
until you have to re-generate the docs or after passing to production environment.
Lumen 5.1+ will read this file for configuration parameters if it is present, and may overlap some configurations if it is completely populated.
You can change the generated filename via the config `meta_filename`. This can be useful for cases where you want to take advantage of PhpStorm's support of the _directory_ `.phpstorm.meta.php/`: all files placed there are parsed, should you want to provide additional files to PhpStorm.
## License
The Laravel IDE Helper Generator is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
[ico-version]: https://img.shields.io/packagist/v/barryvdh/laravel-ide-helper.svg?style=flat-square
[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square
[ico-gha]: https://github.com/barryvdh/laravel-ide-helper/workflows/Tests/badge.svg
[ico-downloads]: https://img.shields.io/packagist/dt/barryvdh/laravel-ide-helper.svg?style=flat-square
[link-packagist]: https://packagist.org/packages/barryvdh/laravel-ide-helper
[link-gha]: https://github.com/barryvdh/laravel-ide-helper/actions
[link-downloads]: https://packagist.org/packages/barryvdh/laravel-ide-helper
+20 -17
View File
@@ -20,30 +20,30 @@
}
],
"require": {
"php": "^7.3 || ^8.0",
"php": "^8.0",
"ext-json": "*",
"barryvdh/reflection-docblock": "^2.0.6",
"composer/composer": "^1.10.23 || ^2.1.9",
"doctrine/dbal": "^2.6 || ^3",
"illuminate/console": "^8 || ^9",
"illuminate/filesystem": "^8 || ^9",
"illuminate/support": "^8 || ^9",
"nikic/php-parser": "^4.7",
"composer/class-map-generator": "^1.0",
"doctrine/dbal": "^2.6 || ^3.1.4",
"illuminate/console": "^9 || ^10",
"illuminate/filesystem": "^9 || ^10",
"illuminate/support": "^9 || ^10",
"nikic/php-parser": "^4.18 || ^5",
"phpdocumentor/type-resolver": "^1.1.0"
},
"require-dev": {
"ext-pdo_sqlite": "*",
"friendsofphp/php-cs-fixer": "^2",
"illuminate/config": "^8 || ^9",
"illuminate/view": "^8 || ^9",
"friendsofphp/php-cs-fixer": "^3",
"illuminate/config": "^9 || ^10",
"illuminate/view": "^9 || ^10",
"mockery/mockery": "^1.4",
"orchestra/testbench": "^6 || ^7",
"phpunit/phpunit": "^8.5 || ^9",
"spatie/phpunit-snapshot-assertions": "^3 || ^4",
"vimeo/psalm": "^3.12"
"orchestra/testbench": "^7 || ^8",
"phpunit/phpunit": "^9",
"spatie/phpunit-snapshot-assertions": "^4",
"vimeo/psalm": "^5.4"
},
"suggest": {
"illuminate/events": "Required for automatic helper generation (^6|^7|^8|^9)."
"illuminate/events": "Required for automatic helper generation (^6|^7|^8|^9|^10)."
},
"minimum-stability": "dev",
"prefer-stable": true,
@@ -58,11 +58,14 @@
}
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true
},
"sort-packages": true
},
"extra": {
"branch-alias": {
"dev-master": "2.12-dev"
"dev-master": "2.14-dev"
},
"laravel": {
"providers": [
@@ -78,7 +81,7 @@
],
"fix-style": [
"php-cs-fixer fix",
"php-cs-fixer fix --config=.php_cs.tests.php"
"php-cs-fixer fix --config=.php-cs-fixer.tests.php"
],
"psalm-set-baseline": "psalm --set-baseline=psalm-baseline.xml",
"test": "phpunit",
+24
View File
@@ -292,6 +292,17 @@ return [
*/
'force_fqn' => false,
/*
|--------------------------------------------------------------------------
| Use generics syntax
|--------------------------------------------------------------------------
|
| Use generics syntax within DocBlocks,
| e.g. `Collection<User>` instead of `Collection|User[]`.
|
*/
'use_generics_annotations' => true,
/*
|--------------------------------------------------------------------------
| Additional relation types
@@ -304,6 +315,19 @@ return [
*/
'additional_relation_types' => [],
/*
|--------------------------------------------------------------------------
| Additional relation return types
|--------------------------------------------------------------------------
|
| When using custom relation types its possible for the class name to not contain
| the proper return type of the relation. The key of the array is the relationship
| method name. The value of the array is the return type of the relation.
| e.g. `'relationName' => 'many'`.
|
*/
'additional_relation_return_types' => [],
/*
|--------------------------------------------------------------------------
| Run artisan commands after migrations to generate model helpers
+9 -5
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="3.15@de6e7f324f44dde540ebe7ebd4eb481b97c86f30">
<files psalm-version="5.4.0@62db5d4f6a7ae0a20f7cc5a4952d730272fc0863">
<file src="src/Factories.php">
<UndefinedClass occurrences="2">
<code>Factory</code>
@@ -7,14 +7,18 @@
</UndefinedClass>
</file>
<file src="src/Generator.php">
<UndefinedClass occurrences="7">
<UndefinedClass occurrences="6">
<code>\Auth</code>
<code>\Cache</code>
<code>\Cache</code>
<code>\DB</code>
<code>\Cache</code>
<code>\Cache</code>
<code>\Queue</code>
<code>\SSH</code>
<code>\Storage</code>
</UndefinedClass>
</file>
<file src="src/Console/ModelsCommand.php">
<UndefinedClass occurrences="1">
<code>\UnitEnum</code>
</UndefinedClass>
</file>
</files>
+21 -13
View File
@@ -8,6 +8,7 @@
*/
?>
/* @noinspection ALL */
// @formatter:off
// phpcs:ignoreFile
@@ -22,15 +23,12 @@
*/
<?php foreach ($namespaces_by_extends_ns as $namespace => $aliases) : ?>
<?php if ($namespace == '\Illuminate\Database\Eloquent') :
continue;
endif; ?>
namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
<?php foreach ($aliases as $alias) : ?>
<?= trim($alias->getDocComment(' ')) ?>
<?= trim($alias->getDocComment(' ')) ?>
<?= $alias->getClassType() ?> <?= $alias->getExtendsClass() ?> {
<?php foreach ($alias->getMethods() as $method) : ?>
<?= trim($method->getDocComment(' ')) ?>
<?= trim($method->getDocComment(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
{<?php if ($method->getDeclaringClass() !== $method->getRoot()) : ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
@@ -41,19 +39,19 @@ namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
<?php endif?>
<?= $method->shouldReturn() ? 'return ' : '' ?><?= $method->getRootMethodCall() ?>;
}
<?php endforeach; ?>
<?php endforeach; ?>
}
<?php endforeach; ?>
<?php endforeach; ?>
}
<?php endforeach; ?>
<?php foreach ($namespaces_by_alias_ns as $namespace => $aliases) : ?>
namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
<?php foreach ($aliases as $alias) : ?>
<?= $alias->getClassType() ?> <?= $alias->getShortName() ?> extends <?= $alias->getExtends() ?> {<?php if ($alias->getExtendsNamespace() == '\Illuminate\Database\Eloquent') : ?>
<?php foreach ($alias->getMethods() as $method) : ?>
<?= trim($method->getDocComment(' ')) ?>
<?php foreach ($alias->getMethods() as $method) : ?>
<?= trim($method->getDocComment(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
{<?php if ($method->getDeclaringClass() !== $method->getRoot()) : ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
@@ -66,14 +64,24 @@ namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
}
<?php endforeach; ?>
<?php endif; ?>}
<?php endforeach; ?>
<?php endforeach; ?>
}
<?php endforeach; ?>
<?php foreach($real_time_facades as $name): ?>
<?php $nested = explode('\\', str_replace('\\' . class_basename($name), '', $name)); ?>
namespace <?php echo implode('\\', $nested); ?> {
/**
* @mixin <?= str_replace('Facades', '', $name) ?>
*/
class <?= class_basename($name) ?> extends <?= str_replace('Facades', '', $name) ?> {}
}
<?php endforeach; ?>
<?php if ($helpers) : ?>
namespace {
<?= $helpers ?>
<?= $helpers ?>
}
<?php endif; ?>
+6
View File
@@ -1,6 +1,8 @@
<?= '<?php' ?>
/* @noinspection ALL */
// @formatter:off
// phpcs:ignoreFile
namespace PHPSTORM_META {
@@ -28,6 +30,10 @@ namespace PHPSTORM_META {
]));
<?php endif; ?>
override(\Illuminate\Foundation\Testing\Concerns\InteractsWithContainer::mock(0), map(["" => "@&\Mockery\MockInterface"]));
override(\Illuminate\Foundation\Testing\Concerns\InteractsWithContainer::partialMock(0), map(["" => "@&\Mockery\MockInterface"]));
override(\Illuminate\Foundation\Testing\Concerns\InteractsWithContainer::instance(0), type(1));
override(\Illuminate\Foundation\Testing\Concerns\InteractsWithContainer::spy(0), map(["" => "@&\Mockery\MockInterface"]));
override(\Illuminate\Support\Arr::add(0), type(0));
override(\Illuminate\Support\Arr::except(0), type(0));
override(\Illuminate\Support\Arr::first(0), elementType(0));
+5 -4
View File
@@ -20,6 +20,7 @@ use Illuminate\Config\Repository as ConfigRepository;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Support\Facades\Facade;
use ReflectionClass;
use Throwable;
class Alias
{
@@ -301,7 +302,7 @@ class Alias
"\nPlease configure your database connection correctly, or use the sqlite memory driver (-M)." .
" Skipping $facade."
);
} catch (\Exception $e) {
} catch (Throwable $e) {
$this->error('Exception: ' . $e->getMessage() . "\nSkipping $facade.");
}
}
@@ -323,12 +324,12 @@ class Alias
protected function addMagicMethods()
{
foreach ($this->magicMethods as $magic => $real) {
list($className, $name) = explode('::', $real);
[$className, $name] = explode('::', $real);
if ((!class_exists($className) && !interface_exists($className)) || !method_exists($className, $name)) {
continue;
}
$method = new \ReflectionMethod($className, $name);
$class = new \ReflectionClass($className);
$class = new ReflectionClass($className);
if (!in_array($magic, $this->usedMethods)) {
if ($class !== $this->root) {
@@ -347,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) {
+2 -2
View File
@@ -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(
+6
View File
@@ -13,6 +13,7 @@ namespace Barryvdh\LaravelIdeHelper\Console;
use Barryvdh\LaravelIdeHelper\Factories;
use Illuminate\Console\Command;
use RuntimeException;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@@ -95,6 +96,11 @@ class MetaCommand extends Command
try {
$concrete = $this->laravel->make($abstract);
if ($concrete === null) {
throw new RuntimeException("Cannot create instance for '$abstract', received 'null'");
}
$reflectionClass = new \ReflectionClass($concrete);
if (is_object($concrete) && !$reflectionClass->isAnonymous()) {
$bindings[$abstract] = get_class($concrete);
+158 -50
View File
@@ -16,12 +16,13 @@ use Barryvdh\Reflection\DocBlock;
use Barryvdh\Reflection\DocBlock\Context;
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
use Barryvdh\Reflection\DocBlock\Tag;
use Composer\Autoload\ClassMapGenerator;
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\Attribute;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Model;
@@ -230,6 +231,7 @@ class ModelsCommand extends Command
$output = "<?php
// @formatter:off
// phpcs:ignoreFile
/**
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
@@ -264,6 +266,7 @@ class ModelsCommand extends Command
}
$this->properties = [];
$this->methods = [];
$this->foreignKeyConstraintsColumns = [];
if (class_exists($name)) {
try {
// handle abstract classes, interfaces, ...
@@ -352,7 +355,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)
{
@@ -362,8 +365,16 @@ class ModelsCommand extends Command
$type = 'decimal';
} elseif (Str::startsWith($type, 'custom_datetime:')) {
$type = 'date';
} elseif (Str::startsWith($type, 'date:')) {
$type = 'date';
} elseif (Str::startsWith($type, 'datetime:')) {
$type = 'date';
} elseif (Str::startsWith($type, 'immutable_custom_datetime:')) {
$type = 'immutable_date';
} elseif (Str::startsWith($type, 'immutable_date:')) {
$type = 'immutable_date';
} elseif (Str::startsWith($type, 'immutable_datetime:')) {
$type = 'immutable_datetime';
} elseif (Str::startsWith($type, 'encrypted:')) {
$type = Str::after($type, ':');
}
@@ -425,18 +436,53 @@ class ModelsCommand extends Command
if (!isset($this->properties[$name])) {
continue;
}
if ($this->isInboundCast($realType)) {
continue;
}
$realType = $this->checkForCastableCasts($realType, $params);
$realType = $this->checkForCustomLaravelCasts($realType);
$realType = $this->getTypeOverride($realType);
$this->properties[$name]['type'] = $this->getTypeInModel($model, $realType);
$realType = $this->getTypeInModel($model, $realType);
$realType = $this->applyNullability($realType, isset($this->nullableColumns[$name]));
if (isset($this->nullableColumns[$name])) {
$this->properties[$name]['type'] .= '|null';
}
$this->properties[$name]['type'] = $realType;
}
}
protected function applyNullability(?string $type, bool $isNullable): ?string
{
if (!$type) {
return null;
}
$nullString = null;
// Find instance of:
// A) start of string or non-word character (like space or pipe) followed by 'null|'
// B) '|null' followed by end of string or non-word character (like space or pipe)
// This will find 'or null' instances at the beginning, middle or end of a type string,
// but will exclude solo/pure null instances and null being part of a type's name (e.g. class 'Benull').
if (preg_match('/(?:(?:^|\W)(null\|))|(\|null(?:$|\W))/', $type, $matches) === 1) {
$nullString = array_pop($matches);
}
// Return the current type string if:
// A) the type can be null and the type contains a null instance
// B) the type can not be null and the type does not contain a null instance
if (!($isNullable xor $nullString)) {
return $type;
}
if ($isNullable) {
$type .= '|null';
} else {
$type = str_replace($nullString, '', $type);
}
return $type;
}
/**
* Returns the override type for the give type.
*
@@ -453,12 +499,13 @@ 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();
@@ -478,11 +525,6 @@ class ModelsCommand extends Command
$databasePlatform->registerDoctrineTypeMapping($yourTypeName, $doctrineTypeName);
}
$database = null;
if (strpos($table, '.')) {
[$database, $table] = explode('.', $table);
}
$columns = $schema->listTableColumns($table, $database);
if (!$columns) {
@@ -561,17 +603,31 @@ class ModelsCommand extends Command
}
/**
* @param \Illuminate\Database\Eloquent\Model $model
* @param Model $model
*/
public function getPropertiesFromMethods($model)
{
$methods = get_class_methods($model);
if ($methods) {
sort($methods);
foreach ($methods as $method) {
$reflection = new \ReflectionMethod($model, $method);
$reflectionClass = new ReflectionClass($model);
$reflections = $reflectionClass->getMethods();
if ($reflections) {
// Filter out private methods because they can't be used to generate magic properties and HasAttributes'
// 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->getName() === 'setClassCastableAttribute' ||
$methodReflection->getName() === 'setEnumCastableAttribute'
)
);
});
sort($reflections);
foreach ($reflections as $reflection) {
$type = $this->getReturnTypeFromReflection($reflection);
$isAttribute = is_a($type, '\Illuminate\Database\Eloquent\Casts\Attribute', true);
$method = $reflection->getName();
if (
Str::startsWith($method, 'get') && Str::endsWith(
$method,
@@ -588,16 +644,15 @@ class ModelsCommand extends Command
}
} elseif ($isAttribute) {
$name = Str::snake($method);
$types = $this->getAttributeReturnType($model, $method);
$types = $this->getAttributeReturnType($model, $reflection);
$comment = $this->getCommentFromDocBlock($reflection);
if ($types->has('get')) {
$type = $this->getTypeInModel($model, $types['get']);
$comment = $this->getCommentFromDocBlock($reflection);
$this->setProperty($name, $type, true, null, $comment);
}
if ($types->has('set')) {
$comment = $this->getCommentFromDocBlock($reflection);
$this->setProperty($name, null, null, true, $comment);
}
} elseif (
@@ -673,8 +728,7 @@ class ModelsCommand extends Command
$search = '$this->' . $relation . '(';
if (stripos($code, $search) || ltrim($impl, '\\') === ltrim((string)$type, '\\')) {
//Resolve the relation's model to a Relation object.
$methodReflection = new \ReflectionMethod($model, $method);
if ($methodReflection->getNumberOfParameters()) {
if ($reflection->getNumberOfParameters()) {
continue;
}
@@ -682,11 +736,12 @@ class ModelsCommand extends Command
// 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) {
$relationObj = Relation::noConstraints(function () use ($model, $reflection) {
try {
return $model->$method();
$methodName = $reflection->getName();
return $model->$methodName();
} catch (Throwable $e) {
$this->warn(sprintf('Error resolving relation model of %s:%s() : %s', get_class($model), $method, $e->getMessage()));
$this->warn(sprintf('Error resolving relation model of %s:%s() : %s', get_class($model), $reflection->getName(), $e->getMessage()));
return null;
}
@@ -698,7 +753,10 @@ class ModelsCommand extends Command
get_class($relationObj->getRelated())
);
if (strpos(get_class($relationObj), 'Many') !== false) {
if (
strpos(get_class($relationObj), 'Many') !== false ||
($this->getRelationReturnTypes()[$relation] ?? '') === 'many'
) {
//Collection or array of models (because Collection is Arrayable)
$relatedClass = '\\' . get_class($relationObj->getRelated());
$collectionClass = $this->getCollectionClass($relatedClass);
@@ -706,9 +764,10 @@ class ModelsCommand extends Command
$model,
$collectionClass
);
$collectionTypeHint = $this->getCollectionTypeHint($collectionClassNameInModel, $relatedModel);
$this->setProperty(
$method,
$collectionClassNameInModel . '|' . $relatedModel . '[]',
$collectionTypeHint,
true,
null,
$comment
@@ -719,10 +778,13 @@ 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') {
} elseif (
$relation === 'morphTo' ||
($this->getRelationReturnTypes()[$relation] ?? '') === 'morphTo'
) {
// Model isn't specified because relation is polymorphic
$this->setProperty(
$method,
@@ -920,10 +982,19 @@ class ModelsCommand extends Command
$phpdoc->appendTag($tag);
}
if ($this->write && !$phpdoc->getTagsByName('mixin')) {
if ($this->write) {
$eloquentClassNameInModel = $this->getClassNameInDestinationFile($reflection, 'Eloquent');
// remove the already existing tag to prevent duplicates
foreach ($phpdoc->getTagsByName('mixin') as $tag) {
if ($tag->getContent() === $eloquentClassNameInModel) {
$phpdoc->deleteTag($tag);
}
}
$phpdoc->appendTag(Tag::createInstance('@mixin ' . $eloquentClassNameInModel, $phpdoc));
}
if ($this->phpstorm_noinspections) {
/**
* Facades, Eloquent API
@@ -1029,6 +1100,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) . "'";
}
@@ -1056,11 +1129,28 @@ 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());
}
/**
* Determine a model classes' collection type hint.
*
* @param string $collectionClassNameInModel
* @param string $relatedModel
* @return string
*/
protected function getCollectionTypeHint(string $collectionClassNameInModel, string $relatedModel): string
{
$useGenericsSyntax = $this->laravel['config']->get('ide-helper.use_generics_annotations', true);
if ($useGenericsSyntax) {
return $collectionClassNameInModel . '<int, ' . $relatedModel . '>';
} else {
return $collectionClassNameInModel . '|' . $relatedModel . '[]';
}
}
/**
* Returns the available relation types
*/
@@ -1070,6 +1160,14 @@ class ModelsCommand extends Command
return array_merge(self::RELATION_TYPES, $configuredRelations);
}
/**
* Returns the return types of relations
*/
protected function getRelationReturnTypes(): array
{
return $this->laravel['config']->get('ide-helper.additional_relation_return_types', []);
}
/**
* @return bool
*/
@@ -1078,10 +1176,13 @@ class ModelsCommand extends Command
return $this->laravel['config']->get('ide-helper.model_camel_case_properties', false);
}
protected function getAttributeReturnType(Model $model, string $method): Collection
protected function getAttributeReturnType(Model $model, \ReflectionMethod $reflectionMethod): Collection
{
// Private/protected ReflectionMethods require setAccessible prior to PHP 8.1
$reflectionMethod->setAccessible(true);
/** @var Attribute $attribute */
$attribute = $model->{$method}();
$attribute = $reflectionMethod->invoke($model);
return collect([
'get' => $attribute->get ? optional(new \ReflectionFunction($attribute->get))->getReturnType() : null,
@@ -1090,7 +1191,7 @@ class ModelsCommand extends Command
->filter()
->map(function ($type) {
if ($type instanceof \ReflectionUnionType) {
$types =collect($type->getTypes())
$types = collect($type->getTypes())
/** @var ReflectionType $reflectionType */
->map(function ($reflectionType) {
return collect($this->extractReflectionTypes($reflectionType));
@@ -1178,7 +1279,7 @@ class ModelsCommand extends Command
$type = implode('|', $types);
if ($returnType->allowsNull()) {
$type .='|null';
$type .= '|null';
}
return $type;
@@ -1187,14 +1288,14 @@ class ModelsCommand extends Command
/**
* Generates methods provided by the SoftDeletes trait
* @param \Illuminate\Database\Eloquent\Model $model
* @param Model $model
*/
protected function getSoftDeleteMethods($model)
{
$traits = class_uses_recursive($model);
if (in_array('Illuminate\\Database\\Eloquent\\SoftDeletes', $traits)) {
$modelName = $this->getClassNameInDestinationFile($model, get_class($model));
$builder = $this->getClassNameInDestinationFile($model, \Illuminate\Database\Query\Builder::class);
$builder = $this->getClassNameInDestinationFile($model, \Illuminate\Database\Eloquent\Builder::class);
$this->setMethod('withTrashed', $builder . '|' . $modelName, []);
$this->setMethod('withoutTrashed', $builder . '|' . $modelName, []);
$this->setMethod('onlyTrashed', $builder . '|' . $modelName, []);
@@ -1204,7 +1305,7 @@ class ModelsCommand extends Command
/**
* Generate factory method from "HasFactory" trait.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param Model $model
*/
protected function getFactoryMethods($model)
{
@@ -1232,12 +1333,12 @@ class ModelsCommand extends Command
return;
}
$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)
{
@@ -1246,8 +1347,9 @@ class ModelsCommand extends Command
if ($collectionClass !== '\\' . \Illuminate\Database\Eloquent\Collection::class) {
$collectionClassInModel = $this->getClassNameInDestinationFile($model, $collectionClass);
$this->setMethod('get', $collectionClassInModel . '|static[]', ['$columns = [\'*\']']);
$this->setMethod('all', $collectionClassInModel . '|static[]', ['$columns = [\'*\']']);
$collectionTypeHint = $this->getCollectionTypeHint($collectionClassInModel, 'static');
$this->setMethod('get', $collectionTypeHint, ['$columns = [\'*\']']);
$this->setMethod('all', $collectionTypeHint, ['$columns = [\'*\']']);
}
}
@@ -1268,13 +1370,18 @@ class ModelsCommand extends Command
return $keyword;
}
protected function isInboundCast(string $type): bool
{
return class_exists($type) && is_subclass_of($type, CastsInboundAttributes::class);
}
protected function checkForCastableCasts(string $type, array $params = []): string
{
if (!class_exists($type) || !interface_exists(Castable::class)) {
return $type;
}
$reflection = new \ReflectionClass($type);
$reflection = new ReflectionClass($type);
if (!$reflection->implementsInterface(Castable::class)) {
return $type;
@@ -1291,7 +1398,8 @@ class ModelsCommand extends Command
$methodReflection = $castReflection->getMethod('get');
return $this->getReturnTypeFromReflection($methodReflection) ??
$this->getReturnTypeFromDocBlock($methodReflection, $reflection);
$this->getReturnTypeFromDocBlock($methodReflection, $reflection) ??
$type;
}
/**
@@ -1305,7 +1413,7 @@ class ModelsCommand extends Command
return $type;
}
$reflection = new \ReflectionClass($type);
$reflection = new ReflectionClass($type);
if (!$reflection->implementsInterface(CastsAttributes::class)) {
return $type;
@@ -1409,10 +1517,10 @@ class ModelsCommand extends Command
$type = implode('|', $types);
if ($paramType->allowsNull()) {
if (count($types)==1) {
if (count($types) == 1) {
$type = '?' . $type;
} else {
$type .='|null';
$type .= '|null';
}
}
@@ -1489,7 +1597,7 @@ class ModelsCommand extends Command
} else {
$types = [];
foreach ($reflection_type->getTypes() as $named_type) {
if ($named_type->getName()==='null') {
if ($named_type->getName() === 'null') {
continue;
}
@@ -1511,7 +1619,7 @@ class ModelsCommand extends Command
}
/**
* @param \Illuminate\Database\Eloquent\Model $model
* @param Model $model
* @throws \Illuminate\Contracts\Container\BindingResolutionException
* @throws \RuntimeException
*/
+61 -12
View File
@@ -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))
@@ -127,15 +133,6 @@ class Generator
} catch (\Exception $e) {
}
try {
if (class_exists('SSH') && is_a('SSH', '\Illuminate\Support\Facades\SSH', true)) {
$class = get_class(\SSH::connection());
$this->extra['SSH'] = [$class];
$this->interfaces['\Illuminate\Remote\ConnectionInterface'] = $class;
}
} catch (\Exception $e) {
}
try {
if (class_exists('Storage') && is_a('Storage', '\Illuminate\Support\Facades\Storage', true)) {
$class = get_class(\Storage::disk());
@@ -162,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()) {
@@ -177,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
*
@@ -184,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);
+4 -4
View File
@@ -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
View File
@@ -22,7 +22,7 @@ use Illuminate\Support\Str;
class Method
{
/** @var \Barryvdh\Reflection\DocBlock */
/** @var DocBlock */
protected $phpdoc;
/** @var \ReflectionMethod */
+1 -1
View File
@@ -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) {
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ArrayCastsWithComment\Models;
use Illuminate\Database\Eloquent\Model;
/**
* @property array<int, string>|null $cast_to_array -- These three should not be duplicated
* @property array<int, string> $cast_to_json some-description
* @property \Illuminate\Support\Collection<int, string> $cast_to_collection some-description
*
* @property array|null $cast_to_encrypted_array -- These three are OK (no types)
* @property array $cast_to_encrypted_json some-description
* @property \Illuminate\Support\Collection $cast_to_encrypted_collection some-description
*
* @property string $cast_to_string -- The next three are OK (no description), this not included
*
* @property array<int, string>|null $cast_to_immutable_date
* @property array<int, string> $cast_to_immutable_date_serialization
* @property \Illuminate\Support\Collection<int, string> $cast_to_immutable_custom_datetime
*/
class ArrayCastsWithComment extends Model
{
protected $table = 'simple_casts';
protected $casts = [
'cast_to_array' => 'array',
'cast_to_json' => 'json',
'cast_to_collection' => 'collection',
'cast_to_encrypted_array' => 'array',
'cast_to_encrypted_json' => 'json',
'cast_to_encrypted_collection' => 'collection',
'cast_to_string' => 'string',
'cast_to_immutable_date' => 'array',
'cast_to_immutable_date_serialization' => 'json',
'cast_to_immutable_custom_datetime' => 'collection',
];
}
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ArrayCastsWithComment;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
class Test extends AbstractModelsCommand
{
/**
* The generated snapshot is wrong until
* https://github.com/barryvdh/laravel-ide-helper/issues/1505 is fixed
*/
public function test(): void
{
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay());
$this->assertMatchesMockedSnapshot();
}
}
@@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ArrayCastsWithComment\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ArrayCastsWithComment\Models\ArrayCastsWithComment
*
* @property array<int, string>|null $cast_to_array -- These three should not be duplicated
* @property array<int, string> $cast_to_json some-description
* @property \Illuminate\Support\Collection<int, string> $cast_to_collection some-description
* @property array|null $cast_to_encrypted_array -- These three are OK (no types)
* @property array $cast_to_encrypted_json some-description
* @property \Illuminate\Support\Collection $cast_to_encrypted_collection some-description
* @property string $cast_to_string -- The next three are OK (no description), this not included
* @property array<int, string>|null $cast_to_immutable_date
* @property array<int, string> $cast_to_immutable_date_serialization
* @property \Illuminate\Support\Collection<int, string> $cast_to_immutable_custom_datetime
* @property string $cast_to_int
* @property string $cast_to_integer
* @property string $cast_to_real
* @property string $cast_to_float
* @property string $cast_to_double
* @property string $cast_to_decimal
* @property string $cast_to_bool
* @property string $cast_to_boolean
* @property string $cast_to_object
* @property array $cast_to_array
* @property array $cast_to_json
* @property \Illuminate\Support\Collection $cast_to_collection
* @property string $cast_to_date
* @property string $cast_to_datetime
* @property string $cast_to_date_serialization
* @property string $cast_to_datetime_serialization
* @property string $cast_to_custom_datetime
* @property string $cast_to_immutable_datetime
* @property string $cast_to_immutable_datetime_serialization
* @property string $cast_to_timestamp
* @property string $cast_to_encrypted
* @property string $cast_to_encrypted_object
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment query()
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToArray($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToBool($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToBoolean($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToCollection($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToCustomDatetime($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToDate($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToDateSerialization($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToDatetime($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToDatetimeSerialization($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToDecimal($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToDouble($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToEncrypted($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToEncryptedArray($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToEncryptedCollection($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToEncryptedJson($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToEncryptedObject($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToFloat($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToImmutableCustomDatetime($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToImmutableDate($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToImmutableDateSerialization($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToImmutableDatetime($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToImmutableDatetimeSerialization($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToInt($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToInteger($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToJson($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToObject($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToReal($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToString($value)
* @method static \Illuminate\Database\Eloquent\Builder|ArrayCastsWithComment whereCastToTimestamp($value)
* @mixin \Eloquent
*/
class ArrayCastsWithComment extends Model
{
protected $table = 'simple_casts';
protected $casts = [
'cast_to_array' => 'array',
'cast_to_json' => 'json',
'cast_to_collection' => 'collection',
'cast_to_encrypted_array' => 'array',
'cast_to_encrypted_json' => 'json',
'cast_to_encrypted_collection' => 'collection',
'cast_to_string' => 'string',
'cast_to_immutable_date' => 'array',
'cast_to_immutable_date_serialization' => 'json',
'cast_to_immutable_custom_datetime' => 'collection',
];
}
@@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\Model;
class Simple extends Model
{
public function name(): Attribute
protected function name(): Attribute
{
return new Attribute(
function (?string $name): ?string {
@@ -27,9 +27,9 @@ class Simple extends Model
* phpdoc is ignored here deliberately due to performance reasons and also
* isn't supported by Laravel itself.
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
* @return Attribute
*/
public function notAnAttribute()
protected function notAnAttribute()
{
return new Attribute(
function (?string $value): ?string {
@@ -9,15 +9,6 @@ use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
class Test extends AbstractModelsCommand
{
protected function setUp(): void
{
parent::setUp();
if (!class_exists('\Illuminate\Database\Eloquent\Casts\Attribute')) {
$this->markTestSkipped('This test requires Laravel 8.77 or newer');
}
}
public function test(): void
{
$command = $this->app->make(ModelsCommand::class);
@@ -20,7 +20,7 @@ use Illuminate\Database\Eloquent\Model;
*/
class Simple extends Model
{
public function name(): Attribute
protected function name(): Attribute
{
return new Attribute(
function (?string $name): ?string {
@@ -38,9 +38,9 @@ class Simple extends Model
* phpdoc is ignored here deliberately due to performance reasons and also
* isn't supported by Laravel itself.
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
* @return Attribute
*/
public function notAnAttribute()
protected function notAnAttribute()
{
return new Attribute(
function (?string $value): ?string {
@@ -21,7 +21,7 @@ use Illuminate\Database\Eloquent\Relations\MorphTo;
* This is second line, success too.
* @property-read string $many_format_comment There is format comment, success.
* @property-read string $not_comment
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationHasMany HasMany relations.
* @property-read \Illuminate\Database\Eloquent\Collection<int, Simple> $relationHasMany HasMany relations.
* @property-read int|null $relation_has_many_count
* @property-read Simple|null $relationHasOne Others relations.
* @property-read Model|\Eloquent $relationMorphTo MorphTo relations.
@@ -12,10 +12,10 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Models\Simple
*
* @property integer $id
* @property-read SimpleCollection|Simple[] $relationHasMany
* @property-read SimpleCollection<int, Simple> $relationHasMany
* @property-read int|null $relation_has_many_count
* @method static SimpleCollection|static[] all($columns = ['*'])
* @method static SimpleCollection|static[] get($columns = ['*'])
* @method static SimpleCollection<int, static> all($columns = ['*'])
* @method static SimpleCollection<int, static> get($columns = ['*'])
* @method static \Illuminate\Database\Eloquent\Builder|Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple query()
@@ -1,6 +1,7 @@
<?php
// @formatter:off
// phpcs:ignoreFile
/**
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
@@ -17,19 +17,11 @@ class Test extends AbstractModelsCommand
'--write' => true,
]);
if (PHP_VERSION_ID >= 80000) {
$errors = [
'Error resolving relation model of Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic:dynamicBelongsTo() : Attempt to read property "created_at" on null',
'Error resolving relation model of Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic:dynamicHasMany() : Attempt to read property "created_at" on null',
'Error resolving relation model of Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic:dynamicHasOne() : Attempt to read property "created_at" on null',
];
} else {
$errors = [
"Error resolving relation model of Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic:dynamicBelongsTo() : Trying to get property 'created_at' of non-object",
"Error resolving relation model of Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic:dynamicHasMany() : Trying to get property 'created_at' of non-object",
"Error resolving relation model of Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic:dynamicHasOne() : Trying to get property 'created_at' of non-object",
];
}
$errors = [
'Error resolving relation model of Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic:dynamicBelongsTo() : Attempt to read property "created_at" on null',
'Error resolving relation model of Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic:dynamicHasMany() : Attempt to read property "created_at" on null',
'Error resolving relation model of Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic:dynamicHasOne() : Attempt to read property "created_at" on null',
];
$this->assertSame(0, $tester->getStatusCode());
$this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay());
@@ -12,7 +12,7 @@ use Illuminate\Database\Eloquent\Relations\HasOne;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\DynamicRelations\Models\Dynamic
*
* @property-read \Illuminate\Database\Eloquent\Collection|Dynamic[] $regularHasMany
* @property-read \Illuminate\Database\Eloquent\Collection<int, Dynamic> $regularHasMany
* @property-read int|null $regular_has_many_count
* @method static \Illuminate\Database\Eloquent\Builder|Dynamic newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Dynamic newQuery()
@@ -8,19 +8,12 @@ use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Closure;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Foundation\Application;
use Illuminate\Support\Str;
class Test extends AbstractModelsCommand
{
public function test(): void
public function testFactory(): void
{
if (!version_compare(Application::VERSION, '8.2', '>=')) {
$this->markTestSkipped(
'This test only works in Laravel >= 8.2'
);
}
Factory::guessFactoryNamesUsing(static::getFactoryNameResolver());
$command = $this->app->make(ModelsCommand::class);
@@ -11,7 +11,7 @@ use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Models\ModelWithCustomNamespace
*
* @method static \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\CustomSpace\ModelWithCustomNamespaceFactory factory(...$parameters)
* @method static \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\CustomSpace\ModelWithCustomNamespaceFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithCustomNamespace newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithCustomNamespace newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithCustomNamespace query()
@@ -43,7 +43,7 @@ use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Models\ModelWithFactory
*
* @method static \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Factories\ModelWithFactoryFactory factory(...$parameters)
* @method static \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Factories\ModelWithFactoryFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithFactory newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithFactory newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithFactory query()
@@ -62,7 +62,7 @@ namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Models
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Models\ModelWithNestedFactory
*
* @method static \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Factories\ModelWithNestedFactoryFactory factory(...$parameters)
* @method static \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Factories\Factories\ModelWithNestedFactoryFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithNestedFactory newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithNestedFactory newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ModelWithNestedFactory query()
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpDocWithEnumDefaults\Enums;
enum PostStatus
{
case Published;
case Unpublished;
case Archived;
}
@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpDocWithEnumDefaults\Models;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpDocWithEnumDefaults\Enums\PostStatus;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function scopeHasStatus(Builder $query, ?PostStatus $status = PostStatus::Published)
{
//
}
}
@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpDocWithEnumDefaults;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
class Test extends AbstractModelsCommand
{
public function test(): void
{
if (!version_compare(PHP_VERSION, '8.1', '>=')) {
$this->markTestSkipped(
'This test only works in PHP >= 8.1'
);
}
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay());
$this->assertMatchesMockedSnapshot();
}
}
@@ -0,0 +1,172 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpDocWithEnumDefaults\Models;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpDocWithEnumDefaults\Enums\PostStatus;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpDocWithEnumDefaults\Models\Post
*
* @property integer $id
* @property string|null $char_nullable
* @property string $char_not_nullable
* @property string|null $string_nullable
* @property string $string_not_nullable
* @property string|null $text_nullable
* @property string $text_not_nullable
* @property string|null $medium_text_nullable
* @property string $medium_text_not_nullable
* @property string|null $long_text_nullable
* @property string $long_text_not_nullable
* @property integer|null $integer_nullable
* @property integer $integer_not_nullable
* @property integer|null $tiny_integer_nullable
* @property integer $tiny_integer_not_nullable
* @property integer|null $small_integer_nullable
* @property integer $small_integer_not_nullable
* @property integer|null $medium_integer_nullable
* @property integer $medium_integer_not_nullable
* @property integer|null $big_integer_nullable
* @property integer $big_integer_not_nullable
* @property integer|null $unsigned_integer_nullable
* @property integer $unsigned_integer_not_nullable
* @property integer|null $unsigned_tiny_integer_nullable
* @property integer $unsigned_tiny_integer_not_nullable
* @property integer|null $unsigned_small_integer_nullable
* @property integer $unsigned_small_integer_not_nullable
* @property integer|null $unsigned_medium_integer_nullable
* @property integer $unsigned_medium_integer_not_nullable
* @property integer|null $unsigned_big_integer_nullable
* @property integer $unsigned_big_integer_not_nullable
* @property float|null $float_nullable
* @property float $float_not_nullable
* @property float|null $double_nullable
* @property float $double_not_nullable
* @property string|null $decimal_nullable
* @property string $decimal_not_nullable
* @property string|null $unsigned_decimal_nullable
* @property string $unsigned_decimal_not_nullable
* @property integer|null $boolean_nullable
* @property integer $boolean_not_nullable
* @property string|null $enum_nullable
* @property string $enum_not_nullable
* @property string|null $json_nullable
* @property string $json_not_nullable
* @property string|null $jsonb_nullable
* @property string $jsonb_not_nullable
* @property string|null $date_nullable
* @property string $date_not_nullable
* @property string|null $datetime_nullable
* @property string $datetime_not_nullable
* @property string|null $datetimetz_nullable
* @property string $datetimetz_not_nullable
* @property string|null $time_nullable
* @property string $time_not_nullable
* @property string|null $timetz_nullable
* @property string $timetz_not_nullable
* @property string|null $timestamp_nullable
* @property string $timestamp_not_nullable
* @property string|null $timestamptz_nullable
* @property string $timestamptz_not_nullable
* @property integer|null $year_nullable
* @property integer $year_not_nullable
* @property mixed|null $binary_nullable
* @property mixed $binary_not_nullable
* @property string|null $uuid_nullable
* @property string $uuid_not_nullable
* @property string|null $ipaddress_nullable
* @property string $ipaddress_not_nullable
* @property string|null $macaddress_nullable
* @property string $macaddress_not_nullable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static Builder|Post hasStatus(?\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpDocWithEnumDefaults\Enums\PostStatus $status = \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpDocWithEnumDefaults\Enums\PostStatus::Published)
* @method static Builder|Post newModelQuery()
* @method static Builder|Post newQuery()
* @method static Builder|Post query()
* @method static Builder|Post whereBigIntegerNotNullable($value)
* @method static Builder|Post whereBigIntegerNullable($value)
* @method static Builder|Post whereBinaryNotNullable($value)
* @method static Builder|Post whereBinaryNullable($value)
* @method static Builder|Post whereBooleanNotNullable($value)
* @method static Builder|Post whereBooleanNullable($value)
* @method static Builder|Post whereCharNotNullable($value)
* @method static Builder|Post whereCharNullable($value)
* @method static Builder|Post whereCreatedAt($value)
* @method static Builder|Post whereDateNotNullable($value)
* @method static Builder|Post whereDateNullable($value)
* @method static Builder|Post whereDatetimeNotNullable($value)
* @method static Builder|Post whereDatetimeNullable($value)
* @method static Builder|Post whereDatetimetzNotNullable($value)
* @method static Builder|Post whereDatetimetzNullable($value)
* @method static Builder|Post whereDecimalNotNullable($value)
* @method static Builder|Post whereDecimalNullable($value)
* @method static Builder|Post whereDoubleNotNullable($value)
* @method static Builder|Post whereDoubleNullable($value)
* @method static Builder|Post whereEnumNotNullable($value)
* @method static Builder|Post whereEnumNullable($value)
* @method static Builder|Post whereFloatNotNullable($value)
* @method static Builder|Post whereFloatNullable($value)
* @method static Builder|Post whereId($value)
* @method static Builder|Post whereIntegerNotNullable($value)
* @method static Builder|Post whereIntegerNullable($value)
* @method static Builder|Post whereIpaddressNotNullable($value)
* @method static Builder|Post whereIpaddressNullable($value)
* @method static Builder|Post whereJsonNotNullable($value)
* @method static Builder|Post whereJsonNullable($value)
* @method static Builder|Post whereJsonbNotNullable($value)
* @method static Builder|Post whereJsonbNullable($value)
* @method static Builder|Post whereLongTextNotNullable($value)
* @method static Builder|Post whereLongTextNullable($value)
* @method static Builder|Post whereMacaddressNotNullable($value)
* @method static Builder|Post whereMacaddressNullable($value)
* @method static Builder|Post whereMediumIntegerNotNullable($value)
* @method static Builder|Post whereMediumIntegerNullable($value)
* @method static Builder|Post whereMediumTextNotNullable($value)
* @method static Builder|Post whereMediumTextNullable($value)
* @method static Builder|Post whereSmallIntegerNotNullable($value)
* @method static Builder|Post whereSmallIntegerNullable($value)
* @method static Builder|Post whereStringNotNullable($value)
* @method static Builder|Post whereStringNullable($value)
* @method static Builder|Post whereTextNotNullable($value)
* @method static Builder|Post whereTextNullable($value)
* @method static Builder|Post whereTimeNotNullable($value)
* @method static Builder|Post whereTimeNullable($value)
* @method static Builder|Post whereTimestampNotNullable($value)
* @method static Builder|Post whereTimestampNullable($value)
* @method static Builder|Post whereTimestamptzNotNullable($value)
* @method static Builder|Post whereTimestamptzNullable($value)
* @method static Builder|Post whereTimetzNotNullable($value)
* @method static Builder|Post whereTimetzNullable($value)
* @method static Builder|Post whereTinyIntegerNotNullable($value)
* @method static Builder|Post whereTinyIntegerNullable($value)
* @method static Builder|Post whereUnsignedBigIntegerNotNullable($value)
* @method static Builder|Post whereUnsignedBigIntegerNullable($value)
* @method static Builder|Post whereUnsignedDecimalNotNullable($value)
* @method static Builder|Post whereUnsignedDecimalNullable($value)
* @method static Builder|Post whereUnsignedIntegerNotNullable($value)
* @method static Builder|Post whereUnsignedIntegerNullable($value)
* @method static Builder|Post whereUnsignedMediumIntegerNotNullable($value)
* @method static Builder|Post whereUnsignedMediumIntegerNullable($value)
* @method static Builder|Post whereUnsignedSmallIntegerNotNullable($value)
* @method static Builder|Post whereUnsignedSmallIntegerNullable($value)
* @method static Builder|Post whereUnsignedTinyIntegerNotNullable($value)
* @method static Builder|Post whereUnsignedTinyIntegerNullable($value)
* @method static Builder|Post whereUpdatedAt($value)
* @method static Builder|Post whereUuidNotNullable($value)
* @method static Builder|Post whereUuidNullable($value)
* @method static Builder|Post whereYearNotNullable($value)
* @method static Builder|Post whereYearNullable($value)
* @mixin \Eloquent
*/
class Post extends Model
{
public function scopeHasStatus(Builder $query, ?PostStatus $status = PostStatus::Published)
{
//
}
}
@@ -1,6 +1,7 @@
<?php
// @formatter:off
// phpcs:ignoreFile
/**
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
@@ -84,12 +84,12 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @property string $macaddress_not_nullable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post[] $posts
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post> $posts
* @property-read int|null $posts_count
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post null(string $unusedParam)
* @method static \Illuminate\Database\Query\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post whereBigIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post whereBigIntegerNullable($value)
@@ -164,8 +164,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post whereUuidNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post whereYearNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post whereYearNullable($value)
* @method static \Illuminate\Database\Query\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post withTrashed()
* @method static \Illuminate\Database\Query\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post withoutTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GeneratePhpdocWithForcedFqn\Models\Post withoutTrashed()
* @mixin \Eloquent
*/
class Post extends Model
@@ -90,12 +90,12 @@ use Illuminate\Support\Carbon;
* @property string $macaddress_not_nullable
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property-read Collection|Post[] $posts
* @property-read Collection<int, Post> $posts
* @property-read int|null $posts_count
* @method static EloquentBuilder|Post newModelQuery()
* @method static EloquentBuilder|Post newQuery()
* @method static EloquentBuilder|Post null(string $unusedParam)
* @method static QueryBuilder|Post onlyTrashed()
* @method static EloquentBuilder|Post onlyTrashed()
* @method static EloquentBuilder|Post query()
* @method static EloquentBuilder|Post whereBigIntegerNotNullable($value)
* @method static EloquentBuilder|Post whereBigIntegerNullable($value)
@@ -170,8 +170,8 @@ use Illuminate\Support\Carbon;
* @method static EloquentBuilder|Post whereUuidNullable($value)
* @method static EloquentBuilder|Post whereYearNotNullable($value)
* @method static EloquentBuilder|Post whereYearNullable($value)
* @method static QueryBuilder|Post withTrashed()
* @method static QueryBuilder|Post withoutTrashed()
* @method static EloquentBuilder|Post withTrashed()
* @method static EloquentBuilder|Post withoutTrashed()
* @mixin Eloquent
*/
class Post extends Model
@@ -1,6 +1,7 @@
<?php
// @formatter:off
// phpcs:ignoreFile
/**
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
@@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Model;
/**
* @property $someProp
* @method someMethod(string $method)
* @mixin IdeHelperPost
*/
class Post extends Model
{
@@ -17,6 +17,7 @@ class Post extends Model
<?php
// @formatter:off
// phpcs:ignoreFile
/**
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenericsSyntaxDisabled\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Simple extends Model
{
// Regular relations
public function regularHasMany(): HasMany
{
return $this->hasMany(Simple::class);
}
public function regularBelongsToMany(): BelongsToMany
{
return $this->belongsToMany(Simple::class);
}
}
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenericsSyntaxDisabled;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper.use_generics_annotations', false);
}
public function test(): void
{
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay());
$this->assertMatchesMockedSnapshot();
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenericsSyntaxDisabled\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenericsSyntaxDisabled\Models\Simple
*
* @property integer $id
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $regularBelongsToMany
* @property-read int|null $regular_belongs_to_many_count
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $regularHasMany
* @property-read int|null $regular_has_many_count
* @method static \Illuminate\Database\Eloquent\Builder|Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|Simple whereId($value)
* @mixin \Eloquent
*/
class Simple extends Model
{
// Regular relations
public function regularHasMany(): HasMany
{
return $this->hasMany(Simple::class);
}
public function regularBelongsToMany(): BelongsToMany
{
return $this->belongsToMany(Simple::class);
}
}
@@ -103,4 +103,8 @@ class Simple extends Model
public function getAttributeReturnsVoidAttribute(): void
{
}
private function getInvalidAccessModifierAttribute()
{
}
}
@@ -133,4 +133,8 @@ class Simple extends Model
public function getAttributeReturnsVoidAttribute(): void
{
}
private function getInvalidAccessModifierAttribute()
{
}
}
@@ -1,6 +1,7 @@
<?php
// @formatter:off
// phpcs:ignoreFile
/**
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
@@ -11,7 +11,7 @@ class CastableReturnsAnonymousCaster implements Castable
{
public static function castUsing(array $arguments)
{
return new class() implements CastsAttributes {
return new class () implements CastsAttributes {
/**
* @inheritDoc
* @return CastedProperty
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
use Illuminate\Contracts\Database\Eloquent\Castable;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class CastableWithoutReturnType implements Castable
{
public static function castUsing(array $arguments)
{
return new class () implements CastsAttributes {
public function get($model, string $key, $value, array $attributes)
{
return new CastedProperty();
}
public function set($model, string $key, $value, array $attributes)
{
// TODO: Implement set() method.
}
};
}
}
@@ -10,7 +10,7 @@ class CustomCasterWithDocblockReturnFqn implements CastsAttributes
{
/**
* @inheritDoc
* @return \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty
* @return CastedProperty
*/
public function get($model, string $key, $value, array $attributes)
{
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;
class InboundAttributeCaster implements CastsInboundAttributes
{
public function set($model, string $key, $value, array $attributes)
{
// TODO: Implement set() method.
}
}
@@ -6,6 +6,7 @@ namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCas
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableReturnsAnonymousCaster;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableReturnsCustomCaster;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableWithoutReturnType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturnFqn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithNullablePrimitiveReturn;
@@ -16,6 +17,7 @@ use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Cas
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithReturnType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\ExtendedSelfCastingCasterWithStaticDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\ExtendedSelfCastingCasterWithThisDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\InboundAttributeCaster;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\SelfCastingCasterWithStaticDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\SelfCastingCasterWithThisDocblockReturn;
use Illuminate\Database\Eloquent\Model;
@@ -29,15 +31,18 @@ class CustomCast extends Model
'casted_property_with_return_primitive' => CustomCasterWithPrimitiveReturn::class,
'casted_property_with_return_primitive_docblock' => CustomCasterWithPrimitiveDocblockReturn::class,
'casted_property_with_return_nullable_primitive' => CustomCasterWithNullablePrimitiveReturn::class,
'casted_property_with_return_nullable_primitive_and_nullable_column' => CustomCasterWithNullablePrimitiveReturn::class,
'casted_property_without_return' => CustomCasterWithoutReturnType::class,
'casted_property_with_param' => CustomCasterWithParam::class . ':param',
'casted_property_with_static_return_docblock' => SelfCastingCasterWithStaticDocblockReturn::class,
'casted_property_with_this_return_docblock' => SelfCastingCasterWithThisDocblockReturn::class,
'casted_property_with_castable' => CastableReturnsCustomCaster::class,
'casted_property_with_anonymous_cast' => CastableReturnsAnonymousCaster::class,
'casted_property_without_return_type' => CastableWithoutReturnType::class,
'extended_casted_property_with_static_return_docblock' => ExtendedSelfCastingCasterWithStaticDocblockReturn::class,
'extended_casted_property_with_this_return_docblock' => ExtendedSelfCastingCasterWithThisDocblockReturn::class,
'casted_property_with_static_return_docblock_and_param' => SelfCastingCasterWithStaticDocblockReturn::class . ':param',
'cast_without_property' => CustomCasterWithReturnType::class,
'cast_inbound_attribute' => InboundAttributeCaster::class,
];
}
@@ -6,6 +6,7 @@ namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCas
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableReturnsAnonymousCaster;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableReturnsCustomCaster;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastableWithoutReturnType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturnFqn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithNullablePrimitiveReturn;
@@ -16,6 +17,7 @@ use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Cas
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithReturnType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\ExtendedSelfCastingCasterWithStaticDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\ExtendedSelfCastingCasterWithThisDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\InboundAttributeCaster;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\SelfCastingCasterWithStaticDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\SelfCastingCasterWithThisDocblockReturn;
use Illuminate\Database\Eloquent\Model;
@@ -27,8 +29,9 @@ use Illuminate\Database\Eloquent\Model;
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $casted_property_with_return_docblock
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $casted_property_with_return_docblock_fqn
* @property array $casted_property_with_return_primitive
* @property array|null $casted_property_with_return_primitive_docblock
* @property array|null $casted_property_with_return_nullable_primitive
* @property array $casted_property_with_return_primitive_docblock
* @property array $casted_property_with_return_nullable_primitive
* @property array|null $casted_property_with_return_nullable_primitive_and_nullable_column
* @property $casted_property_without_return
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $casted_property_with_param
* @property SelfCastingCasterWithStaticDocblockReturn $casted_property_with_static_return_docblock
@@ -38,7 +41,9 @@ use Illuminate\Database\Eloquent\Model;
* @property SelfCastingCasterWithStaticDocblockReturn $casted_property_with_static_return_docblock_and_param
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $casted_property_with_castable
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $casted_property_with_anonymous_cast
* @property CastableWithoutReturnType $casted_property_without_return_type
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $cast_without_property
* @property mixed $cast_inbound_attribute
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast query()
@@ -46,6 +51,7 @@ use Illuminate\Database\Eloquent\Model;
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast whereCastedPropertyWithReturnDocblock($value)
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast whereCastedPropertyWithReturnDocblockFqn($value)
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast whereCastedPropertyWithReturnNullablePrimitive($value)
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast whereCastedPropertyWithReturnNullablePrimitiveAndNullableColumn($value)
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast whereCastedPropertyWithReturnPrimitive($value)
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast whereCastedPropertyWithReturnPrimitiveDocblock($value)
* @method static \Illuminate\Database\Eloquent\Builder|CustomCast whereCastedPropertyWithReturnType($value)
@@ -66,15 +72,18 @@ class CustomCast extends Model
'casted_property_with_return_primitive' => CustomCasterWithPrimitiveReturn::class,
'casted_property_with_return_primitive_docblock' => CustomCasterWithPrimitiveDocblockReturn::class,
'casted_property_with_return_nullable_primitive' => CustomCasterWithNullablePrimitiveReturn::class,
'casted_property_with_return_nullable_primitive_and_nullable_column' => CustomCasterWithNullablePrimitiveReturn::class,
'casted_property_without_return' => CustomCasterWithoutReturnType::class,
'casted_property_with_param' => CustomCasterWithParam::class . ':param',
'casted_property_with_static_return_docblock' => SelfCastingCasterWithStaticDocblockReturn::class,
'casted_property_with_this_return_docblock' => SelfCastingCasterWithThisDocblockReturn::class,
'casted_property_with_castable' => CastableReturnsCustomCaster::class,
'casted_property_with_anonymous_cast' => CastableReturnsAnonymousCaster::class,
'casted_property_without_return_type' => CastableWithoutReturnType::class,
'extended_casted_property_with_static_return_docblock' => ExtendedSelfCastingCasterWithStaticDocblockReturn::class,
'extended_casted_property_with_this_return_docblock' => ExtendedSelfCastingCasterWithThisDocblockReturn::class,
'casted_property_with_static_return_docblock_and_param' => SelfCastingCasterWithStaticDocblockReturn::class . ':param',
'cast_without_property' => CustomCasterWithReturnType::class,
'cast_inbound_attribute' => InboundAttributeCaster::class,
];
}
@@ -83,7 +83,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
* @property string $macaddress_not_nullable
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection|Post[] $relationHasMany
* @property-read \Illuminate\Database\Eloquent\Collection<int, Post> $relationHasMany
* @method static \Illuminate\Database\Eloquent\Builder|Post newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Post newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Post query()
@@ -97,4 +97,14 @@ class Simple extends Model
{
return $this->testToManyRelation(Simple::class);
}
public function relationSampleToAnyRelationType()
{
return $this->testToAnyRelation(Simple::class);
}
public function relationSampleToAnyMorphedRelationType()
{
return $this->testToAnyMorphedRelation(Simple::class);
}
}
@@ -6,6 +6,7 @@ namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToAnyRelationType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToManyRelationType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToOneRelationType;
use Illuminate\Support\Facades\Config;
@@ -19,6 +20,13 @@ class Test extends AbstractModelsCommand
Config::set('ide-helper.additional_relation_types', [
'testToOneRelation' => SampleToOneRelationType::class,
'testToManyRelation' => SampleToManyRelationType::class,
'testToAnyRelation' => SampleToAnyRelationType::class,
'testToAnyMorphedRelation' => SampleToAnyMorphedRelationType::class,
]);
Config::set('ide-helper.additional_relation_return_types', [
'testToAnyRelation' => 'many',
'testToAnyMorphedRelation' => 'morphTo',
]);
}
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Traits;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToAnyMorphedRelationType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToAnyRelationType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToManyRelationType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToOneRelationType;
@@ -20,4 +22,16 @@ trait HasTestRelations
$instance = $this->newRelatedInstance($related);
return new SampleToManyRelationType($instance->newQuery(), $this);
}
public function testToAnyRelation($related)
{
$instance = $this->newRelatedInstance($related);
return new SampleToAnyRelationType($instance->newQuery(), $this);
}
public function testToAnyMorphedRelation($related)
{
$instance = $this->newRelatedInstance($related);
return new SampleToAnyMorphedRelationType($instance->newQuery(), $this);
}
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\Relation;
class SampleToAnyMorphedRelationType extends Relation
{
public function addConstraints()
{
// Fake
}
public function addEagerConstraints(array $models)
{
// Fake
}
public function initRelation(array $models, $relation)
{
// Fake
}
public function match(array $models, Collection $results, $relation)
{
// Fake
}
public function getResults()
{
// Fake
}
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\Relation;
class SampleToAnyRelationType extends Relation
{
public function addConstraints()
{
// Fake
}
public function addEagerConstraints(array $models)
{
// Fake
}
public function initRelation(array $models, $relation)
{
// Fake
}
public function match(array $models, Collection $results, $relation)
{
// Fake
}
public function getResults()
{
// Fake
}
}
@@ -75,25 +75,28 @@ use Illuminate\Database\Eloquent\Relations\MorphToMany;
* @property integer $id
* @property-read Simple|null $relationBelongsTo
* @property-read AnotherModel|null $relationBelongsToInAnotherNamespace
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationBelongsToMany
* @property-read \Illuminate\Database\Eloquent\Collection<int, Simple> $relationBelongsToMany
* @property-read int|null $relation_belongs_to_many_count
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationBelongsToManyWithSub
* @property-read \Illuminate\Database\Eloquent\Collection<int, Simple> $relationBelongsToManyWithSub
* @property-read int|null $relation_belongs_to_many_with_sub_count
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationBelongsToManyWithSubAnother
* @property-read \Illuminate\Database\Eloquent\Collection<int, Simple> $relationBelongsToManyWithSubAnother
* @property-read int|null $relation_belongs_to_many_with_sub_another_count
* @property-read AnotherModel|null $relationBelongsToSameNameAsColumn
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationHasMany
* @property-read \Illuminate\Database\Eloquent\Collection<int, Simple> $relationHasMany
* @property-read int|null $relation_has_many_count
* @property-read Simple|null $relationHasOne
* @property-read Simple $relationHasOneWithDefault
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationMorphMany
* @property-read \Illuminate\Database\Eloquent\Collection<int, Simple> $relationMorphMany
* @property-read int|null $relation_morph_many_count
* @property-read Simple|null $relationMorphOne
* @property-read Model|\Eloquent $relationMorphTo
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationMorphedByMany
* @property-read \Illuminate\Database\Eloquent\Collection<int, Simple> $relationMorphedByMany
* @property-read int|null $relation_morphed_by_many_count
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationSampleRelationType
* @property-read \Illuminate\Database\Eloquent\Collection<int, Simple> $relationSampleRelationType
* @property-read int|null $relation_sample_relation_type_count
* @property-read Model|\Eloquent $relationSampleToAnyMorphedRelationType
* @property-read \Illuminate\Database\Eloquent\Collection<int, Simple> $relationSampleToAnyRelationType
* @property-read int|null $relation_sample_to_any_relation_type_count
* @property-read Simple $relationSampleToManyRelationType
* @method static \Illuminate\Database\Eloquent\Builder|Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple newQuery()
@@ -182,4 +185,14 @@ class Simple extends Model
{
return $this->testToManyRelation(Simple::class);
}
public function relationSampleToAnyRelationType()
{
return $this->testToAnyRelation(Simple::class);
}
public function relationSampleToAnyMorphedRelationType()
{
return $this->testToAnyMorphedRelation(Simple::class);
}
}
@@ -24,10 +24,14 @@ class SimpleCast extends Model
'cast_to_collection' => 'collection',
'cast_to_date' => 'date',
'cast_to_datetime' => 'datetime',
'cast_to_date_serialization' => 'date:Y-m-d',
'cast_to_datetime_serialization' => 'datetime:Y-m-d H:i:s',
'cast_to_custom_datetime' => 'custom_datetime:Y-m-d H:i:s',
'cast_to_immutable_date' => 'immutable_date',
'cast_to_immutable_date_serialization' => 'immutable_date:Y-m-d',
'cast_to_immutable_custom_datetime' => 'immutable_custom_datetime:Y-m-d H:i:s',
'cast_to_immutable_datetime' => 'immutable_datetime',
'cast_to_immutable_datetime_serialization' => 'immutable_datetime:Y-m-d H:i:s',
'cast_to_timestamp' => 'timestamp',
'cast_to_encrypted' => 'encrypted',
'cast_to_encrypted_array' => 'encrypted:array',
@@ -24,10 +24,14 @@ use Illuminate\Database\Eloquent\Model;
* @property \Illuminate\Support\Collection $cast_to_collection
* @property \Illuminate\Support\Carbon $cast_to_date
* @property \Illuminate\Support\Carbon $cast_to_datetime
* @property \Illuminate\Support\Carbon $cast_to_date_serialization
* @property \Illuminate\Support\Carbon $cast_to_datetime_serialization
* @property \Illuminate\Support\Carbon $cast_to_custom_datetime
* @property \Carbon\CarbonImmutable $cast_to_immutable_date
* @property \Carbon\CarbonImmutable $cast_to_immutable_date_serialization
* @property \Carbon\CarbonImmutable $cast_to_immutable_custom_datetime
* @property \Carbon\CarbonImmutable $cast_to_immutable_datetime
* @property \Carbon\CarbonImmutable $cast_to_immutable_datetime_serialization
* @property integer $cast_to_timestamp
* @property mixed $cast_to_encrypted
* @property array $cast_to_encrypted_array
@@ -43,7 +47,9 @@ use Illuminate\Database\Eloquent\Model;
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToCollection($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToCustomDatetime($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToDate($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToDateSerialization($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToDatetime($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToDatetimeSerialization($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToDecimal($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToDouble($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToEncrypted($value)
@@ -54,7 +60,9 @@ use Illuminate\Database\Eloquent\Model;
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToFloat($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToImmutableCustomDatetime($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToImmutableDate($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToImmutableDateSerialization($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToImmutableDatetime($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToImmutableDatetimeSerialization($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToInt($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToInteger($value)
* @method static \Illuminate\Database\Eloquent\Builder|SimpleCast whereCastToJson($value)
@@ -82,10 +90,14 @@ class SimpleCast extends Model
'cast_to_collection' => 'collection',
'cast_to_date' => 'date',
'cast_to_datetime' => 'datetime',
'cast_to_date_serialization' => 'date:Y-m-d',
'cast_to_datetime_serialization' => 'datetime:Y-m-d H:i:s',
'cast_to_custom_datetime' => 'custom_datetime:Y-m-d H:i:s',
'cast_to_immutable_date' => 'immutable_date',
'cast_to_immutable_date_serialization' => 'immutable_date:Y-m-d',
'cast_to_immutable_custom_datetime' => 'immutable_custom_datetime:Y-m-d H:i:s',
'cast_to_immutable_datetime' => 'immutable_datetime',
'cast_to_immutable_datetime_serialization' => 'immutable_datetime:Y-m-d H:i:s',
'cast_to_timestamp' => 'timestamp',
'cast_to_encrypted' => 'encrypted',
'cast_to_encrypted_array' => 'encrypted:array',
@@ -13,11 +13,11 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @property integer $id
* @method static \Illuminate\Database\Eloquent\Builder|Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple newQuery()
* @method static \Illuminate\Database\Query\Builder|Simple onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Simple onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|Simple whereId($value)
* @method static \Illuminate\Database\Query\Builder|Simple withTrashed()
* @method static \Illuminate\Database\Query\Builder|Simple withoutTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Simple withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Simple withoutTrashed()
* @mixin \Eloquent
*/
class Simple extends Model
@@ -9,15 +9,6 @@ use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
class Test extends AbstractModelsCommand
{
protected function setUp(): void
{
parent::setUp();
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped('This test requires PHP 8.0 or higher');
}
}
public function test(): void
{
$command = $this->app->make(ModelsCommand::class);
@@ -12,7 +12,7 @@ use Illuminate\Database\Query\Builder;
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\UnionTypes\Models\UnionTypeModel
*
* @property-read string|int|null $foo
* @property-read \Illuminate\Database\Eloquent\Collection|UnionTypeModel[] $withUnionTypeReturn
* @property-read \Illuminate\Database\Eloquent\Collection<int, UnionTypeModel> $withUnionTypeReturn
* @property-read int|null $with_union_type_return_count
* @method static \Illuminate\Database\Eloquent\Builder|UnionTypeModel newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UnionTypeModel newQuery()
@@ -17,6 +17,7 @@ class CustomCastsTable extends Migration
$table->string('casted_property_with_return_primitive');
$table->string('casted_property_with_return_primitive_docblock');
$table->string('casted_property_with_return_nullable_primitive');
$table->string('casted_property_with_return_nullable_primitive_and_nullable_column')->nullable();
$table->string('casted_property_without_return');
$table->string('casted_property_with_param');
$table->string('casted_property_with_static_return_docblock');
@@ -26,10 +26,14 @@ class SimpleCastsTable extends Migration
$table->string('cast_to_collection');
$table->string('cast_to_date');
$table->string('cast_to_datetime');
$table->string('cast_to_date_serialization');
$table->string('cast_to_datetime_serialization');
$table->string('cast_to_custom_datetime');
$table->string('cast_to_immutable_date');
$table->string('cast_to_immutable_date_serialization');
$table->string('cast_to_immutable_custom_datetime');
$table->string('cast_to_immutable_datetime');
$table->string('cast_to_immutable_datetime_serialization');
$table->string('cast_to_timestamp');
$table->string('cast_to_encrypted');
$table->string('cast_to_encrypted_array');
+2 -6
View File
@@ -190,10 +190,6 @@ class MacroTest extends TestCase
public function testInitPhpDocParamsWithUnionTypes(): void
{
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped('This test requires PHP 8.0 or higher');
}
$phpdoc = (new MacroMock())->getPhpDoc(eval(<<<'PHP'
return new ReflectionFunction(
/**
@@ -231,7 +227,7 @@ class MacroTest extends TestCase
{
$reflectionMethod = new \ReflectionMethod(UrlGeneratorMacroClass::class, '__invoke');
$macro = new Macro($reflectionMethod, UrlGenerator::class, new \ReflectionClass(UrlGenerator::class), 'macroName');
$macro = new Macro($reflectionMethod, UrlGenerator::class, new ReflectionClass(UrlGenerator::class), 'macroName');
$this->assertInstanceOf(Macro::class, $macro);
}
@@ -243,7 +239,7 @@ class MacroTest extends TestCase
{
$reflectionMethod = new \ReflectionMethod(UrlGeneratorMacroClass::class, '__invoke');
$macro = new Macro($reflectionMethod, 'URL', new \ReflectionClass(UrlGenerator::class), 'macroName');
$macro = new Macro($reflectionMethod, 'URL', new ReflectionClass(UrlGenerator::class), 'macroName');
$output = <<<'DOC'
/**
*
+90
View File
@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests;
use Barryvdh\LaravelIdeHelper\Generator;
use Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View;
use PhpParser\Lexer\Emulative;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\Parser\Php7;
class RealTimeFacadesTest extends TestCase
{
public function testRealTimeFacades()
{
// Add the views path to the view finder so the generator actually generates the file
View::addLocation(__DIR__ . '/../resources/views');
// Clear cached real-time facades
$cachedFacades = glob(storage_path('framework/cache/facade-*.php'));
foreach ($cachedFacades as $cachedFacade) {
unlink($cachedFacade);
}
// Copy stubs to storage path as if the real-time facades were cached by the framework
copy(
__DIR__ . '/stubs/facade-0e0385307adf5db34c7986ecbd11646061356ec8.php',
storage_path('framework/cache/facade-0e0385307adf5db34c7986ecbd11646061356ec8.php')
);
copy(
__DIR__ . '/stubs/facade-9431b04ec1494fc71a1bc848f020044aba2af7b1.php',
storage_path('framework/cache/facade-9431b04ec1494fc71a1bc848f020044aba2af7b1.php')
);
// new instance of the generator which we test
$generator = new Generator($this->app['config'], $this->app['view'], null, false);
// Clear aliases and macros to have a small output file
AliasLoader::getInstance()->setAliases([]);
Request::flushMacros();
// Generate the helper file and return the content
$content = $generator->generate();
$this->assertStringContainsString('namespace Facades\Illuminate\Foundation\Exceptions {', $content, 'Could not find Facades\Illuminate\Foundation\Exceptions namespace in the generated helper file.');
$this->assertStringContainsString('namespace Facades\App\Exceptions {', $content, 'Could not find Facades\App\Exceptions namespace in the generated helper file.');
$parsed = collect((new Php7(new Emulative()))->parse($content) ?: []);
// test the Facades\Illuminate\Foundation\Exceptions namespace in the generated helper file
$frameworkExceptionsNamespace = $parsed->first(function ($stmt) {
return ($stmt instanceof Namespace_) && $stmt->name->toString() === 'Facades\Illuminate\Foundation\Exceptions';
});
$this->assertNotNull($frameworkExceptionsNamespace, 'Could not find Facades\Illuminate\Foundation\Exceptions namespace');
$this->assertSame('Facades\Illuminate\Foundation\Exceptions', $frameworkExceptionsNamespace->name->toString());
$this->verifyNamespace($frameworkExceptionsNamespace, 'Illuminate\Foundation\Exceptions\Handler');
// test the Facades\App\Exceptions namespace in the generated helper file
$appExceptionsNamespace = $parsed->first(function ($stmt) {
return ($stmt instanceof Namespace_) && $stmt->name->toString() === 'Facades\App\Exceptions';
});
$this->assertNotNull($appExceptionsNamespace, 'Could not find Facades\App\Exceptions namespace');
$this->assertSame('Facades\App\Exceptions', $appExceptionsNamespace->name->toString());
$this->verifyNamespace($appExceptionsNamespace, 'App\Exceptions\Handler');
}
private function verifyNamespace(Namespace_ $namespace, $target)
{
$stmts = collect($namespace->stmts);
$this->assertInstanceOf(Class_::class, $stmts[0], 'Expected instance of Class_');
$statement = $stmts[0];
$this->assertArrayHasKey('comments', $statement->getAttributes());
$this->assertStringContainsString('@mixin \\' . $target, $statement->getAttributes()['comments'][0]->getText(), 'Mixin comment not found');
$this->assertSame(class_basename($target), $statement->name->toString(), 'Class name not found');
$this->assertSame($target, $statement->extends->toString(), 'Class extends not found');
}
protected function getPackageProviders($app)
{
return [IdeHelperServiceProvider::class];
}
}
@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace Facades\Illuminate\Foundation\Exceptions;
use Illuminate\Support\Facades\Facade;
/**
* @see \Illuminate\Foundation\Exceptions\Handler
*/
class Handler extends Facade
{
/**
* Get the registered name of the component.
*/
protected static function getFacadeAccessor(): string
{
return 'Illuminate\Foundation\Exceptions\Handler';
}
}
@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace Facades\App\Exceptions;
use Illuminate\Support\Facades\Facade;
/**
* @see \App\Exceptions\Handler
*/
class Handler extends Facade
{
/**
* Get the registered name of the component.
*/
protected static function getFacadeAccessor(): string
{
return 'App\Exceptions\Handler';
}
}