]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - includes/specials/SpecialBooksources.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / specials / SpecialBooksources.php
index 67fb54048e3bab600ac2b95eb81ea639516ca47a..72e0b888feb151a2e84249cbe65a53f3baf9139e 100644 (file)
  * The parser creates links to this page when dealing with ISBNs in wikitext
  *
  * @author Rob Church <robchur@gmail.com>
- * @todo Validate ISBNs using the standard check-digit method
  * @ingroup SpecialPage
  */
 class SpecialBookSources extends SpecialPage {
-
-       /**
-        * ISBN passed to the page, if any
-        */
-       private $isbn = '';
-
-       /**
-        * Constructor
-        */
        public function __construct() {
                parent::__construct( 'Booksources' );
        }
@@ -46,62 +36,80 @@ class SpecialBookSources extends SpecialPage {
        /**
         * Show the special page
         *
-        * @param $isbn ISBN passed as a subpage parameter
+        * @param string $isbn ISBN passed as a subpage parameter
         */
        public function execute( $isbn ) {
-               global $wgOut, $wgRequest;
+               $out = $this->getOutput();
+
                $this->setHeaders();
-               $this->isbn = self::cleanIsbn( $isbn ? $isbn : $wgRequest->getText( 'isbn' ) );
-               $wgOut->addWikiMsg( 'booksources-summary' );
-               $wgOut->addHTML( $this->makeForm() );
-               if( strlen( $this->isbn ) > 0 ) {
-                       if( !self::isValidISBN( $this->isbn ) ) {
-                               $wgOut->wrapWikiMsg( "<div class=\"error\">\n$1\n</div>", 'booksources-invalid-isbn' );
+               $this->outputHeader();
+
+               // User provided ISBN
+               $isbn = $isbn ?: $this->getRequest()->getText( 'isbn' );
+               $isbn = trim( $isbn );
+
+               $this->buildForm( $isbn );
+
+               if ( $isbn !== '' ) {
+                       if ( !self::isValidISBN( $isbn ) ) {
+                               $out->wrapWikiMsg(
+                                       "<div class=\"error\">\n$1\n</div>",
+                                       'booksources-invalid-isbn'
+                               );
                        }
-                       $this->showList();
+
+                       $this->showList( $isbn );
                }
        }
 
        /**
-        * Returns whether a given ISBN (10 or 13) is valid.  True indicates validity.
-        * @param isbn ISBN passed for check
+        * Return whether a given ISBN (10 or 13) is valid.
+        *
+        * @param string $isbn ISBN passed for check
+        * @return bool
         */
        public static function isValidISBN( $isbn ) {
                $isbn = self::cleanIsbn( $isbn );
                $sum = 0;
-               if( strlen( $isbn ) == 13 ) {
-                       for( $i = 0; $i < 12; $i++ ) {
-                               if($i % 2 == 0) {
-                                       $sum += $isbn{$i};
+               if ( strlen( $isbn ) == 13 ) {
+                       for ( $i = 0; $i < 12; $i++ ) {
+                               if ( $isbn[$i] === 'X' ) {
+                                       return false;
+                               } elseif ( $i % 2 == 0 ) {
+                                       $sum += $isbn[$i];
                                } else {
-                                       $sum += 3 * $isbn{$i};
+                                       $sum += 3 * $isbn[$i];
                                }
                        }
-               
-                       $check = (10 - ($sum % 10)) % 10;
-                       if ($check == $isbn{12}) {
+
+                       $check = ( 10 - ( $sum % 10 ) ) % 10;
+                       if ( (string)$check === $isbn[12] ) {
                                return true;
                        }
-               } elseif( strlen( $isbn ) == 10 ) {
-                       for($i = 0; $i < 9; $i++) {
-                               $sum += $isbn{$i} * ($i + 1);
+               } elseif ( strlen( $isbn ) == 10 ) {
+                       for ( $i = 0; $i < 9; $i++ ) {
+                               if ( $isbn[$i] === 'X' ) {
+                                       return false;
+                               }
+                               $sum += $isbn[$i] * ( $i + 1 );
                        }
-               
+
                        $check = $sum % 11;
-                       if($check == 10) {
+                       if ( $check == 10 ) {
                                $check = "X";
                        }
-                       if($check == $isbn{9}) {
+                       if ( (string)$check === $isbn[9] ) {
                                return true;
                        }
                }
+
                return false;
        }
 
        /**
         * Trim ISBN and remove characters which aren't required
         *
-        * @param $isbn Unclean ISBN
+        * @param string $isbn Unclean ISBN
         * @return string
         */
        private static function cleanIsbn( $isbn ) {
@@ -111,61 +119,96 @@ class SpecialBookSources extends SpecialPage {
        /**
         * Generate a form to allow users to enter an ISBN
         *
-        * @return string
+        * @param string $isbn
         */
-       private function makeForm() {
-               global $wgScript;
-               $title = self::getTitleFor( 'Booksources' );
-               $form  = '<fieldset><legend>' . wfMsgHtml( 'booksources-search-legend' ) . '</legend>';
-               $form .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
-               $form .= Html::hidden( 'title', $title->getPrefixedText() );
-               $form .= '<p>' . Xml::inputLabel( wfMsg( 'booksources-isbn' ), 'isbn', 'isbn', 20, $this->isbn );
-               $form .= '&#160;' . Xml::submitButton( wfMsg( 'booksources-go' ) ) . '</p>';
-               $form .= Xml::closeElement( 'form' );
-               $form .= '</fieldset>';
-               return $form;
+       private function buildForm( $isbn ) {
+               $formDescriptor = [
+                       'isbn' => [
+                               'type' => 'text',
+                               'name' => 'isbn',
+                               'label-message' => 'booksources-isbn',
+                               'default' => $isbn,
+                               'autofocus' => true,
+                               'required' => true,
+                       ],
+               ];
+
+               $context = new DerivativeContext( $this->getContext() );
+               $context->setTitle( $this->getPageTitle() );
+               HTMLForm::factory( 'ooui', $formDescriptor, $context )
+                       ->setWrapperLegendMsg( 'booksources-search-legend' )
+                       ->setSubmitTextMsg( 'booksources-search' )
+                       ->setMethod( 'get' )
+                       ->prepareForm()
+                       ->displayForm( false );
        }
 
        /**
         * Determine where to get the list of book sources from,
         * format and output them
         *
-        * @return string
+        * @param string $isbn
+        * @throws MWException
+        * @return bool
         */
-       private function showList() {
-               global $wgOut, $wgContLang;
+       private function showList( $isbn ) {
+               $out = $this->getOutput();
+
+               global $wgContLang;
 
+               $isbn = self::cleanIsbn( $isbn );
                # Hook to allow extensions to insert additional HTML,
                # e.g. for API-interacting plugins and so on
-               wfRunHooks( 'BookInformation', array( $this->isbn, &$wgOut ) );
+               Hooks::run( 'BookInformation', [ $isbn, $out ] );
 
                # Check for a local page such as Project:Book_sources and use that if available
-               $title = Title::makeTitleSafe( NS_PROJECT, wfMsgForContent( 'booksources' ) ); # Show list in content language
-               if( is_object( $title ) && $title->exists() ) {
-                       $rev = Revision::newFromTitle( $title );
-                       $wgOut->addWikiText( str_replace( 'MAGICNUMBER', $this->isbn, $rev->getText() ) );
-                       return true;
+               $page = $this->msg( 'booksources' )->inContentLanguage()->text();
+               $title = Title::makeTitleSafe( NS_PROJECT, $page ); # Show list in content language
+               if ( is_object( $title ) && $title->exists() ) {
+                       $rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
+                       $content = $rev->getContent();
+
+                       if ( $content instanceof TextContent ) {
+                               // XXX: in the future, this could be stored as structured data, defining a list of book sources
+
+                               $text = $content->getNativeData();
+                               $out->addWikiText( str_replace( 'MAGICNUMBER', $isbn, $text ) );
+
+                               return true;
+                       } else {
+                               throw new MWException( "Unexpected content type for book sources: " . $content->getModel() );
+                       }
                }
 
                # Fall back to the defaults given in the language file
-               $wgOut->addWikiMsg( 'booksources-text' );
-               $wgOut->addHTML( '<ul>' );
+               $out->addWikiMsg( 'booksources-text' );
+               $out->addHTML( '<ul>' );
                $items = $wgContLang->getBookstoreList();
-               foreach( $items as $label => $url )
-                       $wgOut->addHTML( $this->makeListItem( $label, $url ) );
-               $wgOut->addHTML( '</ul>' );
+               foreach ( $items as $label => $url ) {
+                       $out->addHTML( $this->makeListItem( $isbn, $label, $url ) );
+               }
+               $out->addHTML( '</ul>' );
+
                return true;
        }
 
        /**
         * Format a book source list item
         *
-        * @param $label Book source label
-        * @param $url Book source URL
+        * @param string $isbn
+        * @param string $label Book source label
+        * @param string $url Book source URL
         * @return string
         */
-       private function makeListItem( $label, $url ) {
-               $url = str_replace( '$1', $this->isbn, $url );
-               return '<li><a href="' . htmlspecialchars( $url ) . '" class="external">' . htmlspecialchars( $label ) . '</a></li>';
+       private function makeListItem( $isbn, $label, $url ) {
+               $url = str_replace( '$1', $isbn, $url );
+
+               return Html::rawElement( 'li', [],
+                       Html::element( 'a', [ 'href' => $url, 'class' => 'external' ], $label )
+               );
+       }
+
+       protected function getGroupName() {
+               return 'wiki';
        }
 }