Skip to content

Commit

Permalink
Merge pull request #5647 from Laravel-Backpack/dont-call-mutators-as-…
Browse files Browse the repository at this point in the history
…methods

Dont call mutators as methods
  • Loading branch information
pxpm committed Sep 2, 2024
2 parents 2eac727 + a5266f1 commit 1eaebf7
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/app/Library/CrudPanel/CrudPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,9 @@ public function getRelationModel($relationString, $length = null, $model = null)
$result = array_reduce(array_splice($relationArray, 0, $length), function ($obj, $method) {
try {
$result = $obj->$method();
if (! $result instanceof Relation) {
throw new Exception('Not a relation');
}

return $result->getRelated();
} catch (Exception $e) {
Expand Down
25 changes: 19 additions & 6 deletions src/app/Library/CrudPanel/Traits/Relationships.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public function getRelationInstance($field)
// here we are going to iterate through all relation parts to check
foreach ($parts as $i => $part) {
$relation = $model->$part();
if (! is_a($relation, \Illuminate\Database\Eloquent\Relations\Relation::class, true)) {
return $model;
}
$model = $relation->getRelated();
}

Expand Down Expand Up @@ -62,10 +65,10 @@ public function inferRelationTypeFromRelationship($field)
public function getOnlyRelationEntity($field)
{
$entity = isset($field['baseEntity']) ? $field['baseEntity'].'.'.$field['entity'] : $field['entity'];
$model = $this->getRelationModel($entity, -1);
$lastSegmentAfterDot = Str::of($field['entity'])->afterLast('.');
$model = new ($this->getRelationModel($entity, -1));
$lastSegmentAfterDot = Str::of($field['entity'])->afterLast('.')->value();

if (! method_exists($model, $lastSegmentAfterDot)) {
if (! $this->modelMethodIsRelationship($model, $lastSegmentAfterDot)) {
return (string) Str::of($field['entity'])->beforeLast('.');
}

Expand Down Expand Up @@ -325,8 +328,12 @@ private static function getPivotFieldStructure($field)
*/
private function modelMethodIsRelationship($model, $method)
{
if (! method_exists($model, $method) && $model->isRelation($method)) {
return $method;
if (! method_exists($model, $method)) {
if ($model->isRelation($method)) {
return $method;
}

return false;
}

$methodReflection = new \ReflectionMethod($model, $method);
Expand Down Expand Up @@ -378,7 +385,13 @@ public function isAttributeInRelationString(array $field): bool
// if the attribute is present in the relation string.
foreach ($parts as $i => $part) {
try {
$model = $model->$part()->getRelated();
$model = $model->$part();

if (! is_a($model, \Illuminate\Database\Eloquent\Relations\Relation::class, true)) {
return true;
}

$model = $model->getRelated();
} catch (\Exception $e) {
// return true if the last part of a relation string is not a method on the model
// so it's probably the attribute that we should show
Expand Down
37 changes: 37 additions & 0 deletions tests/Unit/CrudPanel/CrudPanelColumnsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,43 @@ public function testAddRelationsByName()
}
}

public function testAddRelationByNameWithMutator()
{
$this->crudPanel->setModel(User::class);
$this->crudPanel->addColumn('accountDetails.nicknamutator');
if (backpack_pro()) {
$this->assertEquals(['accountDetails__nicknamutator' => [
'name' => 'accountDetails.nicknamutator',
'label' => 'AccountDetails.nicknamutator',
'type' => 'relationship',
'key' => 'accountDetails__nicknamutator',
'priority' => 0,
'attribute' => 'nicknamutator',
'tableColumn' => false,
'orderable' => false,
'searchLogic' => false,
'relation_type' => 'HasOne',
'entity' => 'accountDetails.nicknamutator',
'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
]], $this->crudPanel->columns());
} else {
$this->assertEquals(['accountDetails__nicknamutator' => [
'name' => 'accountDetails.nicknamutator',
'label' => 'AccountDetails.nicknamutator',
'type' => 'text',
'key' => 'accountDetails__nicknamutator',
'priority' => 0,
'attribute' => 'nicknamutator',
'tableColumn' => false,
'orderable' => false,
'searchLogic' => false,
'relation_type' => 'HasOne',
'entity' => 'accountDetails.nicknamutator',
'model' => 'Backpack\CRUD\Tests\Config\Models\AccountDetails',
]], $this->crudPanel->columns());
}
}

public function testAddRelationColumn()
{
$this->crudPanel->setModel(User::class);
Expand Down
6 changes: 6 additions & 0 deletions tests/config/Models/AccountDetails.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Backpack\CRUD\Tests\Config\Models;

use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class AccountDetails extends Model
Expand Down Expand Up @@ -49,4 +50,9 @@ public function bangsPivot()
{
return $this->belongsToMany('Backpack\CRUD\Tests\config\Models\Bang', 'account_details_bangs_pivot')->withPivot('pivot_field');
}

public function nicknamutator(): Attribute
{
return Attribute::get(fn ($value) => strtoupper($value));
}
}

0 comments on commit 1eaebf7

Please sign in to comment.