Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.21% covered (success)
98.21%
55 / 56
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
ApiErrorFormatter_BackCompat
100.00% covered (success)
100.00%
55 / 55
100.00% covered (success)
100.00%
6 / 6
21
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 arrayFromStatus
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
3
 formatMessageInternal
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 formatException
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 addWarningOrError
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
1 / 1
13
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 */
6
7namespace MediaWiki\Api;
8
9use MediaWiki\MediaWikiServices;
10use StatusValue;
11use Throwable;
12
13/**
14 * Format errors and warnings in the old style, for backwards compatibility.
15 * @since 1.25
16 * @deprecated since 1.25; only for backwards compatibility, do not use
17 * @ingroup API
18 */
19// phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
20class ApiErrorFormatter_BackCompat extends ApiErrorFormatter {
21
22    /**
23     * @param ApiResult $result Into which data will be added
24     */
25    public function __construct( ApiResult $result ) {
26        parent::__construct(
27            $result,
28            MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( 'en' ),
29            'none',
30            false
31        );
32    }
33
34    /** @inheritDoc */
35    public function getFormat() {
36        return 'bc';
37    }
38
39    /** @inheritDoc */
40    public function arrayFromStatus( StatusValue $status, $type = 'error', $format = null ) {
41        if ( $status->isGood() ) {
42            return [];
43        }
44
45        $result = [];
46        foreach ( $status->getMessages( $type ) as $msg ) {
47            $msg = ApiMessage::create( $msg );
48            $error = [
49                'message' => $msg->getKey(),
50                'params' => $msg->getParams(),
51                'code' => $msg->getApiCode(),
52                'type' => $type,
53            ];
54            ApiResult::setIndexedTagName( $error['params'], 'param' );
55            $result[] = $error;
56        }
57        ApiResult::setIndexedTagName( $result, $type );
58
59        return $result;
60    }
61
62    /** @inheritDoc */
63    protected function formatMessageInternal( $msg, $format ) {
64        return [
65            'code' => $msg->getApiCode(),
66            'info' => $msg->text(),
67        ] + $msg->getApiData();
68    }
69
70    /**
71     * Format a throwable as an array
72     * @since 1.29
73     * @param Throwable $exception
74     * @param array $options See parent::formatException(), plus
75     *  - bc: (bool) Return only the string, not an array
76     * @return array|string
77     */
78    public function formatException( Throwable $exception, array $options = [] ) {
79        $ret = parent::formatException( $exception, $options );
80        return empty( $options['bc'] ) ? $ret : $ret['info'];
81    }
82
83    /** @inheritDoc */
84    protected function addWarningOrError( $tag, $modulePath, $msg ) {
85        $value = self::stripMarkup( $msg->text() );
86
87        if ( $tag === 'error' ) {
88            // In BC mode, only one error
89            $existingError = $this->result->getResultData( [ 'error' ] );
90            if ( !is_array( $existingError ) ||
91                !isset( $existingError['code'] ) || !isset( $existingError['info'] )
92            ) {
93                $value = [
94                    'code' => $msg->getApiCode(),
95                    'info' => $value,
96                ] + $msg->getApiData();
97                $this->result->addValue( null, 'error', $value,
98                    ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
99            }
100        } else {
101            if ( $modulePath === null ) {
102                $moduleName = 'unknown';
103            } else {
104                $i = strrpos( $modulePath, '+' );
105                $moduleName = $i === false ? $modulePath : substr( $modulePath, $i + 1 );
106            }
107
108            // Don't add duplicate warnings
109            $tag .= 's';
110            $path = [ $tag, $moduleName ];
111            $oldWarning = $this->result->getResultData( [ $tag, $moduleName, $tag ] );
112            if ( $oldWarning !== null ) {
113                $warnPos = strpos( $oldWarning, $value );
114                // If $value was found in $oldWarning, check if it starts at 0 or after "\n"
115                if ( $warnPos !== false && ( $warnPos === 0 || $oldWarning[$warnPos - 1] === "\n" ) ) {
116                    // Check if $value is followed by "\n" or the end of the $oldWarning
117                    $warnPos += strlen( $value );
118                    if ( strlen( $oldWarning ) <= $warnPos || $oldWarning[$warnPos] === "\n" ) {
119                        return;
120                    }
121                }
122                // If there is a warning already, append it to the existing one
123                $value = "$oldWarning\n$value";
124            }
125            $this->result->addContentValue( $path, $tag, $value,
126                ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
127        }
128    }
129}
130
131/** @deprecated class alias since 1.43 */
132class_alias( ApiErrorFormatter_BackCompat::class, 'ApiErrorFormatter_BackCompat' );