Skip to content

Commit 98c30f0

Browse files
author
Sam Rapaport
authored
Merge pull request #16 from samrap/0.3
v0.3.0 - First stable release
2 parents 51af7b9 + 3647771 commit 98c30f0

File tree

8 files changed

+282
-83
lines changed

8 files changed

+282
-83
lines changed

readme.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,20 @@ The current supported functions for the `escape` method are:
210210

211211
---
212212

213+
#### `Samrap\Acf\Fluent\Builder::shortcodes(void)`
214+
215+
You may have a textarea or WYSIWYG field in which you wish to support shortcodes. You could pass the retreived value through the `do_shortcode` function, but with ACF Fluent there is a better way. The `shortcodes` method will instruct ACF Fluent to call the WordPress `do_shortcode` function on the retrieved value automatically:
216+
217+
```php
218+
use Samrap\Acf\Acf;
219+
220+
$content = Acf::field('wysiwyg')
221+
->shortcodes()
222+
->get();
223+
```
224+
225+
If the field value is not a string, a `\Samrap\Acf\Exceptions\RunnerException` exception will be thrown.
226+
213227
#### `Samrap\Acf\Fluent\Builder::raw(void)`
214228

215229
When retrieving a field, ACF lets you specify whether or not to format the value from the database. ACF Fluent follows the plugin's convention by formatting the field by default. You may use the builder's `raw` method to retrieve the value from the database unformatted:

src/Acf.php

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@
99

1010
class Acf
1111
{
12+
/**
13+
* The class' single instance.
14+
*
15+
* @var \Samrap\Acf\Acf
16+
*/
17+
private static $instance;
18+
19+
/**
20+
* The behavior instances.
21+
*
22+
* @var \Samrap\Acf\Behaviors\BehaviorInterface[]
23+
*/
24+
private $behaviors = [];
25+
1226
/**
1327
* Private constructor to prevent instantiation.
1428
*
@@ -19,6 +33,20 @@ private function __construct()
1933
//
2034
}
2135

36+
/**
37+
* Get the single instance of this object.
38+
*
39+
* @return \Samrap\Acf\Acf
40+
*/
41+
private static function getInstance()
42+
{
43+
if (! self::$instance) {
44+
self::$instance = new self();
45+
}
46+
47+
return self::$instance;
48+
}
49+
2250
/**
2351
* Return a new builder instance for a field call.
2452
*
@@ -28,7 +56,8 @@ private function __construct()
2856
*/
2957
public static function field($name, $id = null)
3058
{
31-
return static::getBuilder(FieldBehavior::class)
59+
return self::getInstance()
60+
->getBuilder(FieldBehavior::class)
3261
->field($name)
3362
->id($id);
3463
}
@@ -41,7 +70,9 @@ public static function field($name, $id = null)
4170
*/
4271
public static function subField($name)
4372
{
44-
return static::getBuilder(SubFieldBehavior::class)->field($name);
73+
return self::getInstance()
74+
->getBuilder(SubFieldBehavior::class)
75+
->field($name);
4576
}
4677

4778
/**
@@ -52,7 +83,8 @@ public static function subField($name)
5283
*/
5384
public static function option($name)
5485
{
55-
return static::getBuilder(FieldBehavior::class)
86+
return self::getInstance()
87+
->getBuilder(FieldBehavior::class)
5688
->field($name)
5789
->id('option');
5890
}
@@ -63,8 +95,13 @@ public static function option($name)
6395
* @param string $behavior
6496
* @return \Samrap\Acf\Fluent\Builder
6597
*/
66-
private static function getBuilder($behavior)
98+
private function getBuilder($behavior)
6799
{
68-
return new Builder(new Runner(new $behavior));
100+
// Create a new behavior of the given type if one does not yet exist.
101+
if (! isset($this->behaviors[$behavior])) {
102+
$this->behaviors[$behavior] = new $behavior();
103+
}
104+
105+
return new Builder(new Runner($this->behaviors[$behavior]));
69106
}
70107
}

src/Fluent/Builder.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ class Builder
5050
public $escape;
5151

5252
/**
53+
* Whether or not to do shortcodes.
54+
*
55+
* @var bool
56+
*/
57+
public $shortcodes;
58+
59+
/*
5360
* Get the field raw (unformatted).
5461
*
5562
* @var bool
@@ -143,6 +150,16 @@ public function escape($func = 'esc_html')
143150
}
144151

145152
/**
153+
* Set the shortcodes component.
154+
*
155+
* @return \Samrap\Acf\Fluent\Builder
156+
*/
157+
public function shortcodes()
158+
{
159+
$this->shortcodes = true;
160+
}
161+
162+
/*
146163
* Set the raw component.
147164
*
148165
* @return \Samrap\Acf\Fluent\Builder

src/Fluent/Runner.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Runner
2525
protected $components = [
2626
'expect',
2727
'default',
28+
'shortcodes',
2829
'escape',
2930
];
3031

@@ -48,6 +49,17 @@ public function getBehavior()
4849
return $this->behavior;
4950
}
5051

52+
/**
53+
* Set the behavior.
54+
*
55+
* @param \Samrap\Acf\Behaviors\BehaviorInterface $behavior
56+
* @return void
57+
*/
58+
public function setBehavior(BehaviorInterface $behavior)
59+
{
60+
$this->behavior = $behavior;
61+
}
62+
5163
/**
5264
* Run the ACF 'get' behavior from the given builder.
5365
*
@@ -145,4 +157,22 @@ protected function runEscape($func, $value)
145157
? call_user_func($func, $value)
146158
: $value;
147159
}
160+
161+
/**
162+
* Do shortcodes on the given value.
163+
*
164+
* @param bool $_
165+
* @param mixed $value
166+
* @return mixed
167+
*/
168+
protected function runShortcodes($_, $value)
169+
{
170+
if (! is_string($value)) {
171+
throw new RunnerException(
172+
'Cannot do shortcode on value of type '.gettype($value)
173+
);
174+
}
175+
176+
return do_shortcode($value);
177+
}
148178
}

tests/Support/Mocks/functions.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,8 @@ function esc_textarea($text)
5454
{
5555
return $text;
5656
}
57+
58+
function do_shortcode($shortcode)
59+
{
60+
return 'shortcode '.$shortcode;
61+
}

tests/Unit/AcfTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function subFieldBuilderUsesRunnerWithSubFieldBehavior()
4444
}
4545

4646
/** @test */
47-
public function optionBuilderUserRunnerWithFieldBehavior()
47+
public function optionBuilderUsesRunnerWithFieldBehavior()
4848
{
4949
$this->assertInstanceOf(
5050
FieldBehavior::class,
@@ -58,6 +58,26 @@ public function optionBuilderUsesOptionPost()
5858
$this->assertEquals('option', Acf::option('foo')->id);
5959
}
6060

61+
/** @test */
62+
public function sameBuilderInRunner()
63+
{
64+
$one = Acf::field('foo');
65+
$two = Acf::field('bar');
66+
$three = Acf::subField('baz');
67+
68+
// Make sure that both `field` queries use the same behavior instance...
69+
$this->assertSame(
70+
$one->getRunner()->getBehavior(),
71+
$two->getRunner()->getBehavior()
72+
);
73+
74+
// ...But the `subField` query should have its own behavior.
75+
$this->assertNotSame(
76+
$one->getRunner()->getBehavior(),
77+
$three->getRunner()->getBehavior()
78+
);
79+
}
80+
6181
/** @test */
6282
public function setIdOnFieldMethod()
6383
{

tests/Unit/Fluent/BuilderTest.php

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,92 +6,115 @@
66

77
class BuilderTest extends TestCase
88
{
9-
/** @var \Samrap\Acf\Fluent\Builder */
10-
protected $builder;
11-
129
public function setUp()
1310
{
1411
$this->setFields(['foo' => 'bar']);
15-
16-
$this->builder = new Builder(new RunnerMock);
1712
}
1813

1914
/** @test */
2015
public function setField()
2116
{
22-
$this->builder->field('foo');
17+
$builder = new Builder(new RunnerMock);
18+
19+
$builder->field('foo');
2320

24-
$this->assertEquals('foo', $this->builder->field);
21+
$this->assertEquals('foo', $builder->field);
2522
}
2623

2724
/** @test */
2825
public function setExpect()
2926
{
30-
$this->builder->expect('string');
27+
$builder = new Builder(new RunnerMock);
3128

32-
$this->assertEquals('string', $this->builder->expect);
29+
$builder->expect('string');
30+
31+
$this->assertEquals('string', $builder->expect);
3332
}
3433

3534
/** @test */
3635
public function setDefault()
3736
{
38-
$this->builder->default('bar');
37+
$builder = new Builder(new RunnerMock);
38+
39+
$builder->default('bar');
3940

40-
$this->assertEquals('bar', $this->builder->default);
41+
$this->assertEquals('bar', $builder->default);
4142
}
4243

4344
/** @test */
4445
public function setEscape()
4546
{
46-
$this->builder->escape();
47+
$builder = new Builder(new RunnerMock);
4748

48-
$this->assertEquals('esc_html', $this->builder->escape);
49+
$builder->escape();
50+
51+
$this->assertEquals('esc_html', $builder->escape);
4952
}
5053

5154
/** @test */
5255
public function setEscapeAllowsCustomFunction()
5356
{
54-
$this->builder->escape('htmlentities');
57+
$builder = new Builder(new RunnerMock);
58+
59+
$builder->escape('htmlentities');
5560

56-
$this->assertEquals('htmlentities', $this->builder->escape);
61+
$this->assertEquals('htmlentities', $builder->escape);
5762
}
5863

5964
/** @test */
6065
public function setId()
6166
{
62-
$this->builder->id(2);
67+
$builder = new Builder(new RunnerMock);
68+
69+
$builder->id(2);
6370

64-
$this->assertEquals(2, $this->builder->id);
71+
$this->assertEquals(2, $builder->id);
72+
}
73+
74+
/** @test */
75+
public function setShortcodes()
76+
{
77+
$builder = new Builder(new RunnerMock);
78+
79+
$builder->shortcodes();
80+
81+
$this->assertTrue($builder->shortcodes);
6582
}
6683

6784
/** @test */
6885
public function setRaw()
6986
{
70-
$this->builder->raw();
87+
$builder = new Builder(new RunnerMock);
88+
89+
$builder->raw();
7190

72-
$this->assertTrue($this->builder->raw);
91+
$this->assertTrue($builder->raw);
7392
}
7493

7594
/** @test */
7695
public function fluentBuilder()
7796
{
78-
$this->builder
97+
$builder = new Builder(new RunnerMock);
98+
99+
$builder
79100
->field('foo')
80101
->id(2)
81102
->expect('string')
82103
->default('bar')
83104
->escape();
84105

85-
$this->assertEquals('foo', $this->builder->field);
86-
$this->assertEquals('string', $this->builder->expect);
87-
$this->assertEquals('bar', $this->builder->default);
88-
$this->assertEquals('esc_html', $this->builder->escape);
106+
$this->assertEquals('foo', $builder->field);
107+
$this->assertEquals('string', $builder->expect);
108+
$this->assertEquals('bar', $builder->default);
109+
$this->assertEquals('esc_html', $builder->escape);
89110
}
90111

91112
/** @test */
92113
public function builderGet()
93114
{
94-
$this->assertEquals('bar', $this->builder->field('foo')->get());
115+
$builder = new Builder(new RunnerMock);
116+
117+
$this->assertEquals('bar', $builder->field('foo')->get());
95118
}
96119

97120
/**
@@ -100,14 +123,18 @@ public function builderGet()
100123
*/
101124
public function builderGetThrowsExceptionIfFieldNotSet()
102125
{
103-
$this->builder->get();
126+
$builder = new Builder(new RunnerMock);
127+
128+
$builder->get();
104129
}
105130

106131
/** @test */
107132
public function builderUpdate()
108133
{
109-
$this->builder->field('foo')->update('fiz');
134+
$builder = new Builder(new RunnerMock);
135+
136+
$builder->field('foo')->update('fiz');
110137

111-
$this->assertEquals('fiz', $this->builder->field('foo')->get());
138+
$this->assertEquals('fiz', $builder->field('foo')->get());
112139
}
113140
}

0 commit comments

Comments
 (0)