MediaWiki  master
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:344
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:236
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:214
MediaWiki exception.
Definition: MWException.php:29
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:40
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.
Definition: SpecialPage.php:44
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.
Definition: TextContent.php:40
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