diff --git a/lib/WebGUI/Asset/MapPoint.pm b/lib/WebGUI/Asset/MapPoint.pm new file mode 100644 index 000000000..d8ccb8f33 --- /dev/null +++ b/lib/WebGUI/Asset/MapPoint.pm @@ -0,0 +1,402 @@ +package WebGUI::Asset::MapPoint; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2009 Plain Black Corporation. + ------------------------------------------------------------------- + Please read the legal notices (docs/legal.txt) and the license + (docs/license.txt) that came with this distribution before using + this software. + ------------------------------------------------------------------- + http://www.plainblack.com info@plainblack.com + ------------------------------------------------------------------- + +=cut + +use strict; +use Tie::IxHash; +use base 'WebGUI::AssetAspect::Installable','WebGUI::Asset'; +use WebGUI::Utility; + +# To get an installer for your wobject, add the Installable AssetAspect +# See WebGUI::AssetAspect::Installable and sbin/installClass.pl for more +# details + +=head1 NAME + +Package WebGUI::Asset::MapPoint + +=head1 DESCRIPTION + +Describe your New Asset's functionality and features here. + +=head1 SYNOPSIS + +use WebGUI::Asset::MapPoint; + + +=head1 METHODS + +These methods are available from this class: + +=cut + +#------------------------------------------------------------------- + +=head2 definition ( session, definition ) + +defines asset properties for New Asset instances. You absolutely need +this method in your new Assets. + +=head3 session + +=head3 definition + +A hash reference passed in from a subclass definition. + +=cut + +sub definition { + my $class = shift; + my $session = shift; + my $definition = shift; + my $i18n = WebGUI::International->new( $session, "Asset_MapPoint" ); + tie my %properties, 'Tie::IxHash', ( + latitude => { + tab => "properties", + fieldType => "float", + label => $i18n->echo("Latitude"), + hoverHelp => $i18n->echo("The latitude of the point"), + noFormPost => 1, + }, + longitude => { + tab => "properties", + fieldType => "float", + label => $i18n->echo("Longitude"), + hoverHelp => $i18n->echo("The longitude of the point"), + noFormPost => 1, + }, + website => { + tab => "properties", + fieldType => "text", + label => $i18n->echo("Website"), + hoverHelp => $i18n->echo("The URL to the location's website"), + }, + address1 => { + tab => "properties", + fieldType => "text", + label => $i18n->echo("Address 1"), + hoverHelp => $i18n->echo("The first line of the address"), + }, + address2 => { + tab => "properties", + fieldType => "text", + label => $i18n->echo("Address 2"), + hoverHelp => $i18n->echo("The second line of the address"), + }, + city => { + tab => "properties", + fieldType => "text", + label => $i18n->echo("City"), + hoverHelp => $i18n->echo("The city the point is located in"), + }, + state => { + tab => "properties", + fieldType => "text", + label => $i18n->echo("State/Province"), + hoverHelp => $i18n->echo("The state/provice the point is located in"), + }, + zipCode => { + tab => "properties", + fieldType => "text", + label => $i18n->echo("Zip/Postal Code"), + hoverHelp => $i18n->echo("The zip/postal code the point is located in"), + }, + country => { + tab => "properties", + fieldType => "country", + label => $i18n->echo("Country"), + hoverHelp => $i18n->echo("The country the point is located in"), + }, + phone => { + tab => "properties", + fieldType => "phone", + label => $i18n->echo("Phone"), + hoverHelp => $i18n->echo("The phone number of the location"), + }, + fax => { + tab => "properties", + fieldType => "phone", + label => $i18n->echo("Fax"), + hoverHelp => $i18n->echo("The fax number of the location"), + }, + email => { + tab => "properties", + fieldType => "email", + label => $i18n->echo("E-mail"), + hoverHelp => $i18n->echo("The e-mail address of the location"), + }, + storageIdPhoto => { + tab => "properties", + fieldType => "image", + forceImageOnly => 1, + label => $i18n->echo("Photo"), + hoverHelp => $i18n->echo("A photo of the location"), + noFormPost => 1, + }, + userDefined1 => { + fieldType => "hidden", + }, + userDefined2 => { + fieldType => "hidden", + }, + userDefined3 => { + fieldType => "hidden", + }, + userDefined4 => { + fieldType => "hidden", + }, + userDefined5 => { + fieldType => "hidden", + }, + ); + push @{$definition}, { + assetName => $i18n->get('assetName'), + icon => 'MapPoint.gif', + autoGenerateForms => 1, + tableName => 'MapPoint', + className => 'WebGUI::Asset::MapPoint', + properties => \%properties, + }; + return $class->SUPER::definition( $session, $definition ); +} ## end sub definition + +#------------------------------------------------------------------- + +=head2 canEdit ( [userId] ) + +Returns true if the user can edit this MapPoint. Only the owner or the +group to edit the parent Map are allowed to edit MapPoint. + +=cut + +sub canEdit { + my $self = shift; + my $userId = shift || $self->session->user->userId; + return 1 if $userId eq $self->get('ownerUserId'); + return $self->SUPER::canEdit( $userId ); +} + +#------------------------------------------------------------------- + +=head2 getMapInfo ( ) + +Get a hash of info to be put into the parent Map. Must include +AT LEAST the following keys: + + assetId - The ID of the MapPoint + latitude - The latitude of the point + longitude - The longitude of the point + title - The title of the point + content - HTML content to show details about the point + url - The URL of the point + +The following keys are optional + + canEdit - If true, the user is allowed to edit the MapPoint + + +=cut + +sub getMapInfo { + my $self = shift; + my $var = {}; + + # Get asset properties + $var->{ url } = $self->getUrl; + $var->{ assetId } = $self->getId; + my @keys = qw( latitude longitude title ); + for my $key ( @keys ) { + $var->{ $key } = $self->get( $key ); + } + + # Get permissions + $var->{ canEdit } = $self->canEdit; + + # Process the template to get the content + my $template = $self->getParent->getViewPointTemplate; + $var->{ content } = $template->process( $self->getTemplateVars ); + WebGUI::Macro::process( $self->session, \$var->{content} ); + + return $var; +} + +#------------------------------------------------------------------- + +=head2 getTemplateVars ( ) + +Get common template vars for this MapPoint + +=cut + +sub getTemplateVars { + my $self = shift; + my $var = $self->get; + + # Add gateway to URL + $var->{ url } = $self->getUrl; + + return $var; +} + +#------------------------------------------------------------------- + +=head2 getTemplateVarsEditForm ( ) + +Get the template vars for the MapPoint edit form + +=cut + +sub getTemplateVarsEditForm { + my $self = shift; + my $session = $self->session; + my $var = $self->getTemplateVars; + + $var->{ form_header } + = WebGUI::Form::formHeader( $session ) + . WebGUI::Form::hidden( $session, { + name => 'func', + value => 'ajaxEditPointSave', + } ) + . WebGUI::Form::hidden( $session, { + name => 'assetId', + value => $self->getId, + defaultValue => 'new', + } ) + ; + $var->{ form_footer } = WebGUI::Form::formFooter( $session ); + + # Stuff from this class's definition + my $definition = __PACKAGE__->definition($session)->[0]->{properties}; + for my $key ( keys %{$definition} ) { + next if $definition->{$key}->{noFormPost}; + $definition->{$key}->{name} = $key; + $definition->{$key}->{value} = $self->getValue($key); + $var->{ "form_$key" } + = WebGUI::Form::dynamicField( $session, %{$definition->{$key}} ); + } + + # Stuff from Asset + $var->{ "form_title" } + = WebGUI::Form::text( $session, { + name => "title", + value => $self->get("title"), + } ); + $var->{ "form_synopsis" } + = WebGUI::Form::textarea( $session, { + name => "synopsis", + value => $self->get("synopsis"), + resizable => 0, + } ); + + # Fix storageIdPhoto because scripts do not get executed in ajax requests + $var->{ "form_storageIdPhoto" } + = ''; + if ( $self->get('storageIdPhoto') ) { + my $storage = WebGUI::Storage->get( $self->session, $self->get('storageIdPhoto') ); + $var->{ "currentPhoto" } + = sprintf '', $storage->getUrl($storage->getFiles->[0]); + } + + return $var; +} + +#------------------------------------------------------------------- + +=head2 processAjaxEditForm ( ) + +Process the Ajax Edit Form from the Map. If any errors occur, return +an array reference of error messages. + +=cut + +sub processAjaxEditForm { + my $self = shift; + my $session = $self->session; + my $form = $self->session->form; + my $prop = {}; + + # Stuff from this class's definition + my $definition = __PACKAGE__->definition($session)->[0]->{properties}; + for my $key ( keys %{$definition} ) { + my $field = $definition->{$key}; + next if $field->{noFormPost}; + $prop->{$key} + = $form->get($key,$field->{fieldType},$field->{defaultValue},$field); + } + + # Stuff from Asset + $prop->{ title } = $form->get('title'); + $prop->{ menuTitle } = $form->get('title'); + $prop->{ synopsis } = $form->get('synopsis'); + $prop->{ url } = $session->url->urlize( $self->getParent->getUrl . '/' . $prop->{title} ); + $prop->{ ownerUserId } = $form->get('ownerUserId') || $session->user->userId; + + $self->update( $prop ); + + # Photo magic + $session->log->info("BEEP!"); + if ( $form->get('storageIdPhoto') ) { + $session->log->info("BOOP!"); + my $storage; + if ( $self->get('storageIdPhoto') ) { + $storage = WebGUI::Storage->get( $session, $self->get('storageIdPhoto') ); + $storage->deleteFile( $storage->getFiles->[0] ); + } + else { + $storage = WebGUI::Storage->create( $session ); + $self->update({ storageIdPhoto => $storage->getId }); + } + + $storage->addFileFromFormPost( 'storageIdPhoto', 1 ); + } + + return; +} + +#------------------------------------------------------------------- + +=head2 view ( ) + +Get the content to show in the map text box. This will not be called +by www_view, but we may want to call it elsewhere for some reason. + +=cut + +sub view { + my $self = shift; + return "TODO"; +} + +#------------------------------------------------------------------- + +=head2 www_view ( ) + +Redirect the user to the correct Map with the appropriate focus point +so that this point is automatically shown. + +=cut + +sub www_view { + my $self = shift; + + $self->session->http->setRedirect( + $self->getParent->getUrl('focusOn=' . $self->getId ) + ); + return "redirect"; +} + +1; + +#vim:ft=perl diff --git a/lib/WebGUI/Asset/Wobject/Map.pm b/lib/WebGUI/Asset/Wobject/Map.pm new file mode 100644 index 000000000..f441fdc73 --- /dev/null +++ b/lib/WebGUI/Asset/Wobject/Map.pm @@ -0,0 +1,587 @@ +package WebGUI::Asset::Wobject::Map; + +$VERSION = "1.0.0"; + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2009 Plain Black Corporation. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +use strict; +use Tie::IxHash; +use WebGUI::International; +use WebGUI::Utility; +use base 'WebGUI::AssetAspect::Installable','WebGUI::Asset::Wobject'; + +# To get an installer for your wobject, add the Installable AssetAspect +# See WebGUI::AssetAspect::Installable and sbin/installClass.pl for more +# details + +#------------------------------------------------------------------- + +=head2 definition ( ) + +Define asset properties + +=cut + +sub definition { + my $class = shift; + my $session = shift; + my $definition = shift; + my $i18n = WebGUI::International->new( $session, 'Asset_Map' ); + + tie my %properties, 'Tie::IxHash', ( + groupIdAddPoint => { + tab => "security", + fieldType => "group", + label => $i18n->echo("Group to Add Points"), + hoverHelp => $i18n->echo("Group that is allowed to add points to the map"), + }, + mapApiKey => { + tab => "properties", + fieldType => "text", + label => $i18n->echo("Google Maps API Key"), + hoverHelp => $i18n->echo("The generated Google Maps API key for this site"), + defaultValue=> $class->getDefaultApiKey($session), + subtext => $i18n->echo(q{Get your Google Maps API key}), + }, + mapHeight => { + tab => "display", + fieldType => "text", + label => $i18n->echo("Map Height"), + hoverHelp => $i18n->echo("The height of the generated map"), + defaultValue => '400px', + }, + mapWidth => { + tab => "display", + fieldType => "text", + label => $i18n->echo("Map Width"), + hoverHelp => $i18n->echo("The width of the generated map"), + defaultValue => '100%', + }, + startLatitude => { + tab => "display", + fieldType => "float", + label => $i18n->echo("Starting Latitude"), + hoverHelp => $i18n->echo("Latitude of the default starting point of the map"), + defaultValue => 43.074719, + }, + startLongitude => { + tab => "display", + fieldType => "float", + label => $i18n->echo("Starting Longitude"), + hoverHelp => $i18n->echo("Longitude of the default starting point of the map"), + defaultValue => -89.384251, + }, + startZoom => { + tab => "display", + fieldType => "intSlider", + minimum => 1, + maximum => 19, + label => $i18n->echo("Starting Zoom Level"), + hoverHelp => $i18n->echo("Zoom level of the default starting point of the map"), + }, + templateIdEditPoint => { + tab => "display", + fieldType => "template", + namespace => "MapPoint/Edit", + label => $i18n->echo("Template to Edit Map Point"), + hoverHelp => $i18n->echo("Template to edit a map point."), + }, + templateIdView => { + tab => "display", + fieldType => "template", + namespace => "Map/View", + label => $i18n->echo("Template to View"), + hoverHelp => $i18n->echo("Template to view the map"), + }, + templateIdViewPoint => { + tab => "display", + fieldType => "template", + namespace => "MapPoint/View", + label => $i18n->echo("Template to View Map Point"), + hoverHelp => $i18n->echo("Template to view a map point. Will pop-up a box inside the map."), + }, + workflowIdPoint => { + tab => "security", + fieldType => "workflow", + label => $i18n->echo("Workflow for Adding Points"), + hoverHelp => $i18n->echo("Commit workflow for adding points"), + }, + ); + push @{$definition}, { + assetName => $i18n->get('assetName'), + icon => 'Map.gif', + autoGenerateForms => 1, + tableName => 'Map', + className => 'WebGUI::Asset::Wobject::Map', + properties => \%properties + }; + return $class->SUPER::definition( $session, $definition ); +} ## end sub definition + +#------------------------------------------------------------------- + +=head2 canAddPoint ( [userId] ) + +Returns true if the user can add points to this map. C is the +ID of the user to check, defaults to the current user. + +=cut + +sub canAddPoint { + my $self = shift; + my $userId = shift; + my $user = $userId + ? WebGUI::User->new( $self->session, $userId ) + : $self->session->user + ; + + return $user->isInGroup( $self->get("groupIdAddPoint") ); +} + +#---------------------------------------------------------------------------- + +=head2 canEdit ( [userId] ) + +Returns true if the user can edit this Map. C is the userId to +check. If no userId is passed, will check the current user. + +Users can edit this map if they are part of the C group. + +Also checks if a user is adding a MapPoint and allows them to if they are +part of the C group. + +=cut + +sub canEdit { + my $self = shift; + my $userId = shift; + + my $form = $self->session->form; + + if ( $form->get('func') eq "add" && $form->get( 'class' )->isa( "WebGUI::Asset::MapPoint" ) ) { + return $self->canAddPoint( $userId ); + } + elsif ( $form->get('func') eq "editSave" && $form->get('assetId') eq "new" && $form->get( 'class' )->isa( 'WebGUI::Asset::MapPoint' ) ) { + return $self->canAddPoint( $userId ); + } + else { + my $user = $userId + ? WebGUI::User->new( $self->session, $userId ) + : $self->session->user + ; + + return $user->isInGroup( $self->get("groupIdEdit") ); + } +} + +#------------------------------------------------------------------- + +=head2 getAllPoints ( ) + +Get all the MapPoints for this Map. Returns an array reference of +asset IDs. + +=cut + +sub getAllPoints { + my $self = shift; + + my $assetIds = $self->getLineage(['children']); + return $assetIds; +} + +#------------------------------------------------------------------- + +=head2 getDefaultApiKey ( session ) + +Get the default API key for the Map. + +=cut + +sub getDefaultApiKey { + my $class = shift; + my $session = shift; + + # Get the API key used in other Maps on the site + eval { + # Map may not exist yet! + my $defaultApiKey = $session->db->quickScalar( + "SELECT mapApiKey FROM Map LIMIT 1" + ); + + return $defaultApiKey; + }; + return ''; +} + +#------------------------------------------------------------------- + +=head2 getEditPointTemplate ( ) + +Get the template to edit a MapPoint. Returns a fully-prepared template + +=cut + +sub getEditPointTemplate { + my $self = shift; + + if ( !$self->{_editPointTemplate} ) { + my $templateId = $self->get('templateIdEditPoint'); + my $template + = WebGUI::Asset::Template->new( $self->session, $templateId ); + $template->prepare; + $self->{_editPointTemplate} = $template; + } + + return $self->{_editPointTemplate}; +} + +#------------------------------------------------------------------- + +=head2 getViewPointTemplate ( ) + +Get the template to view a MapPoint. Returns a fully-prepared template +that can be used multiple times in a Map. + +=cut + +sub getViewPointTemplate { + my $self = shift; + + if ( !$self->{_viewPointTemplate} ) { + my $templateId = $self->get('templateIdViewPoint'); + my $template + = WebGUI::Asset::Template->new( $self->session, $templateId ); + $self->{_viewPointTemplate} = $template; + } + + return $self->{_viewPointTemplate}; +} + +#------------------------------------------------------------------- + +=head2 getTemplateVars ( ) + +Get the template variables for this asset + +=cut + +sub getTemplateVars { + my $self = shift; + my $var = {}; + + $var->{ url } = $self->getUrl; + $var->{ canAddPoint } = $self->canAddPoint; + $var->{ canEdit } = $self->canEdit; + + return $var; +} + +#------------------------------------------------------------------- + +=head2 loadMapApiTags ( ) + +Load the Map API tags into the response. Load everything needed to +create the map (but do not create the map itself). + +This is seperate for timing purposes. This part can be loaded in the HEAD or +in the BODY, but the rest of the map must be loaded at a very specific +time. + +=cut + +sub loadMapApiTags { + my $self = shift; + my $style = $self->session->style; + my $url = $self->session->url; + + $style->setScript("http://www.google.com/jsapi?key=" . $self->get('mapApiKey'),{type=>"text/javascript"}); + $style->setRawHeadTags(<<'ENDHTML'); + +ENDHTML + $style->setScript('http://gmaps-utility-library.googlecode.com/svn/trunk/markermanager/release/src/markermanager.js', {type=>"text/javascript"}); + $style->setScript($url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'),{type=>'text/javascript'}); + $style->setScript($url->extras('yui/build/connection/connection-min.js'),{type=>'text/javascript'}); + $style->setScript($url->extras('yui/build/json/json-min.js'),{type=>'text/javascript'}); + $style->setScript($url->extras('map/map.js'),{type=>'text/javascript'}); + + return; +} + +#------------------------------------------------------------------- + +=head2 prepareView ( ) + +See WebGUI::Asset::prepareView() for details. + +=cut + +sub prepareView { + my $self = shift; + $self->SUPER::prepareView(); + my $template = WebGUI::Asset::Template->new( $self->session, $self->get("templateIdView") ); + $template->prepare; + $self->{_viewTemplate} = $template; +} + +#------------------------------------------------------------------- + +=head2 view ( ) + +method called by the www_view method. Returns a processed template +to be displayed within the page style. + +=cut + +sub view { + my $self = shift; + my $session = $self->session; + my $style = $self->session->style; + my $i18n = WebGUI::International->new( $session, 'Asset_Map' ); + + $self->loadMapApiTags; + my $var = $self->getTemplateVars; + + # Build the map container + my $mapHtml = sprintf '
', + $self->getId, + $self->get('mapHeight'), + $self->get('mapWidth'), + ; + + # The script to load the map into the container + $mapHtml .= sprintf <<'ENDHTML', $self->getId, $self->getUrl, $self->get('startLatitude'), $self->get('startLongitude'), $self->get('startZoom'); + +ENDHTML + + $var->{ map } = $mapHtml; + + # Button to add a map point + $var->{ button_addPoint } + = WebGUI::Form::Button( $session, { + value => $i18n->echo("Add Point"), + id => sprintf( 'addPoint_%s', $self->getId ), + } ); + + # Button to set the map's default view + $var->{ button_setCenter } + = WebGUI::Form::Button( $session, { + value => $i18n->echo("Set Default Viewing Area"), + id => sprintf( 'setCenter_%s', $self->getId ), + } ); + + return $self->processTemplate( $var, undef, $self->{_viewTemplate} ); +} + +#------------------------------------------------------------------- + +=head2 www_ajaxDeletePoint ( ) + +Immediately remove a point from the map. + +=cut + +sub www_ajaxDeletePoint { + my ( $self ) = @_; + my $session = $self->session; + my $assetId = $self->session->form->get('assetId'); + my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId ); + $self->session->http->setMimeType('application/json'); + return JSON->new->encode({error => 'You are not allowed to remove this point'}) + unless $asset && $asset->canEdit; + + $asset->purge; + return JSON->new->encode({message => 'Point deleted'}); +} + +#------------------------------------------------------------------- + +=head2 www_ajaxEditPoint ( ) + +Get the form to edit a point to the map + +=cut + +sub www_ajaxEditPoint { + my $self = shift; + my $session = $self->session; + my $form = $self->session->form; + + my $asset; + if ( $form->get('assetId') eq "new" ) { + $asset = WebGUI::Asset->newByPropertyHashRef( $session, { + className => "WebGUI::Asset::MapPoint", + } ); + } + else { + $asset = WebGUI::Asset->newByDynamicClass( $session, $form->get('assetId') ); + } + + my $output = $self->getEditPointTemplate->process( $asset->getTemplateVarsEditForm ); + WebGUI::Macro::process( $session, \$output ); + return $output; +} + +#------------------------------------------------------------------- + +=head2 www_ajaxEditPointSave ( ) + +Process the form to edit a point to the map + +=cut + +sub www_ajaxEditPointSave { + my $self = shift; + my $session = $self->session; + my $form = $self->session->form; + + $session->http->setMimeType("text/html"); + + my $assetId = $form->get('assetId'); + my $asset; + if ( $assetId eq "new" ) { + return JSON->new->encode({message => "Error"}) + unless $self->canAddPoint; + + $asset = $self->addChild( { + className => 'WebGUI::Asset::MapPoint', + } ); + } + else { + $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId ); + return JSON->new->encode({message => "Error"}) + unless $asset && $asset->canEdit; + } + + my $errors = $asset->processAjaxEditForm; + + return JSON->new->encode($asset->getMapInfo); +} + +#------------------------------------------------------------------- + +=head2 www_ajaxSetCenter ( ) + +Set the center of the map, ajax-style. + +=cut + +sub www_ajaxSetCenter { + my $self = shift; + my $session = $self->session; + my $form = $self->session->form; + my $i18n = WebGUI::International->new( $session, 'Asset_Map' ); + + $session->http->setMimeType("application/json"); + + return JSON->new->encode({message => $i18n->echo("No permissions")}) + unless $self->canEdit; + + $self->update({ + startLatitude => $form->get("startLatitude"), + startLongitude => $form->get("startLongitude"), + startZoom => $form->get("startZoom"), + }); + + return JSON->new->encode({message => $i18n->echo("Success!")}); +} + +#------------------------------------------------------------------- + +=head2 www_ajaxSetPointLocation ( ) + +Set the location of a point + +=cut + +sub www_ajaxSetPointLocation { + my $self = shift; + my $session = $self->session; + my $form = $self->session->form; + my $i18n = WebGUI::International->new( $session, 'Asset_Map' ); + + $session->http->setMimeType("application/json"); + + my $assetId = $form->get('assetId'); + my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId ); + $asset->update( { + latitude => $form->get('latitude'), + longitude => $form->get('longitude'), + } ); + + return JSON->new->encode( {message => $i18n->echo("Success!")} ); +} + +1; + +#vim:ft=perl diff --git a/lib/WebGUI/i18n/English/Asset_Map.pm b/lib/WebGUI/i18n/English/Asset_Map.pm new file mode 100644 index 000000000..4cd4de614 --- /dev/null +++ b/lib/WebGUI/i18n/English/Asset_Map.pm @@ -0,0 +1,14 @@ +package WebGUI::i18n::English::Asset_Map; + +use strict; + +our $I18N = { + 'assetName' => { + message => "Map", + lastUpdated => 0, + context => "Name of this asset", + }, +}; + +1; +#vim:ft=perl diff --git a/lib/WebGUI/i18n/English/Asset_MapPoint.pm b/lib/WebGUI/i18n/English/Asset_MapPoint.pm new file mode 100644 index 000000000..0a2bf30b7 --- /dev/null +++ b/lib/WebGUI/i18n/English/Asset_MapPoint.pm @@ -0,0 +1,15 @@ +package WebGUI::i18n::English::Asset_MapPoint; + +use strict; + +our $I18N = { + + 'assetName' => { + message => "MapPoint", + lastUpdated => 0, + context => "Name of this asset", + }, +}; + +1; +#vim:ft=perl diff --git a/www/extras/map/map.js b/www/extras/map/map.js new file mode 100644 index 000000000..28f43e4eb --- /dev/null +++ b/www/extras/map/map.js @@ -0,0 +1,237 @@ + +// Initialize namespace +if (typeof WebGUI == "undefined") { + var WebGUI = {}; +} +if (typeof WebGUI.Map == "undefined") { + WebGUI.Map = {}; +} + +// Keep track of all points on all maps and how to focus on them +WebGUI.Map.markers = {}; + +/** + * WebGUI.Map.deletePoint( map, mgr, mapUrl, marker ) + * Delete a point from the map. + * NOTE: We assume the user has already confirmed this action + */ +WebGUI.Map.deletePoint += function ( map, mgr, mapUrl, marker ) { + var callback = function ( text, code ) { + var response = YAHOO.lang.JSON.parse( text ); + // remove the marker from the map + if ( !response.error ) { + mgr.removeMarker( marker ); + } + }; + GDownloadUrl( mapUrl + '?func=ajaxDeletePoint;assetId=' + marker.assetId, callback); +}; + +/** + * WebGUI.Map.editPoint( map, mgr, mapUrl, marker ) + * Edit a point on the map. + * up the edit box. mgr is the Marker Manager to add the marker + * to. mapUrl is the URL of the map asset + */ +WebGUI.Map.editPoint += function ( map, mgr, mapUrl, marker ) { + var assetId = ''; + if ( !marker ) { + marker = new GMarker( map.getCenter(), { draggable: true } ); + mgr.addMarker( marker, 1 ); + mgr.refresh(); + assetId = "new"; + marker.assetId = "new"; + GEvent.addListener( marker, "dragend", function (latlng) { + WebGUI.Map.setPointLocation( marker, latlng, mapUrl ); + } ); + } + else { + assetId = marker.assetId; + } + + // Callback should open the window with the form + var callback = function (text, code) { + marker.openInfoWindowHtml( text ); + GEvent.addListener( marker, "infowindowbeforeclose", function () { + WebGUI.Map.editPointSave( map, mgr, mapUrl, marker ); + }); + }; + + // Get the form + GDownloadUrl( mapUrl + '?func=ajaxEditPoint;assetId=' + assetId, callback ); +}; + +/** + * WebGUI.Map.editPointSave( map, mgr, mapUrl, marker ) + * Save the edit form. + */ +WebGUI.Map.editPointSave += function ( map, mgr, mapUrl, marker ) { + var iwin = map.getInfoWindow(); + var form = iwin.getContentContainers()[0].getElementsByTagName('form')[0]; + + // Make ajax request + var callback = { + upload: function (o) { + // Update marker info + console.log(o.responseText); + var point = YAHOO.lang.JSON.parse( o.responseText ); + GEvent.clearListeners( marker, "click" ); + GEvent.clearListeners( marker, "infowindowbeforeclose" ); + + var infoWin = document.createElement( "div" ); + infoWin.innerHTML = point.content; + marker.infoWin = infoWin; + if ( point.canEdit ) { + var editButton = document.createElement("input"); + editButton.type = "button"; + editButton.value = "Edit"; + GEvent.addDomListener( editButton, "click", function () { + WebGUI.Map.editPoint( map, mgr, mapUrl, marker ); + } ); + infoWin.appendChild( editButton ); + + var deleteButton = document.createElement("input"); + deleteButton.type = "button"; + deleteButton.value = "Delete"; // Replace with i18n + GEvent.addDomListener( deleteButton, "click", function () { + if ( confirm("Are you sure you want to delete this point?") ) { + WebGUI.Map.deletePoint( map, mgr, mapUrl, marker ); + } + } ); + divButton.appendChild( deleteButton ); + } + marker.bindInfoWindow( infoWin ); + + // Make sure the point has a Lat/Lng in case the user doesn't + // move it after initially creating it. + if ( marker.assetId == "new" ) { + marker.assetId = point.assetId; + WebGUI.Map.setPointLocation( marker, marker.getLatLng(), mapUrl ); + } + marker.assetId = point.assetId; + } + }; + // In case our form does not have a file upload in it + callback["success"] = callback["upload"]; + + YAHOO.util.Connect.setForm( form, 1 ); + YAHOO.util.Connect.asyncRequest( 'POST', mapUrl, callback ); +}; + +/** + * WebGUI.Map.focusOn( assetId ) + * Pan the appropriate map to view the appropriate map point + */ +WebGUI.Map.focusOn += function ( assetId ) { + var marker = WebGUI.Map.markers[assetId]; + var map = marker.map; + var infoWin = marker.infoWin; + if ( map.getZoom() < 5 ) { + map.setZoom(6); + } + map.panTo( marker.getLatLng() ); + marker.openInfoWindow( marker.infoWin ); +}; + +/** + * WebGUI.Map.preparePoints ( map, mgr, mapUrl, points ) + * Prepare the points from WebGUI into Google Map GMarkers + */ +WebGUI.Map.preparePoints += function ( map, mgr, mapUrl, points ) { + // Transform points into markers + var markers = []; + for ( var i = 0; i < points.length; i++ ) (function(i){ // Create closure for callbacks + var point = points[i]; + var latlng = new GLatLng( point.latitude, point.longitude ); + var marker = new GMarker( latlng, { + title: point.title, + draggable: point.canEdit + } ); + marker.assetId = point.assetId; + marker.map = map; + + // Create info window + var infoWin = document.createElement( "div" ); + infoWin.innerHTML = point.content; + marker.infoWin = infoWin; + + // Make editable features + if ( point.canEdit ) { + var divButton = document.createElement('div'); + + var editButton = document.createElement("input"); + editButton.type = "button"; + editButton.value = "Edit"; // Replace with i18n + GEvent.addDomListener( editButton, "click", function () { + WebGUI.Map.editPoint( map, mgr, mapUrl, marker ); + } ); + divButton.appendChild( editButton ); + + var deleteButton = document.createElement("input"); + deleteButton.type = "button"; + deleteButton.value = "Delete"; // Replace with i18n + GEvent.addDomListener( deleteButton, "click", function () { + if ( confirm("Are you sure you want to delete this point?") ) { + WebGUI.Map.deletePoint( map, mgr, mapUrl, marker ); + } + } ); + divButton.appendChild( deleteButton ); + + infoWin.appendChild( divButton ); + GEvent.addListener( marker, "dragend", function (latlng) { + WebGUI.Map.setPointLocation( marker, latlng, mapUrl ); + } ); + } + + // Keep info + WebGUI.Map.markers[point.assetId] = marker; + + marker.bindInfoWindow( infoWin ); + + markers.push(marker); + })(i); + return markers; +}; + +/** + * WebGUI.Map.setCenter ( map, baseUrl ) + * Set the new center point and zoom level of the map. + * map is the Google Map object + * baseUrl is the base URL to the Map asset + */ +WebGUI.Map.setCenter += function ( map, baseUrl ) { + var url = baseUrl + '?func=ajaxSetCenter'; + var center = map.getCenter(); + url = url + ';startLatitude=' + center.lat() + + ';startLongitude=' + center.lng() + + ';startZoom=' + map.getZoom() + ; + var callback = function ( text, code ) { + // TODO: Notify the poor user + }; + GDownloadUrl(url,callback); +}; + +/** + * WebGUI.Map.setPointLocation( marker, latlng, mapUrl, assetId ) + * Update the point's location in the database. + */ +WebGUI.Map.setPointLocation += function ( marker, latlng, mapUrl, assetId ) { + var url = mapUrl + '?func=ajaxSetPointLocation' + + ';assetId=' + marker.assetId + + ';latitude=' + latlng.lat() + + ';longitude=' + latlng.lng() + ; + var callback = function ( text, code ) { + // TODO: Notify the poor user + }; + GDownloadUrl(url, callback); +}; + +