Merge "Special:Block: Align partial input field better with rest of interface"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 3 Jan 2019 17:54:16 +0000 (17:54 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 3 Jan 2019 17:54:16 +0000 (17:54 +0000)
12 files changed:
.mailmap
CREDITS
autoload.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLSelectLanguageField.php [new file with mode: 0644]
includes/mail/UserMailer.php
includes/skins/SkinApi.php
includes/specials/SpecialAllMessages.php
includes/specials/pagers/AllMessagesTablePager.php
includes/watcheditem/WatchedItemStore.php
maintenance/sql.php
resources/src/mediawiki.special.block.js

index 8637e77..8f2aa28 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -33,6 +33,7 @@ addshore <addshorewiki@gmail.com>
 addshore <addshorewiki@gmail.com> <adamshorland@gmail.com>
 Aditya Sastry <ganeshaditya1@gmail.com>
 Adrian Heine <adrian.heine@wikimedia.de>
+Alangi Derick <alangiderick@gmail.com>
 Alex Z. <mrzmanwiki@gmail.com> <mrzman@users.mediawiki.org>
 Aleksey Bekh-Ivanov <aleksey.bekh-ivanov@wikimedia.de>
 Alexandre Emsenhuber <ialex.wiki@gmail.com>
@@ -272,6 +273,7 @@ Marcin Cieślak <saper@saper.info>
 Marcin Cieślak <saper@saper.info> <saper@users.mediawiki.org>
 Marco Falke <maic23@live.de>
 MarcoAurelio <strigiwm@gmail.com>
+MarcoAurelio <strigiwm@gmail.com> <maurelio@tools.wmflabs.org>
 Marielle Volz <marielle.volz@gmail.com>
 Marius Hoch <hoo@online.de>
 Mark Clements <mediawiki@kennel17.co.uk> <happydog@users.mediawiki.org>
@@ -286,6 +288,7 @@ Markus Glaser <glaser@hallowelt.biz>
 Markus Glaser <glaser@hallowelt.biz> <mglaser@users.mediawiki.org>
 Matt Johnston <mattj@emazestudios.com> <mattj@users.mediawiki.org>
 Matthew Britton <hugglegurch@gmail.com> <gurch@users.mediawiki.org>
+Matthew Bowker <matthewrbowker.bugs@gmail.com>
 Matthew Flaschen <mflaschen@wikimedia.org>
 Matthew Walker <mwalker@wikimedia.org>
 MatthiasDD <Matthias_K2@gmx.de>
@@ -373,6 +376,7 @@ Robert Hoenig <indielives010@gmail.com>
 Robert Leverington <robert@rhl.me.uk> <roberthl@users.mediawiki.org>
 Robert Rohde <rarohde@gmail.com> <rarohde@users.mediawiki.org>
 Robert Stojnić <rainmansr@gmail.com> <rainman@users.mediawiki.org>
+Robert Vogel <vogel@hallowelt.biz>
 Robin Pepermans <robinp.1273@gmail.com>
 Robin Pepermans <robinp.1273@gmail.com> <robin@users.mediawiki.org>
 robinhood701 <robinhood70@live.ca>
diff --git a/CREDITS b/CREDITS
index 27ded1c..5e19ca0 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -16,6 +16,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Aashaka Shah
 * abhinand
 * Abhishek Das
+* Abián
 * Ad Huikeshoven
 * Adam Miller
 * Adam Roses Wight
@@ -101,6 +102,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Bill Traynor
 * Billinghurst
 * billm
+* Bjornskjald
 * blackspirit96
 * blotmandroid
 * Bogdan Stancescu
@@ -347,6 +349,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Jonathan Wiltshire
 * Jools Wills
 * jsahleen
+* Juan Osorio
 * Julian Ostrow
 * Juliano F. Ravasi
 * Julien Girault
@@ -402,6 +405,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Lucas Werkmeister
 * Luigi Corsaro
 * Luis Felipe Schenone
+* LukBukkit
 * Luke Faraone
 * Luke Welling
 * Lupin
@@ -475,6 +479,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Misza13
 * mjbmr
 * moejoe0000
+* Mogmog123
 * Mohamed Magdy
 * Molly White
 * Moriel Schottlender
@@ -506,6 +511,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Nicolaie Constantinescu
 * Nicolas Dumazet
 * Nicolas Weeger
+* Niedzielski
 * Niharika Kohli
 * Nik Everett
 * Niklas Laxström
@@ -561,6 +567,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Pikne
 * Piotr Miazga
 * PiRSquared17
+* pjht
 * Platonides
 * Pmlineditor
 * pmolina
@@ -578,6 +585,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * quiddity
 * quietust
 * Quim Gil
+* Rafid Aslam
 * rahul21
 * Raimond Spekking
 * Ramunas Geciauskas
@@ -641,11 +649,13 @@ The following list can be found parsed under Special:Version/Credits -->
 * Sethakill
 * Sfic
 * Shahyar
+* shandrenkoff
 * Shane Gibbons
 * Shane King
 * shanika
 * Shinjiman
 * shirayuki
+* Shreyas Minocha
 * Sidhant Gupta
 * Siebrand Mazeland
 * Simeon Dahl
@@ -669,6 +679,7 @@ The following list can be found parsed under Special:Version/Credits -->
 * Steve Sanbeg
 * Steven Roddis
 * Steven Walling
+* stibba
 * Str4nd
 * Strainu
 * Subin Siby
index 6a5a9df..2713857 100644 (file)
@@ -603,6 +603,7 @@ $wgAutoloadLocalClasses = [
        'HTMLRestrictionsField' => __DIR__ . '/includes/htmlform/fields/HTMLRestrictionsField.php',
        'HTMLSelectAndOtherField' => __DIR__ . '/includes/htmlform/fields/HTMLSelectAndOtherField.php',
        'HTMLSelectField' => __DIR__ . '/includes/htmlform/fields/HTMLSelectField.php',
+       'HTMLSelectLanguageField' => __DIR__ . '/includes/htmlform/HTMLSelectLanguageField.php',
        'HTMLSelectLimitField' => __DIR__ . '/includes/htmlform/fields/HTMLSelectLimitField.php',
        'HTMLSelectNamespace' => __DIR__ . '/includes/htmlform/fields/HTMLSelectNamespace.php',
        'HTMLSelectNamespaceWithButton' => __DIR__ . '/includes/htmlform/fields/HTMLSelectNamespaceWithButton.php',
index 1a7f850..44e703b 100644 (file)
@@ -159,6 +159,7 @@ class HTMLForm extends ContextSource {
                'checkmatrix' => HTMLCheckMatrix::class,
                'cloner' => HTMLFormFieldCloner::class,
                'autocompleteselect' => HTMLAutoCompleteSelectField::class,
+               'language' => HTMLSelectLanguageField::class,
                'date' => HTMLDateTimeField::class,
                'time' => HTMLDateTimeField::class,
                'datetime' => HTMLDateTimeField::class,
diff --git a/includes/htmlform/HTMLSelectLanguageField.php b/includes/htmlform/HTMLSelectLanguageField.php
new file mode 100644 (file)
index 0000000..5d2019c
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * Language select field.
+ */
+class HTMLSelectLanguageField extends HTMLSelectField {
+       public function __construct( $params ) {
+               parent::__construct( $params );
+
+               if ( $this->mParent instanceof HTMLForm ) {
+                       $config = $this->mParent->getConfig();
+                       $languageCode = $config->get( 'LanguageCode' );
+               } else {
+                       global $wgLanguageCode;
+                       $languageCode = $wgLanguageCode;
+               }
+
+               $languages = Language::fetchLanguageNames( null, 'mw' );
+
+               // Make sure the site language is in the list;
+               // a custom language code might not have a defined name…
+               if ( !array_key_exists( $languageCode, $languages ) ) {
+                       $languages[$languageCode] = $languageCode;
+               }
+
+               foreach ( $languages as $code => $name ) {
+                       $this->mParams['options'][$code . ' - ' . $name] = $code;
+               }
+
+               if ( !array_key_exists( 'default', $params ) ) {
+                       $this->mParams['default'] = $languageCode;
+               }
+       }
+}
index f348c5b..63a3eb0 100644 (file)
@@ -102,7 +102,7 @@ class UserMailer {
         * @param MailAddress|MailAddress[] $to Recipient's email (or an array of them)
         * @param MailAddress $from Sender's email
         * @param string $subject Email's subject.
-        * @param string $body Email's text or Array of two strings to be the text and html bodies
+        * @param string|string[] $body Email's text or Array of two strings to be the text and html bodies
         * @param array $options Keys:
         *     'replyTo' MailAddress
         *     'contentType' string default 'text/plain; charset=UTF-8'
@@ -225,7 +225,7 @@ class UserMailer {
         * @param MailAddress[] $to Array of recipients' email addresses
         * @param MailAddress $from Sender's email
         * @param string $subject Email's subject.
-        * @param string $body Email's text or Array of two strings to be the text and html bodies
+        * @param string|string[] $body Email's text or Array of two strings to be the text and html bodies
         * @param array $options Keys:
         *     'replyTo' MailAddress
         *     'contentType' string default 'text/plain; charset=UTF-8'
index 38d94e4..8ee2a75 100644 (file)
@@ -35,6 +35,8 @@ class SkinApi extends SkinTemplate {
        public function getDefaultModules() {
                $modules = parent::getDefaultModules();
                $modules['styles']['skin'][] = 'mediawiki.skinning.interface';
+               // There is no search box, disable 'mediawiki.searchSuggest'
+               $modules['search'] = [];
                return $modules;
        }
 
index 9e66447..2482d74 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup SpecialPage
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * Use this special page to get a list of the MediaWiki system messages.
  * @ingroup SpecialPage
  */
 class SpecialAllMessages extends SpecialPage {
-       /**
-        * @var AllMessagesTablePager
-        */
-       protected $table;
 
        public function __construct() {
                parent::__construct( 'Allmessages' );
@@ -43,7 +40,6 @@ class SpecialAllMessages extends SpecialPage {
         * @param string $par Parameter passed to the page or null
         */
        public function execute( $par ) {
-               $request = $this->getRequest();
                $out = $this->getOutput();
 
                $this->setHeaders();
@@ -54,18 +50,77 @@ class SpecialAllMessages extends SpecialPage {
                        return;
                }
 
-               $this->outputHeader( 'allmessagestext' );
                $out->addModuleStyles( 'mediawiki.special' );
                $this->addHelpLink( 'Help:System message' );
 
-               $this->table = new AllMessagesTablePager(
-                       $this,
-                       [],
-                       wfGetLangObj( $request->getVal( 'lang', $par ) )
-               );
+               $contLang = MediaWikiServices::getInstance()->getContentLanguage()->getCode();
+               $lang = $this->getLanguage();
+
+               $opts = new FormOptions();
+
+               $opts->add( 'prefix', '' );
+               $opts->add( 'filter', 'all' );
+               $opts->add( 'lang', $contLang );
+               $opts->add( 'limit', 50 );
+
+               $opts->fetchValuesFromRequest( $this->getRequest() );
+               $opts->validateIntBounds( 'limit', 0, 5000 );
+
+               $pager = new AllMessagesTablePager( $this->getContext(), $opts );
+
+               $formDescriptor = [
+                       'prefix' => [
+                               'type' => 'text',
+                               'name' => 'prefix',
+                               'label-message' => 'allmessages-prefix',
+                       ],
+
+                       'filter' => [
+                               'type' => 'radio',
+                               'name' => 'filter',
+                               'label-message' => 'allmessages-filter',
+                               'options' => [
+                                       $this->msg( 'allmessages-filter-unmodified' )->text() => 'unmodified',
+                                       $this->msg( 'allmessages-filter-all' )->text() => 'all',
+                                       $this->msg( 'allmessages-filter-modified' )->text() => 'modified',
+                               ],
+                               'default' => 'all',
+                               'flatlist' => true,
+                       ],
+
+                       'lang' => [
+                               'type' => 'language',
+                               'name' => 'lang',
+                               'label-message' => 'allmessages-language',
+                               'default' => $opts->getValue( 'lang' ),
+                       ],
+
+                       'limit' => [
+                               'type' => 'limitselect',
+                               'name' => 'limit',
+                               'label-message' => 'table_pager_limit_label',
+                               'options' => [
+                                       $lang->formatNum( 20 ) => 20,
+                                       $lang->formatNum( 50 ) => 50,
+                                       $lang->formatNum( 100 ) => 100,
+                                       $lang->formatNum( 250 ) => 250,
+                                       $lang->formatNum( 500 ) => 500,
+                                       $lang->formatNum( 5000 ) => 5000,
+                               ],
+                               'default' => $opts->getValue( 'limit' ),
+                       ],
+               ];
+
+               $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() );
+               $htmlForm
+                       ->setMethod( 'get' )
+                       ->setIntro( $this->msg( 'allmessagestext' ) )
+                       ->setWrapperLegendMsg( 'allmessages' )
+                       ->setSubmitTextMsg( 'allmessages-filter-submit' )
+                       ->prepareForm()
+                       ->displayForm( false );
 
-               $out->addHTML( $this->table->buildForm() );
-               $out->addParserOutputContent( $this->table->getFullOutput() );
+               $out->addParserOutputContent( $pager->getFullOutput() );
        }
 
        protected function getGroupName() {
index e3c0d6d..26c2c50 100644 (file)
@@ -30,9 +30,20 @@ use Wikimedia\Rdbms\FakeResultWrapper;
  */
 class AllMessagesTablePager extends TablePager {
 
-       protected $filter, $prefix, $langcode, $displayPrefix;
+       /**
+        * @var string
+        */
+       protected $langcode;
+
+       /**
+        * @var bool
+        */
+       protected $foreign;
 
-       public $mLimitsShown;
+       /**
+        * @var string
+        */
+       protected $prefix;
 
        /**
         * @var Language
@@ -44,41 +55,40 @@ class AllMessagesTablePager extends TablePager {
         */
        public $custom;
 
-       public function __construct( $page, $conds, Language $langObj = null ) {
-               parent::__construct( $page->getContext() );
+       /**
+        * @param IContextSource|null $context
+        * @param FormOptions $opts
+        */
+       public function __construct( IContextSource $context = null, FormOptions $opts ) {
+               parent::__construct( $context );
+
                $this->mIndexField = 'am_title';
-               $this->mPage = $page;
-               $this->mConds = $conds;
                // FIXME: Why does this need to be set to DIR_DESCENDING to produce ascending ordering?
                $this->mDefaultDirection = IndexPager::DIR_DESCENDING;
-               $this->mLimitsShown = [ 20, 50, 100, 250, 500, 5000 ];
-
-               $this->talk = $this->msg( 'talkpagelinktext' )->escaped();
 
+               $langObj = wfGetLangObj( $opts->getValue( 'lang' ) );
                $contLang = MediaWikiServices::getInstance()->getContentLanguage();
                $this->lang = $langObj ?? $contLang;
+
                $this->langcode = $this->lang->getCode();
                $this->foreign = !$this->lang->equals( $contLang );
 
-               $request = $this->getRequest();
-
-               $this->filter = $request->getVal( 'filter', 'all' );
-               if ( $this->filter === 'all' ) {
+               $filter = $opts->getValue( 'filter' );
+               if ( $filter === 'all' ) {
                        $this->custom = null; // So won't match in either case
                } else {
-                       $this->custom = ( $this->filter === 'unmodified' );
+                       $this->custom = ( $filter === 'unmodified' );
                }
 
-               $prefix = $this->getLanguage()->ucfirst( $request->getVal( 'prefix', '' ) );
+               $prefix = $this->getLanguage()->ucfirst( $opts->getValue( 'prefix' ) );
                $prefix = $prefix !== '' ?
-                       Title::makeTitleSafe( NS_MEDIAWIKI, $request->getVal( 'prefix', null ) ) :
+                       Title::makeTitleSafe( NS_MEDIAWIKI, $opts->getValue( 'prefix' ) ) :
                        null;
 
                if ( $prefix !== null ) {
-                       $this->displayPrefix = $prefix->getDBkey();
-                       $this->prefix = '/^' . preg_quote( $this->displayPrefix, '/' ) . '/i';
+                       $displayPrefix = $prefix->getDBkey();
+                       $this->prefix = '/^' . preg_quote( $displayPrefix, '/' ) . '/i';
                } else {
-                       $this->displayPrefix = false;
                        $this->prefix = false;
                }
 
@@ -91,84 +101,6 @@ class AllMessagesTablePager extends TablePager {
                }
        }
 
-       function buildForm() {
-               $attrs = [ 'id' => 'mw-allmessages-form-lang', 'name' => 'lang' ];
-               $msg = wfMessage( 'allmessages-language' );
-               $langSelect = Xml::languageSelector( $this->langcode, false, null, $attrs, $msg );
-
-               $out = Xml::openElement( 'form', [
-                               'method' => 'get',
-                               'action' => $this->getConfig()->get( 'Script' ),
-                               'id' => 'mw-allmessages-form'
-                       ] ) .
-                       Xml::fieldset( $this->msg( 'allmessages-filter-legend' )->text() ) .
-                       Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
-                       Xml::openElement( 'table', [ 'class' => 'mw-allmessages-table' ] ) . "\n" .
-                       '<tr>
-                               <td class="mw-label">' .
-                       Xml::label( $this->msg( 'allmessages-prefix' )->text(), 'mw-allmessages-form-prefix' ) .
-                       "</td>\n
-                       <td class=\"mw-input\">" .
-                       Xml::input(
-                               'prefix',
-                               20,
-                               str_replace( '_', ' ', $this->displayPrefix ),
-                               [ 'id' => 'mw-allmessages-form-prefix' ]
-                       ) .
-                       "</td>\n
-                       </tr>
-                       <tr>\n
-                       <td class='mw-label'>" .
-                       $this->msg( 'allmessages-filter' )->escaped() .
-                       "</td>\n
-                               <td class='mw-input'>" .
-                       Xml::radioLabel( $this->msg( 'allmessages-filter-unmodified' )->text(),
-                               'filter',
-                               'unmodified',
-                               'mw-allmessages-form-filter-unmodified',
-                               ( $this->filter === 'unmodified' )
-                       ) .
-                       Xml::radioLabel( $this->msg( 'allmessages-filter-all' )->text(),
-                               'filter',
-                               'all',
-                               'mw-allmessages-form-filter-all',
-                               ( $this->filter === 'all' )
-                       ) .
-                       Xml::radioLabel( $this->msg( 'allmessages-filter-modified' )->text(),
-                               'filter',
-                               'modified',
-                               'mw-allmessages-form-filter-modified',
-                               ( $this->filter === 'modified' )
-                       ) .
-                       "</td>\n
-                       </tr>
-                       <tr>\n
-                               <td class=\"mw-label\">" . $langSelect[0] . "</td>\n
-                               <td class=\"mw-input\">" . $langSelect[1] . "</td>\n
-                       </tr>" .
-
-                       '<tr>
-                               <td class="mw-label">' .
-                       Xml::label( $this->msg( 'table_pager_limit_label' )->text(), 'mw-table_pager_limit_label' ) .
-                       '</td>
-                       <td class="mw-input">' .
-                       $this->getLimitSelect( [ 'id' => 'mw-table_pager_limit_label' ] ) .
-                       '</td>
-                       <tr>
-                               <td></td>
-                               <td>' .
-                       Xml::submitButton( $this->msg( 'allmessages-filter-submit' )->text() ) .
-                       "</td>\n
-                       </tr>" .
-
-                       Xml::closeElement( 'table' ) .
-                       $this->getHiddenFields( [ 'title', 'prefix', 'filter', 'lang', 'limit' ] ) .
-                       Xml::closeElement( 'fieldset' ) .
-                       Xml::closeElement( 'form' );
-
-               return $out;
-       }
-
        function getAllMessages( $descending ) {
                $messageNames = Language::getLocalisationCache()->getSubitemList( 'en', 'messages' );
 
@@ -318,6 +250,7 @@ class AllMessagesTablePager extends TablePager {
                                        ] ),
                                        $this->msg( 'allmessages-filter-translate' )->text()
                                );
+                               $talkLink = $this->msg( 'talkpagelinktext' )->escaped();
 
                                if ( $this->mCurrentRow->am_customised ) {
                                        $title = $linkRenderer->makeKnownLink( $title, $this->getLanguage()->lcfirst( $value ) );
@@ -328,11 +261,11 @@ class AllMessagesTablePager extends TablePager {
                                        );
                                }
                                if ( $this->mCurrentRow->am_talk_exists ) {
-                                       $talk = $linkRenderer->makeKnownLink( $talk, $this->talk );
+                                       $talk = $linkRenderer->makeKnownLink( $talk, $talkLink );
                                } else {
                                        $talk = $linkRenderer->makeBrokenLink(
                                                $talk,
-                                               $this->talk
+                                               $talkLink
                                        );
                                }
 
index a9bba7a..5f38775 100644 (file)
@@ -4,7 +4,6 @@ use Wikimedia\Rdbms\IDatabase;
 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
 use MediaWiki\Linker\LinkTarget;
 use Wikimedia\Assert\Assert;
-use Wikimedia\Rdbms\LBFactory;
 use Wikimedia\ScopedCallback;
 use Wikimedia\Rdbms\ILBFactory;
 use Wikimedia\Rdbms\LoadBalancer;
index dba4a22..6a4cf04 100644 (file)
@@ -42,6 +42,8 @@ class MwSql extends Maintenance {
                $this->addOption( 'query',
                        'Run a single query instead of running interactively', false, true );
                $this->addOption( 'json', 'Output the results as JSON instead of PHP objects' );
+               $this->addOption( 'status', 'Return successful exit status only if the query succeeded '
+                       . '(selected or altered rows), otherwise 1 for errors, 2 for no rows' );
                $this->addOption( 'cluster', 'Use an external cluster by name', false, true );
                $this->addOption( 'wikidb',
                        'The database wiki ID to use if not the current one', false, true );
@@ -108,8 +110,11 @@ class MwSql extends Maintenance {
 
                if ( $this->hasOption( 'query' ) ) {
                        $query = $this->getOption( 'query' );
-                       $this->sqlDoQuery( $db, $query, /* dieOnError */ true );
+                       $res = $this->sqlDoQuery( $db, $query, /* dieOnError */ true );
                        wfWaitForSlaves();
+                       if ( $this->hasOption( 'status' ) ) {
+                               exit( $res ? 0 : 2 );
+                       }
                        return;
                }
 
@@ -128,6 +133,7 @@ class MwSql extends Maintenance {
                $newPrompt = '> ';
                $prompt = $newPrompt;
                $doDie = !Maintenance::posix_isatty( 0 );
+               $res = 1;
                while ( ( $line = Maintenance::readconsole( $prompt ) ) !== false ) {
                        if ( !$line ) {
                                # User simply pressed return key
@@ -148,17 +154,26 @@ class MwSql extends Maintenance {
                                readline_add_history( $wholeLine . ';' );
                                readline_write_history( $historyFile );
                        }
-                       $this->sqlDoQuery( $db, $wholeLine, $doDie );
+                       $res = $this->sqlDoQuery( $db, $wholeLine, $doDie );
                        $prompt = $newPrompt;
                        $wholeLine = '';
                }
                wfWaitForSlaves();
+               if ( $this->hasOption( 'status' ) ) {
+                       exit( $res ? 0 : 2 );
+               }
        }
 
+       /**
+        * @param IDatabase $db
+        * @param string $line The SQL text of the query
+        * @param bool $dieOnError
+        * @return int|null Number of rows selected or updated, or null if the query was unsuccessful.
+        */
        protected function sqlDoQuery( IDatabase $db, $line, $dieOnError ) {
                try {
                        $res = $db->query( $line );
-                       $this->sqlPrintResult( $res, $db );
+                       return $this->sqlPrintResult( $res, $db );
                } catch ( DBQueryError $e ) {
                        if ( $dieOnError ) {
                                $this->fatalError( $e );
@@ -166,17 +181,19 @@ class MwSql extends Maintenance {
                                $this->error( $e );
                        }
                }
+               return null;
        }
 
        /**
         * Print the results, callback for $db->sourceStream()
         * @param ResultWrapper|bool $res
         * @param IDatabase $db
+        * @return int|null Number of rows selected or updated, or null if the query was unsuccessful.
         */
        public function sqlPrintResult( $res, $db ) {
                if ( !$res ) {
                        // Do nothing
-                       return;
+                       return null;
                } elseif ( is_object( $res ) ) {
                        $out = '';
                        $rows = [];
@@ -190,6 +207,7 @@ class MwSql extends Maintenance {
                                $out = 'Query OK, 0 row(s) affected';
                        }
                        $this->output( $out . "\n" );
+                       return count( $rows );
                } else {
                        $affected = $db->affectedRows();
                        if ( $this->hasOption( 'json' ) ) {
@@ -197,6 +215,7 @@ class MwSql extends Maintenance {
                        } else {
                                $this->output( "Query OK, $affected row(s) affected\n" );
                        }
+                       return $affected;
                }
        }
 
index 255b878..89bbbc8 100644 (file)
@@ -67,7 +67,9 @@
                        // Bind functions so they're checked whenever stuff changes
                        blockTargetWidget.on( 'change', updateBlockOptions );
                        expiryWidget.on( 'change', updateBlockOptions );
-                       editingRestrictionWidget.on( 'change', updateBlockOptions );
+                       if ( editingRestrictionWidget ) {
+                               editingRestrictionWidget.on( 'change', updateBlockOptions );
+                       }
 
                        // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours)
                        updateBlockOptions();