| Current File : /home/jvzmxxx/wiki1/extensions/Maps/SemanticMaps/src/queryprinters/SM_QueryHandler.php |
<?php
use Maps\Elements\Location;
/**
* Class for handling geographical SMW queries.
*
* @licence GNU GPL v2+
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
class SMQueryHandler {
private $queryResult;
private $outputmode;
/**
* @var array
*/
private $geoShapes = [
'lines' => [],
'locations' => [],
'polygons' => []
];
/**
* The template to use for the text, or false if there is none.
*
* @var string|boolean false
*/
private $template = false;
/**
* The global icon.
*
* @var string
*/
public $icon = '';
/**
* The global text.
*
* @var string
*/
public $text = '';
/**
* The global title.
*
* @var string
*/
public $title = '';
/**
* Make a separate link to the title or not?
*
* @var boolean
*/
public $titleLinkSeparate;
/**
* Should link targets be made absolute (instead of relative)?
*
* @var boolean
*/
private $linkAbsolute;
/**
* The text used for the link to the page (if it's created). $1 will be replaced by the page name.
*
* @var string
*/
private $pageLinkText;
/**
* A separator to use between the subject and properties in the text field.
*
* @var string
*/
private $subjectSeparator = '<hr />';
/**
* Make the subject in the text bold or not?
*
* @var boolean
*/
private $boldSubject = true;
/**
* Show the subject in the text or not?
*
* @var boolean
*/
private $showSubject = true;
/**
* Hide the namespace or not.
*
* @var boolean
*/
private $hideNamespace = false;
/**
* Defines which article names in the result are hyperlinked, all normally is the default
* none, subject, all
*/
private $linkStyle = 'all';
/*
* Show headers (with links), show headers (just text) or hide them. show is default
* show, plain, hide
*/
private $headerStyle = 'show';
/**
* Marker icon to show when marker equals active page
*
* @var string
*/
private $activeIcon;
/**
* @var string
*/
private $userParam = '';
/**
* @param SMWQueryResult $queryResult
* @param integer $outputmode
* @param boolean $linkAbsolute
* @param string $pageLinkText
* @param boolean $titleLinkSeparate
* @param string $activeIcon
*/
public function __construct( SMWQueryResult $queryResult, $outputmode, $linkAbsolute = false, $pageLinkText = '$1', $titleLinkSeparate = false, $hideNamespace = false, $activeIcon = null ) {
$this->queryResult = $queryResult;
$this->outputmode = $outputmode;
$this->linkAbsolute = $linkAbsolute;
$this->pageLinkText = $pageLinkText;
$this->titleLinkSeparate = $titleLinkSeparate;
$this->hideNamespace = $hideNamespace;
$this->activeIcon = $activeIcon;
}
/**
* Sets the template.
*
* @param string $template
*/
public function setTemplate( $template ) {
$this->template = $template === '' ? false : $template;
}
/**
* @param string $userParam
*/
public function setUserParam( $userParam ) {
$this->userParam = $userParam;
}
/**
* Sets the global icon.
*
* @param string $icon
*/
public function setIcon( $icon ) {
$this->icon = $icon;
}
/**
* Sets the global title.
*
* @param string $title
*/
public function setTitle( $title ) {
$this->title = $title;
}
/**
* Sets the global text.
*
* @param string $text
*/
public function setText( $text ) {
$this->text = $text;
}
/**
* Sets the subject separator.
*
* @param string $subjectSeparator
*/
public function setSubjectSeparator( $subjectSeparator ) {
$this->subjectSeparator = $subjectSeparator;
}
/**
* Sets if the subject should be made bold in the text.
*
* @param string $boldSubject
*/
public function setBoldSubject( $boldSubject ) {
$this->boldSubject = $boldSubject;
}
/**
* Sets if the subject should shown in the text.
*
* @param string $showSubject
*/
public function setShowSubject( $showSubject ) {
$this->showSubject = $showSubject;
}
/**
* Sets the text for the link to the page when separate from the title.
*
* @param string $text
*/
public function setPageLinkText( $text ) {
$this->pageLinkText = $text;
}
/**
*
* @param boolean $link
*/
public function setLinkStyle ( $link ) {
$this->linkStyle = $link;
}
/**
*
* @param boolean $headers
*/
public function setHeaderStyle ( $headers ) {
$this->headerStyle = $headers;
}
/**
* @return array
*/
public function getShapes() {
$this->findShapes();
return $this->geoShapes;
}
/**
* @since 2.0
*/
private function findShapes() {
while ( ( $row = $this->queryResult->getNext() ) !== false ) {
$this->handleResultRow( $row );
}
}
/**
* Returns the locations found in the provided result row.
*
* @param SMWResultArray[] $row
*/
private function handleResultRow( array $row ) {
$locations = [];
$properties = [];
$title = '';
$text = '';
// Loop through all fields of the record.
foreach ( $row as $i => $resultArray ) {
/* SMWPrintRequest */ $printRequest = $resultArray->getPrintRequest();
// Loop through all the parts of the field value.
while ( ( /* SMWDataValue */ $dataValue = $resultArray->getNextDataValue() ) !== false ) {
if ( $dataValue->getTypeID() == '_wpg' && $i == 0 ) {
list( $title, $text ) = $this->handleResultSubject( $dataValue );
}
else if ( $dataValue->getTypeID() == '_str' && $i == 0 ) {
$title = $dataValue->getLongText( $this->outputmode, null );
$text = $dataValue->getLongText( $this->outputmode, smwfGetLinker() );
}
else if ( $dataValue->getTypeID() == '_gpo' ) {
$dataItem = $dataValue->getDataItem();
$polyHandler = new PolygonHandler ( $dataItem->getString() );
$this->geoShapes[ $polyHandler->getGeoType() ][] = $polyHandler->shapeFromText();
} else if ( strpos( $dataValue->getTypeID(), '_rec' ) !== false ) {
foreach ( $dataValue->getDataItems() as $dataItem ) {
if ( $dataItem instanceof \SMWDIGeoCoord ) {
$location = Location::newFromLatLon( $dataItem->getLatitude(), $dataItem->getLongitude() );
$locations[] = $location;
}
}
}
else if ( $dataValue->getTypeID() != '_geo' && $i != 0 && !$this->isHeadersHide()) {
$properties[] = $this->handleResultProperty( $dataValue, $printRequest );
}
else if ( $printRequest->getMode() == SMWPrintRequest::PRINT_PROP && $printRequest->getTypeID() == '_geo' || $dataValue->getTypeID() == '_geo' ) {
$dataItem = $dataValue->getDataItem();
$location = Location::newFromLatLon( $dataItem->getLatitude(), $dataItem->getLongitude() );
$locations[] = $location;
}
}
}
if ( count( $properties ) > 0 && $text !== '' ) {
$text .= $this->subjectSeparator;
}
$icon = $this->getLocationIcon( $row );
$this->geoShapes['locations'] = array_merge(
$this->geoShapes['locations'],
$this->buildLocationsList(
$locations,
$text,
$icon,
$properties,
Title::newFromText( $title )
)
);
}
/**
* Handles a SMWWikiPageValue subject value.
* Gets the plain text title and creates the HTML text with headers and the like.
*
* @param SMWWikiPageValue $object
*
* @return array with title and text
*/
private function handleResultSubject( SMWWikiPageValue $object ) {
$title = $object->getLongText( $this->outputmode, null );
$text = '';
if ( $this->showSubject ) {
if( !$this->showArticleLink()){
$text = $this->hideNamespace ? $object->getText() : $object->getTitle()->getFullText();
}else if ( !$this->titleLinkSeparate && $this->linkAbsolute ) {
$text = Html::element(
'a',
[ 'href' => $object->getTitle()->getFullUrl() ],
$this->hideNamespace ? $object->getText() : $object->getTitle()->getFullText()
);
}
else {
if($this->hideNamespace){
$text = $object->getShortHTMLText(smwfGetLinker());
}else{
$text = $object->getLongHTMLText( smwfGetLinker() );
}
}
if ( $this->boldSubject ) {
$text = '<b>' . $text . '</b>';
}
if ( $this->titleLinkSeparate ) {
$txt = $object->getTitle()->getText();
if ( $this->pageLinkText !== '' ) {
$txt = str_replace( '$1', $txt, $this->pageLinkText );
}
$text .= Html::element(
'a',
[ 'href' => $object->getTitle()->getFullUrl() ],
$txt
);
}
}
return [ $title, $text ];
}
private function showArticleLink() {
return $this->linkStyle !== 'none';
}
/**
* Handles a single property (SMWPrintRequest) to be displayed for a record (SMWDataValue).
*
* @param SMWDataValue $object
* @param SMWPrintRequest $printRequest
*
* @return string
*/
private function handleResultProperty( SMWDataValue $object, SMWPrintRequest $printRequest ) {
if($this->isHeadersHide()){
return '';
}
if ( $this->template ) {
if ( $object instanceof SMWWikiPageValue ) {
return $object->getTitle()->getPrefixedText();
} else {
return $object->getLongText( SMW_OUTPUT_WIKI, null );
}
}
if ( $this->linkAbsolute ) {
$titleText = $printRequest->getText( null );
$t = Title::newFromText($titleText , SMW_NS_PROPERTY );
if ($this->isHeadersShow() && $t instanceof Title && $t->exists() ) {
$propertyName = $propertyName = Html::element(
'a',
[ 'href' => $t->getFullUrl() ],
$printRequest->getHTMLText( null )
);
}
else {
$propertyName = $titleText;
}
}
else {
if($this->isHeadersShow()){
$propertyName = $printRequest->getHTMLText( smwfGetLinker() );
}else if($this->isHeadersPlain()){
$propertyName = $printRequest->getText(null);
}
}
if ( $this->linkAbsolute ) {
$hasPage = $object->getTypeID() == '_wpg';
if ( $hasPage ) {
$t = Title::newFromText( $object->getLongText( $this->outputmode, null ), NS_MAIN );
$hasPage = $t !== null && $t->exists();
}
if ( $hasPage ) {
$propertyValue = Html::element(
'a',
[ 'href' => $t->getFullUrl() ],
$object->getLongText( $this->outputmode, null )
);
}
else {
$propertyValue = $object->getLongText( $this->outputmode, null );
}
}
else {
$propertyValue = $object->getLongText( $this->outputmode, smwfGetLinker() );
}
return $propertyName . ( $propertyName === '' ? '' : ': ' ) . $propertyValue;
}
private function isHeadersShow(){
return $this->headerStyle === 'show';
}
private function isHeadersHide(){
return $this->headerStyle === 'hide';
}
private function isHeadersPlain(){
return $this->headerStyle === 'plain';
}
/**
* Builds a set of locations with the provided title, text and icon.
*
* @param Location[] $locations
* @param string $text
* @param string $icon
* @param array $properties
* @param Title|null $title
*
* @return Location[]
*/
private function buildLocationsList( array $locations, $text, $icon, array $properties, Title $title = null ) {
if ( $this->template ) {
global $wgParser;
$parser = clone $wgParser;
}
else {
$text .= implode( '<br />', $properties );
}
if ( $title === null ) {
$titleOutput = '';
}
else {
$titleOutput = $this->hideNamespace ? $title->getText() : $title->getFullText();
}
foreach ( $locations as &$location ) {
if ( $this->template ) {
$segments = array_merge(
[
$this->template,
'title=' . $titleOutput,
'latitude=' . $location->getCoordinates()->getLatitude(),
'longitude=' . $location->getCoordinates()->getLongitude(),
'userparam=' . $this->userParam
],
$properties
);
$text .= $parser->parse( '{{' . implode( '|', $segments ) . '}}', $parser->getTitle(), new ParserOptions() )->getText();
}
$location->setTitle( $titleOutput );
$location->setText( $text );
$location->setIcon( $icon );
}
return $locations;
}
/**
* Get the icon for a row.
*
* @param array $row
*
* @return string
*/
private function getLocationIcon( array $row ) {
$icon = '';
$legend_labels = [];
//Check for activeicon parameter
if ( $this->shouldGetActiveIconUrlFor( $row[0]->getResultSubject()->getTitle() ) ){
$icon = MapsMapper::getFileUrl( $this->activeIcon );
}
// Look for display_options field, which can be set by Semantic Compound Queries
// the location of this field changed in SMW 1.5
$display_location = method_exists( $row[0], 'getResultSubject' ) ? $row[0]->getResultSubject() : $row[0];
if ( property_exists( $display_location, 'display_options' ) && is_array( $display_location->display_options ) ) {
$display_options = $display_location->display_options;
if ( array_key_exists( 'icon', $display_options ) ) {
$icon = $display_options['icon'];
// This is somewhat of a hack - if a legend label has been set, we're getting it for every point, instead of just once per icon
if ( array_key_exists( 'legend label', $display_options ) ) {
$legend_label = $display_options['legend label'];
if ( ! array_key_exists( $icon, $legend_labels ) ) {
$legend_labels[$icon] = $legend_label;
}
}
}
} // Icon can be set even for regular, non-compound queries If it is, though, we have to translate the name into a URL here
elseif ( $this->icon !== '' ) {
$icon = MapsMapper::getFileUrl( $this->icon );
}
return $icon;
}
private function shouldGetActiveIconUrlFor( Title $title ) {
global $wgTitle;
return isset( $this->activeIcon ) && is_object( $wgTitle )
&& $wgTitle->equals( $title );
}
/**
* @param boolean $hideNamespace
*/
public function setHideNamespace( $hideNamespace ) {
$this->hideNamespace = $hideNamespace;
}
/**
* @return boolean
*/
public function getHideNamespace() {
return $this->hideNamespace;
}
/**
* @param string $activeIcon
*/
public function setActiveIcon( $activeIcon ){
$this->activeIcon = $activeIcon;
}
/**
* @return string
*/
public function getActiveIcon( ){
return $this->activeIcon;
}
}