Skip to content

Commit af8f509

Browse files
[12.x] EnumerateValues::value() support objects and return negative values (#57570)
* Improve the EnumerateValues::value() for returns value from first item in negative case * Improve the EnumerateValues::value() for returns value from first item in negative case * Update EnumeratesValues.php * Refactor logic of EnumerateValues::value for iterate on collection * Fix issue on EnumeratesValue::value * Refactor logic of EnumerateValues::value for iterate on collection * Add data_has helper for handle EnumerateValues::value * Add data_has helper for handle EnumerateValues::value * Add data_has helper for handle EnumerateValues::value * Add data_has helper for handle EnumerateValues::value * Update helpers.php --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
1 parent 89eb34f commit af8f509

File tree

3 files changed

+74
-4
lines changed

3 files changed

+74
-4
lines changed

src/Illuminate/Collections/Traits/EnumeratesValues.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,11 @@ public function firstWhere($key, $operator = null, $value = null)
340340
*/
341341
public function value($key, $default = null)
342342
{
343-
if ($value = $this->firstWhere($key)) {
344-
return data_get($value, $key, $default);
345-
}
343+
$value = $this->first(function ($target) use ($key) {
344+
return data_has($target, $key);
345+
});
346346

347-
return value($default);
347+
return data_get($value, $key, $default);
348348
}
349349

350350
/**

src/Illuminate/Collections/helpers.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,32 @@ function data_fill(&$target, $key, $value)
3434
}
3535
}
3636

37+
if (! function_exists('data_has')) {
38+
/**
39+
* Determine if a key / property exists on an array or object using "dot" notation.
40+
*
41+
* @param mixed $target
42+
* @param string|array|int|null $key
43+
* @return bool
44+
*/
45+
function data_has($target, $key): bool
46+
{
47+
if (Arr::accessible($target)) {
48+
return Arr::has($target, $key);
49+
}
50+
51+
$key = is_array($key) ? $key : explode('.', $key);
52+
53+
while ($property = array_shift($key)) {
54+
if (property_exists($target, $property)) {
55+
return $key ? data_has($target->{$property}, $key) : true;
56+
}
57+
}
58+
59+
return false;
60+
}
61+
}
62+
3763
if (! function_exists('data_get')) {
3864
/**
3965
* Get an item from an array or object using "dot" notation.

tests/Support/SupportCollectionTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,50 @@ public function testValueUsingEnum($collection)
11821182
$this->assertEquals(StaffEnum::Joe, $c->where('id', 2)->value('name'));
11831183
}
11841184

1185+
#[DataProvider('collectionClassProvider')]
1186+
public function testValueWithNegativeValue($collection)
1187+
{
1188+
$c = new $collection([['id' => 1, 'balance' => 0], ['id' => 2, 'balance' => 200]]);
1189+
1190+
$this->assertEquals(0, $c->value('balance'));
1191+
1192+
$c = new $collection([['id' => 1, 'balance' => ''], ['id' => 2, 'balance' => 200]]);
1193+
1194+
$this->assertEquals('', $c->value('balance'));
1195+
1196+
$c = new $collection([['id' => 1, 'balance' => null], ['id' => 2, 'balance' => 200]]);
1197+
1198+
$this->assertEquals(null, $c->value('balance'));
1199+
1200+
$c = new $collection([['id' => 1], ['id' => 2, 'balance' => 200]]);
1201+
1202+
$this->assertEquals(200, $c->value('balance'));
1203+
1204+
$c = new $collection([['id' => 1], ['id' => 2, 'balance' => 0], ['id' => 3, 'balance' => 200]]);
1205+
1206+
$this->assertEquals(0, $c->value('balance'));
1207+
}
1208+
1209+
#[DataProvider('collectionClassProvider')]
1210+
public function testValueWithObjects($collection)
1211+
{
1212+
$c = new $collection([
1213+
literal(id: 1),
1214+
literal(id: 2, balance: ''),
1215+
literal(id: 3, balance: 200),
1216+
]);
1217+
1218+
$this->assertEquals('', $c->value('balance'));
1219+
1220+
$c = new $collection([
1221+
literal(id: 1),
1222+
literal(id: 2, balance: literal(currency: 'USD', value: 0)),
1223+
literal(id: 3, balance: literal(currency: 'USD', value: 200)),
1224+
]);
1225+
1226+
$this->assertEquals(0, $c->value('balance.value'));
1227+
}
1228+
11851229
#[DataProvider('collectionClassProvider')]
11861230
public function testBetween($collection)
11871231
{

0 commit comments

Comments
 (0)