Skip to content

Commit a3af428

Browse files
committed
resource serialize
1 parent 96415fc commit a3af428

File tree

4 files changed

+258
-0
lines changed

4 files changed

+258
-0
lines changed

src/ResourceIdentifierInterface.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
/**
3+
* @author Anton Tuyakhov <atuyakhov@gmail.com>
4+
*/
5+
6+
namespace tuyakhov\jsonapi;
7+
8+
9+
interface ResourceIdentifierInterface
10+
{
11+
public function getId();
12+
13+
public function getType();
14+
}

src/ResourceInterface.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
/**
3+
* @author Anton Tuyakhov <atuyakhov@gmail.com>
4+
*/
5+
6+
namespace tuyakhov\jsonapi;
7+
8+
9+
interface ResourceInterface extends ResourceIdentifierInterface
10+
{
11+
public function getAttributes(array $fields = []);
12+
13+
public function getRelationships();
14+
15+
public function getLinks();
16+
17+
public function getMeta();
18+
19+
}

src/ResourceTrait.php

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?php
2+
/**
3+
* @link http://www.stombox.com/
4+
* @copyright Copyright (c) 2015 Stombox LLC
5+
* @license http://www.stombox.com/license/
6+
*/
7+
8+
namespace tuyakhov\jsonapi;
9+
10+
11+
use yii\base\Arrayable;
12+
use yii\db\ActiveRecordInterface;
13+
use yii\helpers\ArrayHelper;
14+
use yii\helpers\Inflector;
15+
16+
trait ResourceTrait
17+
{
18+
/**
19+
* @return null|string
20+
*/
21+
public function getId()
22+
{
23+
if ($this instanceof ActiveRecordInterface) {
24+
return (string) $this->getPrimaryKey();
25+
}
26+
return null;
27+
}
28+
29+
/**
30+
* @return string
31+
*/
32+
public function getType()
33+
{
34+
$reflect = new \ReflectionClass($this);
35+
$className = $reflect->getShortName();
36+
return Inflector::pluralize(Inflector::camel2id($className));
37+
}
38+
39+
/**
40+
* @param array $fields
41+
* @return array
42+
*/
43+
public function getAttributes(array $fields = [])
44+
{
45+
$attributes = [];
46+
47+
foreach (self::resolveFields($this->fields(), $fields) as $name => $definition) {
48+
$attributes[$name] = is_string($definition) ? $this->$definition : call_user_func($definition, $this, $name);
49+
}
50+
return $attributes;
51+
}
52+
53+
/**
54+
* @return array
55+
*/
56+
public function getRelationships()
57+
{
58+
$relationships = [];
59+
60+
foreach (self::resolveFields($this->extraFields()) as $name => $definition) {
61+
if (is_string($definition)) {
62+
$relation = $this->$definition;
63+
if (!is_array($relation)) {
64+
$relation = [$relation];
65+
}
66+
foreach($relation as $item) {
67+
if ($item instanceof ResourceIdentifierInterface) {
68+
$relationships[$name]['data'] = ['id' => $item->getId(), 'type' => $item->getType()];
69+
}
70+
}
71+
// TODO add links and meta. Should create interface
72+
}
73+
}
74+
return $relationships;
75+
}
76+
77+
/**
78+
* @param array $fields
79+
* @param array $expand
80+
* @param bool $recursive
81+
* @return array
82+
*/
83+
public function toArray(array $fields = [], array $expand = [], $recursive = true)
84+
{
85+
$data = [
86+
'id' => $this->getId(),
87+
'type' => $this->getType(),
88+
];
89+
$attributes = $this->getAttributes($fields);
90+
$relationships = $this->getRelationships();
91+
if (!empty($attributes)) {
92+
$data['attributes'] = $attributes;
93+
}
94+
if (!empty($relationships)) {
95+
$data['relationships'] = $relationships;
96+
}
97+
98+
// TODO add links and meta. Should create interface
99+
100+
return $recursive ? ArrayHelper::toArray($data) : $data;
101+
}
102+
103+
/**
104+
* @return array
105+
*/
106+
public function fields()
107+
{
108+
$fields = array_keys(\Yii::getObjectVars($this));
109+
return array_combine($fields, $fields);
110+
}
111+
112+
/**
113+
* @return array
114+
*/
115+
public function extraFields()
116+
{
117+
return [];
118+
}
119+
120+
/**
121+
* @param array $fields
122+
* @param array $fieldSet
123+
* @return array
124+
*/
125+
protected static function resolveFields(array $fields, array $fieldSet = [])
126+
{
127+
$result = [];
128+
129+
foreach ($fields as $field => $definition) {
130+
if (is_int($field)) {
131+
$field = $definition;
132+
}
133+
if (empty($fieldSet) || in_array($field, $fieldSet, true)) {
134+
$result[$field] = $definition;
135+
}
136+
}
137+
138+
return $result;
139+
}
140+
}

src/Serializer.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
/**
3+
* @link http://www.stombox.com/
4+
* @copyright Copyright (c) 2015 Stombox LLC
5+
* @license http://www.stombox.com/license/
6+
*/
7+
8+
namespace tuyakhov\jsonapi;
9+
10+
use yii\base\Model;
11+
12+
class Serializer extends \yii\rest\Serializer
13+
{
14+
/**
15+
* @var $modelNamespace string the namespace that model classes are in
16+
*/
17+
public $modelNamespace;
18+
19+
/**
20+
* @var $modelMapping array
21+
*/
22+
public $modelMapping = [];
23+
24+
/**
25+
* @var string resources that are related to the primary data
26+
*/
27+
public $expandParam = 'include';
28+
29+
/**
30+
* @inheritdoc
31+
*/
32+
public function init()
33+
{
34+
if ($this->modelNamespace === null) {
35+
$class = get_class(\Yii::$app);
36+
if (($pos = strrpos($class, '\\')) !== false) {
37+
$this->modelNamespace = substr($class, 0, $pos) . '\\models';
38+
}
39+
}
40+
parent::init();
41+
}
42+
43+
/**
44+
* Serializes a model object.
45+
* @param Model $model
46+
* @return array
47+
*/
48+
public function serializeModel($model)
49+
{
50+
$data = [];
51+
52+
if ($this->request->getIsHead()) {
53+
return null;
54+
} else {
55+
list ($fields, $relationships) = $this->getRequestedFields();
56+
if (!empty($relationships)) {
57+
// TODO Implement included. Compound Documents
58+
}
59+
$data['data'] = $model->toArray($fields);
60+
}
61+
return $data;
62+
}
63+
64+
/**
65+
* @return array
66+
*/
67+
protected function getRequestedFields()
68+
{
69+
$fields = $this->request->get($this->fieldsParam);
70+
$relationships = $this->request->get($this->expandParam);
71+
72+
if (!is_array($fields)) {
73+
$fields = [];
74+
}
75+
foreach ($fields as $key => $field) {
76+
$fields[$key] = preg_split('/\s*,\s*/', $fields, -1, PREG_SPLIT_NO_EMPTY);
77+
}
78+
$relationships = preg_split('/\s*,\s*/', $relationships, -1, PREG_SPLIT_NO_EMPTY);
79+
return [
80+
$fields,
81+
$relationships
82+
];
83+
}
84+
85+
}

0 commit comments

Comments
 (0)