Skip to content

Commit af9db33

Browse files
committed
Fix up URL encoding for query strings.
1 parent 77790e3 commit af9db33

File tree

2 files changed

+72
-57
lines changed

2 files changed

+72
-57
lines changed

src/View/Helper/GoogleMapHelper.php

Lines changed: 58 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* @author Mark Scherer
2424
* @link http://www.dereuromark.de/2010/12/21/googlemapsv3-cakephp-helper/
2525
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
26+
* @property \Cake\View\Helper\HtmlHelper $Html
2627
*/
2728
class GoogleMapHelper extends Helper {
2829

@@ -326,47 +327,44 @@ public function initialize(array $config) {
326327
}
327328

328329
/**
329-
* JS maps.google API url
330-
* Like:
331-
* http://maps.google.com/maps/api/js?key=ABC
332-
* Adds Key - more variables could be added after it with "&key=value&..."
333-
* - region
330+
* JS maps.google API url.
334331
*
335-
* @param string|null $api
336-
* @param string|null $language (iso2: en, de, ja, ...)
337-
* @param string|null $append (more key-value-pairs to append)
332+
* Options read via configs
333+
* - key
334+
* - api
335+
* - language (iso2: en, de, ja, ...)
336+
*
337+
* You can adds more after the URL like "&key=value&..." via
338+
* - query string array: additional query strings (e.g. callback for deferred execution - not supported yet by this helper)
339+
*
340+
* @param array $query
338341
* @return string Full URL
339342
*/
340-
public function apiUrl($api = null, $language = null, $append = null) {
343+
public function apiUrl($query = []) {
341344
$url = $this->_protocol() . static::API;
342345

343-
// Make sure no one still uses $sensor
344-
if (is_bool($api)) {
345-
throw new LogicException('First argument is $api, either string or null. Bool given!');
346+
// Make sure no one still uses old args.
347+
if (!is_array($query)) {
348+
throw new LogicException('First argument is now array. Bool given!');
346349
}
347350

348-
$query = [];
349-
if (!empty($api)) {
350-
$this->_runtimeConfig['map']['api'] = $api;
351+
if ($this->_runtimeConfig['map']['api']) {
352+
$query['v'] = $this->_runtimeConfig['map']['api'];
351353
}
352-
if (!empty($this->_runtimeConfig['map']['api'])) {
353-
$query[] = 'v=' . $this->_runtimeConfig['map']['api'];
354-
}
355-
356-
if (!empty($this->_runtimeConfig['key'])) {
357-
$query[] = 'key=' . $this->_runtimeConfig['key'];
354+
if ($this->_runtimeConfig['key']) {
355+
$query['key'] = $this->_runtimeConfig['key'];
358356
}
359357

360-
if (!empty($language)) {
361-
$query[] = 'language=' . $language;
358+
if ($this->_runtimeConfig['language']) {
359+
$query['language'] = $this->_runtimeConfig['language'];
362360
}
363361

364362
if ($query) {
365-
$url .= '?' . implode('&', $query);
366-
}
367-
if (!empty($append)) {
368-
$url .= $append;
363+
$query = http_build_query($query);
364+
365+
$url .= '?' . $query;
369366
}
367+
370368
return $url;
371369
}
372370

@@ -1311,49 +1309,54 @@ public function mapLink($title, $mapOptions = [], $linkOptions = []) {
13111309
/**
13121310
* Returns a maps.google url
13131311
*
1314-
* @param array $options Options
1312+
* Options:
13151313
* - from: necessary (address or lat,lng)
13161314
* - to: 1x necessary (address or lat,lng - can be an array of multiple destinations: array('dest1', 'dest2'))
13171315
* - zoom: optional (defaults to none)
1316+
* - query: Additional query strings as array
1317+
*
1318+
* @param array $options Options
13181319
* @return string link: http://...
13191320
*/
13201321
public function mapUrl($options = []) {
13211322
$url = $this->_protocol() . 'maps.google.com/maps?';
13221323

1323-
$urlArray = [];
1324+
$urlArray = !empty($options['query']) ? $options['query'] : [];
13241325
if (!empty($options['from'])) {
1325-
$urlArray[] = 'saddr=' . urlencode($options['from']);
1326+
$urlArray['saddr'] = $options['from'];
13261327
}
13271328

13281329
if (!empty($options['to']) && is_array($options['to'])) {
13291330
$to = array_shift($options['to']);
13301331
foreach ($options['to'] as $key => $value) {
13311332
$to .= '+to:' . $value;
13321333
}
1333-
$urlArray[] = 'daddr=' . urlencode($to);
1334+
$urlArray['daddr'] = $to;
13341335
} elseif (!empty($options['to'])) {
1335-
$urlArray[] = 'daddr=' . urlencode($options['to']);
1336+
$urlArray['daddr'] = $options['to'];
13361337
}
13371338

13381339
if (isset($options['zoom']) && $options['zoom'] !== false) {
1339-
$urlArray[] = 'z=' . (int)$options['zoom'];
1340+
$urlArray['z'] = (int)$options['zoom'];
13401341
}
13411342
//$urlArray[] = 'f=d';
13421343
//$urlArray[] = 'hl=de';
13431344
//$urlArray[] = 'ie=UTF8';
1344-
return $url . implode('&', $urlArray);
1345-
}
13461345

1347-
/**
1348-
* STATIC MAP
1349-
**/
1346+
$options += [
1347+
'escape' => true,
1348+
];
13501349

1351-
/**
1352-
* http://maps.google.com/staticmap?center=40.714728,-73.998672&zoom=14&size=512x512&maptype=mobile&markers=40.702147,-74.015794,blues%7C40.711614,-74.012318,greeng%7C40.718217,-73.998284,redc&mobile=true&sensor=false
1353-
**/
1350+
$query = http_build_query($urlArray);
1351+
if ($options['escape']) {
1352+
$query = h($query);
1353+
}
1354+
1355+
return $url . $query;
1356+
}
13541357

13551358
/**
1356-
* Create a plain image map
1359+
* Creates a plain image map.
13571360
*
13581361
* @link http://code.google.com/intl/de-DE/apis/maps/documentation/staticmaps
13591362
* @param array $options Options
@@ -1392,14 +1395,14 @@ public function staticMapLink($title, $mapOptions = [], $linkOptions = []) {
13921395
}
13931396

13941397
/**
1395-
* Create an url to a plain image map
1398+
* Creates a URL to a plain image map.
13961399
*
13971400
* @param array $options
13981401
* - see staticMap() for details
13991402
* @return string urlOfImage: http://...
14001403
*/
14011404
public function staticMapUrl($options = []) {
1402-
$map = $this->_protocol() . static::STATIC_API;
1405+
$mapUrl = $this->_protocol() . static::STATIC_API;
14031406
/*
14041407
$params = array(
14051408
'mobile' => 'false',
@@ -1413,6 +1416,7 @@ public function staticMapUrl($options = []) {
14131416
*/
14141417

14151418
$defaults = $this->_config['staticMap'] + $this->_config;
1419+
14161420
$mapOptions = $options + $defaults;
14171421

14181422
$params = array_intersect_key($mapOptions, [
@@ -1498,7 +1502,16 @@ public function staticMapUrl($options = []) {
14981502
}
14991503
$pieces[] = $key . '=' . $value;
15001504
}
1501-
return $map . implode('&', $pieces);
1505+
1506+
$options += [
1507+
'escape' => true,
1508+
];
1509+
$query = implode('&', $pieces);
1510+
if ($options['escape']) {
1511+
$query = h($query);
1512+
}
1513+
1514+
return $mapUrl . '?' . $query;
15021515
}
15031516

15041517
/**

tests/TestCase/View/Helper/GoogleMapHelperTest.php

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ public function testConfigMergeDeep() {
6666
$this->assertSame(0, $result['map']['zoom']);
6767
}
6868

69+
/**
70+
* @return void
71+
*/
72+
public function testApiUrl() {
73+
$result = $this->GoogleMap->apiUrl();
74+
$this->assertSame('http://maps.google.com/maps/api/js?v=3', $result);
75+
76+
$result = $this->GoogleMap->apiUrl(['foo' => '<b>Bar</b>']);
77+
$this->assertSame('http://maps.google.com/maps/api/js?foo=%3Cb%3EBar%3C%2Fb%3E&v=3', $result);
78+
}
79+
6980
/**
7081
* @return void
7182
*/
@@ -74,7 +85,7 @@ public function testMapUrl() {
7485
$this->assertEquals('http://maps.google.com/maps?daddr=Munich%2C+Germany', $url);
7586

7687
$url = $this->GoogleMap->mapUrl(['to' => '<München>, Germany', 'zoom' => 1]);
77-
$this->assertEquals('http://maps.google.com/maps?daddr=%3CM%C3%BCnchen%3E%2C+Germany&z=1', $url);
88+
$this->assertEquals('http://maps.google.com/maps?daddr=%3CM%C3%BCnchen%3E%2C+Germany&amp;z=1', $url);
7889
}
7990

8091
/**
@@ -203,9 +214,6 @@ public function testStatic() {
203214
'title' => '<b>Yeah!</b>'
204215
];
205216
$is = $this->GoogleMap->staticMap($options, $attr);
206-
//echo h($is).BR;
207-
//echo $is;
208-
//echo BR.BR;
209217

210218
$pos = [
211219
['lat' => 48.1, 'lng' => '11.1'],
@@ -217,32 +225,26 @@ public function testStatic() {
217225

218226
$attr = ['url' => $this->GoogleMap->mapUrl(['to' => 'Munich, Germany'])];
219227
$is = $this->GoogleMap->staticMap($options, $attr);
220-
//echo h($is).BR;
221-
//echo $is;
222-
223-
//echo BR.BR.BR;
224228

225229
$url = $this->GoogleMap->mapUrl(['to' => 'Munich, Germany']);
226230
$attr = [
227231
'title' => 'Yeah'
228232
];
229233
$image = $this->GoogleMap->staticMap($options, $attr);
230234
$link = $this->GoogleMap->Html->link($image, $url, ['escape' => false, 'target' => '_blank']);
231-
//echo h($link).BR;
232-
//echo $link;
233235
}
234236

235237
/**
236238
* @return void
237239
*/
238240
public function testStaticMapWithStaticMapLink() {
239-
//echo '<h2>testStaticMapWithStaticMapLink</h2>';
240241
$markers = [];
241242
$markers[] = ['lat' => 48.2, 'lng' => 11.1, 'color' => 'red'];
242243
$mapMarkers = $this->GoogleMap->staticMarkers($markers);
243244

244245
$staticMapUrl = $this->GoogleMap->staticMapUrl(['center' => 48 . ',' . 11, 'markers' => $mapMarkers, 'size' => '640x510', 'zoom' => 6]);
245-
//echo $this->GoogleMap->Html->link('Open Static Map', $staticMapUrl, array('class'=>'staticMap', 'title'=>__d('tools', 'click for full map'))); //, 'escape'=>false
246+
$expected = '?size=640x510&amp;format=png&amp;mobile=false&amp;center=48%2C11&amp;zoom=6&amp;maptype=roadmap&amp;markers=color:red|shadow:true|48.2%2C11.1';
247+
$this->assertTextContains($expected, $staticMapUrl);
246248
}
247249

248250
/**

0 commit comments

Comments
 (0)