Compare commits

...
358 Commits
Author SHA1 Message Date
Barry vd. Heuvel 5f677edc14 Private->protected 2020-04-22 11:57:26 +02:00
Barry vd. Heuvel 1b611d7f80 Check if CastsAttributes exists 2020-04-22 11:55:33 +02:00
Krot Eval a233d5bd5a Ability to use patterns for model_locations (#921)
Example: app/Services/*/Models
2020-04-22 06:33:49 +02:00
belamov cfa9a81d65 Added support for Laravel 7 custom casts (#913)
* added support for laravel 7 custom casts

* refactored tests; added test cases

* added test case

* resolved method dublication
2020-04-22 06:32:40 +02:00
mzglinskiandMichał Zgliński dcf76c1a81 Generate noinspections PHPStorm tags (#905)
* Generate noinspections PHPStorm tags

* Add comments about PHPStorm noinspection tags

* Fix line to long warnings

* Add tests for PHPStorm noinspection

Co-authored-by: Michał Zgliński <[email protected]>
2020-04-21 21:36:27 +02:00
Barry vd. Heuvel bef8158d02 Merge pull request #901 from loilo/fix-default-param-values
Prevent generation of invalid code for certain parameter default values
2020-04-21 21:35:11 +02:00
Barry vd. Heuvel 8381a2ebdd Merge pull request #906 from mfn/mfn-return-reflection
Infer return type from reflection if no phpdoc given
2020-04-21 21:16:27 +02:00
Barry vd. Heuvel 6bab45b8c2 Merge pull request #920 from mr-feek/include-interfaces
if a model implements interfaces, include them in the stub
2020-04-21 21:15:37 +02:00
Feek 2617352869 if a model implements interfaces, include them in the stub 2020-04-21 02:32:02 -07:00
Barry vd. Heuvel ce275a9bf2 Merge pull request #919 from mr-feek/unregister-custom-autoloader
fix: unregister meta command custom autoloader when it is no longer needed
2020-04-20 18:22:59 +02:00
Feek b7b835bf09 fix: unregister meta command custom autoloader when it is no longer needed. closes #915 2020-04-19 18:05:23 -07:00
Barry vd. Heuvel b0481aef33 Merge pull request #908 from goodjack/patch-1
Update the version in the comment
2020-04-19 07:51:11 +02:00
Barry vd. Heuvel f80887914b Update helper.php 2020-04-19 07:51:00 +02:00
Markus Podar f4ae4c4b45 Remove unnecessary and wrong definition of SoftDelete methods (#918)
These two methods are already regular methods on the trait, there's no
need to add them and additionally they're not static, so their
definition was changed for the worse.

The other methods are magic so it's fine to keep them.

Fixes https://github.com/barryvdh/laravel-ide-helper/issues/917
2020-04-19 07:49:54 +02:00
Daniel MasonandMarkus Podar 6a27c5df68 Add custom collection support for get and all methods (#903)
* Add custom collection support for get and all methods

* Only add get and all when using custom collection

* Use static instead of class name

* Add missing custom collection test with relation

* Use class reference over string

Co-Authored-By: Markus Podar <[email protected]>

* Fix when using class reference

Co-authored-by: Markus Podar <[email protected]>
2020-04-19 07:49:23 +02:00
小克 7be6afbe5f Update the version in the comment 2020-04-06 18:52:32 +08:00
Markus Podar b72689755b Infer return type from reflection if no phpdoc given 2020-04-01 22:44:26 +02:00
Florian ReuschelandMarkus Podar 3cc7d7ccf6 Improve test method doc block
Co-Authored-By: Markus Podar <[email protected]>
2020-03-31 21:19:33 +02:00
leo108 18588eacf3 Make hasOne / hasOneThrough and morphOne nullable. (#864) 2020-03-31 14:40:50 +02:00
Loilo da59650fb2 Add test for method default values with special chars 2020-03-26 09:37:33 +01:00
Loilo fe2890925e Prevent generation of invalid code for certain parameter default values 2020-03-25 23:51:04 +01:00
Barry vd. Heuvel 1d1484025c Test L7 (#899)
* Test L7

* Update composer.json
2020-03-10 15:00:00 +01:00
Pataar 0692626c41 Add ignored_models as config option (#890)
* Add ignored_models as config option

* Add README.md entry

* Add tests

* Change name of test class

* Add Ignored to the return values from the mocked filesystem

* Improve test speed by adding prestissimo

* Revert "Improve test speed by adding prestissimo"

This reverts commit 246a9f2a78.
2020-03-10 12:18:29 +01:00
Sergio García 90437012b8 Fix camelCase duplicated properties generator. (#881)
* Fix camelCase duplicated properties generator.

* Add basic tests for camel case
2020-03-10 12:17:29 +01:00
Kirill Uksusov e743f44011 Fixed #892 (#894)
* Fixed #892

* #892 test added
2020-03-03 10:48:00 +01:00
Barry vd. Heuvel edd69c5e05 Allow L7 2020-02-25 21:41:32 +01:00
Markus Podar 68d3d19298 tests: fix after recent merged "stepping on each others toes" (#882)
🩰
2020-02-02 21:12:24 +01:00
Markus Podar 75149ddb1f tests: cover reset and smart-reset options (#875) 2020-01-12 18:24:10 +01:00
Markus Podar e020e265a4 Fixed bug in model command where loose string comparison would override properties for model relations (#873) 2020-01-12 18:23:52 +01:00
Markus Podar 6af1f32d96 tests: fix typo in migration 🤦‍♂️ and adapt tests (#874) 2020-01-12 18:23:27 +01:00
Matt A 972befd7aa Prevent undefined property errors (#877)
If the property name matches the foreign key name
creating a BelongsTo relation triggers an undefined
property error. Disabling constraints prevents
accessing the property and thus prevents the error.
2020-01-12 17:51:04 +01:00
Johannes Rudolph 805c4e9a2a Update ModelsCommand.php (#862)
Improve Error Reporting for easy debugging
2020-01-05 11:53:34 +01:00
Markus Podar c0bb9ee1fd Add more tests (#870)
* tests: be more systematic when testing discrete column types

Still not covering all due to SQLite limitation

* tests: relations of models

* tests: model in another namespace gets correctly qualified

* tests: cover SoftDeletes trait

* tests: cover some variants of getter
2020-01-03 23:08:24 +01:00
Markus Podar d9a731daba [TESTS] Add some basic tests for ModelsCommand (#869)
* tests: add abstract class for all database related tests

* tests: add abstract class for all ModelsCommand related tests

* tests: add GenerateBasicPhpdoc test

* tests: add CustomDate test

* tests: remove MITM abstract TestCaseDatabase, not useful here

* tests: skip new ModelsCommand test on Laravel < 6

* tests: remove CarbonImmutable checked

Since we decided to skip for Laravel < 6.0 anyway, it's always present
2020-01-03 09:52:10 +01:00
Markus Podar d3b24ffeae Bump grumphp version (#867)
The current version emits the following:
```
Deprecated: strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior in laravel-ide-helper/vendor/phpro/grumphp/src/Locator/ConfigurationFile.php on line 75

Deprecated: strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior in laravel-ide-helper/vendor/phpro/grumphp/src/Locator/ConfigurationFile.php on line 75

```

Manually tested it locally, worked as expected.
2020-01-02 15:21:05 +01:00
Markus Podar 015cc6c493 Drop support for PHP < 7.2 and improve test matrix (#868)
* travis: use explicit test matrix and drop PHP < 7.2

* composer: use more liberal version requirements for orchestra

This is to easier satisfy when we want to use older Laravel versions on travis

* tests: add shim for assertStringContainsString for older Laravel/phpunit versions

Specifically, Laravel 5.5 works with an older phpunit version, which
does not feature assertStringContainsString

* composer: bump minimum PHP version to 7.2

* travis: explicitly install Mockery for testing older Laravel versions

* composer: make mockery a root requirement and remove the one from travis

* travis: further improve based on suggestions from https://github.com/fruitcake/laravel-cors/blob/master/.travis.yml

* tests: skip test if mixin markers are already present in model

We're also testing Laravel 5.5 which contains them (they were removed later)
2020-01-02 14:39:34 +01:00
Markus Podar 44f289f76a [CHORE] Remove unused/stale utilities (#866)
* Remove grumphp

It reports so many violations, I don't think anyone paid attention
to them in some time.

Also there's code sniffer which is:
- installed
- works
- and also run on travis explicitly

Here are the current violations:

```
$ vendor/bin/grumphp run
PHP Deprecated:  strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior in /Users/mfischer/src/laravel-ide-helper/vendor/phpro/grumphp/src/Locator/ConfigurationFile.php on line 75

Deprecated: strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior in /Users/mfischer/src/laravel-ide-helper/vendor/phpro/grumphp/src/Locator/ConfigurationFile.php on line 75
GrumPHP is sniffing your code!✘
Running task 2/2: Phpunit... ✔
             ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
           ▄▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌
         ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
        ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌
       ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌
  ▄███▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌
 █▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌
 ▐█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌
   ▀█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌
     ▀▀▓▓▓▓▓▓▓▓▓▓▓▓█▀▀▀▀▀▀▀▀▀▀▀▀▀▀████████████▄
      ▄███████                       ██████████
     ███████▀  ▀▀▀▀▀▄      ▄▀▀▀▀▀     █████ ▀
      ▐████      ▐██        ▐██        ████▌
      ████▌                            ███
       ▌██▌           ▄▄ ▄▄           ▐███
        ███       ▄▄▄▄▄▄▄▄▄▄▄▄       ▐███
         ██▄ ▐███████████████████████████
        █▀███████████▀     ▀▀███████████
          ██████████▄███████▄███████████
         ▐█████████████████████████████
          █████████████████████████████
           ██ █████████████████████▐██▀
            ▀ ▐███████████████████▌ ▐▀
                ████▀████████▀▐███
                 ▀█▌  ▐█████  ██▌
                        ██▀   ▐▀

       ██████████████████████████████████
       █░░░░░░▀█▀░░░░░░▀█░░░░░░▀█▀░░░░░▀█
       █░░▐█▌░░█░░░██░░░█░░██░░░█░░░██░░█
       █░░▐█▌░░█░░░██░░░█░░██░░░█░░░██░░█
       █░░▐█▌░░█░░░██░░░█░░░░░░▄█░░▄▄▄▄▄█
       █░░▐█▌░░█░░░██░░░█░░░░████░░░░░░░█
       █░░░█░░░█▄░░░░░░▄█░░░░████▄░░░░░▄█
       ██████████████████████████████████

FILE: ...Users/mfischer/src/laravel-ide-helper/resources/views/helper.php
----------------------------------------------------------------------
FOUND 46 ERRORS AND 3 WARNINGS AFFECTING 24 LINES
----------------------------------------------------------------------
  23 | ERROR   | [x] Expected 1 space(s) after FOREACH keyword; 0
     |         |     found
  23 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  24 | ERROR   | [x] Line indented incorrectly; expected at least 4
     |         |     spaces, found 0
  24 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  24 | ERROR   | [x] Newline required after opening brace
  24 | ERROR   | [x] Closing brace must be on a line by itself
  24 | ERROR   | [x] Each PHP statement must be on a line by itself
  26 | ERROR   | [x] Line indented incorrectly; expected at least 4
     |         |     spaces, found 0
  26 | ERROR   | [x] Expected 1 space(s) after FOREACH keyword; 0
     |         |     found
  26 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  26 | ERROR   | [x] Blank line found at start of control structure
  28 | ERROR   | [x] Line indented incorrectly; expected at least 8
     |         |     spaces, found 4
  29 | ERROR   | [x] Line indented incorrectly; expected at least 8
     |         |     spaces, found 4
  30 | ERROR   | [x] Expected 1 space(s) after FOREACH keyword; 0
     |         |     found
  30 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  30 | ERROR   | [x] Blank line found at start of control structure
  32 | ERROR   | [x] Line indented incorrectly; expected at least 12
     |         |     spaces, found 8
  34 | ERROR   | [x] Expected 1 space(s) after IF keyword; 0 found
  34 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  34 | ERROR   | [x] Blank line found at start of control structure
  37 | ERROR   | [x] Closing brace indented incorrectly; expected 9
     |         |     spaces, found 12
  39 | ERROR   | [x] Expected 1 space(s) after IF keyword; 0 found
  39 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  51 | ERROR   | [x] Expected 1 space(s) after FOREACH keyword; 0
     |         |     found
  51 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  53 | ERROR   | [x] Line indented incorrectly; expected at least 4
     |         |     spaces, found 0
  53 | ERROR   | [x] Expected 1 space(s) after FOREACH keyword; 0
     |         |     found
  53 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  53 | ERROR   | [x] Blank line found at start of control structure
  55 | ERROR   | [x] Line indented incorrectly; expected at least 8
     |         |     spaces, found 4
  55 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  55 | WARNING | [ ] Line exceeds 120 characters; contains 180
     |         |     characters
  56 | ERROR   | [x] Expected 1 space(s) after FOREACH keyword; 0
     |         |     found
  56 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  59 | ERROR   | [x] Expected 1 space(s) after IF keyword; 0 found
  59 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  59 | ERROR   | [x] Blank line found at start of control structure
  62 | ERROR   | [x] Closing brace indented incorrectly; expected 13
     |         |     spaces, found 16
  64 | ERROR   | [x] Expected 1 space(s) after IF keyword; 0 found
  64 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  70 | ERROR   | [x] Closing brace indented incorrectly; expected 4
     |         |     spaces, found 0
  76 | ERROR   | [x] Expected 1 space(s) after IF keyword; 0 found
  76 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
  78 | ERROR   | [x] Line indented incorrectly; expected at least 4
     |         |     spaces, found 0
  82 | ERROR   | [x] Expected 1 space(s) after IF keyword; 0 found
  82 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
 109 | ERROR   | [x] Expected 1 space(s) after closing parenthesis;
     |         |     found 0
 112 | WARNING | [ ] Line exceeds 120 characters; contains 141
     |         |     characters
 113 | WARNING | [ ] Line exceeds 120 characters; contains 139
     |         |     characters
----------------------------------------------------------------------
PHPCBF CAN FIX THE 46 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

FILE: /Users/mfischer/src/laravel-ide-helper/resources/views/meta.php
----------------------------------------------------------------------
FOUND 10 ERRORS AFFECTING 6 LINES
----------------------------------------------------------------------
 14 | ERROR | [x] Expected 1 space(s) after closing parenthesis;
    |       |     found 0
 17 | ERROR | [x] Line indented incorrectly; expected at least 4
    |       |     spaces, found 0
 17 | ERROR | [x] Expected 1 space(s) after FOREACH keyword; 0 found
 17 | ERROR | [x] Expected 1 space(s) after closing parenthesis;
    |       |     found 0
 23 | ERROR | [x] Expected 1 space(s) after closing parenthesis;
    |       |     found 0
 24 | ERROR | [x] Spaces must be used to indent lines; tabs are not
    |       |     allowed
 26 | ERROR | [x] Line indented incorrectly; expected at least 4
    |       |     spaces, found 0
 26 | ERROR | [x] Expected 1 space(s) after FOREACH keyword; 0 found
 26 | ERROR | [x] Expected 1 space(s) after closing parenthesis;
    |       |     found 0
 29 | ERROR | [x] Spaces must be used to indent lines; tabs are not
    |       |     allowed
----------------------------------------------------------------------
PHPCBF CAN FIX THE 10 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

Time: 260ms; Memory: 12MB
```

* Remove scrutinizer/ocular

Looks unused, also not used on travis

* Remove StyleCI

Isn't enabled

* Revert "Remove grumphp"

This reverts commit a69696f0

* grumphp: add whitelist to ignore the resources/ folder

* grumphp: per .editorconf the indentation is 4 spaces, not 2
2020-01-02 11:34:21 +01:00
Markus Podar fb0c576806 [PROPOSAL] Add more tests to the library (#865)
* phpunit: use dedicate `Tests` namespace for tests

* tests: replace phpunit with orchestra/testbench

* phpunit: ignore result cache file

* phpunit: adapt test for newer version

* tests: add base testcase class with a helper to run/assert commands

* tests: add test for ide-helper:eloquent

* travis: add global default variables

* travis: disable xdebug, speeds up running tests

* travis: convert php versions to build matrix for environment vars

* travis: only run phpcs/phpunit when the env vars signal it

However phpcs only runs with one test combination from the matrix,
not necessary to execute it every time.
2020-01-01 22:51:21 +01:00
Markus Podar 0d1dd2182b Add support for custom date class via Date::use() (#859)
Laravel 5.8 introduced a feature to support a custom date class via
`Date::use()`, see https://github.com/laravel/framework/pull/25320

When e.g. using `Date::use(CarbonImmutable)` in a project, it means
all date casts are not returning `\Illuminate\Support\Carbon` anymore
but `\Carbon\CarbonImmutable`, which means all the generated type hints
for dates are now wrong.

This change tries to be still backwards compatible with Laravel < 5.8
which do not have the Date facade.
2019-12-28 14:33:08 +01:00
Graham Campbell 027e58fd56 Removed legacy travis option (#861) 2019-12-25 15:16:51 +01:00
mihaileu a46e3b4505 test agains php 7.4 (#854) 2019-12-25 12:18:37 +01:00
Yuta Nagamiya e7734d3c20 Add splat operator (...) support (#860)
* Add splat operator (...) support

* Add test
2019-12-25 12:17:50 +01:00
mihaileu fcf3fae860 add php 7.3 to travis (#853)
allow testing via php 7.3
2019-12-09 20:28:07 +01:00
Barry vd. Heuvel b91b959364 Create FUNDING.yml 2019-10-30 21:53:27 +01:00
naneri 9b0fbb4467 Added table of contents to Readme.md (#833) 2019-10-02 17:32:49 +02:00
Chris Morrell 6c8e847430 Add support for factory()->create() return types (#758)
* Revert "Forked release"

* Initial factory builder support

* Oops — fixed tabs

* Revert "Forked release"

* Whitespace

* Reverted more code

* Whitespace

* More whitespace

* Fixed PHPCS line
2019-10-01 20:18:19 +02:00
cxlblm 25b61c56fe __toString function has been DEPRECATED (#801)
* __toString function has been DEPRECATED

__toString function has been DEPRECATED as of PHP 7.1.0

* remove code

remove code
2019-09-17 07:08:26 +02:00
Alex 428d32cebd Add hasOneThrough to ide-helper:models (#807)
Added missing relation type.
2019-09-16 14:33:30 +02:00
Matthew Hailwood 51a72d7766 [PSR-12] Update param type array to use short array syntax (#828)
* Update Param type array to use short array syntax (PSR-12)

* Update Param type array to use short array syntax (PSR-12)
2019-09-16 11:52:59 +02:00
Patompong Savaengsuk d200f2284b Update readme.md (#825)
* Update readme.md

In version 2.6.5, this commit https://github.com/barryvdh/laravel-ide-helper/commit/f8a8cb18e0a42ae4131b7ed865fe792f9b34630c made it so library's consumer no longer need to pull in `doctrine/dbal` manually. I think we should mention that in the readme file as well. Although I'm not sure if it adds any value to the file itself or not.

* Remove note about doctrine/dbal from readme.md
2019-09-11 08:25:44 +02:00
Давид 8faae38655 Update readme.md (#824) 2019-09-10 15:46:31 +02:00
Barry vd. Heuvel 8740a9a158 Fix CS 2019-09-08 11:56:38 +02:00
liquid207 d344cdc842 Fix phpcs (#803) 2019-09-08 11:55:17 +02:00
Mandy Schoep 5e411ef104 Do not added instances of a anonymous class to the phpstorm_meta file (#806) 2019-09-08 11:46:25 +02:00
Barry vd. Heuvel 499a2113b3 Check if method exists 2019-09-08 11:45:23 +02:00
Barry vd. Heuvel f8a8cb18e0 Always require doctrine 2019-09-08 11:36:40 +02:00
Barry vd. Heuvel 16eb4f65ee Update readme.md 2019-09-03 19:51:13 +02:00
Kevin Bond 0edf8f750e remove monolog configuration (fixes #818) (#820) 2019-09-03 19:49:46 +02:00
Johan van Helden 1b15d2930b fix the identation in the config (#817) 2019-08-31 12:53:08 +02:00
Matthew Hailwood 3668e3821a Add support for custom cast classes (#816)
* Add support for custom cast classes

* Fix unrelated code style warning.
2019-08-30 07:32:01 +02:00
Barry vd. Heuvel 7b4cef1ea4 Update composer.json 2019-08-23 14:21:37 +02:00
Stanislas cd2a71d43c ModelsCommand: Remove question mark (#812)
Sorry this is a bit nitpicky 😅
2019-08-06 07:54:53 +02:00
edvordo c9132b28a6 Chages to x2Many relationships detection & adds relationship_count docBlock comment (#783)
* x to Many relationships are detected via a `Many` keyword in the relationship object class name
   * reason: example: `belongsTo` was incorrectly recognized as `belongsToMany`
 * adds `@property-read int|null $x2Many_relationship_method_name_count` model class docBlock comment
   * when model makes use of `withCount` or `loadCount` there is a property on the resource `$instance->relationship_method_count` that states the count of related models
   * can be `NULL` when `withCount` or `loadCount` aren't used
2019-06-18 16:38:42 +02:00
Guilherme Pressutto 8ab6e0536b Fixed meta not working with app()->makeWith() (#791) 2019-05-29 17:09:57 +02:00
Theodore R. Smith 87ebe458e9 Removed confusing README installation instructions (#786)
While installing this for my project, I didn't see the `--dev` instructions until I was literally editing this README for a pull request.

Since laravel-ide-helper is only designed for development purposes, let's just remove the superfluous entry altogether. Smart devs who for some crazy reason need it on prod will know to remove the `--dev`, while less knowledgeable devs won't shoot themselves in the foot accidentally.
2019-04-17 22:07:56 +02:00
leo108 9ef14f83be use Throwable instead of Exception (#779) 2019-03-27 05:56:31 +01:00
Brent Roose 39c148ad42 Support for custom builder classes (#782) 2019-03-26 11:38:22 +01:00
Francis Lavoie 2b3c9a2449 Fix BC introduced in #765 (#778)
See my comment https://github.com/barryvdh/laravel-ide-helper/pull/765#issuecomment-471014271:

The change in #765 made anonymous functions get reflected with `ReflectionMethod` instead of `ReflectionFunction`, which makes it lose the doc comment. This means that the generated helpers are missing their return types. This is because Closure is also an object and callable.

To fix it, Closure should be excluded from that new condition.
2019-03-12 11:38:49 +01:00
Matthew Brown 725711022b Make autoload exception more specific (#777)
This is a nice-to-have ([as I'm currently overriding it](https://github.com/psalm/laravel-psalm-plugin/commit/a700c89061d151d1c08851abd93d834f9183534d)), but might help other packages.
2019-03-05 10:24:51 +01:00
neoteknic 881f77156c Fix php 7.3 bug (#772) 2019-03-02 15:15:16 +01:00
neoteknic 0fad511954 Fix Bug PHP 7.3 & L5.8 (#774)
add cast (string) to disable bug ($type can be null)
2019-03-02 15:14:46 +01:00
Stan Daniëls 754bb4d075 Add support for invokable classes as macro function (#765)
Macros can be used with invokable classes, like so.

```
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;

class ResponseMacroServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Response::macro('foo', new Foo());
    }
}

class Foo
{
    public function __invoke()
    {
        return 'foobar';
    }
}
```

When running `ide-helper:generate` the following fatal error was thrown.

```  Symfony\Component\Debug\Exception\FatalThrowableError  : ReflectionFunction::__construct() expects parameter 1 to be string, object given```

This commit fixes this error.
2019-02-18 20:54:27 +01:00
edcoreweb bcb881b20d Nested relations detection. (#763) 2019-02-03 16:59:09 +01:00
Tim Philips d00600d769 Include DocBloc’s from classes to allow deeper code inspection (#745)
* Add support to include DocBloc’s from classes to allow further code inspection

* Adjust for PSR2

* Additional fix for PSR2
2019-01-28 21:38:57 +01:00
Ahmed Fathy 858dd40844 Install doctrine/dbal on development (#753) 2019-01-28 21:25:55 +01:00
Kyle 4cd11a4d33 Allow Laravel 5.8 (#754) 2019-01-28 21:24:50 +01:00
Barry vd. Heuvel 5439781e7c Update composer.json 2018-12-19 13:13:32 +01:00
+pikari 190bf07c05 fix: warning when call the instance method (#735) 2018-12-19 13:12:44 +01:00
Vladimir Yuldashev 3d7f124089 prevent loading views if view class not in container (#691) 2018-12-19 13:12:05 +01:00
hubertnnn 32df0a3bc6 Fix: Parametrized relationships prevent generation of metadata (#719) 2018-12-19 13:11:08 +01:00
Patrick 2f8283a746 Optionally write missing Laravel Model DocBlock (#700)
* Fix missing doc-block.

* Fixes a bug where a missing DocBlock caused errors.

* Change Option Shorthand to W
Because it is not allowed to have two char shorthands for options.

* Revert code refactoring.

* Fix copied config header.
2018-12-19 13:10:53 +01:00
Barry vd. Heuvel 2a63b31475 Merge pull request #730 from apollopy/master
if aliases not Redis, don't skip
2018-12-19 13:10:13 +01:00
Barry vd. Heuvel 494d1593c8 Merge pull request #732 from HikaruYasuda/fix/duplicateMacroMethods
fix: Macro methods are duplicated registration.
2018-12-19 13:08:48 +01:00
Barry vd. Heuvel e513fb34dc Merge pull request #743 from JeppeKnockaert/fix-travis-timeout
bugfix - Increase composer update timeout in Travis
2018-12-19 13:08:22 +01:00
Barry vd. Heuvel 5db82752ef Merge pull request #742 from JeppeKnockaert/update-reflection-docblock-to-v2-0-6
Update ReflectionDocBlock to v2.0.6
2018-12-19 13:08:07 +01:00
Jeppe Knockaert 1f555bc194 bugfix - Increase composer update timeout in Travis
The composer update takes about 12 minutes, which is just over the
10 minute timeout in Travis.
2018-12-18 08:55:50 +01:00
Jeppe Knockaert b0ce5325de Update ReflectionDocBlock to v2.0.6
This update improves the parsing of return types, allowing array return
types to be recognized.

This was needed to properly recognize the files and allFiles methods as
duplicates (the function filtering duplicate definitions -
`removeDuplicateMethodsFromPhpDoc` in `Alias.php` - didn't recognise
them as duplicates, because the return type was seen as part of the name).
2018-12-17 18:15:59 +01:00
Barry vd. Heuvel aeae59d0af Merge pull request #740 from JeppeKnockaert/fix-cannot-redeclare-method
bugfix - Prevent redeclaring methods inside Aliases
2018-12-17 17:40:51 +01:00
Jeppe Knockaert 001719245c bugfix - Prevent redeclaring methods inside Aliases
The getMethods function gets called both in the removeDuplicateMethodsFromPhpDoc
function and in helper.php, which causes the method detection to be performed twice.

Parts of the method detection includes a check for duplicate methods, but Macro
methods for example, aren't checked for duplicates.

Instead of checking everywhere if we're not adding duplicates, I've included a
check in the getMethods call to just use the already generated methods
if they have been generated already.
2018-12-12 14:46:18 +01:00
Barry vd. Heuvel 99226c92b7 Merge pull request #736 from JeppeKnockaert/fix-real-name-for-closures
bugfix - Do not use the real_name for closures
2018-12-11 12:35:36 +01:00
Jeppe Knockaert dda63bf8df bugfix - Do not use the real_name for closures
Closures do not have a method name that makes sense to use in the ide_helper
file.

e.g. Illuminate\Foundation\Providers\{closure} would be the real_name instead of
just validate. So for the closure methods, we should just use the provided
methodName instead.
2018-12-10 14:14:34 +01:00
HikaruYasuda 3d7f45479e fix: Macro methods are duplicated registration. 2018-12-04 10:33:00 +09:00
ApolloPY 7905dd3926 if aliases not Redis, don't skip 2018-11-30 20:30:51 +08:00
ApolloPY 8d135a1dea Merge pull request #1 from barryvdh/master
merge master
2018-11-30 20:26:36 +08:00
Barry vd. Heuvel 858e730c00 Merge pull request #720 from JeppeKnockaert/remove-duplicate-functions-from-phpdoc
Prevent duplicate function declarations in docblocks
2018-11-07 21:27:14 +01:00
Jeppe Knockaert 2ab961e734 Prevent duplicate function declarations in docblocks
When a method is declared both in the phpdoc and in the class itself,
PhpStorm (2018.3) complains about duplicate function declarations, preventing
correct code hinting.

To solve this, I remove the already declared functions from the generated dockblocks.
2018-11-07 20:59:15 +01:00
Barry vd. Heuvel 981ff45b43 Merge pull request #707 from crhg/fix_getAliases
Fix alias class existence determination #698
2018-10-06 11:35:51 +02:00
Barry vd. Heuvel 8174730714 Merge pull request #714 from pahan35/fix-missed-autocomplete-in-header-view
Fix missed autocomplete in helper view
2018-10-06 11:34:14 +02:00
Barry vd. Heuvel ae5b623cf2 Merge pull request #713 from pahan35/fix-missed-methods-with-same-name
Fix missed methods with same name
2018-10-06 11:33:25 +02:00
Pavlo Zhukov eff51d41b3 Add missed getRealName() call for $namespaces_by_alias group 2018-10-01 03:25:34 +03:00
Pavlo Zhukov b14d983f74 Change comments style to allow folding and make its clear 2018-10-01 00:50:28 +03:00
Pavlo Zhukov 1fdc866fb0 Fix missed autocomplete in helper view 2018-10-01 00:39:40 +03:00
Pavlo Zhukov d7359b86d4 Avoid code duplication in constructors 2018-10-01 00:20:54 +03:00
Pavlo Zhukov 5d8d93273f Fix missed helpers for abstract methods the same name but different classes 2018-10-01 00:02:03 +03:00
Manabu Matsui 30e5300e49 Fix alias class existence determination 2018-09-14 10:16:13 +09:00
Barry vd. Heuvel 593e0d4aa7 Merge pull request #701 from brendt/master
Add ::query support
2018-09-07 12:07:33 +02:00
Brent Roose e7d4cb322f Update ModelsCommand.php 2018-09-07 10:29:59 +02:00
Brent Roose 5318f485e2 Add ::query support 2018-09-07 10:27:20 +02:00
Barry vd. Heuvel 7db1843473 Remove Eloquent mixin thing 2018-09-06 20:41:09 +02:00
Barry vd. Heuvel 1989d0e794 Update .travis.yml 2018-09-04 16:19:48 +02:00
Barry vd. Heuvel 09db8c9a76 Update composer.json 2018-08-31 15:28:09 +02:00
Barry vd. Heuvel 4aa43fa613 Merge pull request #690 from kevinpijning/laravel-5.7-support
Laravel 5.7 support
2018-08-21 11:29:23 +02:00
kevin d55b48476e Laravel 5.7 support
Added Laravel 5.7 support
2018-08-15 09:57:53 +02:00
Barry vd. Heuvel 45e84b9070 Merge pull request #678 from BinotaLIU/add-fluent-change
add change modifier
2018-07-16 09:12:17 +02:00
BinotaLIU f472c26601 add change modifier 2018-07-05 19:31:23 +08:00
Barry vd. Heuvel 1deadced46 Merge pull request #675 from glamorous/bugfix/phpstan-error-formatter
bugfix - Space/Enter between starting php tag and comment for PHPStan
2018-06-21 14:14:18 +02:00
Jonas De Smet e1d1352ac5 bugfix - Space/Enter between starting php tag and comment for PHPStan 2018-06-19 14:59:59 +02:00
Barry vd. Heuvel 65e3278c86 Merge pull request #668 from falnyr/final-abstract-class
Added support for abstract/final models.
2018-06-13 10:16:26 +02:00
Barry vd. Heuvel efd7e51566 Merge pull request #671 from eidng8/patch-2
suppress formatter in meta file
2018-06-13 10:16:01 +02:00
Barry vd. Heuvel 2a5dda6a27 Merge pull request #672 from eidng8/patch-3
suppress formatter in helper file
2018-06-13 10:15:47 +02:00
Jackey Cheung 6577af8464 suppress formatter in helper file 2018-06-13 10:24:58 +08:00
Jackey Cheung 6c7bc371f9 suppress formatter in meta file 2018-06-13 10:21:51 +08:00
Jan Alfred Richter 217b8989c2 Added support for abstract/final models. 2018-05-31 15:39:22 +12:00
Barry vd. Heuvel c003eb40d7 Merge pull request #667 from BinotaLIU/master
nullable is actually support an argument
2018-05-29 17:29:40 +02:00
BinotaLIU 1a3d32f0d1 nullable actually support an argument 2018-05-29 22:28:49 +08:00
Barry vd. Heuvel bd733b7b7c Merge pull request #665 from JeppeKnockaert/fix-model-comments
Only skip non-models when generating docs
2018-05-24 14:10:51 +02:00
Jeppe Knockaert 93630fdf62 Only skip non-models when generating docs
The fix made in PR https://github.com/barryvdh/laravel-ide-helper/pull/614 for issue https://github.com/barryvdh/laravel-ide-helper/issues/253 was incorrect as it resulted in comments
no longer being generated for Models that are not Pivot Rlations.

This PR allow comments to be generated for both Pivot Models (as they are
a subclass of Eloquent\Model) and normal Models.
2018-05-24 11:43:03 +02:00
Barry vd. Heuvel f64ed52205 Merge pull request #664 from huydang284/master
ide-helper:models error when model's method has parameters and also has relation
2018-05-24 10:32:51 +02:00
Huy Dang ba28841870 fix case relation method has parameter 2018-05-22 13:26:27 +07:00
Barry vd. Heuvel b02a0bc6c9 Update phpunit.xml.dist 2018-05-07 13:03:54 +02:00
Barry vd. Heuvel a665961fb9 Update .travis.yml 2018-05-07 12:56:29 +02:00
Barry vd. Heuvel 83852e9de0 Update .travis.yml 2018-05-07 12:41:54 +02:00
Barry vd. Heuvel d2f29d997b Update .travis.yml 2018-05-07 11:56:03 +02:00
Barry vd. Heuvel cbacb28f19 Update .travis.yml 2018-05-07 11:55:44 +02:00
Barry vd. Heuvel 930e5bd301 Update composer.json 2018-05-07 11:49:06 +02:00
Barry vd. Heuvel 930d258cd4 Update composer.json 2018-05-07 11:48:47 +02:00
Barry vd. Heuvel 94248adae8 Merge pull request #600 from mike-grinspan/patch-1
Use Illuminate\Support\Carbon instead of Carbon\Carbon
2018-05-07 11:44:40 +02:00
Barry vd. Heuvel 50ecd8b815 Update CS, typo 2018-05-07 11:38:57 +02:00
Barry vd. Heuvel 1b70277203 Typo 2018-05-07 11:25:19 +02:00
Barry vd. Heuvel 87a03fd9c4 Merge pull request #576 from yuklia/docs-enhancment
Add notice about "Package Auto-Discovery" to docs
2018-05-07 11:23:21 +02:00
Barry vd. Heuvel b8a73bcab9 Merge pull request #581 from soltmar/master
Changed overwriting confirmation message
2018-05-07 11:23:06 +02:00
Barry vd. Heuvel 0556991c69 Merge pull request #583 from inxilpro/support-fakes
Support for ::fake() calls
2018-05-07 11:22:33 +02:00
Barry vd. Heuvel be78ac62cd Merge pull request #589 from mfn/patch-1
Keep "null"-ness of column even with model casts
2018-05-07 11:21:47 +02:00
Barry vd. Heuvel 265f00c322 Update LICENSE.md 2018-05-07 11:20:53 +02:00
Barry vd. Heuvel bbd96d3616 Merge pull request #609 from lx1036/patch
Sort keys for generating stable .phpstorm.meta.php
2018-05-07 11:17:33 +02:00
Barry vd. Heuvel 8d913089db Merge pull request #614 from WickedSik/master
Allow command to find and use pivot models
2018-05-07 11:17:07 +02:00
Barry vd. Heuvel 9a2588cb3a Merge pull request #612 from westphalen/master
Added Validator and Gate facades for Lumen
2018-05-07 11:16:47 +02:00
Barry vd. Heuvel e7fa36bdc3 Merge pull request #629 from bedezign/smart-reset
"smart-reset": Reset properties/methods, but keep the text
2018-05-07 11:15:59 +02:00
Barry vd. Heuvel b1e868c5fc Merge pull request #621 from Zae/feature/fix-callable-macros
Support php's array callable format for macro's.
2018-05-07 11:15:49 +02:00
Barry vd. Heuvel 203d60dc8c Merge branch 'master' into feature/fix-callable-macros 2018-05-07 11:15:43 +02:00
Barry vd. Heuvel f5275b700a Merge pull request #632 from JeppeKnockaert/feature/add-morphedByMany-relation
Add morphedByMany relationship
2018-05-07 11:13:27 +02:00
Barry vd. Heuvel 046a9bcc77 Merge pull request #647 from eidng8/eidng8-suppress-formatter
suppress PHPStorm formatter
2018-05-07 11:10:25 +02:00
Barry vd. Heuvel c6191830ab Merge pull request #660 from TomzxForks/fixes/659-use-composer-classmapgenerator
Replace Symfony ClassMapGenerator with Composer ClassMapGenerator
2018-05-07 11:09:58 +02:00
Barry vd. Heuvel cfff7721bc Merge pull request #661 from tzurbaev/patch-1
Remove `mixed` typehint from `Fluent::default` method
2018-05-07 11:09:27 +02:00
Timur Zurbaev 4691bc5fbd Remove mixed typehint from Fluent::default method 2018-05-05 10:09:30 +08:00
Tom Rochette b1b05b694b Remove dependecy to Symfony\Component\ClassLoader\ClassMapGenerator and replace it with Composer\Autoload\ClassMapGenerator. 2018-05-03 16:02:16 -04:00
Barry vd. Heuvel 98d6087a1e Merge pull request #568 from fisharebest/artisan-optimize
The 'artisan optimize' command is now deprecated.
2018-03-26 12:18:59 +02:00
Jackey Cheung c7b7ebf1b5 suppress PHPStorm formatter 2018-03-21 11:36:02 +08:00
Jeppe Knockaert 17982029f0 Move long one-line array to multiple lines 2018-02-14 12:15:38 +01:00
Jeppe Knockaert bda5120e9a Add morphedByMany relationship 2018-02-14 12:06:45 +01:00
Steve Guns d961482d22 Fixed PHPCS PSR2 issues 2018-02-14 08:59:19 +01:00
Steve Guns 8852b1ca9d Added "smart-reset": Reset properties/methods, but keep the docBlock text, if any 2018-02-11 19:09:33 +01:00
Barry vd. Heuvel b644e48801 Merge pull request #618 from glamorous/feature/docblocks-on-classes
Add DocBlocks for classes too
2018-02-10 14:47:48 +01:00
Barry vd. Heuvel 09610da602 Merge pull request #626 from barryvdh/revert-624-Fix/623
Revert "Fixes a bug where a missing DocBlock caused errors"
2018-02-08 17:01:01 +01:00
Barry vd. Heuvel 2d56afce8e Revert "Fixes a bug where a missing DocBlock caused errors" 2018-02-08 17:00:48 +01:00
Barry vd. Heuvel 5c304db44f Merge pull request #624 from iPaat/Fix/623
Fixes a bug where a missing DocBlock caused errors
2018-02-08 08:56:07 +01:00
Patrick 1fc4284af6 Fixes for Travis. 2018-02-07 13:24:36 +01:00
Patrick ea113e8c0b Fixes a bug where a missing DocBlock caused errors 2018-02-07 13:17:03 +01:00
Barry vd. Heuvel 387efb9b42 Allow L5.6 2018-02-07 09:31:35 +01:00
Ezra Pool 8ab907f219 Support php's array callable format for macro's.
This allows you to define methods like this as well: Str::macro('name', [$this, 'method']);
2018-02-03 21:10:48 +01:00
Jonas De Smet e29e035135 Add DocBlocks for classes too 2018-02-01 15:53:32 +01:00
Jurrien Dokter 7b2786ac2b Fixing issue #253 2018-01-27 13:01:07 +01:00
Sune Westphalen 76bd86dbaf Added Validator and Gate facades for Lumen. 2018-01-23 13:56:22 +07:00
Xiang Liu 7b067198a6 Sort keys for generating stable .phpstorm.meta.php 2018-01-15 12:44:44 +08:00
Mike b6f525b320 Use Illuminate\Support\Carbon instead of Carbon\Carbon in config/ide-helper.php 2017-12-27 17:26:16 -05:00
Mike d65f1cedcd Use Illuminate\Support\Carbon instead of Carbon\Carbon in readme.md 2017-12-27 17:25:44 -05:00
Mike df6b1b6f82 Use Illuminate\Support\Carbon instead of Carbon\Carbon 2017-12-27 17:17:00 -05:00
Markus Fischer 76a1952c41 Keep "null"-ness of column even with model casts
A cast in Laravel should only affect the type, but not the database intrinsics whether a column accepts `null` or not.

As an example, consider this table (Postgres syntax):
```sql
CREATE TABLE foo (
  some_column jsonb
);
```
This will be generated as: `@property string|null $some_column`

When providing a the following casts on the model:
```php
protected $casts = [
  'some_column' => 'array',
];
```
then the generated property changes to: `@property array $some_column`

However the DB still accepts `null`, but this can't be expressed via the casts.

This change will make the null "sticky" and generate: `@property array|null $some_column`
2017-10-28 18:01:18 +02:00
Chris Morrell d45b02efb1 Support for ::fake() calls 2017-10-13 11:41:30 -04:00
Mariusz b0abafb8c7 Changed overwriting confirmation message
When running php artisan ide-helper:models below message was presented:
"Do you want to overwrite the existing model files? Choose no to write to _ide_helper_models.php instead? (Yes/No):  (yes/no) [no]:"
This commit changes message to:
"Do you want to overwrite the existing model files? Choose no to write to _ide_helper_models.php instead? (yes/no) [no]:"
2017-10-11 11:43:16 +01:00
Yulia Kostrikova 6b0e9ec48d Add notice about "Package Auto-Discovery" to docs 2017-09-21 00:40:49 +03:00
M. Vugteveen 28f0ac3781 also show time in generated files (#574) 2017-09-13 14:18:03 +02:00
Greg Roach 721a7cd3f7 The 'artisan optimize' command is deprecated 2017-09-02 21:25:00 +01:00
Carl Evison ea6d6d0105 update to the latest code intel (#567) 2017-09-02 17:44:59 +02:00
Subodh Dahal 01320a48e3 Bugfix: Undefined property: Barryvdh\LaravelIdeHelper\Console\MetaCommand::$config (#562) 2017-08-28 15:16:15 +02:00
Charles Peterson fedcb57295 Add an eloquent command (#544)
* Add an eloquent command for adding the `@mixin \Eloquent` to the Illuminate\Database\Eloquent\Model

* spacing updates...

* multi-line function call syntax

* Write helper mixin to Eloquent/Model after helper created

* Cleanup into helper - similar to Generator

* syntax cleanup
2017-08-28 15:12:54 +02:00
Barry vd. Heuvel ce72ff4663 Remove exit for static code analysers 2017-08-28 13:39:24 +02:00
Zakaria Acharki cb6f52f4d6 Minor typo fix (#548) 2017-08-28 13:38:22 +02:00
Chris Morrell 55c9bfc33b Allow for configurable meta filename (#553) 2017-08-28 13:37:22 +02:00
Chris Morrell a9ea231679 Support higher order tap() (#554) 2017-08-28 13:35:56 +02:00
Jan.Weskamp 2b1273c45e Fix for Laravel 5.5 (#540)
Command fire method is now handle
2017-07-16 02:24:12 +02:00
Stidges 08d39c125f Add back leading slash on meta class names (#532) 2017-07-06 21:25:44 +02:00
dannehl 87a02ff574 added L55-support (#525) 2017-06-16 16:08:59 +02:00
Michael Tsang 9e42ce11f4 return eloquent builder instead of plain database builder from model methods (#522) 2017-06-15 17:22:20 +02:00
Stidges dca7fa7b10 Use new PhpStorm advanced metadata format (#523) 2017-06-14 20:49:19 +02:00
Abdelrahman Omran 0e4b9b77c3 Support Auto-Discovery (#524) 2017-06-14 19:56:10 +02:00
leo 46901d2c80 set include_fluent default to true (#512) 2017-06-08 12:19:59 +02:00
Max Matiukhin 25b5576f57 generate methods for the SoftDeletes trait (#518) 2017-06-08 12:19:38 +02:00
Michael Tsang d6d99994c3 return eloquent builder instead of plain database builder from model methods (#521) 2017-06-08 12:19:27 +02:00
Barry vd. Heuvel 7e78d02d0a Update .travis.yml 2017-06-06 16:29:23 +02:00
Victor Isadov 35d954fc39 Note for \Eloquent (#515)
https://github.com/barryvdh/laravel-ide-helper/issues/514
2017-06-06 16:18:54 +02:00
Jez McKean 5eeda63958 replaced curly quotes and other minor tweaks (#510) 2017-05-29 19:44:30 +02:00
Matthew Erwin b76156b24c Adds support for macros (#500)
* Adds support for macros

* Fixes formatting
2017-05-05 11:22:12 +02:00
Emir Beganović 2a63d51496 Add PHP 7.1 to build script (#492) 2017-04-14 17:57:13 +02:00
Neil Farrington 3814fe86ca Resolve displaying @return types with descriptions (#491) 2017-04-14 08:56:19 +02:00
JC Lee 3ab73555d9 Add support for pgsql for boolean types. (#489) 2017-04-11 07:31:58 +02:00
Antoine Aflalo ff3844e4e1 Implements Nullable (#487)
* Add nullable support

Fixes #407

* Add nullable to setProperty

Better do it like this to still be able to override the base type if wanted

* Cleanup nullableColumns between models iterations

Also rename it to nullableColumns since it contains multiple columns

* Fix formatting
2017-04-08 10:19:23 +02:00
JC Lee d11bf58084 Fix #480 where tinyint is casts as bool (#481)
* Fix #480 where tinyint is casts as bool

`tinyint` is classified by bool as doctrine/dbal, but it should not be so in our use case. `tinyint` is better PHPDoc'ed as int. If the user wants bool, he should use Eloquent's `$casts` property to do that.

* Pass PSR-2 check

* Remove comment as requested
2017-04-05 09:45:19 +02:00
theMadness 75e1f22ec6 Decoupled from main app View Factory (#475) 2017-03-31 11:14:28 +02:00
Ivan Boldyrev 144a50e8ee Add disable write magic methods on models (#466)
* Add desable write magic methods on models

* Fix property name

* Opps commit

* Fix

* Change default parameter of property
2017-03-16 11:46:50 +01:00
Florian Lefèvre b611cb5eff Add namespaced aliases (#456)
* Add namespaced aliases

* Move aliases regouping logic in Generator

* Fix getValidAliases return type
2017-03-05 20:04:42 +01:00
Barry vd. Heuvel e82de98cef Add Eloquent methods back 2017-02-22 13:27:33 +01:00
arasharg 456853be46 ignore intermediate table models (#454) 2017-02-22 08:59:06 +01:00
Barry vd. Heuvel 25c8de637d Skip eloquent
Fixes #https://github.com/barryvdh/laravel-ide-helper/issues/451
2017-02-20 13:54:53 +01:00
Emmanuel Maggion 5a841a209d Fix case (#452) 2017-02-20 11:52:55 +01:00
Barry vd. Heuvel 56660cab84 Update composer.json 2017-02-14 16:45:07 +01:00
Zimin Cao 555d3e3700 Add documentation in readme.md for Laravel Fluent methods support (#446)
* Added readme for Fluent methods

* Add readme for Laravel Fluent methods
2017-02-13 20:20:12 +01:00
Tommi Finnilae 963ead0a01 Correct Fluent helper output (#445)
'references()' and 'on()' argument names were backwards
2017-02-13 12:53:06 +01:00
Florian Lefèvre 8c306035aa Fix facades fullpath autocomplete (#441)
* Add method to retrieve namespace of extended class

* Regroup classes by namespace of the class they extends

* Restore facades shortnames

* Fix classnames used for methods declaration
2017-02-13 12:52:36 +01:00
Barry vd. Heuvel f1e93f042d Update helper.php 2017-02-03 15:05:31 +01:00
Charles Peterson 5280b47750 readme spelling (#436)
just a couple spelling fixes for the readme file.
2017-02-01 09:59:19 +01:00
Florian Lefèvre 525733122e Add facades fullpath autocomplete (#437)
* Add method to retrieve namespace of extended class

* Regroup classes by namespace of the class they extends

* Restore facades shortnames
2017-02-01 07:21:31 +01:00
Django Eijgensteijn a7fc2ec489 Sorting model docs (#424) 2017-01-05 22:20:42 +01:00
Barry vd. Heuvel 8caca941b3 Update IdeHelperServiceProvider.php 2017-01-05 10:02:31 +01:00
Barry vd. Heuvel e96943fe6f Use singleton instead of share 2017-01-05 09:58:45 +01:00
Barry vd. Heuvel df3ecb2843 Update composer.json 2016-12-09 12:13:18 +01:00
Jackey Cheung 105f14a50d Add Fluent helpers (using config option) (#404)
* add fluent option to Generator

* add fluent to helper output

* add fluent option to config

* typo
2016-11-15 09:21:23 +01:00
Barry vd. Heuvel 5fad258f5d Merge pull request #397 from ockle/scope-typehints
Scope parameter typehints
2016-10-13 09:23:59 +02:00
ockle 13e65d3885 if model scope method parameters have typehints, add them to the docblock 2016-10-12 21:53:42 +01:00
Barry vd. Heuvel 22612733a2 Merge pull request #389 from pinepain/return_type
Use accessor docblock return type to guess property type
2016-09-08 08:54:27 +02:00
Barry vd. Heuvel dc476f9736 Merge pull request #388 from KarimGeiger/master
Fix "Using $this when not in object context" bug
2016-09-07 15:05:31 +02:00
Bogdan Padalko 71cb03ca6a Use accessor docblock return type to guess property type 2016-09-06 12:24:42 +03:00
Karim Geiger abe2df5853 Fix "Using $this when not in object context" bug
This commit fixes the "Using $this when not in object context" bug for the Lumen configuration. Since the `bootstrap/app.php`-file is not in object context, and the `app` instance accessible using the `$app` variable directly, using `$this->app` will result in a fatal error.
2016-09-05 23:24:04 +02:00
Barry vd. Heuvel 2de6ab6038 Merge pull request #387 from DarkGhostHunter/master
Update readme.md
2016-09-03 00:21:49 +02:00
Italo c229335651 Update readme.md
Typos and H2
2016-09-02 19:14:12 -03:00
Italo 495361e501 Update readme.md 2016-09-02 13:44:58 -03:00
Barry vd. Heuvel 7583353915 Merge pull request #386 from dimsav/patch-1
Minor style fix in readme
2016-09-02 16:16:38 +02:00
Dimitris Savvopoulos 16c570c589 Minor style fix in readme 2016-09-02 12:50:36 +03:00
Barry vd. Heuvel 884eaeeb1a Check if getCasts() exists
Fixes #382
2016-08-26 13:37:21 +02:00
Barry vd. Heuvel b6706683b2 Merge pull request #380 from ellisio/patch-1
hotfix for type overrides
2016-08-26 13:27:42 +02:00
Andrew Ellis 6f9b90c204 hotfix for type overrides
Oops, looks like I forgot to commit one call to the new method. This is related to #377.
2016-08-25 18:53:51 -06:00
Barry vd. Heuvel e1a0f034a1 Merge pull request #377 from ellisio/type-overrides
Allow Type Overrides
2016-08-24 22:41:37 +02:00
Andrew Ellis b75f879383 uncommented defaults 2016-08-24 14:23:02 -06:00
Andrew Ellis ad800d197f and one more blank line fix for travis-ci 2016-08-19 12:39:16 -06:00
Andrew Ellis f3a3533b2d fixed blank line errors for travis-ci build 2016-08-19 12:37:17 -06:00
Andrew Ellis e938cd3a31 added missing comma 2016-08-19 12:25:22 -06:00
Andrew Ellis f8c6ec95f6 allow a user to define the type overrides 2016-08-19 12:20:34 -06:00
Barry vd. Heuvel 0a4ff969d2 Merge pull request #375 from leo108/master
add support for $casts
2016-08-19 09:26:14 +02:00
leo108 4b47c0b61c add support for $casts 2016-08-19 07:35:07 +08:00
Barry vd. Heuvel 7598293bc6 Merge pull request #372 from chrisforrence/readme-updates
README updates
2016-08-14 18:38:30 +02:00
Chris Forrence 035b14176b Add instructions on installing for development 2016-08-12 17:39:45 -04:00
Chris Forrence cb08c6ff81 Grammar-related changes 2016-08-12 17:28:25 -04:00
Barry vd. Heuvel 28af7cd19c Update composer.json 2016-07-04 13:52:48 +02:00
Barry vd. Heuvel 8f004f5d6b Merge pull request #326 from valorin/master
Allow for camel case model properties.
2016-07-04 13:45:34 +02:00
Barry vd. Heuvel da677f1ba5 Merge pull request #357 from tnorthcutt/patch-1
An --> A
2016-07-04 13:44:48 +02:00
Barry vd. Heuvel 321844d9a5 Merge pull request #361 from cnanney/patch-1
Use FQN for app() methods
2016-06-29 21:27:36 +02:00
Chris Nanney 928389d7a4 Use FQN for app() methods 2016-06-29 10:21:17 -05:00
Travis Northcutt dbfcfd66c5 An --> A 2016-06-14 07:23:16 -06:00
Barry vd. Heuvel a9484c67d1 Merge branch 'master' of github.com:barryvdh/laravel-ide-helper 2016-06-13 21:36:24 +02:00
Barry vd. Heuvel 3064296216 Use fork of reflection docblock 2016-06-13 21:35:48 +02:00
Barry vd. Heuvel f057a4f820 Merge pull request #351 from ferdiunal/patch-1
Laravel 5.2.* composer.json file
2016-06-08 22:28:01 +02:00
Barry vd. Heuvel 091f78508c Add cache 2016-06-08 22:23:10 +02:00
Barry vd. Heuvel cf4fcd810c Prefest dist installs 2016-06-08 22:20:46 +02:00
Barry vd. Heuvel d3203de671 Remove other badges 2016-06-08 22:12:12 +02:00
Barry vd. Heuvel 093171e01f Update badges/licence 2016-06-08 22:11:14 +02:00
Barry vd. Heuvel 2d82419167 Test method output 2016-06-08 22:06:05 +02:00
Barry vd. Heuvel 0e84805e37 Update gitignore 2016-06-08 21:39:39 +02:00
Barry vd. Heuvel 7a07515149 Remove build dir 2016-06-08 21:39:24 +02:00
Barry vd. Heuvel bae462604e Add test config, CS rules and fix CS 2016-06-08 21:36:25 +02:00
Ferdi ÜNAL b28c8cbae1 Laravel 5.2.* composer.json file 2016-05-26 14:43:33 +03:00
Barry vd. Heuvel d734ecabcc Merge pull request #350 from Kurre/hasManyThrough-relationship
Add hasManyThrough relationship
2016-05-25 11:51:22 +02:00
Tommi Finnilä 4f227d5c57 Add hasManyThrough relationship 2016-05-25 09:28:34 +01:00
Barry vd. Heuvel 35ebf3a2ba Merge pull request #338 from cnanney/patch-1
Look for additional facade aliases in app config array
2016-05-12 07:32:54 +02:00
Barry vd. Heuvel f7b31bdbdc Merge pull request #345 from alexbowers/patch-1
Support Laravel 5.3.x (beta)
2016-05-01 09:29:05 +02:00
Alex Bowers 8de1673535 Update composer.json 2016-05-01 00:08:49 +01:00
Chris Nanney d818b72f82 Look for additional facade aliases in app config array
In my Lumen app, I load my providers and aliases from a `config/app.php` file like in Laravel. Maybe that is uncommon, but this simple PR will include those aliases as well if any are present.
2016-03-29 14:56:12 -05:00
Barry vd. Heuvel e97ed532f0 Merge pull request #327 from vedmant/master
Added support for default storage driver shortcuts, eg. Storage::exists('file.jpg');
2016-03-03 15:38:04 +01:00
Vedmant 606183ea12 Added support for default storage driver shortcuts, eg. Storage::exists('file.jpg'); 2016-03-03 16:33:28 +02:00
Stephen Rees-Carter a72cd81e5f Allow for camel case model properties. 2016-03-03 21:36:10 +11:00
Barry vd. Heuvel f1ebd847aa Check on actual model, not facade
Fixes #311
2016-03-03 09:45:00 +01:00
Barry vd. Heuvel 83597196f9 Prevent double mixin tags 2016-03-03 09:43:49 +01:00
Barry vd. Heuvel 19553f63e4 Update composer.json 2016-03-02 11:03:09 +01:00
Barry vd. Heuvel f50470ba49 Add morphOne, fix morphTo
Fixes #236 thanks to @boxfrommars
2016-03-02 10:54:41 +01:00
Barry vd. Heuvel 7762e07f0a Use new provider config
Fixes #274, #324
2016-03-02 10:47:25 +01:00
Barry vd. Heuvel 467b5f5b5f Always add whereColumn
Fixes #300, #325
2016-03-02 10:42:37 +01:00
Barry vd. Heuvel c213be3d3c Merge pull request #305 from matiaspub/patch-1
Add extend \Eloquent for ide-helper:models command
2016-03-02 10:39:21 +01:00
Barry vd. Heuvel 4b8ba85b34 Merge pull request #315 from icedfish/ignore_exception
Ignore abstract class or interface, not throw exception
2016-01-28 09:19:58 +01:00
Barry vd. Heuvel d4c0ae5851 Merge pull request #314 from icedfish/recover-helper-function
recover model's whereXXX() helper function
2016-01-28 07:21:05 +01:00
Yu Bing 3a01e351de Ignore abstract class or interface, not throw exception 2016-01-28 11:37:08 +08:00
Yu Bing add34665a8 fix typo 2016-01-28 11:20:48 +08:00
Yu Bing c77752bb58 recover model's whereXXX() helper function 2016-01-28 11:18:42 +08:00
Barry vd. Heuvel aa8f772a46 Merge pull request #310 from naerymdan/master
Add support for Lumen 5.0, 5.1 and 5.2+
2016-01-22 14:33:15 +01:00
Vincent Labreche 0c4c55f349 Add support for Lumen 5.0, 5.1 and 5.2+ 2016-01-22 08:30:36 -05:00
Barry vd. Heuvel ed972acf19 Merge pull request #308 from barryvdh/revert-303-master
Revert "Don't use force aliases loading"
2016-01-21 15:55:37 +01:00
Barry vd. Heuvel 60e642e881 Revert "Don't use force aliases loading" 2016-01-21 15:55:29 +01:00
Sergius 4069863d0c Add extend \Eloquent for ide-helper:models command
It's help author to close many issues! )
Like: #269, #259, #248, #209, #191, #74, 
and https://github.com/laravel/framework/issues/7558 )))
etc. maybe
2016-01-12 15:33:05 +02:00
Barry vd. Heuvel da05897cb7 Merge pull request #303 from dkulyk/master
Don't use force aliases loading
2016-01-11 13:00:09 +01:00
Dmytro Kulyk 74bac1a4e9 Don't use force aliases loading
Another autoloader throw exception if aliases not exists.
2016-01-11 13:45:41 +02:00
Barry vd. Heuvel 33cee80609 Merge pull request #302 from Propaganistas/patch-1
Fix Auth driver detection in Laravel 5.2
2016-01-08 18:03:38 +01:00
Propaganistas dee3878566 Fix Auth driver detection in Laravel 5.2 2016-01-06 20:31:08 +01:00
Barry vd. Heuvel eb5736a7bd Merge pull request #298 from onigoetz/patch-1
Allow symfony/class-loader 3.0 to be installed
2016-01-03 11:48:37 +01:00
Stéphane Goetz cc794a2fba Allow symfony/class-loader 3.0 to be installed 2016-01-03 11:25:12 +01:00
Barry vd. Heuvel d82e8f191f Fix meta for 5.2 seeder
Fixes #287
2015-12-21 20:48:06 +01:00
Barry vd. Heuvel 5497e7d506 Merge pull request #294 from bytestream/master
Fixes #293
2015-12-14 14:33:18 +01:00
Kieran 2f83db311f Fixes #293 2015-12-14 13:29:24 +00:00
Barry vd. Heuvel d56bbb2356 Merge pull request #290 from nikolay-zakharov/dev-resource-fails
Fixed: fails to generate with resources
2015-12-11 15:38:48 +01:00
Nikolay Zakharov 2fb1135fc5 Fixed: fails to generate with resources 2015-12-11 17:18:14 +03:00
Barry vd. Heuvel aec17e3327 Update composer.json 2015-12-11 09:26:59 +01:00
Barry vd. Heuvel 0c560cb375 Merge pull request #288 from miraage/fix/models-command
fix(models-command): check for default reflectionparameter value
2015-12-07 08:55:26 +01:00
miraage 5708012a77 fix(models-command): check for default reflectionparameter value to prevent fail in variadic params 2015-12-06 13:49:27 +03:00
Barry vd. Heuvel af6d9a7fa1 Merge pull request #275 from Houbsi/master
Automatic phpDocs for models: added copy/past
2015-10-22 14:34:24 +02:00
Mike Houben f708b9a46c Automatic phpDocs for models: added copy/past
With this information it's much easier to install.
2015-10-22 14:31:54 +02:00
Barry vd. Heuvel e3de462538 Resolve user model at runtime
Fixes #274
2015-10-22 14:26:11 +02:00
Barry vd. Heuvel 76f09aaa65 Remove magic where 2015-10-19 09:32:38 +02:00
Barry vd. Heuvel 56f89502e3 Tweak relation object
Tweaks #273
2015-10-19 09:31:08 +02:00
Barry vd. Heuvel 11037acfe6 Merge pull request #273 from klaude/custom-collection-support
Add custom collection support
2015-10-19 09:30:05 +02:00
Kevin Laude e48974e545 Add custom collection support
Add support for models that override Eloquent's newCollection() with a
custom collection type. Do this by executing the relationship on the
model then executing that relationship's newCollection() method to see
what type of colletion class is returned.

Remove the now-unused
Barryvdh\LaravelIdeHelper\Console\ModelsCommand::getClassName() method.
2015-10-18 20:54:25 -05:00
Barry vd. Heuvel 38a97cf07c Swap facade/alias
See #202
2015-08-18 10:57:06 +02:00
Barry vd. Heuvel 74ee804dde Update readme 2015-08-14 09:50:36 +02:00
Barry vd. Heuvel 83999f8467 Bump version 2015-08-13 13:40:00 +02:00
Barry vd. Heuvel fab54d90dd Merge pull request #252 from mahmutbayri/master
Trim tag text.…
2015-08-13 13:12:39 +02:00
Mahmut Bayri 5d4056fe87 Trim tag text. If tag doesn't have comment or the comment has any space at the end of line, phpcs (with --standard=PSR2) dedects an error. 2015-08-13 13:42:10 +03:00
Barry vd. Heuvel 3fbe330998 Update readme.md 2015-08-10 21:05:06 +02:00
Barry vd. Heuvel 78d233fea7 Skip validator 2015-08-10 21:01:41 +02:00
Barry vd. Heuvel 0d13a51ff5 Use preset list of aliases in Lumen 2015-08-10 21:00:31 +02:00
Barry vd. Heuvel 326e8ea25f Bring back changes
Missed them from previous commit
2015-08-10 20:38:57 +02:00
Barry vd. Heuvel e7ee934bb1 Inject filesystem 2015-08-10 20:36:00 +02:00
Barry vd. Heuvel 99953adb73 Inject filesystem instance 2015-08-10 20:35:04 +02:00
Barry vd. Heuvel 0d333c6228 Check for config_path (Lumen)
For #202
2015-08-10 20:23:56 +02:00
Barry vd. Heuvel 0a717d1e79 Merge pull request #243 from bebnev/master
fix get_class($this) in relationship functions
2015-08-09 15:04:14 +02:00
bebnev dc62d35bed fix parsing relations arguments 2015-08-09 15:28:04 +03:00
Barry vd. Heuvel 2b7733c6b9 Merge pull request #242 from bebnev/master
fix model docBlocks duplicates
2015-08-01 16:59:45 +02:00
bebnev 76674be735 fix model docBlocks duplicates
Add each parsed model to ignore list, so if it exists more than once it will not be parsed twice.
2015-08-01 17:13:43 +04:00
Barry vd. Heuvel e34b7fb84b Merge pull request #232 from konomae/patch-1
Fix vendor:publish provider name
2015-07-14 11:09:59 +02:00
konomae e77a7b5a9c Fix vendor:publish provider name 2015-07-14 17:54:07 +09:00
Barry vd. Heuvel 19f7d75c10 Update readme.md 2015-06-25 13:32:53 +02:00
Barry vd. Heuvel 0373861536 Add generic factory 2015-06-25 10:58:59 +02:00
Barry vd. Heuvel 3a4671f3ea Update meta file 2015-06-18 14:58:06 +02:00
Barry vd. Heuvel 8515b7ac0b Use verbosity to hide some errors 2015-06-18 09:11:05 +02:00
Barry vd. Heuvel 541b9508e2 Update compiled locations 2015-06-11 16:11:52 +02:00
Barry vd. Heuvel afe1fe88ba Merge pull request #222 from akshayagarwal/patch-1
Update provider include syntax for Laravel 5.1.1 LTS
2015-06-11 08:41:55 +02:00
Akshay Agarwal a59a5e1ae1 Update provider include syntax for Laravel 5.1.1 LTS 2015-06-10 21:04:26 +05:30
Barry vd. Heuvel bb3bba2c5b Catch non-existant class fatal exceptions
Add autoloader that throws an error, so we can catch errors instead of fatal crashes.
Fixes #220
2015-06-08 09:04:31 +02:00
Barry vd. Heuvel 5aa0f55d2f Update composer.json 2015-06-07 15:09:00 +02:00
Barry vd. Heuvel 89b585b242 Merge pull request #212 from modder2/modder2-patch-1
Bug fix with model relations
2015-05-15 12:26:15 +02:00
Alexander f5b1248a37 Bug fix with model relations
If relation has other methods, generating doc is fail.
E.g.
$this->belongsToMany('App\User')->withTimestamps();
generate this:
@property-read \Illuminate\Database\Eloquent\Collection|\App\User')->withTimestamps([] $drinks
2015-05-14 14:44:54 +03:00
Barry vd. Heuvel 8b190ac295 Merge pull request #211 from MrCue/master
Update ModelsCommand.php
2015-05-14 13:40:20 +02:00
MrCue a861bcaf1b Update ModelsCommand.php
Work with tables in different databases
2015-05-13 16:46:47 +01:00
Barry vd. Heuvel bb3bd2645d Merge pull request #190 from MalikinSergey/patch-1
Add Query\Builder return type to magic scope* methods
2015-05-06 12:08:42 +02:00
Barry vd. Heuvel 687a8c9b47 Merge pull request #178 from fhteam/master_custom_types_support
Custom database types support for L5 branch
2015-05-06 12:02:57 +02:00
Barry vd. Heuvel b1dedc3ee6 5.1 support 2015-05-03 16:00:11 +02:00
Barry vd. Heuvel dac46a081d Merge pull request #201 from elliotwms/patch-1
Indefinite article
2015-04-22 17:46:01 +02:00
Elliot Williams 0c38360317 Indefinite article
I'm pretty sure it should be `a helper file` as opposed to `an helper file`
2015-04-22 16:42:49 +01:00
Malikin Sergey 1d3a98f0e5 Add Query\Builder return type to magic scope* methods 2015-03-29 13:30:50 +03:00
Barry vd. Heuvel d9f79eb128 Merge pull request #188 from grrnikos/master
update readme.md
2015-03-25 21:00:56 +01:00
Nikos Gr 7ef2d2f398 update readme.md 2015-03-25 21:56:47 +02:00
Barry vd. Heuvel 5afcbdc7c8 Supress FQN warning 2015-03-17 10:13:32 +01:00
Vladislav Rastrusny 8378f1bd67 Adding custom DB types support for models 2015-03-03 13:02:47 +03:00
66 changed files with 5428 additions and 1124 deletions
+15
View File
@@ -0,0 +1,15 @@
; This file is for unifying the coding style for different editors and IDEs.
; More information at http://editorconfig.org
root = true
[*]
charset = utf-8
indent_size = 4
indent_style = space
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
+9
View File
@@ -0,0 +1,9 @@
# Path-based git attributes
# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
# Ignore all test and documentation with "export-ignore".
/.gitattributes export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/phpunit.xml.dist export-ignore
/tests export-ignore
+12
View File
@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: barryvdh
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
+3 -1
View File
@@ -1,3 +1,5 @@
/vendor
build
vendor
composer.lock
.idea
.phpunit.result.cache
+67
View File
@@ -0,0 +1,67 @@
language: php
## Cache composer
cache:
directories:
- $HOME/.composer/cache
env:
global:
- RUN_PHPCS=0
matrix:
include:
- php: '7.2'
env: LARAVEL='5.5.*' COMPOSER_FLAGS='--prefer-lowest'
- php: '7.2'
env: LARAVEL='5.5.*' COMPOSER_FLAGS='--prefer-stable'
- php: '7.2'
env: LARAVEL='5.8.*' COMPOSER_FLAGS='--prefer-lowest'
- php: '7.2'
env: LARAVEL='5.8.*' COMPOSER_FLAGS='--prefer-stable'
- php: '7.2'
env: LARAVEL='^6.0' COMPOSER_FLAGS='--prefer-lowest'
- php: '7.2'
env: LARAVEL='^6.0' COMPOSER_FLAGS='--prefer-stable'
- php: '7.3'
env: LARAVEL='5.5.*' COMPOSER_FLAGS='--prefer-lowest'
- php: '7.3'
env: LARAVEL='5.5.*' COMPOSER_FLAGS='--prefer-stable'
- php: '7.3'
env: LARAVEL='5.8.*' COMPOSER_FLAGS='--prefer-lowest'
- php: '7.3'
env: LARAVEL='5.8.*' COMPOSER_FLAGS='--prefer-stable'
- php: '7.3'
env: LARAVEL='^6.0' COMPOSER_FLAGS='--prefer-lowest'
- php: '7.3'
env: LARAVEL='^6.0' COMPOSER_FLAGS='--prefer-stable'
- php: '7.4'
env: LARAVEL='5.5.*' COMPOSER_FLAGS='--prefer-lowest'
- php: '7.4'
env: LARAVEL='5.5.*' COMPOSER_FLAGS='--prefer-stable'
- php: '7.4'
env: LARAVEL='5.8.*' COMPOSER_FLAGS='--prefer-lowest'
- php: '7.4'
env: LARAVEL='5.8.*' COMPOSER_FLAGS='--prefer-stable'
- php: '7.4'
env: LARAVEL='^6.0' COMPOSER_FLAGS='--prefer-lowest'
- php: '7.4'
env: LARAVEL='^6.0' COMPOSER_FLAGS='--prefer-stable' RUN_PHPCS=1
- php: '7.4'
env: LARAVEL='^7.0' COMPOSER_FLAGS='--prefer-stable' RUN_PHPCS=1
before_script:
- phpenv config-rm xdebug.ini || true
install:
- travis_retry composer remove phpro/grumphp --no-interaction --no-update --dev
- composer require "illuminate/support:${LARAVEL}" --no-interaction --no-update
- composer require "illuminate/console:${LARAVEL}" --no-interaction --no-update
- composer require "illuminate/filesystem:${LARAVEL}" --no-interaction --no-update
- composer require --dev "illuminate/config:${LARAVEL}" --no-interaction --no-update
- composer require --dev "illuminate/view:${LARAVEL}" --no-interaction --no-update
- travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-dist --no-suggest
script:
- vendor/bin/phpunit
- if [[ $RUN_PHPCS = 1 ]]; then vendor/bin/phpcs --standard=psr2 src/; fi
+21
View File
@@ -0,0 +1,21 @@
# The MIT License (MIT)
Copyright (c) Barry vd. Heuvel <barryvdh@gmail.com>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
+29 -11
View File
@@ -10,27 +10,45 @@
}
],
"require": {
"php": ">=5.4.0",
"illuminate/support": "5.0.x",
"illuminate/console": "5.0.x",
"illuminate/filesystem": "5.0.x",
"phpdocumentor/reflection-docblock": "2.0.x",
"symfony/class-loader": "~2.3"
},
"require-dev": {
"php": ">=7.2",
"illuminate/support": "^5.5|^6|^7",
"illuminate/console": "^5.5|^6|^7",
"illuminate/filesystem": "^5.5|^6|^7",
"barryvdh/reflection-docblock": "^2.0.6",
"composer/composer": "^1.6",
"doctrine/dbal": "~2.3"
},
"suggest": {
"doctrine/dbal": "Load information from the database about models for phpdocs (~2.3)"
"require-dev": {
"illuminate/config": "^5.5|^6|^7",
"illuminate/view": "^5.5|^6|^7",
"phpro/grumphp": "^0.17.1",
"squizlabs/php_codesniffer": "^3",
"orchestra/testbench": "^3|^4|^5",
"mockery/mockery": "^1.3"
},
"autoload": {
"psr-4": {
"Barryvdh\\LaravelIdeHelper\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Barryvdh\\LaravelIdeHelper\\Tests\\": "tests"
}
},
"scripts": {
"test": "phpunit",
"check-style": "phpcs -p --standard=PSR2 src/",
"fix-style": "phpcbf -p --standard=PSR2 src/"
},
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
"dev-master": "2.6-dev"
},
"laravel": {
"providers": [
"Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider"
]
}
}
}
+149 -17
View File
@@ -1,4 +1,4 @@
<?php
<?php
return array(
@@ -14,6 +14,57 @@ return array(
'filename' => '_ide_helper',
'format' => 'php',
'meta_filename' => '.phpstorm.meta.php',
/*
|--------------------------------------------------------------------------
| Fluent helpers
|--------------------------------------------------------------------------
|
| Set to true to generate commonly used Fluent methods
|
*/
'include_fluent' => false,
/*
|--------------------------------------------------------------------------
| Factory Builders
|--------------------------------------------------------------------------
|
| Set to true to generate factory generators for better factory()
| method auto-completion.
|
*/
'include_factory_builders' => false,
/*
|--------------------------------------------------------------------------
| Write Model Magic methods
|--------------------------------------------------------------------------
|
| Set to false to disable write magic methods of model
|
*/
'write_model_magic_where' => true,
/*
|--------------------------------------------------------------------------
| Write Eloquent Model Mixins
|--------------------------------------------------------------------------
|
| This will add the necessary DocBlock mixins to the model class
| contained in the Laravel Framework. This helps the IDE with
| auto-completion.
|
| Please be aware that this setting changes a file within the /vendor directory.
|
*/
'write_eloquent_model_mixins' => false,
/*
|--------------------------------------------------------------------------
| Helper files to include
@@ -44,6 +95,18 @@ return array(
'app',
),
/*
|--------------------------------------------------------------------------
| Models to ignore
|--------------------------------------------------------------------------
|
| Define which models should be ignored.
|
*/
'ignored_models' => array(
),
/*
|--------------------------------------------------------------------------
@@ -59,19 +122,8 @@ return array(
'Session' => array('Illuminate\Session\Store'),
),
'magic' => array(
'Log' => array(
'debug' => 'Monolog\Logger::addDebug',
'info' => 'Monolog\Logger::addInfo',
'notice' => 'Monolog\Logger::addNotice',
'warning' => 'Monolog\Logger::addWarning',
'error' => 'Monolog\Logger::addError',
'critical' => 'Monolog\Logger::addCritical',
'alert' => 'Monolog\Logger::addAlert',
'emergency' => 'Monolog\Logger::addEmergency',
)
),
'magic' => array(),
/*
|--------------------------------------------------------------------------
| Interface implementations
@@ -81,9 +133,89 @@ return array(
| are detected by the helpers, others can be listed below.
|
*/
'interfaces' => array(
'\Illuminate\Contracts\Auth\Authenticatable' => config('auth.model', 'App\User'),
)
),
/*
|--------------------------------------------------------------------------
| Support for custom DB types
|--------------------------------------------------------------------------
|
| This setting allow you to map any custom database type (that you may have
| created using CREATE TYPE statement or imported using database plugin
| / extension to a Doctrine type.
|
| Each key in this array is a name of the Doctrine2 DBAL Platform. Currently valid names are:
| 'postgresql', 'db2', 'drizzle', 'mysql', 'oracle', 'sqlanywhere', 'sqlite', 'mssql'
|
| This name is returned by getName() method of the specific Doctrine/DBAL/Platforms/AbstractPlatform descendant
|
| The value of the array is an array of type mappings. Key is the name of the custom type,
| (for example, "jsonb" from Postgres 9.4) and the value is the name of the corresponding Doctrine2 type (in
| our case it is 'json_array'. Doctrine types are listed here:
| http://doctrine-dbal.readthedocs.org/en/latest/reference/types.html
|
| So to support jsonb in your models when working with Postgres, just add the following entry to the array below:
|
| "postgresql" => array(
| "jsonb" => "json_array",
| ),
|
*/
'custom_db_types' => array(
),
/*
|--------------------------------------------------------------------------
| Support for camel cased models
|--------------------------------------------------------------------------
|
| There are some Laravel packages (such as Eloquence) that allow for accessing
| Eloquent model properties via camel case, instead of snake case.
|
| Enabling this option will support these packages by saving all model
| properties as camel case, instead of snake case.
|
| For example, normally you would see this:
|
| * @property \Illuminate\Support\Carbon $created_at
| * @property \Illuminate\Support\Carbon $updated_at
|
| With this enabled, the properties will be this:
|
| * @property \Illuminate\Support\Carbon $createdAt
| * @property \Illuminate\Support\Carbon $updatedAt
|
| Note, it is currently an all-or-nothing option.
|
*/
'model_camel_case_properties' => false,
/*
|--------------------------------------------------------------------------
| Property Casts
|--------------------------------------------------------------------------
|
| Cast the given "real type" to the given "type".
|
*/
'type_overrides' => array(
'integer' => 'int',
'boolean' => 'bool',
),
/*
|--------------------------------------------------------------------------
| Include DocBlocks from classes
|--------------------------------------------------------------------------
|
| Include DocBlocks from classes to allow additional code inspection for
| magic methods and properties.
|
*/
'include_class_docblocks' => false,
);
+18
View File
@@ -0,0 +1,18 @@
parameters:
git_dir: .
bin_dir: vendor/bin
tasks:
phpunit:
config_file: ~
testsuite: ~
group: []
always_execute: false
phpcs:
standard: PSR2
warning_severity: ~
ignore_patterns:
- tests/
triggered_by: [php]
whitelist_patterns:
- /^src\/.*/
- /^config\/.*/
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit Tests">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
</phpunit>
+234 -71
View File
@@ -1,115 +1,278 @@
## Laravel 5 IDE Helper Generator
[![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)
## Laravel IDE Helper Generator
### For Laravel 4.x, check [version 1.11](https://github.com/barryvdh/laravel-ide-helper/tree/1.11)
[![Latest Version on Packagist][ico-version]][link-packagist]
[![Software License][ico-license]](LICENSE.md)
[![Build Status][ico-travis]][link-travis]
[![Total Downloads][ico-downloads]][link-downloads]
__For Laravel 4.x, check [version 1.11](https://github.com/barryvdh/laravel-ide-helper/tree/1.11)__
* [Complete phpDocs, directly from the source](#complete-phpdocs--directly-from-the-source)
* [Install](#install)
* [Automatic phpDoc generation for Laravel Facades](#automatic-phpdoc-generation-for-laravel-facades)
* [Automatic phpDocs for models](#automatic-phpdocs-for-models)
* [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)
- [Lumen Install](#lumen-install)
+ [Enabling Facades](#enabling-facades)
+ [Adding the Service Provider](#adding-the-service-provider)
+ [Adding Additional Facades](#adding-additional-facades)
* [License](#license)
### Complete phpDocs, directly from the source
_Checkout [this Laracasts video](https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15) for a quick introduction/explanation!_
_Check out [this Laracasts video](https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15) for a quick introduction/explanation!_
This packages generates a file that your IDE can understand, so it can provide accurate autocompletion. Generation is done, based on the files in your project, so they are alway up-to-date.
If you don't want to generate it, you can add a pre-generated file to the root folder of your laravel project. (But this isn't as up-to-date as self generated files)
* [`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:meta` - PhpStorm Meta file](#phpstorm-meta-for-container-instances)
* Generated version: https://gist.github.com/barryvdh/5227822
This package generates a file that your IDE understands, so it can provide accurate autocompletion. Generation is done based on the files in your project, so they are always up-to-date.
If you don't want to generate it, you can add a pre-generated file to the root folder of your Laravel project (but this isn't as up-to-date as self generated files).
Note: You do need CodeIntel for Sublime Text: https://github.com/SublimeCodeIntel/SublimeCodeIntel
* Generated version for L5: https://gist.github.com/barryvdh/5227822
* Generated version for Lumen: https://gist.github.com/barryvdh/be17164b0ad51f832f20
* Generated Phpstorm Meta file: https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67
### New: PhpStorm Meta for Container instances
Note: You do need CodeComplice for Sublime Text: https://github.com/spectacles/CodeComplice
It's possible to generate a PhpStorm meta file, to [add support for factory design pattern](https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata). For Laravel, this means we can make PhpStorm understand what kind of object we are resolving from the IoC Container. For example, `events` will return ann `Illuminate\Events\Dispatcher` object, so with the meta file you can call `app('events')` and it will autocomplete the Dispatcher methods.
php artisan ide-helper:meta
app('events')->fire();
\App::make('events')->fire();
/** @var \Illuminate\Foundation\Application $app */
$app->make('events')->fire();
Pre-generated example: https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67
> Note: You might need to restart PhpStorm and make sure `.phpstorm.meta.php` is indexed.
> Note: When you receive a FatalException about a class that is 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.)
### Automatic phpDoc generation for Laravel Facades
### Install
Require this package with composer using the following command:
composer require barryvdh/laravel-ide-helper
```bash
composer require --dev barryvdh/laravel-ide-helper
```
After updating composer, add the ServiceProvider to the providers array in config/app.php
After updating composer, add the service provider to the `providers` array in `config/app.php`
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
```php
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
```
**Laravel 5.5** uses Package Auto-Discovery, so doesn't require you to manually add the ServiceProvider.
You can now re-generate the docs yourself (for future updates) in artisan
In Laravel, instead of adding the service provider in the `config/app.php` file, you can add the following code to your `app/Providers/AppServiceProvider.php` file, within the `register()` method:
php artisan ide-helper:generate
```php
public function register()
{
if ($this->app->environment() !== 'production') {
$this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
}
// ...
}
```
Note: bootstrap/compiled.php has to be cleared first, so run `php artisan clear-compiled` before generating (and `php artisan optimize` after..)
This will allow your application to load the Laravel IDE Helper on non-production enviroments.
### Automatic phpDoc generation for Laravel Facades
You can now re-generate the docs yourself (for future updates)
```bash
php artisan ide-helper:generate
```
Note: `bootstrap/compiled.php` has to be cleared first, so run `php artisan clear-compiled` before generating.
You can configure your composer.json to do this after each commit:
"scripts":{
"post-update-cmd":[
"php artisan clear-compiled",
"php artisan ide-helper:generate",
"php artisan optimize"
]
},
```js
"scripts":{
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"@php artisan ide-helper:generate",
"@php artisan ide-helper:meta"
]
},
```
You can also publish the config-file to change implementations (ie. interface to specific class) or set defaults for --helpers or --sublime.
You can also publish the config file to change implementations (ie. interface to specific class) or set defaults for `--helpers` or `--sublime`.
php artisan vendor:publish --provider=barryvdh/laravel-ide-helper --tag=config
```bash
php artisan vendor:publish --provider="Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider" --tag=config
```
The generator tries to identify the real class, but if it cannot be found, you can define it in the config file.
Some classes need a working database connection. If you do not have a working default connection, some facades will not be included.
You can use a in-memory sqlite driver, using the -M option.
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.
You can choose to include helper files. This is not enabled by default, but you can override this 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.
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.
### Automatic phpDocs for Models
### Automatic phpDocs for models
> You need to require `doctrine/dbal: ~2.3` in your own composer.json to get database columns.
If you don't want to write your properties yourself, you can use the command `ide-helper:models` to generate
phpDocs, based on table columns, relations and getters/setters. You can write the comments directly to your Model file, using the `--write (-W)` option. By default, you are asked to overwrite or write to a separate file (\_ide\_helper\_models.php) (You can force No with `--nowrite (-N)`).
If you don't want to write your properties yourself, you can use the command `php artisan ide-helper:models` to generate
phpDocs, based on table columns, relations and getters/setters. You can write the comments directly to your Model file, using the `--write (-W)` option. By default, you are asked to overwrite or write to a separate file (`_ide_helper_models.php`). You can force No with `--nowrite (-N)`.
Please make sure to backup your models, before writing the info.
It 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, only the newly found columns/relations are saved as phpdocs.
With the `--reset (-R)` option, the existing phpdocs are ignored, and only the newly found columns/relations are saved as phpdocs.
php artisan ide-helper:models Post
```bash
php artisan ide-helper:models Post
```
/**
* An Eloquent Model: 'Post'
*
* @property integer $id
* @property integer $author_id
* @property string $title
* @property string $text
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property-read \User $author
* @property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
*/
```php
/**
* An Eloquent Model: 'Post'
*
* @property integer $id
* @property integer $author_id
* @property string $title
* @property string $text
* @property \Illuminate\Support\Carbon $created_at
* @property \Illuminate\Support\Carbon $updated_at
* @property-read \User $author
* @property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
*/
```
By default, models in app/models are scanned. The optional argument tells what models to use (also outside app/models).
By default, models in `app/models` are scanned. The optional argument tells what models to use (also outside app/models).
php artisan ide-helper:models Post User
```bash
php artisan ide-helper:models Post User
```
You can also scan a different directory, using the --dir option (relative from the base path):
You can also scan a different directory, using the `--dir` option (relative from the base path):
```bash
php artisan ide-helper:models --dir="path/to/models" --dir="app/src/Model"
```
php artisan ide-helper:models --dir="path/to/models" --dir="app/src/Model"
You can publish the config file (`php artisan vendor:publish`) and set the default directories.
Models can be ignored using the --ignore (-I) option
Models can be ignored using the `--ignore (-I)` option
php artisan ide-helper:models --ignore="Post,User"
```bash
php artisan ide-helper:models --ignore="Post,User"
```
Note: With namespaces, wrap your model name in " signs: `php artisan ide-helper:models "API\User"`, or escape the slashes (`Api\\User`)
Or can be ignored by setting the `ignored_models` config
```php
'ignored_models' => array(
Post::class,
Api\User::class
),
```
Note: With namespaces, wrap your model name in double-quotes (`"`): `php artisan ide-helper:models "API\User"`, or escape the slashes (`Api\\User`)
For properly recognition of `Model` methods (i.e. `paginate`, `findOrFail`) you should extend `\Eloquent` or add
```php
/** @mixin \Eloquent */
```
for your model class.
### Automatic phpDocs generation for Laravel Fluent methods
If you need phpDocs support for Fluent methods in migration, for example
```php
$table->string("somestring")->nullable()->index();
```
After publishing vendor, simply change the `include_fluent` line your `config/ide-helper.php` file into:
```php
'include_fluent' => true,
```
And then run `php artisan ide-helper:generate` , you will now see all of the Fluent methods are recognized by your IDE.
### 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.
```php
'include_factory_builders' => true,
```
For this to work, you must also publish the PhpStorm Meta file (see below).
## PhpStorm Meta for Container instances
It's possible to generate a PhpStorm meta file to [add support for factory design pattern](https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata). For Laravel, this means we can make PhpStorm understand what kind of object we are resolving from the IoC Container. For example, `events` will return an `Illuminate\Events\Dispatcher` object, so with the meta file you can call `app('events')` and it will autocomplete the Dispatcher methods.
``` bash
php artisan ide-helper:meta
```
```php
app('events')->fire();
\App::make('events')->fire();
/** @var \Illuminate\Foundation\Application $app */
$app->make('events')->fire();
// When the key is not found, it uses the argument as class name
app('App\SomeClass');
```
Pre-generated example: https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67
> Note: You might need to restart PhpStorm and make sure `.phpstorm.meta.php` is indexed.
> Note: When you receive a FatalException about a class that is 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).
## Lumen Install
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 barebone 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 enviroment. Lumen 5.1+ will read this file for configuration parameters if it is present, and may overlap some configurations if it is completely populated.
### 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-travis]: https://img.shields.io/travis/barryvdh/laravel-ide-helper/master.svg?style=flat-square
[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-travis]: https://travis-ci.org/barryvdh/laravel-ide-helper
[link-downloads]: https://packagist.org/packages/barryvdh/laravel-ide-helper
[link-author]: https://github.com/barryvdh
[link-contributors]: ../../contributors
+96 -18
View File
@@ -1,39 +1,117 @@
<?= '<?php' ?>
<?php
/**
* @var \Barryvdh\LaravelIdeHelper\Alias[][] $namespaces_by_alias_ns
* @var \Barryvdh\LaravelIdeHelper\Alias[][] $namespaces_by_extends_ns
* @var bool $include_fluent
* @var string $helpers
*/
?>
// @formatter:off
/**
* An helper file for Laravel 5, to provide autocomplete information to your IDE
* Generated for Laravel <?= $version ?> on <?= date("Y-m-d") ?>.
* A helper file for Laravel, to provide autocomplete information to your IDE
* Generated for Laravel <?= $version ?> on <?= date("Y-m-d H:i:s") ?>.
*
* This file should not be included in your code, only analyzed by your IDE!
*
* @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper
*/
<?php foreach($namespaces as $namespace => $aliases): ?>
namespace <?= $namespace == '__root' ? '' : $namespace ?>{
<?php if($namespace == '__root'): ?>
exit("This file should not be included, only analyzed by your IDE");
<?= $helpers ?>
<?php endif; ?>
<?php foreach($namespaces_by_extends_ns as $namespace => $aliases): ?>
<?php if ($namespace == '\Illuminate\Database\Eloquent'): continue; endif; ?>
namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
<?php foreach($aliases as $alias): ?>
<?= $alias->getClassType() ?> <?= $alias->getShortName() ?> <?= $alias->getExtends() ? 'extends ' . $alias->getExtends() : '' ?>{
<?= trim($alias->getDocComment(' ')) ?>
<?= $alias->getClassType() ?> <?= $alias->getExtendsClass() ?> {
<?php foreach($alias->getMethods() as $method): ?>
<?= trim($method->getDocComment(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>){<?php if($method->getDeclaringClass() !== $method->getRoot()): ?>
<?= trim($method->getDocComment(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
{<?php if($method->getDeclaringClass() !== $method->getRoot()): ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
<?= $method->shouldReturn() ? 'return ': '' ?><?= $method->getRoot() ?>::<?= $method->getName() ?>(<?= $method->getParams() ?>);
<?php if($method->isInstanceCall()):?>
/** @var <?=$method->getRoot()?> $instance */
<?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, '\\') ?> {
<?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(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
{<?php if($method->getDeclaringClass() !== $method->getRoot()): ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
<?php if($method->isInstanceCall()):?>
/** @var <?=$method->getRoot()?> $instance */
<?php endif?>
<?= $method->shouldReturn() ? 'return ': '' ?><?= $method->getRootMethodCall() ?>;
}
<?php endforeach; ?>
<?php endif; ?>}
<?php endforeach; ?>
}
<?php endforeach; ?>
<?php if($helpers): ?>
namespace {
<?= $helpers ?>
}
<?php endif; ?>
<?php if($include_fluent): ?>
namespace Illuminate\Support {
/**
* Methods commonly used in migrations
*
* @method Fluent after(string $column) Add the after modifier
* @method Fluent charset(string $charset) Add the character set modifier
* @method Fluent collation(string $collation) Add the collation modifier
* @method Fluent comment(string $comment) Add comment
* @method Fluent default($value) Add the default modifier
* @method Fluent first() Select first row
* @method Fluent index(string $name = null) Add the in dex clause
* @method Fluent on(string $table) `on` of a foreign key
* @method Fluent onDelete(string $action) `on delete` of a foreign key
* @method Fluent onUpdate(string $action) `on update` of a foreign key
* @method Fluent primary() Add the primary key modifier
* @method Fluent references(string $column) `references` of a foreign key
* @method Fluent nullable(bool $value = true) Add the nullable modifier
* @method Fluent unique(string $name = null) Add unique index clause
* @method Fluent unsigned() Add the unsigned modifier
* @method Fluent useCurrent() Add the default timestamp value
* @method Fluent change() Add the change modifier
*/
class Fluent {}
}
<?php endif ?>
<?php foreach ($factories as $factory): ?>
namespace <?=$factory->getNamespaceName()?> {
/**
* @method \Illuminate\Database\Eloquent\Collection|<?=$factory->getShortName()?>[]|<?=$factory->getShortName()?> create($attributes = [])
* @method \Illuminate\Database\Eloquent\Collection|<?=$factory->getShortName()?>[]|<?=$factory->getShortName()?> make($attributes = [])
*/
class <?=$factory->getShortName()?>FactoryBuilder extends \Illuminate\Database\Eloquent\FactoryBuilder {}
}
<?php endforeach; ?>
+53 -12
View File
@@ -1,21 +1,62 @@
<?= '<?php' ?> namespace PHPSTORM_META {
<?= '<?php' ?>
// @formatter:off
namespace PHPSTORM_META {
/**
* PhpStorm Meta file, to provide autocomplete information for PhpStorm
* Generated on <?= date("Y-m-d") ?>.
* Generated on <?= date("Y-m-d H:i:s") ?>.
*
* @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper
*/
/** @noinspection PhpIllegalArrayKeyTypeInspection */
/** @noinspection PhpUnusedLocalVariableInspection */
$STATIC_METHOD_TYPES = [
<?php foreach($methods as $method): ?>
<?= $method ?>('') => [
<?php foreach ($methods as $method): ?>
override(<?= $method ?>, map([
'' => '@',
<?php foreach($bindings as $abstract => $class): ?>
'<?= $abstract ?>' instanceof \<?= $class ?>,
<?php endforeach ?> ],
<?php endforeach ?>
];
'<?= $abstract ?>' => \<?= $class ?>::class,
<?php endforeach; ?>
]));
<?php endforeach; ?>
<?php if (count($factories)): ?>
override(\factory(0), map([
'' => '@FactoryBuilder',
<?php foreach($factories as $factory): ?>
'<?= $factory->getName() ?>' => \<?= $factory->getName() ?>FactoryBuilder::class,
<?php endforeach; ?>
]));
<?php endif; ?>
override(\Illuminate\Support\Arr::add(0), type(0));
override(\Illuminate\Support\Arr::except(0), type(0));
override(\Illuminate\Support\Arr::first(0), elementType(0));
override(\Illuminate\Support\Arr::last(0), elementType(0));
override(\Illuminate\Support\Arr::get(0), elementType(0));
override(\Illuminate\Support\Arr::only(0), type(0));
override(\Illuminate\Support\Arr::prepend(0), type(0));
override(\Illuminate\Support\Arr::pull(0), elementType(0));
override(\Illuminate\Support\Arr::set(0), type(0));
override(\Illuminate\Support\Arr::shuffle(0), type(0));
override(\Illuminate\Support\Arr::sort(0), type(0));
override(\Illuminate\Support\Arr::sortRecursive(0), type(0));
override(\Illuminate\Support\Arr::where(0), type(0));
override(\array_add(0), type(0));
override(\array_except(0), type(0));
override(\array_first(0), elementType(0));
override(\array_last(0), elementType(0));
override(\array_get(0), elementType(0));
override(\array_only(0), type(0));
override(\array_prepend(0), type(0));
override(\array_pull(0), elementType(0));
override(\array_set(0), type(0));
override(\array_sort(0), type(0));
override(\array_sort_recursive(0), type(0));
override(\array_where(0), type(0));
override(\head(0), elementType(0));
override(\last(0), elementType(0));
override(\with(0), type(0));
override(\tap(0), type(0));
}
+463 -284
View File
@@ -1,284 +1,463 @@
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
class Alias
{
protected $alias;
protected $facade;
protected $extends = null;
protected $classType = 'class';
protected $short;
protected $namespace = '__root';
protected $root = null;
protected $classes = array();
protected $methods = array();
protected $usedMethods = array();
protected $valid = false;
protected $magicMethods = array();
protected $interfaces = array();
/**
* @param string $alias
* @param string $facade
* @param array $magicMethods
* @param array $interfaces
*/
public function __construct($alias, $facade, $magicMethods = array(), $interfaces = array())
{
$this->alias = $alias;
$this->magicMethods = $magicMethods;
$this->interfaces = $interfaces;
// Make the class absolute
$facade = '\\' . ltrim($facade, '\\');
$this->facade = $facade;
$this->detectRoot();
if ((!$this->isTrait() && $this->root)) {
$this->valid = true;
} else {
return;
}
$this->addClass($this->root);
$this->detectNamespace();
$this->detectClassType();
if($facade === '\Illuminate\Database\Eloquent\Model'){
$this->usedMethods = array('decrement', 'increment');
}
}
/**
* Add one or more classes to analyze
*
* @param array|string $classes
*/
public function addClass($classes)
{
$classes = (array)$classes;
foreach ($classes as $class) {
if (class_exists($class) || interface_exists($class)) {
$this->classes[] = $class;
}else{
echo "Class not exists: $class\r\n";
}
}
}
/**
* Check if this class is valid to process.
* @return bool
*/
public function isValid()
{
return $this->valid;
}
/**
* Get the classtype, 'interface' or 'class'
*
* @return string
*/
public function getClasstype()
{
return $this->classType;
}
/**
* Get the class which this alias extends
*
* @return null|string
*/
public function getExtends()
{
return $this->extends;
}
/**
* Get the Alias by which this class is called
*
* @return string
*/
public function getAlias()
{
return $this->alias;
}
/**
* Return the short name (without namespace)
*/
public function getShortName(){
return $this->short;
}
/**
* Get the namespace from the alias
*
* @return string
*/
public function getNamespace()
{
return $this->namespace;
}
/**
* Get the methods found by this Alias
*
* @return array
*/
public function getMethods()
{
$this->addMagicMethods();
$this->detectMethods();
return $this->methods;
}
/**
* Detect the namespace
*/
protected function detectNamespace()
{
if (strpos($this->alias, '\\')) {
$nsParts = explode('\\', $this->alias);
$this->short = array_pop($nsParts);
$this->namespace = implode('\\', $nsParts);
}else{
$this->short = $this->alias;
}
}
/**
* Detect the class type
*/
protected function detectClassType()
{
//Some classes extend the facade
if (interface_exists($this->facade)) {
$this->classType = 'interface';
$this->extends = $this->facade;
} else {
$this->classType = 'class';
if (class_exists($this->facade)) {
$this->extends = $this->facade;
}
}
}
/**
* Get the real root of a facade
*
* @return bool|string
*/
protected function detectRoot()
{
$facade = $this->facade;
try {
//If possible, get the facade root
if (method_exists($facade, 'getFacadeRoot')) {
$root = get_class($facade::getFacadeRoot());
} else {
$root = $facade;
}
//If it doesn't exist, skip it
if (!class_exists($root) && !interface_exists($root)) {
return;
}
$this->root = $root;
//When the database connection is not set, some classes will be skipped
} catch (\PDOException $e) {
$this->error(
"PDOException: " . $e->getMessage() . "\nPlease configure your database connection correctly, or use the sqlite memory driver (-M). Skipping $facade."
);
} catch (\Exception $e) {
$this->error("Exception: " . $e->getMessage() . "\nSkipping $facade.");
}
}
/**
* Detect if this class is a trait or not.
*
* @return bool
*/
protected function isTrait()
{
// Check if the facade is not a Trait
if (function_exists('trait_exists') && trait_exists($this->facade)) {
return true;
}
return false;
}
/**
* Add magic methods, as defined in the configuration files
*/
protected function addMagicMethods()
{
foreach($this->magicMethods as $magic => $real){
list($className, $name) = explode('::', $real);
if(!class_exists($className) && !interface_exists($className)){
continue;
}
$method = new \ReflectionMethod($className, $name);
$class = new \ReflectionClass($className);
if(!in_array($method->name, $this->usedMethods)){
if($class !== $this->root){
$this->methods[] = new Method($method, $this->alias, $class, $magic, $this->interfaces);
}
$this->usedMethods[] = $magic;
}
}
}
/**
* Get the methods for one or multiple classes.
*
* @return string
*/
protected function detectMethods()
{
foreach ($this->classes as $class) {
$reflection = new \ReflectionClass($class);
$methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
if ($methods) {
foreach ($methods as $method) {
if (!in_array($method->name, $this->usedMethods)) {
// Only add the methods to the output when the root is not the same as the class.
// And don't add the __*() methods
if ($this->extends !== $class && substr($method->name, 0, 2) !== '__') {
$this->methods[] = new Method($method, $this->alias, $reflection, $method->name, $this->interfaces);
}
$this->usedMethods[] = $method->name;
}
}
}
}
}
/**
* Output an error.
*
* @param string $string
* @return void
*/
protected function error($string)
{
echo $string . "\r\n";
}
}
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
use Closure;
use ReflectionClass;
use Barryvdh\Reflection\DocBlock;
use Barryvdh\Reflection\DocBlock\Context;
use Barryvdh\Reflection\DocBlock\Tag\MethodTag;
use Illuminate\Config\Repository as ConfigRepository;
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
class Alias
{
protected $alias;
protected $facade;
protected $extends = null;
protected $extendsClass = null;
protected $extendsNamespace = null;
protected $classType = 'class';
protected $short;
protected $namespace = '__root';
protected $root = null;
protected $classes = array();
protected $methods = array();
protected $usedMethods = array();
protected $valid = false;
protected $magicMethods = array();
protected $interfaces = array();
protected $phpdoc = null;
/** @var ConfigRepository */
protected $config;
/**
* @param ConfigRepository $config
* @param string $alias
* @param string $facade
* @param array $magicMethods
* @param array $interfaces
*/
public function __construct($config, $alias, $facade, $magicMethods = array(), $interfaces = array())
{
$this->alias = $alias;
$this->magicMethods = $magicMethods;
$this->interfaces = $interfaces;
$this->config = $config;
// Make the class absolute
$facade = '\\' . ltrim($facade, '\\');
$this->facade = $facade;
$this->detectRoot();
if ((!$this->isTrait() && $this->root)) {
$this->valid = true;
} else {
return;
}
$this->addClass($this->root);
$this->detectFake();
$this->detectNamespace();
$this->detectClassType();
$this->detectExtendsNamespace();
if (!empty($this->namespace)) {
//Create a DocBlock and serializer instance
$this->phpdoc = new DocBlock(new ReflectionClass($alias), new Context($this->namespace));
}
if ($facade === '\Illuminate\Database\Eloquent\Model') {
$this->usedMethods = array('decrement', 'increment');
}
}
/**
* Add one or more classes to analyze
*
* @param array|string $classes
*/
public function addClass($classes)
{
$classes = (array)$classes;
foreach ($classes as $class) {
if (class_exists($class) || interface_exists($class)) {
$this->classes[] = $class;
} else {
echo "Class not exists: $class\r\n";
}
}
}
/**
* Check if this class is valid to process.
* @return bool
*/
public function isValid()
{
return $this->valid;
}
/**
* Get the classtype, 'interface' or 'class'
*
* @return string
*/
public function getClasstype()
{
return $this->classType;
}
/**
* Get the class which this alias extends
*
* @return null|string
*/
public function getExtends()
{
return $this->extends;
}
/**
* Get the class short name which this alias extends
*
* @return null|string
*/
public function getExtendsClass()
{
return $this->extendsClass;
}
/**
* Get the namespace of the class which this alias extends
*
* @return null|string
*/
public function getExtendsNamespace()
{
return $this->extendsNamespace;
}
/**
* Get the Alias by which this class is called
*
* @return string
*/
public function getAlias()
{
return $this->alias;
}
/**
* Return the short name (without namespace)
*/
public function getShortName()
{
return $this->short;
}
/**
* Get the namespace from the alias
*
* @return string
*/
public function getNamespace()
{
return $this->namespace;
}
/**
* Get the methods found by this Alias
*
* @return array|Method[]
*/
public function getMethods()
{
if (count($this->methods) > 0) {
return $this->methods;
}
$this->addMagicMethods();
$this->detectMethods();
return $this->methods;
}
/**
* Detect class returned by ::fake()
*/
protected function detectFake()
{
$facade = $this->facade;
if (!method_exists($facade, 'fake')) {
return;
}
$real = $facade::getFacadeRoot();
try {
$facade::fake();
$fake = $facade::getFacadeRoot();
if ($fake !== $real) {
$this->addClass(get_class($fake));
}
} finally {
$facade::swap($real);
}
}
/**
* Detect the namespace
*/
protected function detectNamespace()
{
if (strpos($this->alias, '\\')) {
$nsParts = explode('\\', $this->alias);
$this->short = array_pop($nsParts);
$this->namespace = implode('\\', $nsParts);
} else {
$this->short = $this->alias;
}
}
/**
* Detect the extends namespace
*/
protected function detectExtendsNamespace()
{
if (strpos($this->extends, '\\') !== false) {
$nsParts = explode('\\', $this->extends);
$this->extendsClass = array_pop($nsParts);
$this->extendsNamespace = implode('\\', $nsParts);
}
}
/**
* Detect the class type
*/
protected function detectClassType()
{
//Some classes extend the facade
if (interface_exists($this->facade)) {
$this->classType = 'interface';
$this->extends = $this->facade;
} else {
$this->classType = 'class';
if (class_exists($this->facade)) {
$this->extends = $this->facade;
}
}
}
/**
* Get the real root of a facade
*
* @return bool|string
*/
protected function detectRoot()
{
$facade = $this->facade;
try {
//If possible, get the facade root
if (method_exists($facade, 'getFacadeRoot')) {
$root = get_class($facade::getFacadeRoot());
} else {
$root = $facade;
}
//If it doesn't exist, skip it
if (!class_exists($root) && !interface_exists($root)) {
return;
}
$this->root = $root;
//When the database connection is not set, some classes will be skipped
} catch (\PDOException $e) {
$this->error(
"PDOException: " . $e->getMessage() .
"\nPlease configure your database connection correctly, or use the sqlite memory driver (-M)." .
" Skipping $facade."
);
} catch (\Exception $e) {
$this->error("Exception: " . $e->getMessage() . "\nSkipping $facade.");
}
}
/**
* Detect if this class is a trait or not.
*
* @return bool
*/
protected function isTrait()
{
// Check if the facade is not a Trait
if (function_exists('trait_exists') && trait_exists($this->facade)) {
return true;
}
return false;
}
/**
* Add magic methods, as defined in the configuration files
*/
protected function addMagicMethods()
{
foreach ($this->magicMethods as $magic => $real) {
list($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);
if (!in_array($magic, $this->usedMethods)) {
if ($class !== $this->root) {
$this->methods[] = new Method($method, $this->alias, $class, $magic, $this->interfaces);
}
$this->usedMethods[] = $magic;
}
}
}
/**
* Get the methods for one or multiple classes.
*
* @return string
*/
protected function detectMethods()
{
foreach ($this->classes as $class) {
$reflection = new \ReflectionClass($class);
$methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
if ($methods) {
foreach ($methods as $method) {
if (!in_array($method->name, $this->usedMethods)) {
// Only add the methods to the output when the root is not the same as the class.
// And don't add the __*() methods
if ($this->extends !== $class && substr($method->name, 0, 2) !== '__') {
$this->methods[] = new Method(
$method,
$this->alias,
$reflection,
$method->name,
$this->interfaces
);
}
$this->usedMethods[] = $method->name;
}
}
}
// Check if the class is macroable
$traits = collect($reflection->getTraitNames());
if ($traits->contains('Illuminate\Support\Traits\Macroable')) {
$properties = $reflection->getStaticProperties();
$macros = isset($properties['macros']) ? $properties['macros'] : [];
foreach ($macros as $macro_name => $macro_func) {
if (!in_array($macro_name, $this->usedMethods)) {
// Add macros
$this->methods[] = new Macro(
$this->getMacroFunction($macro_func),
$this->alias,
$reflection,
$macro_name,
$this->interfaces
);
$this->usedMethods[] = $macro_name;
}
}
}
}
}
/**
* @param $macro_func
*
* @return \ReflectionFunctionAbstract
* @throws \ReflectionException
*/
protected function getMacroFunction($macro_func)
{
if (is_array($macro_func) && is_callable($macro_func)) {
return new \ReflectionMethod($macro_func[0], $macro_func[1]);
}
if (is_object($macro_func) && is_callable($macro_func) && !$macro_func instanceof Closure) {
return new \ReflectionMethod($macro_func, '__invoke');
}
return new \ReflectionFunction($macro_func);
}
/*
* Get the docblock for this alias
*
* @param string $prefix
* @return mixed
*/
public function getDocComment($prefix = "\t\t")
{
$serializer = new DocBlockSerializer(1, $prefix);
if ($this->phpdoc) {
if ($this->config->get('ide-helper.include_class_docblocks')) {
// if a class doesn't expose any DocBlock tags
// we can perform reflection on the class and
// add in the original class DocBlock
if (count($this->phpdoc->getTags()) === 0) {
$class = new ReflectionClass($this->root);
$this->phpdoc = new DocBlock($class->getDocComment());
}
}
$this->removeDuplicateMethodsFromPhpDoc();
return $serializer->getDocComment($this->phpdoc);
}
return '';
}
/**
* Removes method tags from the doc comment that already appear as functions inside the class.
* This prevents duplicate function errors in the IDE.
*
* @return void
*/
protected function removeDuplicateMethodsFromPhpDoc()
{
$methodNames = array_map(function (Method $method) {
return $method->getName();
}, $this->getMethods());
foreach ($this->phpdoc->getTags() as $tag) {
if ($tag instanceof MethodTag && in_array($tag->getMethodName(), $methodNames)) {
$this->phpdoc->deleteTag($tag);
}
}
}
/**
* Output an error.
*
* @param string $string
* @return void
*/
protected function error($string)
{
echo $string . "\r\n";
}
}
+61
View File
@@ -0,0 +1,61 @@
<?php
/**
* Laravel IDE Helper Generator - Eloquent Model Mixin
*
* @author Charles A. Peterson <[email protected]>
* @copyright 2017 Charles A. Peterson / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper\Console;
use Barryvdh\LaravelIdeHelper\Eloquent;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
/**
* A command to add \Eloquent mixin to Eloquent\Model
*
* @author Charles A. Peterson <[email protected]>
*/
class EloquentCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'ide-helper:eloquent';
/**
* @var Filesystem $files
*/
protected $files;
/**
* The console command description.
*
* @var string
*/
protected $description = 'Add \Eloquent helper to \Eloquent\Model';
/**
* @param Filesystem $files
*/
public function __construct(Filesystem $files)
{
parent::__construct();
$this->files = $files;
}
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
Eloquent::writeEloquentModelHelper($this, $this->files);
}
}
+14 -7
View File
@@ -10,14 +10,13 @@
namespace Barryvdh\LaravelIdeHelper\Console;
use Barryvdh\LaravelIdeHelper\Eloquent;
use Barryvdh\LaravelIdeHelper\Generator;
use Illuminate\Config\Repository as ConfigRepository;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
/**
* A command to generate autocomplete information for your IDE
*
@@ -60,7 +59,8 @@ class GeneratorCommand extends Command
*/
public function __construct(
/*ConfigRepository */ $config,
Filesystem $files, /* Illuminate\View\Factory */
Filesystem $files,
/* Illuminate\View\Factory */
$view
) {
$this->config = $config;
@@ -74,11 +74,13 @@ class GeneratorCommand extends Command
*
* @return void
*/
public function fire()
public function handle()
{
if (file_exists($compiled = base_path() . '/bootstrap/compiled.php')) {
if (file_exists(base_path() . '/vendor/compiled.php') ||
file_exists(base_path() . '/bootstrap/cache/compiled.php') ||
file_exists(base_path() . '/storage/framework/compiled.php')) {
$this->error(
'Error generating IDE Helper: first delete bootstrap/compiled.php (php artisan clear-compiled)'
'Error generating IDE Helper: first delete your compiled file (php artisan clear-compiled)'
);
} else {
$filename = $this->argument('filename');
@@ -113,6 +115,10 @@ class GeneratorCommand extends Command
if ($written !== false) {
$this->info("A new helper file was written to $filename");
if ($this->option('write_mixins')) {
Eloquent::writeEloquentModelHelper($this, $this->files);
}
} else {
$this->error("The helper file could not be created at $filename");
}
@@ -156,13 +162,14 @@ class GeneratorCommand extends Command
protected function getOptions()
{
$format = $this->config->get('ide-helper.format');
$writeMixins = $this->config->get('ide-helper.write_eloquent_model_mixins');
return array(
array('format', "F", InputOption::VALUE_OPTIONAL, 'The format for the IDE Helper', $format),
array('write_mixins', "W", InputOption::VALUE_OPTIONAL, 'Write mixins to Laravel Model?', $writeMixins),
array('helpers', "H", InputOption::VALUE_NONE, 'Include the helper files'),
array('memory', "M", InputOption::VALUE_NONE, 'Use sqlite memory driver'),
array('sublime', "S", InputOption::VALUE_NONE, 'DEPRECATED: Use different style for SublimeText CodeIntel'),
);
}
}
+71 -29
View File
@@ -10,15 +10,18 @@
namespace Barryvdh\LaravelIdeHelper\Console;
use Barryvdh\LaravelIdeHelper\Factories;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* A command to generate phpstorm meta data
*
* @author Barry vd. Heuvel <[email protected]>
*/
class MetaCommand extends Command {
class MetaCommand extends Command
{
/**
* The console command name.
@@ -26,7 +29,6 @@ class MetaCommand extends Command {
* @var string
*/
protected $name = 'ide-helper:meta';
protected $filename = '.phpstorm.meta.php';
/**
* The console command description.
@@ -40,24 +42,32 @@ class MetaCommand extends Command {
/** @var \Illuminate\Contracts\View\Factory */
protected $view;
/** @var \Illuminate\Contracts\Config */
protected $config;
protected $methods = [
'\Illuminate\Foundation\Application::make',
'\Illuminate\Contracts\Foundation\Application::make',
'\Illuminate\Contracts\Container\Container::make',
'\Illuminate\Container\Container::make',
'\App::make',
'app',
'new \Illuminate\Contracts\Container\Container',
'\Illuminate\Container\Container::makeWith(0)',
'\Illuminate\Contracts\Container\Container::make(0)',
'\Illuminate\Contracts\Container\Container::makeWith(0)',
'\App::make(0)',
'\App::makeWith(0)',
'\app(0)',
'\resolve(0)',
];
/**
*
* @param \Illuminate\Contracts\Filesystem\Filesystem $files
* @param \Illuminate\Contracts\View\Factory $view
* @param \Illuminate\Contracts\Config $config
*/
public function __construct($files, $view) {
public function __construct($files, $view, $config)
{
$this->files = $files;
$this->view = $view;
$this->config = $config;
parent::__construct();
}
@@ -66,23 +76,39 @@ class MetaCommand extends Command {
*
* @return void
*/
public function fire()
public function handle()
{
// Needs to run before exception handler is registered
$factories = $this->config->get('ide-helper.include_factory_builders') ? Factories::all() : [];
$this->registerClassAutoloadExceptions();
$bindings = array();
foreach ($this->getAbstracts() as $abstract) {
// Validator and seeder cause problems
if (in_array($abstract, ['validator', 'seeder'])) {
continue;
}
try {
$concrete = $this->laravel->make($abstract);
if (is_object($concrete)) {
$reflectionClass = new \ReflectionClass($concrete);
if (is_object($concrete) && !$reflectionClass->isAnonymous()) {
$bindings[$abstract] = get_class($concrete);
}
}catch (\Exception $e) {
$this->error("Cannot make $abstract: ".$e->getMessage());
} catch (\Throwable $e) {
if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
$this->comment("Cannot make '$abstract': ".$e->getMessage());
}
}
}
$content = $this->view->make('ide-helper::meta', [
$this->unregisterClassAutoloadExceptions();
$content = $this->view->make('meta', [
'bindings' => $bindings,
'methods' => $this->methods,
'factories' => $factories,
])->render();
$filename = $this->option('filename');
@@ -96,26 +122,30 @@ class MetaCommand extends Command {
}
/**
* Get a filtered list of abstracts from the Laravel Application.
*
* Get a list of abstracts from the Laravel Application.
*
* @return array
*/
protected function getAbstracts()
{
$abstracts = $this->laravel->getBindings();
// Remove the S3 cloud driver when not available
if (config('filesystems.cloud') === 's3' && !class_exists('League\Flysystem\AwsS3v2\AwsS3Adapter')) {
unset($abstracts['filesystem.cloud']);
}
// Remove Redis when not available
if (isset($abstracts['redis']) && !class_exists('Predis\Client')) {
unset($abstracts['redis']);
}
// Return the abstract names only
return array_keys($abstracts);
$keys = array_keys($abstracts);
sort($keys);
return $keys;
}
/**
* Register an autoloader the throws exceptions when a class is not found.
*/
protected function registerClassAutoloadExceptions()
{
spl_autoload_register(function ($class) {
throw new \ReflectionException("Class '$class' not found.");
});
}
/**
@@ -125,8 +155,20 @@ class MetaCommand extends Command {
*/
protected function getOptions()
{
$filename = $this->config->get('ide-helper.meta_filename');
return array(
array('filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the meta file', $this->filename),
array('filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the meta file', $filename),
);
}
/**
* Remove our custom autoloader that we pushed onto the autoload stack
*/
private function unregisterClassAutoloadExceptions()
{
$autoloadFunctions = spl_autoload_functions();
$ourAutoloader = array_pop($autoloadFunctions);
spl_autoload_unregister($ourAutoloader);
}
}
+548 -104
View File
@@ -10,15 +10,20 @@
namespace Barryvdh\LaravelIdeHelper\Console;
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 Illuminate\Console\Command;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputOption;
use ReflectionClass;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\ClassLoader\ClassMapGenerator;
use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Context;
use phpDocumentor\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* A command to generate autocomplete information for your IDE
@@ -27,6 +32,10 @@ use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer;
*/
class ModelsCommand extends Command
{
/**
* @var Filesystem $files
*/
protected $files;
/**
* The console command name.
@@ -43,19 +52,42 @@ class ModelsCommand extends Command
*/
protected $description = 'Generate autocompletion for models';
protected $write_model_magic_where;
protected $properties = array();
protected $methods = array();
protected $write = false;
protected $dirs = array();
protected $reset;
protected $keep_text;
protected $phpstorm_noinspections;
/**
* @var bool[string]
*/
protected $nullableColumns = [];
/**
* During initializtion we use Laravels Date Facade to
* determine the actual date class and store it here.
*
* @var string
*/
protected $dateClass;
/**
* @param Filesystem $files
*/
public function __construct(Filesystem $files)
{
parent::__construct();
$this->files = $files;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
public function handle()
{
$filename = $this->option('filename');
$this->write = $this->option('write');
@@ -66,21 +98,30 @@ class ModelsCommand extends Command
$model = $this->argument('model');
$ignore = $this->option('ignore');
$this->reset = $this->option('reset');
$this->phpstorm_noinspections = $this->option('phpstorm-noinspections');
if ($this->option('smart-reset')) {
$this->keep_text = $this->reset = true;
}
$this->write_model_magic_where = $this->laravel['config']->get('ide-helper.write_model_magic_where', true);
//If filename is default and Write is not specified, ask what to do
if (!$this->write && $filename === $this->filename && !$this->option('nowrite')) {
if ($this->confirm(
"Do you want to overwrite the existing model files? Choose no to write to $filename instead? (Yes/No): "
"Do you want to overwrite the existing model files? Choose no to write to $filename instead"
)
) {
$this->write = true;
}
}
$this->dateClass = class_exists(\Illuminate\Support\Facades\Date::class)
? '\\' . get_class(\Illuminate\Support\Facades\Date::now())
: '\Illuminate\Support\Carbon';
$content = $this->generateDocs($model, $ignore);
if (!$this->write) {
$written = \File::put($filename, $content);
$written = $this->files->put($filename, $content);
if ($written !== false) {
$this->info("Model information was written to $filename");
} else {
@@ -98,7 +139,7 @@ class ModelsCommand extends Command
protected function getArguments()
{
return array(
array('model', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Which models to include', array()),
array('model', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Which models to include', array()),
);
}
@@ -110,12 +151,17 @@ class ModelsCommand extends Command
protected function getOptions()
{
return array(
array('filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file', $this->filename),
array('dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The model dir', array()),
array('write', 'W', InputOption::VALUE_NONE, 'Write to Model file'),
array('nowrite', 'N', InputOption::VALUE_NONE, 'Don\'t write to Model file'),
array('reset', 'R', InputOption::VALUE_NONE, 'Remove the original phpdocs instead of appending'),
array('ignore', 'I', InputOption::VALUE_OPTIONAL, 'Which models to ignore', ''),
array('filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file', $this->filename),
array('dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The model dir', array()),
array('write', 'W', InputOption::VALUE_NONE, 'Write to Model file'),
array('nowrite', 'N', InputOption::VALUE_NONE, 'Don\'t write to Model file'),
array('reset', 'R', InputOption::VALUE_NONE, 'Remove the original phpdocs instead of appending'),
array('smart-reset', 'r', InputOption::VALUE_NONE, 'Refresh the properties/methods list, but keep the text'),
array('phpstorm-noinspections', 'p', InputOption::VALUE_NONE,
'Add PhpFullyQualifiedNameUsageInspection and PhpUnnecessaryFullyQualifiedNameInspection PHPStorm ' .
'noinspection tags'
),
array('ignore', 'I', InputOption::VALUE_OPTIONAL, 'Which models to ignore', ''),
);
}
@@ -124,8 +170,10 @@ class ModelsCommand extends Command
$output = "<?php
// @formatter:off
/**
* An helper file for your Eloquent Models
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
* And remove them from this file, to prevent double declarations.
*
@@ -144,11 +192,16 @@ class ModelsCommand extends Command
}
}
$ignore = explode(',', $ignore);
$ignore = array_merge(
explode(',', $ignore),
$this->laravel['config']->get('ide-helper.ignored_models', array())
);
foreach ($models as $name) {
if (in_array($name, $ignore)) {
$this->comment("Ignoring model '$name'");
if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
$this->comment("Ignoring model '$name'");
}
continue;
}
$this->properties = array();
@@ -156,16 +209,19 @@ class ModelsCommand extends Command
if (class_exists($name)) {
try {
// handle abstract classes, interfaces, ...
$reflectionClass = new \ReflectionClass($name);
$reflectionClass = new ReflectionClass($name);
if (!$reflectionClass->isSubclassOf('Illuminate\Database\Eloquent\Model')) {
continue;
}
$this->comment("Loading model '$name'");
if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
$this->comment("Loading model '$name'");
}
if (!$reflectionClass->IsInstantiable()) {
throw new \Exception($name . ' is not instantiable.');
// ignore abstract class or interface
continue;
}
$model = $this->laravel->make($name);
@@ -174,23 +230,32 @@ class ModelsCommand extends Command
$this->getPropertiesFromTable($model);
}
if (method_exists($model, 'getCasts')) {
$this->castPropertiesType($model);
}
$this->getPropertiesFromMethods($model);
$output .= $this->createPhpDocs($name);
} catch (\Exception $e) {
$this->error("Exception: " . $e->getMessage() . "\nCould not analyze class $name.");
$this->getSoftDeleteMethods($model);
$this->getCollectionMethods($model);
$output .= $this->createPhpDocs($name);
$ignore[] = $name;
$this->nullableColumns = [];
} catch (\Throwable $e) {
$this->error("Exception: " . $e->getMessage() .
"\nCould not analyze class $name.\n\nTrace:\n" .
$e->getTraceAsString());
}
}
}
if (!$hasDoctrine) {
$this->error(
'Warning: `"doctrine/dbal": "~2.3"` is required to load database information. Please require that in your composer.json and run `composer update`.'
'Warning: `"doctrine/dbal": "~2.3"` is required to load database information. '.
'Please require that in your composer.json and run `composer update`.'
);
}
return $output;
}
@@ -199,15 +264,91 @@ class ModelsCommand extends Command
$models = array();
foreach ($this->dirs as $dir) {
$dir = base_path() . '/' . $dir;
if (file_exists($dir)) {
foreach (ClassMapGenerator::createMap($dir) as $model => $path) {
$models[] = $model;
$dirs = glob($dir, GLOB_ONLYDIR);
foreach ($dirs as $dir) {
if (file_exists($dir)) {
foreach (ClassMapGenerator::createMap($dir) as $model => $path) {
$models[] = $model;
}
}
}
}
return $models;
}
/**
* cast the properties's type from $casts.
*
* @param \Illuminate\Database\Eloquent\Model $model
*/
protected function castPropertiesType($model)
{
$casts = $model->getCasts();
foreach ($casts as $name => $type) {
switch ($type) {
case 'boolean':
case 'bool':
$realType = 'boolean';
break;
case 'string':
$realType = 'string';
break;
case 'array':
case 'json':
$realType = 'array';
break;
case 'object':
$realType = 'object';
break;
case 'int':
case 'integer':
case 'timestamp':
$realType = 'integer';
break;
case 'real':
case 'double':
case 'float':
$realType = 'float';
break;
case 'date':
case 'datetime':
$realType = $this->dateClass;
break;
case 'collection':
$realType = '\Illuminate\Support\Collection';
break;
default:
$realType = class_exists($type) ? ('\\' . $type) : 'mixed';
break;
}
if (!isset($this->properties[$name])) {
continue;
} else {
$realType = $this->checkForCustomLaravelCasts($realType);
$this->properties[$name]['type'] = $this->getTypeOverride($realType);
if (isset($this->nullableColumns[$name])) {
$this->properties[$name]['type'] .= '|null';
}
}
}
}
/**
* Returns the overide type for the give type.
*
* @param string $type
* @return string
*/
protected function getTypeOverride($type)
{
$typeOverrides = $this->laravel['config']->get('ide-helper.type_overrides', array());
return isset($typeOverrides[$type]) ? $typeOverrides[$type] : $type;
}
/**
* Load the properties from the database table.
*
@@ -217,15 +358,27 @@ class ModelsCommand extends Command
{
$table = $model->getConnection()->getTablePrefix() . $model->getTable();
$schema = $model->getConnection()->getDoctrineSchemaManager($table);
$schema->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
$databasePlatform = $schema->getDatabasePlatform();
$databasePlatform->registerDoctrineTypeMapping('enum', 'string');
$columns = $schema->listTableColumns($table);
$platformName = $databasePlatform->getName();
$customTypes = $this->laravel['config']->get("ide-helper.custom_db_types.{$platformName}", array());
foreach ($customTypes as $yourTypeName => $doctrineTypeName) {
$databasePlatform->registerDoctrineTypeMapping($yourTypeName, $doctrineTypeName);
}
$database = null;
if (strpos($table, '.')) {
list($database, $table) = explode('.', $table);
}
$columns = $schema->listTableColumns($table, $database);
if ($columns) {
foreach ($columns as $column) {
$name = $column->getName();
if (in_array($name, $model->getDates())) {
$type = '\Carbon\Carbon';
$type = $this->dateClass;
} else {
$type = $column->getType()->getName();
switch ($type) {
@@ -243,13 +396,21 @@ class ModelsCommand extends Command
case 'smallint':
$type = 'integer';
break;
case 'boolean':
switch (config('database.default')) {
case 'sqlite':
case 'mysql':
$type = 'integer';
break;
default:
$type = 'boolean';
break;
}
break;
case 'decimal':
case 'float':
$type = 'float';
break;
case 'boolean':
$type = 'boolean';
break;
default:
$type = 'mixed';
break;
@@ -257,12 +418,17 @@ class ModelsCommand extends Command
}
$comment = $column->getComment();
$this->setProperty($name, $type, true, true, $comment);
$this->setMethod(
Str::camel("where_" . $name),
'\Illuminate\Database\Query\Builder|\\' . get_class($model),
array('$value')
);
if (!$column->getNotnull()) {
$this->nullableColumns[$name] = true;
}
$this->setProperty($name, $type, true, true, $comment, !$column->getNotnull());
if ($this->write_model_magic_where) {
$this->setMethod(
Str::camel("where_" . $name),
'\Illuminate\Database\Eloquent\Builder|\\' . get_class($model),
array('$value')
);
}
}
}
}
@@ -274,21 +440,24 @@ class ModelsCommand extends Command
{
$methods = get_class_methods($model);
if ($methods) {
sort($methods);
foreach ($methods as $method) {
if (Str::startsWith($method, 'get') && Str::endsWith(
$method,
'Attribute'
) && $method !== 'getAttribute'
$method,
'Attribute'
) && $method !== 'getAttribute'
) {
//Magic get<name>Attribute
$name = Str::snake(substr($method, 3, -9));
if (!empty($name)) {
$this->setProperty($name, null, true, null);
$reflection = new \ReflectionMethod($model, $method);
$type = $this->getReturnType($reflection);
$this->setProperty($name, $type, true, null);
}
} elseif (Str::startsWith($method, 'set') && Str::endsWith(
$method,
'Attribute'
) && $method !== 'setAttribute'
$method,
'Attribute'
) && $method !== 'setAttribute'
) {
//Magic set<name>Attribute
$name = Str::snake(substr($method, 3, -9));
@@ -303,13 +472,29 @@ class ModelsCommand extends Command
$args = $this->getParameters($reflection);
//Remove the first ($query) argument
array_shift($args);
$this->setMethod($name, '\\' . $reflection->class, $args);
$this->setMethod($name, '\Illuminate\Database\Eloquent\Builder|\\' . $reflection->class, $args);
}
} elseif (!method_exists('Eloquent', $method) && !Str::startsWith($method, 'get')) {
} elseif (in_array($method, ['query', 'newQuery', 'newModelQuery'])) {
$reflection = new \ReflectionClass($model);
$builder = get_class($model->newModelQuery());
$this->setMethod($method, "\\{$builder}|\\" . $reflection->getName());
} elseif (!method_exists('Illuminate\Database\Eloquent\Model', $method)
&& !Str::startsWith($method, 'get')
) {
//Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php
$reflection = new \ReflectionMethod($model, $method);
if ($returnType = $reflection->getReturnType()) {
$type = $returnType instanceof \ReflectionNamedType
? $returnType->getName()
: (string)$returnType;
} else {
// php 7.x type or fallback to docblock
$type = (string)$this->getReturnTypeFromDocBlock($reflection);
}
$file = new \SplFileObject($reflection->getFileName());
$file->seek($reflection->getStartLine() - 1);
@@ -318,52 +503,128 @@ class ModelsCommand extends Command
$code .= $file->current();
$file->next();
}
$code = trim(preg_replace('/\s\s+/', '', $code));
$begin = strpos($code, 'function(');
$code = substr($code, $begin, strrpos($code, '}') - $begin + 1);
foreach (array(
'hasMany',
'belongsToMany',
'hasOne',
'belongsTo',
'morphTo',
'morphMany',
'morphToMany'
) as $relation) {
'hasMany' => '\Illuminate\Database\Eloquent\Relations\HasMany',
'hasManyThrough' => '\Illuminate\Database\Eloquent\Relations\HasManyThrough',
'hasOneThrough' => '\Illuminate\Database\Eloquent\Relations\HasOneThrough',
'belongsToMany' => '\Illuminate\Database\Eloquent\Relations\BelongsToMany',
'hasOne' => '\Illuminate\Database\Eloquent\Relations\HasOne',
'belongsTo' => '\Illuminate\Database\Eloquent\Relations\BelongsTo',
'morphOne' => '\Illuminate\Database\Eloquent\Relations\MorphOne',
'morphTo' => '\Illuminate\Database\Eloquent\Relations\MorphTo',
'morphMany' => '\Illuminate\Database\Eloquent\Relations\MorphMany',
'morphToMany' => '\Illuminate\Database\Eloquent\Relations\MorphToMany',
'morphedByMany' => '\Illuminate\Database\Eloquent\Relations\MorphToMany'
) as $relation => $impl) {
$search = '$this->' . $relation . '(';
if ($pos = stripos($code, $search)) {
$code = substr($code, $pos + strlen($search));
$arguments = explode(',', substr($code, 0, strpos($code, ');')));
//Remove quotes, ensure 1 \ in front of the model
$returnModel = $this->getClassName($arguments[0], $model);
if ($relation === "belongsToMany" or $relation === 'hasMany' or $relation === 'morphMany' or $relation === 'morphToMany') {
//Collection or array of models (because Collection is Arrayable)
$this->setProperty(
$method,
'\Illuminate\Database\Eloquent\Collection|' . $returnModel . '[]',
true,
null
);
} else {
//Single model is returned
$this->setProperty($method, $returnModel, true, null);
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()) {
continue;
}
// Adding constraints requires reading model properties which
// can cause errors. Since we don't need constraints we can
// disable them when we fetch the relation to avoid errors.
$relationObj = Relation::noConstraints(function () use ($model, $method) {
return $model->$method();
});
if ($relationObj instanceof Relation) {
$relatedModel = '\\' . get_class($relationObj->getRelated());
$relations = [
'hasManyThrough',
'belongsToMany',
'hasMany',
'morphMany',
'morphToMany',
'morphedByMany',
];
if (strpos(get_class($relationObj), 'Many') !== false) {
//Collection or array of models (because Collection is Arrayable)
$this->setProperty(
$method,
$this->getCollectionClass($relatedModel) . '|' . $relatedModel . '[]',
true,
null
);
$this->setProperty(
Str::snake($method) . '_count',
'int|null',
true,
false
);
} elseif ($relation === "morphTo") {
// Model isn't specified because relation is polymorphic
$this->setProperty(
$method,
'\Illuminate\Database\Eloquent\Model|\Eloquent',
true,
null
);
} else {
//Single model is returned
$this->setProperty(
$method,
$relatedModel,
true,
null,
'',
$this->isRelationNullable($relation, $relationObj)
);
}
}
}
}
}
}
}
}
/**
* @param string $name
* @param string|null $type
* @param bool|null $read
* @param bool|null $write
* @param string|null $comment
* Check if the relation is nullable
*
* @param string $relation
* @param Relation $relationObj
*
* @return bool
*/
protected function setProperty($name, $type = null, $read = null, $write = null, $comment='')
protected function isRelationNullable(string $relation, Relation $relationObj): bool
{
$reflectionObj = new \ReflectionObject($relationObj);
if (in_array($relation, ['hasOne', 'hasOneThrough', 'morphOne'], true)) {
$defaultProp = $reflectionObj->getProperty('withDefault');
$defaultProp->setAccessible(true);
return !$defaultProp->getValue($relationObj);
}
if (!$reflectionObj->hasProperty('foreignKey')) {
return false;
}
$fkProp = $reflectionObj->getProperty('foreignKey');
$fkProp->setAccessible(true);
return isset($this->nullableColumns[$fkProp->getValue($relationObj)]);
}
/**
* @param string $name
* @param string|null $type
* @param bool|null $read
* @param bool|null $write
* @param string|null $comment
* @param bool $nullable
*/
protected function setProperty($name, $type = null, $read = null, $write = null, $comment = '', $nullable = false)
{
if (!isset($this->properties[$name])) {
$this->properties[$name] = array();
@@ -373,7 +634,11 @@ class ModelsCommand extends Command
$this->properties[$name]['comment'] = (string) $comment;
}
if ($type !== null) {
$this->properties[$name]['type'] = $type;
$newType = $this->getTypeOverride($type);
if ($nullable) {
$newType .='|null';
}
$this->properties[$name]['type'] = $newType;
}
if ($read !== null) {
$this->properties[$name]['read'] = $read;
@@ -385,7 +650,9 @@ class ModelsCommand extends Command
protected function setMethod($name, $type = '', $arguments = array())
{
if (!isset($this->methods[$name])) {
$methods = array_change_key_case($this->methods, CASE_LOWER);
if (!isset($methods[strtolower($name)])) {
$this->methods[$name] = array();
$this->methods[$name]['type'] = $type;
$this->methods[$name]['arguments'] = $arguments;
@@ -399,13 +666,23 @@ class ModelsCommand extends Command
protected function createPhpDocs($class)
{
$reflection = new \ReflectionClass($class);
$reflection = new ReflectionClass($class);
$namespace = $reflection->getNamespaceName();
$classname = $reflection->getShortName();
$originalDoc = $reflection->getDocComment();
$keyword = $this->getClassKeyword($reflection);
$interfaceNames = array_diff_key(
$reflection->getInterfaceNames(),
$reflection->getParentClass()->getInterfaceNames()
);
if ($this->reset) {
$phpdoc = new DocBlock('', new Context($namespace));
if ($this->keep_text) {
$phpdoc->setText(
(new DocBlock($reflection, new Context($namespace)))->getText()
);
}
} else {
$phpdoc = new DocBlock($reflection, new Context($namespace));
}
@@ -427,6 +704,11 @@ class ModelsCommand extends Command
foreach ($this->properties as $name => $property) {
$name = "\$$name";
if ($this->hasCamelCaseModelProperties()) {
$name = Str::camel($name);
}
if (in_array($name, $properties)) {
continue;
}
@@ -437,10 +719,14 @@ class ModelsCommand extends Command
} else {
$attr = 'property-read';
}
$tag = Tag::createInstance("@{$attr} {$property['type']} {$name} {$property['comment']}", $phpdoc);
$tagLine = trim("@{$attr} {$property['type']} {$name} {$property['comment']}");
$tag = Tag::createInstance($tagLine, $phpdoc);
$phpdoc->appendTag($tag);
}
ksort($this->methods);
foreach ($this->methods as $name => $method) {
if (in_array($name, $methods)) {
continue;
@@ -450,6 +736,24 @@ class ModelsCommand extends Command
$phpdoc->appendTag($tag);
}
if ($this->write && ! $phpdoc->getTagsByName('mixin')) {
$phpdoc->appendTag(Tag::createInstance("@mixin \\Eloquent", $phpdoc));
}
if ($this->phpstorm_noinspections) {
/**
* Facades, Eloquent API
* @see https://www.jetbrains.com/help/phpstorm/php-fully-qualified-name-usage.html
*/
$phpdoc->appendTag(Tag::createInstance("@noinspection PhpFullyQualifiedNameUsageInspection", $phpdoc));
/**
* Relations, other models in the same namespace
* @see https://www.jetbrains.com/help/phpstorm/php-unnecessary-fully-qualified-name.html
*/
$phpdoc->appendTag(
Tag::createInstance("@noinspection PhpUnnecessaryFullyQualifiedNameInspection", $phpdoc)
);
}
$serializer = new DocBlockSerializer();
$serializer->getDocComment($phpdoc);
$docComment = $serializer->getDocComment($phpdoc);
@@ -457,7 +761,7 @@ class ModelsCommand extends Command
if ($this->write) {
$filename = $reflection->getFileName();
$contents = \File::get($filename);
$contents = $this->files->get($filename);
if ($originalDoc) {
$contents = str_replace($originalDoc, $docComment, $contents);
} else {
@@ -468,13 +772,19 @@ class ModelsCommand extends Command
$contents = substr_replace($contents, $replace, $pos, strlen($needle));
}
}
if (\File::put($filename, $contents)) {
if ($this->files->put($filename, $contents)) {
$this->info('Written new phpDocBlock to ' . $filename);
}
}
$output = "namespace {$namespace}{\n{$docComment}\n\tclass {$classname} {}\n}\n\n";
return $output;
$output = "namespace {$namespace}{\n{$docComment}\n\t{$keyword}class {$classname} extends \Eloquent ";
if ($interfaceNames) {
$interfaces = implode(', \\', $interfaceNames);
$output .= "implements \\{$interfaces} ";
}
return $output . "{}\n}\n\n";
}
/**
@@ -488,15 +798,17 @@ class ModelsCommand extends Command
//Loop through the default values for paremeters, and make the correct output string
$params = array();
$paramsWithDefault = array();
/** @var \ReflectionParameter $param */
foreach ($method->getParameters() as $param) {
$paramStr = '$' . $param->getName();
$paramClass = $param->getClass();
$paramStr = (!is_null($paramClass) ? '\\' . $paramClass->getName() . ' ' : '') . '$' . $param->getName();
$params[] = $paramStr;
if ($param->isOptional()) {
if ($param->isOptional() && $param->isDefaultValueAvailable()) {
$default = $param->getDefaultValue();
if (is_bool($default)) {
$default = $default ? 'true' : 'false';
} elseif (is_array($default)) {
$default = 'array()';
$default = '[]';
} elseif (is_null($default)) {
$default = 'null';
} elseif (is_int($default)) {
@@ -512,23 +824,155 @@ class ModelsCommand extends Command
}
/**
* Determine a model classes' collection type.
*
* @see http://laravel.com/docs/eloquent-collections#custom-collections
* @param string $className
* @param \Illuminate\Database\Eloquent\Model $model
* @return string
*/
private function getClassName($className, $model)
protected function getCollectionClass($className)
{
// If the class name was resolved via get_class($this) or static::class
if (strpos($className, 'get_class($this)') !== false || strpos($className, 'static::class') !== false) {
return get_class($model);
// Return something in the very very unlikely scenario the model doesn't
// have a newCollection() method.
if (!method_exists($className, 'newCollection')) {
return '\Illuminate\Database\Eloquent\Collection';
}
// If the class name was resolved via ::class (PHP 5.5+)
if (strpos($className, '::class') !== false) {
$end = -1 * strlen('::class');
return substr($className, 0, $end);
/** @var \Illuminate\Database\Eloquent\Model $model */
$model = new $className;
return '\\' . get_class($model->newCollection());
}
/**
* @return bool
*/
protected function hasCamelCaseModelProperties()
{
return $this->laravel['config']->get('ide-helper.model_camel_case_properties', false);
}
protected function getReturnType(\ReflectionMethod $reflection): ?string
{
$type = $this->getReturnTypeFromDocBlock($reflection);
if ($type) {
return $type;
}
return "\\" . ltrim(trim($className, " \"'"), "\\") ;
return $this->getReturnTypeFromReflection($reflection);
}
/**
* Get method return type based on it DocBlock comment
*
* @param \ReflectionMethod $reflection
*
* @return null|string
*/
protected function getReturnTypeFromDocBlock(\ReflectionMethod $reflection)
{
$type = null;
$phpdoc = new DocBlock($reflection);
if ($phpdoc->hasTag('return')) {
$type = $phpdoc->getTagsByName('return')[0]->getType();
}
return $type;
}
protected function getReturnTypeFromReflection(\ReflectionMethod $reflection): ?string
{
$returnType = $reflection->getReturnType();
if (!$returnType) {
return null;
}
$type = $returnType instanceof \ReflectionNamedType
? $returnType->getName()
: (string)$returnType;
if (!$returnType->isBuiltin()) {
$type = '\\' . $type;
}
if ($returnType->allowsNull()) {
$type .= '|null';
}
return $type;
}
/**
* Generates methods provided by the SoftDeletes trait
* @param \Illuminate\Database\Eloquent\Model $model
*/
protected function getSoftDeleteMethods($model)
{
$traits = class_uses(get_class($model), true);
if (in_array('Illuminate\\Database\\Eloquent\\SoftDeletes', $traits)) {
$this->setMethod('withTrashed', '\Illuminate\Database\Query\Builder|\\' . get_class($model), []);
$this->setMethod('withoutTrashed', '\Illuminate\Database\Query\Builder|\\' . get_class($model), []);
$this->setMethod('onlyTrashed', '\Illuminate\Database\Query\Builder|\\' . get_class($model), []);
}
}
/**
* Generates methods that return collections
* @param \Illuminate\Database\Eloquent\Model $model
*/
protected function getCollectionMethods($model)
{
$collectionClass = $this->getCollectionClass(get_class($model));
if ($collectionClass !== '\\' . \Illuminate\Database\Eloquent\Collection::class) {
$this->setMethod('get', $collectionClass . '|static[]', ['$columns = [\'*\']']);
$this->setMethod('all', $collectionClass . '|static[]', ['$columns = [\'*\']']);
}
}
/**
* @param ReflectionClass $reflection
* @return string
*/
protected function getClassKeyword(ReflectionClass $reflection)
{
if ($reflection->isFinal()) {
$keyword = 'final ';
} elseif ($reflection->isAbstract()) {
$keyword = 'abstract ';
} else {
$keyword = '';
}
return $keyword;
}
/**
* @param string $type
* @return string|null
* @throws \ReflectionException
*/
protected function checkForCustomLaravelCasts(string $type): ?string
{
if (!class_exists($type) || !interface_exists(CastsAttributes::class)) {
return $type;
}
$reflection = new \ReflectionClass($type);
if (!$reflection->implementsInterface(CastsAttributes::class)) {
return $type;
}
$methodReflection = new \ReflectionMethod($type, 'get');
$type = $this->getReturnTypeFromReflection($methodReflection);
if ($type === null) {
$type = $this->getReturnTypeFromDocBlock($methodReflection);
}
return $type;
}
}
+108
View File
@@ -0,0 +1,108 @@
<?php
/**
* Laravel IDE Helper to add \Eloquent mixin to Eloquent\Model
*
* @author Charles A. Peterson <[email protected]>
*/
namespace Barryvdh\LaravelIdeHelper;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Barryvdh\Reflection\DocBlock;
use Barryvdh\Reflection\DocBlock\Context;
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
use Barryvdh\Reflection\DocBlock\Tag;
class Eloquent
{
/**
* Write mixin helper to the Eloquent\Model
* This is needed since laravel/framework v5.4.29
*
* @param Command $command
* @param Filesystem $files
*
* @return void
*/
public static function writeEloquentModelHelper(Command $command, Filesystem $files)
{
$class = 'Illuminate\Database\Eloquent\Model';
$reflection = new \ReflectionClass($class);
$namespace = $reflection->getNamespaceName();
$originalDoc = $reflection->getDocComment();
if (!$originalDoc) {
$command->info('Unexpected no document on ' . $class);
}
$phpdoc = new DocBlock($reflection, new Context($namespace));
$mixins = $phpdoc->getTagsByName('mixin');
$expectedMixins = [
'\Eloquent' => false,
'\Illuminate\Database\Eloquent\Builder' => false,
'\Illuminate\Database\Query\Builder' => false,
];
foreach ($mixins as $m) {
$mixin = $m->getContent();
if (isset($expectedMixins[$mixin])) {
$command->info('Tag Exists: @mixin ' . $mixin . ' in ' . $class);
$expectedMixins[$mixin] = true;
}
}
$changed = false;
foreach ($expectedMixins as $expectedMixin => $present) {
if ($present === false) {
$phpdoc->appendTag(Tag::createInstance('@mixin ' . $expectedMixin, $phpdoc));
$changed = true;
}
}
// If nothing's changed, stop here.
if (!$changed) {
return;
}
$serializer = new DocBlockSerializer();
$serializer->getDocComment($phpdoc);
$docComment = $serializer->getDocComment($phpdoc);
/*
The new DocBlock is appended to the beginning of the class declaration.
Since there is no DocBlock, the declaration is used as a guide.
*/
if (!$originalDoc) {
$originalDoc = 'abstract class Model implements';
$docComment .= "\nabstract class Model implements";
}
$filename = $reflection->getFileName();
if ($filename) {
$contents = $files->get($filename);
if ($contents) {
$count = 0;
$contents = str_replace($originalDoc, $docComment, $contents, $count);
if ($count > 0) {
if ($files->put($filename, $contents)) {
$command->info('Wrote expected docblock to ' . $filename);
} else {
$command->error('File write failed to ' . $filename);
}
} else {
$command->error('Content did not change ' . $contents);
}
} else {
$command->error('No file contents found ' . $filename);
}
} else {
$command->error('Filename not found ' . $class);
}
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace Barryvdh\LaravelIdeHelper;
use Exception;
use Illuminate\Database\Eloquent\Factory;
use ReflectionClass;
class Factories
{
public static function all()
{
$factories = [];
$factory = app(Factory::class);
$definitions = (new ReflectionClass(Factory::class))->getProperty('definitions');
$definitions->setAccessible(true);
foreach ($definitions->getValue($factory) as $factory_target => $config) {
try {
$factories[] = new ReflectionClass($factory_target);
} catch (Exception $exception) {
}
}
return $factories;
}
}
+329 -241
View File
@@ -1,241 +1,329 @@
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Config\Repository as ConfigRepository;
use Symfony\Component\Console\Output\OutputInterface;
class Generator
{
/** @var \Illuminate\Config\Repository */
protected $config;
/** @var \Illuminate\View\Factory */
protected $view;
/** @var \Symfony\Component\Console\Output\OutputInterface */
protected $output;
protected $extra = array();
protected $magic = array();
protected $interfaces = array();
protected $helpers;
/**
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\View\Factory $view
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @param string $helpers
*/
public function __construct(/*ConfigRepository */ $config,
/* Illuminate\View\Factory */ $view,
OutputInterface $output = null,
$helpers = ''
) {
$this->config = $config;
$this->view = $view;
// Find the drivers to add to the extra/interfaces
$this->detectDrivers();
$this->extra = array_merge($this->extra, $this->config->get('ide-helper.extra'));
$this->magic = array_merge($this->magic, $this->config->get('ide-helper.magic'));
$this->interfaces = array_merge($this->interfaces, $this->config->get('ide-helper.interfaces'));
// Make all interface classes absolute
foreach ($this->interfaces as &$interface) {
$interface = '\\' . ltrim($interface, '\\');
}
$this->helpers = $helpers;
}
/**
* Generate the helper file contents;
*
* @param string $format The format to generate the helper in (php/json)
* @return string;
*/
public function generate($format = 'php')
{
// Check if the generator for this format exists
$method = 'generate'.ucfirst($format).'Helper';
if (method_exists($this, $method)) {
return $this->$method();
}
return $this->generatePhpHelper();
}
public function generatePhpHelper()
{
$app = app();
return $this->view->make('ide-helper::helper')
->with('namespaces', $this->getNamespaces())
->with('helpers', $this->helpers)
->with('version', $app::VERSION)
->render();
}
public function generateJsonHelper()
{
$classes = array();
foreach ($this->getNamespaces() as $aliases) {
foreach($aliases as $alias) {
$functions = array();
foreach ($alias->getMethods() as $method) {
$functions[$method->getName()] = '('. $method->getParamsWithDefault().')';
}
$classes[$alias->getAlias()] = array(
'functions' => $functions,
);
}
}
$flags = JSON_FORCE_OBJECT;
if (defined('JSON_PRETTY_PRINT')) {
$flags |= JSON_PRETTY_PRINT;
}
return json_encode(array(
'php' => array(
'classes' => $classes,
),
), $flags);
}
protected function detectDrivers()
{
try{
if (class_exists('Auth') && is_a('Auth', '\Illuminate\Support\Facades\Auth', true)) {
$class = get_class(\Auth::driver());
$this->extra['Auth'] = array($class);
$this->interfaces['\Illuminate\Auth\UserProviderInterface'] = $class;
}
}catch (\Exception $e) {}
try{
if (class_exists('DB') && is_a('DB', '\Illuminate\Support\Facades\DB', true)) {
$class = get_class(\DB::connection());
$this->extra['DB'] = array($class);
$this->interfaces['\Illuminate\Database\ConnectionInterface'] = $class;
}
}catch (\Exception $e) {}
try{
if (class_exists('Cache') && is_a('Cache', '\Illuminate\Support\Facades\Cache', true)) {
$driver = get_class(\Cache::driver());
$store = get_class(\Cache::getStore());
$this->extra['Cache'] = array($driver, $store);
$this->interfaces['\Illuminate\Cache\StoreInterface'] = $store;
}
}catch (\Exception $e) {}
try{
if (class_exists('Queue') && is_a('Queue', '\Illuminate\Support\Facades\Queue', true)) {
$class = get_class(\Queue::connection());
$this->extra['Queue'] = array($class);
$this->interfaces['\Illuminate\Queue\QueueInterface'] = $class;
}
}catch (\Exception $e) {}
try{
if (class_exists('SSH') && is_a('SSH', '\Illuminate\Support\Facades\SSH', true)){
$class = get_class(\SSH::connection());
$this->extra['SSH'] = array($class);
$this->interfaces['\Illuminate\Remote\ConnectionInterface'] = $class;
}
}catch (\Exception $e) {}
}
/**
* Find all namespaces/aliases that are valid for us to render
*
* @return array
*/
protected function getNamespaces()
{
$namespaces = array();
// Get all aliases
foreach (AliasLoader::getInstance()->getAliases() as $name => $facade) {
// Skip the Redis facade, if not available (otherwise Fatal PHP Error)
if ($facade == 'Illuminate\Support\Facades\Redis' && !class_exists('Predis\Client')) {
continue;
}
$magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array();
$alias = new Alias($name, $facade, $magicMethods, $this->interfaces);
if ($alias->isValid()) {
//Add extra methods, from other classes (magic static calls)
if (array_key_exists($name, $this->extra)) {
$alias->addClass($this->extra[$name]);
}
$namespace = $alias->getNamespace();
if (!isset($namespaces[$namespace])) {
$namespaces[$namespace] = array();
}
$namespaces[$namespace][] = $alias;
}
}
return $namespaces;
}
/**
* Get the driver/connection/store from the managers
*
* @param $alias
* @return array|bool|string
*/
public function getDriver($alias)
{
try {
if ($alias == "Auth") {
$driver = \Auth::driver();
} elseif ($alias == "DB") {
$driver = \DB::connection();
} elseif ($alias == "Cache") {
$driver = get_class(\Cache::driver());
$store = get_class(\Cache::getStore());
return array($driver, $store);
} elseif ($alias == "Queue") {
$driver = \Queue::connection();
} else {
return false;
}
return get_class($driver);
} catch (\Exception $e) {
$this->error("Could not determine driver/connection for $alias.");
return false;
}
}
/**
* Write a string as error output.
*
* @param string $string
* @return void
*/
protected function error($string)
{
if($this->output){
$this->output->writeln("<error>$string</error>");
}else{
echo $string . "\r\n";
}
}
}
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\Collection;
use ReflectionClass;
use Symfony\Component\Console\Output\OutputInterface;
class Generator
{
/** @var \Illuminate\Config\Repository */
protected $config;
/** @var \Illuminate\View\Factory */
protected $view;
/** @var \Symfony\Component\Console\Output\OutputInterface */
protected $output;
protected $extra = array();
protected $magic = array();
protected $interfaces = array();
protected $helpers;
/**
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\View\Factory $view
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @param string $helpers
*/
public function __construct(
/*ConfigRepository */ $config,
/* Illuminate\View\Factory */ $view,
OutputInterface $output = null,
$helpers = ''
) {
$this->config = $config;
$this->view = $view;
// Find the drivers to add to the extra/interfaces
$this->detectDrivers();
$this->extra = array_merge($this->extra, $this->config->get('ide-helper.extra'));
$this->magic = array_merge($this->magic, $this->config->get('ide-helper.magic'));
$this->interfaces = array_merge($this->interfaces, $this->config->get('ide-helper.interfaces'));
// Make all interface classes absolute
foreach ($this->interfaces as &$interface) {
$interface = '\\' . ltrim($interface, '\\');
}
$this->helpers = $helpers;
}
/**
* Generate the helper file contents;
*
* @param string $format The format to generate the helper in (php/json)
* @return string;
*/
public function generate($format = 'php')
{
// Check if the generator for this format exists
$method = 'generate'.ucfirst($format).'Helper';
if (method_exists($this, $method)) {
return $this->$method();
}
return $this->generatePhpHelper();
}
public function generatePhpHelper()
{
$app = app();
return $this->view->make('helper')
->with('namespaces_by_extends_ns', $this->getAliasesByExtendsNamespace())
->with('namespaces_by_alias_ns', $this->getAliasesByAliasNamespace())
->with('helpers', $this->helpers)
->with('version', $app->version())
->with('include_fluent', $this->config->get('ide-helper.include_fluent', true))
->with('factories', $this->config->get('ide-helper.include_factory_builders') ? Factories::all() : [])
->render();
}
public function generateJsonHelper()
{
$classes = array();
foreach ($this->getValidAliases() as $aliases) {
foreach ($aliases as $alias) {
$functions = array();
foreach ($alias->getMethods() as $method) {
$functions[$method->getName()] = '('. $method->getParamsWithDefault().')';
}
$classes[$alias->getAlias()] = array(
'functions' => $functions,
);
}
}
$flags = JSON_FORCE_OBJECT;
if (defined('JSON_PRETTY_PRINT')) {
$flags |= JSON_PRETTY_PRINT;
}
return json_encode(array(
'php' => array(
'classes' => $classes,
),
), $flags);
}
protected function detectDrivers()
{
$defaultUserModel = config('auth.providers.users.model', config('auth.model', 'App\User'));
$this->interfaces['\Illuminate\Contracts\Auth\Authenticatable'] = $defaultUserModel;
try {
if (class_exists('Auth') && is_a('Auth', '\Illuminate\Support\Facades\Auth', true)) {
if (class_exists('\Illuminate\Foundation\Application')) {
$authMethod = version_compare(Application::VERSION, '5.2', '>=') ? 'guard' : 'driver';
} else {
$refClass = new ReflectionClass('\Laravel\Lumen\Application');
$versionStr = $refClass->newInstanceWithoutConstructor()->version();
$authMethod = strpos($versionStr, 'Lumen (5.0') === 0 ?
'driver' :
(strpos($versionStr, 'Lumen (5.1') === 0 ? 'driver' : 'guard');
}
$class = get_class(\Auth::$authMethod());
$this->extra['Auth'] = array($class);
$this->interfaces['\Illuminate\Auth\UserProviderInterface'] = $class;
}
} catch (\Exception $e) {
}
try {
if (class_exists('DB') && is_a('DB', '\Illuminate\Support\Facades\DB', true)) {
$class = get_class(\DB::connection());
$this->extra['DB'] = array($class);
$this->interfaces['\Illuminate\Database\ConnectionInterface'] = $class;
}
} catch (\Exception $e) {
}
try {
if (class_exists('Cache') && is_a('Cache', '\Illuminate\Support\Facades\Cache', true)) {
$driver = get_class(\Cache::driver());
$store = get_class(\Cache::getStore());
$this->extra['Cache'] = array($driver, $store);
$this->interfaces['\Illuminate\Cache\StoreInterface'] = $store;
}
} catch (\Exception $e) {
}
try {
if (class_exists('Queue') && is_a('Queue', '\Illuminate\Support\Facades\Queue', true)) {
$class = get_class(\Queue::connection());
$this->extra['Queue'] = array($class);
$this->interfaces['\Illuminate\Queue\QueueInterface'] = $class;
}
} catch (\Exception $e) {
}
try {
if (class_exists('SSH') && is_a('SSH', '\Illuminate\Support\Facades\SSH', true)) {
$class = get_class(\SSH::connection());
$this->extra['SSH'] = array($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());
$this->extra['Storage'] = array($class);
$this->interfaces['\Illuminate\Contracts\Filesystem\Filesystem'] = $class;
}
} catch (\Exception $e) {
}
}
/**
* Find all aliases that are valid for us to render
*
* @return Collection
*/
protected function getValidAliases()
{
$aliases = new Collection();
// Get all aliases
foreach ($this->getAliases() as $name => $facade) {
// Skip the Redis facade, if not available (otherwise Fatal PHP Error)
if ($facade == 'Illuminate\Support\Facades\Redis' && $name == 'Redis' && !class_exists('Predis\Client')) {
continue;
}
$magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array();
$alias = new Alias($this->config, $name, $facade, $magicMethods, $this->interfaces);
if ($alias->isValid()) {
//Add extra methods, from other classes (magic static calls)
if (array_key_exists($name, $this->extra)) {
$alias->addClass($this->extra[$name]);
}
$aliases[] = $alias;
}
}
return $aliases;
}
/**
* Regroup aliases by namespace of extended classes
*
* @return Collection
*/
protected function getAliasesByExtendsNamespace()
{
return $this->getValidAliases()->groupBy(function (Alias $alias) {
return $alias->getExtendsNamespace();
});
}
/**
* Regroup aliases by namespace of alias
*
* @return Collection
*/
protected function getAliasesByAliasNamespace()
{
return $this->getValidAliases()->groupBy(function (Alias $alias) {
return $alias->getNamespace();
});
}
protected function getAliases()
{
// For Laravel, use the AliasLoader
if (class_exists('Illuminate\Foundation\AliasLoader')) {
return AliasLoader::getInstance()->getAliases();
}
$facades = [
'App' => 'Illuminate\Support\Facades\App',
'Auth' => 'Illuminate\Support\Facades\Auth',
'Bus' => 'Illuminate\Support\Facades\Bus',
'DB' => 'Illuminate\Support\Facades\DB',
'Cache' => 'Illuminate\Support\Facades\Cache',
'Cookie' => 'Illuminate\Support\Facades\Cookie',
'Crypt' => 'Illuminate\Support\Facades\Crypt',
'Event' => 'Illuminate\Support\Facades\Event',
'Hash' => 'Illuminate\Support\Facades\Hash',
'Log' => 'Illuminate\Support\Facades\Log',
'Mail' => 'Illuminate\Support\Facades\Mail',
'Queue' => 'Illuminate\Support\Facades\Queue',
'Request' => 'Illuminate\Support\Facades\Request',
'Schema' => 'Illuminate\Support\Facades\Schema',
'Session' => 'Illuminate\Support\Facades\Session',
'Storage' => 'Illuminate\Support\Facades\Storage',
'Validator' => 'Illuminate\Support\Facades\Validator',
'Gate' => 'Illuminate\Support\Facades\Gate',
];
$facades = array_merge($facades, $this->config->get('app.aliases', []));
// Only return the ones that actually exist
return array_filter(
$facades,
function ($alias) {
return class_exists($alias);
},
ARRAY_FILTER_USE_KEY
);
}
/**
* Get the driver/connection/store from the managers
*
* @param $alias
* @return array|bool|string
*/
public function getDriver($alias)
{
try {
if ($alias == "Auth") {
$driver = \Auth::driver();
} elseif ($alias == "DB") {
$driver = \DB::connection();
} elseif ($alias == "Cache") {
$driver = get_class(\Cache::driver());
$store = get_class(\Cache::getStore());
return array($driver, $store);
} elseif ($alias == "Queue") {
$driver = \Queue::connection();
} else {
return false;
}
return get_class($driver);
} catch (\Exception $e) {
$this->error("Could not determine driver/connection for $alias.");
return false;
}
}
/**
* Write a string as error output.
*
* @param string $string
* @return void
*/
protected function error($string)
{
if ($this->output) {
$this->output->writeln("<error>$string</error>");
} else {
echo $string . "\r\n";
}
}
}
+61 -18
View File
@@ -10,10 +10,15 @@
namespace Barryvdh\LaravelIdeHelper;
use Illuminate\Support\ServiceProvider;
use Barryvdh\LaravelIdeHelper\Console\EloquentCommand;
use Barryvdh\LaravelIdeHelper\Console\GeneratorCommand;
use Barryvdh\LaravelIdeHelper\Console\MetaCommand;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Console\GeneratorCommand;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\Engines\EngineResolver;
use Illuminate\View\Engines\PhpEngine;
use Illuminate\View\Factory;
use Illuminate\View\FileViewFinder;
class IdeHelperServiceProvider extends ServiceProvider
{
@@ -32,11 +37,18 @@ class IdeHelperServiceProvider extends ServiceProvider
*/
public function boot()
{
$viewPath = __DIR__.'/../resources/views';
$this->loadViewsFrom($viewPath, 'ide-helper');
if ($this->app->has('view')) {
$viewPath = __DIR__ . '/../resources/views';
$this->loadViewsFrom($viewPath, 'ide-helper');
}
$configPath = __DIR__ . '/../config/ide-helper.php';
$this->publishes([$configPath => config_path('ide-helper.php')], 'config');
if (function_exists('config_path')) {
$publishPath = config_path('ide-helper.php');
} else {
$publishPath = base_path('config/ide-helper.php');
}
$this->publishes([$configPath => $publishPath], 'config');
}
/**
@@ -48,26 +60,42 @@ class IdeHelperServiceProvider extends ServiceProvider
{
$configPath = __DIR__ . '/../config/ide-helper.php';
$this->mergeConfigFrom($configPath, 'ide-helper');
$this->app['command.ide-helper.generate'] = $this->app->share(
$localViewFactory = $this->createLocalViewFactory();
$this->app->singleton(
'command.ide-helper.generate',
function ($app) use ($localViewFactory) {
return new GeneratorCommand($app['config'], $app['files'], $localViewFactory);
}
);
$this->app->singleton(
'command.ide-helper.models',
function ($app) {
return new GeneratorCommand($app['config'], $app['files'], $app['view']);
return new ModelsCommand($app['files']);
}
);
$this->app['command.ide-helper.models'] = $this->app->share(
function () {
return new ModelsCommand();
$this->app->singleton(
'command.ide-helper.meta',
function ($app) use ($localViewFactory) {
return new MetaCommand($app['files'], $localViewFactory, $app['config']);
}
);
$this->app['command.ide-helper.meta'] = $this->app->share(
function ($app) {
return new MetaCommand($app['files'], $app['view']);
}
$this->app->singleton(
'command.ide-helper.eloquent',
function ($app) use ($localViewFactory) {
return new EloquentCommand($app['files']);
}
);
$this->commands('command.ide-helper.generate', 'command.ide-helper.models', 'command.ide-helper.meta');
$this->commands(
'command.ide-helper.generate',
'command.ide-helper.models',
'command.ide-helper.meta',
'command.ide-helper.eloquent'
);
}
/**
@@ -80,4 +108,19 @@ class IdeHelperServiceProvider extends ServiceProvider
return array('command.ide-helper.generate', 'command.ide-helper.models');
}
/**
* @return Factory
*/
private function createLocalViewFactory()
{
$resolver = new EngineResolver();
$resolver->register('php', function () {
return new PhpEngine();
});
$finder = new FileViewFinder($this->app['files'], [__DIR__ . '/../resources/views']);
$factory = new Factory($resolver, $finder, $this->app['events']);
$factory->addExtension('php', 'php');
return $factory;
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace Barryvdh\LaravelIdeHelper;
use Barryvdh\Reflection\DocBlock;
use Barryvdh\Reflection\DocBlock\Tag;
class Macro extends Method
{
/**
* Macro constructor.
*
* @param \ReflectionFunctionAbstract $method
* @param string $alias
* @param \ReflectionClass $class
* @param null $methodName
* @param array $interfaces
*/
public function __construct(
$method,
$alias,
$class,
$methodName = null,
$interfaces = array()
) {
parent::__construct($method, $alias, $class, $methodName, $interfaces);
}
/**
* @param \ReflectionFunctionAbstract $method
*/
protected function initPhpDoc($method)
{
$this->phpdoc = new DocBlock($method);
}
/**
* @param \ReflectionFunctionAbstract $method
* @param \ReflectionClass $class
*/
protected function initClassDefinedProperties($method, \ReflectionClass $class)
{
$this->namespace = $class->getNamespaceName();
$this->declaringClassName = '\\' . ltrim($class->name, '\\');
}
}
+369 -311
View File
@@ -1,311 +1,369 @@
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Context;
use phpDocumentor\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
use phpDocumentor\Reflection\DocBlock\Tag\ParamTag;
use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer;
class Method
{
/** @var \phpDocumentor\Reflection\DocBlock */
protected $phpdoc;
/** @var \ReflectionMethod */
protected $method;
protected $output = '';
protected $name;
protected $namespace;
protected $params = array();
protected $params_with_default = array();
protected $interfaces = array();
protected $return = null;
/**
* @param \ReflectionMethod $method
* @param string $alias
* @param string $class
* @param string|null $methodName
* @param array $interfaces
*/
public function __construct(\ReflectionMethod $method, $alias, $class, $methodName = null, $interfaces = array())
{
$this->method = $method;
$this->interfaces = $interfaces;
$this->name = $methodName ?: $method->name;
$this->namespace = $method->getDeclaringClass()->getNamespaceName();
//Create a DocBlock and serializer instance
$this->phpdoc = new DocBlock($method, new Context($this->namespace));
//Normalize the description and inherit the docs from parents/interfaces
try {
$this->normalizeParams($this->phpdoc);
$this->normalizeReturn($this->phpdoc);
$this->normalizeDescription($this->phpdoc);
} catch (\Exception $e) {}
//Get the parameters, including formatted default values
$this->getParameters($method);
//Make the method static
$this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc));
//Reference the 'real' function in the declaringclass
$declaringClass = $method->getDeclaringClass();
$this->declaringClassName = '\\' . ltrim($declaringClass->name, '\\');
$this->root = '\\' . ltrim($class->getName(), '\\');
}
/**
* Get the class wherein the function resides
*
* @return string
*/
public function getDeclaringClass()
{
return $this->declaringClassName;
}
/**
* Return the class from which this function would be called
*
* @return string
*/
public function getRoot()
{
return $this->root;
}
/**
* Get the docblock for this method
*
* @param string $prefix
* @return mixed
*/
public function getDocComment($prefix = "\t\t")
{
$serializer = new DocBlockSerializer(1, $prefix);
return $serializer->getDocComment($this->phpdoc);
}
/**
* Get the method name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Get the parameters for this method
*
* @param bool $implode Wether to implode the array or not
* @return string
*/
public function getParams($implode = true)
{
return $implode ? implode(', ', $this->params) : $this->params;
}
/**
* Get the parameters for this method including default values
*
* @param bool $implode Wether to implode the array or not
* @return string
*/
public function getParamsWithDefault($implode = true)
{
return $implode ? implode(', ', $this->params_with_default) : $this->params_with_default;
}
/**
* Get the description and get the inherited docs.
*
* @param DocBlock $phpdoc
*/
protected function normalizeDescription(DocBlock $phpdoc)
{
//Get the short + long description from the DocBlock
$description = $phpdoc->getText();
//Loop through parents/interfaces, to fill in {@inheritdoc}
if (strpos($description, '{@inheritdoc}') !== false) {
$inheritdoc = $this->getInheritDoc($this->method);
$inheritDescription = $inheritdoc->getText();
$description = str_replace('{@inheritdoc}', $inheritDescription, $description);
$phpdoc->setText($description);
$this->normalizeParams($inheritdoc);
$this->normalizeReturn($inheritdoc);
//Add the tags that are inherited
$inheritTags = $inheritdoc->getTags();
if ($inheritTags) {
/** @var Tag $tag */
foreach ($inheritTags as $tag) {
$tag->setDocBlock();
$phpdoc->appendTag($tag);
}
}
}
}
/**
* Normalize the parameters
*
* @param DocBlock $phpdoc
*/
protected function normalizeParams(DocBlock $phpdoc)
{
//Get the return type and adjust them for beter autocomplete
$paramTags = $phpdoc->getTagsByName('param');
if ($paramTags) {
/** @var ParamTag $tag */
foreach($paramTags as $tag){
// Convert the keywords
$content = $this->convertKeywords($tag->getContent());
$tag->setContent($content);
// Get the expanded type and re-set the content
$content = $tag->getType() . ' ' . $tag->getVariableName() . ' ' . $tag->getDescription();
$tag->setContent(trim($content));
}
}
}
/**
* Normalize the return tag (make full namespace, replace interfaces)
*
* @param DocBlock $phpdoc
*/
protected function normalizeReturn(DocBlock $phpdoc)
{
//Get the return type and adjust them for beter autocomplete
$returnTags = $phpdoc->getTagsByName('return');
if ($returnTags) {
/** @var ReturnTag $tag */
$tag = reset($returnTags);
// Get the expanded type
$returnValue = $tag->getType();
// Replace the interfaces
foreach($this->interfaces as $interface => $real){
$returnValue = str_replace($interface, $real, $returnValue);
}
// Set the changed content
$tag->setContent($returnValue . ' ' . $tag->getDescription());
$this->return = $returnValue;
}else{
$this->return = null;
}
}
/**
* Convert keywwords that are incorrect.
*
* @param string $string
* @return string
*/
protected function convertKeywords($string)
{
$string = str_replace('\Closure', 'Closure', $string);
$string = str_replace('Closure', '\Closure', $string);
$string = str_replace('dynamic', 'mixed', $string);
return $string;
}
/**
* Should the function return a value?
*
* @return bool
*/
public function shouldReturn()
{
if($this->return !== "void" && $this->method->name !== "__construct"){
return true;
}
return false;
}
/**
* Get the parameters and format them correctly
*
* @param $method
* @return array
*/
public function getParameters($method)
{
//Loop through the default values for paremeters, and make the correct output string
$params = array();
$paramsWithDefault = array();
foreach ($method->getParameters() as $param) {
$paramStr = '$' . $param->getName();
$params[] = $paramStr;
if ($param->isOptional()) {
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
if (is_bool($default)) {
$default = $default ? 'true' : 'false';
} elseif (is_array($default)) {
$default = 'array()';
} elseif (is_null($default)) {
$default = 'null';
} elseif (is_int($default)) {
//$default = $default;
} else {
$default = "'" . trim($default) . "'";
}
$paramStr .= " = $default";
}
$paramsWithDefault[] = $paramStr;
}
$this->params = $params;
$this->params_with_default = $paramsWithDefault;
}
/**
* @param \ReflectionMethod $reflectionMethod
* @return DocBlock
*/
protected function getInheritDoc($reflectionMethod)
{
$parentClass = $reflectionMethod->getDeclaringClass()->getParentClass();
//Get either a parent or the interface
if ($parentClass) {
$method = $parentClass->getMethod($reflectionMethod->getName());
} else {
$method = $reflectionMethod->getPrototype();
}
if ($method) {
$namespace = $method->getDeclaringClass()->getNamespaceName();
$phpdoc = new DocBlock($method, new Context($namespace));
if (strpos($phpdoc->getText(), '{@inheritdoc}') !== false) {
//Not at the end yet, try another parent/interface..
return $this->getInheritDoc($method);
} else {
return $phpdoc;
}
}
}
}
<?php
/**
* Laravel IDE Helper Generator
*
* @author Barry vd. Heuvel <[email protected]>
* @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/barryvdh/laravel-ide-helper
*/
namespace Barryvdh\LaravelIdeHelper;
use Barryvdh\Reflection\DocBlock;
use Barryvdh\Reflection\DocBlock\Context;
use Barryvdh\Reflection\DocBlock\Tag;
use Barryvdh\Reflection\DocBlock\Tag\ReturnTag;
use Barryvdh\Reflection\DocBlock\Tag\ParamTag;
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
class Method
{
/** @var \Barryvdh\Reflection\DocBlock */
protected $phpdoc;
/** @var \ReflectionMethod */
protected $method;
protected $output = '';
protected $declaringClassName;
protected $name;
protected $namespace;
protected $params = array();
protected $params_with_default = array();
protected $interfaces = array();
protected $real_name;
protected $return = null;
protected $root;
/**
* @param \ReflectionMethod|\ReflectionFunctionAbstract $method
* @param string $alias
* @param \ReflectionClass $class
* @param string|null $methodName
* @param array $interfaces
*/
public function __construct($method, $alias, $class, $methodName = null, $interfaces = array())
{
$this->method = $method;
$this->interfaces = $interfaces;
$this->name = $methodName ?: $method->name;
$this->real_name = $method->isClosure() ? $this->name : $method->name;
$this->initClassDefinedProperties($method, $class);
//Reference the 'real' function in the declaring class
$this->root = '\\' . ltrim($class->getName(), '\\');
//Create a DocBlock and serializer instance
$this->initPhpDoc($method);
//Normalize the description and inherit the docs from parents/interfaces
try {
$this->normalizeParams($this->phpdoc);
$this->normalizeReturn($this->phpdoc);
$this->normalizeDescription($this->phpdoc);
} catch (\Exception $e) {
}
//Get the parameters, including formatted default values
$this->getParameters($method);
//Make the method static
$this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc));
}
/**
* @param \ReflectionMethod $method
*/
protected function initPhpDoc($method)
{
$this->phpdoc = new DocBlock($method, new Context($this->namespace));
}
/**
* @param \ReflectionMethod $method
* @param \ReflectionClass $class
*/
protected function initClassDefinedProperties($method, \ReflectionClass $class)
{
$declaringClass = $method->getDeclaringClass();
$this->namespace = $declaringClass->getNamespaceName();
$this->declaringClassName = '\\' . ltrim($declaringClass->name, '\\');
}
/**
* Get the class wherein the function resides
*
* @return string
*/
public function getDeclaringClass()
{
return $this->declaringClassName;
}
/**
* Return the class from which this function would be called
*
* @return string
*/
public function getRoot()
{
return $this->root;
}
/**
* @return bool
*/
public function isInstanceCall()
{
return ! ($this->method->isClosure() || $this->method->isStatic());
}
/**
* @return string
*/
public function getRootMethodCall()
{
if ($this->isInstanceCall()) {
return "\$instance->{$this->getRealName()}({$this->getParams()})";
} else {
return "{$this->getRoot()}::{$this->getRealName()}({$this->getParams()})";
}
}
/**
* Get the docblock for this method
*
* @param string $prefix
* @return mixed
*/
public function getDocComment($prefix = "\t\t")
{
$serializer = new DocBlockSerializer(1, $prefix);
return $serializer->getDocComment($this->phpdoc);
}
/**
* Get the method name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Get the real method name
*
* @return string
*/
public function getRealName()
{
return $this->real_name;
}
/**
* Get the parameters for this method
*
* @param bool $implode Wether to implode the array or not
* @return string
*/
public function getParams($implode = true)
{
return $implode ? implode(', ', $this->params) : $this->params;
}
/**
* Get the parameters for this method including default values
*
* @param bool $implode Wether to implode the array or not
* @return string
*/
public function getParamsWithDefault($implode = true)
{
return $implode ? implode(', ', $this->params_with_default) : $this->params_with_default;
}
/**
* Get the description and get the inherited docs.
*
* @param DocBlock $phpdoc
*/
protected function normalizeDescription(DocBlock $phpdoc)
{
//Get the short + long description from the DocBlock
$description = $phpdoc->getText();
//Loop through parents/interfaces, to fill in {@inheritdoc}
if (strpos($description, '{@inheritdoc}') !== false) {
$inheritdoc = $this->getInheritDoc($this->method);
$inheritDescription = $inheritdoc->getText();
$description = str_replace('{@inheritdoc}', $inheritDescription, $description);
$phpdoc->setText($description);
$this->normalizeParams($inheritdoc);
$this->normalizeReturn($inheritdoc);
//Add the tags that are inherited
$inheritTags = $inheritdoc->getTags();
if ($inheritTags) {
/** @var Tag $tag */
foreach ($inheritTags as $tag) {
$tag->setDocBlock();
$phpdoc->appendTag($tag);
}
}
}
}
/**
* Normalize the parameters
*
* @param DocBlock $phpdoc
*/
protected function normalizeParams(DocBlock $phpdoc)
{
//Get the return type and adjust them for beter autocomplete
$paramTags = $phpdoc->getTagsByName('param');
if ($paramTags) {
/** @var ParamTag $tag */
foreach ($paramTags as $tag) {
// Convert the keywords
$content = $this->convertKeywords($tag->getContent());
$tag->setContent($content);
// Get the expanded type and re-set the content
$content = $tag->getType() . ' ' . $tag->getVariableName() . ' ' . $tag->getDescription();
$tag->setContent(trim($content));
}
}
}
/**
* Normalize the return tag (make full namespace, replace interfaces)
*
* @param DocBlock $phpdoc
*/
protected function normalizeReturn(DocBlock $phpdoc)
{
//Get the return type and adjust them for beter autocomplete
$returnTags = $phpdoc->getTagsByName('return');
if ($returnTags) {
/** @var ReturnTag $tag */
$tag = reset($returnTags);
// Get the expanded type
$returnValue = $tag->getType();
// Replace the interfaces
foreach ($this->interfaces as $interface => $real) {
$returnValue = str_replace($interface, $real, $returnValue);
}
// Set the changed content
$tag->setContent($returnValue . ' ' . $tag->getDescription());
$this->return = $returnValue;
if ($tag->getType() === '$this') {
$tag->setType($this->root);
}
} else {
$this->return = null;
}
}
/**
* Convert keywwords that are incorrect.
*
* @param string $string
* @return string
*/
protected function convertKeywords($string)
{
$string = str_replace('\Closure', 'Closure', $string);
$string = str_replace('Closure', '\Closure', $string);
$string = str_replace('dynamic', 'mixed', $string);
return $string;
}
/**
* Should the function return a value?
*
* @return bool
*/
public function shouldReturn()
{
if ($this->return !== "void" && $this->method->name !== "__construct") {
return true;
}
return false;
}
/**
* Get the parameters and format them correctly
*
* @param \ReflectionMethod $method
* @return array
*/
public function getParameters($method)
{
//Loop through the default values for paremeters, and make the correct output string
$params = array();
$paramsWithDefault = array();
foreach ($method->getParameters() as $param) {
$paramStr = $param->isVariadic() ? '...$' . $param->getName() : '$' . $param->getName();
$params[] = $paramStr;
if ($param->isOptional() && !$param->isVariadic()) {
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
if (is_bool($default)) {
$default = $default ? 'true' : 'false';
} elseif (is_array($default)) {
$default = '[]';
} elseif (is_null($default)) {
$default = 'null';
} elseif (is_int($default)) {
//$default = $default;
} elseif (is_resource($default)) {
//skip to not fail
} else {
$default = var_export($default, true);
}
$paramStr .= " = $default";
}
$paramsWithDefault[] = $paramStr;
}
$this->params = $params;
$this->params_with_default = $paramsWithDefault;
}
/**
* @param \ReflectionMethod $reflectionMethod
* @return DocBlock
*/
protected function getInheritDoc($reflectionMethod)
{
$parentClass = $reflectionMethod->getDeclaringClass()->getParentClass();
//Get either a parent or the interface
if ($parentClass) {
$method = $parentClass->getMethod($reflectionMethod->getName());
} else {
$method = $reflectionMethod->getPrototype();
}
if ($method) {
$namespace = $method->getDeclaringClass()->getNamespaceName();
$phpdoc = new DocBlock($method, new Context($namespace));
if (strpos($phpdoc->getText(), '{@inheritdoc}') !== false) {
//Not at the end yet, try another parent/interface..
return $this->getInheritDoc($method);
} else {
return $phpdoc;
}
}
}
}
+65
View File
@@ -0,0 +1,65 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console;
use Barryvdh\LaravelIdeHelper\Console\EloquentCommand;
use Barryvdh\LaravelIdeHelper\Tests\TestCase;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Filesystem\Filesystem;
use Mockery;
use ReflectionClass;
class EloquentCommandTest extends TestCase
{
public function testCommand()
{
$modelFilename = $this->getVendorModelFilename();
$modelSource = file_get_contents($modelFilename);
if (false !== strpos($modelSource, '* @mixin')) {
$msg = sprintf('Class %s already contains the @mixin markers', Model::class);
$this->markTestSkipped($msg);
}
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
// We don't care about actual args (filename)
->andReturn('abstract class Model implements'); // This is enough to trigger the replacement logic
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(), // First arg is path, we don't care
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(EloquentCommand::class);
$tester = $this->runCommand($command);
$expectedContent = '/**
*
*
* @mixin \Eloquent
* @mixin \Illuminate\Database\Eloquent\Builder
* @mixin \Illuminate\Database\Query\Builder
*/
abstract class Model implements';
$this->assertSame($expectedContent, $actualContent);
$display = $tester->getDisplay();
$this->assertRegExp(';Unexpected no document on Illuminate\\\Database\\\Eloquent\\\Model;', $display);
$this->assertRegExp(';Wrote expected docblock to .*/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php;', $display);
}
private function getVendorModelFilename(): string
{
$class = Model::class;
$reflectedClass = new ReflectionClass($class);
return $reflectedClass->getFileName();
}
}
@@ -0,0 +1,37 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\TestCase;
use Illuminate\Foundation\Application;
abstract class AbstractModelsCommand extends TestCase
{
protected function setUp(): void
{
parent::setUp();
// Skip older Laravel version for these tests
if (version_compare(Application::VERSION, '6.0', '<')) {
$this->markTestSkipped('This test requires Laravel 6.0 or higher');
return;
}
$this->loadMigrationsFrom(__DIR__ . '/migrations');
$this->artisan('migrate');
}
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$config = $app['config'];
$config->set('database.default', 'sqlite');
$config->set('database.connections.sqlite', [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
]);
}
}
@@ -0,0 +1,10 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Collections;
use Illuminate\Database\Eloquent\Collection;
class SimpleCollection extends Collection
{
}
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Models;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Collections\SimpleCollection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Simple extends Model
{
public function newCollection(array $models = [])
{
return new SimpleCollection($models);
}
public function relationHasMany(): HasMany
{
return $this->hasMany(Simple::class);
}
}
@@ -0,0 +1,94 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Collections\SimpleCollection;
use Illuminate\Filesystem\Filesystem;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/CustomCollection/Models',
],
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Models;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Collections\SimpleCollection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Models\Simple
*
* @property integer $id
* @property-read \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Collections\SimpleCollection|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Models\Simple[] $relationHasMany
* @property-read int|null $relation_has_many_count
* @method static \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Collections\SimpleCollection|static[] all($columns = ['*'])
* @method static \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Collections\SimpleCollection|static[] get($columns = ['*'])
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Models\Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Models\Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Models\Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomCollection\Models\Simple whereId($value)
* @mixin \Eloquent
*/
class Simple extends Model
{
public function newCollection(array $models = [])
{
return new SimpleCollection($models);
}
public function relationHasMany(): HasMany
{
return $this->hasMany(Simple::class);
}
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,9 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomDate\Models;
use Illuminate\Database\Eloquent\Model;
class CustomDate extends Model
{
}
@@ -0,0 +1,97 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomDate;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Carbon\CarbonImmutable;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Date;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function setUp(): void
{
parent::setUp();
Date::use(CarbonImmutable::class);
}
protected function tearDown(): void
{
Date::use(Carbon::class);
parent::tearDown();
}
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/CustomDate/Models',
],
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/CustomDate.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomDate\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomDate\Models\CustomDate
*
* @property \Carbon\CarbonImmutable|null $created_at
* @property \Carbon\CarbonImmutable|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomDate\Models\CustomDate newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomDate\Models\CustomDate newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomDate\Models\CustomDate query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomDate\Models\CustomDate whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\CustomDate\Models\CustomDate whereUpdatedAt($value)
* @mixin \Eloquent
*/
class CustomDate extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,9 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
}
@@ -0,0 +1,222 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Illuminate\Filesystem\Filesystem;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/GenerateBasicPhpdoc/Models',
],
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Post.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\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 float|null $decimal_nullable
* @property float $decimal_not_nullable
* @property float|null $unsigned_decimal_nullable
* @property float $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 \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereBigIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereBigIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereBinaryNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereBinaryNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereBooleanNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereBooleanNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereCharNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereCharNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDateNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDateNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDatetimeNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDatetimeNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDatetimetzNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDatetimetzNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDecimalNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDecimalNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDoubleNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereDoubleNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereEnumNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereEnumNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereFloatNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereFloatNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereIpaddressNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereIpaddressNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereJsonNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereJsonNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereJsonbNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereJsonbNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereLongTextNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereLongTextNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereMacaddressNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereMacaddressNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereMediumIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereMediumIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereMediumTextNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereMediumTextNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereSmallIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereSmallIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereStringNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereStringNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTextNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTextNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTimeNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTimeNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTimestampNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTimestampNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTimestamptzNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTimestamptzNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTimetzNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTimetzNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTinyIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereTinyIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedBigIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedBigIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedDecimalNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedDecimalNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedMediumIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedMediumIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedSmallIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedSmallIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedTinyIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUnsignedTinyIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUuidNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereUuidNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereYearNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdoc\Models\Post whereYearNullable($value)
* @mixin \Eloquent
*/
class Post extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,9 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
}
@@ -0,0 +1,224 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Illuminate\Filesystem\Filesystem;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/GenerateBasicPhpdocCamel/Models',
],
// Activate the camel_case mode
'model_camel_case_properties' => true,
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Post.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post
*
* @property integer $id
* @property string|null $charNullable
* @property string $charNotNullable
* @property string|null $stringNullable
* @property string $stringNotNullable
* @property string|null $textNullable
* @property string $textNotNullable
* @property string|null $mediumTextNullable
* @property string $mediumTextNotNullable
* @property string|null $longTextNullable
* @property string $longTextNotNullable
* @property integer|null $integerNullable
* @property integer $integerNotNullable
* @property integer|null $tinyIntegerNullable
* @property integer $tinyIntegerNotNullable
* @property integer|null $smallIntegerNullable
* @property integer $smallIntegerNotNullable
* @property integer|null $mediumIntegerNullable
* @property integer $mediumIntegerNotNullable
* @property integer|null $bigIntegerNullable
* @property integer $bigIntegerNotNullable
* @property integer|null $unsignedIntegerNullable
* @property integer $unsignedIntegerNotNullable
* @property integer|null $unsignedTinyIntegerNullable
* @property integer $unsignedTinyIntegerNotNullable
* @property integer|null $unsignedSmallIntegerNullable
* @property integer $unsignedSmallIntegerNotNullable
* @property integer|null $unsignedMediumIntegerNullable
* @property integer $unsignedMediumIntegerNotNullable
* @property integer|null $unsignedBigIntegerNullable
* @property integer $unsignedBigIntegerNotNullable
* @property float|null $floatNullable
* @property float $floatNotNullable
* @property float|null $doubleNullable
* @property float $doubleNotNullable
* @property float|null $decimalNullable
* @property float $decimalNotNullable
* @property float|null $unsignedDecimalNullable
* @property float $unsignedDecimalNotNullable
* @property integer|null $booleanNullable
* @property integer $booleanNotNullable
* @property string|null $enumNullable
* @property string $enumNotNullable
* @property string|null $jsonNullable
* @property string $jsonNotNullable
* @property string|null $jsonbNullable
* @property string $jsonbNotNullable
* @property string|null $dateNullable
* @property string $dateNotNullable
* @property string|null $datetimeNullable
* @property string $datetimeNotNullable
* @property string|null $datetimetzNullable
* @property string $datetimetzNotNullable
* @property string|null $timeNullable
* @property string $timeNotNullable
* @property string|null $timetzNullable
* @property string $timetzNotNullable
* @property string|null $timestampNullable
* @property string $timestampNotNullable
* @property string|null $timestamptzNullable
* @property string $timestamptzNotNullable
* @property integer|null $yearNullable
* @property integer $yearNotNullable
* @property mixed|null $binaryNullable
* @property mixed $binaryNotNullable
* @property string|null $uuidNullable
* @property string $uuidNotNullable
* @property string|null $ipaddressNullable
* @property string $ipaddressNotNullable
* @property string|null $macaddressNullable
* @property string $macaddressNotNullable
* @property \Illuminate\Support\Carbon|null $createdAt
* @property \Illuminate\Support\Carbon|null $updatedAt
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereBigIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereBigIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereBinaryNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereBinaryNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereBooleanNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereBooleanNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereCharNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereCharNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDateNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDateNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDatetimeNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDatetimeNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDatetimetzNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDatetimetzNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDecimalNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDecimalNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDoubleNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereDoubleNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereEnumNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereEnumNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereFloatNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereFloatNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereIpaddressNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereIpaddressNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereJsonNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereJsonNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereJsonbNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereJsonbNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereLongTextNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereLongTextNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereMacaddressNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereMacaddressNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereMediumIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereMediumIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereMediumTextNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereMediumTextNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereSmallIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereSmallIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereStringNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereStringNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTextNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTextNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTimeNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTimeNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTimestampNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTimestampNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTimestamptzNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTimestamptzNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTimetzNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTimetzNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTinyIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereTinyIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedBigIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedBigIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedDecimalNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedDecimalNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedMediumIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedMediumIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedSmallIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedSmallIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedTinyIntegerNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUnsignedTinyIntegerNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUuidNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereUuidNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereYearNotNullable($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateBasicPhpdocCamel\Models\Post whereYearNullable($value)
* @mixin \Eloquent
*/
class Post extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,104 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Getter\Models;
use DateTime;
use Illuminate\Database\Eloquent\Model;
class Simple extends Model
{
/**
* @return int
*/
public function getAttributeWithIntReturnPhpdocAttribute()
{
}
public function getAttributeWithIntReturnTypeAttribute(): int
{
}
/**
* @return int
*/
public function getAttributeWithIntReturnTypeAndPhpdocAttribute(): int
{
}
/**
* @return string
*/
public function getAttributeWithIntReturnTypeAndButPhpdocStringAttribute(): int
{
}
public function getAttributeWithoutTypeAttribute()
{
}
/**
* @return what|ever|we-write/here
*/
public function getAttributeTakesPhpdocLiteralAttribute()
{
}
public function getAttributeReturnTypeIntOrNullAttribute(): ?int
{
}
public function getAttributeReturnsImportedClassAttribute(): DateTime
{
}
public function getAttributeReturnsFqnClassAttribute(): \Illuminate\Support\Facades\Date
{
}
public function getAttributeReturnsArrayAttribute(): array
{
}
public function getAttributeReturnsNullableArrayAttribute(): ?array
{
}
public function getAttributeReturnsStdClassAttribute(): \stdClass
{
}
public function getAttributeReturnsNullableStdClassAttribute(): ?\stdClass
{
}
public function getAttributeReturnsBoolAttribute(): bool
{
}
public function getAttributeReturnsNullableBoolAttribute(): ?bool
{
}
public function getAttributeReturnsFloatAttribute(): bool
{
}
public function getAttributeReturnsNullableFloatAttribute(): ?bool
{
}
public function getAttributeReturnsCallableAttribute(): callable
{
}
public function getAttributeReturnsNullableCallableAttribute(): ?callable
{
}
/**
* Doesn't make sense, but…
*/
public function getAttributeReturnsVoidAttribute(): void
{
}
}
+193
View File
@@ -0,0 +1,193 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Getter;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Illuminate\Filesystem\Filesystem;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/Getter/Models',
],
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Getter\Models;
use DateTime;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Getter\Models\Simple
*
* @property integer $id
* @property-read int|null $attribute_return_type_int_or_null
* @property-read array $attribute_returns_array
* @property-read bool $attribute_returns_bool
* @property-read callable $attribute_returns_callable
* @property-read bool $attribute_returns_float
* @property-read \Illuminate\Support\Facades\Date $attribute_returns_fqn_class
* @property-read \DateTime $attribute_returns_imported_class
* @property-read array|null $attribute_returns_nullable_array
* @property-read bool|null $attribute_returns_nullable_bool
* @property-read callable|null $attribute_returns_nullable_callable
* @property-read bool|null $attribute_returns_nullable_float
* @property-read \stdClass|null $attribute_returns_nullable_std_class
* @property-read \stdClass $attribute_returns_std_class
* @property-read void $attribute_returns_void
* @property-read \what|\ever|\we-write/here $attribute_takes_phpdoc_literal
* @property-read int $attribute_with_int_return_phpdoc
* @property-read string $attribute_with_int_return_type_and_but_phpdoc_string
* @property-read int $attribute_with_int_return_type_and_phpdoc
* @property-read int $attribute_with_int_return_type
* @property-read mixed $attribute_without_type
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Getter\Models\Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Getter\Models\Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Getter\Models\Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Getter\Models\Simple whereId($value)
* @mixin \Eloquent
*/
class Simple extends Model
{
/**
* @return int
*/
public function getAttributeWithIntReturnPhpdocAttribute()
{
}
public function getAttributeWithIntReturnTypeAttribute(): int
{
}
/**
* @return int
*/
public function getAttributeWithIntReturnTypeAndPhpdocAttribute(): int
{
}
/**
* @return string
*/
public function getAttributeWithIntReturnTypeAndButPhpdocStringAttribute(): int
{
}
public function getAttributeWithoutTypeAttribute()
{
}
/**
* @return what|ever|we-write/here
*/
public function getAttributeTakesPhpdocLiteralAttribute()
{
}
public function getAttributeReturnTypeIntOrNullAttribute(): ?int
{
}
public function getAttributeReturnsImportedClassAttribute(): DateTime
{
}
public function getAttributeReturnsFqnClassAttribute(): \Illuminate\Support\Facades\Date
{
}
public function getAttributeReturnsArrayAttribute(): array
{
}
public function getAttributeReturnsNullableArrayAttribute(): ?array
{
}
public function getAttributeReturnsStdClassAttribute(): \stdClass
{
}
public function getAttributeReturnsNullableStdClassAttribute(): ?\stdClass
{
}
public function getAttributeReturnsBoolAttribute(): bool
{
}
public function getAttributeReturnsNullableBoolAttribute(): ?bool
{
}
public function getAttributeReturnsFloatAttribute(): bool
{
}
public function getAttributeReturnsNullableFloatAttribute(): ?bool
{
}
public function getAttributeReturnsCallableAttribute(): callable
{
}
public function getAttributeReturnsNullableCallableAttribute(): ?callable
{
}
/**
* Doesn't make sense, but…
*/
public function getAttributeReturnsVoidAttribute(): void
{
}
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Ignored\Models;
use DateTime;
use Illuminate\Database\Eloquent\Model;
class Ignored extends Model
{
}
@@ -0,0 +1,9 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Ignored\Models;
use Illuminate\Database\Eloquent\Model;
class NotIgnored extends Model
{
}
@@ -0,0 +1,81 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Ignored;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Ignored\Models\Ignored;
use Illuminate\Filesystem\Filesystem;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/Ignored/Models',
],
'ignored_models' => [
Ignored::class
]
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Ignored.php'))
->andReturn(file_get_contents(__DIR__ . '/Models/NotIgnored.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Ignored\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Ignored\Models\NotIgnored
*
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Ignored\Models\NotIgnored newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Ignored\Models\NotIgnored newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Ignored\Models\NotIgnored query()
* @mixin \Eloquent
*/
class NotIgnored extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,39 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Interfaces\Models;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
class User extends Model implements Authenticatable
{
public function getAuthIdentifierName()
{
// TODO: Implement getAuthIdentifierName() method.
}
public function getAuthIdentifier()
{
// TODO: Implement getAuthIdentifier() method.
}
public function getAuthPassword()
{
// TODO: Implement getAuthPassword() method.
}
public function getRememberToken()
{
// TODO: Implement getRememberToken() method.
}
public function setRememberToken($value)
{
// TODO: Implement setRememberToken() method.
}
public function getRememberTokenName()
{
// TODO: Implement getRememberTokenName() method.
}
}
@@ -0,0 +1,79 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Interfaces;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Illuminate\Filesystem\Filesystem;
use Mockery;
final class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/Interfaces/Models',
],
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--nowrite' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php
// @formatter:off
/**
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
* And remove them from this file, to prevent double declarations.
*
* @author Barry vd. Heuvel <barryvdh@gmail.com>
*/
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Interfaces\Models{
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Interfaces\Models\User
*
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Interfaces\Models\User newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Interfaces\Models\User newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Interfaces\Models\User query()
*/
class User extends \Eloquent implements \Illuminate\Contracts\Auth\Authenticatable {}
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,8 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
class CastedProperty
{
}
@@ -0,0 +1,25 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class CustomCasterWithDocblockReturn implements CastsAttributes
{
/**
* @inheritDoc
* @return CastedProperty
*/
public function get($model, string $key, $value, array $attributes)
{
return new CastedProperty();
}
/**
* @inheritDoc
*/
public function set($model, string $key, $value, array $attributes)
{
// TODO: Implement set() method.
}
}
@@ -0,0 +1,25 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class CustomCasterWithNullablePrimitiveReturn implements CastsAttributes
{
/**
* @inheritDoc
* @return string
*/
public function get($model, string $key, $value, array $attributes): ?array
{
return new CastedProperty();
}
/**
* @inheritDoc
*/
public function set($model, string $key, $value, array $attributes)
{
// TODO: Implement set() method.
}
}
@@ -0,0 +1,25 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class CustomCasterWithPrimitiveDocblockReturn implements CastsAttributes
{
/**
* @inheritDoc
* @return array|null
*/
public function get($model, string $key, $value, array $attributes)
{
return new CastedProperty();
}
/**
* @inheritDoc
*/
public function set($model, string $key, $value, array $attributes)
{
// TODO: Implement set() method.
}
}
@@ -0,0 +1,25 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class CustomCasterWithPrimitiveReturn implements CastsAttributes
{
/**
* @inheritDoc
* @return string
*/
public function get($model, string $key, $value, array $attributes): array
{
return new CastedProperty();
}
/**
* @inheritDoc
*/
public function set($model, string $key, $value, array $attributes)
{
// TODO: Implement set() method.
}
}
@@ -0,0 +1,24 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class CustomCasterWithReturnType implements CastsAttributes
{
/**
* @return array
*/
public function get($model, string $key, $value, array $attributes): CastedProperty
{
return new CastedProperty();
}
/**
* @inheritDoc
*/
public function set($model, string $key, $value, array $attributes)
{
// TODO: Implement set() method.
}
}
@@ -0,0 +1,21 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class CustomCasterWithoutReturnType implements CastsAttributes
{
public function get($model, string $key, $value, array $attributes)
{
return new CastedProperty();
}
/**
* @inheritDoc
*/
public function set($model, string $key, $value, array $attributes)
{
// TODO: Implement set() method.
}
}
@@ -0,0 +1,23 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithNullablePrimitiveReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithoutReturnType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithPrimitiveDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithPrimitiveReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithReturnType;
use Illuminate\Database\Eloquent\Model;
class CustomCast extends Model
{
protected $casts = [
'casted_property_with_return_type' => CustomCasterWithReturnType::class,
'casted_property_with_return_docblock' => CustomCasterWithDocblockReturn::class,
'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_without_return' => CustomCasterWithoutReturnType::class,
];
}
@@ -0,0 +1,113 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Foundation\Application;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function setUp(): void
{
parent::setUp();
if (version_compare(Application::VERSION, '7.0', '<')) {
$this->markTestSkipped('This test requires Laravel 7.0 or higher');
}
}
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/LaravelCustomCasts/Models',
],
]);
}
public function test_it_parses_casted_properties_correctly(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__.'/Models/CustomCast.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithNullablePrimitiveReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithoutReturnType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithPrimitiveDocblockReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithPrimitiveReturn;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CustomCasterWithReturnType;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast
*
* @property \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Casts\CastedProperty $casted_property_with_return_type
* @property \CastedProperty $casted_property_with_return_docblock
* @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 $casted_property_without_return
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast whereCastedPropertyWithReturnDocblock($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast whereCastedPropertyWithReturnNullablePrimitive($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast whereCastedPropertyWithReturnPrimitive($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast whereCastedPropertyWithReturnPrimitiveDocblock($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast whereCastedPropertyWithReturnType($value)
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCasts\Models\CustomCast whereCastedPropertyWithoutReturn($value)
* @mixin \Eloquent
*/
class CustomCast extends Model
{
protected $casts = [
'casted_property_with_return_type' => CustomCasterWithReturnType::class,
'casted_property_with_return_docblock' => CustomCasterWithDocblockReturn::class,
'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_without_return' => CustomCasterWithoutReturnType::class,
];
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,9 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models;
use Illuminate\Database\Eloquent\Model;
class Simple extends Model
{
}
@@ -0,0 +1,136 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Illuminate\Filesystem\Filesystem;
use Mockery;
use function file_get_contents;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/PHPStormNoInspection/Models',
],
]);
}
public function testNoinspectionNotPresent(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple
*
* @property integer $id
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple whereId($value)
* @mixin \Eloquent
*/
class Simple extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
public function testNoinspectionPresent(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
'--phpstorm-noinspections' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple
*
* @property integer $id
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PHPStormNoInspection\Models\Simple whereId($value)
* @mixin \Eloquent
* @noinspection PhpFullyQualifiedNameUsageInspection
* @noinspection PhpUnnecessaryFullyQualifiedNameInspection
*/
class Simple extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,85 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\ModelsOtherNamespace\AnotherModel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
class Simple extends Model
{
// Regular relations
public function relationHasMany(): HasMany
{
return $this->hasMany(Simple::class);
}
public function relationHasOne(): HasOne
{
return $this->hasOne(Simple::class);
}
public function relationHasOneWithDefault(): HasOne
{
return $this->hasOne(Simple::class)->withDefault();
}
public function relationBelongsTo(): BelongsTo
{
return $this->belongsTo(Simple::class);
}
public function relationBelongsToMany(): BelongsToMany
{
return $this->belongsToMany(Simple::class);
}
public function relationBelongsToManyWithSub(): BelongsToMany
{
return $this->belongsToMany(Simple::class)->where('foo', 'bar');
}
public function relationBelongsToManyWithSubAnother(): BelongsToMany
{
return $this->relationBelongsToManyWithSub()->where('foo', 'bar');
}
public function relationMorphTo(): MorphTo
{
return $this->morphTo();
}
public function relationMorphOne(): MorphOne
{
return $this->morphOne(Simple::class, 'relationMorphTo');
}
public function relationMorphMany(): MorphMany
{
return $this->morphMany(Simple::class, 'relationMorphTo');
}
public function relationMorphedByMany(): MorphToMany
{
return $this->morphedByMany(Simple::class, 'foo');
}
// Custom relations
public function relationBelongsToInAnotherNamespace(): BelongsTo
{
return $this->belongsTo(AnotherModel::class);
}
public function relationBelongsToSameNameAsColumn(): BelongsTo
{
return $this->belongsTo(AnotherModel::class, __FUNCTION__);
}
}
@@ -0,0 +1,9 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\ModelsOtherNamespace;
use Illuminate\Database\Eloquent\Model;
class AnotherModel extends Model
{
}
@@ -0,0 +1,173 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Illuminate\Filesystem\Filesystem;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/Relations/Models',
],
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\ModelsOtherNamespace\AnotherModel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple
*
* @property integer $id
* @property-read \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple $relationBelongsTo
* @property-read \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\ModelsOtherNamespace\AnotherModel $relationBelongsToInAnotherNamespace
* @property-read \Illuminate\Database\Eloquent\Collection|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple[] $relationBelongsToMany
* @property-read int|null $relation_belongs_to_many_count
* @property-read \Illuminate\Database\Eloquent\Collection|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple[] $relationBelongsToManyWithSub
* @property-read int|null $relation_belongs_to_many_with_sub_count
* @property-read \Illuminate\Database\Eloquent\Collection|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple[] $relationBelongsToManyWithSubAnother
* @property-read int|null $relation_belongs_to_many_with_sub_another_count
* @property-read \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\ModelsOtherNamespace\AnotherModel $relationBelongsToSameNameAsColumn
* @property-read \Illuminate\Database\Eloquent\Collection|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple[] $relationHasMany
* @property-read int|null $relation_has_many_count
* @property-read \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple|null $relationHasOne
* @property-read \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple $relationHasOneWithDefault
* @property-read \Illuminate\Database\Eloquent\Collection|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple[] $relationMorphMany
* @property-read int|null $relation_morph_many_count
* @property-read \Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple|null $relationMorphOne
* @property-read \Illuminate\Database\Eloquent\Model|\Eloquent $relationMorphTo
* @property-read \Illuminate\Database\Eloquent\Collection|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple[] $relationMorphedByMany
* @property-read int|null $relation_morphed_by_many_count
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\Simple whereId($value)
* @mixin \Eloquent
*/
class Simple extends Model
{
// Regular relations
public function relationHasMany(): HasMany
{
return $this->hasMany(Simple::class);
}
public function relationHasOne(): HasOne
{
return $this->hasOne(Simple::class);
}
public function relationHasOneWithDefault(): HasOne
{
return $this->hasOne(Simple::class)->withDefault();
}
public function relationBelongsTo(): BelongsTo
{
return $this->belongsTo(Simple::class);
}
public function relationBelongsToMany(): BelongsToMany
{
return $this->belongsToMany(Simple::class);
}
public function relationBelongsToManyWithSub(): BelongsToMany
{
return $this->belongsToMany(Simple::class)->where('foo', 'bar');
}
public function relationBelongsToManyWithSubAnother(): BelongsToMany
{
return $this->relationBelongsToManyWithSub()->where('foo', 'bar');
}
public function relationMorphTo(): MorphTo
{
return $this->morphTo();
}
public function relationMorphOne(): MorphOne
{
return $this->morphOne(Simple::class, 'relationMorphTo');
}
public function relationMorphMany(): MorphMany
{
return $this->morphMany(Simple::class, 'relationMorphTo');
}
public function relationMorphedByMany(): MorphToMany
{
return $this->morphedByMany(Simple::class, 'foo');
}
// Custom relations
public function relationBelongsToInAnotherNamespace(): BelongsTo
{
return $this->belongsTo(AnotherModel::class);
}
public function relationBelongsToSameNameAsColumn(): BelongsTo
{
return $this->belongsTo(AnotherModel::class, __FUNCTION__);
}
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,14 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Text of existing phpdoc
*
* @property string $foo
*/
class Simple extends Model
{
}
@@ -0,0 +1,189 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Illuminate\Filesystem\Filesystem;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/ResetAndSmartReset/Models',
],
]);
}
public function testNoReset(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Text of existing phpdoc
*
* @property string $foo
* @property integer $id
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple whereId($value)
* @mixin \Eloquent
*/
class Simple extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
public function testReset(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
'--reset' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple
*
* @property integer $id
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple whereId($value)
* @mixin \Eloquent
*/
class Simple extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
public function testSmartReset(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
'--smart-reset' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Text of existing phpdoc
*
* @property integer $id
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\ResetAndSmartReset\Models\Simple whereId($value)
* @mixin \Eloquent
*/
class Simple extends Model
{
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,11 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Simple extends Model
{
use SoftDeletes;
}
@@ -0,0 +1,83 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
use Illuminate\Filesystem\Filesystem;
use Mockery;
class Test extends AbstractModelsCommand
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('ide-helper', [
'model_locations' => [
// This is calculated from the base_path() which points to
// vendor/orchestra/testbench-core/laravel
'/../../../../tests/Console/ModelsCommand/SoftDeletes/Models',
],
]);
}
public function test(): void
{
$actualContent = null;
$mockFilesystem = Mockery::mock(Filesystem::class);
$mockFilesystem
->shouldReceive('get')
->andReturn(file_get_contents(__DIR__ . '/Models/Simple.php'))
->once();
$mockFilesystem
->shouldReceive('put')
->with(
Mockery::any(),
Mockery::capture($actualContent)
)
->andReturn(1) // Simulate we wrote _something_ to the file
->once();
$this->instance(Filesystem::class, $mockFilesystem);
$command = $this->app->make(ModelsCommand::class);
$tester = $this->runCommand($command, [
'--write' => true,
]);
$this->assertSame(0, $tester->getStatusCode());
$this->assertEmpty($tester->getDisplay());
$expectedContent = <<<'PHP'
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models\Simple
*
* @property integer $id
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models\Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models\Simple newQuery()
* @method static \Illuminate\Database\Query\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models\Simple onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models\Simple query()
* @method static \Illuminate\Database\Eloquent\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models\Simple whereId($value)
* @method static \Illuminate\Database\Query\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models\Simple withTrashed()
* @method static \Illuminate\Database\Query\Builder|\Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\SoftDeletes\Models\Simple withoutTrashed()
* @mixin \Eloquent
*/
class Simple extends Model
{
use SoftDeletes;
}
PHP;
$this->assertSame($expectedContent, $actualContent);
}
}
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CustomCastsTable extends Migration
{
public function up(): void
{
Schema::create('custom_casts', static function (Blueprint $table) {
$table->string('casted_property_with_return_type');
$table->string('casted_property_with_return_docblock');
$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_without_return');
});
}
}
@@ -0,0 +1,15 @@
<?php declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CustomDatesTable extends Migration
{
public function up(): void
{
Schema::create('custom_dates', function (Blueprint $table) {
$table->timestamps();
});
}
}
@@ -0,0 +1,122 @@
<?php declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class PostsTable extends Migration
{
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->char('char_nullable')->nullable();
$table->char('char_not_nullable');
$table->string('string_nullable')->nullable();
$table->string('string_not_nullable');
$table->text('text_nullable')->nullable();
$table->text('text_not_nullable');
$table->mediumText('medium_text_nullable')->nullable();
$table->mediumText('medium_text_not_nullable');
$table->longText('long_text_nullable')->nullable();
$table->longText('long_text_not_nullable');
$table->integer('integer_nullable')->nullable();
$table->integer('integer_not_nullable');
$table->tinyInteger('tiny_integer_nullable')->nullable();
$table->tinyInteger('tiny_integer_not_nullable');
$table->smallInteger('small_integer_nullable')->nullable();
$table->smallInteger('small_integer_not_nullable');
$table->mediumInteger('medium_integer_nullable')->nullable();
$table->mediumInteger('medium_integer_not_nullable');
$table->bigInteger('big_integer_nullable')->nullable();
$table->bigInteger('big_integer_not_nullable');
$table->unsignedInteger('unsigned_integer_nullable')->nullable();
$table->unsignedInteger('unsigned_integer_not_nullable');
$table->unsignedTinyInteger('unsigned_tiny_integer_nullable')->nullable();
$table->unsignedTinyInteger('unsigned_tiny_integer_not_nullable');
$table->unsignedSmallInteger('unsigned_small_integer_nullable')->nullable();
$table->unsignedSmallInteger('unsigned_small_integer_not_nullable');
$table->unsignedMediumInteger('unsigned_medium_integer_nullable')->nullable();
$table->unsignedMediumInteger('unsigned_medium_integer_not_nullable');
$table->unsignedBigInteger('unsigned_big_integer_nullable')->nullable();
$table->unsignedBigInteger('unsigned_big_integer_not_nullable');
$table->float('float_nullable')->nullable();
$table->float('float_not_nullable');
$table->double('double_nullable')->nullable();
$table->double('double_not_nullable');
$table->decimal('decimal_nullable')->nullable();
$table->decimal('decimal_not_nullable');
$table->unsignedDecimal('unsigned_decimal_nullable')->nullable();
$table->unsignedDecimal('unsigned_decimal_not_nullable');
$table->boolean('boolean_nullable')->nullable();
$table->boolean('boolean_not_nullable');
$table->enum('enum_nullable', ['foo', 'bar'])->nullable();
$table->enum('enum_not_nullable', ['foo', 'bar']);
$table->json('json_nullable')->nullable();
$table->json('json_not_nullable');
$table->jsonb('jsonb_nullable')->nullable();
$table->jsonb('jsonb_not_nullable');
$table->date('date_nullable')->nullable();
$table->date('date_not_nullable');
$table->dateTime('datetime_nullable')->nullable();
$table->dateTime('datetime_not_nullable');
$table->dateTimeTz('datetimetz_nullable')->nullable();
$table->dateTimeTz('datetimetz_not_nullable');
$table->time('time_nullable')->nullable();
$table->time('time_not_nullable');
$table->timeTz('timetz_nullable')->nullable();
$table->timeTz('timetz_not_nullable');
$table->timestamp('timestamp_nullable')->nullable();
$table->timestamp('timestamp_not_nullable');
$table->timestampTz('timestamptz_nullable')->nullable();
$table->timestampTz('timestamptz_not_nullable');
$table->year('year_nullable')->nullable();
$table->year('year_not_nullable');
$table->binary('binary_nullable')->nullable();
$table->binary('binary_not_nullable');
$table->uuid('uuid_nullable')->nullable();
$table->uuid('uuid_not_nullable');
$table->ipAddress('ipaddress_nullable')->nullable();
$table->ipAddress('ipaddress_not_nullable');
$table->macAddress('macaddress_nullable')->nullable();
$table->macAddress('macaddress_not_nullable');
$table->timestamps();
});
}
}
@@ -0,0 +1,15 @@
<?php declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class SimpleTable extends Migration
{
public function up(): void
{
Schema::create('simples', function (Blueprint $table) {
$table->bigIncrements('id');
});
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests;
use Barryvdh\LaravelIdeHelper\Method;
use PHPUnit\Framework\TestCase;
class ExampleTest extends TestCase
{
/**
* Test that we can actually instantiate the class
*/
public function testCanInstantiate()
{
$reflectionClass = new \ReflectionClass(ExampleClass::class);
$reflectionMethod = $reflectionClass->getMethod('setName');
$method = new Method($reflectionMethod, 'Example', $reflectionClass);
$this->assertInstanceOf(Method::class, $method);
}
/**
* Test the output of a class
*/
public function testOutput()
{
$reflectionClass = new \ReflectionClass(ExampleClass::class);
$reflectionMethod = $reflectionClass->getMethod('setName');
$method = new Method($reflectionMethod, 'Example', $reflectionClass);
$output = '/**
*
*
* @param string $last
* @param string $first
* @param string $middle
* @static
*/';
$this->assertEquals($output, $method->getDocComment(''));
$this->assertEquals('setName', $method->getName());
$this->assertEquals('\\'.ExampleClass::class, $method->getDeclaringClass());
$this->assertEquals('$last, $first, ...$middle', $method->getParams(true));
$this->assertEquals(['$last', '$first', '...$middle'], $method->getParams(false));
$this->assertEquals('$last, $first = \'Barry\', ...$middle', $method->getParamsWithDefault(true));
$this->assertEquals(['$last', '$first = \'Barry\'', '...$middle'], $method->getParamsWithDefault(false));
$this->assertEquals(true, $method->shouldReturn());
}
/**
* Test special characters in methods default values
*/
public function testDefaultSpecialChars()
{
$reflectionClass = new \ReflectionClass(ExampleClass::class);
$reflectionMethod = $reflectionClass->getMethod('setSpecialChars');
$method = new Method($reflectionMethod, 'Example', $reflectionClass);
$this->assertEquals('$chars', $method->getParams(true));
$this->assertEquals(['$chars'], $method->getParams(false));
$this->assertEquals('$chars = \'$\\\'\\\\\'', $method->getParamsWithDefault(true));
$this->assertEquals(['$chars = \'$\\\'\\\\\''], $method->getParamsWithDefault(false));
}
}
class ExampleClass
{
/**
* @param string $last
* @param string $first
* @param string $middle
*/
public function setName($last, $first = 'Barry', ...$middle)
{
return;
}
public function setSpecialChars($chars = "\$'\\")
{
return;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php declare(strict_types=1);
namespace Barryvdh\LaravelIdeHelper\Tests;
use Illuminate\Console\Command;
use Orchestra\Testbench\TestCase as BaseTestCase;
use Symfony\Component\Console\Tester\CommandTester;
abstract class TestCase extends BaseTestCase
{
/**
* The `CommandTester` is directly returned, use methods like
* `->getDisplay()` or `->getStatusCode()` on it.
*
* @param Command $command
* @param array $arguments The command line arguments, array of key=>value
* Examples:
* - named arguments: ['model' => 'Post']
* - boolean flags: ['--all' => true]
* - arguments with values: ['--arg' => 'value']
* @param array $interactiveInput Interactive responses to the command
* I.e. anything the command `->ask()` or `->confirm()`, etc.
* @return CommandTester
*/
protected function runCommand(Command $command, array $arguments = [], array $interactiveInput = []): CommandTester
{
$command->setLaravel($this->app);
$tester = new CommandTester($command);
$tester->setInputs($interactiveInput);
$tester->execute($arguments);
return $tester;
}
}