MediaWiki  master
SpecialBookSources.php
Go to the documentation of this file.
1 <?php
25 
34  public function __construct() {
35  parent::__construct( 'Booksources' );
36  }
37 
41  public function execute( $isbn ) {
42  $out = $this->getOutput();
43 
44  $this->setHeaders();
45  $this->outputHeader();
46 
47  // User provided ISBN
48  $isbn = $isbn ?: $this->getRequest()->getText( 'isbn' );
49  $isbn = trim( $isbn );
50 
51  $this->buildForm( $isbn );
52 
53  if ( $isbn !== '' ) {
54  if ( !self::isValidISBN( $isbn ) ) {
55  $out->wrapWikiMsg(
56  "<div class=\"error\">\n$1\n</div>",
57  'booksources-invalid-isbn'
58  );
59  }
60 
61  $this->showList( $isbn );
62  }
63  }
64 
71  public static function isValidISBN( $isbn ) {
72  $isbn = self::cleanIsbn( $isbn );
73  $sum = 0;
74  if ( strlen( $isbn ) == 13 ) {
75  for ( $i = 0; $i < 12; $i++ ) {
76  if ( $isbn[$i] === 'X' ) {
77  return false;
78  } elseif ( $i % 2 == 0 ) {
79  $sum += $isbn[$i];
80  } else {
81  $sum += 3 * $isbn[$i];
82  }
83  }
84 
85  $check = ( 10 - ( $sum % 10 ) ) % 10;
86  if ( (string)$check === $isbn[12] ) {
87  return true;
88  }
89  } elseif ( strlen( $isbn ) == 10 ) {
90  for ( $i = 0; $i < 9; $i++ ) {
91  if ( $isbn[$i] === 'X' ) {
92  return false;
93  }
94  $sum += $isbn[$i] * ( $i + 1 );
95  }
96 
97  $check = $sum % 11;
98  if ( $check == 10 ) {
99  $check = "X";
100  }
101  if ( (string)$check === $isbn[9] ) {
102  return true;
103  }
104  }
105 
106  return false;
107  }
108 
115  private static function cleanIsbn( $isbn ) {
116  return trim( preg_replace( '![^0-9X]!', '', $isbn ) );
117  }
118 
124  private function buildForm( $isbn ) {
125  $formDescriptor = [
126  'isbn' => [
127  'type' => 'text',
128  'name' => 'isbn',
129  'label-message' => 'booksources-isbn',
130  'default' => $isbn,
131  'autofocus' => true,
132  'required' => true,
133  ],
134  ];
135 
136  $context = new DerivativeContext( $this->getContext() );
137  $context->setTitle( $this->getPageTitle() );
138  HTMLForm::factory( 'ooui', $formDescriptor, $context )
139  ->setWrapperLegendMsg( 'booksources-search-legend' )
140  ->setSubmitTextMsg( 'booksources-search' )
141  ->setMethod( 'get' )
142  ->prepareForm()
143  ->displayForm( false );
144  }
145 
154  private function showList( $isbn ) {
155  $out = $this->getOutput();
156 
157  $isbn = self::cleanIsbn( $isbn );
158  # Hook to allow extensions to insert additional HTML,
159  # e.g. for API-interacting plugins and so on
160  Hooks::run( 'BookInformation', [ $isbn, $out ] );
161 
162  # Check for a local page such as Project:Book_sources and use that if available
163  $page = $this->msg( 'booksources' )->inContentLanguage()->text();
164  $title = Title::makeTitleSafe( NS_PROJECT, $page ); # Show list in content language
165  if ( is_object( $title ) && $title->exists() ) {
166  $rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
167  $content = $rev->getContent();
168 
169  if ( $content instanceof TextContent ) {
170  // XXX: in the future, this could be stored as structured data, defining a list of book sources
171 
172  $text = $content->getText();
173  $out->addWikiTextAsInterface( str_replace( 'MAGICNUMBER', $isbn, $text ) );
174 
175  return true;
176  } else {
177  throw new MWException( "Unexpected content type for book sources: " . $content->getModel() );
178  }
179  }
180 
181  # Fall back to the defaults given in the language file
182  $out->addWikiMsg( 'booksources-text' );
183  $out->addHTML( '<ul>' );
184  $items = MediaWikiServices::getInstance()->getContentLanguage()->getBookstoreList();
185  foreach ( $items as $label => $url ) {
186  $out->addHTML( $this->makeListItem( $isbn, $label, $url ) );
187  }
188  $out->addHTML( '</ul>' );
189 
190  return true;
191  }
192 
201  private function makeListItem( $isbn, $label, $url ) {
202  $url = str_replace( '$1', $isbn, $url );
203 
204  return Html::rawElement( 'li', [],
205  Html::element( 'a', [ 'href' => $url, 'class' => 'external' ], $label )
206  );
207  }
208 
209  protected function getGroupName() {
210  return 'wiki';
211  }
212 }
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
$context
Definition: load.php:45
getContext()
Gets the context this SpecialPage is executed in.
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
An IContextSource implementation which will inherit context from another source but allow individual ...
getOutput()
Get the OutputPage being used for this instance.
static newFromTitle(LinkTarget $linkTarget, $id=0, $flags=0)
Load either the current, or a specified, revision that&#39;s attached to a given link target...
Definition: Revision.php:138
static isValidISBN( $isbn)
Return whether a given ISBN (10 or 13) is valid.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
static factory( $displayFormat,... $arguments)
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:307
const NS_PROJECT
Definition: Defines.php:64
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes! ...
buildForm( $isbn)
Generate a form to allow users to enter an ISBN.
showList( $isbn)
Determine where to get the list of book sources from, format and output them.
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:612
static cleanIsbn( $isbn)
Trim ISBN and remove characters which aren&#39;t required.
$content
Definition: router.php:78
getRequest()
Get the WebRequest being used for this instance.
makeListItem( $isbn, $label, $url)
Format a book source list item.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
getPageTitle( $subpage=false)
Get a self-referential title object.
Special page outputs information on sourcing a book with a particular ISBN The parser creates links t...
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200