MediaWiki REL1_39
SpecialBookSources.php
Go to the documentation of this file.
1<?php
26
35
37 private $revisionLookup;
38
42 public function __construct(
43 RevisionLookup $revisionLookup
44 ) {
45 parent::__construct( 'Booksources' );
46 $this->revisionLookup = $revisionLookup;
47 }
48
52 public function execute( $isbn ) {
53 $out = $this->getOutput();
54
55 $this->setHeaders();
56 $this->outputHeader();
57
58 // User provided ISBN
59 $isbn = $isbn ?: $this->getRequest()->getText( 'isbn' );
60 $isbn = trim( $isbn );
61
62 $this->buildForm( $isbn );
63
64 if ( $isbn !== '' ) {
65 if ( !self::isValidISBN( $isbn ) ) {
66 $out->wrapWikiMsg(
67 "<div class=\"error\">\n$1\n</div>",
68 'booksources-invalid-isbn'
69 );
70 }
71
72 $this->showList( $isbn );
73 }
74 }
75
82 public static function isValidISBN( $isbn ) {
83 $isbn = self::cleanIsbn( $isbn );
84 $sum = 0;
85 if ( strlen( $isbn ) == 13 ) {
86 for ( $i = 0; $i < 12; $i++ ) {
87 if ( $isbn[$i] === 'X' ) {
88 return false;
89 } elseif ( $i % 2 == 0 ) {
90 $sum += (int)$isbn[$i];
91 } else {
92 $sum += 3 * (int)$isbn[$i];
93 }
94 }
95
96 $check = ( 10 - ( $sum % 10 ) ) % 10;
97 if ( (string)$check === $isbn[12] ) {
98 return true;
99 }
100 } elseif ( strlen( $isbn ) == 10 ) {
101 for ( $i = 0; $i < 9; $i++ ) {
102 if ( $isbn[$i] === 'X' ) {
103 return false;
104 }
105 $sum += (int)$isbn[$i] * ( $i + 1 );
106 }
107
108 $check = $sum % 11;
109 if ( $check == 10 ) {
110 $check = "X";
111 }
112 if ( (string)$check === $isbn[9] ) {
113 return true;
114 }
115 }
116
117 return false;
118 }
119
126 private static function cleanIsbn( $isbn ) {
127 return trim( preg_replace( '![^0-9X]!', '', $isbn ) );
128 }
129
135 private function buildForm( $isbn ) {
136 $formDescriptor = [
137 'isbn' => [
138 'type' => 'text',
139 'name' => 'isbn',
140 'label-message' => 'booksources-isbn',
141 'default' => $isbn,
142 'autofocus' => true,
143 'required' => true,
144 ],
145 ];
146
147 HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
148 ->setTitle( $this->getPageTitle() )
149 ->setWrapperLegendMsg( 'booksources-search-legend' )
150 ->setSubmitTextMsg( 'booksources-search' )
151 ->setMethod( 'get' )
152 ->prepareForm()
153 ->displayForm( false );
154 }
155
164 private function showList( $isbn ) {
165 $out = $this->getOutput();
166
167 $isbn = self::cleanIsbn( $isbn );
168 # Hook to allow extensions to insert additional HTML,
169 # e.g. for API-interacting plugins and so on
170 $this->getHookRunner()->onBookInformation( $isbn, $out );
171
172 # Check for a local page such as Project:Book_sources and use that if available
173 $page = $this->msg( 'booksources' )->inContentLanguage()->text();
174 $title = Title::makeTitleSafe( NS_PROJECT, $page ); # Show list in content language
175 if ( is_object( $title ) && $title->exists() ) {
176 $rev = $this->revisionLookup->getRevisionByTitle( $title );
177 $content = $rev->getContent( SlotRecord::MAIN );
178
179 if ( $content instanceof TextContent ) {
180 // XXX: in the future, this could be stored as structured data, defining a list of book sources
181
182 $text = $content->getText();
183 $out->addWikiTextAsInterface( str_replace( 'MAGICNUMBER', $isbn, $text ) );
184
185 return true;
186 } else {
187 throw new MWException( "Unexpected content type for book sources: " . $content->getModel() );
188 }
189 }
190
191 # Fall back to the defaults given in the language file
192 $out->addWikiMsg( 'booksources-text' );
193 $out->addHTML( '<ul>' );
194 $items = $this->getContentLanguage()->getBookstoreList();
195 foreach ( $items as $label => $url ) {
196 $out->addHTML( $this->makeListItem( $isbn, $label, $url ) );
197 }
198 $out->addHTML( '</ul>' );
199
200 return true;
201 }
202
211 private function makeListItem( $isbn, $label, $url ) {
212 $url = str_replace( '$1', $isbn, $url );
213
214 return Html::rawElement( 'li', [],
215 Html::element( 'a', [ 'href' => $url, 'class' => 'external' ], $label )
216 );
217 }
218
219 protected function getGroupName() {
220 return 'wiki';
221 }
222}
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:348
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition Html.php:214
MediaWiki exception.
Value object representing a content slot associated with a page revision.
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.
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition Title.php:664
Service for looking up page revisions.
$content
Definition router.php:76