From ddfb4817b59ec10fa928c4059066f2ef39110ad5 Mon Sep 17 00:00:00 2001 From: Matthias Mullie Date: Mon, 18 Dec 2017 15:14:38 +0100 Subject: [PATCH] Allow extension of the Special:Upload form * 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 | 3 + docs/hooks.txt | 6 ++ includes/specials/SpecialUpload.php | 28 +++---- includes/specials/formfields/Licenses.php | 80 ++++++++++++++----- includes/specials/helpers/License.php | 25 ++++-- .../mediawiki.special.upload.js | 41 +++++----- 6 files changed, 123 insertions(+), 60 deletions(-) diff --git a/RELEASE-NOTES-1.31 b/RELEASE-NOTES-1.31 index 30a174a8f8..2069e71efe 100644 --- a/RELEASE-NOTES-1.31 +++ b/RELEASE-NOTES-1.31 @@ -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 diff --git a/docs/hooks.txt b/docs/hooks.txt index 45387a386f..7f1fe4bbce 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -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. diff --git a/includes/specials/SpecialUpload.php b/includes/specials/SpecialUpload.php index 024034a628..53b7a2ff3b 100644 --- a/includes/specials/SpecialUpload.php +++ b/includes/specials/SpecialUpload.php @@ -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; } diff --git a/includes/specials/formfields/Licenses.php b/includes/specials/formfields/Licenses.php index f499cc161b..c4dbf1269f 100644 --- a/includes/specials/formfields/Licenses.php +++ b/includes/specials/formfields/Licenses.php @@ -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; } } diff --git a/includes/specials/helpers/License.php b/includes/specials/helpers/License.php index 4f94b4d232..940f69c765 100644 --- a/includes/specials/helpers/License.php +++ b/includes/specials/helpers/License.php @@ -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 ) ]; } } diff --git a/resources/src/mediawiki.special/mediawiki.special.upload.js b/resources/src/mediawiki.special/mediawiki.special.upload.js index aa003591f3..ec51975d76 100644 --- a/resources/src/mediawiki.special/mediawiki.special.upload.js +++ b/resources/src/mediawiki.special/mediawiki.special.upload.js @@ -10,7 +10,7 @@ /* global Uint8Array */ ( function ( mw, $ ) { - var uploadWarning, uploadLicense, + var uploadWarning, uploadTemplatePreview, ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ), $license = $( '#wpLicense' ); @@ -113,43 +113,46 @@ } }; - 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 ); } }; @@ -177,7 +180,7 @@ // 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 -- 2.20.1