additional_plugins/serendipity_event_geotag/serendipity_plugin_geotag.php

469 lines
17 KiB
PHP

<?php
// 20050923 Zoran Kovacevic (http://www.kovacevic.nl/blog).
// The plugin is a shameless copy from Rob Antonishen (http://ffaat.pointclark.net/).
// The GMap javascript code is a shameless copy from Mikel Maron (http://brainoff.com/gmaps/rss.html).
// Wishlist
// - generate KML file to provide a fly-over in Google Earth
// http://www.keyhole.com/kml/kml_doc.html
// or use the Network Links option ..
// - link to larger google map
if (IN_serendipity !== true) {
die ("Don't hack!");
}
@serendipity_plugin_api::load_language(dirname(__FILE__));
include_once dirname(__FILE__) . '/plugin_version.inc.php';
class serendipity_plugin_geotag extends serendipity_plugin {
function introspect(&$propbag) {
$propbag->add('name', PLUGIN_GEOTAG_GMAP_NAME);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_NAME_DESC);
$propbag->add('author', PLUGIN_EVENT_GEOTAG_AUTHOR);
$propbag->add('stackable', false);
$propbag->add('version', PLUGIN_EVENT_GEOTAG_VERSION);
$propbag->add('configuration', array('title','service','key','width','height','latitude','longitude','zoom','type','rss_url','geodata_source','category'));
$propbag->add('requirements', array(
'serendipity' => '0.9',
'smarty' => '2.6.7',
'php' => '4.1.0'
));
$propbag->add('groups', array('FRONTEND_EXTERNAL_SERVICES'));
}
function introspect_config_item($name, &$propbag) {
global $serendipity;
switch($name) {
case 'title':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_GEOTAG_GMAP_TITLE);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_TITLE_DESC);
$propbag->add('default', PLUGIN_GEOTAG_GMAP_TITLE_DEFAULT);
break;
case 'service':
$propbag->add('type', 'select');
$propbag->add('select_values', array(
'google' => 'Google Maps',
'osm' => 'Openstreetmap',
));
$propbag->add('name', PLUGIN_GEOTAG_SERVICE);
$propbag->add('description', PLUGIN_GEOTAG_SERVICE_DESC);
$propbag->add('default', 'google');
break;
case 'key':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_GEOTAG_GMAP_KEY);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_KEY_DESC.' ('.$serendipity['baseURL'].')');
$propbag->add('default', 'XXXYYYZZZ');
break;
case 'width':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_GEOTAG_GMAP_WIDTH);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_WIDTH_DESC);
$propbag->add('default', 220);
break;
case 'height':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_GEOTAG_GMAP_HEIGHT);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_HEIGHT_DESC);
$propbag->add('default', 150);
break;
case 'latitude':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_GEOTAG_GMAP_LATITUDE);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_LATITUDE_DESC);
$propbag->add('default', 0);
break;
case 'longitude':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_GEOTAG_GMAP_LONGITUDE);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_LONGITUDE_DESC);
$propbag->add('default', 0);
break;
case 'zoom':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_GEOTAG_GMAP_ZOOM);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_ZOOM_DESC);
$propbag->add('default', 1);
break;
case 'type':
$propbag->add('type', 'select');
$propbag->add('name', PLUGIN_GEOTAG_GMAP_TYPE);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_TYPE_DESC);
$propbag->add('default', 'G_HYBRID_MAP');
$propbag->add('select_values', array(
'SATELLITE'=>PLUGIN_GEOTAG_GMAP_SATELLITE,
'ROADMAP'=>PLUGIN_GEOTAG_GMAP_MAP,
'HYBRID'=>PLUGIN_GEOTAG_GMAP_HYBRID,
'TERRAIN'=>PLUGIN_GEOTAG_GMAP_TERRAIN
));
break;
case 'rss_url':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_GEOTAG_GMAP_RSSURL);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_RSSURL_DESC.' ('.$serendipity['baseURL'].'feeds/index.rss2?all=1)');
$propbag->add('default', $serendipity['baseURL'].'rss.php');
break;
case 'geodata_source':
$propbag->add('type', 'select');
$propbag->add('select_values', array('database' => PLUGIN_GEOTAG_GMAP_DATABASE,
'rss' => 'RSS'));
$propbag->add('name', PLUGIN_GEOTAG_GMAP_GEODATA_SOURCE);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_GEODATA_SOURCE_DESC);
$propbag->add('default', 'database');
break;
case 'category':
$cat = serendipity_fetchCategories();
$cat_array = array();
$cat_array[0] = ALL_CATEGORIES;
if (is_array($cat)) {
foreach ($cat as $c) {
$cat_array[$c['categoryid']] = $c['category_name'];
}
}
$propbag->add('type', 'select');
$propbag->add('select_values', $cat_array);
$propbag->add('name', CATEGORY);
$propbag->add('description', PLUGIN_GEOTAG_GMAP_CATEGORY_DESC);
$propbag->add('default', '0');
break;
default:
return false;
}
return true;
}
function generate_content(&$title) {
global $serendipity;
//get config vars
$title = $this->get_config('title');
$service = $this->get_config('service');
$key = trim($this->get_config('key'));
$width = $this->get_config('width', 220);
$height = $this->get_config('height', 150);
$longitude = $this->get_config('longitude', 0);
$latitude = $this->get_config('latitude', 0);
$zoom = $this->get_config('zoom', 1);
$type = $this->get_config('type');
$rss_url = $this->get_config('rss_url');
$geodata_source = $this->get_config('geodata_source', 'rss');
$category = $this->get_config('category');
if (!is_numeric($width)) {
$width = 220;
} else {
$width = (int)$width;
}
if (!is_numeric($height)) {
$height = 150;
} else {
$height = (int)$height;
}
if (!is_numeric($longitude)) {
$longitude = 0;
} else {
$longitude = (float)$longitude;
}
if (!is_numeric($latitude)) {
$latitude = 0;
} else {
$latitude = (float)$latitude;
}
if (!is_numeric($zoom)) {
$zoom = 2;
} else {
$zoom = min(max((int)$zoom, 0), $service === 'google' ? 21 : 18);
}
if ($geodata_source == 'database') {
if ($category == 0) {
$cat_query = "";
$cat_join = "";
} else {
$cat_query = "AND categoryid = $category";
$cat_join = "LEFT JOIN {$serendipity['dbPrefix']}entrycat as c ON (c.entryid = id)";
}
$q = "SELECT id, title, e1.value as lng, e2.value as lat, permalink
FROM {$serendipity['dbPrefix']}entries
LEFT JOIN {$serendipity['dbPrefix']}entryproperties as e1 ON (e1.entryid = id AND e1.property='geo_long')
LEFT JOIN {$serendipity['dbPrefix']}entryproperties as e2 ON (e2.entryid = id AND e2.property='geo_lat')
LEFT JOIN {$serendipity['dbPrefix']}permalinks ON (entry_id = id AND type='entry')
$cat_join
WHERE e1.property='geo_long' AND e2.property='geo_lat' $cat_query";
$tt = serendipity_db_query($q);
if (!is_array($tt)) {
$tt = array();
}
}
?>
<div id="serendipity_geotag_map" style="width: <?php echo $width ?>px; height: <?php echo $height ?>px"></div>
<?php
if ($geodata_source != 'database') { ?>
<script type="text/javascript ">
(function () {
getMarkerOptions = function (item) {
var title = item.getElementsByTagName("title")[0].childNodes[0].nodeValue,
link = item.getElementsByTagName("link")[0].childNodes[0].nodeValue,
lat,
lng;
if (navigator.userAgent.toLowerCase().indexOf("msie") < 0) {
if (item.getElementsByTagNameNS("http://www.w3.org/2003/01/geo/wgs84_pos#", "lat").length > 0) {
item.getElementsByTagNameNS("http://www.w3.org/2003/01/geo/wgs84_pos#", "lat")[0].normalize();
// Is there a value for geo:lat
if (item.getElementsByTagNameNS("http://www.w3.org/2003/01/geo/wgs84_pos#", "lat")[0].hasChildNodes()) {
// Then there probably is a geo:long too
lat = item.getElementsByTagNameNS("http://www.w3.org/2003/01/geo/wgs84_pos#", "lat")[0].childNodes[0].nodeValue;
lng = item.getElementsByTagNameNS("http://www.w3.org/2003/01/geo/wgs84_pos#", "long")[0].childNodes[0].nodeValue;
}
}
} else {
lat = item.getElementsByTagName("geo:lat")[0].childNodes[0].nodeValue;
if (lat === undefined) {
lat = item.getElementsByTagName("icbm:lat")[0].childNodes[0].nodeValue;
}
lng = item.getElementsByTagName("geo:long")[0].childNodes[0].nodeValue;
if (lng === undefined) {
lng = item.getElementsByTagName("icbm:long")[0].childNodes[0].nodeValue;
}
}
return {
lat: lat,
lng: lng,
title: title,
url: link
};
};
})();
</script>
<?php
}
/***************
* GOOGLE MAPS *
**************/
if ($service === 'google') { ?>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=<?php echo $key;?>&sensor=false"></script>
<script type="text/javascript">
//<![CDATA[
(function () {
var latlng = new google.maps.LatLng(<?php echo $latitude ?>, <?php echo $longitude ?>),
myOptions = {
zoom: <?php echo $zoom; ?>,
center: latlng,
mapTypeId: google.maps.MapTypeId.<?php echo $type; ?>,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
}
},
map = new google.maps.Map(document.getElementById("serendipity_geotag_map"), myOptions);
setMarker = function (item) {
var marker = new google.maps.Marker(
{
position: new google.maps.LatLng(item.lat, item.lng),
map: map,
title: item.title,
icon: new google.maps.MarkerImage('<?php echo $serendipity['baseURL'] ?>plugins/serendipity_event_geotag/marker_r.png'),
shadow: new google.maps.MarkerImage('<?php echo $serendipity['baseURL'] ?>plugins/serendipity_event_geotag/marker_s.png')
}
);
var infoWindow = new google.maps.InfoWindow(
{
content: '<a href="' + item.url + '">' + item.title + '</a>'
}
);
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open(map, marker);
});
};
})();
<?php
if ($geodata_source == 'database') {
foreach ($tt as $t) { ?>
setMarker({
lat: <?php echo $t['lat']; ?>,
lng: <?php echo $t['lng']; ?>,
title: '<?php echo $t['title']; ?>',
url: '<?php echo $t['permalink']; ?>'
});
<?php }
} else { ?>
var rss_url = "<?php echo $rss_url; ?>";
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
var xmlDoc = xmlhttp.responseXML,
items = xmlDoc.documentElement.getElementsByTagName('item');
for (var i = 0; i < items.length; i++) {
var item = items[i];
try {
setMarker(getMarkerOptions(item));
} catch (e) {
console.log(e);
}
}
}
};
xmlhttp.open('GET', rss_url, true);
xmlhttp.send(null);
<?php
}
?>
//]]>
</script>
<?php
/*****************
* OPENSTREETMAP *
****************/
} elseif ($service === 'osm') {
?>
<script src="//openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
(function () {
createPopup = function (evt) {
var popup = new OpenLayers.Popup.FramedCloud(
null,
this.marker.lonlat,
null,
'<a href="' + urls[this.id] + '">' + titles[this.id] + '</a>',
null,
true,
null
);
map.addPopup(popup, true);
OpenLayers.Event.stop(evt);
};
setMarkerOsm = function (mOpt, i) {
var myMarker = new OpenLayers.Marker(
new OpenLayers.LonLat(mOpt.lng, mOpt.lat).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
),
(i === 0) ? icon : icon.clone()
);
titles.push(mOpt.title);
urls.push(mOpt.url);
myMarker.events.register('mousedown', myMarker, function (evt) {
var popup = new OpenLayers.Popup.FramedCloud(
null,
myMarker.lonlat,
null,
"<a href='" + mOpt.url + "'>" + mOpt.title + "</a> ",
null,
true,
null
);
map.addPopup(popup);
OpenLayers.Event.stop(evt);
});
markerCollection.addMarker(myMarker);
};
})();
var map = new OpenLayers.Map("serendipity_geotag_map");
map.addLayer(new OpenLayers.Layer.OSM());
var lonLat = new OpenLayers.LonLat(<?php echo $longitude; ?>, <?php echo $latitude; ?>).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
);
var zoom = <?php echo $zoom; ?>,
markerCollection = new OpenLayers.Layer.Markers("Markers");
var attribution = document.getElementsByClassName('olControlAttribution'),
attr = attribution[0],
size = new OpenLayers.Size(10, 10),
offset = new OpenLayers.Pixel(-(size.w / 2), -size.h),
icon = new OpenLayers.Icon('<?php echo $serendipity['baseURL'] ?>plugins/serendipity_event_geotag/marker_r.png', size, offset),
titles = [],
urls = [];
attr.setAttribute('style', 'position: absolute; z-index: 1004; bottom: 0;');
map.addLayer(markerCollection);
map.setCenter(lonLat, zoom);
<?php
if ($geodata_source === 'database') {
$counter = 0;
foreach ($tt as $t) { ?>
titles.push('<?php echo addslashes($t['title']); ?>');
urls.push('<?php echo $t['permalink']; ?>');
setMarkerOsm(
{
lat: <?php echo $t['lat']; ?>,
lng: <?php echo $t['lng']; ?>,
title: '<?php echo addslashes($t['title']); ?>',
url: '<?php echo $t['permalink']; ?>'
},
null
);
<?php
$counter++;
}
} else { ?>
var rss_url = "<?php echo $rss_url; ?>",
popup,
m;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
var xmlDoc = xmlhttp.responseXML,
items = xmlDoc.documentElement.getElementsByTagName('item'),
item;
for (var i = 0; i < items.length; i++) {
item = items[i];
try {
setMarkerOsm(getMarkerOptions(item), i);
} catch (e) {
console.log(e);
}
}
}
};
xmlhttp.open('GET', rss_url, true);
xmlhttp.send(null);
<?php
} // END database || RSS
?>
</script>
<?php
}
}
}