Merge "Move WatchedItem logic to WatchedItemStore"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 8 Mar 2016 18:04:11 +0000 (18:04 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 8 Mar 2016 18:04:11 +0000 (18:04 +0000)
1  2 
RELEASE-NOTES-1.27
includes/api/ApiBase.php

diff --combined RELEASE-NOTES-1.27
@@@ -217,10 -217,7 +217,10 @@@ HHVM 3.1
    ApiQueryBase::keyPartToTitle() all removed (deprecated since 1.24).
  * ApiQueryBase::checkRowCount() was removed (deprecated since 1.24).
  * ApiQueryBase::getDirectionDescription() was removed (deprecated since 1.25).
 +* ApiQuery::getGenerators() was removed (deprecated since 1.21).
  * ApiQuery::getModules() was removed (deprecated since 1.21).
 +* ApiQuery::getModuleType() was removed (deprecated since 1.21).
 +* ApiQuery::setGeneratorContinue() was removed (deprecated since 1.24).
  * ApiMain::getModules() was removed (deprecated since 1.21).
  * ApiBase::getVersion() was removed (deprecated since 1.21).
  
@@@ -327,6 -324,17 +327,17 @@@ changes to languages because of Phabric
    does not support categories.
  * wikidiff difference engine is no longer supported, anyone still using it are encouraged
    to upgrade to wikidiff2 which is actively maintained and has better package availability.
+ * Database logic was removed from WatchedItem and a WatchedItemStore was created:
+ ** WatchedItem::IGNORE_USER_RIGHTS and WatchedItem::CHECK_USER_RIGHTS were deprecated.
+    User::IGNORE_USER_RIGHTS and User::CHECK_USER_RIGHTS were introduced.
+ ** WatchedItem::fromUserTitle was deprecated in favour of the constructor.
+ ** WatchedItem::resetNotificationTimestamp was deprecated.
+ ** WatchedItem::batchAddWatch was deprecated.
+ ** WatchedItem::addWatch was deprecated.
+ ** WatchedItem::removeWatch was deprecated.
+ ** WatchedItem::isWatched was deprecated.
+ ** WatchedItem::duplicateEntries was deprecated.
+ ** User::getWatchedItem was removed.
  
  == Compatibility ==
  
diff --combined includes/api/ApiBase.php
@@@ -302,7 -302,7 +302,7 @@@ abstract class ApiBase extends ContextS
                                        $qs = $k;
                                        $msg = self::escapeWikiText( $v );
                                        if ( is_array( $msg ) ) {
 -                                              $msg = join( " ", $msg );
 +                                              $msg = join( ' ', $msg );
                                        }
                                }
  
                $p = $this->getModulePrefix();
  
                $intersection = array_intersect( array_keys( array_filter( $params,
 -                      [ $this, "parameterNotEmpty" ] ) ), $required );
 +                      [ $this, 'parameterNotEmpty' ] ) ), $required );
  
                if ( count( $intersection ) > 1 ) {
                        $this->dieUsage(
                $p = $this->getModulePrefix();
  
                $intersection = array_intersect( array_keys( array_filter( $params,
 -                      [ $this, "parameterNotEmpty" ] ) ), $required );
 +                      [ $this, 'parameterNotEmpty' ] ) ), $required );
  
                if ( count( $intersection ) > 1 ) {
                        $this->dieUsage(
                $p = $this->getModulePrefix();
  
                $intersection = array_intersect(
 -                      array_keys( array_filter( $params, [ $this, "parameterNotEmpty" ] ) ),
 +                      array_keys( array_filter( $params, [ $this, 'parameterNotEmpty' ] ) ),
                        $required
                );
  
         */
        protected function getWatchlistValue( $watchlist, $titleObj, $userOption = null ) {
  
-               $userWatching = $this->getUser()->isWatched( $titleObj, WatchedItem::IGNORE_USER_RIGHTS );
+               $userWatching = $this->getUser()->isWatched( $titleObj, User::IGNORE_USER_RIGHTS );
  
                switch ( $watchlist ) {
                        case 'watch':
                                ApiBase::dieDebug(
                                        __METHOD__,
                                        "Boolean param $encParamName's default is set to '$default'. " .
 -                                              "Boolean parameters must default to false."
 +                                              'Boolean parameters must default to false.'
                                );
                        }
  
                                if ( $value !== null ) {
                                        $this->dieUsage(
                                                "File upload param $encParamName is not a file upload; " .
 -                                                      "be sure to use multipart/form-data for your POST and include " .
 -                                                      "a filename in the Content-Disposition header.",
 +                                                      'be sure to use multipart/form-data for your POST and include ' .
 +                                                      'a filename in the Content-Disposition header.',
                                                "badupload_{$encParamName}"
                                        );
                                }
                        if ( count( $unknown ) ) {
                                if ( $allowMultiple ) {
                                        $s = count( $unknown ) > 1 ? 's' : '';
 -                                      $vals = implode( ", ", $unknown );
 +                                      $vals = implode( ', ', $unknown );
                                        $this->setWarning( "Unrecognized value$s for parameter '$valueName': $vals" );
                                } else {
                                        $this->dieUsage(
                ],
                'badaccess-group0' => [
                        'code' => 'permissiondenied',
 -                      'info' => "Permission denied"
 +                      'info' => 'Permission denied'
                ], // Generic permission denied message
                'badaccess-groups' => [
                        'code' => 'permissiondenied',
 -                      'info' => "Permission denied"
 +                      'info' => 'Permission denied'
                ],
                'titleprotected' => [
                        'code' => 'protectedtitle',
 -                      'info' => "This title has been protected from creation"
 +                      'info' => 'This title has been protected from creation'
                ],
                'nocreate-loggedin' => [
                        'code' => 'cantcreate',
                ],
                'confirmedittext' => [
                        'code' => 'confirmemail',
 -                      'info' => "You must confirm your email address before you can edit"
 +                      'info' => 'You must confirm your email address before you can edit'
                ],
                'blockedtext' => [
                        'code' => 'blocked',
 -                      'info' => "You have been blocked from editing"
 +                      'info' => 'You have been blocked from editing'
                ],
                'autoblockedtext' => [
                        'code' => 'autoblocked',
 -                      'info' => "Your IP address has been blocked automatically, because it was used by a blocked user"
 +                      'info' => 'Your IP address has been blocked automatically, because it was used by a blocked user'
                ],
  
                // Miscellaneous interface messages
                ],
                'alreadyrolled' => [
                        'code' => 'alreadyrolled',
 -                      'info' => "The page you tried to rollback was already rolled back"
 +                      'info' => 'The page you tried to rollback was already rolled back'
                ],
                'cantrollback' => [
                        'code' => 'onlyauthor',
 -                      'info' => "The page you tried to rollback only has one author"
 +                      'info' => 'The page you tried to rollback only has one author'
                ],
                'readonlytext' => [
                        'code' => 'readonly',
 -                      'info' => "The wiki is currently in read-only mode"
 +                      'info' => 'The wiki is currently in read-only mode'
                ],
                'sessionfailure' => [
                        'code' => 'badtoken',
 -                      'info' => "Invalid token" ],
 +                      'info' => 'Invalid token' ],
                'cannotdelete' => [
                        'code' => 'cantdelete',
                        'info' => "Couldn't delete \"\$1\". Maybe it was deleted already by someone else"
                ],
                'immobile_namespace' => [
                        'code' => 'immobilenamespace',
 -                      'info' => "You tried to move pages from or to a namespace that is protected from moving"
 +                      'info' => 'You tried to move pages from or to a namespace that is protected from moving'
                ],
                'articleexists' => [
                        'code' => 'articleexists',
 -                      'info' => "The destination article already exists and is not a redirect to the source article"
 +                      'info' => 'The destination article already exists and is not a redirect to the source article'
                ],
                'protectedpage' => [
                        'code' => 'protectedpage',
                ],
                'hookaborted' => [
                        'code' => 'hookaborted',
 -                      'info' => "The modification you tried to make was aborted by an extension hook"
 +                      'info' => 'The modification you tried to make was aborted by an extension hook'
                ],
                'cantmove-titleprotected' => [
                        'code' => 'protectedtitle',
 -                      'info' => "The destination article has been protected from creation"
 +                      'info' => 'The destination article has been protected from creation'
                ],
                'imagenocrossnamespace' => [
                        'code' => 'nonfilenamespace',
                ],
                // 'badarticleerror' => shouldn't happen
                // 'badtitletext' => shouldn't happen
 -              'ip_range_invalid' => [ 'code' => 'invalidrange', 'info' => "Invalid IP range" ],
 +              'ip_range_invalid' => [ 'code' => 'invalidrange', 'info' => 'Invalid IP range' ],
                'range_block_disabled' => [
                        'code' => 'rangedisabled',
 -                      'info' => "Blocking IP ranges has been disabled"
 +                      'info' => 'Blocking IP ranges has been disabled'
                ],
                'nosuchusershort' => [
                        'code' => 'nosuchuser',
                        'info' => "The user you specified doesn't exist"
                ],
 -              'badipaddress' => [ 'code' => 'invalidip', 'info' => "Invalid IP address specified" ],
 -              'ipb_expiry_invalid' => [ 'code' => 'invalidexpiry', 'info' => "Invalid expiry time" ],
 +              'badipaddress' => [ 'code' => 'invalidip', 'info' => 'Invalid IP address specified' ],
 +              'ipb_expiry_invalid' => [ 'code' => 'invalidexpiry', 'info' => 'Invalid expiry time' ],
                'ipb_already_blocked' => [
                        'code' => 'alreadyblocked',
 -                      'info' => "The user you tried to block was already blocked"
 +                      'info' => 'The user you tried to block was already blocked'
                ],
                'ipb_blocked_as_range' => [
                        'code' => 'blockedasrange',
                ],
                'ipb_cant_unblock' => [
                        'code' => 'cantunblock',
 -                      'info' => "The block you specified was not found. It may have been unblocked already"
 +                      'info' => 'The block you specified was not found. It may have been unblocked already'
                ],
                'mailnologin' => [
                        'code' => 'cantsend',
 -                      'info' => "You are not logged in, you do not have a confirmed email address, or you are not allowed to send email to other users, so you cannot send email"
 +                      'info' => 'You are not logged in, you do not have a confirmed email address, or you are not allowed to send email to other users, so you cannot send email'
                ],
                'ipbblocked' => [
                        'code' => 'ipbblocked',
                ],
                'usermaildisabled' => [
                        'code' => 'usermaildisabled',
 -                      'info' => "User email has been disabled"
 +                      'info' => 'User email has been disabled'
                ],
                'blockedemailuser' => [
                        'code' => 'blockedfrommail',
 -                      'info' => "You have been blocked from sending email"
 +                      'info' => 'You have been blocked from sending email'
                ],
                'notarget' => [
                        'code' => 'notarget',
 -                      'info' => "You have not specified a valid target for this action"
 +                      'info' => 'You have not specified a valid target for this action'
                ],
                'noemail' => [
                        'code' => 'noemail',
 -                      'info' => "The user has not specified a valid email address, or has chosen not to receive email from other users"
 +                      'info' => 'The user has not specified a valid email address, or has chosen not to receive email from other users'
                ],
                'rcpatroldisabled' => [
                        'code' => 'patroldisabled',
 -                      'info' => "Patrolling is disabled on this wiki"
 +                      'info' => 'Patrolling is disabled on this wiki'
                ],
                'markedaspatrollederror-noautopatrol' => [
                        'code' => 'noautopatrol',
                // API-specific messages
                'readrequired' => [
                        'code' => 'readapidenied',
 -                      'info' => "You need read permission to use this module"
 +                      'info' => 'You need read permission to use this module'
                ],
                'writedisabled' => [
                        'code' => 'noapiwrite',
                ],
                'unblock-notarget' => [
                        'code' => 'notarget',
 -                      'info' => "Either the id or the user parameter must be set"
 +                      'info' => 'Either the id or the user parameter must be set'
                ],
                'unblock-idanduser' => [
                        'code' => 'idanduser',
                ],
                'createonly-exists' => [
                        'code' => 'articleexists',
 -                      'info' => "The article you tried to create has been created already"
 +                      'info' => 'The article you tried to create has been created already'
                ],
                'nocreate-missing' => [
                        'code' => 'missingtitle',
                'noedit' => [ 'code' => 'noedit', 'info' => "You don't have permission to edit pages" ],
                'wasdeleted' => [
                        'code' => 'pagedeleted',
 -                      'info' => "The page has been deleted since you fetched its timestamp"
 +                      'info' => 'The page has been deleted since you fetched its timestamp'
                ],
                'blankpage' => [
                        'code' => 'emptypage',
 -                      'info' => "Creating new, empty pages is not allowed"
 +                      'info' => 'Creating new, empty pages is not allowed'
                ],
 -              'editconflict' => [ 'code' => 'editconflict', 'info' => "Edit conflict detected" ],
 -              'hashcheckfailed' => [ 'code' => 'badmd5', 'info' => "The supplied MD5 hash was incorrect" ],
 +              'editconflict' => [ 'code' => 'editconflict', 'info' => 'Edit conflict detected' ],
 +              'hashcheckfailed' => [ 'code' => 'badmd5', 'info' => 'The supplied MD5 hash was incorrect' ],
                'missingtext' => [
                        'code' => 'notext',
 -                      'info' => "One of the text, appendtext, prependtext and undo parameters must be set"
 +                      'info' => 'One of the text, appendtext, prependtext and undo parameters must be set'
                ],
                'emptynewsection' => [
                        'code' => 'emptynewsection',
                // Messages from WikiPage::doEit(]
                'edit-hook-aborted' => [
                        'code' => 'edit-hook-aborted',
 -                      'info' => "Your edit was aborted by an ArticleSave hook"
 +                      'info' => 'Your edit was aborted by an ArticleSave hook'
                ],
                'edit-gone-missing' => [
                        'code' => 'edit-gone-missing',
                        'info' => "The page you tried to edit doesn't seem to exist anymore"
                ],
 -              'edit-conflict' => [ 'code' => 'editconflict', 'info' => "Edit conflict detected" ],
 +              'edit-conflict' => [ 'code' => 'editconflict', 'info' => 'Edit conflict detected' ],
                'edit-already-exists' => [
                        'code' => 'edit-already-exists',
                        'info' => 'It seems the page you tried to create already exist'
                        $msg = ApiBase::makeMessage( $msg, $this->getContext(),
                                [ $prefix, $param, $name, $path ] );
                        if ( !$msg ) {
 -                              $this->dieDebug( __METHOD__,
 +                              self::dieDebug( __METHOD__,
                                        'Value in ApiBase::PARAM_HELP_MSG is not valid' );
                        }
                        $msgs[$param] = [ $msg ];
  
                        if ( isset( $settings[ApiBase::PARAM_HELP_MSG_PER_VALUE] ) ) {
                                if ( !is_array( $settings[ApiBase::PARAM_HELP_MSG_PER_VALUE] ) ) {
 -                                      $this->dieDebug( __METHOD__,
 +                                      self::dieDebug( __METHOD__,
                                                'ApiBase::PARAM_HELP_MSG_PER_VALUE is not valid' );
                                }
                                if ( !is_array( $settings[ApiBase::PARAM_TYPE] ) ) {
 -                                      $this->dieDebug( __METHOD__,
 +                                      self::dieDebug( __METHOD__,
                                                'ApiBase::PARAM_HELP_MSG_PER_VALUE may only be used when ' .
                                                'ApiBase::PARAM_TYPE is an array' );
                                }
                                                );
                                                $msgs[$param][] = $m->setContext( $this->getContext() );
                                        } else {
 -                                              $this->dieDebug( __METHOD__,
 +                                              self::dieDebug( __METHOD__,
                                                        "Value in ApiBase::PARAM_HELP_MSG_PER_VALUE for $value is not valid" );
                                        }
                                }
  
                        if ( isset( $settings[ApiBase::PARAM_HELP_MSG_APPEND] ) ) {
                                if ( !is_array( $settings[ApiBase::PARAM_HELP_MSG_APPEND] ) ) {
 -                                      $this->dieDebug( __METHOD__,
 +                                      self::dieDebug( __METHOD__,
                                                'Value for ApiBase::PARAM_HELP_MSG_APPEND is not an array' );
                                }
                                foreach ( $settings[ApiBase::PARAM_HELP_MSG_APPEND] as $m ) {
                                        if ( $m ) {
                                                $msgs[$param][] = $m;
                                        } else {
 -                                              $this->dieDebug( __METHOD__,
 +                                              self::dieDebug( __METHOD__,
                                                        'Value in ApiBase::PARAM_HELP_MSG_APPEND is not valid' );
                                        }
                                }
                                                $examples
                                        ];
                                }
 -                              $msg .= "Example" . ( count( $examples ) > 1 ? 's' : '' ) . ":\n";
 +                              $msg .= 'Example' . ( count( $examples ) > 1 ? 's' : '' ) . ":\n";
                                foreach ( $examples as $k => $v ) {
                                        if ( is_numeric( $k ) ) {
                                                $msg .= "  $v\n";
                                                } else {
                                                        $msgExample = "  $v";
                                                }
 -                                              $msgExample .= ":";
 +                                              $msgExample .= ':';
                                                $msg .= wordwrap( $msgExample, 100, "\n" ) . "\n    $k\n";
                                        }
                                }
         * @return string
         */
        private function indentExampleText( $item ) {
 -              return "  " . $item;
 +              return '  ' . $item;
        }
  
        /**
                                if ( isset( $paramSettings[self::PARAM_REQUIRED] )
                                        && $paramSettings[self::PARAM_REQUIRED]
                                ) {
 -                                      $desc .= $paramPrefix . "This parameter is required";
 +                                      $desc .= $paramPrefix . 'This parameter is required';
                                }
  
                                $type = isset( $paramSettings[self::PARAM_TYPE] )
                                                                }
                                                                break;
                                                        case 'upload':
 -                                                              $desc .= $paramPrefix . "Must be posted as a file upload using multipart/form-data";
 +                                                              $desc .= $paramPrefix . 'Must be posted as a file upload using multipart/form-data';
                                                                break;
                                                }
                                        }
                                                if ( !$isArray
                                                        || $isArray && count( $type ) > self::LIMIT_SML1
                                                ) {
 -                                                      $desc .= $paramPrefix . "Maximum number of values " .
 -                                                              self::LIMIT_SML1 . " (" . self::LIMIT_SML2 . " for bots)";
 +                                                      $desc .= $paramPrefix . 'Maximum number of values ' .
 +                                                              self::LIMIT_SML1 . ' (' . self::LIMIT_SML2 . ' for bots)';
                                                }
                                        }
                                }