Skip to content

Commit

Permalink
[11.x] Add strict-mode safe hasAttribute method to Eloquent (#50909)
Browse files Browse the repository at this point in the history
* add hasAttribute method

* fix test
  • Loading branch information
mateusjatenee authored Apr 5, 2024
1 parent e22bff0 commit 92beae3
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
25 changes: 20 additions & 5 deletions src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,25 @@ protected function getArrayableItems(array $values)
return $values;
}

/**
* Determine whether an attribute exists on the model.
*
* @param string $key
* @return bool
*/
public function hasAttribute($key)
{
if (! $key) {
return false;
}

return array_key_exists($key, $this->attributes) ||
array_key_exists($key, $this->casts) ||
$this->hasGetMutator($key) ||
$this->hasAttributeMutator($key) ||
$this->isClassCastable($key);
}

/**
* Get an attribute from the model.
*
Expand All @@ -448,11 +467,7 @@ public function getAttribute($key)
// If the attribute exists in the attribute array or has a "get" mutator we will
// get the attribute's value. Otherwise, we will proceed as if the developers
// are asking for a relationship's value. This covers both types of values.
if (array_key_exists($key, $this->attributes) ||
array_key_exists($key, $this->casts) ||
$this->hasGetMutator($key) ||
$this->hasAttributeMutator($key) ||
$this->isClassCastable($key)) {
if ($this->hasAttribute($key)) {
return $this->getAttributeValue($key);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function testModelsAreProperlyMatchedToParents()
{
$relation = $this->getRelation();
$model1 = m::mock(Model::class);
$model1->shouldReceive('hasAttribute')->passthru();
$model1->shouldReceive('getAttribute')->with('parent_key')->andReturn(1);
$model1->shouldReceive('getAttribute')->with('foo')->passthru();
$model1->shouldReceive('hasGetMutator')->andReturn(false);
Expand All @@ -29,6 +30,7 @@ public function testModelsAreProperlyMatchedToParents()
$model1->shouldReceive('getRelationValue', 'relationLoaded', 'relationResolver', 'setRelation', 'isRelation')->passthru();

$model2 = m::mock(Model::class);
$model2->shouldReceive('hasAttribute')->passthru();
$model2->shouldReceive('getAttribute')->with('parent_key')->andReturn(2);
$model2->shouldReceive('getAttribute')->with('foo')->passthru();
$model2->shouldReceive('hasGetMutator')->andReturn(false);
Expand Down
13 changes: 13 additions & 0 deletions tests/Database/DatabaseEloquentModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3024,6 +3024,19 @@ public function testDiscardChanges()
$this->assertNull($user->getOriginal('name'));
$this->assertNull($user->getAttribute('name'));
}

public function testHasAttribute()
{
$user = new EloquentModelStub([
'name' => 'Mateus',
]);

$this->assertTrue($user->hasAttribute('name'));
$this->assertTrue($user->hasAttribute('password'));
$this->assertTrue($user->hasAttribute('castedFloat'));
$this->assertFalse($user->hasAttribute('nonexistent'));
$this->assertFalse($user->hasAttribute('belongsToStub'));
}
}

class EloquentTestObserverStub
Expand Down

0 comments on commit 92beae3

Please sign in to comment.