mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 06:15:19 +08:00
Fixes #2655: Arrayable and ArrayableTrait are incompatible for some PHP versions.
This commit is contained in:
@ -8,7 +8,14 @@
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* Arrayable should be implemented by classes that need to be represented in array format.
|
||||
* Arrayable is the interface that should be implemented by classes who want to support customizable representation of their instances.
|
||||
*
|
||||
* For example, if a class implements Arrayable, by calling [[toArray()]], an instance of this class
|
||||
* can be turned into an array (including all its embedded objects) which can then be further transformed easily
|
||||
* into other formats, such as JSON, XML.
|
||||
*
|
||||
* The methods [[fields()]] and [[extraFields()]] allow the implementing classes to customize how and which of their data
|
||||
* should be formatted and put into the result of [[toArray()]].
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
@ -16,8 +23,68 @@ namespace yii\base;
|
||||
interface Arrayable
|
||||
{
|
||||
/**
|
||||
* Converts the object into an array.
|
||||
* @return array the array representation of this object
|
||||
* Returns the list of fields that should be returned by default by [[toArray()]] when no specific fields are specified.
|
||||
*
|
||||
* A field is a named element in the returned array by [[toArray()]].
|
||||
*
|
||||
* This method should return an array of field names or field definitions.
|
||||
* If the former, the field name will be treated as an object property name whose value will be used
|
||||
* as the field value. If the latter, the array key should be the field name while the array value should be
|
||||
* the corresponding field definition which can be either an object property name or a PHP callable
|
||||
* returning the corresponding field value. The signature of the callable should be:
|
||||
*
|
||||
* ```php
|
||||
* function ($field, $model) {
|
||||
* // return field value
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* For example, the following code declares four fields:
|
||||
*
|
||||
* - `email`: the field name is the same as the property name `email`;
|
||||
* - `firstName` and `lastName`: the field names are `firstName` and `lastName`, and their
|
||||
* values are obtained from the `first_name` and `last_name` properties;
|
||||
* - `fullName`: the field name is `fullName`. Its value is obtained by concatenating `first_name`
|
||||
* and `last_name`.
|
||||
*
|
||||
* ```php
|
||||
* return [
|
||||
* 'email',
|
||||
* 'firstName' => 'first_name',
|
||||
* 'lastName' => 'last_name',
|
||||
* 'fullName' => function () {
|
||||
* return $this->first_name . ' ' . $this->last_name;
|
||||
* },
|
||||
* ];
|
||||
* ```
|
||||
*
|
||||
* @return array the list of field names or field definitions.
|
||||
* @see toArray()
|
||||
*/
|
||||
public function toArray();
|
||||
public function fields();
|
||||
/**
|
||||
* Returns the list of additional fields that can be returned by [[toArray()]] in addition to those listed in [[fields()]].
|
||||
*
|
||||
* This method is similar to [[fields()]] except that the list of fields declared
|
||||
* by this method are not returned by default by [[toArray()]]. Only when a field in the list
|
||||
* is explicitly requested, will it be included in the result of [[toArray()]].
|
||||
*
|
||||
* @return array the list of expandable field names or field definitions. Please refer
|
||||
* to [[fields()]] on the format of the return value.
|
||||
* @see toArray()
|
||||
* @see fields()
|
||||
*/
|
||||
public function extraFields();
|
||||
/**
|
||||
* Converts the object into an array.
|
||||
*
|
||||
* @param array $fields the fields that the output array should contain. Fields not specified
|
||||
* in [[fields()]] will be ignored. If this parameter is empty, all fields as specified in [[fields()]] will be returned.
|
||||
* @param array $expand the additional fields that the output array should contain.
|
||||
* Fields not specified in [[extraFields()]] will be ignored. If this parameter is empty, no extra fields
|
||||
* will be returned.
|
||||
* @param boolean $recursive whether to recursively return array representation of embedded objects.
|
||||
* @return array the array representation of the object
|
||||
*/
|
||||
public function toArray(array $fields = [], array $expand = [], $recursive = true);
|
||||
}
|
||||
|
@ -13,6 +13,10 @@ use yii\web\Link;
|
||||
use yii\web\Linkable;
|
||||
|
||||
/**
|
||||
* ArrayableTrait provides a common implementation of the [[Arrayable]] interface.
|
||||
*
|
||||
* ArrayableTrait implements [[toArray()]] by respecting the field definitions as declared
|
||||
* in [[fields()]] and [[extraFields()]].
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
|
@ -15,7 +15,7 @@ use Yii;
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ErrorException extends \ErrorException implements Arrayable
|
||||
class ErrorException extends \ErrorException
|
||||
{
|
||||
/**
|
||||
* Constructs the exception.
|
||||
@ -93,32 +93,4 @@ class ErrorException extends \ErrorException implements Arrayable
|
||||
];
|
||||
return isset($names[$this->getCode()]) ? $names[$this->getCode()] : 'Error';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array representation of this object.
|
||||
* @return array the array representation of this object.
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->toArrayRecursive($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array representation of the exception and all previous exceptions recursively.
|
||||
* @param \Exception $exception object
|
||||
* @return array the array representation of the exception.
|
||||
*/
|
||||
protected function toArrayRecursive($exception)
|
||||
{
|
||||
$array = [
|
||||
'type' => get_class($exception),
|
||||
'name' => $exception instanceof self ? $exception->getName() : 'Exception',
|
||||
'message' => $exception->getMessage(),
|
||||
'code' => $exception->getCode(),
|
||||
];
|
||||
if (($prev = $exception->getPrevious()) !== null) {
|
||||
$array['previous'] = $this->toArrayRecursive($prev);
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
@ -119,15 +119,8 @@ class ErrorHandler extends Component
|
||||
'exception' => $exception,
|
||||
]);
|
||||
}
|
||||
} elseif ($exception instanceof Arrayable) {
|
||||
$response->data = $exception->toArray();
|
||||
} else {
|
||||
$response->data = [
|
||||
'type' => get_class($exception),
|
||||
'name' => 'Exception',
|
||||
'message' => $exception->getMessage(),
|
||||
'code' => $exception->getCode(),
|
||||
];
|
||||
$response->data = $this->convertExceptionToArray($exception);
|
||||
}
|
||||
|
||||
if ($exception instanceof HttpException) {
|
||||
@ -139,6 +132,25 @@ class ErrorHandler extends Component
|
||||
$response->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an exception into an array.
|
||||
* @param \Exception $exception the exception being converted
|
||||
* @return array the array representation of the exception.
|
||||
*/
|
||||
protected function convertExceptionToArray($exception)
|
||||
{
|
||||
$array = [
|
||||
'type' => get_class($exception),
|
||||
'name' => $exception instanceof \yii\base\Exception || $exception instanceof \yii\base\ErrorException ? $exception->getName() : 'Exception',
|
||||
'message' => $exception->getMessage(),
|
||||
'code' => $exception->getCode(),
|
||||
];
|
||||
if (($prev = $exception->getPrevious()) !== null) {
|
||||
$array['previous'] = $this->convertExceptionToArray($prev);
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts special characters to HTML entities.
|
||||
* @param string $text to encode.
|
||||
|
@ -13,7 +13,7 @@ namespace yii\base;
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Exception extends \Exception implements Arrayable
|
||||
class Exception extends \Exception
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
@ -22,32 +22,4 @@ class Exception extends \Exception implements Arrayable
|
||||
{
|
||||
return 'Exception';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array representation of this object.
|
||||
* @return array the array representation of this object.
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->toArrayRecursive($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array representation of the exception and all previous exceptions recursively.
|
||||
* @param \Exception $exception object
|
||||
* @return array the array representation of the exception.
|
||||
*/
|
||||
protected function toArrayRecursive($exception)
|
||||
{
|
||||
$array = [
|
||||
'type' => get_class($exception),
|
||||
'name' => $exception instanceof self ? $exception->getName() : 'Exception',
|
||||
'message' => $exception->getMessage(),
|
||||
'code' => $exception->getCode(),
|
||||
];
|
||||
if (($prev = $exception->getPrevious()) !== null) {
|
||||
$array['previous'] = $this->toArrayRecursive($prev);
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
namespace yii\data;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Arrayable;
|
||||
use yii\base\Object;
|
||||
use yii\web\Link;
|
||||
use yii\web\Linkable;
|
||||
@ -68,7 +67,7 @@ use yii\web\Request;
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Pagination extends Object implements Linkable, Arrayable
|
||||
class Pagination extends Object implements Linkable
|
||||
{
|
||||
const LINK_NEXT = 'next';
|
||||
const LINK_PREV = 'prev';
|
||||
@ -316,19 +315,6 @@ class Pagination extends Object implements Linkable, Arrayable
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'totalCount' => $this->totalCount,
|
||||
'pageCount' => $this->getPageCount(),
|
||||
'currentPage' => $this->getPage(),
|
||||
'perPage' => $this->getPageSize(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified query parameter.
|
||||
* This method returns the named parameter value from [[params]]. Null is returned if the value does not exist.
|
||||
|
@ -91,7 +91,11 @@ class BaseJson
|
||||
} elseif ($data instanceof Arrayable) {
|
||||
$data = $data->toArray();
|
||||
} else {
|
||||
$data = get_object_vars($data);
|
||||
$result = [];
|
||||
foreach ($data as $name => $value) {
|
||||
$result[$name] = $value;
|
||||
}
|
||||
$data = $result;
|
||||
}
|
||||
|
||||
if ($data === []) {
|
||||
|
@ -8,7 +8,6 @@
|
||||
namespace yii\i18n;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Arrayable;
|
||||
use yii\base\Component;
|
||||
use yii\base\InvalidConfigException;
|
||||
|
||||
@ -104,11 +103,7 @@ class I18N extends Component
|
||||
*/
|
||||
public function format($message, $params, $language)
|
||||
{
|
||||
if ($params instanceof Arrayable) {
|
||||
$params = $params->toArray();
|
||||
} else {
|
||||
$params = (array)$params;
|
||||
}
|
||||
if ($params === []) {
|
||||
return $message;
|
||||
}
|
||||
|
@ -169,12 +169,31 @@ class Serializer extends Component
|
||||
$this->collectionEnvelope => $models,
|
||||
];
|
||||
if ($pagination !== false) {
|
||||
$result['_links'] = Link::serialize($pagination->getLinks());
|
||||
$result['_meta'] = $pagination->toArray();
|
||||
}
|
||||
return array_merge($result, $this->serializePagination($pagination));
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a pagination into an array.
|
||||
* @param Pagination $pagination
|
||||
* @return array the array representation of the pagination
|
||||
* @see addPaginationHeader()
|
||||
*/
|
||||
protected function serializePagination($pagination)
|
||||
{
|
||||
return [
|
||||
'_links' => Link::serialize($pagination->getLinks(true)),
|
||||
'_meta' => [
|
||||
'totalCount' => $pagination->totalCount,
|
||||
'pageCount' => $pagination->getPageCount(),
|
||||
'currentPage' => $pagination->getPage(),
|
||||
'perPage' => $pagination->getPageSize(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds HTTP headers about the pagination to the response.
|
||||
|
@ -9,7 +9,6 @@ namespace yii\web;
|
||||
|
||||
use Yii;
|
||||
use ArrayIterator;
|
||||
use yii\base\Arrayable;
|
||||
use yii\base\InvalidCallException;
|
||||
use yii\base\Object;
|
||||
|
||||
@ -23,7 +22,7 @@ use yii\base\Object;
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class CookieCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable, Arrayable
|
||||
class CookieCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable
|
||||
{
|
||||
/**
|
||||
* @var boolean whether this collection is read only.
|
||||
@ -166,17 +165,6 @@ class CookieCollection extends Object implements \IteratorAggregate, \ArrayAcces
|
||||
$this->_cookies = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collection as a PHP array.
|
||||
* @return array the array representation of the collection.
|
||||
* The array keys are cookie names, and the array values are the corresponding
|
||||
* cookie objects.
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->_cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is a cookie with the specified name.
|
||||
* This method is required by the SPL interface `ArrayAccess`.
|
||||
|
@ -8,7 +8,6 @@
|
||||
namespace yii\web;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Arrayable;
|
||||
use yii\base\Object;
|
||||
use ArrayIterator;
|
||||
|
||||
@ -22,7 +21,7 @@ use ArrayIterator;
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class HeaderCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable, Arrayable
|
||||
class HeaderCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable
|
||||
{
|
||||
/**
|
||||
* @var array the headers in this collection (indexed by the header names)
|
||||
@ -160,16 +159,6 @@ class HeaderCollection extends Object implements \IteratorAggregate, \ArrayAcces
|
||||
$this->_headers = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collection as a PHP array.
|
||||
* @return array the array representation of the collection.
|
||||
* The array keys are header names, and the array values are the corresponding header values.
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is a header with the specified name.
|
||||
* This method is required by the SPL interface `ArrayAccess`.
|
||||
|
@ -58,15 +58,4 @@ class HttpException extends UserException
|
||||
return 'Error';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array representation of this object.
|
||||
* @return array the array representation of this object.
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$array = parent::toArray();
|
||||
$array['status'] = $this->statusCode;
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace yii\web;
|
||||
|
||||
use yii\base\Arrayable;
|
||||
use yii\base\Object;
|
||||
|
||||
/**
|
||||
@ -16,7 +15,7 @@ use yii\base\Object;
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Link extends Object implements Arrayable
|
||||
class Link extends Object
|
||||
{
|
||||
/**
|
||||
* The self link.
|
||||
@ -53,13 +52,6 @@ class Link extends Object implements Arrayable
|
||||
*/
|
||||
public $hreflang;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return array_filter((array)$this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a list of links into proper array format.
|
||||
@ -71,7 +63,7 @@ class Link extends Object implements Arrayable
|
||||
foreach ($links as $rel => $link) {
|
||||
if (is_array($link)) {
|
||||
foreach ($link as $i => $l) {
|
||||
$link[$i] = $l instanceof self ? $l->toArray() : ['href' => $l];
|
||||
$link[$i] = $l instanceof self ? array_filter((array)$l) : ['href' => $l];
|
||||
}
|
||||
$links[$rel] = $link;
|
||||
} elseif (!$link instanceof self) {
|
||||
|
@ -8,7 +8,6 @@
|
||||
namespace yii\web;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Arrayable;
|
||||
use yii\base\Component;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\base\InvalidParamException;
|
||||
@ -72,7 +71,7 @@ use yii\base\InvalidParamException;
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Countable, Arrayable
|
||||
class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Countable
|
||||
{
|
||||
/**
|
||||
* @var string the name of the session variable that stores the flash message data.
|
||||
@ -599,15 +598,6 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
|
||||
return isset($_SESSION[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array the list of all session variables in array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$this->open();
|
||||
return $_SESSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the counters for flash messages and removes outdated flash messages.
|
||||
* This method should only be called once in [[init()]].
|
||||
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
namespace yiiunit\framework\base;
|
||||
|
||||
use yiiunit\TestCase;
|
||||
use yii\base\UserException;
|
||||
use yii\base\InvalidCallException;
|
||||
|
||||
|
||||
class ExceptionTest extends TestCase
|
||||
{
|
||||
public function testToArrayWithPrevious()
|
||||
{
|
||||
$e = new InvalidCallException('bar', 0 ,new InvalidCallException('foo'));
|
||||
$array = $e->toArray();
|
||||
$this->assertEquals('bar', $array['message']);
|
||||
$this->assertEquals('foo', $array['previous']['message']);
|
||||
|
||||
$e = new InvalidCallException('bar', 0, new UserException('foo'));
|
||||
$array = $e->toArray();
|
||||
$this->assertEquals('bar', $array['message']);
|
||||
$this->assertEquals('foo', $array['previous']['message']);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user