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