PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/extensions/SemanticMaps/includes/queryprinters/SM_MapPrinter.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 419 lines | 231 code | 60 blank | 128 comment | 19 complexity | b49b7c50b13d0c77c2c56143f58d124d MD5 | raw file
  1. <?php
  2. /**
  3. * Query printer for maps. Is invoked via SMMapper.
  4. * Can be overriden per service to have custom output.
  5. *
  6. * @file SM_MapPrinter.php
  7. * @ingroup SemanticMaps
  8. *
  9. * @licence GNU GPL v3
  10. * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  11. */
  12. class SMMapPrinter extends SMWResultPrinter {
  13. /**
  14. * @since 0.6
  15. *
  16. * @var iMappingService
  17. */
  18. protected $service;
  19. /**
  20. * @since 1.0
  21. *
  22. * @var false or string
  23. */
  24. protected $fatalErrorMsg = false;
  25. /**
  26. * @since 1.0
  27. *
  28. * @var array
  29. */
  30. protected $parameters;
  31. /**
  32. * Constructor.
  33. *
  34. * @param $format String
  35. * @param $inline
  36. * @param $service iMappingService
  37. */
  38. public function __construct( $format, $inline, iMappingService $service ) {
  39. $this->service = $service;
  40. parent::__construct( $format, $inline );
  41. $this->useValidator = true;
  42. }
  43. /**
  44. * (non-PHPdoc)
  45. * @see SMWResultPrinter::readParameters()
  46. */
  47. protected function readParameters( /* array */ $params, $outputmode ) {
  48. parent::readParameters( $params, $outputmode );
  49. $validator = new Validator( $this->getName(), false );
  50. $validator->setParameters( $params, $this->getParameterInfo() );
  51. $validator->validateParameters();
  52. $fatalError = $validator->hasFatalError();
  53. if ( $fatalError === false ) {
  54. $this->parameters = $validator->getParameterValues();
  55. }
  56. else {
  57. $this->fatalErrorMsg =
  58. '<span class="errorbox">' .
  59. htmlspecialchars( wfMsgExt( 'validator-fatal-error', 'parsemag', $fatalError->getMessage() ) ) .
  60. '</span>';
  61. }
  62. }
  63. /**
  64. * Returns an array containing the parameter info.
  65. *
  66. * @since 1.0
  67. *
  68. * @return array
  69. */
  70. protected function getParameterInfo() {
  71. global $egMapsDefaultLabel, $egMapsDefaultTitle;
  72. global $smgQPForceShow, $smgQPShowTitle, $smgQPTemplate;
  73. $params = MapsMapper::getCommonParameters();
  74. $this->service->addParameterInfo( $params );
  75. $params['zoom']->setDefault( false );
  76. $params['zoom']->setDoManipulationOfDefault( false );
  77. $params['staticlocations'] = new ListParameter( 'staticlocations', ';' );
  78. $params['staticlocations']->addAliases( 'locations' );
  79. $params['staticlocations']->addCriteria( new CriterionIsLocation( '~' ) );
  80. $params['staticlocations']->addManipulations( new MapsParamLocation( '~' ) );
  81. $params['staticlocations']->setDefault( array() );
  82. $params['staticlocations']->setMessage( 'semanticmaps-par-staticlocations' );
  83. $params['centre'] = new Parameter( 'centre' );
  84. $params['centre']->setDefault( false );
  85. $params['centre']->addAliases( 'center' );
  86. $params['centre']->addCriteria( new CriterionIsLocation() );
  87. $params['centre']->setDoManipulationOfDefault( false );
  88. $manipulation = new MapsParamLocation();
  89. $manipulation->toJSONObj = true;
  90. $params['centre']->addManipulations( $manipulation );
  91. $params['centre']->setMessage( 'semanticmaps-par-centre' );
  92. $params['icon'] = new Parameter(
  93. 'icon',
  94. Parameter::TYPE_STRING,
  95. '',
  96. array(),
  97. array(
  98. New CriterionNotEmpty()
  99. )
  100. );
  101. $params['icon']->setMessage( 'maps-displaypoints-par-icon' );
  102. $params['forceshow'] = new Parameter(
  103. 'forceshow',
  104. Parameter::TYPE_BOOLEAN,
  105. $smgQPForceShow,
  106. array( 'force show' )
  107. );
  108. $params['forceshow']->setMessage( 'semanticmaps-par-forceshow' );
  109. $params['showtitle'] = new Parameter(
  110. 'showtitle',
  111. Parameter::TYPE_BOOLEAN,
  112. $smgQPShowTitle,
  113. array( 'show title' )
  114. );
  115. $params['showtitle']->setMessage( 'semanticmaps-par-showtitle' );
  116. $params['template'] = new Parameter(
  117. 'template',
  118. Parameter::TYPE_STRING,
  119. $smgQPTemplate,
  120. array(),
  121. array(
  122. New CriterionNotEmpty()
  123. )
  124. );
  125. $params['template']->setDoManipulationOfDefault( false );
  126. $params['template']->setMessage( 'semanticmaps-par-template' );
  127. $params['title'] = new Parameter(
  128. 'title',
  129. Parameter::TYPE_STRING,
  130. $egMapsDefaultTitle
  131. );
  132. $params['title']->setMessage( 'maps-displaypoints-par-title' );
  133. $params['label'] = new Parameter(
  134. 'label',
  135. Parameter::TYPE_STRING,
  136. $egMapsDefaultLabel,
  137. array( 'text' )
  138. );
  139. $params['label']->setMessage( 'maps-displaypoints-par-label' );
  140. return $params;
  141. }
  142. /**
  143. * Builds up and returns the HTML for the map, with the queried coordinate data on it.
  144. *
  145. * @param SMWQueryResult $res
  146. * @param $outputmode
  147. *
  148. * @return array or string
  149. */
  150. public final function getResultText( SMWQueryResult $res, $outputmode ) {
  151. if ( $this->fatalErrorMsg === false ) {
  152. global $wgParser;
  153. $params = $this->parameters;
  154. $queryHandler = new SMQueryHandler( $res, $outputmode );
  155. $queryHandler->setShowSubject( $params['showtitle'] );
  156. $queryHandler->setTemplate( $params['template'] );
  157. $this->handleMarkerData( $params, $queryHandler->getLocations() );
  158. $locationAmount = count( $params['locations'] );
  159. if ( $params['forceshow'] || $locationAmount > 0 ) {
  160. // We can only take care of the zoom defaulting here,
  161. // as not all locations are available in whats passed to Validator.
  162. if ( $params['zoom'] === false && $locationAmount <= 1 ) {
  163. $params['zoom'] = $this->service->getDefaultZoom();
  164. }
  165. $mapName = $this->service->getMapId();
  166. // MediaWiki 1.17 does not play nice with addScript, so add the vars via the globals hook.
  167. if ( version_compare( $GLOBALS['wgVersion'], '1.18', '<' ) ) {
  168. $GLOBALS['egMapsGlobalJSVars'] += $this->service->getConfigVariables();
  169. }
  170. SMWOutputs::requireHeadItem(
  171. $mapName,
  172. $this->service->getDependencyHtml() .
  173. $configVars = Skin::makeVariablesScript( $this->service->getConfigVariables() )
  174. );
  175. foreach ( $this->service->getResourceModules() as $resourceModule ) {
  176. SMWOutputs::requireResource( $resourceModule );
  177. }
  178. return array(
  179. $this->getMapHTML( $params, $wgParser, $mapName ) . $this->getJSON( $params, $wgParser, $mapName ),
  180. 'noparse' => true,
  181. 'isHTML' => true
  182. );
  183. }
  184. else {
  185. return '';
  186. }
  187. }
  188. else {
  189. return $this->fatalErrorMsg;
  190. }
  191. }
  192. /**
  193. * Returns the HTML to display the map.
  194. *
  195. * @since 1.0
  196. *
  197. * @param array $params
  198. * @param Parser $parser
  199. * @param string $mapName
  200. *
  201. * @return string
  202. */
  203. protected function getMapHTML( array $params, Parser $parser, $mapName ) {
  204. return Html::element(
  205. 'div',
  206. array(
  207. 'id' => $mapName,
  208. 'style' => "width: {$params['width']}; height: {$params['height']}; background-color: #cccccc; overflow: hidden;",
  209. ),
  210. wfMsg( 'maps-loading-map' )
  211. );
  212. }
  213. /**
  214. * Returns the JSON with the maps data.
  215. *
  216. * @since 1.0
  217. *
  218. * @param array $params
  219. * @param Parser $parser
  220. * @param string $mapName
  221. *
  222. * @return string
  223. */
  224. protected function getJSON( array $params, Parser $parser, $mapName ) {
  225. $object = $this->getJSONObject( $params, $parser );
  226. if ( $object === false ) {
  227. return '';
  228. }
  229. return Html::inlineScript(
  230. MapsMapper::getBaseMapJSON( $this->service->getName() )
  231. . "mwmaps.{$this->service->getName()}.{$mapName}=" . json_encode( $object ) . ';'
  232. );
  233. }
  234. /**
  235. * Returns a PHP object to encode to JSON with the map data.
  236. *
  237. * @since 1.0
  238. *
  239. * @param array $params
  240. * @param Parser $parser
  241. *
  242. * @return mixed
  243. */
  244. protected function getJSONObject( array $params, Parser $parser ) {
  245. return $params;
  246. }
  247. /**
  248. * Converts the data in the coordinates parameter to JSON-ready objects.
  249. * These get stored in the locations parameter, and the coordinates on gets deleted.
  250. *
  251. * @since 1.0
  252. *
  253. * @param array &$params
  254. * @param array $queryLocations
  255. */
  256. protected function handleMarkerData( array &$params, array $queryLocations ) {
  257. global $wgParser;
  258. $parser = version_compare( $GLOBALS['wgVersion'], '1.18', '<' ) ? $wgParser : clone $wgParser;
  259. $iconUrl = MapsMapper::getFileUrl( $params['icon'] );
  260. $params['locations'] = array();
  261. foreach ( $params['staticlocations'] as $location ) {
  262. if ( $location->isValid() ) {
  263. $jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl );
  264. $jsonObj['title'] = $parser->parse( $jsonObj['title'], $parser->getTitle(), new ParserOptions() )->getText();
  265. $jsonObj['text'] = $parser->parse( $jsonObj['text'], $parser->getTitle(), new ParserOptions() )->getText();
  266. $hasTitleAndtext = $jsonObj['title'] != '' && $jsonObj['text'] != '';
  267. $jsonObj['text'] = ( $hasTitleAndtext ? '<b>' . $jsonObj['title'] . '</b><hr />' : $jsonObj['title'] ) . $jsonObj['text'];
  268. $jsonObj['title'] = strip_tags( $jsonObj['title'] );
  269. $params['locations'][] = $jsonObj;
  270. }
  271. }
  272. foreach ( $queryLocations as $location ) {
  273. if ( $location->isValid() ) {
  274. $jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl );
  275. $jsonObj['title'] = strip_tags( $jsonObj['title'] );
  276. $params['locations'][] = $jsonObj;
  277. }
  278. }
  279. unset( $params['staticlocations'] );
  280. }
  281. /**
  282. * Reads the parameters and gets the query printers output.
  283. *
  284. * @param SMWQueryResult $results
  285. * @param array $params
  286. * @param $outputmode
  287. *
  288. * @return array
  289. */
  290. public final function getResult( SMWQueryResult $results, array $params, $outputmode ) {
  291. // Skip checks, results with 0 entries are normal.
  292. $this->readParameters( $params, $outputmode );
  293. return $this->getResultText( $results, SMW_OUTPUT_HTML );
  294. }
  295. /**
  296. * Returns the internationalized name of the mapping service.
  297. *
  298. * @return string
  299. */
  300. public final function getName() {
  301. return wfMsg( 'maps_' . $this->service->getName() );
  302. }
  303. /**
  304. * Returns a list of parameter information, for usage by Special:Ask and others.
  305. *
  306. * @return array
  307. */
  308. public function getParameters() {
  309. $params = parent::getParameters();
  310. $paramInfo = $this->getParameterInfo();
  311. // Do not display this as an option, as the format already determines it
  312. // TODO: this can probably be done cleaner with some changes in Maps
  313. unset( $paramInfo['mappingservice'] );
  314. if ( version_compare( SMW_VERSION, '1.6', '<' ) ) {
  315. // Go through the descriptions, and convert them from Validator- to SMW-style.
  316. // This if for b/c with SMW 1.5.x; SMW 1.6 directly accepts Parameter objects.
  317. foreach ( $paramInfo as $paramDesc ) {
  318. $param = array(
  319. 'name' => $paramDesc->getName(),
  320. 'type' => $this->getMappedParamType( $paramDesc->getType() ),
  321. 'description' => $paramDesc->getDescription() ? $paramDesc->getDescription() : '',
  322. 'default' => $paramDesc->isRequired() ? '' : $paramDesc->getDefault()
  323. );
  324. foreach ( $paramDesc->getCriteria() as $criterion ) {
  325. if ( $criterion instanceof CriterionInArray ) {
  326. $param['values'] = $criterion->getAllowedValues();
  327. $param['type'] = $paramDesc->isList() ? 'enum-list' : 'enumeration';
  328. break;
  329. }
  330. }
  331. $params[] = $param;
  332. }
  333. }
  334. else {
  335. $params = array_merge( $params, $paramInfo );
  336. }
  337. return $params;
  338. }
  339. /**
  340. * Takes in an element of the Parameter::TYPE_ enum and turns it into an SMW type (string) indicator.
  341. *
  342. * @since 1.0
  343. *
  344. * @param Parameter::TYPE_ $type
  345. *
  346. * @return string
  347. */
  348. protected function getMappedParamType( $type ) {
  349. static $typeMap = array(
  350. Parameter::TYPE_STRING => 'string',
  351. Parameter::TYPE_BOOLEAN => 'boolean',
  352. Parameter::TYPE_CHAR => 'int',
  353. Parameter::TYPE_FLOAT => 'int',
  354. Parameter::TYPE_INTEGER => 'int',
  355. Parameter::TYPE_NUMBER => 'int',
  356. );
  357. return $typeMap[$type];
  358. }
  359. }