Umherirrender has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/356840 )
Change subject: Break long lines ...................................................................... Break long lines Prepare to make phpcs pass Change-Id: I52a4119e1e64417fd1d0c732d0b3a87a3e3a625c --- M includes/JCApi.php M includes/JCCache.php M includes/JCContent.php M includes/JCObjContent.php M includes/JCSingleton.php M includes/JCTitle.php M includes/JCUtils.php M includes/JCValidators.php M tests/manual/TestObjectContent.php M tests/phpunit/JCObjContentTest.php 10 files changed, 286 insertions(+), 128 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/JsonConfig refs/changes/40/356840/1 diff --git a/includes/JCApi.php b/includes/JCApi.php index 1ae3087..399c46a 100644 --- a/includes/JCApi.php +++ b/includes/JCApi.php @@ -88,28 +88,41 @@ // (and violate the HTTP RFC by doing so without a // WWW-Authenticate header). $this->dieWithError( - [ 'apierror-permissiondenied', $this->msg( "action-jsonconfig-flush" ) ], + [ + 'apierror-permissiondenied', + $this->msg( "action-jsonconfig-flush" ) + ], 'permissiondenied', [], 401 ); } else { - $this->dieUsage( "Must be authenticated with jsonconfig-flush right to use this API", - 'login', 401 ); + $this->dieUsage( + "Must be authenticated with jsonconfig-flush right to use this API", + 'login', 401 + ); } } if ( !isset( $params['namespace'] ) ) { if ( is_callable( [ $this, 'dieWithError' ] ) ) { $this->dieWithError( - [ 'apierror-jsonconfig-paramrequired', 'namespace' ], 'badparam-namespace' + [ 'apierror-jsonconfig-paramrequired', 'namespace' ], + 'badparam-namespace' ); } else { - $this->dieUsage( 'Parameter "namespace" is required for this command', 'badparam-namespace' ); + $this->dieUsage( + 'Parameter "namespace" is required for this command', + 'badparam-namespace' + ); } } if ( !isset( $params['title'] ) ) { if ( is_callable( [ $this, 'dieWithError' ] ) ) { - $this->dieWithError( [ 'apierror-jsonconfig-paramrequired', 'title' ], 'badparam-title' ); + $this->dieWithError( + [ 'apierror-jsonconfig-paramrequired', 'title' ], 'badparam-title' + ); } else { - $this->dieUsage( 'Parameter "title" is required for this command', 'badparam-title' ); + $this->dieUsage( + 'Parameter "title" is required for this command', 'badparam-title' + ); } } @@ -118,19 +131,30 @@ if ( is_callable( [ $this, 'dieWithError' ] ) ) { $this->dieWithError( 'apierror-jsonconfig-badtitle', 'badparam-titles' ); } else { - $this->dieUsage( 'The page specified by "namespace" and "title" parameters is either invalid or is not registered in JsonConfig configuration', - 'badparam-titles' ); + $this->dieUsage( + 'The page specified by "namespace" and "title" parameters ' . + 'is either invalid or is not registered in JsonConfig configuration', + 'badparam-titles' + ); } } if ( isset( $params['content'] ) && $params['content'] !== '' ) { if ( $command !== 'reload ' ) { if ( is_callable( [ $this, 'dieWithError' ] ) ) { - $this->dieWithError( [ 'apierror-invalidparammix-mustusewith', 'content', 'command=reload' ], - 'badparam-content' ); + $this->dieWithError( + [ + 'apierror-invalidparammix-mustusewith', + 'content', + 'command=reload' + ], + 'badparam-content' + ); } else { - $this->dieUsage( 'The "content" parameter may only be used with command=reload', - 'badparam-content' ); + $this->dieUsage( + 'The "content" parameter may only be used with command=reload', + 'badparam-content' + ); } } $content = JCSingleton::parseContent( $jct, $params['content'], true ); diff --git a/includes/JCCache.php b/includes/JCCache.php index 1815780..742cd80 100644 --- a/includes/JCCache.php +++ b/includes/JCCache.php @@ -94,7 +94,9 @@ if ( !$value ) { $value = ''; $exp = 10; // caching an error condition for short time - wfLogWarning( "No content is available, caching empty '$this->titleValue' for $exp seconds" ); + wfLogWarning( + "No content is available, caching empty '$this->titleValue' for $exp seconds" + ); } elseif ( !is_string( $value ) ) { $value = $value->getNativeData(); } @@ -105,8 +107,11 @@ /** * Delete any cached information related to this config * @param null|bool $updateCacheContent controls if cache should be updated with the new content - * false = only clear cache, true = set cache to the new value, null = use configuration settings - * New content will be set only if it is present (either get() was called before, or it was set via ctor + * false = only clear cache, + * true = set cache to the new value, + * null = use configuration settings + * New content will be set only if it is present + * (either get() was called before, or it was set via ctor) */ public function resetCache( $updateCacheContent = null ) { global $wgJsonConfigDisableCache; @@ -124,7 +129,8 @@ } /** - * Retrieves the config from the local storage, and sets $this->content to the content object or false + * Retrieves the config from the local storage, + * and sets $this->content to the content object or false */ private function loadLocal() { // @fixme @bug handle flagged revisions @@ -137,7 +143,8 @@ // If this is a regular wiki page, allow it to be parsed as a json config $result = $result->getNativeData(); } else { - wfLogWarning( "The locally stored wiki page '$this->titleValue' has unsupported content model'" ); + wfLogWarning( "The locally stored wiki page '$this->titleValue' has " . + "unsupported content model'" ); $result = false; } } @@ -161,7 +168,8 @@ : MWNamespace::getCanonicalName( $this->titleValue->getNamespace() ); $articleName = $ns . ':' . $this->titleValue->getText(); $flrevs = $conf->flaggedRevs; - // if flaggedRevs is false, get wiki page directly, otherwise get the flagged state first + // if flaggedRevs is false, get wiki page directly, + // otherwise get the flagged state first $res = $this->getPageFromApi( $articleName, $req, $flrevs === false ? [ 'action' => 'query', @@ -181,11 +189,12 @@ ) { // If there is a stable flagged revision present, use it. // else - if flaggedRevs is null, use the latest revision that exists - // otherwise, fail because flaggedRevs is true, which means we require rev to be flagged + // otherwise, fail because flaggedRevs is true, + // which means we require rev to be flagged $res = $this->getPageFromApi( $articleName, $req, [ 'action' => 'query', - 'revids' => array_key_exists( 'flagged', $res ) ? $res['flagged']['stable_revid'] - : $res['lastrevid'], + 'revids' => array_key_exists( 'flagged', $res ) + ? $res['flagged']['stable_revid'] : $res['lastrevid'], 'prop' => 'revisions', 'rvprop' => 'content', 'continue' => '', diff --git a/includes/JCContent.php b/includes/JCContent.php index 50ffc49..418ac79 100644 --- a/includes/JCContent.php +++ b/includes/JCContent.php @@ -15,7 +15,8 @@ * @ingroup Extensions * @ingroup JsonConfig * - * @author Yuri Astrakhan <yu...@wikimedia.org>, based on Ori Livneh <o...@wikimedia.org> extension schema + * @author Yuri Astrakhan <yu...@wikimedia.org>, + * based on Ori Livneh <o...@wikimedia.org> extension schema */ class JCContent extends \TextContent { /** @var array */ @@ -63,7 +64,8 @@ } /** - * Returns JSON object as resulted from parsing initial text, before any validation/modifications took place + * Returns JSON object as resulted from parsing initial text, + * before any validation/modifications took place * @return mixed */ public function getRawData() { @@ -107,7 +109,8 @@ } /** - * @return boolean true if thorough validation may be needed - e.g. rendering HTML or saving new value + * @return boolean true if thorough validation may be needed - + * e.g. rendering HTML or saving new value */ public function thorough() { return $this->thorough; @@ -137,7 +140,9 @@ // @fixme: HACK - need a deep clone of the data // @fixme: but doing (object)(array)$data will re-encode empty [] as {} // @performance: re-encoding is likely faster than stripping comments in PHP twice - $this->rawData = FormatJson::decode( FormatJson::encode( $data, FormatJson::ALL_OK ), true ); + $this->rawData = FormatJson::decode( + FormatJson::encode( $data, FormatJson::ALL_OK ), true + ); $this->data = $this->validate( $data ); } @@ -194,7 +199,8 @@ global $wgJsonConfigModels; $view = $this->view; if ( $view === null ) { - $configModels = \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigModels' ) + $wgJsonConfigModels; + $configModels = \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigModels' ) + + $wgJsonConfigModels; if ( array_key_exists( $modelId, $configModels ) ) { $value = $configModels[$modelId]; if ( is_array( $value ) && array_key_exists( 'view', $value ) ) { @@ -211,8 +217,8 @@ } /** - * In case view is not associated with the model for this class, this function will instantiate a default. - * Override may instantiate a more appropriate view + * In case view is not associated with the model for this class, this function will instantiate + * a default. Override may instantiate a more appropriate view * @return JCContentView */ protected function createDefaultView() { diff --git a/includes/JCObjContent.php b/includes/JCObjContent.php index c1a0406..6817b7e 100644 --- a/includes/JCObjContent.php +++ b/includes/JCObjContent.php @@ -12,15 +12,25 @@ */ abstract class JCObjContent extends JCContent { - /** @var bool if false, prevents multiple fields from having identical names that differ only by casing */ + /** + * @var bool if false, prevents multiple fields from having identical names that differ + * only by casing + */ protected $isCaseSensitive = false; + /** @var bool if false, ensure the root to be an stdClass, otherwise - an array */ protected $isRootArray = false; - /** @var JCValue contains raw validation results. At first it is a parsed JSON value, with the root element - * wrapped into JCValue. As validation progresses, all visited values become wrapped with JCValue. */ + + /** + * @var JCValue contains raw validation results. At first it is a parsed JSON value, with the + * root element wrapped into JCValue. As validation progresses, all visited values become + * wrapped with JCValue. + */ protected $validationData; + /** @var mixed */ protected $dataWithDefaults; + /** @var bool|null validation status - null=before, true=during, false=done */ protected $isValidating = null; @@ -67,7 +77,9 @@ */ public function getValidationData() { if ( $this->isValidating === null ) { - throw new Exception( 'This method may only be called during or after validation has started' ); + throw new Exception( + 'This method may only be called during or after validation has started' + ); } return $this->validationData; } @@ -135,14 +147,16 @@ /** * Use this function to test a value, or if the value is missing, use the default value. * The value will be tested with validator(s) if provided, even if it was the default. - * @param string|array $path name of the root field to check, or a path to the field in a nested structure. - * Nested path should be in the form of [ 'field-level1', 'field-level2', ... ]. For example, if client - * needs to check validity of the 'value1' in the structure {'key':{'sub-key':['value0','value1']}}, + * @param string|array $path name of the root field to check, or a path to the field in a nested + * structure. Nested path should be in the form of + * [ 'field-level1', 'field-level2', ... ]. For example, if client needs to check + * validity of the 'value1' in the structure {'key':{'sub-key':['value0','value1']}}, * $field should be set to [ 'key', 'sub-key', 1 ]. - * @param mixed $default value to be used in case field is not found. $default is passed to the validator - * if validation fails. If validation of the default passes, the value is considered optional. - * @param callable $validator callback function as defined in JCValidators::run(). - * More than one validator may be given. If validators are not provided, any value is accepted + * @param mixed $default value to be used in case field is not found. $default is passed to the + * validator if validation fails. If validation of the default passes, + * the value is considered optional. + * @param callable $validator callback function as defined in JCValidators::run(). More than one + * validator may be given. If validators are not provided, any value is accepted * @return bool true if ok, false otherwise * @throws \Exception if $this->initValidation() was not called. */ @@ -154,14 +168,16 @@ } /** - * Use this function to test a field in the data. If missing, the validator(s) will receive JCMissing - * singleton as a value, and it will be up to the validator(s) to accept it or not. - * @param string|array $path name of the root field to check, or a path to the field in a nested structure. - * Nested path should be in the form of [ 'field-level1', 'field-level2', ... ]. For example, if client - * needs to check validity of the 'value1' in the structure {'key':{'sub-key':['value0','value1']}}, + * Use this function to test a field in the data. If missing, the validator(s) will receive + * JCMissing singleton as a value, and it will be up to the validator(s) to accept it or not. + * @param string|array $path name of the root field to check, or a path to the field in a nested + * structure. Nested path should be in the form of + * [ 'field-level1', 'field-level2', ... ]. For example, if client needs to check + * validity of the 'value1' in the structure {'key':{'sub-key':['value0','value1']}}, * $field should be set to [ 'key', 'sub-key', 1 ]. * @param callable $validator callback function as defined in JCValidators::run(). - * More than one validator may be given. If validators are not provided, any value is accepted + * More than one validator may be given. + * If validators are not provided, any value is accepted * @throws \Exception * @return bool true if ok, false otherwise */ @@ -175,11 +191,13 @@ * All validators will be called for each of the sub-values. If there is no value * at the given $path, or it is not a container, no action will be taken and no errors reported * @param string|array $path path to the container field in a nested structure. - * Nested path should be in the form of [ 'field-level1', 'field-level2', ... ]. For example, if client - * needs to check validity of the 'value1' in the structure {'key':{'sub-key':['value0','value1']}}, + * Nested path should be in the form of [ 'field-level1', 'field-level2', ... ]. + * For example, if client needs to check validity of the 'value1' in the structure + * {'key':{'sub-key':['value0','value1']}}, * $field should be set to [ 'key', 'sub-key', 1 ]. * @param callable $validator callback function as defined in JCValidators::run(). - * More than one validator may be given. If validators are not provided, any value is accepted + * More than one validator may be given. + * If validators are not provided, any value is accepted * @throws \Exception * @return bool true if all values tested ok, false otherwise */ @@ -215,7 +233,9 @@ return false; // skip all validation in case of a fatal error } if ( $this->isValidating !== true ) { - throw new Exception( 'This function should only be called inside the validateContent() override' ); + throw new Exception( + 'This function should only be called inside the validateContent() override' + ); } return $this->testRecursive( (array)$path, [], $this->validationData, $validators ); } @@ -318,7 +338,9 @@ // if ( !$isRequired ) { // // User supplied value, so we don't know if the value is required or not // // if $default passes validation, original value was optional -// $isRequired = !JCValidators::run( $validators, $fldPath, JCValue::getMissing(), $this ); +// $isRequired = !JCValidators::run( +// $validators, $fldPath, JCValue::getMissing(), $this +// ); // } $this->addValidationError( $err, !$isRequired ); } @@ -328,10 +350,11 @@ } } // if ( $this->thorough() && $jcv->status() === JCValue::CHECKED ) { -// // Check if the value is the same as default - use a cast to array hack to compare objects +// // Check if the value is the same as default - use a cast to array +// // hack to compare objects // $isRequired = (bool)JCValidators::run( $validators, $fldPath, JCMissing::get(), $this ); -// if ( ( is_object( $jcv ) && is_object( $default ) && (array)$jcv === (array)$default ) || -// ( !is_object( $default ) && $jcv === $default ) +// if ( ( is_object( $jcv ) && is_object( $default ) && (array)$jcv === (array)$default ) +// || ( !is_object( $default ) && $jcv === $default ) // ) { // $newStatus = JCValue::SAME_AS_DEFAULT; // } @@ -456,7 +479,8 @@ * @param int|string $fld * @param array $fldPath * @throws \Exception - * @return bool|null true if renamed, false if not found or original unchanged, null if duplicate (error) + * @return bool|null true if renamed, false if not found or original unchanged, + * null if duplicate (error) */ private function normalizeField( JCValue $jcv, $fld, array $fldPath ) { $valueRef = $jcv->getValue(); @@ -498,7 +522,8 @@ /** * @param null|callable|array $param first validator parameter * @param array $funcArgs result of func_get_args() call - * @param int $skipArgs how many non-validator arguments to remove from the beginning of the $funcArgs + * @param int $skipArgs how many non-validator arguments to remove + * from the beginning of the $funcArgs * @return array of validators */ private static function convertValidators( $param, $funcArgs, $skipArgs ) { diff --git a/includes/JCSingleton.php b/includes/JCSingleton.php index 2d1276c..253b623 100644 --- a/includes/JCSingleton.php +++ b/includes/JCSingleton.php @@ -45,12 +45,14 @@ public static $namespaces = []; /** - * @var MapCacheLRU[] contains a cache of recently resolved JCTitle's as namespace => MapCacheLRU + * @var MapCacheLRU[] contains a cache of recently resolved JCTitle's + * as namespace => MapCacheLRU */ public static $titleMapCacheLru = []; /** - * @var MapCacheLRU[] contains a cache of recently requested content objects as namespace => MapCacheLRU + * @var MapCacheLRU[] contains a cache of recently requested content objects + * as namespace => MapCacheLRU */ public static $mapCacheLru = []; @@ -73,8 +75,13 @@ list( self::$titleMap, self::$namespaces ) = self::parseConfiguration( $wgNamespaceContentModels, $wgContentHandlers, - array_replace_recursive( \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigs' ), $wgJsonConfigs ), - array_replace_recursive( \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigModels' ), $wgJsonConfigModels ) + array_replace_recursive( + \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigs' ), $wgJsonConfigs + ), + array_replace_recursive( + \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigModels' ), + $wgJsonConfigModels + ) ); } @@ -86,8 +93,10 @@ * @param bool $warn if true, calls wfLogWarning() for all errors * @return array [ $titleMap, $namespaces ] */ - public static function parseConfiguration( array $namespaceContentModels, array $contentHandlers, - array $configs, array $models, $warn = true ) { + public static function parseConfiguration( + array $namespaceContentModels, array $contentHandlers, + array $configs, array $models, $warn = true + ) { $defaultModelId = 'JsonConfig'; $warnFunc = $warn ? 'wfLogWarning' : function() {}; @@ -95,26 +104,29 @@ $titleMap = []; foreach ( $configs as $confId => &$conf ) { if ( !is_string( $confId ) ) { - $warnFunc( "JsonConfig: Invalid \$wgJsonConfigs['$confId'], the key must be a string" ); + $warnFunc( + "JsonConfig: Invalid \$wgJsonConfigs['$confId'], the key must be a string" + ); continue; } if ( null === self::getConfObject( $warnFunc, $conf, $confId ) ) { continue; // warned inside the function } - $modelId = property_exists( $conf, 'model' ) ? ( $conf->model ? : $defaultModelId ) : $confId; + $modelId = property_exists( $conf, 'model' ) + ? ( $conf->model ? : $defaultModelId ) : $confId; if ( !array_key_exists( $modelId, $models ) ) { if ( $modelId === $defaultModelId ) { $models[$defaultModelId] = null; } else { $warnFunc( "JsonConfig: Invalid \$wgJsonConfigs['$confId']: " . - "Model '$modelId' is not defined in \$wgJsonConfigModels" ); + "Model '$modelId' is not defined in \$wgJsonConfigModels" ); continue; } } if ( array_key_exists( $modelId, $contentHandlers ) ) { $warnFunc( "JsonConfig: Invalid \$wgJsonConfigs['$confId']: Model '$modelId' is " . - "already registered in \$contentHandlers to {$contentHandlers[$modelId]}" ); + "already registered in \$contentHandlers to {$contentHandlers[$modelId]}" ); continue; } $conf->model = $modelId; @@ -122,13 +134,14 @@ $ns = self::getConfVal( $conf, 'namespace', NS_CONFIG ); if ( !is_int( $ns ) || $ns % 2 !== 0 ) { $warnFunc( "JsonConfig: Invalid \$wgJsonConfigs['$confId']: " . - "Namespace $ns should be an even number" ); + "Namespace $ns should be an even number" ); continue; } - // Even though we might be able to override default content model for namespace, lets keep things clean + // Even though we might be able to override default content model for namespace, + // lets keep things clean if ( array_key_exists( $ns, $namespaceContentModels ) ) { - $warnFunc( "JsonConfig: Invalid \$wgJsonConfigs['$confId']: Namespace $ns is already " . - "set to handle model '$namespaceContentModels[$ns]'" ); + $warnFunc( "JsonConfig: Invalid \$wgJsonConfigs['$confId']: Namespace $ns is " . + "already set to handle model '$namespaceContentModels[$ns]'" ); continue; } @@ -143,13 +156,15 @@ // Decide if matching configs should be stored on this wiki $storeHere = $islocal || property_exists( $conf, 'store' ); if ( !$storeHere ) { - $conf->store = false; // 'store' does not exist, use it as a flag to indicate remote storage - if ( null === ( $remote = self::getConfObject( $warnFunc, $conf, 'remote', $confId, 'url' ) ) ) { + // 'store' does not exist, use it as a flag to indicate remote storage + $conf->store = false; + $remote = self::getConfObject( $warnFunc, $conf, 'remote', $confId, 'url' ); + if ( null === $remote ) { continue; // warned inside the function } if ( self::getConfVal( $remote, 'url', '' ) === '' ) { $warnFunc( "JsonConfig: Invalid \$wgJsonConfigs['$confId']['remote']['url']: " . - "API URL is not set, and this config is not being stored locally" ); + "API URL is not set, and this config is not being stored locally" ); continue; } self::getConfVal( $remote, 'username', '' ); @@ -157,10 +172,14 @@ } else { if ( property_exists( $conf, 'remote' ) ) { // non-fatal -- simply ignore the 'remote' setting - $warnFunc( "JsonConfig: In \$wgJsonConfigs['$confId']['remote'] is set for the config that will be stored on this wiki. 'remote' parameter will be ignored." ); + $warnFunc( "JsonConfig: In \$wgJsonConfigs['$confId']['remote'] is set for " . + "the config that will be stored on this wiki. " . + "'remote' parameter will be ignored." + ); } $conf->remote = null; - if ( null === ( $store = self::getConfObject( $warnFunc, $conf, 'store', $confId ) ) ) { + $store = self::getConfObject( $warnFunc, $conf, 'store', $confId ); + if ( null === $store ) { continue; // warned inside the function } self::getConfVal( $store, 'cacheNewValue', true ); @@ -170,18 +189,21 @@ } // Too lazy to write proper error messages for all parameters. - if ( ( isset( $conf->nsTalk ) && !is_string( $conf->nsTalk ) ) || !is_string( $conf->pattern ) || - !is_bool( $islocal ) || !is_int( $conf->cacheExp ) || - !is_string( $conf->cacheKey ) || !is_bool( $conf->flaggedRevs ) + if ( ( isset( $conf->nsTalk ) && !is_string( $conf->nsTalk ) ) || + !is_string( $conf->pattern ) || + !is_bool( $islocal ) || !is_int( $conf->cacheExp ) || !is_string( $conf->cacheKey ) + || !is_bool( $conf->flaggedRevs ) ) { - $warnFunc( "JsonConfig: Invalid type of one of the parameters in \$wgJsonConfigs['$confId'], please check documentation" ); + $warnFunc( "JsonConfig: Invalid type of one of the parameters in " . + "\$wgJsonConfigs['$confId'], please check documentation" ); continue; } if ( isset( $remote ) ) { if ( !is_string( $remote->url ) || !is_string( $remote->username ) || !is_string( $remote->password ) ) { - $warnFunc( "JsonConfig: Invalid type of one of the parameters in \$wgJsonConfigs['$confId']['remote'], please check documentation" ); + $warnFunc( "JsonConfig: Invalid type of one of the parameters in " . + "\$wgJsonConfigs['$confId']['remote'], please check documentation" ); continue; } } @@ -189,7 +211,8 @@ if ( !is_bool( $store->cacheNewValue ) || !is_string( $store->notifyUrl ) || !is_string( $store->notifyUsername ) || !is_string( $store->notifyPassword ) ) { - $warnFunc( "JsonConfig: Invalid type of one of the parameters in \$wgJsonConfigs['$confId']['store'], please check documentation" ); + $warnFunc( "JsonConfig: Invalid type of one of the parameters in " . + " \$wgJsonConfigs['$confId']['store'], please check documentation" ); continue; } } @@ -203,8 +226,8 @@ $namespaces[$ns] = false; } } elseif ( $ns === NS_CONFIG ) { - $warnFunc( "JsonConfig: Parameter 'nsName' in \$wgJsonConfigs['$confId'] is not " . - "supported for namespace == NS_CONFIG ($ns)" ); + $warnFunc( "JsonConfig: Parameter 'nsName' in \$wgJsonConfigs['$confId'] " . + "is not supported for namespace == NS_CONFIG ($ns)" ); } else { $nsName = $conf->nsName; $nsTalk = isset( $conf->nsTalk ) ? $conf->nsTalk : ( $nsName . '_talk' ); @@ -246,7 +269,9 @@ $nsName = 'Config'; if ( $ns !== NS_CONFIG ) { $nsName .= $missingNs; - $warnFunc( "JsonConfig: Namespace $ns does not have 'nsName' defined, using '$nsName'" ); + $warnFunc( + "JsonConfig: Namespace $ns does not have 'nsName' defined, using '$nsName'" + ); $missingNs += 1; } $namespaces[$ns] = $nsName; @@ -281,7 +306,9 @@ * @param string $treatAsField * @return null|object|stdClass */ - private static function getConfObject( $warnFunc, & $value, $field, $confId = null, $treatAsField = null ) { + private static function getConfObject( + $warnFunc, & $value, $field, $confId = null, $treatAsField = null + ) { if ( !$confId ) { $val = & $value; } else { @@ -299,7 +326,7 @@ $val = (object) [ $treatAsField => $val ]; } elseif ( !is_object( $val ) ) { $warnFunc( "JsonConfig: Invalid \$wgJsonConfigs" . ( $confId ? "['$confId']" : "" ) . - "['$field'], the value must be either an array or an object" ); + "['$field'], the value must be either an array or an object" ); return null; } return $val; @@ -351,7 +378,8 @@ } else { $content = false; } - self::$mapCacheLru[$titleValue->getNamespace()]->set( $titleValue->getDBkey(), $content ); + self::$mapCacheLru[$titleValue->getNamespace()] + ->set( $titleValue->getDBkey(), $content ); } return $content; @@ -394,13 +422,17 @@ */ public static function getContentClass( $modelId ) { global $wgJsonConfigModels; - $configModels = array_replace_recursive( \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigModels' ), $wgJsonConfigModels ); + $configModels = array_replace_recursive( + \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigModels' ), + $wgJsonConfigModels + ); $class = null; if ( array_key_exists( $modelId, $configModels ) ) { $value = $configModels[$modelId]; if ( is_array( $value ) ) { if ( !array_key_exists( 'class', $value ) ) { - wfLogWarning( "JsonConfig: Invalid \$wgJsonConfigModels['$modelId'] array value, 'class' not found" ); + wfLogWarning( "JsonConfig: Invalid \$wgJsonConfigModels['$modelId'] array " . + "value, 'class' not found" ); } else { $class = $value['class']; } @@ -501,7 +533,8 @@ // A bit weird here: cache will store JCTitle objects or false if the namespace // is known to JsonConfig but the dbkey does not match. But in case the title is not - // handled, this function returns null instead of false if the namespace is known, and false otherwise + // handled, this function returns null instead of false if the namespace is known, + // and false otherwise $result = $cache->get( $dbKey ); if ( $result === null ) { @@ -517,7 +550,8 @@ $cache->set( $dbKey, $result ); } - // return null if the given namespace is mentioned in the config, but title doesn't match + // return null if the given namespace is mentioned in the config, + // but title doesn't match return $result ?: null; } else { @@ -527,8 +561,9 @@ } /** - * Returns an array with settings if the $titleValue object is handled by the JsonConfig extension, - * false if unrecognized namespace, and null if namespace is handled but not this title + * Returns an array with settings if the $titleValue object is handled by the JsonConfig + * extension, false if unrecognized namespace, + * and null if namespace is handled but not this title * @param TitleValue $titleValue * @return stdClass|false|null * @deprecated use JCSingleton::parseTitle() instead @@ -539,7 +574,8 @@ } /** - * Only register NS_CONFIG if running on the MediaWiki instance which houses the JSON configs (i.e. META) + * Only register NS_CONFIG if running on the MediaWiki instance which houses + * the JSON configs (i.e. META) * @param array $namespaces */ public static function onCanonicalNamespaces( array &$namespaces ) { @@ -601,7 +637,10 @@ } self::init(); - $models = array_replace_recursive( \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigModels' ), $wgJsonConfigModels ); + $models = array_replace_recursive( + \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigModels' ), + $wgJsonConfigModels + ); if ( array_key_exists( $modelId, $models ) ) { // This is one of our model IDs $handler = new JCContentHandler( $modelId ); @@ -665,8 +704,10 @@ * @param bool $minoredit * @return bool */ - public static function onEditFilterMergedContent( /** @noinspection PhpUnusedParameterInspection */ - $context, $content, $status, $summary, $user, $minoredit ) { + public static function onEditFilterMergedContent( + /** @noinspection PhpUnusedParameterInspection */ + $context, $content, $status, $summary, $user, $minoredit + ) { if ( !self::jsonConfigIsStorage() ) { return true; } @@ -760,13 +801,16 @@ * @param \Skin &$skin * @return bool */ - public static function onBeforePageDisplay( /** @noinspection PhpUnusedParameterInspection */ &$out, &$skin ) { + public static function onBeforePageDisplay( + /** @noinspection PhpUnusedParameterInspection */ &$out, &$skin + ) { if ( !self::jsonConfigIsStorage() ) { return true; } $title = $out->getTitle(); - // todo/fixme? We should probably add ext.jsonConfig style to only those pages that pass parseTitle() + // todo/fixme? We should probably add ext.jsonConfig style to only those pages + // that pass parseTitle() $handler = ContentHandler::getForModelID( $title->getContentModel() ); if ( $handler->getDefaultFormat() === CONTENT_FORMAT_JSON || self::parseTitle( $title ) @@ -776,7 +820,9 @@ return true; } - public static function onMovePageIsValidMove( Title $oldTitle, Title $newTitle, Status $status ) { + public static function onMovePageIsValidMove( + Title $oldTitle, Title $newTitle, Status $status + ) { if ( !self::jsonConfigIsStorage() ) { return true; } @@ -797,7 +843,10 @@ return true; } - public static function onAbortMove( /** @noinspection PhpUnusedParameterInspection */ Title $title, Title $newTitle, $wgUser, &$err, $reason ) { + public static function onAbortMove( + /** @noinspection PhpUnusedParameterInspection */ + Title $title, Title $newTitle, $wgUser, &$err, $reason + ) { if ( !self::jsonConfigIsStorage() ) { return true; } @@ -827,34 +876,49 @@ return true; } - public static function onPageContentSaveComplete( /** @noinspection PhpUnusedParameterInspection */ $article, $user, $content, $summary, $isMinor, $isWatch, - $section, $flags, $revision, $status, $baseRevId ) { + public static function onPageContentSaveComplete( + /** @noinspection PhpUnusedParameterInspection */ + $article, $user, $content, $summary, $isMinor, $isWatch, + $section, $flags, $revision, $status, $baseRevId + ) { return self::onArticleChangeComplete( $article, $content ); } - public static function onArticleDeleteComplete( /** @noinspection PhpUnusedParameterInspection */ $article, &$user, $reason, $id, $content, $logEntry ) { + public static function onArticleDeleteComplete( + /** @noinspection PhpUnusedParameterInspection */ + $article, &$user, $reason, $id, $content, $logEntry + ) { return self::onArticleChangeComplete( $article ); } - public static function onArticleUndelete( /** @noinspection PhpUnusedParameterInspection */ $title, $created, $comment, $oldPageId ) { + public static function onArticleUndelete( + /** @noinspection PhpUnusedParameterInspection */ + $title, $created, $comment, $oldPageId + ) { return self::onArticleChangeComplete( $title ); } - public static function onTitleMoveComplete( /** @noinspection PhpUnusedParameterInspection */ $title, $newTitle, $wgUser, $pageid, $redirid, $reason ) { + public static function onTitleMoveComplete( + /** @noinspection PhpUnusedParameterInspection */ + $title, $newTitle, $wgUser, $pageid, $redirid, $reason + ) { return self::onArticleChangeComplete( $title ) || - self::onArticleChangeComplete( $newTitle ); + self::onArticleChangeComplete( $newTitle ); } /** - * Prohibit creation of the pages that are part of our namespaces but have not been explicitly allowed - * Bad capitalization is due to "userCan" hook name + * Prohibit creation of the pages that are part of our namespaces but have not been explicitly + * allowed. Bad capitalization is due to "userCan" hook name * @param Title $title * @param $user * @param string $action * @param null $result * @return bool */ - public static function onuserCan( /** @noinspection PhpUnusedParameterInspection */ &$title, &$user, $action, &$result = null ) { + public static function onuserCan( + /** @noinspection PhpUnusedParameterInspection */ + &$title, &$user, $action, &$result = null + ) { if ( !self::jsonConfigIsStorage() ) { return true; } @@ -919,7 +983,10 @@ if ( $isStorage === null ) { global $wgJsonConfigs; $isStorage = false; - $configs = array_replace_recursive( \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigs' ), $wgJsonConfigs ); + $configs = array_replace_recursive( + \ExtensionRegistry::getInstance()->getAttribute( 'JsonConfigs' ), + $wgJsonConfigs + ); foreach ( $configs as $jc ) { if ( ( !array_key_exists( 'isLocal', $jc ) || $jc['isLocal'] ) || ( array_key_exists( 'store', $jc ) ) diff --git a/includes/JCTitle.php b/includes/JCTitle.php index c250103..e316c4e 100644 --- a/includes/JCTitle.php +++ b/includes/JCTitle.php @@ -6,7 +6,8 @@ use TitleValue; /** - * A value object class that contains namespace ID, title, and the corresponding jsonconfig configuration + * A value object class that contains namespace ID, title, and + * the corresponding jsonconfig configuration * @package JsonConfig */ final class JCTitle extends TitleValue { diff --git a/includes/JCUtils.php b/includes/JCUtils.php index 2b01013..71dc6b0 100644 --- a/includes/JCUtils.php +++ b/includes/JCUtils.php @@ -15,7 +15,8 @@ class JCUtils { /** - * Uses wfLogWarning() to report an error. All complex arguments are escaped with FormatJson::encode() + * Uses wfLogWarning() to report an error. + * All complex arguments are escaped with FormatJson::encode() * @param string $msg * @param mixed|array $vals * @param bool|array $query @@ -94,7 +95,8 @@ self::warn( 'Failed to login', [ 'url' => $url, 'user' => $username, - 'result' => isset( $res['login']['result'] ) ? $res['login']['result'] : '???' + 'result' => isset( $res['login']['result'] ) + ? $res['login']['result'] : '???' ] ); $req = false; } @@ -123,7 +125,9 @@ [ 'warnings' => $res['warnings'] ], $query ); } if ( isset( $res['error'] ) ) { - self::warn( 'API call failed trying to ' . $debugMsg, [ 'error' => $res['error'] ], $query ); + self::warn( + 'API call failed trying to ' . $debugMsg, [ 'error' => $res['error'] ], $query + ); return false; } return $res; @@ -157,7 +161,8 @@ * @return bool */ public static function allValuesAreStrings( $array ) { - return is_array( $array ) && count( array_filter( $array, 'is_string' ) ) === count( $array ); + return is_array( $array ) + && count( array_filter( $array, 'is_string' ) ) === count( $array ); } /** Helper function to check if the given value is a valid string no longer than maxlength, @@ -185,7 +190,9 @@ } elseif ( is_string( $fld ) ) { $res .= $res !== '' ? ( '/' . $fld ) : $fld; } else { - throw new Exception( 'Unexpected field type, only strings and integers are allowed' ); + throw new Exception( + 'Unexpected field type, only strings and integers are allowed' + ); } } return $res === '' ? '/' : $res; diff --git a/includes/JCValidators.php b/includes/JCValidators.php index 5a7c2b9..edcfd57 100644 --- a/includes/JCValidators.php +++ b/includes/JCValidators.php @@ -10,15 +10,17 @@ /** Call one or more validator functions with the given parameters. * Validator parameters: function ( JCValue $jcv, string $fieldPath, JCContent $content ) - * Validator should update $jcv object with any errors it finds by using error() function. Validator - * may also change the value or set default/same-as-default flags. + * Validator should update $jcv object with any errors it finds by using error() function. + * Validator may also change the value or set default/same-as-default flags. * Setting status to JCValue::MISSING will delete this value (but not its parent) * @param array $validators an array of validator function closures * @param JCValue $value value to validate, modify, and change status of * @param array $path path to the field, needed by the error messages * @param JCContent $content */ - public static function run( array $validators, JCValue $value, array $path, JCContent $content ) { + public static function run( + array $validators, JCValue $value, array $path, JCContent $content + ) { if ( $validators ) { foreach ( $validators as $validator ) { if ( !call_user_func( $validator, $value, $path, $content ) ) { @@ -142,7 +144,8 @@ } /** Returns a validator function that will substitute missing value with default - * @param mixed $default value to use in case field is not present, or a closure function to generate that value + * @param mixed $default value to use in case field is not present, or a closure function to + * generate that value * @param bool $validateDefault if true, the default value will be verified by the validators * @return callable */ diff --git a/tests/manual/TestObjectContent.php b/tests/manual/TestObjectContent.php index 9270734..98a8c8c 100644 --- a/tests/manual/TestObjectContent.php +++ b/tests/manual/TestObjectContent.php @@ -37,7 +37,11 @@ // $this->check( [ 'dict', 'string' ], "" ); $this->testOptional( [ 'emptydict', 'new1' ], new stdClass() ); // $this->check( [ 'emptydict', 1 ], new stdClass() ); - $this->testOptional( [ 'emptydict', 'new1', 'blah', 2 ], new stdClass(), function() { return wfMessage( 'fail' ); } ); + $this->testOptional( [ 'emptydict', 'new1', 'blah', 2 ], new stdClass(), + function() { + return wfMessage( 'fail' ); + } + ); // $this->check( [ 'emptydict', 'newObj', 'newInt' ], 1 ); } } diff --git a/tests/phpunit/JCObjContentTest.php b/tests/phpunit/JCObjContentTest.php index a9fe533..22045a9 100644 --- a/tests/phpunit/JCObjContentTest.php +++ b/tests/phpunit/JCObjContentTest.php @@ -44,7 +44,9 @@ * @-dataProvider provideValidationFirst * @dataProvider provideValidation */ - public function testValidation( $message, $initial, $expectedWithDflts, $expectedNoDflts, $validators, $errors = null ) { + public function testValidation( + $message, $initial, $expectedWithDflts, $expectedNoDflts, $validators, $errors = null + ) { if ( $expectedWithDflts === true ) { $expectedWithDflts = $initial; } @@ -59,13 +61,17 @@ } else { $this->assertFalse( $c->isValid(), $msg . 'MUST-BE-INVALID' ); $errCount = is_int( $errors ) ? $errors : count( $errors ); - $this->assertCount( $errCount, $c->getStatus()->getErrorsArray(), $msg . 'ERROR-COUNT' ); + $this->assertCount( + $errCount, $c->getStatus()->getErrorsArray(), $msg . 'ERROR-COUNT' + ); } - $expected = is_array( $expectedWithDflts ) ? $expectedWithDflts[(int)$th] : $expectedWithDflts; + $expected = is_array( $expectedWithDflts ) + ? $expectedWithDflts[(int)$th] : $expectedWithDflts; $this->assertJsonEquals( $expected, $c->getDataWithDefaults(), $msg . 'WITH-DEFAULTS' ); if ( $expectedNoDflts ) { - $expected = is_array( $expectedNoDflts ) ? $expectedNoDflts[(int)$th] : $expectedNoDflts; + $expected = is_array( $expectedNoDflts ) + ? $expectedNoDflts[(int)$th] : $expectedNoDflts; } $this->assertJsonEquals( $expected, $c->getData(), $msg . 'NO-DEFAULTS' ); } @@ -282,7 +288,10 @@ [ 'sort1', '{"unknown":1, "checked":2}', - [ '{"unknown":1, "checked":2, "default":0}', '{"default":0, "checked":2, "unknown":1}' ], + [ + '{"unknown":1, "checked":2, "default":0}', + '{"default":0, "checked":2, "unknown":1}' + ], [ '{"unknown":1, "checked":2}', '{"checked":2, "unknown":1}' ], function ( JCObjContent $o ) { $o->testOptional( 'default', 0, JCValidators::isInt() ); @@ -292,7 +301,10 @@ [ 'sort2', '{"f":[{"unknown":1, "checked":2}]}', - [ '{"f":[{"unknown":1, "checked":2, "default":0}]}', '{"f":[{"default":0, "checked":2, "unknown":1}]}' ], + [ + '{"f":[{"unknown":1, "checked":2, "default":0}]}', + '{"f":[{"default":0, "checked":2, "unknown":1}]}' + ], [ '{"f":[{"unknown":1, "checked":2}]}', '{"f":[{"checked":2, "unknown":1}]}' ], function ( JCObjContent $o ) { $o->testOptional( [ 'f', 0, 'default' ], 0, JCValidators::isInt() ); -- To view, visit https://gerrit.wikimedia.org/r/356840 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I52a4119e1e64417fd1d0c732d0b3a87a3e3a625c Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/JsonConfig Gerrit-Branch: master Gerrit-Owner: Umherirrender <umherirrender_de...@web.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits