1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12: 
 13: $plugin_is_filter = 5 | THEME_PLUGIN;
 14: $plugin_description = gettext('Display Google Maps based on <em>latitude</em> and <em>longitude</em> metadata in the images.');
 15: $plugin_notice = sprintf(gettext('<strong>Note</strong>: Google does place limits on the use of its <a href="%s"><em>Maps API</em></a>. Please review these to be sure your site is in compliance.'), 'http://googlegeodevelopers.blogspot.com/2011/10/introduction-of-usage-limits-to-maps.html');
 16: $plugin_author = 'Stephen Billard (sbillard) & Vincent Bourganel (vincent3569)';
 17: 
 18: 
 19: $option_interface = 'GoogleMap';
 20: if (isset($_zp_gallery_page) && $_zp_gallery_page != 'index.php') {
 21:     if (getOption('gmap_sessions')) {
 22:         zp_session_start();
 23:     }
 24:     zp_register_filter('theme_head', 'GoogleMap::js');
 25: }
 26: 
 27:  28:  29:  30: 
 31: class GoogleMap {
 32: 
 33:     function __construct() {
 34:         setOptionDefault('gmap_map_roadmap', 1);
 35:         setOptionDefault('gmap_map_hybrid', 1);
 36:         setOptionDefault('gmap_map_satellite', 1);
 37:         setOptionDefault('gmap_map_terrain', 1);
 38:         setOptionDefault('gmap_starting_map', 'HYBRID');
 39:         setOptionDefault('gmap_control_type', 'HORIZONTAL_BAR');
 40:         setOptionDefault('gmap_zoom_size', 'LARGE');
 41:         setOptionDefault('gmap_cluster_max_zoom', 13);
 42:         setOptionDefault('gmap_sessions', 1);
 43:         if (OFFSET_PATH == 2) {
 44:             setOptionDefault('gmap_display', 'hide');
 45:             purgeOption('gmap_hide');
 46:         }
 47:         setOptionDefault('gmap_display', 'show');
 48:         if (class_exists('cacheManager')) {
 49:             cacheManager::deleteThemeCacheSizes('GoogleMap');
 50:             cacheManager::addThemeCacheSize('GoogleMap', 150, NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL);
 51:         }
 52:     }
 53: 
 54:     function getOptionsSupported() {
 55: 
 56:         $MapTypes = array(); 
 57:         if (getOption('gmap_map_hybrid'))
 58:             $MapTypes[gettext('Hybrid')] = 'HYBRID';
 59:         if (getOption('gmap_map_roadmap'))
 60:             $MapTypes[gettext('Map')] = 'ROADMAP';
 61:         if (getOption('gmap_map_satellite'))
 62:             $MapTypes[gettext('Satellite')] = 'SATELLITE';
 63:         if (getOption('gmap_map_terrain'))
 64:             $MapTypes[gettext('Terrain')] = 'TERRAIN';
 65: 
 66:         $defaultMap = getOption('gmap_starting_map');
 67:         if (array_search($defaultMap, $MapTypes) === false) { 
 68:             $temp = $MapTypes;
 69:             $defaultMap = array_shift($temp);
 70:             setOption('gmap_starting_map', $defaultMap);
 71:         }
 72: 
 73:         return array(
 74:                         gettext('Allowed maps')                                  => array('key'              => 'gmap_allowed_maps', 'type'          => OPTION_TYPE_CHECKBOX_ARRAY,
 75:                                         'order'          => 1,
 76:                                         'checkboxes' => array(gettext('Hybrid')      => 'gmap_map_hybrid',
 77:                                                         gettext('Map')           => 'gmap_map_roadmap',
 78:                                                         gettext('Satellite') => 'gmap_map_satellite',
 79:                                                         gettext('Terrain')   => 'gmap_map_terrain'),
 80:                                         'desc'           => gettext('Select the map types that are allowed.')),
 81:                         gettext('Initial map display selection') => array('key'              => 'gmap_starting_map', 'type'          => OPTION_TYPE_SELECTOR,
 82:                                         'order'          => 2,
 83:                                         'selections' => $MapTypes,
 84:                                         'desc'           => gettext('Select the initial type of map to display.')),
 85:                         gettext('Map display')                                   => array('key'              => 'gmap_display', 'type'           => OPTION_TYPE_SELECTOR,
 86:                                         'order'          => 3,
 87:                                         'selections' => array(gettext('show')            => 'show',
 88:                                                         gettext('hide')          => 'hide',
 89:                                                         gettext('colorbox')  => 'colorbox'),
 90:                                         'desc'           => gettext('Select <em>hide</em> to initially hide the map. Select <em>colorbox</em> for the map to display in a colorbox. Select <em>show</em> and the map will display when the page loads.')),
 91:                         gettext('Map controls')                                  => array('key'          => 'gmap_control_type', 'type'      => OPTION_TYPE_RADIO,
 92:                                         'order'      => 4,
 93:                                         'buttons'    => array(gettext('None')                => 'none',
 94:                                                         gettext('Default')       => 'DEFAULT',
 95:                                                         gettext('Dropdown')      => 'DROPDOWN_MENU',
 96:                                                         gettext('Horizontal')    => 'HORIZONTAL_BAR'),
 97:                                         'desc'       => gettext('Display options for the Map type control.')),
 98:                         gettext('Zoom controls')                                 => array('key'          => 'gmap_zoom_size', 'type'         => OPTION_TYPE_RADIO,
 99:                                         'order'      => 5,
100:                                         'buttons'    => array(gettext('Small')   => 'SMALL',
101:                                                         gettext('Default') => 'DEFAULT',
102:                                                         gettext('Large')     => 'LARGE'),
103:                                         'desc'       => gettext('Display options for the Zoom control.')),
104:                         gettext('Max zoom level')                                => array('key'      => 'gmap_cluster_max_zoom', 'type'  => OPTION_TYPE_TEXTBOX,
105:                                         'order'  => 6,
106:                                         'desc'   => gettext('The max zoom level for clustering pictures on map.')),
107:                         gettext('Map sessions')                                  => array('key'      => 'gmap_sessions', 'type'  => OPTION_TYPE_CHECKBOX,
108:                                         'order'  => 9,
109:                                         'desc'   => gettext('If checked GoogleMaps will use sessions to pass map data for the <em>colorbox</em> display option. We recommend this option be selected. It protects against reference forgery security attacks and mitigates problems with data exceeding the allowed by some browsers.')),
110:                         gettext('API key')                                   => array('key'      => 'gmap_api_key', 'type'   => OPTION_TYPE_TEXTBOX,
111:                                         'order'  => 10,
112:                                         'desc'   => gettext('Enter your API key. You can get one <a href="https://developers.google.com/maps/documentation/javascript/get-api-key#key">here</a>.'))
113:         );
114:     }
115: 
116:     function handleOption($option, $currentValue) {
117: 
118:     }
119: 
120:     121: 122: 
123:     static function js() {
124: 
125:         if (!defined('BASEPATH'))
126:             define('BASEPATH', true); 
127:         require_once(dirname(__FILE__) . '/GoogleMap/CodeIgniter-Google-Maps-V3-API/Googlemaps.php');
128:         $parameters = array();
129:         $url_appendix = '';
130:         $loc = getOption('locale');
131:         if ( !empty($loc) ) {
132:             $parameters[] = 'language=' . substr(getOption('locale'), 0, 2);
133:         }
134:         $apikey = getOption('gmap_api_key');
135:         if ( !empty($apikey) ) {
136:             $parameters[]  = 'key=' . $apikey;
137:         }
138:         if ( !empty($parameters) ) {
139:             $url_appendix = implode('&', $parameters);
140:         }
141:         ?>
142:         <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?<?php echo $url_appendix; ?>"></script>
143:         <script type="text/javascript" src="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER; ?>/GoogleMap/markerClustererPlus/markerclusterer.js"></script>
144:         <script type="text/javascript" src="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER; ?>/GoogleMap/overlappingMarkerSpiderfier/oms.min.js"></script>
145:         <link rel="stylesheet" href="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER; ?>/GoogleMap/googleMap.css" type="text/css" media="screen"/>
146:         <?php
147:     }
148: 
149: }
150: 
151: 
152: require_once(SERVERPATH . '/' . ZENFOLDER . '/' . COMMON_FOLDER . '/jsMin/JSMin.php');
153: 
154: class CI_load {
155: 
156:     function library($library) {
157:         
158:         assert($library == 'jsmin');
159:     }
160: 
161: }
162: 
163: class CI_jsmin {
164: 
165:     function min($js) {
166:         return JSMin::minify($js);
167:     }
168: 
169: }
170: 
171: class codeIgniter_kludge { 
172: 
173:     var $load;
174:     var $jsmin;
175: 
176:     function __construct() {
177:         $this->load = new CI_load();
178:         $this->jsmin = new CI_jsmin();
179:     }
180: 
181: }
182: 
183: function log_message($class, $msg) {
184:     
185: }
186: 
187: function get_instance() {
188:     
189:     return new codeIgniter_kludge();
190: }
191: 
192: function omsAdditions() {
193:     
194:     return '';
195: }
196: 
197: 198: 199: 200: 
201: function getGeoCoord($image) {
202:     global $_zp_current_image;
203:     $result = false;
204:     if (isImageClass($image)) {
205:         $_zp_current_image = $image;
206:         $exif = $_zp_current_image->getMetaData();
207:         if ((!empty($exif['EXIFGPSLatitude'])) && (!empty($exif['EXIFGPSLongitude']))) {
208:             $lat_c = explode('.', str_replace(',', '.', $exif['EXIFGPSLatitude']) . '.0');
209:             $lat_f = round((float) abs($lat_c[0]) + ($lat_c[1] / pow(10, strlen($lat_c[1]))), 12);
210:             if (strtoupper(@$exif['EXIFGPSLatitudeRef']{0}) == 'S') {
211:                 $lat_f = -$lat_f;
212:             }
213: 
214:             $long_c = explode('.', str_replace(',', '.', $exif['EXIFGPSLongitude']) . '.0');
215:             $long_f = round((float) abs($long_c[0]) + ($long_c[1] / pow(10, strlen($long_c[1]))), 12);
216:             if (strtoupper(@$exif['EXIFGPSLongitudeRef']{0}) == 'W') {
217:                 $long_f = -$long_f;
218:             }
219: 
220:             $thumb = '<a href="javascript:image(\'' . $_zp_current_image->albumname . '\',\'' . $_zp_current_image->filename . '\');"><img src="' . getCustomImageURL(150, NULL, NULL, NULL, NULL, NULL, NULL, true) . '" /></a>';
221: 
222:             $result = array('lat' => $lat_f, 'long' => $long_f, 'title' => $_zp_current_image->getTitle(), 'desc' => $_zp_current_image->getDesc(), 'thumb' => $thumb);
223:         }
224:     }
225: 
226:     return $result;
227: }
228: 
229: 230: 231: 232: 233: 
234: function addGeoCoord($map, $coord) {
235:     global $_x, $_y, $_z, $_n;
236:     if ($coord) {
237:         $marker = array();
238: 
239:         $title = str_replace('/', '\/', str_replace('"', '\"', str_replace(array("\n", "\r"), "", html_encodeTagged($coord['title']))));
240:         $desc = str_replace('/', '\/', str_replace('"', '\"', str_replace(array("\n", "\r"), "", html_encodeTagged($coord['desc']))));
241:         $thumb = str_replace('/', '\/', str_replace('"', '\"', str_replace(array("\n", "\r"), "", html_encodeTagged($coord['thumb']))));
242:         if ($title <> '') {
243:             $title = '<h3 class="map_title">' . $title . '</h3>';
244:         }
245:         if ($desc <> '') {
246:             $desc = '<div class="map_desc">' . $desc . '</div>';
247:         }
248:         if ($coord['thumb'] <> '') {
249:             $thumb = '<p class="map_img">' . $coord['thumb'] . '</p>';
250:         }
251: 
252:         $marker['position'] = number_format($coord['lat'], 12, '.', '') . ", " . number_format($coord['long'], 12, '.', '');
253:         $marker['title'] = addslashes($coord['title']);
254:         $marker['infowindow_content'] = $title . $thumb . $desc;
255:         $map->add_marker($marker);
256:         $lat_f = $coord['lat'] * M_PI / 180;
257:         $long_f = $coord['long'] * M_PI / 180;
258:         $_x = $_x + cos($lat_f) * cos($long_f);
259:         $_y = $_y + cos($lat_f) * sin($long_f);
260:         $_z = $_z + sin($lat_f);
261:         $_n++;
262:     }
263: }
264: 
265: 266: 267: 268: 269: 
270: function getImageGeodata($image, $map) {
271:     $coord = getGeoCoord($image);
272:     if ($coord) {
273:         addGeoCoord($map, $coord);
274:     }
275:     return $coord;
276: }
277: 
278: 279: 280: 281: 282: 
283: function getAlbumGeodata($album, $map) {
284:     $result = false;
285:     $images = $album->getImages(0, 0, null, null, false);
286:     foreach ($images as $an_image) {
287:         $image = newImage($album, $an_image);
288:         $coord = getGeoCoord($image);
289:         if ($coord) {
290:             $result = true; 
291:             addGeoCoord($map, $coord);
292:         }
293:     }
294:     return $result;
295: }
296: 
297: 298: 299: 300: 301: 302: 303: 304: 305: 
306: function printGoogleMap($text = NULL, $id = NULL, $hide = NULL, $obj = NULL, $callback = NULL) {
307:     global $_zp_current_album, $_zp_current_image, $_x, $_y, $_z, $_n;
308: 
309:     
310:     if (is_null($obj)) {
311:         if (is_null($_zp_current_image)) {
312:             $obj = $_zp_current_album;
313:         } else {
314:             $obj = $_zp_current_image;
315:         }
316:     }
317:     if (is_null($obj)) {
318:         return false;
319:     }
320:     if (is_object($obj)) {
321:         $type = $obj->table;
322:         $typeid = $obj->getID();
323:     } else {
324:         $type = $obj;
325:         $typeid = '';
326:     }
327:     if (is_null($text)) {
328:         $text = gettext('Google Map');
329:     }
330:     if (empty($text)) {
331:         $hide = 'show';
332:     }
333:     if (is_null($hide)) {
334:         $hide = getOption('gmap_display');
335:     }
336:     if (!is_string($hide)) {
337:         if ($hide) {
338:             $hide = 'hide';
339:         } else {
340:             $hide = 'show';
341:         }
342:     }
343: 
344:     
345:     $mapControls = getOption('gmap_control_type');
346:     if ($mapControls == 'none') {
347:         $mapTypeControl = false;
348:     } else {
349:         $mapTypeControl = true;
350:         $map_control_type = $mapControls;
351: 
352:         $allowedMapTypes = array();
353:         if (getOption('gmap_map_hybrid'))
354:             $allowedMapTypes[] = 'HYBRID';
355:         if (getOption('gmap_map_roadmap'))
356:             $allowedMapTypes[] = 'ROADMAP';
357:         if (getOption('gmap_map_satellite'))
358:             $allowedMapTypes[] = 'SATELLITE';
359:         if (getOption('gmap_map_terrain'))
360:             $allowedMapTypes[] = 'TERRAIN';
361:     }
362: 
363:     $config['center'] = '0, 0';
364:     $config['zoom'] = 'auto';
365:     $config['cluster'] = true;
366:     $config['zoomControlStyle'] = getOption('gmap_zoom_size');
367:     if ($mapTypeControl) {
368:         $config['map_type'] = getOption('gmap_starting_map');
369:         $config['map_types_available'] = $allowedMapTypes;
370:     } else {
371:         $config['disableMapTypeControl'] = true;
372:     }
373:     $config['clusterMaxZoom'] = getOption('gmap_cluster_max_zoom');
374:     $config['clusterAverageCenter'] = true;
375:     $config['onclick'] = "iw.close();";
376:     $config['minifyJS'] = !TEST_RELEASE;
377:     $map = new Googlemaps($config);
378: 
379:     
380:     switch ($type) {
381:         case 'images':
382:             if (getImageGeodata($obj, $map)) {
383:                 break;
384:             } else {
385:                 $map = NULL;
386:                 return false;
387:             }
388:         case 'albums':
389:             if (getAlbumGeodata($obj, $map)) {
390:                 break;
391:             } else {
392:                 $map = NULL;
393:                 return false;
394:             }
395:         default:
396:             break;
397:     }
398: 
399:     if ($_n == 1)
400:         $map->zoom = 13;
401: 
402:     if ($_n) {
403:         $_x = $_x / $_n;
404:         $_y = $_y / $_n;
405:         $_z = $_z / $_n;
406:         $lon = number_format(atan2($_y, $_x) * 180 / M_PI, 12, '.', '');
407:         $hyp = sqrt($_x * $_x + $_y * $_y);
408:         $lat = number_format(atan2($_z, $hyp) * 180 / M_PI, 12, '.', '');
409:         $map->center = $lat . ', ' . $lon;
410:     }
411: 
412:     if (!is_null($callback)) {
413:         call_user_func($callback, $map);
414:     }
415: 
416:     
417:     if (is_null($id)) {
418:         $id = $type . $typeid . '_googlemap';
419:     }
420:     $id_toggle = $id . '_toggle';
421:     $id_data = $id . '_data';
422: 
423:     switch ($hide) {
424:         case 'show':
425:             $map->create_map();
426:             ?>
427:             <script type="text/javascript">
428:                 
429:             <?php
430:             echo $map->output_js_contents;
431:             echo omsAdditions();
432:             ?>
433: 
434:                 function image(album, image) {
435:                     window.location = '<?php echo WEBPATH ?>/index.php?album=' + album + '&image=' + image;
436:                 }
437:                 
438:             </script>
439:             <div id="<?php echo $id_data; ?>">
440:                 <?php echo $map->output_html; ?>
441:             </div>
442:             <?php
443:             break;
444:         case 'hide':
445:             $map->create_map();
446:             ?>
447:             <script type="text/javascript">
448:                 
449:             <?php
450:             echo $map->output_js_contents;
451:             echo omsAdditions();
452:             ?>
453: 
454:                 function image(album, image) {
455:                     window.location = '<?php echo WEBPATH ?>/index.php?album=' + album + '&image=' + image;
456:                 }
457: 
458:                 function toggle_<?php echo $id_data; ?>() {
459:                     if ($('#<?php echo $id_data; ?>').hasClass('hidden_map')) {
460:                         $('#<?php echo $id_data; ?>').removeClass('hidden_map');
461:                     } else {
462:                         $('#<?php echo $id_data; ?>').addClass('hidden_map');
463:                     }
464:                 }
465:                 
466:             </script>
467:             <a id="<?php echo $id_toggle; ?>" href="javascript:toggle_<?php echo $id_data; ?>();" title="<?php echo gettext('Display or hide the Google Map.'); ?>">
468:                 <?php echo $text; ?>
469:             </a>
470:             <div id="<?php echo $id_data; ?>" class="hidden_map">
471:                 <?php echo $map->output_html; ?>
472:             </div>
473:             <?php
474:             break;
475:         case 'colorbox':
476:             if (zp_has_filter('theme_head', 'colorbox::css')) {
477:                 $map->create_map();
478:                 $map_data["output_js_contents"] = $map->output_js_contents;
479:                 $map_data["output_html"] = $map->output_html;
480: 
481:                 if (getOption('gmap_sessions')) {
482:                     $param = '';
483:                     $_SESSION['GoogleMapVars'] = $map_data;
484:                 } else {
485:                     $serializedData = serialize($map_data);
486:                     if (function_exists('bzcompress')) {
487:                         $data = bzcompress($serializedData);
488:                     } else {
489:                         $data = gzcompress($serializedData);
490:                     }
491:                     $param = '?map_data=' . base64_encode($data);
492:                 }
493:                 ?>
494:                 <a href="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/GoogleMap/Map.php' . $param ?>" title="<?php echo $text; ?>" class="google_map">
495:                     <?php echo $text; ?>
496:                 </a>
497:                 <script type="text/javascript">
498:                     
499:                     $(document).ready(function() {
500:                         $(".google_map").colorbox({
501:                             iframe: true,
502:                             innerWidth: $(window).width() * 0.8,
503:                             innerHeight: $(window).height() * 0.7,
504:                             close: '<?php echo gettext("close"); ?>',
505:                             onComplete: function() {
506:                                 parent.resizeColorBoxMap();$(window).resize(resizeColorBoxMap);
507:                             }
508:                         });
509:                     });
510:                     
511:                 </script>
512:                 <?php
513:             }
514:             break;
515:     }
516: }
517: ?>