Skip to content

Instantly share code, notes, and snippets.

@mikehaertl
Last active Dec 28, 2015
Embed
What would you like to do?
Reorganization of Yii2 REST HAL implementation
<?php
namespace app\models;
use Yii;
use yii\web\Link;
use yii\web\Linkable;
use yii\helpers\Url;
// Use HAL trait
use yii\rest\hal\ArrayableTrait;
class User extends ActiveRecord implements IdentityInterface, Linkable
{
use ArrayableTrait;
public function extraFields()
{
return ['profile'];
}
public function getLinks()
{
return [
Link::REL_SELF => Url::to(['user/view', 'id' => $this->id], true),
];
}
public function getProfile()
{
return $this->hasOne(Profile::className(), ['user_id' => 'id']);
}
}
<?php
// Only showing the modifications in this class
// Removed the Link/Linkable 'use' on top
trait ArrayableTrait
{
// ...
public function toArray(array $fields = [], array $expand = [], $recursive = true)
{
$data = [];
foreach ($this->resolveFields($fields, $expand) as $field => $definition) {
$data[$field] = is_string($definition) ? $this->$definition : call_user_func($definition, $this, $field);
}
// Remove the Linkable stuff
return $recursive ? ArrayHelper::toArray($data) : $data;
}
// Method required to be public
public function resolveFields(array $fields, array $expand)
{
<?php
use yii\helpers\ArrayHelper;
use yii\web\Link;
use yii\web\Linkable;
trait ArrayableTrait
{
public function toArray(array $fields = [], array $expand = [], $recursive = true)
{
$data = [];
foreach ($this->resolveFields($fields, $expand) as $field => $definition) {
$value = is_string($definition) ? $this->$definition : call_user_func($definition, $this, $field);
if (is_object($value)) {
if ($recursive) {
$value = ($value instanceof Arrayable) ? $value->toArray() : ArrayHelper::toArray($value);
}
if (!isset($data['_embedded'])) {
$data['_embedded'] = [];
}
$data['_embedded'][$field] = $value;
} elseif (is_array($value) && count($value)) {
// If the first element is an object we assume a list of objects
$first = current($value);
if (is_object($first)) {
if (!isset($data['_embedded'])) {
$data['_embedded'] = [];
}
if (!isset($data['_embedded'][$field])) {
$data['_embedded'][$field] = [];
}
foreach($value as $k => $v) {
if ($recursive) {
$v = ($v instanceof Arrayable) ? $v->toArray() : ArrayHelper::toArray($v);
}
$data['_embedded'][$field][$k] = $value;
}
} else {
$data[$field] = $value;
}
} else {
$data[$field] = $value;
}
}
if ($this instanceof Linkable) {
$data['_links'] = Link::serialize($this->getLinks());
}
return $data;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment