]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/specials/SpecialBooksources.php
MediaWiki 1.15.0
[autoinstallsdev/mediawiki.git] / includes / specials / SpecialBooksources.php
1 <?php
2
3 /**
4  * Special page outputs information on sourcing a book with a particular ISBN
5  * The parser creates links to this page when dealing with ISBNs in wikitext
6  *
7  * @author Rob Church <robchur@gmail.com>
8  * @todo Validate ISBNs using the standard check-digit method
9  * @ingroup SpecialPages
10  */
11 class SpecialBookSources extends SpecialPage {
12
13         /**
14          * ISBN passed to the page, if any
15          */
16         private $isbn = '';
17
18         /**
19          * Constructor
20          */
21         public function __construct() {
22                 parent::__construct( 'Booksources' );
23         }
24
25         /**
26          * Show the special page
27          *
28          * @param $isbn ISBN passed as a subpage parameter
29          */
30         public function execute( $isbn ) {
31                 global $wgOut, $wgRequest;
32                 $this->setHeaders();
33                 $this->isbn = self::cleanIsbn( $isbn ? $isbn : $wgRequest->getText( 'isbn' ) );
34                 $wgOut->addWikiMsg( 'booksources-summary' );
35                 $wgOut->addHTML( $this->makeForm() );
36                 if( strlen( $this->isbn ) > 0 ) {
37                         if( !self::isValidISBN( $this->isbn ) ) {
38                                 $wgOut->wrapWikiMsg( '<div class="error">$1</div>', 'booksources-invalid-isbn' );
39                         }
40                         $this->showList();
41                 }
42         }
43
44         /**
45          * Returns whether a given ISBN (10 or 13) is valid.  True indicates validity.
46          * @param isbn ISBN passed for check
47          */
48         public static function isValidISBN( $isbn ) {
49                 $isbn = self::cleanIsbn( $isbn );
50                 $sum = 0;
51                 $check = -1;
52                 if( strlen( $isbn ) == 13 ) {
53                         for( $i = 0; $i < 12; $i++ ) {
54                                 if($i % 2 == 0) {
55                                         $sum += $isbn{$i};
56                                 } else {
57                                         $sum += 3 * $isbn{$i};
58                                 }
59                         }
60                 
61                         $check = (10 - ($sum % 10)) % 10;
62                         if ($check == $isbn{12}) {
63                                 return true;
64                         }
65                 } elseif( strlen( $isbn ) == 10 ) {
66                         for($i = 0; $i < 9; $i++) {
67                                 $sum += $isbn{$i} * ($i + 1);
68                         }
69                 
70                         $check = $sum % 11;
71                         if($check == 10) {
72                                 $check = "X";
73                         }
74                         if($check == $isbn{9}) {
75                                 return true;
76                         }
77                 }
78                 return false;
79         }
80
81
82         /**
83          * Trim ISBN and remove characters which aren't required
84          *
85          * @param $isbn Unclean ISBN
86          * @return string
87          */
88         private static function cleanIsbn( $isbn ) {
89                 return trim( preg_replace( '![^0-9X]!', '', $isbn ) );
90         }
91
92         /**
93          * Generate a form to allow users to enter an ISBN
94          *
95          * @return string
96          */
97         private function makeForm() {
98                 global $wgScript;
99                 $title = self::getTitleFor( 'Booksources' );
100                 $form  = '<fieldset><legend>' . wfMsgHtml( 'booksources-search-legend' ) . '</legend>';
101                 $form .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
102                 $form .= Xml::hidden( 'title', $title->getPrefixedText() );
103                 $form .= '<p>' . Xml::inputLabel( wfMsg( 'booksources-isbn' ), 'isbn', 'isbn', 20, $this->isbn );
104                 $form .= '&nbsp;' . Xml::submitButton( wfMsg( 'booksources-go' ) ) . '</p>';
105                 $form .= Xml::closeElement( 'form' );
106                 $form .= '</fieldset>';
107                 return $form;
108         }
109
110         /**
111          * Determine where to get the list of book sources from,
112          * format and output them
113          *
114          * @return string
115          */
116         private function showList() {
117                 global $wgOut, $wgContLang;
118
119                 # Hook to allow extensions to insert additional HTML,
120                 # e.g. for API-interacting plugins and so on
121                 wfRunHooks( 'BookInformation', array( $this->isbn, &$wgOut ) );
122
123                 # Check for a local page such as Project:Book_sources and use that if available
124                 $title = Title::makeTitleSafe( NS_PROJECT, wfMsgForContent( 'booksources' ) ); # Show list in content language
125                 if( is_object( $title ) && $title->exists() ) {
126                         $rev = Revision::newFromTitle( $title );
127                         $wgOut->addWikiText( str_replace( 'MAGICNUMBER', $this->isbn, $rev->getText() ) );
128                         return true;
129                 }
130
131                 # Fall back to the defaults given in the language file
132                 $wgOut->addWikiMsg( 'booksources-text' );
133                 $wgOut->addHTML( '<ul>' );
134                 $items = $wgContLang->getBookstoreList();
135                 foreach( $items as $label => $url )
136                         $wgOut->addHTML( $this->makeListItem( $label, $url ) );
137                 $wgOut->addHTML( '</ul>' );
138                 return true;
139         }
140
141         /**
142          * Format a book source list item
143          *
144          * @param $label Book source label
145          * @param $url Book source URL
146          * @return string
147          */
148         private function makeListItem( $label, $url ) {
149                 $url = str_replace( '$1', $this->isbn, $url );
150                 return '<li><a href="' . htmlspecialchars( $url ) . '">' . htmlspecialchars( $label ) . '</a></li>';
151         }
152 }