Current File : /home/jvzmxxx/wiki1/extensions/Maps/includes/Maps_DisplayMapRenderer.php
<?php
use Maps\Element;
use Maps\Elements\Line;
use Maps\Elements\Location;

/**
 * Class handling the #display_map rendering.
 *
 * @licence GNU GPL v2+
 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 * @author Kim Eik
 */
class MapsDisplayMapRenderer {

	/**
	 * @since 2.0
	 *
	 * @var iMappingService
	 */
	protected $service;

	/**
	 * Constructor.
	 *
	 * @param iMappingService $service
	 */
	public function __construct( iMappingService $service ) {
		$this->service = $service;
	}

	/**
	 * Returns the HTML to display the map.
	 *
	 * @since 2.0
	 *
	 * @param array $params
	 * @param Parser $parser
	 * @param string $mapName
	 *
	 * @return string
	 */
	protected function getMapHTML( array $params, Parser $parser, $mapName ) {
		return Html::rawElement(
			'div',
			[
				'id' => $mapName,
				'style' => "width: {$params['width']}; height: {$params['height']}; background-color: #cccccc; overflow: hidden;",
				'class' => 'maps-map maps-' . $this->service->getName()
			],
			wfMessage( 'maps-loading-map' )->inContentLanguage()->escaped() .
				Html::element(
					'div',
					[ 'style' => 'display:none', 'class' => 'mapdata' ],
					FormatJson::encode( $this->getJSONObject( $params, $parser ) )
				)
		);
	}

	/**
	 * Returns a PHP object to encode to JSON with the map data.
	 *
	 * @since 2.0
	 *
	 * @param array $params
	 * @param Parser $parser
	 *
	 * @return mixed
	 */
	protected function getJSONObject( array $params, Parser $parser ) {
		return $params;
	}

	/**
	 * Handles the request from the parser hook by doing the work that's common for all
	 * mapping services, calling the specific methods and finally returning the resulting output.
	 *
	 * @param array $params
	 * @param Parser $parser
	 *
	 * @return string
	 */
	public final function renderMap( array $params, Parser $parser ) {
		$this->handleMarkerData( $params, $parser );

		$mapName = $this->service->getMapId();

		$output = $this->getMapHTML( $params, $parser, $mapName );

		$configVars = Skin::makeVariablesScript( $this->service->getConfigVariables() );

		$this->service->addHtmlDependencies(
			self::getLayerDependencies( $params['mappingservice'], $params )
		);

		$this->service->addDependencies( $parser );
		$parser->getOutput()->addHeadItem( $configVars );

		return $output;
	}

	/**
	 * Converts the data in the coordinates parameter to JSON-ready objects.
	 * These get stored in the locations parameter, and the coordinates on gets deleted.
	 *
	 * FIXME: complexity
	 *
	 * @since 1.0
	 *
	 * @param array &$params
	 * @param Parser $parser
	 */
	protected function handleMarkerData( array &$params, Parser $parser ) {
		if ( is_object( $params['centre'] ) ) {
			$params['centre'] = $params['centre']->getJSONObject();
		}

		$parserClone = clone $parser;

		if ( is_object( $params['wmsoverlay'] ) ) {
			$params['wmsoverlay'] = $params['wmsoverlay']->getJSONObject();
		}

		$iconUrl = MapsMapper::getFileUrl( $params['icon'] );
		$visitedIconUrl = MapsMapper::getFileUrl( $params['visitedicon'] );
		$params['locations'] = [];

		/**
		 * @var Location $location
		 */
		foreach ( $params['coordinates'] as $location ) {
			$jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl, '', '',$visitedIconUrl);

			$jsonObj['title'] = $parserClone->parse( $jsonObj['title'], $parserClone->getTitle(), new ParserOptions() )->getText();
			$jsonObj['text'] = $parserClone->parse( $jsonObj['text'], $parserClone->getTitle(), new ParserOptions() )->getText();
			if ( isset( $jsonObj['inlineLabel'] ) ) {
				$jsonObj['inlineLabel'] = strip_tags($parserClone->parse( $jsonObj['inlineLabel'], $parserClone->getTitle(), new ParserOptions() )->getText(),'<a><img>');
			}

			$hasTitleAndtext = $jsonObj['title'] !== '' && $jsonObj['text'] !== '';
			$jsonObj['text'] = ( $hasTitleAndtext ? '<b>' . $jsonObj['title'] . '</b><hr />' : $jsonObj['title'] ) . $jsonObj['text'];
			$jsonObj['title'] = strip_tags( $jsonObj['title'] );

			$params['locations'][] = $jsonObj;
		}

		unset( $params['coordinates'] );

		$this->handleShapeData( $params, $parserClone );

		if ( $params['mappingservice'] === 'openlayers' ) {
			$params['layers'] = self::evilOpenLayersHack( $params['layers'] );
		}
	}

	protected function handleShapeData( array &$params, Parser $parserClone ) {
		$textContainers = [
			&$params['lines'] ,
			&$params['polygons'] ,
			&$params['circles'] ,
			&$params['rectangles'],
			&$params['imageoverlays'], // FIXME: this is Google Maps specific!!
		];

		foreach ( $textContainers as &$textContainer ) {
			if ( is_array( $textContainer ) ) {
				foreach ( $textContainer as &$obj ) {
					if ( $obj instanceof Element ) {
						$obj = $obj->getArrayValue();
					}

					$obj['title'] = $parserClone->parse( $obj['title'] , $parserClone->getTitle() , new ParserOptions() )->getText();
					$obj['text'] = $parserClone->parse( $obj['text'] , $parserClone->getTitle() , new ParserOptions() )->getText();

					$hasTitleAndtext = $obj['title'] !== '' && $obj['text'] !== '';
					$obj['text'] = ( $hasTitleAndtext ? '<b>' . $obj['title'] . '</b><hr />' : $obj['title'] ) . $obj['text'];
					$obj['title'] = strip_tags( $obj['title'] );
				}
			}
		}
	}

	/**
	 * FIXME
	 *
	 * Temporary hack until the mapping service handling gets a proper refactor
	 * This kind of JS construction is also rather evil and should not be done at this point
	 *
	 * @since 3.0
	 * @deprecated
	 *
	 * @param string[] $layers
	 *
	 * @return string[]
	 */
	public static function evilOpenLayersHack( $layers ) {
		global $egMapsOLLayerGroups, $egMapsOLAvailableLayers;

		$layerDefs = [];
		$layerNames = [];

		foreach ( $layers as $layerOrGroup ) {
			$lcLayerOrGroup = strtolower( $layerOrGroup );

			// Layer groups. Loop over all items and add them if not present yet:
			if ( array_key_exists( $lcLayerOrGroup, $egMapsOLLayerGroups ) ) {
				foreach ( $egMapsOLLayerGroups[$lcLayerOrGroup] as $layerName ) {
					if ( !in_array( $layerName, $layerNames ) ) {
						if ( is_array( $egMapsOLAvailableLayers[$layerName] ) ) {
							$layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$layerName][0];
						}
						else {
							$layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$layerName];
						}
						$layerNames[] = $layerName;
					}
				}
			}
			// Single layers. Add them if not present yet:
			elseif ( array_key_exists( $lcLayerOrGroup, $egMapsOLAvailableLayers ) ) {
				if ( !in_array( $lcLayerOrGroup, $layerNames ) ) {
					if ( is_array( $egMapsOLAvailableLayers[$lcLayerOrGroup] ) ) {
						$layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$lcLayerOrGroup][0];
					}
					else {
						$layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$lcLayerOrGroup];
					}

					$layerNames[] = $lcLayerOrGroup;
				}
			}
		}
		return $layerDefs;
	}

	public static function getLayerDependencies( $service, $params ) {
		global $egMapsOLLayerDependencies, $egMapsOLAvailableLayers,
			   $egMapsLeafletLayerDependencies, $egMapsLeafletAvailableLayers,
			   $egMapsLeafletLayersApiKeys;

		$layerDependencies = [];

		if ( $service === 'leaflet' ) {
			$layerName = $params['layer'];
			if ( array_key_exists( $layerName, $egMapsLeafletAvailableLayers )
					&& $egMapsLeafletAvailableLayers[$layerName]
					&& array_key_exists( $layerName, $egMapsLeafletLayersApiKeys )
					&& array_key_exists( $layerName, $egMapsLeafletLayerDependencies ) ) {
				$layerDependencies[] = '<script src="' . $egMapsLeafletLayerDependencies[$layerName] .
					$egMapsLeafletLayersApiKeys[$layerName] . '"></script>';
			}
		} else if ( $service === 'openlayers' ) {
			$layerNames = $params['layers'];
			foreach ( $layerNames as $layerName ) {
				if ( array_key_exists( $layerName, $egMapsOLAvailableLayers ) // The layer must be defined in php
						&& is_array( $egMapsOLAvailableLayers[$layerName] ) // The layer must be an array...
						&& count( $egMapsOLAvailableLayers[$layerName] ) > 1 // ...with a second element...
						&& array_key_exists( $egMapsOLAvailableLayers[$layerName][1], $egMapsOLLayerDependencies ) ) { //...that is a dependency.
					$layerDependencies[] = $egMapsOLLayerDependencies[$egMapsOLAvailableLayers[$layerName][1]];
				}
			}

		}

		return array_unique( $layerDependencies );
	}

}