2015-09-22 15:48:38 +00:00
|
|
|
<?php
|
|
|
|
|
2018-08-09 09:49:10 +00:00
|
|
|
namespace PortableInfobox\Helpers;
|
2015-09-22 15:48:38 +00:00
|
|
|
|
2018-07-24 13:56:43 +00:00
|
|
|
use MediaWiki\Logger\LoggerFactory;
|
2018-10-11 18:26:59 +00:00
|
|
|
use PortableInfobox\Parser\Nodes\NodeFactory;
|
2018-07-24 13:56:43 +00:00
|
|
|
|
2016-12-14 11:31:25 +00:00
|
|
|
class PortableInfoboxParsingHelper {
|
2015-09-22 15:48:38 +00:00
|
|
|
|
2018-10-02 07:41:19 +00:00
|
|
|
protected $parserTagController;
|
|
|
|
protected $logger;
|
|
|
|
|
|
|
|
public function __construct() {
|
|
|
|
$this->parserTagController = \PortableInfoboxParserTagController::getInstance();
|
|
|
|
$this->logger = LoggerFactory::getInstance( 'PortableInfobox' );
|
|
|
|
}
|
|
|
|
|
2015-09-22 15:48:38 +00:00
|
|
|
/**
|
2018-10-02 07:41:19 +00:00
|
|
|
* Try to find out if infobox got "hidden" inside includeonly tag. Parse it if that's the case.
|
2016-12-13 16:41:55 +00:00
|
|
|
*
|
2018-08-16 09:25:53 +00:00
|
|
|
* @param \Title $title
|
2015-09-22 15:48:38 +00:00
|
|
|
*
|
2015-09-23 13:51:41 +00:00
|
|
|
* @return mixed false when no infoboxes found, Array with infoboxes on success
|
2015-09-22 15:48:38 +00:00
|
|
|
*/
|
2016-12-14 11:31:25 +00:00
|
|
|
public function parseIncludeonlyInfoboxes( $title ) {
|
2016-12-13 16:41:55 +00:00
|
|
|
// for templates we need to check for include tags
|
2018-10-11 18:26:59 +00:00
|
|
|
$templateText = $this->fetchArticleContent( $title );
|
2015-09-22 15:48:38 +00:00
|
|
|
|
2018-08-02 16:05:29 +00:00
|
|
|
if ( $templateText ) {
|
2016-12-13 16:41:55 +00:00
|
|
|
$parser = new \Parser();
|
|
|
|
$parserOptions = new \ParserOptions();
|
|
|
|
$frame = $parser->getPreprocessor()->newFrame();
|
2016-12-09 16:11:17 +00:00
|
|
|
|
2018-08-02 16:05:29 +00:00
|
|
|
$includeonlyText = $parser->getPreloadText( $templateText, $title, $parserOptions );
|
2018-10-11 18:26:59 +00:00
|
|
|
$infoboxes = $this->getInfoboxes( $this->removeNowikiPre( $includeonlyText ) );
|
2016-12-09 15:55:42 +00:00
|
|
|
|
2016-12-13 16:41:55 +00:00
|
|
|
if ( $infoboxes ) {
|
|
|
|
foreach ( $infoboxes as $infobox ) {
|
|
|
|
try {
|
2018-10-11 18:26:59 +00:00
|
|
|
$this->parserTagController->prepareInfobox( $infobox, $parser, $frame );
|
2016-12-13 16:41:55 +00:00
|
|
|
} catch ( \Exception $e ) {
|
2018-10-11 18:26:59 +00:00
|
|
|
$this->logger->info( 'Invalid infobox syntax' );
|
2016-12-13 16:41:55 +00:00
|
|
|
}
|
2016-12-09 15:55:42 +00:00
|
|
|
}
|
|
|
|
|
2018-10-02 07:41:19 +00:00
|
|
|
return json_decode(
|
|
|
|
$parser->getOutput()->getProperty( \PortableInfoboxDataService::INFOBOXES_PROPERTY_NAME ),
|
|
|
|
true
|
|
|
|
);
|
2016-12-13 16:41:55 +00:00
|
|
|
}
|
2016-12-09 15:55:42 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-10-11 18:26:59 +00:00
|
|
|
public function reparseArticle( \Title $title ) {
|
2016-12-14 11:31:25 +00:00
|
|
|
$parser = new \Parser();
|
|
|
|
$parserOptions = new \ParserOptions();
|
|
|
|
$parser->parse( $this->fetchArticleContent( $title ), $title, $parserOptions );
|
|
|
|
|
2018-10-02 07:41:19 +00:00
|
|
|
return json_decode(
|
|
|
|
$parser->getOutput()->getProperty( \PortableInfoboxDataService::INFOBOXES_PROPERTY_NAME ),
|
|
|
|
true
|
|
|
|
);
|
2016-12-14 11:31:25 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:26:59 +00:00
|
|
|
public function hasInfobox( $template ) {
|
|
|
|
$parser = new \Parser();
|
|
|
|
$parserOptions = new \ParserOptions();
|
|
|
|
|
|
|
|
if ( $template instanceof \Title ) {
|
|
|
|
$text = $this->fetchArticleContent( $template );
|
|
|
|
$title = $template;
|
|
|
|
} else {
|
|
|
|
$text = $template;
|
|
|
|
$title = new \Title();
|
|
|
|
}
|
|
|
|
|
|
|
|
$includeonlyText = $parser->getPreloadText( $text, $title, $parserOptions );
|
|
|
|
$infoboxes = $this->getInfoboxes( $this->removeNowikiPre( $includeonlyText ) );
|
|
|
|
|
|
|
|
if ( $infoboxes ) {
|
|
|
|
try {
|
|
|
|
NodeFactory::newFromXML( $infoboxes[0] );
|
|
|
|
return true;
|
|
|
|
} catch ( \Exception $e ) {
|
|
|
|
$this->logger->info( 'Invalid infobox syntax' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-12-14 11:31:25 +00:00
|
|
|
/**
|
2018-08-16 09:25:53 +00:00
|
|
|
* @param \Title $title
|
2016-12-14 11:31:25 +00:00
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected function fetchArticleContent( \Title $title ) {
|
|
|
|
if ( $title && $title->exists() ) {
|
2018-10-11 18:26:59 +00:00
|
|
|
$content = \WikiPage::factory( $title )
|
|
|
|
->getContent( \Revision::FOR_PUBLIC )
|
|
|
|
->getNativeData();
|
2016-12-14 11:31:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return isset( $content ) && $content ? $content : '';
|
|
|
|
}
|
|
|
|
|
2016-02-16 12:37:48 +00:00
|
|
|
/**
|
2018-08-16 09:25:53 +00:00
|
|
|
* @param \Title $title
|
|
|
|
* @return string[] array of strings (infobox markups)
|
2016-02-16 12:37:48 +00:00
|
|
|
*/
|
2018-08-16 09:25:53 +00:00
|
|
|
public function getMarkup( \Title $title ) {
|
2016-12-14 11:31:25 +00:00
|
|
|
$content = $this->fetchArticleContent( $title );
|
2016-04-01 14:43:41 +00:00
|
|
|
return $this->getInfoboxes( $content );
|
2016-02-16 12:37:48 +00:00
|
|
|
}
|
|
|
|
|
2015-09-24 11:48:51 +00:00
|
|
|
/**
|
2018-10-02 07:41:19 +00:00
|
|
|
* For given template text returns it without text in <nowiki> and <pre> tags
|
2015-09-22 15:48:38 +00:00
|
|
|
*
|
2018-08-16 09:25:53 +00:00
|
|
|
* @param string $text
|
2015-09-24 11:48:51 +00:00
|
|
|
*
|
|
|
|
* @return string
|
2015-09-22 15:48:38 +00:00
|
|
|
*/
|
2015-09-24 11:48:51 +00:00
|
|
|
protected function removeNowikiPre( $text ) {
|
2018-10-11 18:26:59 +00:00
|
|
|
$text = preg_replace( '/<(nowiki|pre)>.+<\/\g1>/sU', '', $text );
|
2015-09-22 15:48:38 +00:00
|
|
|
|
2015-09-24 11:48:51 +00:00
|
|
|
return $text;
|
2015-09-22 15:48:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-10-02 07:41:19 +00:00
|
|
|
* From the template without <includeonly> tags, creates an array of
|
2015-09-24 11:48:51 +00:00
|
|
|
* strings containing only infoboxes. All template content which is not an infobox is removed.
|
2015-09-22 15:48:38 +00:00
|
|
|
*
|
2018-08-16 09:25:53 +00:00
|
|
|
* @param string $text Content of template which uses the <includeonly> tags
|
2015-09-22 15:48:38 +00:00
|
|
|
*
|
2015-09-24 11:48:51 +00:00
|
|
|
* @return array of striped infoboxes ready to parse
|
2015-09-22 15:48:38 +00:00
|
|
|
*/
|
2015-09-24 11:48:51 +00:00
|
|
|
protected function getInfoboxes( $text ) {
|
2018-10-11 18:26:59 +00:00
|
|
|
preg_match_all( '/<infobox(?:[^>]*\/>|.+<\/infobox>)/sU', $text, $result );
|
|
|
|
return $result[0];
|
2015-09-22 15:48:38 +00:00
|
|
|
}
|
|
|
|
}
|