Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle protected methods with the attribute syntax #1325

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.

### Fixed
- Fix date and datetime handling for attributes that set a serialization format option for the Carbon instance [#1324 / FLeudts](https://github.com/barryvdh/laravel-ide-helper/pull/1324)
- Add support for protected methods using Laravel 8.77 Attributes syntax [#1325 / mridul89](https://github.com/barryvdh/laravel-ide-helper/pull/1325)

2022-02-08, 2.12.2
------------------
Expand Down
20 changes: 16 additions & 4 deletions src/Console/ModelsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -569,13 +569,24 @@ public function getPropertiesFromTable($model)
*/
public function getPropertiesFromMethods($model)
{
$methods = get_class_methods($model);
$methods = (new ReflectionClass($model))->getMethods();
$methods = array_map(function (\ReflectionMethod $method) {
return $method->getName();
}, array_filter($methods, function (\ReflectionMethod $method) {
// private methods should not be documented because they are inaccessible outside the class
return !$method->isPrivate();
}));
if ($methods) {
sort($methods);
foreach ($methods as $method) {
$reflection = new \ReflectionMethod($model, $method);
$type = $this->getReturnTypeFromReflection($reflection);
$isAttribute = is_a($type, '\Illuminate\Database\Eloquent\Casts\Attribute', true);
if ($reflection->isProtected() && !$isAttribute) {
// only the accessors/mutators protected methods should be documented
// without this condition, we will unintentionally include laravel protected methods like setClassCastableAttribute()
continue;
}
if (
Str::startsWith($method, 'get') && Str::endsWith(
$method,
Expand All @@ -592,7 +603,7 @@ public function getPropertiesFromMethods($model)
}
} elseif ($isAttribute) {
$name = Str::snake($method);
$types = $this->getAttributeReturnType($model, $method);
$types = $this->getAttributeReturnType($model, $reflection);

if ($types->has('get')) {
$type = $this->getTypeInModel($model, $types['get']);
Expand Down Expand Up @@ -1082,10 +1093,11 @@ protected function hasCamelCaseModelProperties()
return $this->laravel['config']->get('ide-helper.model_camel_case_properties', false);
}

protected function getAttributeReturnType(Model $model, string $method): Collection
protected function getAttributeReturnType(Model $model, \ReflectionMethod $method): Collection
{
$method->setAccessible(true);
/** @var Attribute $attribute */
$attribute = $model->{$method}();
$attribute = $method->invoke($model);

return collect([
'get' => $attribute->get ? optional(new \ReflectionFunction($attribute->get))->getReturnType() : null,
Expand Down
9 changes: 8 additions & 1 deletion tests/Console/ModelsCommand/Attributes/Models/Simple.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@

class Simple extends Model
{
public function name(): Attribute
/**
* The method should be protected as per laravel documentation.
* Generally, public works too, but it is not the correct way per laravel documentation and thus intentionally skipped during tests.
* Private Methods are not supported by laravel and will also not be documented by ide-helper.
*
* @return Attribute
*/
protected function name(): Attribute
{
return new Attribute(
function (?string $name): ?string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@
*/
class Simple extends Model
{
public function name(): Attribute
/**
* The method should be protected as per laravel documentation.
* Generally, public works too, but it is not the correct way per laravel documentation and thus intentionally skipped during tests.
* Private Methods are not supported by laravel and will also not be documented by ide-helper.
*
* @return Attribute
*/
protected function name(): Attribute
{
return new Attribute(
function (?string $name): ?string {
Expand Down