258 lines
6.0 KiB
PHP
258 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace SMW;
|
|
|
|
use MediaWiki\Html\Html;
|
|
use MediaWiki\Linker\Linker;
|
|
use MediaWiki\SpecialPage\QueryPage as MWQueryPage;
|
|
use MediaWiki\Xml\Xml;
|
|
use SMW\MediaWiki\MessageBuilder;
|
|
|
|
/**
|
|
* An abstract query page base class that supports array-based
|
|
* data retrieval instead of the SQL-based access used by MW.
|
|
*
|
|
*
|
|
* @license GPL-2.0-or-later
|
|
* @since ??
|
|
*
|
|
* @author Markus Krötzsch
|
|
*/
|
|
|
|
/**
|
|
* Abstract base class for SMW's variant of the MW QueryPage.
|
|
* Subclasses must implement getResults() and formatResult(), as
|
|
* well as some other standard functions of QueryPage.
|
|
*
|
|
* @ingroup SMW
|
|
* @ingroup QueryPage
|
|
*/
|
|
abstract class QueryPage extends MWQueryPage {
|
|
|
|
/** @var MessageFormatter */
|
|
protected $msgFormatter;
|
|
|
|
/** @var Linker */
|
|
protected $linker = null;
|
|
|
|
/** @var array */
|
|
protected $selectOptions = [];
|
|
|
|
/** @var array */
|
|
protected $useSerchForm = false;
|
|
|
|
/**
|
|
* Implemented by subclasses to provide concrete functions.
|
|
*/
|
|
abstract function getResults( $requestoptions );
|
|
|
|
/**
|
|
* Clear the cache and save new results
|
|
* @todo Implement caching for SMW query pages
|
|
*/
|
|
function recache( $limit, $ignoreErrors = true ) {
|
|
/// TODO
|
|
}
|
|
|
|
function isExpensive() {
|
|
return false; // Disables caching for now
|
|
}
|
|
|
|
function isSyndicated() {
|
|
return false; // TODO: why not?
|
|
}
|
|
|
|
/**
|
|
* @see QueryPage::linkParameters
|
|
*
|
|
* @since 1.9
|
|
*
|
|
* @return array
|
|
*/
|
|
public function linkParameters() {
|
|
$parameters = [];
|
|
$property = $this->getRequest()->getVal( 'property' );
|
|
|
|
if ( $property !== null && $property !== '' ) {
|
|
$parameters['property'] = $property;
|
|
}
|
|
|
|
$filter = $this->getRequest()->getVal( 'filter' );
|
|
|
|
if ( $filter !== null && $filter !== '' ) {
|
|
$parameters['filter'] = $filter;
|
|
}
|
|
|
|
return $parameters;
|
|
}
|
|
|
|
/**
|
|
* Returns a MessageFormatter object
|
|
*
|
|
* @since 1.9
|
|
*
|
|
* @return MessageFormatter
|
|
*/
|
|
public function getMessageFormatter() {
|
|
if ( !isset( $this->msgFormatter ) ) {
|
|
$this->msgFormatter = new MessageFormatter( $this->getLanguage() );
|
|
}
|
|
|
|
return $this->msgFormatter;
|
|
}
|
|
|
|
/**
|
|
* Returns a Linker object
|
|
*
|
|
* @since 1.9
|
|
*
|
|
* @return Linker
|
|
*/
|
|
public function getLinker() {
|
|
if ( $this->linker === null ) {
|
|
$this->linker = smwfGetLinker();
|
|
}
|
|
|
|
return $this->linker;
|
|
}
|
|
|
|
/**
|
|
* Generates a search form
|
|
*
|
|
* @since 1.9
|
|
*
|
|
* @param string $property
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getSearchForm( $property = '', $cacheDate = '', $propertySearch = true, $filter = '' ) {
|
|
$this->useSerchForm = true;
|
|
$this->getOutput()->addModules( 'ext.smw.autocomplete.property' );
|
|
|
|
// No need to verify $this->selectOptions because its values are set
|
|
// during doQuery() which is processed before this form is generated
|
|
$limit = $this->selectOptions['limit'];
|
|
$offset = $this->selectOptions['offset'];
|
|
$resultCount = $this->msg( 'smw-showingresults' )->numParams( $limit, $offset + 1 )->parse();
|
|
|
|
$msgBuilder = new MessageBuilder( $this->getLanguage() );
|
|
$selection = $msgBuilder->prevNextToText(
|
|
$this->getContext()->getTitle(),
|
|
$limit,
|
|
$offset,
|
|
$this->linkParameters(),
|
|
$this->selectOptions['end']
|
|
);
|
|
|
|
if ( $cacheDate !== '' ) {
|
|
$cacheDate = Xml::tags( 'p', [], $cacheDate );
|
|
}
|
|
|
|
if ( $propertySearch ) {
|
|
$propertySearch = Xml::tags( 'hr', [ 'style' => 'margin-bottom:10px;' ], '' ) .
|
|
Xml::inputLabel( $this->msg( 'smw-special-property-searchform' )->text(), 'property', 'smw-property-input', 20, $property ) . ' ' .
|
|
Xml::submitButton( $this->msg( 'allpagessubmit' )->text() );
|
|
}
|
|
|
|
if ( $filter !== '' ) {
|
|
$filter = Xml::tags( 'hr', [ 'style' => 'margin-bottom:10px;' ], '' ) . $filter;
|
|
}
|
|
|
|
return Xml::tags( 'form', [
|
|
'method' => 'get',
|
|
'action' => htmlspecialchars( $GLOBALS['wgScript'] ),
|
|
'class' => 'plainlinks'
|
|
], Html::hidden( 'title', $this->getContext()->getTitle()->getPrefixedText() ) .
|
|
Xml::fieldset( $this->msg( 'smw-special-property-searchform-options' )->text(),
|
|
Xml::tags( 'p', [], $resultCount ) .
|
|
Xml::tags( 'p', [], $selection ) .
|
|
$cacheDate .
|
|
$propertySearch .
|
|
$filter
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* This is the actual workhorse. It does everything needed to make a
|
|
* real, honest-to-gosh query page.
|
|
* Alas, we need to overwrite the whole beast since we do not assume
|
|
* an SQL-based storage backend.
|
|
*
|
|
* @param $offset database query offset
|
|
* @param $limit database query limit
|
|
* @param $property database string query
|
|
*/
|
|
function doQuery( $offset = false, $limit = false, $property = false ) {
|
|
$out = $this->getOutput();
|
|
$sk = $this->getSkin();
|
|
|
|
$options = new RequestOptions();
|
|
$options->limit = $limit;
|
|
$options->offset = $offset;
|
|
$options->sort = true;
|
|
|
|
if ( $property ) {
|
|
$options->addStringCondition( $property, StringCondition::STRCOND_MID );
|
|
}
|
|
|
|
if ( ( $filter = $this->getRequest()->getVal( 'filter' ) ) === 'unapprove' ) {
|
|
$options->addExtraCondition( [ 'filter.unapprove' => true ] );
|
|
}
|
|
|
|
$res = $this->getResults( $options );
|
|
$num = count( $res );
|
|
|
|
// often disable 'next' link when we reach the end
|
|
$atend = $num < $limit;
|
|
|
|
$this->selectOptions = [
|
|
'offset' => $offset,
|
|
'limit' => $limit,
|
|
'end' => $atend,
|
|
'count' => $num
|
|
];
|
|
|
|
$out->addHTML( $this->getPageHeader() );
|
|
|
|
// if list is empty, show it
|
|
if ( $num == 0 ) {
|
|
$out->addHTML( '<p>' . $this->msg( 'specialpage-empty' )->escaped() . '</p>' );
|
|
return;
|
|
}
|
|
|
|
if ( $num > 0 ) {
|
|
$s = [];
|
|
if ( !$this->listoutput ) {
|
|
$s[] = $this->openList( $offset );
|
|
}
|
|
|
|
foreach ( $res as $r ) {
|
|
$format = $this->formatResult( $sk, $r );
|
|
if ( $format ) {
|
|
$s[] = $this->listoutput ? $format : "<li>{$format}</li>\n";
|
|
}
|
|
}
|
|
|
|
if ( !$this->listoutput ) {
|
|
$s[] = $this->closeList();
|
|
}
|
|
$str = $this->listoutput ? $this->getLanguage()->listToText( $s ) : implode( '', $s );
|
|
$out->addHTML( $str );
|
|
}
|
|
|
|
if ( !$this->useSerchForm ) {
|
|
$out->addHTML( "<p>{$sl}</p>\n" );
|
|
}
|
|
|
|
return $num;
|
|
}
|
|
|
|
/**
|
|
* @return array|null
|
|
*/
|
|
public function getQueryInfo(): ?array {
|
|
return null;
|
|
}
|
|
}
|