#------------------------------------------------------------------------------- # # Copyright (c) 2007 HighEarthOrbit # # This file is part of the GeoPress # http://georss.org/geopress # # Author : Andrew Turner # Version : 1 # Location : # # Abstract : # # A MovableType plugin to enable adding geographic data (points,lines,areas) to # blog posts, adding maps, outputing GeoRSS and KML feeds # # # Copyright notice: # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # #------------------------------------------------------------------------------- # package MT::Plugin::GeoPress; use strict; use base qw(MT::Plugin); use MT; use GeoPress::Location; use GeoPress::EntryLocation; if ( MT->version_number < 4.0 ) { die 'This plugin only works with Movable Type 4.0 or higher.'; } # @MT::Plugin::GeoPress::ISA = qw(MT::Plugin); use vars qw( $VERSION ); $VERSION = 1.03; my $plugin = new MT::Plugin::GeoPress({ id => "GeoPress", name => "GeoPress", key => "GeoPress", version => $VERSION, description => "GeoPress settings are on a per-blog setting, so you'll need to set this up in each weblog you administer. Use the 'GeoPress' link in the left sidebar under 'Utilities' to configure your Map defaults and Locations.\">", author_name => "Andrew Turner", author_link => "http://highearthorbit.com/", plugin_link => "http://georss.org/geopress/", doc_link => "http://georss.org/geopress/", config_template => 'config.tmpl', schema_version => 1.03, settings => new MT::PluginSettings([ ['google_api_key', {Default => 'GOOGLE_API_KEY', Scope => 'system'}], ['yahoo_api_key', {Default => 'YAHOO_API_KEY', Scope => 'system'}], ['microsoft_map', {Default => 0, Scope => 'system'}], ['georss_format', {Default => 'simple', Scope => 'system'}], ['georss_enable', {Default => 1, Scope => 'system'}], ['default_add_map', {Default => 'all', Scope => 'system'}], ['google_api_key', {Default => 'GOOGLE_API_KEY', Scope => 'blog'}], ['yahoo_api_key', {Default => 'YAHOO_API_KEY', Scope => 'blog'}], ['microsoft_map', {Default => 0, Scope => 'blog'}], ['georss_format', {Default => 'simple', Scope => 'blog'}], ['georss_enable', {Default => 1, Scope => 'blog'}], ['map_width', {Default => '400', Scope => 'blog'}], ['map_height', {Default => '200', Scope => 'blog'}], ['default_map_format', {Default => 'google', Scope => 'blog'}], ['default_map_type', {Default => 'HYBRID', Scope => 'blog'}], ['map_controls_pan', {Default => 1, Scope => 'blog'}], ['map_controls_map_type', {Default => 1, Scope => 'blog'}], ['map_controls_zoom', {Default => "small", Scope => 'blog'}], ['map_controls_overview', {Default => 0, Scope => 'blog'}], ['map_controls_scale', {Default => 1, Scope => 'blog'}], ['default_add_map', {Default => 'all', Scope => 'blog'}], ['default_zoom_level', {Default => 11, Scope => 'blog'}], ]), app_action_links => { 'MT::App::CMS' => { # application the action applies to 'blog' => { link => 'geopress.cgi', link_text => 'Edit GeoPress Locations' }, } } }); MT->add_plugin($plugin); sub init_registry { my $plugin = shift; $plugin->registry({ applications => { cms => { menus => { 'view:location' => { label => 'View Locations', mode => 'view_locations', order => 301, args => { _type => "blog" }, permission => 'manage_assets,publish_post', view => "blog", }, }, }, }, object_types => { 'geopress_location' => 'GeoPress::Location', 'geopress_entrylocation' => 'GeoPress::EntryLocation' }, tags => { function => { 'GeoPressCoords' => sub { $plugin->entry_coords(@_); }, 'GeoPressLocation' => sub { $plugin->entry_location(@_); }, 'GeoPressName' => sub { $plugin->entry_name(@_); }, 'GeoPressMap' => sub { $plugin->entry_map(@_); }, 'GeoPressHeader' =>\&_geopress_headers, 'GeoRSS_Namespace' =>\&_geopress_georss_ns, 'GeoRSS_Channel' =>\&_geopress_georss_channel, 'GeoRSS_Entry' =>\&_geopress_georss_entry, 'GeoRSS_Channel' =>\&_geopress_georss_channel, 'KML_Document' =>\&_geopress_kml_document, 'KML_Entry' =>\&_geopress_kml_entry } }, callbacks => { 'MT::App::CMS::template_param.edit_entry' => sub { $plugin->_edit_entry(@_); }, }, }); } # sub instance { $plugin; } # Callback to actually store the specified location to the database. MT->add_callback("MT::Entry::post_save", 5, $plugin, \&GeoPress::Location::save_location); # Adds the utilities sidebar link to configure geopress MT->add_callback("AppTemplateSource.blog-left-nav", 10, $plugin, \&left_nav); sub left_nav { my ($eh, $app, $tmpl) = @_; my $slug = <class="here" id="nav-mmanager" title="" href="plugins/GeoPress/geopress.cgi?__mode=view&blog_id="> END_TMPL $$tmpl =~ s/(
  • \n
      )/$1$slug/; } # # Get a named template from the tmpl directory - from MTMaps # use HTML::Template; use Cwd; my $cwd = ''; { my($bad); local $SIG{__WARN__} = sub { $bad++ }; eval { $cwd = Cwd::getcwd() }; if ($bad || $@) { eval { $cwd = Cwd::cwd() }; if ($@ && $@ !~ /Insecure \$ENV{PATH}/) { die $@; } } } sub pluginDir() { return $cwd."/plugins/GeoPress"; } sub getTemplate { my ($t) = @_; my $file = pluginDir()."/tmpl/".$t; return HTML::Template->new(filename => $file); } # Creates an actual map for an entry sub entry_map { my $ctx = shift; my ($ctx, $args, $cond) = @_; my $entry = $ctx->stash('entry'); my $blog_id = $ctx->stash('blog_id'); my $location = GeoPress::Location::get_location_for_entry($entry); my $config = $plugin->get_config_hash('blog:' . $blog_id); my $width = $args->{width} ? $args->{width} : $config->{map_width}; my $height = $args->{height} ? $args->{height} : $config->{map_height}; if ($location && $location->geometry && $location->geometry ne '') { my $tmpl = getTemplate("map.tmpl"); $tmpl->param(default_map_format => $config->{default_map_format}); $tmpl->param(map_width => $width); $tmpl->param(map_height => $height); $tmpl->param(geometry => $location->geometry); $tmpl->param(location_name => $location->name); $tmpl->param(map_id => $entry->id); return $tmpl->output; } return ""; } sub _geopress_georss_ns { my $ctx = shift; use MT::App; my $blog_id = $ctx->stash('blog_id'); my $config = $plugin->get_config_hash('blog:' . $blog_id); my $georss_enable = $config->{georss_enable}; if( ! $georss_enable ) { return ""; } # my $georss_format = $config->{georss_format}; if($georss_format eq "simple") { return qq{ xmlns:georss="http://www.georss.org/georss"}; } elsif ($georss_format eq "gml") { return qq{ xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml"}; } elsif ($georss_format eq "w3c") { return qq{ xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"}; } else { return qq{ xmlns:georss="http://www.georss.org/georss"}; } } sub _geopress_kml_document { my $ctx = shift; use MT::App; my $blog_id = $ctx->stash('blog_id'); my $config = $plugin->get_config_hash('blog:' . $blog_id); # TODO: finish KML document metadata - bbox of entire blog return ""; } sub _geopress_georss_channel { my $ctx = shift; use MT::App; my $blog_id = $ctx->stash('blog_id'); my $config = $plugin->get_config_hash('blog:' . $blog_id); my $georss_format = $config->{georss_format}; my $georss_enable = $config->{georss_enable}; if( ! $georss_enable ) { return ""; } return ""; } sub _geopress_kml_entry { my $ctx = shift; use MT::App; my $entry = $ctx->stash('entry'); my $blog_id = $ctx->stash('blog_id'); my $location = GeoPress::Location::get_location_for_entry($entry); my $config = $plugin->get_config_hash('blog:' . $blog_id); my $geometry = $location->geometry; if( !$geometry && $geometry ne "20, -20"){ return ""; } my @coords = split(/,/, $geometry); my $kml_entry = qq{@coords[1],@coords[0]}; return $kml_entry; } sub entry_coords { my $ctx = shift; my ($ctx, $args, $cond) = @_; my $entry = $ctx->stash('entry'); my $blog_id = $ctx->stash('blog_id'); my $location = GeoPress::Location::get_location_for_entry($entry); if ($location && $location->geometry && $location->geometry ne '') { return $location->geometry; } return ""; } sub entry_name { my $ctx = shift; my ($ctx, $args, $cond) = @_; my $entry = $ctx->stash('entry'); my $blog_id = $ctx->stash('blog_id'); my $location = GeoPress::Location::get_location_for_entry($entry); if ($location && $location->name && $location->name ne '') { return $location->name; } return ""; } sub entry_location { my $ctx = shift; my ($ctx, $args, $cond) = @_; my $entry = $ctx->stash('entry'); my $blog_id = $ctx->stash('blog_id'); my $location = GeoPress::Location::get_location_for_entry($entry); if ($location && $location->location && $location->location ne '') { return $location->location; } return ""; } sub _geopress_georss_entry { my $ctx = shift; use MT::App; my $entry = $ctx->stash('entry'); my $blog_id = $ctx->stash('blog_id'); my $location = GeoPress::Location::get_location_for_entry($entry); my $config = $plugin->get_config_hash('blog:' . $blog_id); my $georss_enable = $config->{georss_enable}; if( ! $georss_enable ) { return ""; } my $georss_format = $config->{georss_format}; my $georss_entry = ""; my $geometry = $location->geometry; if( !$geometry && $geometry ne "20, -20"){ return ""; } if ($georss_format eq "gml") { $georss_entry =< $geometry XML } elsif ($georss_format eq "w3c") { my @coords = split(/,/, $geometry); $georss_entry = qq{@coords[0]@coords[1]}; } else { #$georss_format eq "simple" $georss_entry = qq{$geometry}; } return $georss_entry; } # Tag to add the necessary mapping headers #TODO - figure out how to have this get included automatically sub _geopress_headers { my $ctx = shift; my $blog_id; my $config; if(defined $ctx) { $blog_id = $ctx->stash('blog_id'); $config = $plugin->get_config_hash('blog:' . $blog_id); } else { # We're in the admin interface, get things differently use MT::App; my $app = MT::App->instance; $blog_id = $app->blog->id; $config = $plugin->get_config_hash('system'); } my $tmpl = getTemplate("geopress_header.tmpl"); use MT::App; my $app = MT::App->instance; my $apppath = $app->{__path} || ""; my $spath = $app->{cfg}->StaticWebPath || $apppath; $tmpl->param(static_uri => $spath); $tmpl->param(geopress_version => $VERSION); # Build up the keys my $google_api_key = $config->{google_api_key}; if($google_api_key) { $tmpl->param(google_api_key => $google_api_key); } my $yahoo_api_key = $config->{yahoo_api_key}; if($yahoo_api_key) {$tmpl->param(yahoo_api_key => $yahoo_api_key); } my $microsoft_map = $config->{microsoft_map}; if($microsoft_map) {$tmpl->param(microsoft_map => $microsoft_map); } $tmpl->output; } # Creates the Edit form when writing an entry sub _edit_entry { my $plugin = shift; my ($cb, $app, $param, $tmpl) = @_; my $blog = $app->blog; my $system_config = $plugin->get_config_hash('system'); my $config = $plugin->get_config_hash('blog:' . $blog->id); my $google_api_key = $system_config->{google_api_key}; my $yahoo_api_key = $system_config->{yahoo_api_key}; my $microsoft_map = $system_config->{microsoft_map}; my ($old, $new); $old = qq{}; $old = quotemeta($old); if($google_api_key ne "GOOGLE_API_KEY" || $yahoo_api_key ne "YAHOO_API_KEY" || $microsoft_map ne 0) { my $entry_id = $app->{query}->param('id'); my $entrylocation = GeoPress::EntryLocation->get_by_key({entry_id => $entry_id}); my $location = GeoPress::Location->get_by_key({ id => $entrylocation->location_id }); my $location_name = $location->name; my $location_addr = $location->location; my $location_geometry = $location->geometry; my $header = _geopress_headers; my $tmpl = getTemplate("geopress_edit.tmpl"); my $saved_locations = ""; my @locations = GeoPress::Location->load({ blog_id => $blog->id }); foreach $location(@locations) { if( $location->visible) { $saved_locations = $saved_locations . ""; # $saved_locations = $saved_locations . qq{}; } } if( !$location_geometry) { $tmpl->param(new_location => 1); # $location_geometry = "20, -20"; } else { } $tmpl->param(saved_locations => $saved_locations); $tmpl->param(location_addr => $location_addr); $tmpl->param(location_name => $location_name); $tmpl->param(location_geometry => $location_geometry); $new = $header.($tmpl->output); } else { $new = "To Enable GeoPress, add the appropriate mapping library keys in your settings."; } # Get our marker my $basename_field = $tmpl->getElementById('keywords'); # Create our element my $setting = $tmpl->createElement('app:setting', { id => 'geopress_location', label => '<__trans phrase="Location">'}); $setting->innerHTML($new); # Attach our element in the DOM before basename $tmpl->insertAfter($setting, $basename_field); 1; } 1;