1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
<?php
/**
* Defines an interface for messages with additional machine-readable data for
* use by the API, and provides concrete implementations of that interface.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
/**
* Interface for messages with machine-readable data for use by the API
*
* The idea is that it's a Message that has some extra data for the API to use when interpreting it
* as an error (or, in the future, as a warning). Internals of MediaWiki often use messages (or
* message keys, or Status objects containing messages) to pass information about errors to the user
* (see e.g. Title::getUserPermissionsErrors()) and the API has to make do with that.
*
* @since 1.25
* @ingroup API
*/
interface IApiMessage extends MessageSpecifier {
/**
* Returns a machine-readable code for use by the API
*
* The message key is often sufficient, but sometimes there are multiple
* messages used for what is really the same underlying condition (e.g.
* badaccess-groups and badaccess-group0)
* @return string
*/
public function getApiCode();
/**
* Returns additional machine-readable data about the error condition
* @return array
*/
public function getApiData();
/**
* Sets the machine-readable code for use by the API
* @param string|null $code If null, the message key should be returned by self::getApiCode()
* @param array|null $data If non-null, passed to self::setApiData()
*/
public function setApiCode( $code, array $data = null );
/**
* Sets additional machine-readable data about the error condition
* @param array $data
*/
public function setApiData( array $data );
}
/**
* Trait to implement the IApiMessage interface for Message subclasses
* @since 1.27
* @ingroup API
*/
trait ApiMessageTrait {
protected $apiCode = null;
protected $apiData = [];
public function getApiCode() {
return $this->apiCode === null ? $this->getKey() : $this->apiCode;
}
public function setApiCode( $code, array $data = null ) {
$this->apiCode = $code;
if ( $data !== null ) {
$this->setApiData( $data );
}
}
public function getApiData() {
return $this->apiData;
}
public function setApiData( array $data ) {
$this->apiData = $data;
}
public function serialize() {
return serialize( [
'parent' => parent::serialize(),
'apiCode' => $this->apiCode,
'apiData' => $this->apiData,
] );
}
public function unserialize( $serialized ) {
$data = unserialize( $serialized );
parent::unserialize( $data['parent'] );
$this->apiCode = $data['apiCode'];
$this->apiData = $data['apiData'];
}
}
/**
* Extension of Message implementing IApiMessage
* @since 1.25
* @ingroup API
*/
class ApiMessage extends Message implements IApiMessage {
use ApiMessageTrait;
/**
* Create an IApiMessage for the message
*
* This returns $msg if it's an IApiMessage, calls 'new ApiRawMessage' if
* $msg is a RawMessage, or calls 'new ApiMessage' in all other cases.
*
* @param Message|RawMessage|array|string $msg
* @param string|null $code
* @param array|null $data
* @return ApiMessage
*/
public static function create( $msg, $code = null, array $data = null ) {
if ( $msg instanceof IApiMessage ) {
return $msg;
} elseif ( $msg instanceof RawMessage ) {
return new ApiRawMessage( $msg, $code, $data );
} else {
return new ApiMessage( $msg, $code, $data );
}
}
/**
* @param Message|string|array $msg
* - Message: is cloned
* - array: first element is $key, rest are $params to Message::__construct
* - string: passed to Message::__construct
* @param string|null $code
* @param array|null $data
* @return ApiMessage
*/
public function __construct( $msg, $code = null, array $data = null ) {
if ( $msg instanceof Message ) {
foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
if ( isset( $msg->$key ) ) {
$this->$key = $msg->$key;
}
}
} elseif ( is_array( $msg ) ) {
$key = array_shift( $msg );
parent::__construct( $key, $msg );
} else {
parent::__construct( $msg );
}
$this->apiCode = $code;
$this->apiData = (array)$data;
}
}
/**
* Extension of RawMessage implementing IApiMessage
* @since 1.25
* @ingroup API
*/
class ApiRawMessage extends RawMessage implements IApiMessage {
use ApiMessageTrait;
/**
* @param RawMessage|string|array $msg
* - RawMessage: is cloned
* - array: first element is $key, rest are $params to RawMessage::__construct
* - string: passed to RawMessage::__construct
* @param string|null $code
* @param array|null $data
*/
public function __construct( $msg, $code = null, array $data = null ) {
if ( $msg instanceof RawMessage ) {
foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
if ( isset( $msg->$key ) ) {
$this->$key = $msg->$key;
}
}
} elseif ( is_array( $msg ) ) {
$key = array_shift( $msg );
parent::__construct( $key, $msg );
} else {
parent::__construct( $msg );
}
$this->apiCode = $code;
$this->apiData = (array)$data;
}
}
|