Add new MapPoint code for geolocation, Thingy searching and indexing and a macro for rendering thing data outside of the Thingy.

This commit is contained in:
Colin Kuskie 2011-05-02 13:49:18 -07:00
parent 944c76040a
commit 61534779d5
24 changed files with 1442 additions and 176 deletions

View file

@ -5,6 +5,10 @@
- fixed #12106: CalendarUpdateFeeds activity does not handle time zones correctly
- fixed #11213: Gooey on the Go format problem
- mark makeUrlCompliant as deprecated.
- fixed #12059: WebGUI::Asset::Wobject::Map - Set Default Viewing Area button does not work.
- added: Setting MapPoint locations via address.
- added: Make Thing data searchable
- added: AssetProxy like macro for Thing data, ViewThingData
7.10.14
- fixed #12094: Cannot enter in Macros in URLs inside TinyMCE.

View file

@ -7,6 +7,10 @@ upgrading from one version to the next, or even between multiple
versions. Be sure to heed the warnings contained herein as they will
save you many hours of grief.
7.10.15
--------------------------------------------------------------------
* WebGUI now depends on Geo::Coder::Googlev3 for it's Map asset
7.10.13
--------------------------------------------------------------------
* WebGUI now depends on XML::FeedPP::MediaRSS.

View file

@ -22,7 +22,9 @@ use Getopt::Long;
use WebGUI::Session;
use WebGUI::Storage;
use WebGUI::Asset;
use WebGUI::AssetAspect::Installable;
use WebGUI::Asset::MapPoint;
use WebGUI::Asset::Wobject::Thingy;
my $toVersion = '7.10.15';
my $quiet; # this line required
@ -31,6 +33,10 @@ my $quiet; # this line required
my $session = start(); # this line required
# upgrade functions go here
alterAssetIndexTable($session);
reindexAllThingys($session);
WebGUI::AssetAspect::Installable::upgrade("WebGUI::Asset::MapPoint",$session);
addRenderThingDataMacro($session);
finish($session); # this line required
@ -44,6 +50,37 @@ finish($session); # this line required
# print "DONE!\n" unless $quiet;
#}
sub addRenderThingDataMacro {
my $session = shift;
print "\tAdd the new RenderThingData macro to the site config... " unless $quiet;
$session->config->addToHash('macros', 'RenderThingData', 'RenderThingData');
print "DONE!\n" unless $quiet;
}
sub alterAssetIndexTable {
my $session = shift;
print "\tExtend the assetIndex table so we can search things other than assets... " unless $quiet;
$session->db->write(<<EOSQL);
alter table assetIndex
drop primary key,
add column subId char(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
add primary key (assetId, url)
EOSQL
print "DONE!\n" unless $quiet;
}
sub reindexAllThingys {
my $session = shift;
print "\tReindex all Thingys... " unless $quiet;
my $get_thingy = WebGUI::Asset::Wobject::Thingy->getIsa($session);
THINGY: while (1) {
my $thingy = eval { $get_thingy->() };
next THINGY if Exception::Class->caught();
last THINGY unless $thingy;
$thingy->indexContent;
}
print "DONE!\n" unless $quiet;
}
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------

View file

@ -848,6 +848,7 @@
"PickLanguage" : "PickLanguage",
"RandomAssetProxy" : "RandomAssetProxy",
"RandomThread" : "RandomThread",
"RenderThingData" : "RenderThingData",
"RootTitle" : "RootTitle",
"r" : "r_printable",
"Spacer" : "Spacer",

View file

@ -18,6 +18,9 @@ use strict;
use Tie::IxHash;
use base 'WebGUI::Asset';
use WebGUI::Utility;
use Geo::Coder::Googlev3;
use Data::Dumper;
# To get an installer for your wobject, add the Installable AssetAspect
# See WebGUI::AssetAspect::Installable and sbin/installClass.pl for more
@ -143,6 +146,12 @@ sub definition {
hoverHelp => $i18n->get("storageIdPhoto description"),
noFormPost => 1,
},
isGeocoded => {
fieldType => "yesNo",
tab => "properties",
label => $i18n->get("isGeocoded label"),
hoverHelp => $i18n->get("isGeocoded description"),
},
userDefined1 => {
fieldType => "hidden",
},
@ -159,6 +168,7 @@ sub definition {
fieldType => "hidden",
},
);
push @{$definition}, {
assetName => $i18n->get('assetName'),
icon => 'mappoint.png',
@ -212,6 +222,7 @@ AT LEAST the following keys:
title - The title of the point
content - HTML content to show details about the point
url - The URL of the point
userDefined1-5 - The userDefined fields
The following keys are optional
@ -227,7 +238,7 @@ sub getMapInfo {
# Get asset properties
$var->{ url } = $self->getUrl;
$var->{ assetId } = $self->getId;
my @keys = qw( latitude longitude title );
my @keys = qw( latitude longitude title userDefined1 userDefined2 userDefined3 userDefined4 userDefined5 isGeocoded );
for my $key ( @keys ) {
$var->{ $key } = $self->get( $key );
}
@ -274,6 +285,15 @@ sub getTemplateVarsEditForm {
my $session = $self->session;
my $var = $self->getTemplateVars;
my $parent = $self->getParent;
#If it's a new point, we have to get the parent from the url
unless ($parent) {
my $url = $session->url->page;
$parent = WebGUI::Asset->newByUrl($session,$url);
}
$var->{'can_edit_map'} = $parent->canEdit;
$var->{ form_header }
= WebGUI::Form::formHeader( $session )
. WebGUI::Form::hidden( $session, {
@ -323,8 +343,25 @@ sub getTemplateVarsEditForm {
name => "synopsis",
value => $self->get("synopsis"),
resizable => 0,
} );
} );
#Only allow people who can edit the parent to change isHidden
if($var->{'can_edit_map'}) {
my $isHidden = (defined $self->get("isHidden")) ? $self->get("isHidden") : 1;
$var->{ "form_isHidden" }
= WebGUI::Form::yesNo( $session, {
name => "isHidden",
value => $isHidden,
} );
}
my $isGeocoded = ( $self->getId ) ? $self->get("isGeocoded") : 1;
$var->{"form_isGeocoded"}
= WebGUI::Form::checkbox( $session, {
name => "isGeocoded",
value => 1,
checked => $isGeocoded
} );
# Fix storageIdPhoto because scripts do not get executed in ajax requests
$var->{ "form_storageIdPhoto" }
= '<input type="file" name="storageIdPhoto" />';
@ -339,6 +376,35 @@ sub getTemplateVarsEditForm {
#-------------------------------------------------------------------
=head2 indexContent ( )
Indexing the content of attachments and user defined fields. See WebGUI::Asset::indexContent() for additonal details.
=cut
sub indexContent {
my $self = shift;
my $indexer = $self->SUPER::indexContent;
$indexer->addKeywords($self->get("website"));
$indexer->addKeywords($self->get("address1"));
$indexer->addKeywords($self->get("address2"));
$indexer->addKeywords($self->get("city"));
$indexer->addKeywords($self->get("region"));
$indexer->addKeywords($self->get("zipCode"));
$indexer->addKeywords($self->get("country"));
$indexer->addKeywords($self->get("phone"));
$indexer->addKeywords($self->get("fax"));
$indexer->addKeywords($self->get("email"));
$indexer->addKeywords($self->get("userDefined1"));
$indexer->addKeywords($self->get("userDefined2"));
$indexer->addKeywords($self->get("userDefined3"));
$indexer->addKeywords($self->get("userDefined4"));
$indexer->addKeywords($self->get("userDefined5"));
return $indexer;
}
#-------------------------------------------------------------------
=head2 processAjaxEditForm ( )
Process the Ajax Edit Form from the Map. If any errors occur, return
@ -367,6 +433,29 @@ sub processAjaxEditForm {
$prop->{ synopsis } = $form->get('synopsis');
$prop->{ url } = $session->url->urlize( $self->getParent->getUrl . '/' . $prop->{title} );
$prop->{ ownerUserId } = $form->get('ownerUserId') || $session->user->userId;
#Only users who can edit the map can set this property
if($self->getParent->canEdit) {
$prop->{ isHidden } = $form->get('isHidden');
}
$prop->{isGeocoded } = $form->get('isGeocoded') || 0;
if($prop->{isGeocoded} &&
(
( $form->get("address1") ne $self->get("address1") )
|| ( $form->get("address2") ne $self->get("address2") )
|| ( $form->get("city") ne $self->get("city") )
|| ( $form->get("region") ne $self->get("region") )
|| ( $form->get("zipCode") ne $self->get("zipCode") )
|| ( $form->get("country") ne $self->get("country") )
)
) {
my $geocoder = Geo::Coder::Googlev3->new;
my $address_str = $form->get("address1");
$address_str .= " ".$form->get("address2") if($form->get("address2"));
$address_str .= ", ".$form->get("city").", ".$form->get("region").", ".$form->get("zipCode").", ".$form->get("country");
my $location = $geocoder->geocode( location => $address_str );
$prop->{latitude } = $location->{geometry}->{location}->{lat};
$prop->{longitude} = $location->{geometry}->{location}->{lng};
}
$self->update( $prop );
@ -420,6 +509,7 @@ sub www_view {
return "redirect";
}
1;
#vim:ft=perl

View file

@ -18,6 +18,7 @@ use WebGUI::International;
use WebGUI::Utility;
use HTML::Entities qw(encode_entities);
use base 'WebGUI::Asset::Wobject';
use Data::Dumper;
# To get an installer for your wobject, add the Installable AssetAspect
# See WebGUI::AssetAspect::Installable and sbin/installClass.pl for more
@ -387,7 +388,9 @@ sub view {
google.setOnLoadCallback( function() {
var mapId = "%s";
var mapUrl = "%s";
var map = new GMap2( document.getElementById("map_" + mapId) );
var element = document.getElementById("map_" + mapId);
var map = new GMap2( element );
element.mapObject = map;
map.url = mapUrl;
map.assetId = mapId;
map.setCenter(new GLatLng(%s, %s), %s);
@ -395,6 +398,10 @@ sub view {
map.extrasUrl = "%s";
var markermanager = new MarkerManager(map, {trackMarkers: true});
map.markermanager = markermanager;
map.fancyClickHandler = null;
map.panOnClick = true;
map.clickToEdit = false;
ENDHTML
@ -408,9 +415,9 @@ ENDHTML
for my $pointId ( @{$pointIds} ) {
my $point = WebGUI::Asset->newByDynamicClass( $session, $pointId );
next unless $point;
$mapHtml .= sprintf ' points.push(%s);'."\n",
JSON->new->encode($point->getMapInfo),
;
my $buffer = JSON->new->encode( $point->getMapInfo );
$mapHtml .= sprintf ' points.push(%s);'."\n", $buffer;
push @{$var->{ mapPoints }}, $point->getTemplateVars;
}
@ -432,11 +439,11 @@ ENDHTML
}
# Script to control addPoint and setPoint buttons
$mapHtml .= <<'ENDHTML';
$mapHtml .= sprintf <<'ENDHTML', $self->getUrl;
if ( document.getElementById( "setCenter_" + mapId ) ) {
var button = document.getElementById( "setCenter_" + mapId );
GEvent.addDomListener( button, "click", function () {
WebGUI.Map.setCenter( map );
WebGUI.Map.setCenter( map, '%s' );
} );
}
if ( document.getElementById( "addPoint_" + mapId ) ) {

View file

@ -213,30 +213,31 @@ sub view {
);
my @results = ();
foreach my $data (@{$p->getPageData}) {
next unless (
ENTRY: foreach my $data (@{$p->getPageData}) {
next ENTRY unless (
$user->userId eq $data->{ownerUserId}
|| $user->isInGroup($data->{groupIdView})
|| $user->isInGroup($data->{groupIdEdit})
);
my $asset = WebGUI::Asset->new($session, $data->{assetId}, $data->{className});
if (defined $asset) {
my $properties = $asset->get;
if ( $self->get("useContainers") && $asset->getContainer->canView ) {
$properties->{url} = $asset->isa('WebGUI::Asset::Post::Thread') ? $asset->getCSLinkUrl()
: $asset->getContainer->get("url");
}
#Add highlighting
$properties->{'title' } = $hl->highlight($properties->{title} || '');
$properties->{'title_nohighlight' } = $properties->{title};
my $synopsis = $data->{'synopsis'} || '';
WebGUI::Macro::process($self->session, \$synopsis);
$properties->{'synopsis' } = $hl->highlight($synopsis);
$properties->{'synopsis_nohighlight'} = $synopsis;
push(@results, $properties);
$var{results_found} = 1;
}
next ENTRY unless defined $asset;
my $properties = $asset->get;
##Overlay the asset properties with the original data to handle sub-entries for assets
$properties = { %{ $properties }, %{ $data} };
if ( $self->get("useContainers") && $asset->getContainer->canView ) {
$properties->{url} = $asset->isa('WebGUI::Asset::Post::Thread') ? $asset->getCSLinkUrl()
: $asset->getContainer->get("url");
}
#Add highlighting
$properties->{'title' } = $hl->highlight($properties->{title} || '');
$properties->{'title_nohighlight' } = $properties->{title};
my $synopsis = $properties->{'synopsis'} || '';
WebGUI::Macro::process($self->session, \$synopsis);
$properties->{'synopsis' } = $hl->highlight($synopsis);
$properties->{'synopsis_nohighlight'} = $synopsis;
push(@results, $properties);
$var{results_found} = 1;
}
$var{result_set} = \@results;

View file

@ -279,6 +279,24 @@ sub definition {
}
#-------------------------------------------------------------------
=head2 deleteThingIndex ( $thingId )
Remove the entry about this Thing from the database, and for any rows for it that are indexed as well.
=head3 $thingId
The GUID of the Thing, used to pick out this record in the database.
=cut
sub deleteThingIndex {
my $self = shift;
my $thingId = shift;
$self->session->db->write(q|delete from assetIndex where assetId=? and subId like CONCAT(?,'%')|,[$self->getId, $thingId]);
}
#-------------------------------------------------------------------
=head2 duplicate ( )
@ -367,6 +385,8 @@ sub duplicateThing {
$self->addField($field,0);
}
$thingProperties->{thingId} = $newThingId;
$self->indexThing($thingProperties);
return $newThingId;
}
@ -418,6 +438,7 @@ sub deleteField {
$db->write("ALTER TABLE ".$db->dbh->quote_identifier("Thingy_".$thingId)." DROP "
.$db->dbh->quote_identifier("field_".$fieldId));
}
$self->reindexThings;
$error->info("Deleted field: $fieldId in thing: $thingId.");
return undef;
}
@ -468,6 +489,7 @@ sub copyThingData {
}
##Update the copy
$self->setCollateral("Thingy_".$thingId, "thingDataId", $origCollateral, 0, 0);
$self->indexThingData($thingId, $origCollateral);
return undef;
}
@ -522,11 +544,30 @@ sub deleteThingData {
$storage->delete;
}
$self->deleteThingDataIndex($thingDataId);
return undef;
}
#-------------------------------------------------------------------
=head2 deleteThingDataIndex ( $thingDataId )
Remove the entry about this Thing from the database, and for any rows for it that are indexed as well.
=head3 $thingDataId
The GUID of the thingData to remove, used to pick out this record in the database.
=cut
sub deleteThingDataIndex {
my $self = shift;
my $thingDataId = shift;
$self->session->db->write(q|delete from assetIndex where assetId=? and subId like CONCAT('%-',?)|,[$self->getId, $thingDataId]);
}
#-------------------------------------------------------------------
=head2 deleteThing ( thingId )
Deletes a Thing and its fields from Collateral and drops the things table.
@ -549,6 +590,7 @@ sub deleteThing {
$session->db->write("drop table if exists ".$session->db->dbh->quote_identifier("Thingy_".$thingId));
$error->info("Deleted thing: $thingId.");
$self->deleteThingIndex($thingId);
return undef;
}
@ -636,6 +678,7 @@ sub editThingDataSave {
return ('', \@errors);
}
$newThingDataId = $self->setCollateral("Thingy_".$thingId,"thingDataId",\%thingData,0,0);
$self->indexThingData($thingId, \%thingData);
# trigger workflow
if($thingDataId eq "new"){
@ -697,6 +740,7 @@ sub field_isa {
my $session = $self->session;
my $fieldType = shift;
my $isa = shift;
$fieldType = ucfirst $fieldType;
my $control = eval { WebGUI::Pluggable::instanciate("WebGUI::Form::".$fieldType, "new", [ $session, () ]) };
return ($control && $control->isa($isa));
}
@ -1286,6 +1330,7 @@ sub getViewThingVars {
);
push(@viewScreenTitleFields,$value) if ($field{viewScreenTitle});
push(@field_loop, { map {("field_".$_ => $fieldProperties{$_})} keys(%fieldProperties) });
$var->{ $field{label} } = $value;
}
$var->{viewScreenTitle} = join(" ",@viewScreenTitleFields);
$var->{field_loop} = \@field_loop;
@ -1398,6 +1443,7 @@ sub importAssetCollateralData {
# add new thing
$self->addThing($thing,1);
}
$self->indexThing($thing);
}
# delete deleted things
my $thingsInDatabase = $self->getThings;
@ -1439,6 +1485,126 @@ sub importAssetCollateralData {
}
#-------------------------------------------------------------------
=head2 indexContent ( )
Extend the base class to handle reindexing every Thing, and every row in every Thing. We have
to do a complete rework because the URL may have changed, and that affects everything that has
been inserted into the AssetIndex.
=cut
sub indexContent {
my ($self) = @_;
my $session = $self->session;
$self->SUPER::indexContent();
$self->reindexThings;
}
#-------------------------------------------------------------------
=head2 indexThing ( $thing )
Add an entry about this Thing into the AssetIndex so it can be found for searches.
=head3 $thing
A hashref of Thing properties, as returned by getThing
=cut
sub indexThing {
my ($self, $thing) = @_;
return unless $thing;
my $index = WebGUI::Search::Index->new($self);
$index->addRecord(
url => $self->getUrl($self->getThingUrl($thing)),
groupIdView => $thing->{groupIdView},
title => $thing->{label},
subId => $thing->{thingId},
keywords => join(' ', @{$thing}{qw/label editScreenTitle editInstructions searchScreenTitle searchDescription/}),
);
##Easy update of all thingData fields for this thing. This is in lieu of deleting all records
##And rebuilding them all.
$self->session->db->write(q|update assetIndex set title=?, groupIdView=? where assetId=? and subId like CONCAT(?, '%')|, [$thing->{label}, $thing->{groupIdView}, $self->getId, $thing->{thingId}]);
}
#-------------------------------------------------------------------
=head2 indexThingData ( $thingId, $thingData )
Add an entry about a row from this Thing into the AssetIndex so it can be found for searches.
=head3 $thingId
The GUID for a Thing.
=head3 $thingData
A hashref of ThingData properties
=cut
sub indexThingData {
my ($self, $thingId, $thingData) = @_;
my $session = $self->session;
return unless $thingId;
my $thing = $self->getThing($thingId);
my $index = WebGUI::Search::Index->new($self);
my $keywords;
##Get the Thingy's fields
my $fields = $session->db->read('select * from Thingy_fields where assetId = ? and thingId = ?',
[$self->getId, $thingId]);
##Walk the fields
my @viewScreenTitleFields = ();
FIELD: while (my %field = $fields->hash) {
my $fieldName = 'field_'.$field{fieldId};
$field{value} = $thingData->{$fieldName} || $field{defaultValue};
my $subkeywords = '';
my $value = '';
if ($self->field_isa($field{fieldType}, 'WebGUI::Form::File')) {
my $storage = WebGUI::Storage->get($session, $field{value});
if ($storage) {
foreach my $file (@{$storage->getFiles()}) {
$subkeywords = $index->getKeywordsForFile($storage->getPath($file));
}
}
}
else {
$value = $self->getFieldValue($field{value}, \%field);
##If it's a file type, then get keywords from the file.
##Accumulate keywords
$subkeywords = $value;
}
if ($value && $field{viewScreenTitle}) {
push @viewScreenTitleFields, $value;
}
##We don't index date fields, since they're unix epochs and they'd be different for everyone based on timezone.
next FIELD if $field{fieldType} eq 'date'
|| $field{fieldType} eq 'datetime'
|| $field{fieldType} eq 'time';
##Don't show what shouldn't be shown
next FIELD unless $field{displayInSearch};
$keywords = join ' ', $keywords, $subkeywords;
}
return unless $keywords; ##No sense indexing nothing;
my $title = join('', @viewScreenTitleFields)
|| $thing->{label}
|| $self->getTitle;
$index->addRecord(
assetId => $self->getId,
url => $self->getUrl('func=viewThingData;thingId='. $thing->{thingId} . ';thingDataId='. $thingData->{thingDataId}),
groupIdView => $thing->{groupIdView},
title => $title,
subId => $thing->{thingId} . '-' . $thingData->{thingDataId},
keywords => $keywords,
);
}
#-------------------------------------------------------------------
=head2 prepareView ( )
@ -1487,6 +1653,30 @@ sub purge {
return $self->SUPER::purge;
}
#-------------------------------------------------------------------
=head2 reindexThings ( )
Reindex every Thing, and every row in every Thing.
=cut
sub reindexThings {
my ($self) = @_;
my $session = $self->session;
my $things = $self->getThings;
THING: while (my $thing = $things->hashRef) {
$self->deleteThingIndex($thing->{thingId});
$self->indexThing($thing);
my $sth = $session->db->read('select * from '. $session->db->dbh->quote_identifier('Thingy_'.$thing->{thingId}));
while (my $thingData = $sth->hashRef) {
$self->indexThingData($thing->{thingId}, $thingData);
}
$sth->finish;
}
}
#-------------------------------------------------------------------
=head2 triggerWorkflow ( workflowId, thingId, thingDataId )
@ -2222,44 +2412,44 @@ sub www_editThingSave {
my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit;
my $form = $self->session->form;
my ($thingId, $fields);
$thingId = $self->session->form->process("thingId");
$fields = $self->getFields($thingId);
my $form = $self->session->form;
my $thingId = $self->session->form->process("thingId");
my $fields = $self->getFields($thingId);
my $thing = {
thingId => $thingId,
label => $form->process("label"),
editScreenTitle => $form->process("editScreenTitle"),
editInstructions => $form->process("editInstructions"),
groupIdAdd => $form->process("groupIdAdd"),
groupIdEdit => $form->process("groupIdEdit"),
saveButtonLabel => $form->process("saveButtonLabel"),
afterSave => $form->process("afterSave"),
editTemplateId => $form->process("editTemplateId") || 1,
onAddWorkflowId => $form->process("onAddWorkflowId"),
onEditWorkflowId => $form->process("onEditWorkflowId"),
onDeleteWorkflowId => $form->process("onDeleteWorkflowId"),
groupIdView => $form->process("groupIdView"),
viewTemplateId => $form->process("viewTemplateId") || 1,
defaultView => $form->process("defaultView"),
searchScreenTitle => $form->process("searchScreenTitle"),
searchDescription => $form->process("searchDescription"),
groupIdSearch => $form->process("groupIdSearch"),
groupIdImport => $form->process("groupIdImport"),
groupIdExport => $form->process("groupIdExport"),
searchTemplateId => $form->process("searchTemplateId") || 1,
thingsPerPage => $form->process("thingsPerPage") || 25,
sortBy => $form->process("sortBy") || '',
exportMetaData => $form->process("exportMetaData") || '',
maxEntriesPerUser => $form->process("maxEntriesPerUser") || '',
};
$self->setCollateral("Thingy_things", "thingId", $thing, 0, 1);
if($fields->rows < 1){
$self->session->log->warn("Thing failed to create because it had no fields");
my $i18n = WebGUI::International->new($self->session, "Asset_Thingy");
return $self->www_editThing($i18n->get("thing must have fields"));
}
$self->setCollateral("Thingy_things","thingId",{
thingId=>$thingId,
label=>$form->process("label"),
editScreenTitle=>$form->process("editScreenTitle"),
editInstructions=>$form->process("editInstructions"),
groupIdAdd=>$form->process("groupIdAdd"),
groupIdEdit=>$form->process("groupIdEdit"),
saveButtonLabel=>$form->process("saveButtonLabel"),
afterSave=>$form->process("afterSave"),
editTemplateId=>$form->process("editTemplateId") || 1,
onAddWorkflowId=>$form->process("onAddWorkflowId"),
onEditWorkflowId=>$form->process("onEditWorkflowId"),
onDeleteWorkflowId=>$form->process("onDeleteWorkflowId"),
groupIdView=>$form->process("groupIdView"),
viewTemplateId=>$form->process("viewTemplateId") || 1,
defaultView=>$form->process("defaultView"),
searchScreenTitle=>$form->process("searchScreenTitle"),
searchDescription=>$form->process("searchDescription"),
groupIdSearch=>$form->process("groupIdSearch"),
groupIdImport=>$form->process("groupIdImport"),
groupIdExport=>$form->process("groupIdExport"),
searchTemplateId=>$form->process("searchTemplateId") || 1,
thingsPerPage=>$form->process("thingsPerPage") || 25,
sortBy=>$form->process("sortBy") || '',
exportMetaData=>$form->process("exportMetaData") || '',
maxEntriesPerUser=>$form->process("maxEntriesPerUser") || '',
},0,1);
while (my $field = $fields->hashRef) {
my $display = $self->session->form->process("display_".$field->{fieldId}) || 0;
@ -2269,6 +2459,7 @@ sub www_editThingSave {
$self->session->db->write("update Thingy_fields set display = ?, viewScreenTitle = ?, displayinSearch = ?, searchIn = ? where fieldId = ? and thingId = ?",[$display, $viewScreenTitle, $displayInSearch, $searchIn, $field->{fieldId}, $thingId]);
}
$self->indexThing($thing);
return $self->www_manage;
}
#-------------------------------------------------------------------
@ -3135,13 +3326,7 @@ sub www_manage {
'thing_searchUrl' => $session->url->append($url, 'func=search;thingId='.$thing->{thingId}),
);
# set the url for the view icon to the things default view
my $viewParams;
if ($thing->{defaultView} eq "addThing") {
$viewParams = 'func=editThingData;thingId='.$thing->{thingId}.';thingDataId=new';
}
else{
$viewParams = 'func=search;thingId='.$thing->{thingId};
}
my $viewParams = $self->getThingUrl($thing);
$templateVars{'thing_viewIcon'} = $session->icon->view($viewParams);
push (@things_loop, \%templateVars);
}
@ -3602,6 +3787,11 @@ The unique id of a thing.
The unique id of a row of thing data.
=head3 templateId
Optional. The unique id or url of the template to be used. When specified, the style template is not used.
If omitted, the thing data view template and style will be used.
=cut
sub www_viewThingData {
@ -3610,7 +3800,7 @@ sub www_viewThingData {
my $session = $self->session;
my $thingId = shift || $session->form->process('thingId');
my $thingDataId = shift || $session->form->process('thingDataId');
my $templateId = shift || $session->form->process('templateId');
my $var = $self->get;
my $url = $self->getUrl;
my $i18n = WebGUI::International->new($self->session, "Asset_Thingy");
@ -3640,9 +3830,19 @@ sub www_viewThingData {
$self->getViewThingVars($thingId,$thingDataId,$var);
$self->appendThingsVars($var, $thingId);
my $template;
if( $templateId )
{
$template = WebGUI::Asset::Template->newByUrl( $session, $templateId ) ||
WebGUI::Asset::Template->newByDynamicClass( $session, $templateId );
}
return $self->processStyle(
$self->processTemplate($var,$thingProperties->{viewTemplateId})
);
$self->processTemplate($var,$thingProperties->{viewTemplateId})
) if !$template;
return $self->processTemplate($var,$template->getId,$template);
}
#-------------------------------------------------------------------

View file

@ -0,0 +1,59 @@
package WebGUI::Help::Asset_Map;
use strict;
our $HELP = {
'view template' => {
title => 'view template',
body => '',
isa => [
{ namespace => 'Asset_Template',
tag => 'template variables'
},
{ namespace => 'Asset_Map',
tag => 'map asset template variables'
},
],
fields => [],
variables => [
{ name => 'canAddPoint', },
{ name => 'canEdit', },
{ name => 'mapPoints', required => 1, },
{ name => 'button_addPoint', required => 1, },
{ name => 'button_setCenter', required => 1, },
{ name => 'button_setCenter', selectPoint => 1, },
],
related => []
},
'map asset template variables' => {
private => 1,
title => 'map asset template variables',
body => '',
isa => [
{ namespace => 'Asset',
tag => 'asset template asset variables'
},
],
fields => [],
variables => [
{ name => 'groupIdAddPoint', },
{ name => 'mapApiKey', },
{ name => 'mapHeight', },
{ name => 'mapWidth', },
{ name => 'startLatitude', },
{ name => 'startLongitude', },
{ name => 'startZoom', },
{ name => 'templateIdEditPoint', },
{ name => 'templateIdView', },
{ name => 'templateIdViewPoint', },
{ name => 'workflowIdPoint', },
{ name => 'canAddPoint', },
{ name => 'canEdit', },
],
related => []
},
};
1;

View file

@ -10,6 +10,9 @@ our $HELP = {
{ namespace => 'Asset_Template',
tag => 'template variables'
},
{ namespace => 'Asset_MapPoint',
tag => 'map point asset template variables'
},
],
fields => [],
variables => [
@ -32,6 +35,8 @@ our $HELP = {
{ name => 'form_fax', },
{ name => 'form_email', },
{ name => 'user defined variables', },
{ name => 'form_isHidden', },
{ name => 'form_isGeocoded', },
],
related => []
},

View file

@ -152,6 +152,12 @@ our $HELP = {
{ 'name' => 'field_pretext' },
],
},
{
'name' => 'variables by label',
}
{
'name' => 'fields',
}
],
related => [
{ tag => 'edit thing template',

View file

@ -0,0 +1,66 @@
package WebGUI::Macro::RenderThingData;
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2011 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 WebGUI::Group;
use WebGUI::Asset::Template;
use WebGUI::Asset::Wobject::Thingy;
=head1 NAME
Package WebGUI::Macro::RenderThingData
=head1 DESCRIPTION
Macro that allows users to render thing data.
=head2 process ( thingURL, templateHint )
=head3 thingHint
The URL from which to pull the thingId and thingDataId
=head3 templateHint
Optional. Specifies the templateId or template url to use. If omitted, the default thingy view template will be used.
=cut
#-------------------------------------------------------------------
sub process {
my ($session, $thingDataUrl, $templateHint ) = @_;
my $uri = URI->new( $thingDataUrl );
my $urlHash = { $uri->query_form };
my $thingId = $urlHash->{'thingId'};
my $thingDataId = $urlHash->{'thingDataId'};
my $thing = WebGUI::Asset::Wobject::Thingy->newByUrl( $session, $uri->path );
# TODO: i18n
return ( "Bad URL: " . $thingDataUrl ) if !$thing || !$thingId || !$thingDataId;
# Render
my $output = $thing->www_viewThingData( $thingId, $thingDataId, $templateHint );
# FIX: Temporary solution (broken map due to template rendering <script> tags)
return "RenderThingData: Please specify a template." if !$templateHint;
return "RenderThingData: Contained bad tags!" if $output =~ /script>/;
return $output;
}
1;

View file

@ -35,12 +35,12 @@ These methods are available from this package:
=cut
#-------------------------------------------------------------------
=head2 addFile ( path )
Use an external filter defined in the config file as searchIndexerPlugins.
Use an external filter defined in the config file as searchIndexerPlugins to pull keywords from a file and
add them to the index.
=head3 path
@ -51,22 +51,11 @@ The path to the filename to index, including the filename.
sub addFile {
my $self = shift;
my $path = shift;
my $filters = $self->session->config->get("searchIndexerPlugins");
my $content;
if ($path =~ m/\.(\w+)$/) {
my $type = lc($1);
if ($filters->{$type}) {
open my $fh, "$filters->{$type} $path |" or return undef; # open pipe to filter
$content = do { local $/; <$fh> }; # slurp file
close $fh;
}
}
return $self->addKeywords($content)
if $content =~ m/\S/; # only index if we fine non-whitespace
return undef;
my $keywords = $self->getKeywordsForFile($path);
return unless $keywords =~ /\S/;
return $self->addKeywords($keywords)
}
#-------------------------------------------------------------------
=head2 addKeywords ( text )
@ -84,8 +73,39 @@ sub addKeywords {
my $text = join(" ", @_);
$text = $self->_filterKeywords($text);
my ($keywords) = $self->session->db->quickArray("select keywords from assetIndex where assetId=?",[$self->getId]);
$self->session->db->write("update assetIndex set keywords =? where assetId=?", [$keywords.' '.$text, $self->getId]);
my ($keywords) = $self->session->db->quickArray("select keywords from assetIndex where assetId=? and url=?",[$self->getId, $self->asset->get('url')]);
$self->session->db->write("update assetIndex set keywords =? where assetId=? and url=?", [$keywords.' '.$text, $self->getId, $self->asset->get('url')]);
}
#-------------------------------------------------------------------
=head2 addRecord ( %fields )
Adds a duplicate record for the current asset, along with fields that are overridden.
=head3 %fields
A hash of fields to override in the record. Entries for url and keywords are mandatory, and
no record will be added unless they exist in the hash.
The lineage entry cannot be overridden.
=cut
sub addRecord {
my $self = shift;
my %fields = @_;
return unless $fields{url} and $fields{keywords};
my $asset = $self->asset;
##Get the asset's record from the database.
my %defaults = $self->session->db->quickHash('select * from assetIndex where assetId=? and url=?', [$asset->get('assetId'), $asset->get('url')]);
$fields{keywords} = $self->_filterKeywords($fields{keywords});
%fields = (%defaults, %fields);
$fields{lineage} = $defaults{lineage};
my $add = $self->session->db->prepare("replace into assetIndex (assetId, url, title, creationDate, revisionDate,
ownerUserId, groupIdView, groupIdEdit, lineage, className, synopsis, keywords, subId) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )");
$add->execute([@fields{qw/assetId url title creationDate revisionDate ownerUserId groupIdView groupIdEdit lineage className synopsis keywords subId/}]);
}
@ -214,6 +234,36 @@ sub getId {
return $self->{_id};
}
#-------------------------------------------------------------------
=head2 getKeywordsForFile ( path )
Use an external filter defined in the config file as searchIndexerPlugins to get keywords
from a file.
=head3 path
The path to the filename to index, including the filename.
=cut
sub getKeywordsForFile {
my $self = shift;
my $path = shift;
my $filters = $self->session->config->get("searchIndexerPlugins");
my $content;
if ($path =~ m/\.(\w+)$/) {
my $type = lc($1);
if ($filters->{$type}) {
open my $fh, "$filters->{$type} $path |" or return undef; # open pipe to filter
$content = do { local $/; <$fh> }; # slurp file
close $fh;
}
}
return $content;
}
#-------------------------------------------------------------------
=head2 setIsPublic ( boolean )

View file

@ -168,11 +168,133 @@ our $I18N = {
lastUpdated => 0,
context => "Choose from the list of points that existon the map",
},
'assetName' => {
message => "Map",
lastUpdated => 0,
context => "Name of this asset",
},
'canAddPoint' => {
message => "A boolean which is true if the current user can add a new point to the map",
lastUpdated => 0,
context => "template variable help",
},
'canEdit' => {
message => "A boolean which is true if the current user can edit this Map asset",
lastUpdated => 0,
context => "template variable help",
},
'map asset template variables' => {
message => "Map Asset Template Variables",
lastUpdated => 0,
context => "template variable help",
},
'view template' => {
message => "Map Asset View Template",
lastUpdated => 0,
context => "template variable help",
},
'groupIdAddPoint' => {
message => "The GUID of the group that can add points to the Map",
lastUpdated => 0,
context => "template variable help",
},
'mapApiKey' => {
message => "The Google Maps API key",
lastUpdated => 0,
context => "template variable help",
},
'mapHeight' => {
message => "The height of the map, in pixels",
lastUpdated => 0,
context => "template variable help",
},
'mapWidth' => {
message => "The width of the map, in pixels",
lastUpdated => 0,
context => "template variable help",
},
'startLatitude' => {
message => "The starting latitude of the map, for the center",
lastUpdated => 0,
context => "template variable help",
},
'startLongitude' => {
message => "The starting longitude of the map, for the center",
lastUpdated => 0,
context => "template variable help",
},
'startZoom' => {
message => "The starting zoom level of the map",
lastUpdated => 0,
context => "template variable help",
},
'templateIdEditPoint' => {
message => "The GUID of the template for addding or editing a point.",
lastUpdated => 0,
context => "template variable help",
},
'templateIdView' => {
message => "The GUID of the template for viewing the map.",
lastUpdated => 0,
context => "template variable help",
},
'templateIdViewPoint' => {
message => "The GUID of the template for viewing a point of the map.",
lastUpdated => 0,
context => "template variable help",
},
'workflowIdPoint' => {
message => "The GUID of the workflow for committing a Map Point.",
lastUpdated => 0,
context => "template variable help",
},
'mapPoints' => {
message => "A loop of map points. See the MapPoint template variables for a list of available ones.",
lastUpdated => 0,
context => "template variable help",
},
'mapPoints' => {
message => "A loop of map points. See the MapPoint template variables for a list of available ones.",
lastUpdated => 0,
context => "template variable help",
},
'button_addPoint' => {
message => "A templated button with internationalized label to add a button.",
lastUpdated => 0,
context => "template variable help",
},
'button_setCenter' => {
message => "A templated button with internationalized label to set the center of the map back to the default.",
lastUpdated => 0,
context => "template variable help",
},
'selectPoint' => {
message => "A templated dropdown to center the map on a point, and to display it's information.",
lastUpdated => 0,
context => "template variable help",
},
};
1;

View file

@ -133,7 +133,16 @@ our $I18N = {
lastUpdated => 0,
context => 'Description of asset property',
},
'isGeocoded label' => {
message => 'Automatically Position',
lastUpdated => 0,
context => 'Label for asset property',
},
'isGeocoded description' => {
message => q{Choose whether or not this map point should be automatically positioned having it's latitude and longitude dynamically set based on the address. Choosing "Yes" will make the point unable to be moved on the map.},
lastUpdated => 0,
context => 'Description of asset property',
},
'assetName' => {
message => "MapPoint",
lastUpdated => 0,
@ -380,6 +389,17 @@ our $I18N = {
context => "template variable help",
},
'form_isHidden' => {
message => "A yes/no field indicating whether or not the Map Point should display in navigations.",
lastUpdated => 0,
context => "template variable help",
},
'form_isGeocoded' => {
message => "A checkbox field indicating whether or not the Map Point should be automatically placed on the map based on it's address.",
lastUpdated => 0,
context => "template variable help",
},
};
1;

View file

@ -1144,6 +1144,12 @@ below/after the form element.|,
context => q|Status message in the Export Thingy progress bar. %s is the name of the Thing that is being exported.|,
},
'variables by label' => {
message => q|In addition to the <b>field_loop</b>, field values may be directly accessed via their label. Please check the documentation for the template plugin that you are using to handle odd characters like spaces or quotes in the label.|,
lastUpdated => 1231180362,
context => q|Template variable help for getViewThingData|,
},
};
1;

View file

@ -156,6 +156,7 @@ checkModule('Net::Twitter', "3.13006" );
checkModule('PerlIO::eol', "0.14" );
checkModule('Monkey::Patch', '0.03' );
checkModule('Data::ICal', '0.16' );
checkModule('Geo::Coder::Googlev3', '2.18' );
failAndExit("Required modules are missing, running no more checks.") if $missingModule;

143
t/Asset/MapPoint.t Normal file
View file

@ -0,0 +1,143 @@
#-------------------------------------------------------------------
# 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
#-------------------------------------------------------------------
# 1. The basic framework for a test suite for Map Points.
# Includes setup, cleanup, boilerplate, etc. Basically the really boring,
# repetitive parts of the test that you don't want to write yourself.
use FindBin;
use strict;
use lib "$FindBin::Bin/../lib";
use WebGUI::Test;
use WebGUI::Session;
use Test::More tests => 18; # increment this value for each test you create
use Test::Deep;
use WebGUI::Asset::Wobject::Map;
use WebGUI::Asset::MapPoint;
use WebGUI::Search;
my $session = WebGUI::Test->session;
#Run as Admin
$session->user({ userId => 3 });
# Do our work in the import node
my $node = WebGUI::Asset->getImportNode($session);
# Grab a named version tag
my $versionTag = WebGUI::VersionTag->getWorking($session);
$versionTag->set({name=>"Map setup"});
# Create a map
my $map = $node->addChild({
className => 'WebGUI::Asset::Wobject::Map',
mapApiKey => undef,
startZoom => "0",
workflowIdPoint => "pbworkflow000000000003",
});
#Commit the map before creating the map point
$versionTag->commit();
WebGUI::Test->addToCleanup($versionTag);
# Create a map point
my $test_point = {
website => 'http://www.plainblack.com',
address1 => '520 University Ave',
address2 => 'Suite 320',
city => 'Madison',
region => 'WI',
zipCode => '53703',
country => 'United States',
phone => '608-555-1212',
fax => '608-555-1212',
email => 'info@plainblack.com',
userDefined1 => 'one-plainblack',
userDefined2 => 'two-plainblack',
userDefined3 => 'three-plainblack',
userDefined4 => 'four-plainblack',
userDefined5 => 'five-plainblack',
};
my $mapPoint = $map->addChild({
className => 'WebGUI::Asset::MapPoint',
latitude => '43.0736',
longitude => '-89.3946',
%{$test_point}
});
#Call commit manually so we don't have to wait on spectre to run the autocommit workflow
$mapPoint->commit;
# Test for a sane object type
isa_ok($mapPoint, 'WebGUI::Asset::MapPoint');
################################################################
#
# indexContent
#
################################################################
# Test indexContent to make sure keywords are added to assetIndex by searching for them and
# ensuring the asset is returned in the results. indexContent itself does not need to be called
# because commit takes care of that for us.
#In all cases we should get back the one map point for these tests.
my $expected = [$mapPoint->getId];
foreach my $keyword (keys %$test_point) {
my $assetIds = WebGUI::Search->new($session)->search({
keywords => $test_point->{$keyword},
lineage => [ $map->get("lineage") ] #Limit the search to just map points under the newly create map.
})->getAssetIds;
is_deeply( $assetIds, $expected, "$keyword found in search" );
}
#my $assetIds = WebGUI::Search->new($session)->search(\%rules)->getAssetIds;
################################################################
#
# processAjaxEditForm
#
################################################################
#Test isHidden
sleep 1; #Make sure we have a different revision date
my $test_point_edit = {
%{$test_point},
'assetId' => $mapPoint->getId,
'isHidden' => 1,
};
$session->request->setup_body($test_point_edit);
$map->www_ajaxEditPointSave;
#Get the newest mapPoint revision
$mapPoint = WebGUI::Asset->newPending($session,$mapPoint->getId);
is($mapPoint->get("isHidden"),1,"isHidden changed");
#TO DO - Try to change isHidden as a user who can add points but cannot edit
#Test isGeocoded
sleep 1; #Make sure we have a different revision date
$test_point_edit = {
%{$test_point},
'assetId' => $mapPoint->getId,
'isGeocoded' => 1,
};
$session->request->setup_body($test_point_edit);
$map->www_ajaxEditPointSave;
#Get the newest mapPoint revision
$mapPoint = WebGUI::Asset->newPending($session,$mapPoint->getId);
is($mapPoint->get("isGeocoded"),1,"isGeocoded changed");

View file

@ -0,0 +1,97 @@
#-------------------------------------------------------------------
# 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 FindBin;
use strict;
use JSON qw/from_json/;
use lib "$FindBin::Bin/../../../lib";
##The goal of this test is to test the searching for and returning data about
##records created with WebGUI::Search::Index::addRecord;
use WebGUI::Test;
use WebGUI::Session;
use Test::More tests => 6; # increment this value for each test you create
use Test::Deep;
use WebGUI::Asset::Wobject::Search;
my $session = WebGUI::Test->session;
$session->user({userId => 3});
# Do our work in the import node
my $node = WebGUI::Asset->getImportNode($session);
my $default = WebGUI::Asset->getDefault($session);
my $importArticle = $node->addChild({
className => 'WebGUI::Asset::Wobject::Article',
description => 'rockhound',
});
my $templateId = 'SEARCH_ASSET_TEMPLATE_';
my $templateMock = Test::MockObject->new({});
$templateMock->set_isa('WebGUI::Asset::Template');
$templateMock->set_always('getId', $templateId);
$templateMock->set_always('prepare', 1);
my $templateVars;
$templateMock->mock('process', sub { $templateVars = $_[1]; } );
my $defaultArticle = $default->addChild({
className => 'WebGUI::Asset::Wobject::Article',
description => 'shawshank prison',
url => 'introduction'
});
my $search = $default->addChild({
className => 'WebGUI::Asset::Wobject::Search',
searchRoot => $default->getId,
templateId => $templateId,
});
my $tag = WebGUI::VersionTag->getWorking($session);
$tag->commit;
WebGUI::Test->addToCleanup($tag);
my $indexer = WebGUI::Search::Index->new($defaultArticle);
$indexer->addRecord(url => 'brochure', keywords => 'roomy spacious prison');
{
WebGUI::Test->mockAssetId($templateId, $templateMock);
$search->prepareView();
$session->request->setup_body({doit => 1, keywords => 'shawshank'});
$search->view();
WebGUI::Test->unmockAssetId($templateId);
}
is scalar @{ $templateVars->{result_set} }, 1, 'search for shawshank, returns 1 record';
is $templateVars->{result_set}->[0]->{url}, 'introduction', '... url is correct';
{
WebGUI::Test->mockAssetId($templateId, $templateMock);
$search->prepareView();
$session->request->setup_body({doit => 1, keywords => 'prison'});
$search->view();
WebGUI::Test->unmockAssetId($templateId);
}
is scalar @{ $templateVars->{result_set} }, 2, 'search for prison, returns 2 records';
cmp_bag(
[ map { $_->{url} } @{ $templateVars->{result_set} } ],
[qw/ introduction brochure/ ],
'... urls are correct'
);
cmp_bag(
[ map { $_->{groupIdView} } @{ $templateVars->{result_set} } ],
[ 7, 7 ],
' groupIdViews are correct (2nd record inherits from the parent)'
);
cmp_bag(
[ map { $_->{title_nohighlight} } @{ $templateVars->{result_set} } ],
[ ($defaultArticle->get('title'))x2 ],
' titles are correct (2nd record inherits from the parent)'
);

View file

@ -38,6 +38,8 @@ my $versionTag = WebGUI::VersionTag->getWorking($session);
$versionTag->set({name=>"Thingy Test"});
WebGUI::Test->addToCleanup($versionTag);
my $thingy = $node->addChild({className=>'WebGUI::Asset::Wobject::Thingy'});
$versionTag->commit;
$thingy = $thingy->cloneFromDb;
# Test for a sane object type
isa_ok($thingy, 'WebGUI::Asset::Wobject::Thingy');
@ -257,6 +259,7 @@ cmp_deeply(
field_type => "textarea",
}],
viewScreenTitle => "",
'Thingy field' => 'test value',
},
'Getting newly added thing data as JSON: www_viewThingDataViaAjax returns correct data as JSON.'
);

View file

@ -0,0 +1,294 @@
#-------------------------------------------------------------------
# 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 Test::MockTime qw/:all/;
use FindBin;
use strict;
use lib "$FindBin::Bin/../../../lib";
##The goal of this test is to test editThingDataSave, particularly those things not tested in Thingy.t
use WebGUI::Test;
use WebGUI::Session;
use Test::More tests => 24; # increment this value for each test you create
use Test::Deep;
use JSON;
use WebGUI::Asset::Wobject::Thingy;
use WebGUI::Search;
use WebGUI::Search::Index;
use Data::Dumper;
my $session = WebGUI::Test->session;
# Do our work in the import node
my $node = WebGUI::Asset->getImportNode($session);
set_relative_time(-60);
my $versionTag = WebGUI::VersionTag->getWorking($session);
$versionTag->set({name=>"Thingy Test"});
WebGUI::Test->addToCleanup($versionTag);
my $thingy = $node->addChild({
className => 'WebGUI::Asset::Wobject::Thingy',
groupIdView => 7,
url => 'some_thing',
});
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 0, 'no records yet';
$versionTag->commit;
$thingy = $thingy->cloneFromDb;
# Test indexThing, without needing a real thing
my $groupIdEdit = $thingy->get("groupIdEdit");
my %thingProperties = (
thingId => "THING_RECORD",
label => 'Label',
editScreenTitle => 'Edit',
editInstructions => 'instruction_edit',
groupIdAdd => $groupIdEdit,
groupIdEdit => $groupIdEdit,
saveButtonLabel => 'save',
afterSave => 'searchThisThing',
editTemplateId => "ThingyTmpl000000000003",
groupIdView => '2',
viewTemplateId => "ThingyTmpl000000000002",
defaultView => 'searchThing',
searchScreenTitle => 'Search',
searchDescription => 'description_search',
groupIdSearch => $groupIdEdit,
groupIdExport => $groupIdEdit,
groupIdImport => $groupIdEdit,
searchTemplateId => "ThingyTmpl000000000004",
thingsPerPage => 25,
);
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 1, 'committing the asset adds a record';
$thingy->indexThing(\%thingProperties);
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 2, 'indexThing: adds a record to the assetIndex';
my $record;
$record = $session->db->quickHashRef('select * from assetIndex where assetId=?',[$thingy->getId]);
cmp_deeply(
$record,
superhashof({
subId => 'THING_RECORD',
url => $thingy->getUrl('func=search;thingId=THING_RECORD'),
title => 'Label',
groupIdView => 2,
keywords => all(
re('Label'),
re('Edit'),
re('instruction_edit'),
re('Search'),
re('description_search'),
),
}),
'... correct record entered via indexThing'
);
$thingy->deleteThingIndex('THING_RECORD');
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 1, 'deleteThingIndex removes the record of the Thing from assetIndex';
$thingy->indexThing(\%thingProperties);
$thingProperties{saveButtonLabel} = 'Save';
$thingy->indexThing(\%thingProperties);
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 2, 'indexThing safely handles updating the same record';
$thingy->deleteThingIndex('THING_RECORD');
my $thingId = $thingy->addThing(\%thingProperties);
%thingProperties = %{ $thingy->getThing($thingId) };
$thingy->indexThing(\%thingProperties);
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 2, 'two index entries, setup for indexThingData';
my $field1Id = $thingy->addField({
thingId => $thingId,
fieldId => "new",
label => "textual",
dateCreated => time(),
fieldType => "text",
status => "editable",
display => 1,
}, 0);
$thingy->indexThingData($thingId, {
thingDataId => 'THING_DATA',
"field_$field1Id" => 'texty',
});
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 2, 'indexThingData added no records, displayInSearch=0';
$thingy->deleteField($field1Id, $thingId);
$field1Id = $thingy->addField({
thingId => $thingId,
fieldId => "new",
label => "textual",
dateCreated => time(),
fieldType => "text",
status => "editable",
display => 1,
displayInSearch => 1,
}, 0);
$thingy->indexThingData($thingId, {
thingDataId => 'THING_DATA',
"field_$field1Id" => 'texty',
});
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 3, 'indexThingData added one record, displayInSearch=1';
$thingy->indexThingData($thingId, {
thingDataId => 'THING_DATA',
"field_$field1Id" => 'texty',
});
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 3, 'indexThingData added 1 record';
my $search;
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], keywords => 'texty'});
is @{ $search->getAssetIds }, 1, '... verify that it is the right record';
cmp_deeply(
$search->getPaginatorResultSet->getPageData,
[
{
assetId => $thingy->getId,
className => 'WebGUI::Asset::Wobject::Thingy',
creationDate => ignore(),
groupIdEdit => $groupIdEdit,
groupIdView => 2, ##From the thing
ownerUserId => 3,
revisionDate => ignore(),
score => ignore(),
synopsis => ignore(),
title => 'Label', ##From the Thing's label
url => $thingy->getUrl('func=viewThingData;thingId='.$thingId.';thingDataId=THING_DATA'),
}
],
'Checking indexed data for the thingData'
);
$thingy->deleteThingDataIndex('THING_DATA');
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 2, 'deleteThingDataIndex deleted just 1 record';
my $field2Id = $thingy->addField({
thingId => $thingId,
fieldId => "new",
label => "dated",
dateCreated => time(),
fieldType => "date",
status => "editable",
display => 1,
displayInSearch => 1,
viewScreenTitle => 1,
}, 0);
my $birthday = WebGUI::Test->webguiBirthday;
$thingy->indexThingData($thingId, {
thingDataId => 'THING_DATA',
"field_$field1Id" => 'texty',
"field_$field2Id" => $birthday,
});
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?',[$thingy->getId]), 3, 'indexThingData added 1 record';
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], keywords => $birthday});
is @{ $search->getAssetIds }, 0, 'birthday not added as a keyword';
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], keywords => 'texty'});
is @{ $search->getAssetIds }, 1, 'texty added as a keyword';
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], keywords => 'texty'});
cmp_deeply(
$search->getPaginatorResultSet->getPageData,
[
{
assetId => $thingy->getId,
className => 'WebGUI::Asset::Wobject::Thingy',
creationDate => ignore(),
groupIdEdit => $groupIdEdit,
groupIdView => 2, ##From the thing
ownerUserId => 3,
revisionDate => ignore(),
score => ignore(),
synopsis => ignore(),
title => '8/16/2001', ##From viewScreenTitle, which is $birthday in user's preferred date format
url => $thingy->getUrl('func=viewThingData;thingId='.$thingId.';thingDataId=THING_DATA'),
}
],
'Checking indexed data for the thingData'
);
$thingy->deleteThingDataIndex('THING_DATA');
my $field3Id = $thingy->addField({
thingId => $thingId,
fieldId => "new",
label => "nailfile",
dateCreated => time(),
fieldType => "file",
status => "editable",
display => 1,
displayInSearch => 1,
}, 0);
my $storage = WebGUI::Storage->create($session);
$storage->addFileFromScalar('filing.txt', 'filings');
WebGUI::Test->addToCleanup($storage);
$thingy->indexThingData($thingId, {
thingDataId => 'THING_DATA',
"field_$field1Id" => 'texty',
"field_$field2Id" => $birthday,
"field_$field3Id" => $storage->getId,
});
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], keywords => 'texty'});
is @{ $search->getAssetIds }, 1, 'texty added as a keyword';
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], keywords => 'filings'});
is @{ $search->getAssetIds }, 1, 'filings added as a keyword from a file';
restore_time();
##Make a real data entry for indexContent
$thingy->deleteThingDataIndex('THING_DATA');
$thingy->editThingDataSave($thingId, 'new', {
thingDataId => 'new',
"field_$field1Id" => 'texty',
"field_$field2Id" => $birthday,
"field_$field3Id" => $storage->getId,
});
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], });
is @{ $search->getAssetIds }, 3, 'setup for indexContent, start with 3 records...';
my $updateTag = WebGUI::VersionTag->getWorking($session);
WebGUI::Test->addToCleanup($updateTag);
$thingy = $thingy->addRevision({ url => 'wild_thing' });
$updateTag->commit;
$thingy = $thingy->cloneFromDb;
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], });
is @{ $search->getAssetIds }, 3, '... end with 3 records';
my $records = $search->getResultSet();
my @urls;
while (my $record = $records->hashRef) {
push @urls, $record->{url};
}
cmp_deeply(
\@urls,
array_each(re('wild_thing')),
'All search URLs updated on commit'
) or diag Dumper(\@urls);
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], keywords => 'texty'});
is @{ $search->getAssetIds }, 1, 'setup for deleteField, texty keyword has one hit';
$thingy->deleteField($field1Id, $thingId);
$search = WebGUI::Search->new($session)->search({ lineage => [$thingy->get('lineage')], keywords => 'texty'});
is @{ $search->getAssetIds }, 0, 'deleteField causes the thing to be reindexed';

View file

@ -40,7 +40,7 @@ WebGUI::Test->addToCleanup(
#----------------------------------------------------------------------------
# Tests
plan tests => 16; # Increment this number for each test you create
plan tests => 24; # Increment this number for each test you create
use_ok( 'WebGUI::Search::Index' );
@ -72,6 +72,7 @@ cmp_deeply (
re("keyword1"), re("keyword2"),
),
lineage => $article->get('lineage'),
subId => undef,
},
"Index has correct information"
);
@ -84,7 +85,7 @@ is( $indexer->getId, $article->getId, "getId() returns assetId" );
# setIsPublic
$indexer->setIsPublic(0);
is( $db->quickScalar( "SELECT isPublic FROM assetIndex WHERE assetId=?", [$article->getId] ),
is( $db->quickScalar( "SELECT isPublic FROM assetIndex WHERE assetId=? and url=?", [$article->getId, $article->get('url')] ),
0,
"setIsPublic updates database",
);
@ -94,7 +95,7 @@ isa_ok( $indexer->session, 'WebGUI::Session', 'session returns session' );
# updateSynopsis
$indexer->updateSynopsis( "A new synopsis" );
is( $db->quickScalar( "SELECT synopsis FROM assetIndex WHERE assetId=?", [$article->getId] ),
is( $db->quickScalar( "SELECT synopsis FROM assetIndex WHERE assetId=? and url=?", [$article->getId, $article->get('url')] ),
"A new synopsis",
"updateSynopsis updates assetIndex"
);
@ -109,9 +110,9 @@ isnt(
# TODO
# addKeywords
my $currentKeywords = $db->quickScalar( "SELECT keywords FROM assetIndex WHERE assetId=?", [$article->getId] );
my $currentKeywords = $db->quickScalar( "SELECT keywords FROM assetIndex WHERE assetId=? and url=?", [$article->getId, $article->get('url')] );
$indexer->addKeywords("shawshank");
my $newKeywords = $db->quickScalar( "SELECT keywords FROM assetIndex WHERE assetId=?", [$article->getId] );
my $newKeywords = $db->quickScalar( "SELECT keywords FROM assetIndex WHERE assetId=? and url=?", [$article->getId, $article->get('url')] );
like( $newKeywords, qr{$currentKeywords}, "addKeywords keeps old keywords" );
like( $newKeywords, qr{shawshank}, "addKeywords adds the keywords" );
@ -123,7 +124,7 @@ $article->update({
} );
$indexer = WebGUI::Search::Index->create( $article );
ok ( $row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=?", [ $article->getId ] ),
ok ( $row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=? and url=?", [ $article->getId, $article->get('url') ] ),
"assetId exists in assetIndex"
);
cmp_deeply (
@ -148,6 +149,7 @@ cmp_deeply (
re("keyword1"), re("keyword2"),
),
lineage => $article->get('lineage'),
subId => undef,
},
"Index has synopsis information in keywords"
);
@ -161,7 +163,7 @@ $article->update({
});
$indexer = WebGUI::Search::Index->create( $article );
$row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=?", [ $article->getId ]);
$row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=? and url=?", [ $article->getId, $article->get('url') ]);
cmp_deeply (
$row,
{
@ -184,6 +186,7 @@ cmp_deeply (
re("keyword1"), re("keyword2"),
),
lineage => $article->get('lineage'),
subId => undef,
},
"Index has description in keywords"
);
@ -197,7 +200,7 @@ $article->update({
});
$indexer = WebGUI::Search::Index->create( $article );
$row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=?", [ $article->getId ] );
$row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=? and url=?", [ $article->getId, $article->get('url') ] );
cmp_deeply (
$row,
{
@ -219,6 +222,7 @@ cmp_deeply (
re("keyword1"), re("keyword2"),
),
lineage => $article->get('lineage'),
subId => undef,
},
"Index has synopsis and description in keywords"
);
@ -230,7 +234,7 @@ $article->update({
});
$indexer = WebGUI::Search::Index->create( $article );
$row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=?", [ $article->getId ] );
$row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=? and url=?", [ $article->getId, $article->get('url') ] );
cmp_deeply (
$row,
superhashof({
@ -256,7 +260,7 @@ SKIP: {
});
$indexer = WebGUI::Search::Index->create( $article );
$row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=?", [ $article->getId ] );
$row = $db->quickHashRef( "SELECT * FROM assetIndex WHERE assetId=? and url=?", [ $article->getId, $article->get('url') ] );
cmp_deeply (
$row,
superhashof({
@ -270,4 +274,39 @@ SKIP: {
);
}
#----------------------------------------------------------------------------
# Test addRecord
note "addRecord";
$article->update({
description => "descriptive",
});
$indexer = WebGUI::Search::Index->create( $article );
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?', [$article->getId]), 1, 'create puts 1 record into the db';
$indexer->addRecord( url => 'something else');
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?', [$article->getId]), 1, 'addRecord does nothing without url and keywords entries';
$indexer->addRecord( keywords => 'something else');
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?', [$article->getId]), 1, 'addRecord does nothing without url and keywords entries';
$indexer->addRecord( keywords => 'something else', url => '', );
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?', [$article->getId]), 1, 'addRecord does nothing without url and keywords entries';
$indexer->addRecord( keywords => 'something else', url => 'another/thing/coming', );
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?', [$article->getId]), 2, 'new record added';
my %original_record = $session->db->quickHash('select * from assetIndex where assetId=? and url=?', [$article->getId, $article->get('url')]);
my %new_record = $session->db->quickHash('select * from assetIndex where assetId=? and url=?', [$article->getId, 'another/thing/coming']);
delete @original_record{qw/url keywords/};
delete @new_record{qw/url keywords/};
cmp_deeply(\%original_record, \%new_record, 'records are the same, aside from url and keywords');
$indexer->delete;
is $session->db->quickScalar('select count(*) from assetIndex where assetId=?', [$article->getId]), 0, 'all records deleted';
$indexer = WebGUI::Search::Index->create( $article );
$indexer->addRecord(url => 'other', keywords => 'yada yada yada', lineage => 'hike');
my %original_record = $session->db->quickHash('select * from assetIndex where assetId=? and url=?', [$article->getId, $article->get('url')]);
my %new_record = $session->db->quickHash('select * from assetIndex where assetId=? and url=?', [$article->getId, 'other']);
is $original_record{lineage}, $new_record{lineage}, 'lineage is not allowed to be overridden';
#vim:ft=perl

View file

@ -14,15 +14,15 @@ WebGUI.Map.markers = {};
WebGUI.Map.loadingDialog = undefined;
/**
* WebGUI.Map.deletePoint( map, mgr, marker )
* Delete a point from the map.
* NOTE: We assume the user has already confirmed this action
*/
* WebGUI.Map.deletePoint( map, mgr, marker )
* Delete a point from the map.
* NOTE: We assume the user has already confirmed this action
*/
WebGUI.Map.deletePoint
= function ( map, mgr, marker ) {
var callback = function ( text, code ) {
var callback = function ( text, code ) {
WebGUI.Map.hideLoading();
var response = YAHOO.lang.JSON.parse( text );
var response = YAHOO.lang.JSON.parse( text );
// remove the marker from the map
if ( !response.error ) {
mgr.removeMarker( marker );
@ -34,11 +34,11 @@ WebGUI.Map.deletePoint
};
/**
* WebGUI.Map.editPoint( map, mgr, marker )
* Edit a point on the map.
* up the edit box. mgr is the Marker Manager to add the marker
* to.
*/
* WebGUI.Map.editPoint( map, mgr, marker )
* Edit a point on the map.
* up the edit box. mgr is the Marker Manager to add the marker
* to.
*/
WebGUI.Map.editPoint
= function ( map, mgr, marker ) {
var assetId = '';
@ -49,8 +49,8 @@ WebGUI.Map.editPoint
marker.map = map;
mgr.addMarker( marker, 0 );
mgr.refresh();
assetId = "new";
marker.assetId = "new";
assetId = "new";
marker.assetId = "new";
GEvent.addListener( marker, "dragend", function (latlng) {
WebGUI.Map.setPointLocation( marker, latlng );
} );
@ -60,7 +60,7 @@ WebGUI.Map.editPoint
}
// Callback should open the window with the form
var callback = function (text, code) {
var callback = function (text, code) {
YAHOO.util.Dom.addClass( document.body, "yui-skin-sam" );
var dialog = new YAHOO.widget.Dialog("editPoint");
@ -81,9 +81,9 @@ WebGUI.Map.editPoint
this.submit();
}
var myButtons = [
var myButtons = [
{ text:"Submit", handler:handleSubmit, isDefault:true },
{ text:"Cancel", handler:handleCancel }
{ text:"Cancel", handler:handleCancel }
];
dialog.cfg.queueProperty("buttons", myButtons);
dialog.cfg.queueProperty("constraintoviewport", true);
@ -95,37 +95,37 @@ WebGUI.Map.editPoint
dialog.callback = {
upload: function (o) {
// Update marker info
var point = YAHOO.lang.JSON.parse( o.responseText );
marker.assetId = point.assetId;
marker.title = point.title;
var point = YAHOO.lang.JSON.parse( o.responseText );
marker.assetId = point.assetId;
marker.title = point.title;
GEvent.clearListeners( marker, "click" );
GEvent.clearListeners( marker, "infowindowbeforeclose" );
// Decode HTML entities because JSON is being returned as text/html
// See WebGUI::Asset::Wobject::Map www_ajaxEditPointSave
var decoder = document.createElement( "textarea" );
decoder.innerHTML = point.content;
point.content = decoder.value;
decoder.innerHTML = point.content;
point.content = decoder.value;
var infoWin = document.createElement( "div" );
infoWin.innerHTML = point.content;
marker.infoWin = infoWin;
infoWin.innerHTML = point.content;
marker.infoWin = infoWin;
if ( point.canEdit ) {
var divButton = document.createElement('div');
if ( point.canEdit == 1 ) {
var divButton = document.createElement('div');
infoWin.appendChild( divButton );
var editButton = document.createElement("input");
editButton.type = "button";
editButton.value = "Edit";
var editButton = document.createElement("input");
editButton.type = "button";
editButton.value = "Edit";
GEvent.addDomListener( editButton, "click", function () {
WebGUI.Map.editPoint( map, mgr, marker );
WebGUI.Map.editPoint( map, mgr, marker );
} );
divButton.appendChild( editButton );
var deleteButton = document.createElement("input");
deleteButton.type = "button";
deleteButton.value = "Delete"; // Replace with i18n
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, marker );
@ -134,9 +134,19 @@ WebGUI.Map.editPoint
divButton.appendChild( deleteButton );
}
marker.bindInfoWindow( infoWin );
GEvent.addListener( marker, "dragend", function (latlng) {
WebGUI.Map.setPointLocation( marker, latlng );
} );
if( point.isGeocoded == 1 ) {
//Move the marker to the right location
mgr.removeMarker( marker );
marker.setLatLng(new GLatLng( point.latitude, point.longitude ));
marker.disableDragging();
mgr.addMarker(marker,0);
}
else {
marker.enableDragging();
GEvent.addListener( marker, "dragend", function (latlng) {
WebGUI.Map.setPointLocation( marker, latlng );
} );
}
WebGUI.Map.hideLoading();
WebGUI.Map.markers[map.assetId][marker.assetId] = marker;
@ -156,9 +166,9 @@ WebGUI.Map.editPoint
};
/**
* WebGUI.Map.focusOn( pointId )
* Pan the appropriate map to view the appropriate map point
*/
* WebGUI.Map.focusOn( pointId )
* Pan the appropriate map to view the appropriate map point
*/
WebGUI.Map.focusOn
= function ( pointId ) {
var marker;
@ -169,7 +179,7 @@ WebGUI.Map.focusOn
}
}
if ( !marker ) return;
var map = marker.map;
var map = marker.map;
var infoWin = marker.infoWin;
if ( map.getZoom() <= 4 ) {
map.setZoom(5);
@ -184,9 +194,9 @@ WebGUI.Map.hideLoading
};
/**
* WebGUI.Map.preparePoints ( map, mgr, points )
* Prepare the points from WebGUI into Google Map GMarkers
*/
* WebGUI.Map.preparePoints ( map, mgr, points )
* Prepare the points from WebGUI into Google Map GMarkers
*/
WebGUI.Map.preparePoints
= function ( map, mgr, points ) {
WebGUI.Map.markers[map.assetId] = {};
@ -196,34 +206,35 @@ WebGUI.Map.preparePoints
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
var canDrag = (point.canEdit == 1 && point.isGeocoded == 0) ? true : false;
var marker = new GMarker( latlng, {
title: point.title,
draggable: canDrag
} );
marker.assetId = point.assetId;
marker.title = point.title;
marker.map = map;
marker.assetId = point.assetId;
marker.title = point.title;
marker.map = map;
// Create info window
var infoWin = document.createElement( "div" );
infoWin.innerHTML = point.content;
marker.infoWin = infoWin;
infoWin.innerHTML = point.content;
marker.infoWin = infoWin;
// Make editable features
if ( point.canEdit ) {
var divButton = document.createElement('div');
var divButton = document.createElement('div');
var editButton = document.createElement("input");
editButton.type = "button";
editButton.value = "Edit"; // Replace with i18n
var editButton = document.createElement("input");
editButton.type = "button";
editButton.value = "Edit"; // Replace with i18n
GEvent.addDomListener( editButton, "click", function () {
WebGUI.Map.editPoint( map, mgr, marker );
} );
divButton.appendChild( editButton );
var deleteButton = document.createElement("input");
deleteButton.type = "button";
deleteButton.value = "Delete"; // Replace with i18n
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, marker );
@ -248,16 +259,16 @@ WebGUI.Map.preparePoints
};
/**
* 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 ( 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()
var url = baseUrl + '?func=ajaxSetCenter';
var center = map.getCenter();
url = url + ';startLatitude=' + center.lat()
+ ';startLongitude=' + center.lng()
+ ';startZoom=' + map.getZoom()
;
@ -270,9 +281,9 @@ WebGUI.Map.setCenter
};
/**
* WebGUI.Map.setPointLocation( marker, latlng )
* Update the point's location in the database.
*/
* WebGUI.Map.setPointLocation( marker, latlng )
* Update the point's location in the database.
*/
WebGUI.Map.setPointLocation
= function ( marker, latlng ) {
var url = marker.map.url + '?func=ajaxSetPointLocation'
@ -292,14 +303,14 @@ WebGUI.Map.showLoading
= function () {
// Create a loading dialog
if ( !WebGUI.Map.loadingDialog ) {
var loadingDialog = new YAHOO.widget.Panel("loading", { width:"240px",
fixedcenter:true,
close:false,
draggable:false,
var loadingDialog = new YAHOO.widget.Panel("loading", { width:"240px",
fixedcenter:true,
close:false,
draggable:false,
zindex:4,
modal:true,
visible:false
}
}
);
loadingDialog.setHeader("Loading, please wait...");
@ -314,7 +325,7 @@ WebGUI.Map.showLoading
WebGUI.Map.updateSelectPoint
= function (map) {
var select = document.getElementById( 'selectPoint_' + map.assetId );
var select = document.getElementById( 'selectPoint_' + map.assetId );
if ( !select) {
return;
}
@ -325,14 +336,14 @@ WebGUI.Map.updateSelectPoint
}
var markers = WebGUI.Map.markers[map.assetId];
var sorted = [];
var sorted = [];
for ( var pointId in markers ) {
sorted.push( pointId );
}
sorted.sort( function (a,b) {
var ma = WebGUI.Map.markers[map.assetId][a];
var mb = WebGUI.Map.markers[map.assetId][b];
sorted.sort( function (a,b) {
var ma = WebGUI.Map.markers[map.assetId][a];
var mb = WebGUI.Map.markers[map.assetId][b];
if ( ma.title > mb.title ) { return 1; }
else if ( ma.title < mb.title ) { return -1; }