1<?php
2/*
3 * Copyright (c) 2014-2016 Mark C. Prins <mprins@users.sf.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17if (!defined('DOKU_INC'))
18	die ();
19
20if (!defined('DOKU_PLUGIN'))
21	define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
22
23require_once (DOKU_PLUGIN . 'syntax.php');
24
25/**
26 * DokuWiki Plugin mapillary (Syntax Component).
27 *
28 * Handles the rendering part of the Mapillary plugin.
29 *
30 * @license BSD license
31 * @author Mark C. Prins <mprins@users.sf.net>
32 */
33class syntax_plugin_mapillary extends DokuWiki_Syntax_Plugin {
34	/**
35	 *
36	 * @see DokuWiki_Syntax_Plugin::getType()
37	 */
38	public function getType() {
39		return 'substition';
40	}
41
42	/**
43	 *
44	 * @see DokuWiki_Syntax_Plugin::getPType()
45	 */
46	public function getPType() {
47		return 'block';
48	}
49
50	/**
51	 *
52	 * @see Doku_Parser_Mode::getSort()
53	 */
54	public function getSort() {
55		return 305;
56	}
57
58	/**
59	 * Define the syntax pattern.
60	 * The syntax for this plugin is: {{mapillary>imagehash&width&sequences&legs}}
61	 * where imagehash is the hash of the first image of a sequence
62	 * and width is the widget width in pixels. One (optional) space
63	 * either after the opening pair of brackets or before the closing
64	 * pair signifies floating aligment to right of left.
65	 *
66	 * @see http://www.mapillary.com/integrate.html
67	 *
68	 * @see Doku_Parser_Mode::connectTo()
69	 */
70	public function connectTo($mode) {
71		$this->Lexer->addSpecialPattern('\{\{\s?mapillary>[^}\s]*\s?\}\}', $mode, 'plugin_mapillary');
72	}
73
74	/**
75	 * parse the syntax.
76	 *
77	 * @see DokuWiki_Syntax_Plugin::handle()
78	 */
79	public function handle($match, $state, $pos, Doku_Handler $handler) {
80		// check for float assignment left/right
81		$float = 'none';
82		$space = stripos($match, ' ');
83		if ($space > 0) {
84			if ($space < 12) {
85				$float = 'right';
86			}
87			if ($space > 12) {
88				$float = 'left';
89			}
90		}
91		// parse te match
92		$match = substr(str_replace(' ', '', $match), 12, - 2);
93		$params = explode('&', $match);
94		list ($img, $width, $sequences, $legs) = $params;
95		//TODO add support for showImage=
96		//TODO add support for showPlayControls=
97		//TODO add support for showMap=
98		//TODO add support for directions=
99		//TODO add support for showThumbs=
100
101		// make sure we have a min. width & sanity check
102		$width = intval($width);
103		if ($width < 100)
104			$width = 320;
105		if ($width > 2048)
106			$width = 2048;
107
108		return array(
109				hsc($img),
110				$width,
111				hsc($sequences),
112				hsc($legs),
113				$float
114		);
115	}
116
117	/**
118	 * Render the syntax for xhtml, odt or metadata.
119	 *
120	 * @see DokuWiki_Syntax_Plugin::render()
121	 *
122	 * @see http://www.mapillary.com/javascripts/mapillary.js
123	 * @see https://dga406zepc8gy.cloudfront.net/javascripts/mapillary.js
124	 */
125	public function render($mode, Doku_Renderer $renderer, $data) {
126		if ($data === false) {
127					return false;
128		}
129
130		static $id = 0;
131		list ($image, $width, $sequences, $legs, $float) = $data;
132		// this url might break, no idea if this url will be persistant but it
133		// is mentioned in the api docs
134		$image_url = 'http://d1cuyjsrcm0gby.cloudfront.net/' . $image . '/thumb-1024.jpg';
135
136		if ($mode == 'xhtml') {
137			// based on the embed javascript at http://www.mapillary.com/integrate.html
138			// TODO this used to work but not anaymore $height = ($width / 4 * 3 * 2 - 30);
139			/*h= map div height + photo + location,author etc + mapillary link*/
140			$height = 150 + 3 / 4 * intval($width) + 40 + 20;
141			$url = '//www.mapillary.com/jsapi/?';
142			if (!empty ($image)) {
143				$url .= 'image=' . $image . '&';
144			}
145			if (!empty ($sequences)) {
146				$url .= 'sequences=' . $sequences . '&';
147			}
148			if (!empty ($legs)) {
149				$url .= 'legs=' . $legs;
150			}
151
152			$renderer->doc .= '<div id="mapillary-' . $id . '" class="mapillary-' . $float . '">';
153			$renderer->doc .= '<iframe src="' . $url . '" id="mapillary-iframe-' . $id . '"';
154			$renderer->doc .= '  style="width:' . $width . 'px;height:' . $height . 'px;"; title="Mapillary (' . $image . ')">';
155			$renderer->doc .= '</iframe>';
156			$renderer->doc .= '<figure class="mapillary-print">';
157			$renderer->externalmedia($image_url, 'Mapillary (' . $image . ')', 'left', 1024, null, 'cache', 'nolink');
158			$renderer->doc .= '<figcaption>Mapillary: ';
159			$renderer->externallink('http://www.mapillary.com/map/im/' . $image, $image);
160			$renderer->doc .= ' (CC BY-SA 4.0)</figcaption></figure>';
161			$renderer->doc .= '</div>';
162			$id ++;
163			return true;
164		} elseif ($mode == 'metadata') {
165			global $ID;
166			$rel = p_get_metadata($ID, 'relation', METADATA_RENDER_USING_CACHE);
167			$img = $rel [ 'firstimage' ];
168			if (empty ($img)) {
169				$renderer->externalmedia($image_url, 'Mapillary (' . $image . ')');
170			}
171			return true;
172		} elseif ($mode == 'odt') {
173			$renderer->p_open();
174			$renderer->externalmedia($image_url, 'Mapillary (' . $image . ')', 'left', 1024, null, 'cache', 'nolink');
175			$renderer->linebreak();
176			$renderer->cdata('Mapillary: ');
177			$renderer->externallink('http://www.mapillary.com/map/im/' . $image, $image);
178			$renderer->cdata(' (CC BY-SA 4.0)');
179			$renderer->p_close();
180			return true;
181		}
182		return false;
183	}
184}
185