API: Validate API error codes
[lhc/web/wiklou.git] / includes / api / ApiErrorFormatter.php
index c637752..ef28b73 100644 (file)
@@ -58,6 +58,46 @@ class ApiErrorFormatter {
                $this->format = $format;
        }
 
+       /**
+        * Test whether a code is a valid API error code
+        *
+        * A valid code contains only ASCII letters, numbers, underscore, and
+        * hyphen and is not the empty string.
+        *
+        * For backwards compatibility, any code beginning 'internal_api_error_' is
+        * also allowed.
+        *
+        * @param string $code
+        * @return bool
+        */
+       public static function isValidApiCode( $code ) {
+               return is_string( $code ) && (
+                       preg_match( '/^[a-zA-Z0-9_-]+$/', $code ) ||
+                       // TODO: Deprecate this
+                       preg_match( '/^internal_api_error_[^\0\r\n]+$/', $code )
+               );
+       }
+
+       /**
+        * Return a formatter like this one but with a different format
+        *
+        * @since 1.32
+        * @param string $format New format.
+        * @return ApiErrorFormatter
+        */
+       public function newWithFormat( $format ) {
+               return new self( $this->result, $this->lang, $format, $this->useDB );
+       }
+
+       /**
+        * Fetch the format for this formatter
+        * @since 1.32
+        * @return string
+        */
+       public function getFormat() {
+               return $this->format;
+       }
+
        /**
         * Fetch the Language for this formatter
         * @since 1.29
@@ -164,16 +204,6 @@ class ApiErrorFormatter {
                        $msg = Message::newFromSpecifier( $exception );
                        $params = [];
                } else {
-                       // Extract code and data from the exception, if applicable
-                       if ( $exception instanceof UsageException ) {
-                               $data = $exception->getMessageArray();
-                               if ( !$options['code'] ) {
-                                       $options['code'] = $data['code'];
-                               }
-                               unset( $data['code'], $data['info'] );
-                               $options['data'] = array_merge( $data, $options['data'] );
-                       }
-
                        if ( isset( $options['wrap'] ) ) {
                                $msg = $options['wrap'];
                        } else {
@@ -203,7 +233,7 @@ class ApiErrorFormatter {
        public function formatException( $exception, array $options = [] ) {
                return $this->formatMessage(
                        $this->getMessageFromException( $exception, $options ),
-                       isset( $options['format'] ) ? $options['format'] : null
+                       $options['format'] ?? null
                );
        }
 
@@ -371,6 +401,10 @@ class ApiErrorFormatter_BackCompat extends ApiErrorFormatter {
                parent::__construct( $result, Language::factory( 'en' ), 'none', false );
        }
 
+       public function getFormat() {
+               return 'bc';
+       }
+
        public function arrayFromStatus( StatusValue $status, $type = 'error', $format = null ) {
                if ( $status->isGood() || !$status->getErrors() ) {
                        return [];