]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - extensions/CiteThisPage/SpecialCiteThisPage.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / extensions / CiteThisPage / SpecialCiteThisPage.php
diff --git a/extensions/CiteThisPage/SpecialCiteThisPage.php b/extensions/CiteThisPage/SpecialCiteThisPage.php
new file mode 100644 (file)
index 0000000..819635b
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+
+class SpecialCiteThisPage extends FormSpecialPage {
+
+       /**
+        * @var Parser
+        */
+       private $citationParser;
+
+       /**
+        * @var Title|bool
+        */
+       protected $title = false;
+
+       public function __construct() {
+               parent::__construct( 'CiteThisPage' );
+       }
+
+       /**
+        * @param $par string
+        */
+       public function execute( $par ) {
+               $this->setHeaders();
+               parent::execute( $par );
+               if ( $this->title instanceof Title ) {
+                       $id = $this->getRequest()->getInt( 'id' );
+                       $this->showCitations( $this->title, $id );
+               }
+       }
+
+       protected function alterForm( HTMLForm $form ) {
+               $form->setMethod( 'get' );
+       }
+
+       protected function getFormFields() {
+               if ( isset( $this->par ) ) {
+                       $default = $this->par;
+               } else {
+                       $default = '';
+               }
+               return [
+                       'page' => [
+                               'name' => 'page',
+                               'type' => 'title',
+                               'default' => $default,
+                               'label-message' => 'citethispage-change-target'
+                       ]
+               ];
+       }
+
+       public function onSubmit( array $data ) {
+               // GET forms are "submitted" on every view, so check
+               // that some data was put in for page, as empty string
+               // will pass validation
+               if ( strlen( $data['page'] ) ) {
+                       $this->title = Title::newFromText( $data['page'] );
+               }
+       }
+
+       /**
+        * Return an array of subpages beginning with $search that this special page will accept.
+        *
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       public function prefixSearchSubpages( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
+                       return [];
+               }
+               // Autocomplete subpage the same as a normal search
+               $prefixSearcher = new StringPrefixSearch;
+               $result = $prefixSearcher->search( $search, $limit, [], $offset );
+               return $result;
+       }
+
+       protected function getGroupName() {
+               return 'pagetools';
+       }
+
+       private function showCitations( Title $title, $revId ) {
+               if ( !$revId ) {
+                       $revId = $title->getLatestRevID();
+               }
+
+               $out = $this->getOutput();
+
+               $revision = Revision::newFromTitle( $title, $revId );
+               if ( !$revision ) {
+                       $out->wrapWikiMsg( '<div class="errorbox">$1</div>',
+                               [ 'citethispage-badrevision', $title->getPrefixedText(), $revId ] );
+                       return;
+               }
+
+               $parserOptions = $this->getParserOptions();
+               // Set the overall timestamp to the revision's timestamp
+               $parserOptions->setTimestamp( $revision->getTimestamp() );
+
+               $parser = $this->getParser();
+               // Register our <citation> tag which just parses using a different
+               // context
+               $parser->setHook( 'citation', [ $this, 'citationTag' ] );
+               // Also hold on to a separate Parser instance for <citation> tag parsing
+               // since we can't parse in a parse using the same Parser
+               $this->citationParser = $this->getParser();
+
+               $ret = $parser->parse(
+                       $this->getContentText(),
+                       $title,
+                       $parserOptions,
+                       /* $linestart = */ false,
+                       /* $clearstate = */ true,
+                       $revId
+               );
+
+               $this->getOutput()->addModuleStyles( 'ext.citeThisPage' );
+               $this->getOutput()->addParserOutputContent( $ret );
+       }
+
+       /**
+        * @return Parser
+        */
+       private function getParser() {
+               $parserConf = $this->getConfig()->get( 'ParserConf' );
+               return new $parserConf['class']( $parserConf );
+       }
+
+       /**
+        * Get the content to parse
+        *
+        * @return string
+        */
+       private function getContentText() {
+               $msg = $this->msg( 'citethispage-content' )->inContentLanguage()->plain();
+               if ( $msg == '' ) {
+                       # With MediaWiki 1.20 the plain text files were deleted
+                       # and the text moved into SpecialCite.i18n.php
+                       # This code is kept for b/c in case an installation has its own file "citethispage-content-xx"
+                       # for a previously not supported language.
+                       global $wgContLang, $wgContLanguageCode;
+                       $dir = __DIR__ . DIRECTORY_SEPARATOR;
+                       $code = $wgContLang->lc( $wgContLanguageCode );
+                       if ( file_exists( "${dir}citethispage-content-$code" ) ) {
+                               $msg = file_get_contents( "${dir}citethispage-content-$code" );
+                       } elseif ( file_exists( "${dir}citethispage-content" ) ) {
+                               $msg = file_get_contents( "${dir}citethispage-content" );
+                       }
+               }
+
+               return $msg;
+       }
+
+       /**
+        * Get the common ParserOptions for both parses
+        *
+        * @return ParserOptions
+        */
+       private function getParserOptions() {
+               $parserOptions = ParserOptions::newFromUser( $this->getUser() );
+               $parserOptions->setDateFormat( 'default' );
+               $parserOptions->setEditSection( false );
+
+               // Having tidy on causes whitespace and <pre> tags to
+               // be generated around the output of the CiteThisPageOutput
+               // class TODO FIXME.
+               $parserOptions->setTidy( false );
+
+               return $parserOptions;
+       }
+
+       /**
+        * Implements the <citation> tag.
+        *
+        * This is a hack to allow content that is typically parsed
+        * using the page's timestamp/pagetitle to use the current
+        * request's time and title
+        *
+        * @param string $text
+        * @param array $params
+        * @param Parser $parser
+        * @return string
+        */
+       public function citationTag( $text, $params, Parser $parser ) {
+               $ret = $this->citationParser->parse(
+                       $text,
+                       $this->getPageTitle(),
+                       $this->getParserOptions(),
+                       /* $linestart = */ false
+               );
+
+               return $ret->getText();
+       }
+
+       protected function getDisplayFormat() {
+               return 'ooui';
+       }
+
+       public function requiresUnblock() {
+               return false;
+       }
+
+       public function requiresWrite() {
+               return false;
+       }
+}