Skip to content

Commit 91a7a5b

Browse files
committed
add support for includes
1 parent 79974ca commit 91a7a5b

File tree

5 files changed

+173
-0
lines changed

5 files changed

+173
-0
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,29 @@ fractal()
171171
You can change the default serializer by providing the classname of your favorite serializer in
172172
the config file.
173173

174+
### Using includes
175+
176+
Fractal provides support for [optionally including data](http://fractal.thephpleague.com/transformers/) on the relationships for
177+
the data you're exporting. You can use Fractal's `parseInclude` which accepts a string or an array:
178+
179+
```php
180+
$resultWithParseCharacters = fractal()
181+
->collection($this->testBooks, new TestTransformer())
182+
->parseIncludes(['characters', 'publisher'])
183+
->toArray();
184+
```
185+
186+
To improve readablity you can also a function named `include` followed by the name
187+
of the include you want to... include:
188+
189+
```php
190+
$resultWithParseCharacters = fractal()
191+
->collection($this->testBooks, new TestTransformer())
192+
->includeCharacters()
193+
->includePublisher()
194+
->toArray();
195+
```
196+
174197
## Change log
175198

176199
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

src/Fractal.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class Fractal
2424
*/
2525
protected $transformer;
2626

27+
/**
28+
* @var array
29+
*/
30+
protected $includes = [];
31+
2732
/**
2833
* @var string
2934
*/
@@ -104,6 +109,40 @@ public function transformWith($transformer)
104109
return $this;
105110
}
106111

112+
/**
113+
* Specify the includes
114+
*
115+
* @param array|string $includes Array or csv string of resources to include
116+
*
117+
* @return $this
118+
*/
119+
public function parseIncludes($includes)
120+
{
121+
if (is_string($includes)) {
122+
$includes = [$includes];
123+
}
124+
125+
$this->includes = array_merge($this->includes, $includes);
126+
127+
return $this;
128+
}
129+
130+
/**
131+
* Support for magic methods to included data.
132+
*
133+
* @return $this
134+
*/
135+
public function __call($name, array $arguments)
136+
{
137+
if (! starts_with($name, 'include')) {
138+
trigger_error('Call to undefined method '.__CLASS__.'::'.$methodName.'()', E_USER_ERROR);
139+
}
140+
141+
$includeName = lcfirst(substr($name, strlen('include')));
142+
143+
return $this->parseIncludes($includeName);
144+
}
145+
107146
/**
108147
* Set the serializer to be used.
109148
*
@@ -158,6 +197,10 @@ protected function transform($conversionMethod)
158197
$this->manager->setSerializer($this->serializer);
159198
}
160199

200+
if (!is_null($this->includes)) {
201+
$this->manager->parseIncludes($this->includes);
202+
}
203+
161204
$resource = $this->getResource();
162205

163206
$fractalData = $this->manager->createData($resource);

tests/Integration/IncludesTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Spatie\Fractal\Test\Integration;
4+
5+
class IncludesTest extends TestCase
6+
{
7+
/**
8+
* @test
9+
*/
10+
public function it_can_parse_includes()
11+
{
12+
$array = $this->fractal
13+
->collection($this->testBooks, new TestTransformer())
14+
->parseIncludes('characters')
15+
->toArray();
16+
17+
$expectedArray = ['data' => [
18+
['id' => 1, 'author' => 'Philip K Dick', 'characters' => ['data' => ['Death', 'Hex']]],
19+
['id' => 2, 'author' => 'George R. R. Satan', 'characters' => ['data' => ['Ned Stark', 'Tywin Lannister']]],
20+
]];
21+
22+
$this->assertEquals($expectedArray, $array);
23+
}
24+
25+
/**
26+
* @test
27+
*/
28+
public function it_provides_a_convenience_method_to_include_includes()
29+
{
30+
$resultWithParseIncludes = fractal()
31+
->collection($this->testBooks, new TestTransformer())
32+
->parseIncludes('characters')
33+
->toArray();
34+
35+
$resultWithParseCharacters = fractal()
36+
->collection($this->testBooks, new TestTransformer())
37+
->includeCharacters()
38+
->toArray();
39+
40+
$this->assertEquals($resultWithParseIncludes, $resultWithParseCharacters);
41+
}
42+
43+
/**
44+
* @test
45+
*/
46+
public function it_can_handle_multiple_includes()
47+
{
48+
$array = $this->fractal
49+
->collection($this->testBooks, new TestTransformer())
50+
->includeCharacters()
51+
->includePublisher()
52+
->toArray();
53+
54+
$expectedArray = ['data' => [
55+
['id' => 1, 'author' => 'Philip K Dick', 'characters' => ['data' => ['Death', 'Hex']], 'publisher' => ['data' => ['Elephant books']]],
56+
['id' => 2, 'author' => 'George R. R. Satan', 'characters' => ['data' => ['Ned Stark', 'Tywin Lannister']], 'publisher' => ['data' => ['Bloody Fantasy inc.']]],
57+
]];
58+
59+
$this->assertEquals($expectedArray, $array);
60+
}
61+
}

tests/Integration/TestCase.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,17 @@ public function setUp($defaultSerializer = '')
3838
'yr' => '1998',
3939
'author_name' => 'Philip K Dick',
4040
'author_email' => '[email protected]',
41+
'characters' => [['name' => 'Death'], ['name' => 'Hex']],
42+
'publisher' => 'Elephant books',
4143
],
4244
[
4345
'id' => '2',
4446
'title' => 'Game Of Kill Everyone',
4547
'yr' => '2014',
4648
'author_name' => 'George R. R. Satan',
4749
'author_email' => '[email protected]',
50+
'characters' => [['name' => 'Ned Stark'], ['name' => 'Tywin Lannister']],
51+
'publisher' => 'Bloody Fantasy inc.',
4852
],
4953
];
5054
}

tests/Integration/TestTransformer.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66

77
class TestTransformer extends TransformerAbstract
88
{
9+
/**
10+
* List of resources possible to include.
11+
*
12+
* @var array
13+
*/
14+
protected $availableIncludes = [
15+
'characters',
16+
'publisher',
17+
];
18+
919
/**
1020
* @param array $book
1121
*
@@ -18,4 +28,36 @@ public function transform(array $book)
1828
'author' => $book['author_name'],
1929
];
2030
}
31+
32+
/**
33+
* Include characters.
34+
*
35+
* @param array $book
36+
*
37+
* @return \League\Fractal\ItemResource
38+
*/
39+
public function includeCharacters(array $book)
40+
{
41+
$characters = $book['characters'];
42+
43+
return $this->collection($characters, function ($character) {
44+
return $character['name'];
45+
});
46+
}
47+
48+
/**
49+
* Include characters.
50+
*
51+
* @param array $book
52+
*
53+
* @return \League\Fractal\ItemResource
54+
*/
55+
public function includePublisher(array $book)
56+
{
57+
$publisher = $book['publisher'];
58+
59+
return $this->item([$publisher], function ($publisher) {
60+
return $publisher;
61+
});
62+
}
2163
}

0 commit comments

Comments
 (0)