Skip to content

Commit

Permalink
[5.x] Attribute Modifier (#9796)
Browse files Browse the repository at this point in the history
Co-authored-by: Duncan McClean <[email protected]>
Co-authored-by: Jason Varga <[email protected]>
  • Loading branch information
3 people authored May 21, 2024
1 parent 62524db commit 73c48a4
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/Modifiers/CoreModifiers.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,48 @@ public function at($value, $params)
return Stringy::at($value, Arr::get($params, 0));
}

/**
* Returns an attribute ($params[0]) with its value when the given $value variable is not empty.
*
* @param string $value
* @param array $params
* @return string
*/
public function attribute($value, $params)
{
if (! $name = Arr::get($params, 0)) {
throw new \Exception('Attribute name is required.');
}

if ($value instanceof Collection) {
$value = $value->all();
}

if (\is_array($value)) {
if (empty($value)) {
return '';
}

$value = \json_encode($value);
}

if (\is_bool($value)) {
return $value ? ' '.$name : '';
}

if (\is_object($value)) {
$value = (string) $value;
}

$value = trim($value);

if ($value === '') {
return '';
}

return sprintf(' %s="%s"', $name, Html::entities($value));
}

/**
* Returns a focal point as a background-position CSS value.
*
Expand Down
74 changes: 74 additions & 0 deletions tests/Modifiers/AttributeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Tests\Modifiers;

use Statamic\Modifiers\Modify;
use Tests\TestCase;

class AttributeTest extends TestCase
{
/**
* @test
*
* @dataProvider attributeProvider
*/
public function it_converts_to_attribute($value, $expected)
{
$this->assertEquals($expected, $this->modify($value, 'foo'));
}

public static function attributeProvider()
{
return [
'string' => ['bar baz', ' foo="bar baz"'],
'entities' => ['{<!&>}', ' foo="{&lt;!&amp;&gt;}"'],
'integer' => [1, ' foo="1"'],
'integer > 1' => [2, ' foo="2"'],
'negative integer' => [-1, ' foo="-1"'],
'float' => [1.5, ' foo="1.5"'],
'empty string' => ['', ''],
'true' => [true, ' foo'],
'false' => [false, ''],
'array' => [['one' => ['two' => 'three']], ' foo="{&quot;one&quot;:{&quot;two&quot;:&quot;three&quot;}}"'],
'empty array' => [[], ''],
'collection' => [collect(['one' => 'two']), ' foo="{&quot;one&quot;:&quot;two&quot;}"'],
'empty collection' => [collect(), ''],
'object with __toString' => [new AttributeTestStringable, ' foo="Test"'],
];
}

/** @test */
public function it_throws_exception_without_argument()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Attribute name is required.');

$this->modify('value', null);
}

/** @test */
public function it_throws_exception_when_value_is_an_object_without_toString_method()
{
$this->expectException(\Error::class);
$this->expectExceptionMessage('Object of class Tests\Modifiers\AttributeTestNotStringable could not be converted to string');

$this->modify(new AttributeTestNotStringable, 'foo');
}

private function modify($value, $attribute)
{
return Modify::value($value)->attribute($attribute)->fetch();
}
}

class AttributeTestStringable
{
public function __toString()
{
return 'Test';
}
}

class AttributeTestNotStringable
{
}

0 comments on commit 73c48a4

Please sign in to comment.