Allow extension of the Special:Upload form
authorMatthias Mullie <git@mullie.eu>
Mon, 18 Dec 2017 14:14:38 +0000 (15:14 +0100)
committerMatthias Mullie <git@mullie.eu>
Mon, 8 Jan 2018 12:39:03 +0000 (13:39 +0100)
* Some of the license selection code (License & Licenses)
  has seen some minor refactor to make it more open to
  reuse/extension elsewhere.
  Extension:3D will make use of these for patent selection in
  Iafb1e7e5da4b67f4c5ae7dda511d130ae10f748c
* License/TemplateSelectorLine has been modified so the text
  can be wikitext (as needed for patent labels)
* uploadLicense was renamed to uploadTemplatePreview and
  altered so it can be reused elsewhere. And, like
  window.wgUploadWarningObj, uploadTemplatePreview is now also
  added to `window` so it can be re-used from elsewhere (to
  preview patent templates)

Bug: T182683
Change-Id: I0c097442aa557dd90eb5825553ebf892f9af8a01

RELEASE-NOTES-1.31
docs/hooks.txt
includes/specials/SpecialUpload.php
includes/specials/formfields/Licenses.php
includes/specials/helpers/License.php
resources/src/mediawiki.special/mediawiki.special.upload.js

index 30a174a..2069e71 100644 (file)
@@ -37,6 +37,8 @@ production.
   users during an import.
 * Added a hook, ParserOutputPostCacheTransform, to allow extensions to affect
   the ParserOutput::getText() post-cache transformations.
+* Added a hook, UploadForm:getInitialPageText, to allow extensions to alter the
+  initial page text for file uploads.
 
 === External library changes in 1.31 ===
 
@@ -165,6 +167,7 @@ changes to languages because of Phabricator reports.
   has been deprecated since 1.27 and was removed as well.
 * The HtmlFormatter class was removed (deprecated in 1.27). The namespaced
   HtmlFormatter\HtmlFormatter class should be used instead.
+* License::getLicenses has been deprecated; use License::getLines instead.
 
 == Compatibility ==
 MediaWiki 1.31 requires PHP 5.5.9 or later. There is experimental support for
index 45387a3..7f1fe4b 100644 (file)
@@ -3521,6 +3521,12 @@ blank form with no error message; use UploadVerification and UploadVerifyFile
 instead.
 &$form: UploadForm object
 
+'UploadForm:getInitialPageText': After the initial page text for file uploads
+is generated, to allow it to be altered.
+&$pageText: the page text
+$msg: array of header messages
+$config: Config object
+
 'UploadForm:initial': Before the upload form is generated. You might set the
 member-variables $uploadFormTextTop and $uploadFormTextAfterSummary to inject
 text (HTML) either before or after the editform.
index 024034a..53b7a2f 100644 (file)
@@ -612,25 +612,23 @@ class SpecialUpload extends SpecialPage {
                        }
                }
 
+               $licenseText = '';
+               if ( $license !== '' ) {
+                       $licenseText = '== ' . $msg['license-header'] . " ==\n{{" . $license . "}}\n";
+               }
+
+               $pageText = $comment == '' ? '' : '== ' . $msg['filedesc'] . " ==\n" . $comment . "\n";
                if ( $config->get( 'UseCopyrightUpload' ) ) {
-                       $licensetxt = '';
-                       if ( $license != '' ) {
-                               $licensetxt = '== ' . $msg['license-header'] . " ==\n" . '{{' . $license . '}}' . "\n";
-                       }
-                       $pageText = '== ' . $msg['filedesc'] . " ==\n" . $comment . "\n" .
-                               '== ' . $msg['filestatus'] . " ==\n" . $copyStatus . "\n" .
-                               "$licensetxt" .
-                               '== ' . $msg['filesource'] . " ==\n" . $source;
+                       $pageText .= '== ' . $msg['filestatus'] . " ==\n" . $copyStatus . "\n";
+                       $pageText .= $licenseText;
+                       $pageText .= '== ' . $msg['filesource'] . " ==\n" . $source;
                } else {
-                       if ( $license != '' ) {
-                               $filedesc = $comment == '' ? '' : '== ' . $msg['filedesc'] . " ==\n" . $comment . "\n";
-                                       $pageText = $filedesc .
-                                       '== ' . $msg['license-header'] . " ==\n" . '{{' . $license . '}}' . "\n";
-                       } else {
-                               $pageText = $comment;
-                       }
+                       $pageText .= $licenseText;
                }
 
+               // allow extensions to modify the content
+               Hooks::run( 'UploadForm:getInitialPageText', [ &$pageText, $msg, $config ] );
+
                return $pageText;
        }
 
index f499cc1..c4dbf12 100644 (file)
@@ -32,10 +32,13 @@ class Licenses extends HTMLFormField {
        protected $msg;
 
        /** @var array */
-       protected $licenses = [];
+       protected $lines = [];
 
        /** @var string */
        protected $html;
+
+       /** @var string|null */
+       protected $selected;
        /**#@-*/
 
        /**
@@ -44,18 +47,34 @@ class Licenses extends HTMLFormField {
        public function __construct( $params ) {
                parent::__construct( $params );
 
-               $this->msg = empty( $params['licenses'] )
+               $this->msg = static::getMessageFromParams( $params );
+               $this->selected = null;
+
+               $this->makeLines();
+       }
+
+       /**
+        * @param array $params
+        * @return string
+        */
+       protected static function getMessageFromParams( $params ) {
+               return empty( $params['licenses'] )
                        ? wfMessage( 'licenses' )->inContentLanguage()->plain()
                        : $params['licenses'];
-               $this->selected = null;
+       }
 
-               $this->makeLicenses();
+       /**
+        * @param string $line
+        * @return License
+        */
+       protected function buildLine( $line ) {
+               return new License( $line );
        }
 
        /**
         * @private
         */
-       protected function makeLicenses() {
+       protected function makeLines() {
                $levels = [];
                $lines = explode( "\n", $this->msg );
 
@@ -66,8 +85,8 @@ class Licenses extends HTMLFormField {
                                list( $level, $line ) = $this->trimStars( $line );
 
                                if ( strpos( $line, '|' ) !== false ) {
-                                       $obj = new License( $line );
-                                       $this->stackItem( $this->licenses, $levels, $obj );
+                                       $obj = $this->buildLine( $line );
+                                       $this->stackItem( $this->lines, $levels, $obj );
                                } else {
                                        if ( $level < count( $levels ) ) {
                                                $levels = array_slice( $levels, 0, $level );
@@ -109,11 +128,14 @@ class Licenses extends HTMLFormField {
        /**
         * @param array $tagset
         * @param int $depth
+        * @return string
         */
        protected function makeHtml( $tagset, $depth = 0 ) {
+               $html = '';
+
                foreach ( $tagset as $key => $val ) {
                        if ( is_array( $val ) ) {
-                               $this->html .= $this->outputOption(
+                               $html .= $this->outputOption(
                                        $key, '',
                                        [
                                                'disabled' => 'disabled',
@@ -121,15 +143,17 @@ class Licenses extends HTMLFormField {
                                        ],
                                        $depth
                                );
-                               $this->makeHtml( $val, $depth + 1 );
+                               $html .= $this->makeHtml( $val, $depth + 1 );
                        } else {
-                               $this->html .= $this->outputOption(
+                               $html .= $this->outputOption(
                                        $val->text, $val->template,
                                        [ 'title' => '{{' . $val->template . '}}' ],
                                        $depth
                                );
                        }
                }
+
+               return $html;
        }
 
        /**
@@ -154,36 +178,50 @@ class Licenses extends HTMLFormField {
        /**#@-*/
 
        /**
-        *  Accessor for $this->licenses
+        * Accessor for $this->lines
         *
         * @return array
         */
-       public function getLicenses() {
-               return $this->licenses;
+       public function getLines() {
+               return $this->lines;
        }
 
        /**
-        * Accessor for $this->html
+        * Accessor for $this->lines
         *
-        * @param bool $value
+        * @return array
         *
-        * @return string
+        * @deprecated since 1.31 Use getLines() instead
+        */
+       public function getLicenses() {
+               return $this->getLines();
+       }
+
+       /**
+        * {@inheritdoc}
         */
        public function getInputHTML( $value ) {
                $this->selected = $value;
 
-               $this->html = $this->outputOption( wfMessage( 'nolicense' )->text(), '',
-                       (bool)$this->selected ? null : [ 'selected' => 'selected' ] );
-               $this->makeHtml( $this->getLicenses() );
+               // add a default "no license selected" option
+               $default = $this->buildLine( '|nolicense' );
+               array_unshift( $this->lines, $default );
+
+               $html = $this->makeHtml( $this->getLines() );
 
                $attribs = [
                        'name' => $this->mName,
                        'id' => $this->mID
                ];
                if ( !empty( $this->mParams['disabled'] ) ) {
-                       $attibs['disabled'] = 'disabled';
+                       $attribs['disabled'] = 'disabled';
                }
 
-               return Html::rawElement( 'select', $attribs, $this->html );
+               $html = Html::rawElement( 'select', $attribs, $html );
+
+               // remove default "no license selected" from lines again
+               array_shift( $this->lines );
+
+               return $html;
        }
 }
index 4f94b4d..940f69c 100644 (file)
@@ -35,12 +35,27 @@ class License {
        public $text;
 
        /**
-        * @param string $str License name??
+        * @param string $str
         */
-       function __construct( $str ) {
-               list( $text, $template ) = explode( '|', strrev( $str ), 2 );
+       public function __construct( $str ) {
+               $str = $this->parse( $str );
+               list( $this->template, $this->text ) = $this->split( $str );
+       }
 
-               $this->template = strrev( $template );
-               $this->text = strrev( $text );
+       /**
+        * @param string $str
+        * @return string
+        */
+       protected function parse( $str ) {
+               return $str;
+       }
+
+       /**
+        * @param string $str
+        * @return string[] Array with [template, text]
+        */
+       protected function split( $str ) {
+               list( $text, $template ) = explode( '|', strrev( $str ), 2 );
+               return [ strrev( $template ), strrev( $text ) ];
        }
 }
index aa00359..ec51975 100644 (file)
@@ -10,7 +10,7 @@
 /* global Uint8Array */
 
 ( function ( mw, $ ) {
-       var uploadWarning, uploadLicense,
+       var uploadWarning, uploadTemplatePreview,
                ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
                $license = $( '#wpLicense' );
 
                }
        };
 
-       uploadLicense = {
+       window.wgUploadTemplatePreviewObj = uploadTemplatePreview = {
 
                responseCache: { '': '' },
 
-               fetchPreview: function ( license ) {
-                       var $spinnerLicense;
-                       if ( !mw.config.get( 'wgAjaxLicensePreview' ) ) {
-                               return;
-                       }
-                       if ( this.responseCache.hasOwnProperty( license ) ) {
-                               this.showPreview( this.responseCache[ license ] );
+               /**
+                * @param {jQuery} $element The element whose .val() will be previewed
+                * @param {jQuery} $previewContainer The container to display the preview in
+                */
+               getPreview: function ( $element, $previewContainer ) {
+                       var template = $element.val(),
+                               $spinner;
+
+                       if ( this.responseCache.hasOwnProperty( template ) ) {
+                               this.showPreview( this.responseCache[ template ], $previewContainer );
                                return;
                        }
 
-                       $spinnerLicense = $.createSpinner().insertAfter( '#wpLicense' );
+                       $spinner = $.createSpinner().insertAfter( $element );
 
                        ( new mw.Api() ).get( {
                                formatversion: 2,
                                action: 'parse',
-                               text: '{{' + license + '}}',
+                               text: '{{' + template + '}}',
                                title: $( '#wpDestFile' ).val() || 'File:Sample.jpg',
                                prop: 'text',
                                pst: true
                        } ).done( function ( result ) {
-                               uploadLicense.processResult( result, license );
+                               uploadTemplatePreview.processResult( result, template, $previewContainer );
                        } ).always( function () {
-                               $spinnerLicense.remove();
+                               $spinner.remove();
                        } );
                },
 
-               processResult: function ( result, license ) {
-                       this.responseCache[ license ] = result.parse.text;
-                       this.showPreview( this.responseCache[ license ] );
+               processResult: function ( result, template, $previewContainer ) {
+                       this.responseCache[ template ] = result.parse.text;
+                       this.showPreview( this.responseCache[ template ], $previewContainer );
                },
 
-               showPreview: function ( preview ) {
-                       $( '#mw-license-preview' ).html( preview );
+               showPreview: function ( preview, $previewContainer ) {
+                       $previewContainer.html( preview );
                }
 
        };
                        // License selector check
                        $license.change( function () {
                                // We might show a preview
-                               uploadLicense.fetchPreview( $license.val() );
+                               uploadTemplatePreview.getPreview( $license, $( '#mw-license-preview' ) );
                        } );
 
                        // License selector table row