MediaWiki REL1_40
SpecialBookSources.php
Go to the documentation of this file.
1<?php
28
37
39 private $revisionLookup;
40
44 public function __construct(
45 RevisionLookup $revisionLookup
46 ) {
47 parent::__construct( 'Booksources' );
48 $this->revisionLookup = $revisionLookup;
49 }
50
54 public function execute( $isbn ) {
55 $out = $this->getOutput();
56
57 $this->setHeaders();
58 $this->outputHeader();
59
60 // User provided ISBN
61 $isbn = $isbn ?: $this->getRequest()->getText( 'isbn' );
62 $isbn = trim( $isbn );
63
64 $this->buildForm( $isbn );
65
66 if ( $isbn !== '' ) {
67 if ( !self::isValidISBN( $isbn ) ) {
68 $out->wrapWikiMsg(
69 "<div class=\"error\">\n$1\n</div>",
70 'booksources-invalid-isbn'
71 );
72 }
73
74 $this->showList( $isbn );
75 }
76 }
77
84 public static function isValidISBN( $isbn ) {
85 $isbn = self::cleanIsbn( $isbn );
86 $sum = 0;
87 if ( strlen( $isbn ) == 13 ) {
88 for ( $i = 0; $i < 12; $i++ ) {
89 if ( $isbn[$i] === 'X' ) {
90 return false;
91 } elseif ( $i % 2 == 0 ) {
92 $sum += (int)$isbn[$i];
93 } else {
94 $sum += 3 * (int)$isbn[$i];
95 }
96 }
97
98 $check = ( 10 - ( $sum % 10 ) ) % 10;
99 if ( (string)$check === $isbn[12] ) {
100 return true;
101 }
102 } elseif ( strlen( $isbn ) == 10 ) {
103 for ( $i = 0; $i < 9; $i++ ) {
104 if ( $isbn[$i] === 'X' ) {
105 return false;
106 }
107 $sum += (int)$isbn[$i] * ( $i + 1 );
108 }
109
110 $check = $sum % 11;
111 if ( $check == 10 ) {
112 $check = "X";
113 }
114 if ( (string)$check === $isbn[9] ) {
115 return true;
116 }
117 }
118
119 return false;
120 }
121
128 private static function cleanIsbn( $isbn ) {
129 return trim( preg_replace( '![^0-9X]!', '', $isbn ) );
130 }
131
137 private function buildForm( $isbn ) {
138 $formDescriptor = [
139 'isbn' => [
140 'type' => 'text',
141 'name' => 'isbn',
142 'label-message' => 'booksources-isbn',
143 'default' => $isbn,
144 'autofocus' => true,
145 'required' => true,
146 ],
147 ];
148
149 HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
150 ->setTitle( $this->getPageTitle() )
151 ->setWrapperLegendMsg( 'booksources-search-legend' )
152 ->setSubmitTextMsg( 'booksources-search' )
153 ->setMethod( 'get' )
154 ->prepareForm()
155 ->displayForm( false );
156 }
157
165 private function showList( $isbn ) {
166 $out = $this->getOutput();
167
168 $isbn = self::cleanIsbn( $isbn );
169 # Hook to allow extensions to insert additional HTML,
170 # e.g. for API-interacting plugins and so on
171 $this->getHookRunner()->onBookInformation( $isbn, $out );
172
173 # Check for a local page such as Project:Book_sources and use that if available
174 $page = $this->msg( 'booksources' )->inContentLanguage()->text();
175 $title = Title::makeTitleSafe( NS_PROJECT, $page ); # Show list in content language
176 if ( is_object( $title ) && $title->exists() ) {
177 $rev = $this->revisionLookup->getRevisionByTitle( $title );
178 $content = $rev->getContent( SlotRecord::MAIN );
179
180 if ( $content instanceof TextContent ) {
181 // XXX: in the future, this could be stored as structured data, defining a list of book sources
182
183 $text = $content->getText();
184 $out->addWikiTextAsInterface( str_replace( 'MAGICNUMBER', $isbn, $text ) );
185
186 return true;
187 } else {
188 throw new UnexpectedValueException(
189 "Unexpected content type for book sources: " . $content->getModel()
190 );
191 }
192 }
193
194 # Fall back to the defaults given in the language file
195 $out->addWikiMsg( 'booksources-text' );
196 $out->addHTML( '<ul>' );
197 $items = $this->getContentLanguage()->getBookstoreList();
198 foreach ( $items as $label => $url ) {
199 $out->addHTML( $this->makeListItem( $isbn, $label, $url ) );
200 }
201 $out->addHTML( '</ul>' );
202
203 return true;
204 }
205
214 private function makeListItem( $isbn, $label, $url ) {
215 $url = str_replace( '$1', $isbn, $url );
216
217 return Html::rawElement( 'li', [],
218 Html::element( 'a', [ 'href' => $url, 'class' => 'external' ], $label )
219 );
220 }
221
222 protected function getGroupName() {
223 return 'wiki';
224 }
225}
const NS_PROJECT
Definition Defines.php:68
static factory( $displayFormat, $descriptor, IContextSource $context, $messagePrefix='')
Construct a HTMLForm object for given display type.
Definition HTMLForm.php:352
This class is a collection of static functions that serve two purposes:
Definition Html.php:55
Value object representing a content slot associated with a page revision.
Represents a title within MediaWiki.
Definition Title.php:82
Special page outputs information on sourcing a book with a particular ISBN The parser creates links t...
static isValidISBN( $isbn)
Return whether a given ISBN (10 or 13) is valid.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
__construct(RevisionLookup $revisionLookup)
Parent class for all special pages.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getRequest()
Get the WebRequest being used for this instance.
getPageTitle( $subpage=false)
Get a self-referential title object.
getContentLanguage()
Shortcut to get content language.
Content object implementation for representing flat text.
Service for looking up page revisions.
$content
Definition router.php:76