mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-20 16:38:22 +08:00
Finished HATEOAS support.
This commit is contained in:
@@ -12,8 +12,8 @@ In particular, Yii provides support for the following aspects regarding RESTful
|
|||||||
* Support `OPTIONS` and `HEAD` verbs;
|
* Support `OPTIONS` and `HEAD` verbs;
|
||||||
* Authentication;
|
* Authentication;
|
||||||
* Authorization;
|
* Authorization;
|
||||||
|
* Support for HATEOAS;
|
||||||
* Caching via `yii\web\HttpCache`;
|
* Caching via `yii\web\HttpCache`;
|
||||||
* Support for HATEOAS: TBD
|
|
||||||
* Rate limiting: TBD
|
* Rate limiting: TBD
|
||||||
* Searching and filtering: TBD
|
* Searching and filtering: TBD
|
||||||
* Testing: TBD
|
* Testing: TBD
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ use yii\helpers\ArrayHelper;
|
|||||||
use yii\helpers\Inflector;
|
use yii\helpers\Inflector;
|
||||||
use yii\validators\RequiredValidator;
|
use yii\validators\RequiredValidator;
|
||||||
use yii\validators\Validator;
|
use yii\validators\Validator;
|
||||||
|
use yii\web\Link;
|
||||||
|
use yii\web\Linkable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model is the base class for data models.
|
* Model is the base class for data models.
|
||||||
@@ -876,6 +878,11 @@ class Model extends Component implements IteratorAggregate, ArrayAccess, Arrayab
|
|||||||
foreach ($this->resolveFields($fields, $expand) as $field => $definition) {
|
foreach ($this->resolveFields($fields, $expand) as $field => $definition) {
|
||||||
$data[$field] = is_string($definition) ? $this->$definition : call_user_func($definition, $field, $this);
|
$data[$field] = is_string($definition) ? $this->$definition : call_user_func($definition, $field, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this instanceof Linkable) {
|
||||||
|
$data['_links'] = Link::serialize($this->getLinks());
|
||||||
|
}
|
||||||
|
|
||||||
return $recursive ? ArrayHelper::toArray($data) : $data;
|
return $recursive ? ArrayHelper::toArray($data) : $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ namespace yii\data;
|
|||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\Object;
|
use yii\base\Object;
|
||||||
|
use yii\web\Link;
|
||||||
|
use yii\web\Linkable;
|
||||||
use yii\web\Request;
|
use yii\web\Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,9 +67,8 @@ use yii\web\Request;
|
|||||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class Pagination extends Object
|
class Pagination extends Object implements Linkable
|
||||||
{
|
{
|
||||||
const LINK_SELF = 'self';
|
|
||||||
const LINK_NEXT = 'next';
|
const LINK_NEXT = 'next';
|
||||||
const LINK_PREV = 'prev';
|
const LINK_PREV = 'prev';
|
||||||
const LINK_FIRST = 'first';
|
const LINK_FIRST = 'first';
|
||||||
@@ -301,7 +302,7 @@ class Pagination extends Object
|
|||||||
$currentPage = $this->getPage();
|
$currentPage = $this->getPage();
|
||||||
$pageCount = $this->getPageCount();
|
$pageCount = $this->getPageCount();
|
||||||
$links = [
|
$links = [
|
||||||
self::LINK_SELF => $this->createUrl($currentPage, $absolute),
|
Link::REL_SELF => $this->createUrl($currentPage, $absolute),
|
||||||
];
|
];
|
||||||
if ($currentPage > 0) {
|
if ($currentPage > 0) {
|
||||||
$links[self::LINK_FIRST] = $this->createUrl(0, $absolute);
|
$links[self::LINK_FIRST] = $this->createUrl(0, $absolute);
|
||||||
|
|||||||
83
framework/web/Link.php
Normal file
83
framework/web/Link.php
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link http://www.yiiframework.com/
|
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||||
|
* @license http://www.yiiframework.com/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace yii\web;
|
||||||
|
|
||||||
|
use yii\base\Arrayable;
|
||||||
|
use yii\base\Object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link represents a link object as defined in [JSON Hypermedia API Language](https://tools.ietf.org/html/draft-kelly-json-hal-03).
|
||||||
|
*
|
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class Link extends Object implements Arrayable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The self link.
|
||||||
|
*/
|
||||||
|
const REL_SELF = 'self';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string a URI [RFC3986](https://tools.ietf.org/html/rfc3986) or
|
||||||
|
* URI template [RFC6570](https://tools.ietf.org/html/rfc6570). This property is required.
|
||||||
|
*/
|
||||||
|
public $href;
|
||||||
|
/**
|
||||||
|
* @var string a secondary key for selecting Link Objects which share the same relation type
|
||||||
|
*/
|
||||||
|
public $name;
|
||||||
|
/**
|
||||||
|
* @var string a hint to indicate the media type expected when dereferencing the target resource
|
||||||
|
*/
|
||||||
|
public $type;
|
||||||
|
/**
|
||||||
|
* @var boolean a value indicating whether [[href]] refers to a URI or URI template.
|
||||||
|
*/
|
||||||
|
public $templated = false;
|
||||||
|
/**
|
||||||
|
* @var string a URI that hints about the profile of the target resource.
|
||||||
|
*/
|
||||||
|
public $profile;
|
||||||
|
/**
|
||||||
|
* @var string a label describing the link
|
||||||
|
*/
|
||||||
|
public $title;
|
||||||
|
/**
|
||||||
|
* @var string the language of the target resource
|
||||||
|
*/
|
||||||
|
public $hreflang;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function toArray()
|
||||||
|
{
|
||||||
|
return array_filter((array)$this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a list of links into proper array format.
|
||||||
|
* @param array $links the links to be serialized
|
||||||
|
* @return array the proper array representation of the links.
|
||||||
|
*/
|
||||||
|
public static function serialize(array $links)
|
||||||
|
{
|
||||||
|
foreach ($links as $rel => $link) {
|
||||||
|
if (is_array($link)) {
|
||||||
|
foreach ($link as $i => $l) {
|
||||||
|
$link[$i] = $l instanceof self ? $l->toArray() : ['href' => $l];
|
||||||
|
}
|
||||||
|
$links[$rel] = $link;
|
||||||
|
} elseif (!$link instanceof self) {
|
||||||
|
$links[$rel] = ['href' => $link];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
}
|
||||||
42
framework/web/Linkable.php
Normal file
42
framework/web/Linkable.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link http://www.yiiframework.com/
|
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||||
|
* @license http://www.yiiframework.com/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace yii\web;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linkable is the interface that should be implemented by classes that typically represent locatable resources.
|
||||||
|
*
|
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
interface Linkable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns a list of links.
|
||||||
|
*
|
||||||
|
* Each link is either a URI or a [[Link]] object. The return value of this method should
|
||||||
|
* be an array whose keys are the relation names and values the corresponding links.
|
||||||
|
*
|
||||||
|
* If a relation name corresponds to multiple links, use an array to represent them.
|
||||||
|
*
|
||||||
|
* For example,
|
||||||
|
*
|
||||||
|
* ```php
|
||||||
|
* [
|
||||||
|
* 'self' => 'http://example.com/users/1',
|
||||||
|
* 'friends' => [
|
||||||
|
* 'http://example.com/users/2',
|
||||||
|
* 'http://example.com/users/3',
|
||||||
|
* ],
|
||||||
|
* 'manager' => $managerLink, // $managerLink is a Link object
|
||||||
|
* ]
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @return array the links
|
||||||
|
*/
|
||||||
|
public function getLinks();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user