Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
96.55% |
28 / 29 |
|
100.00% |
6 / 6 |
CRAP | |
100.00% |
1 / 1 |
| ApiMessageTrait | |
100.00% |
28 / 28 |
|
100.00% |
6 / 6 |
14 | |
100.00% |
1 / 1 |
| getApiCode | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
6 | |||
| setApiCode | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
4 | |||
| getApiData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| setApiData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| __serialize | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
| __unserialize | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | |
| 3 | // @phan-file-suppress PhanTraitParentReference,PhanUndeclaredMethod |
| 4 | |
| 5 | /** |
| 6 | * @license GPL-2.0-or-later |
| 7 | * @file |
| 8 | */ |
| 9 | |
| 10 | namespace MediaWiki\Api; |
| 11 | |
| 12 | use InvalidArgumentException; |
| 13 | |
| 14 | /** |
| 15 | * Trait to implement the IApiMessage interface for Message subclasses |
| 16 | * @since 1.27 |
| 17 | * @ingroup API |
| 18 | */ |
| 19 | trait ApiMessageTrait { |
| 20 | |
| 21 | /** |
| 22 | * Compatibility code mappings for various MW messages. |
| 23 | * @todo Ideally anything relying on this should be changed to use ApiMessage. |
| 24 | * @var string[] |
| 25 | * @phpcs-require-sorted-array |
| 26 | */ |
| 27 | protected static $messageMap = [ |
| 28 | 'actionthrottledtext' => 'ratelimited', |
| 29 | 'autoblockedtext' => 'autoblocked', |
| 30 | 'autoblockedtext-tempuser' => 'autoblocked', |
| 31 | 'badaccess-group0' => 'permissiondenied', |
| 32 | 'badaccess-groups' => 'permissiondenied', |
| 33 | 'badipaddress' => 'invalidip', |
| 34 | 'blankpage' => 'emptypage', |
| 35 | 'blockedtext' => 'blocked', |
| 36 | 'blockedtext-composite' => 'blocked', |
| 37 | 'blockedtext-partial' => 'blocked', |
| 38 | 'blockedtext-tempuser' => 'blocked', |
| 39 | 'cannotdelete' => 'cantdelete', |
| 40 | 'cannotundelete' => 'cantundelete', |
| 41 | 'cantmove-titleprotected' => 'protectedtitle', |
| 42 | 'cantrollback' => 'onlyauthor', |
| 43 | 'confirmedittext' => 'confirmemail', |
| 44 | 'content-not-allowed-here' => 'contentnotallowedhere', |
| 45 | 'delete-toobig' => 'bigdelete', |
| 46 | 'deleteprotected' => 'cantedit', |
| 47 | 'edit-conflict' => 'editconflict', |
| 48 | 'edit-constraint-confirmrecreate' => 'pagedeleted', |
| 49 | 'edit-constraint-confirmrecreate-noreason' => 'pagedeleted', |
| 50 | 'imagenocrossnamespace' => 'nonfilenamespace', |
| 51 | 'imagetypemismatch' => 'filetypemismatch', |
| 52 | 'import-noarticle' => 'badinterwiki', |
| 53 | 'importbadinterwiki' => 'badinterwiki', |
| 54 | 'importcantopen' => 'cantopenfile', |
| 55 | 'importnofile' => 'nofile', |
| 56 | 'importuploaderrorpartial' => 'partialupload', |
| 57 | 'importuploaderrorsize' => 'filetoobig', |
| 58 | 'importuploaderrortemp' => 'notempdir', |
| 59 | 'ipb-block-not-found' => 'alreadyblocked', |
| 60 | 'ipb_already_blocked' => 'alreadyblocked', |
| 61 | 'ipb_blocked_as_range' => 'blockedasrange', |
| 62 | 'ipb_cant_unblock' => 'cantunblock', |
| 63 | 'ipb_expiry_invalid' => 'invalidexpiry', |
| 64 | 'ip_range_invalid' => 'invalidrange', |
| 65 | 'longpageerror' => 'contenttoobig', |
| 66 | 'mailnologin' => 'cantsend', |
| 67 | 'markedaspatrollederror-noautopatrol' => 'noautopatrol', |
| 68 | 'movenologintext' => 'cantmove-anon', |
| 69 | 'movenotallowed' => 'cantmove', |
| 70 | 'movenotallowedfile' => 'cantmovefile', |
| 71 | 'namespaceprotected' => 'protectednamespace', |
| 72 | 'nocreate-loggedin' => 'cantcreate', |
| 73 | 'nocreatetext' => 'cantcreate-anon', |
| 74 | 'noname' => 'invaliduser', |
| 75 | 'nosuchusershort' => 'nosuchuser', |
| 76 | 'notanarticle' => 'missingtitle', |
| 77 | 'nouserspecified' => 'invaliduser', |
| 78 | 'ns-specialprotected' => 'unsupportednamespace', |
| 79 | 'protect-cantedit' => 'cantedit', |
| 80 | 'protectedinterface' => 'protectednamespace-interface', |
| 81 | 'protectedpagetext' => 'protectedpage', |
| 82 | 'range_block_disabled' => 'rangedisabled', |
| 83 | 'rcpatroldisabled' => 'patroldisabled', |
| 84 | 'readonlytext' => 'readonly', |
| 85 | 'sessionfailure' => 'badtoken', |
| 86 | 'systemblockedtext' => 'blocked', |
| 87 | 'titleprotected' => 'protectedtitle', |
| 88 | 'undo-failure' => 'undofailure', |
| 89 | 'userrights-no-interwiki' => 'nointerwikiuserrights', |
| 90 | 'userrights-nodatabase' => 'nosuchdatabase', |
| 91 | ]; |
| 92 | |
| 93 | /** @var string|null */ |
| 94 | protected $apiCode = null; |
| 95 | /** @var array */ |
| 96 | protected $apiData = []; |
| 97 | |
| 98 | /** @inheritDoc */ |
| 99 | public function getApiCode() { |
| 100 | if ( $this->apiCode === null ) { |
| 101 | $key = $this->getKey(); |
| 102 | if ( isset( self::$messageMap[$key] ) ) { |
| 103 | $this->apiCode = self::$messageMap[$key]; |
| 104 | } elseif ( $key === 'apierror-missingparam' ) { |
| 105 | // @todo: Kill this case along with ApiBase::$messageMap |
| 106 | $this->apiCode = 'no' . $this->getParams()[0]; |
| 107 | } elseif ( str_starts_with( $key, 'apiwarn-' ) ) { |
| 108 | $this->apiCode = substr( $key, 8 ); |
| 109 | } elseif ( str_starts_with( $key, 'apierror-' ) ) { |
| 110 | $this->apiCode = substr( $key, 9 ); |
| 111 | } else { |
| 112 | $this->apiCode = $key; |
| 113 | } |
| 114 | |
| 115 | // Ensure the code is actually valid |
| 116 | $this->apiCode = preg_replace( '/[^a-zA-Z0-9_-]/', '_', $this->apiCode ); |
| 117 | } |
| 118 | return $this->apiCode; |
| 119 | } |
| 120 | |
| 121 | /** @inheritDoc */ |
| 122 | public function setApiCode( $code, ?array $data = null ) { |
| 123 | if ( $code !== null && !ApiErrorFormatter::isValidApiCode( $code ) ) { |
| 124 | throw new InvalidArgumentException( "Invalid code \"$code\"" ); |
| 125 | } |
| 126 | |
| 127 | $this->apiCode = $code; |
| 128 | if ( $data !== null ) { |
| 129 | $this->setApiData( $data ); |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | /** @inheritDoc */ |
| 134 | public function getApiData() { |
| 135 | return $this->apiData; |
| 136 | } |
| 137 | |
| 138 | public function setApiData( array $data ) { |
| 139 | $this->apiData = $data; |
| 140 | } |
| 141 | |
| 142 | public function __serialize() { |
| 143 | return [ |
| 144 | 'parent' => parent::__serialize(), |
| 145 | 'apiCode' => $this->apiCode, |
| 146 | 'apiData' => $this->apiData, |
| 147 | ]; |
| 148 | } |
| 149 | |
| 150 | public function __unserialize( $data ) { |
| 151 | parent::__unserialize( $data['parent'] ); |
| 152 | $this->apiCode = $data['apiCode']; |
| 153 | $this->apiData = $data['apiData']; |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | /** @deprecated class alias since 1.43 */ |
| 158 | class_alias( ApiMessageTrait::class, 'ApiMessageTrait' ); |