diff --git a/docs/changelog/6.x.x.txt b/docs/changelog/6.x.x.txt index 70ff1b2cb..44736108e 100644 --- a/docs/changelog/6.x.x.txt +++ b/docs/changelog/6.x.x.txt @@ -16,6 +16,7 @@ templates. - Added Spectre, WebGUI's new background processing engine which manages things like scheduled tasks and workflow processing. + - Added Matrix asset. 6.7.7 diff --git a/docs/upgrades/upgrade_6.7.8-6.8.0.pl b/docs/upgrades/upgrade_6.7.8-6.8.0.pl index 7dcb4dad5..c190463eb 100644 --- a/docs/upgrades/upgrade_6.7.8-6.8.0.pl +++ b/docs/upgrades/upgrade_6.7.8-6.8.0.pl @@ -35,8 +35,573 @@ addAvatarField(); addEnableAvatarColumn(); addSpectre(); addWorkflow(); +addMatrix(); finish(); +#------------------------------------------------- +sub addMatrix { + print "\tAdding Matrix Asset\n" unless ($quiet); + WebGUI::SQL->write("CREATE TABLE `Matrix_rating` ( + `timeStamp` int(11) NOT NULL default '0', + `category` varchar(255) default NULL, + `rating` int(11) NOT NULL default '1', + `listingId` varchar(22) binary NOT NULL default '', + `ipAddress` varchar(15) default NULL, + `assetId` varchar(22) binary NOT NULL default '', + `userId` varchar(22) binary default NULL +) "); + WebGUI::SQL->write("CREATE TABLE `Matrix_listingData` ( + `listingId` varchar(22) binary NOT NULL default '', + `fieldId` varchar(22) binary NOT NULL default '', + `value` varchar(255) default NULL, + `assetId` varchar(22) binary NOT NULL default '', + PRIMARY KEY (`listingId`,`fieldId`) +) "); + WebGUI::SQL->write("CREATE TABLE `Matrix_field` ( + `fieldId` varchar(22) binary NOT NULL default '', + `category` varchar(255) NOT NULL default '', + `name` varchar(255) default NULL, + `label` varchar(255) default NULL, + `description` text, + `fieldType` varchar(35) default NULL, + `defaultValue` varchar(255) default NULL, + `assetId` varchar(22) binary NOT NULL default '', + PRIMARY KEY (`fieldId`), + KEY `categoryIndex` (`category`) +) "); + WebGUI::SQL->write("CREATE TABLE `Matrix_ratingSummary` ( + `listingId` varchar(22) binary NOT NULL default '', + `category` varchar(255) NOT NULL default '', + `meanValue` decimal(3,2) default NULL, + `medianValue` int(11) default NULL, + `countValue` int(11) default NULL, + `assetId` varchar(22) binary NOT NULL default '', + PRIMARY KEY (`listingId`,`category`) +)"); + WebGUI::SQL->write("CREATE TABLE `Matrix` ( + `detailTemplateId` varchar(22) binary default NULL, + `compareTemplateId` varchar(22) binary default NULL, + `searchTemplateId` varchar(22) binary default NULL, + `ratingDetailTemplateId` varchar(22) binary default NULL, + `categories` text, + `assetId` varchar(22) binary NOT NULL default '', + `templateId` varchar(22) binary NOT NULL default '', + `revisionDate` bigint(20) NOT NULL default '0', + `maxComparisons` int(11) NOT NULL default '10', + `maxComparisonsPrivileged` int(11) NOT NULL default '10', + `privilegedGroup` varchar(22) binary NOT NULL default '2', + `groupToRate` varchar(22) binary NOT NULL default '2', + `ratingTimeout` int(11) NOT NULL default '31536000', + `ratingTimeoutPrivileged` int(11) NOT NULL default '31536000', + `groupToAdd` varchar(22) binary NOT NULL default '2', + PRIMARY KEY (`assetId`,`revisionDate`) +) "); + WebGUI::SQL->write("CREATE TABLE `Matrix_listing` ( + `listingId` varchar(22) binary NOT NULL default '', + `maintainerId` varchar(22) binary default NULL, + `forumId` varchar(22) binary default NULL, + `productName` varchar(255) default NULL, + `productUrl` text, + `manufacturerName` varchar(255) default NULL, + `manufacturerUrl` text, + `description` text, + `lastUpdated` int(11) default NULL, + `versionNumber` varchar(30) default NULL, + `views` int(11) NOT NULL default '0', + `compares` int(11) NOT NULL default '0', + `clicks` int(11) NOT NULL default '0', + `status` varchar(30) NOT NULL default 'pending', + `clicksLastIp` varchar(16) default NULL, + `viewsLastIp` varchar(16) default NULL, + `comparesLastIp` varchar(16) default NULL, + `assetId` varchar(22) binary NOT NULL default '', + PRIMARY KEY (`listingId`) +) "); + my $import = WebGUI::Asset->getImportNode; + my $folder = $import->addChild({ + title=>"Matrix Templates", + menuTitle=>"Matrix Templates", + className=>"WebGUI::Asset::Wobject::Folder", + url=>"matrix-templates", + }); + my $template = <Comparison + + + + + +
+ + +You tried to compare too many listings. Please choose or less at a time. + + + +You must choose at least two products to compare. Less than two isn't much of a comparison. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + class="odd" + + class="even" + + > + + + + + + +
Product
Last Updated
onmouseover="return escape('')"> + +
+ + +
+ +
+STOP + my $newAsset = $folder->addChild({ + title=>"Matrix Default Compare", + menuTitle=>"Matrix Default Compare", + namespace=>"Matrix/Compare", + url=>"matrix-default-compare-template", + className=>"WebGUI::Asset::Template", + template=>$template + }, "matrixtmpl000000000002"); + $newAsset->commit; + $template = < +

+ +

+ + +

+
+ + +
+

Use the form below to select up to listings to compare at once. +

+ + +
+ + +

+Narrow The Matrix
+You can narrow the scope of the matrix by searching for exactly the criteria you're looking for in a listing. +

+ + +

+
Expand The Matrix
+ + Click here to add a new listing. Please note that you will be the official maintainer of the listing, and will be responsible for keeping it up to date. + +If you are the maker of a product, or are an expert user and are willing to maintain the listing, create an account so you can register your listing. + + +

+ + + +
Listing Statistics
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Most clicks:
Most views:
Most compares:
Most recently updated:

Best Rated By Users
/10

View Ratings Details

Worst Rated By Users
/10

+ +
+
Site Statistics
+ + + + + + + + + + + + + +
Listing Count:
Current Visitors:
Registered Users:
+ + + + + +

List Fields +

+ +PENDING LISTINGS: + +
    + +
  • +
    +
+
+ +
+STOP + $newAsset = $folder->addChild({ + title=>"Matrix Default View", + menuTitle=>"Matrix Default View", + namespace=>"Matrix", + url=>"matrix-default-view-template", + className=>"WebGUI::Asset::Template", + template=>$template + }, "matrixtmpl000000000001"); + $newAsset->commit; + $template = < +.ratingForm { + font-size: 9px; +} + + +

+ + + + + + + + + + + + + + +
+ + + + + + + + + +
Web Site
Version Number
Manufacturer
Last Updated
Clicks
Views
Compares
+ +
  + + Description


+
+ +Contact Maintainer
+ +
Message sent.
+
+ +
  + +
+

+ + + + + + + +
+Features + + + + + class="odd" + + class="even" + +> + + + +
+

+ + +

+ +Benefits + + + + class="odd" + + class="even" + +> + + + +
+ + +
+ + + + + +

+ + + + + +


Edit this listing.
+ + + + Approve this listing.
+
+ Delete this listing.
+ +
+STOP + $newAsset = $folder->addChild({ + title=>"Matrix Default Detailed Listing", + menuTitle=>"Matrix Default Detailed Listing", + namespace=>"Matrix/Detail", + url=>"matrix-default-detailed-listing", + className=>"WebGUI::Asset::Template", + template=>$template + }, "matrixtmpl000000000003"); + $newAsset->commit; + $template = <Rating Detail + + + + + + + + + + + + + + + + + +
+

+ + + + + + + + + + + + + + + +
ListingMeanMedianCount
+
+STOP + $newAsset = $folder->addChild({ + title=>"Matrix Default Rating Detail", + menuTitle=>"Matrix Default Rating Detail", + namespace=>"Matrix/RatingDetail", + url=>"matrix-rating-detail-template", + className=>"WebGUI::Asset::Template", + template=>$template + }, "matrixtmpl000000000004"); + $newAsset->commit; + $template = <Search The Matrix + + + +

Your search returned no results. Try specifying a few less criteria.

+
+ + +

+Your search returned too many results. Either select up to products from the list below, or specify more critera. +

+
+ + + +
+ + + + + + + + + + + + + + +
+ + +Features + + + + class="odd" + + class="even" + +> + + + +
+ +
+ +Benefits + + + + class="odd" + + class="even" + +> + + + +
+ + +
+ + + + + +
+STOP + $newAsset = $folder->addChild({ + title=>"Matrix Default Search", + menuTitle=>"Matrix Default Search", + namespace=>"Matrix/Search", + url=>"matrix-search-template", + className=>"WebGUI::Asset::Template", + template=>$template + }, "matrixtmpl000000000005"); + $newAsset->commit; +} + #------------------------------------------------- sub updateCollaboration { print "\tAdding collaboration/rss template\n" unless ($quiet); diff --git a/etc/WebGUI.conf.original b/etc/WebGUI.conf.original index 0d3a2afb9..50270086c 100644 --- a/etc/WebGUI.conf.original +++ b/etc/WebGUI.conf.original @@ -111,6 +111,7 @@ assets = WebGUI::Asset::Snippet, \ WebGUI::Asset::Wobject::IndexedSearch, \ WebGUI::Asset::Wobject::MessageBoard, \ WebGUI::Asset::Wobject::Navigation, \ + WebGUI::Asset::Wobject::Matrix, \ WebGUI::Asset::Wobject::Poll, \ WebGUI::Asset::Wobject::Product, \ WebGUI::Asset::Wobject::SQLReport, \ diff --git a/lib/WebGUI/Asset/Wobject/Matrix.pm b/lib/WebGUI/Asset/Wobject/Matrix.pm new file mode 100644 index 000000000..8f254cb5b --- /dev/null +++ b/lib/WebGUI/Asset/Wobject/Matrix.pm @@ -0,0 +1,1130 @@ +package WebGUI::Asset::Wobject::Matrix; + +use strict; +use Tie::IxHash; +use WebGUI::DateTime; +use WebGUI::Form; +use WebGUI::FormProcessor; +use WebGUI::HTMLForm; +use WebGUI::HTTP; +use WebGUI::Mail; +use WebGUI::Privilege; +use WebGUI::Session; +use WebGUI::SQL; +use WebGUI::URL; +use WebGUI::User; +use WebGUI::Utility; +use WebGUI::Asset::Wobject; +use WebGUI::Asset::Wobject::Collaboration; + + +our @ISA = qw(WebGUI::Asset::Wobject); + +#------------------------------------------------------------------- +sub definition { + my $class = shift; + my $definition = shift; + push(@{$definition}, { + icon=>'matrix.gif' + tableName=>'Matrix', + className=>'WebGUI::Asset::Wobject::Matrix', + properties=>{ + categories=>{ + defaultValue=>"Features\nBenefits", + fieldType=>"textarea" + }, + maxComparisons=>{ + defaultValue=>10, + fieldName=>"integer" + }, + templateId=>{ + defaultValue=>"matrixtmpl000000000001", + fieldType=>"template" + }, + searchTemplateId=>{ + defaultValue=>"matrixtmpl000000000005", + fieldType=>"template" + }, + detailTemplateId=>{ + defaultValue=>"matrixtmpl000000000003", + fieldType=>"template" + }, + ratingDetailTemplateId=>{ + defaultValue=>"matrixtmpl000000000004", + fieldType=>"template" + }, + compareTemplateId=>{ + defaultValue=>"matrixtmpl000000000002", + fieldType=>"template" + }, + privilegedGroup=>{ + defaultValue=>'2', + fieldType=>"group", + }, + groupToRate=>{ + defaultValue=>'2', + fieldType=>"group", + }, + groupToAdd=>{ + defaultValue=>'2', + fieldType=>"group", + }, + maxComparisonsPrivileged=>{ + defaultValue=>10, + fieldType=>"integer", + }, + ratingTimeout=>{ + defaultValue=>60*60*24*365, + fieldType=>"interval" + }, + ratingTimeoutPrivileged=>{ + defaultValue=>60*60*24*365, + fieldType=>"interval" + } + } + }); + return $class->SUPER::definition($definition); +} + +#------------------------------------------------------------------- +sub duplicate { + return ""; +} + + +#------------------------------------------------------------------- +sub formatURL { + my $self = shift; + my $func = shift; + my $listingId = shift; + my $url = $self->getUrl("func=".$func."&listingId=".$listingId); + return $url; +} + + +#------------------------------------------------------------------- +sub getCategories { + my $self = shift; + my $cat = $self->getValue("categories"); + $cat =~ s/\r//g; + chomp($cat); + my @categories = split(/\n/,$cat); + return @categories; +} + +#------------------------------------------------------------------- +sub getCompareForm { + my $self = shift; + my @ids = @_; + my $form = WebGUI::Form::formHeader({action=>$self->getUrl}) + .WebGUI::Form::submit({ + value=>"compare" + }) + ."
" + ."
" + .WebGUI::Form::hidden({ + name=>"func", + value=>"compare" + }) + .WebGUI::Form::checkList({ + name=>"listingId", + vertical=>1, + value=>\@ids, + options=>WebGUI::SQL->buildHashRef("select listingId, concat('getUrl("func=viewDetail")."&listingId=',listingId,'\\\">', productName,'') from Matrix_listing + where assetId=".quote($self->getId)." and status='approved' order by productName") + }) + ."
" + .WebGUI::Form::submit({ + value=>"compare" + }) + .""; + return $form; +} + + +#------------------------------------------------------------------- +sub hasRated { + my $self = shift; + my $listingId = shift; + return 1 unless (WebGUI::Grouping::isInGroup($self->get("groupToRate"))); + my $ratingTimeout = WebGUI::Grouping::isInGroup($self->get("privilegedGroup")) ? $self->get("ratingTimeoutPrivileged") : $self->get("ratingTimeout"); + my ($hasRated) = WebGUI::SQL->quickArray("select count(*) from Matrix_rating where + ((userId=".quote($session{user}{userId})." and userId<>'1') or (userId='1' and ipAddress=".quote($session{env}{HTTP_X_FORWARDED_FOR}).")) and + listingId=".quote($listingId)." and timeStamp>".(WebGUI::DateTime::time()-$ratingTimeout)); + return $hasRated; +} + +#------------------------------------------------------------------- +sub incrementCounter { + my $listingId = shift; + my $counter = shift; + my ($lastIp) = WebGUI::SQL->quickArray("select ".$counter."LastIp from Matrix_listing where listingId = ".quote($listingId)); + unless ($lastIp eq $session{env}{HTTP_X_FORWARDED_FOR}) { + WebGUI::SQL->write("update Matrix_listing set $counter=$counter+1, ".$counter."LastIp=".quote($session{env}{HTTP_X_FORWARDED_FOR})." where listingId=".quote($listingId)); + } +} + +#------------------------------------------------------------------- +sub getName { + return "Matrix"; +} + +#------------------------------------------------------------------- +sub purge { + my $self = shift; + WebGUI::SQL->write("delete from Matrix_listing where assetId=".quote($self->getId)); + WebGUI::SQL->write("delete from Matrix_listingData where assetId=".quote($self->getId)); + WebGUI::SQL->write("delete from Matrix_field where assetId=".quote($self->getId)); + WebGUI::SQL->write("delete from Matrix_rating where assetId=".quote($self->getId)); + WebGUI::SQL->write("delete from Matrix_ratingSummary where assetId=".quote($self->getId)); + $self->SUPER::purge; +} + + +#------------------------------------------------------------------- +sub setRatings { + my $self = shift; + my $listingId = shift; + my $ratings = shift; + foreach my $category ($self->getCategories) { + if ($ratings->{$category}) { + WebGUI::SQL->write("insert into Matrix_rating (userId, category, rating, timeStamp, listingId,ipAddress, assetId) values ( + ".quote($session{user}{userId}).", ".quote($category).", ".quote($ratings->{$category}).", ".WebGUI::DateTime::time() + .", ".quote($listingId).", ".quote($session{env}{HTTP_X_FORWARDED_FOR}).",".quote($self->getId).")"); + } + my $sql = "from Matrix_rating where listingId=".quote($listingId)." and category=".quote($category); + my ($sum) = WebGUI::SQL->quickArray("select sum(rating) $sql"); + my ($count) = WebGUI::SQL->quickArray("select count(*) $sql"); + my $half = round($count/2); + my $mean = $sum / ($count || 1); + my ($median) = WebGUI::SQL->quickArray("select rating $sql limit $half,$half"); + WebGUI::SQL->write("replace into Matrix_ratingSummary (listingId, category, meanValue, medianValue, countValue,assetId) values ( + ".quote($listingId).", ".quote($category).", $mean, ".quote($median).", $count, ".quote($self->getId).")"); + } +} + +#------------------------------------------------------------------- +sub www_approveListing { + my $self = shift; + return WebGUI::Privilege::insufficient() unless($self->canEdit); + my $listing = WebGUI::SQL->getRow("Matrix_listing","listingId",$session{form}{listingId}); + WebGUI::SQL->write("update Matrix_listing set status='approved' where listingId=".quote($session{form}{listingId})); + WebGUI::MessageLog::addEntry($listing->{maintainerId},"","New Listing Approved","Your new listing, ".$listing->{productName}.", has been approved.", + $self->formatURL("viewDetail",$session{form}{listingId}),"notice"); + WebGUI::MessageLog::completeEntry($session{form}{mlog}); + return $self->www_viewDetail; +} + + +#------------------------------------------------------------------- +sub www_click { + my $self = shift; + incrementCounter($session{form}{listingId},"clicks"); + my $listing = WebGUI::SQL->getRow("Matrix_listing","listingId",$session{form}{listingId}); + if ($session{form}{m}) { + WebGUI::HTTP::setRedirect($listing->{manufacturerUrl}); + } else { + WebGUI::HTTP::setRedirect($listing->{productUrl}); + } + return ""; +} + + +#------------------------------------------------------------------- +sub www_compare { + my $self = shift; + my @cmsList = @_; + unless (scalar(@cmsList)) { + @cmsList = WebGUI::FormProcessor::checkList("listingId"); + } + my ( %var, @prodcol, @datecol); + my $max = WebGUI::Grouping::isInGroup($self->get("privilegedGroup")) ? $self->get("maxComparisonsPrivileged") : $self->get("maxComparisons"); + $var{isTooMany} = (scalar(@cmsList)>$max); + $var{isTooFew} = (scalar(@cmsList)<2); + $var{'compare.form'} = $self->getCompareForm(@cmsList); + if ($var{isTooMany} || $var{isTooFew}) { + return $self->processStyle($self->processTemplate(\%var,$self->get("compareTemplateId"))); + } + foreach my $cms (@cmsList) { + incrementCounter($cms,"compares"); + my $data = WebGUI::SQL->quickHashRef("select listingId, productName, versionNumber, lastUpdated + from Matrix_listing where listingId=".quote($cms)); + push(@prodcol, { + name=>$data->{productName} || "__untitled__", + version=>$data->{versionNumber}, + url=>$self->formatURL("viewDetail",$cms) + }); + push(@datecol, { + lastUpdated=>WebGUI::DateTime::epochToHuman($data->{lastUpdated},"%z") + }); + } + $var{product_loop} = \@prodcol; + $var{lastupdated_loop} = \@datecol; + my @categoryloop; + foreach my $category ($self->getCategories()) { + my @rowloop; + my $select = "select a.label, a.description"; + my $from = "from Matrix_field a"; + my $tableCount = "b"; + foreach my $cms (@cmsList) { + $select .= ", ".$tableCount.".value"; + $from .= " left join Matrix_listingData ".$tableCount." on a.fieldId=" + .$tableCount.".fieldId and ".$tableCount.".listingId=".quote($cms); + $tableCount++; + } + my $sth = WebGUI::SQL->read("$select $from where a.category=".quote($category)." order by a.label"); + while (my @row = $sth->array) { + my @columnloop; + my $first = 1; + foreach my $value (@row) { + my $desc = ""; + if ($first) { + $desc = $row[1]; + shift(@row); + $desc =~ s/\n//g; + $desc =~ s/\r//g; + $desc =~ s/'/\\\'/g; + $desc =~ s/"/\"/g; + $first = 0; + } + my $class = lc($value); + $class =~ s/\s/_/g; + $class =~ s/\W//g; + push(@columnloop,{ + value=>$value, + class=>$class, + description=>$desc + }); + } + push(@rowloop,{ + column_loop=>\@columnloop + }); + } + $sth->finish; + push(@categoryloop,{ + category=>$category, + columnCount=>$#cmsList+2, + row_loop=>\@rowloop + }); + } + $var{category_loop} = \@categoryloop; + return $self->processStyle($self->processTemplate(\%var,$self->get("compareTemplateId"))); +} + +#------------------------------------------------------------------- +sub www_copy { + return "This asset may not be copied."; +} + +#------------------------------------------------------------------- +sub www_deleteListing { + my $self = shift; + my $output = '

Confirm Delete

+ Are you absolutely sure you wish to delete this listing? This operation cannot be undone. +

+ Yes! +

+ No, I made a mistake. '; + return $self->processStyle($output); +} + +#------------------------------------------------------------------- +sub www_deleteListingConfirm { + my $self = shift; + return WebGUI::Privilege::insufficient() unless($self->canEdit); + my $listing = WebGUI::SQL->getRow("Matrix_listing","listingId",$session{form}{listingId}); + WebGUI::Asset::Wobject::Collaboration->new($listing->{forumId})->purge; + WebGUI::SQL->write("delete from Matrix_listing where listingId=".quote($session{form}{listingId})); + WebGUI::SQL->write("delete from Matrix_listingData where listingId=".quote($session{form}{listingId})); + WebGUI::SQL->write("delete from Matrix_rating where listingId=".quote($session{form}{listingId})); + WebGUI::SQL->write("delete from Matrix_ratingSummary where listingId=".quote($session{form}{listingId})); + WebGUI::MessageLog::addEntry($listing->{maintainerId},"","Listing Deleted","Your listing, ".$listing->{productName}.", has been deleted from the matrix.","","notice"); + WebGUI::MessageLog::completeEntry($session{form}{mlog}); + return ""; +} + +#------------------------------------------------------------------- +sub getEditForm { + my $self = shift; + my $tabform = $self->SUPER::getEditForm(); + $tabform->getTab("properties")->textarea( + -name=>"categories", + -label=>"Categories", + -value=>$self->getValue("categories"), + -subtext=>"
Enter one per line in the order you want them to appear. Be sure to watch leading and trailing whitespace." + ); + $tabform->getTab("properties")->integer( + -name=>"maxComparisons", + -label=>"Maximum Comparisons", + -value=>$self->getValue("maxComparisons") + ); + $tabform->getTab("properties")->integer( + -name=>"maxComparisonsPrivileged", + -label=>"Maximum Comparisons (For Privileged Users)", + -value=>$self->getValue("maxComparisonsPrivileged") + ); + $tabform->getTab("properties")->interval( + -name=>"ratingTimeout", + -label=>"Time Required Between Ratings", + -value=>$self->getValue("ratingTimeout") + ); + $tabform->getTab("properties")->interval( + -name=>"ratingTimeoutPrivileged", + -label=>"Time Required Between Ratings (For Privileged Users)", + -value=>$self->getValue("ratingTimeoutPrivileged") + ); + $tabform->getTab("security")->group( + -name=>"groupToAdd", + -label=>"Who can add listings?", + -value=>[$self->getValue("groupToAdd")] + ); + $tabform->getTab("security")->group( + -name=>"privilegedGroup", + -label=>"Who should have privileged rights?", + -value=>[$self->getValue("privilegedGroup")] + ); + $tabform->getTab("security")->group( + -name=>"groupToRate", + -label=>"Who can rate listings?", + -value=>[$self->getValue("groupToRate")] + ); + $tabform->getTab("display")->template( + -name=>"templateId", + -value=>$self->getValue("templateId"), + -label=>"Main Template", + -namespace=>"Matrix" + ); + $tabform->getTab("display")->template( + -name=>"detailTemplateId", + -value=>$self->getValue("detailTemplateId"), + -label=>"Detail Template", + -namespace=>"Matrix/Detail" + ); + $tabform->getTab("display")->template( + -name=>"ratingDetailTemplateId", + -value=>$self->getValue("ratingDetailTemplateId"), + -label=>"Rating Detail Template", + -namespace=>"Matrix/RatingDetail" + ); + $tabform->getTab("display")->template( + -name=>"searchTemplateId", + -value=>$self->getValue("searchTemplateId"), + -label=>"Search Template", + -namespace=>"Matrix/Search" + ); + $tabform->getTab("display")->template( + -name=>"compareTemplateId", + -value=>$self->getValue("compareTemplateId"), + -label=>"Compare Template", + -namespace=>"Matrix/Compare" + ); + return $tabform; +} + +#------------------------------------------------------------------- +sub www_edit { + my $self = shift; + return WebGUI::Privilege::insufficient() unless $self->canEdit; + return $self->getAdminConsole->render($self->getEditForm->print,"Edit Matrix"); +} + + + +#------------------------------------------------------------------- +sub www_editListing { + my $self = shift; + my $listing= WebGUI::SQL->getRow("Matrix_listing","listingId",$session{form}{listingId}); + return "You don't have the rights to edit this listing." unless (($session{form}{listingId} eq "new" && WebGUI::Grouping::isInGroup($self->get("groupToAdd"))) || $session{user}{userId} eq $listing->{maintainerId} || $self->canEdit); + my $f = WebGUI::HTMLForm->new(-action=>$self->getUrl); + $f->hidden( + -name=>"func", + -value=>"editListingSave" + ); + $f->hidden( + -name=>"listingId", + -value=>$session{form}{listingId} + ); + $f->text( + -name=>"productName", + -value=>$listing->{productName}, + -label=>"Product Name", + -maxLength=>25 + ); + $f->text( + -name=>"versionNumber", + -value=>$listing->{versionNumber}, + -label=>"Version/Model Number" + ); + $f->url( + -name=>"productUrl", + -value=>$listing->{productUrl}, + -label=>"Product URL" + ); + $f->text( + -name=>"manufacturerName", + -value=>$listing->{manufacturerName}, + -label=>"Manufacturer Name" + ); + $f->url( + -name=>"manufacturerUrl", + -value=>$listing->{manufacturerUrl}, + -label=>"Manufacturer URL" + ); + $f->textarea( + -name=>"description", + -value=>$listing->{description}, + -label=>"Description" + ); + if ($self->canEdit) { + $f->selectList( + -name=>"maintainerId", + -value=>[$listing->{maintainerId}], + -label=>"Listing Maintainer", + -options=>WebGUI::SQL->buildHashRef("select userId,username from users order by username") + ); + } + my %goodBad = ("No"=>"No", "Yes"=>"Yes", "Free Add On"=>"Free Add On","Costs Extra"=>"Costs Extra", "Limited"=>"Limited"); + foreach my $category ($self->getCategories()) { + $f->raw(''.$category.''); + my $a; + if ($session{form}{listingId} ne "new") { + $a = WebGUI::SQL->read("select a.name, a.fieldType, a.defaultValue, a.description, a.label, b.value, a.fieldId + from Matrix_field a left join Matrix_listingData b on a.fieldId=b.fieldId and + listingId=".quote($session{form}{listingId})." where + a.category=".quote($category)." order by a.label"); + } else { + $a = WebGUI::SQL->read("select name, fieldType, defaultValue, description, label, fieldId + from Matrix_field where category=".quote($category)." and assetId=".quote($self->getId)); + } + while (my $field = $a->hashRef) { + if ($field->{fieldType} eq "text") { + $f->text( + -name=>$field->{name}, + -value=>$field->{value} || $field->{defaultValue}, + -label=>$field->{label}, + -subtext=>"
".$field->{description} + ); + } elsif ($field->{fieldType} eq "goodBad") { + my $value = ($field->{value} || $field->{defaultValue} || "No"); + $f->selectList( + -name=>$field->{name}, + -value=>[$value], + -label=>$field->{label}, + -options=>\%goodBad, + -subtext=>"
".$field->{description} + ); + } elsif ($field->{fieldType} eq "textarea") { + $f->textarea( + -name=>$field->{name}, + -value=>$field->{value} || $field->{defaultValue}, + -label=>$field->{label}, + -subtext=>"
".$field->{description} + ); + } elsif ($field->{fieldType} eq "url") { + $f->url( + -name=>$field->{name}, + -value=>$field->{value} || $field->{defaultValue}, + -label=>$field->{label}, + -subtext=>"
".$field->{description} + ); + } elsif ($field->{fieldType} eq "combo") { + my $value = ($field->{value} || $field->{defaultValue}); + $f->combo( + -name=>$field->{name}, + -value=>[$value], + -label=>$field->{label}, + -options=>WebGUI::SQL->buildHashRef("select distinct value,value from Matrix_listingData + where fieldId=".quote($field->{fieldId})." and + assetId=".quote($self->getId)." order by value"), + -subtext=>"
".$field->{description} + ); + } + + } + $a->finish; + } + $f->submit; + return $self->processStyle("

Edit Listing

".$f->print); +} + + +#------------------------------------------------------------------- +sub www_editListingSave { + my $self = shift; + my $listing = WebGUI::SQL->getRow("Matrix_listing","listingId",$session{form}{listingId}); + return "You don't have the rights to edit this listing." unless (($session{form}{listingId} eq "new" && WebGUI::Grouping::isInGroup($self->get("groupToAdd"))) || $session{user}{userId} eq $listing->{maintainerId} || $self->canEdit); + my %data = ( + listingId => $session{form}{listingId}, + lastUpdated => WebGUI::DateTime::time(), + productName => $session{form}{productName}, + productUrl => $session{form}{productUrl}, + manufacturerName => $session{form}{manufacturerName}, + manufacturerUrl => $session{form}{manufacturerUrl}, + description => $session{form}{description}, + versionNumber=>$session{form}{versionNumber} + ); + my $isNew = 0; + if ($session{form}{listingId} eq "new") { + $data{maintainerId} = $session{user}{userId} if ($session{form}{listingId} eq "new"); + my $forum = $self->addChild({ + className=>"WebGUI::Asset::Wobject::Collaboration", + title=>$session{form}{productName}, + menuTitle=>$session{form}{productName}, + url=>$session{form}{productName}, + groupIdView=>7, + groupIdEdit=>3, + startDate=>time(), + endDate=>time()+60*60*24*365*15, + displayLastReply => 0, + allowReplies => 1, + threadsPerPage => 30, + postsPerPage => 10, + archiveAfter =>31536000, + useContentFilter => 1, + filterCode => 'javascript', + richEditor => "PBrichedit000000000002", + attachmentsPerPost => 0, + editTimeout => 3600, + addEditStampToPosts => 0, + usePreview => 1, + sortOrder => 'desc', + sortBy => 'dateUpdated', + notificationTemplateId =>'PBtmpl0000000000000027', + searchTemplateId =>'PBtmpl0000000000000031', + postFormTemplateId =>'PBtmpl0000000000000029', + threadTemplateId =>'PBtmpl0000000000000032', + collaborationTemplateId =>'PBtmpl0000000000000026', + karmaPerPost =>0, + karmaSpentToRate => 0, + karmaRatingMultiplier => 0, + moderatePosts => 0, + moderateGroupId => '4', + postGroupId => '7' + }); + $data{forumId} = $forum->getId; + $data{status} = "pending"; + $isNew = 1; + } + $data{maintainerId} = $session{form}{maintainerId} if ($self->canEdit); + $data{assetId} = $self->getId; + $session{form}{listingId} = WebGUI::SQL->setRow("Matrix_listing","listingId",\%data); + if ($data{status} eq "pending") { + WebGUI::MessageLog::addEntry($self->get("ownerUserId"),$self->get("groupIdEdit"),"New Listing Added","A new listing, ".$data{productName}.", is waiting to be added.", + WebGUI::URL::getSiteURL()."/".$self->formatURL("viewDetail",$session{form}{listingId}),"pending"); + } + my $a = WebGUI::SQL->read("select fieldId, name, fieldType from Matrix_field"); + while (my ($id, $name, $type) = $a->array) { + my $value; + if ($type eq "goodBad") { + $value = WebGUI::FormProcessor::selectList($name); + } else { + $value = WebGUI::FormProcessor::process($name,$type); + } + WebGUI::SQL->write("replace into Matrix_listingData (assetId, listingId, fieldId, value) values ( + ".quote($self->getId).", ".quote($session{form}{listingId}).", ".quote($id).", ".quote($value).")"); + } + $a->finish; + return $self->www_viewDetail; +} + +#------------------------------------------------------------------- +sub www_editField { + my $self = shift; + return WebGUI::Privilege::insufficient() unless($self->canEdit); + my $field = WebGUI::SQL->getRow("Matrix_field","fieldId",$session{form}{fieldId}); + my $f = WebGUI::HTMLForm->new(-action=>$self->getUrl); + $f->hidden( + -name=>"func", + -value=>"editFieldSave" + ); + $f->hidden( + -name=>"fieldId", + -value=>$session{form}{fieldId} + ); + $f->text( + -name=>"name", + -value=>$field->{name}, + -label=>"Name" + ); + $f->text( + -name=>"label", + -value=>$field->{label}, + -label=>"Label" + ); + $f->selectList( + -name=>"fieldType", + -value=>[$field->{fieldType}], + -label=>"Type", + -options=>{ + goodBad=>"Good Bad", + text=>"Text", + url=>"URL", + textarea=>"Text Area", + combo=>"Combo" + } + ); + $f->textarea( + -name=>"description", + -value=>$field->{description}, + -label=>"Description" + ); + $f->text( + -name=>"defaultValue", + -value=>$field->{defaultValue}, + -label=>"Default Value" + ); + my %cats; + foreach my $category ($self->getCategories) { + $cats{$category} = $category; + } + $f->selectList( + -name=>"category", + -value=>[$field->{category}], + -label=>"Category", + -options=>\%cats + ); + $f->submit; + return $self->processStyle("

Edit Field

".$f->print); +} + + +#------------------------------------------------------------------- +sub www_editFieldSave { + my $self = shift; + return WebGUI::Privilege::insufficient() unless($self->canEdit); + WebGUI::SQL->setRow("Matrix_field","fieldId",{ + fieldId=>$session{form}{fieldId}, + name=>$session{form}{name}, + label=>$session{form}{label}, + fieldType=>$session{form}{fieldType}, + description=>$session{form}{description}, + defaultValue=>$session{form}{defaultValue}, + category=>$session{form}{category}, + assetId=>$self->getId + }); + return $self->www_listFields(); +} + +#------------------------------------------------------------------- +sub www_listFields { + my $self = shift; + return WebGUI::Privilege::insufficient() unless($self->canEdit); + my $output = '

Field List

+ Add new field. +

'; + my $sth = WebGUI::SQL->read("select fieldId, label from Matrix_field where assetId=".quote($self->getId)." order by label"); + while (my ($id, $label) = $sth->array) { + $output .= ''.$label.'
'; + } + $sth->finish; + return $self->processStyle($output); +} + + +#------------------------------------------------------------------- +sub www_rate { + my $self = shift; + my $hasRated = $self->hasRated($session{form}{listingId}); + my $sameRating = 1; + my $first = 1; + my $lastRating; + foreach my $category ($self->getCategories) { + if ($first) { + $first=0; + } else { + if ($lastRating != $session{form}{$category}) { + $sameRating = 0; + } + } + $lastRating = $session{form}{$category}; + } + return $self->www_viewDetail("",1) if ($hasRated || $sameRating); # Throw out ratings that are all the same number, or if the user rates twice. + $self->setRatings($session{form}{listingId},$session{form}); + return $self->www_viewDetail; +} + +#------------------------------------------------------------------- +sub www_search { + my $self = shift; + my %var; + my @list = WebGUI::SQL->buildArray("select listingId from Matrix_listing"); + if ($session{form}{doit}) { + my $count; + my $keyword; + if ($session{form}{keyword}) { + $keyword = " and (a.value like ".quote('%'.$session{form}{keyword}.'%')." or a.value='Any')"; + } + my $sth = WebGUI::SQL->read("select name,fieldType from Matrix_field"); + while (my ($name,$fieldType) = $sth->array) { + next unless ($session{form}{$name}); + push(@list,0); + my $where; + if ($fieldType ne "goodBad") { + $where = "(" + ."a.value like ".quote("%".$session{form}{$name}."%") + ." or a.value='Any'" + #." or a.value<".quote($session{form}{$name}) + ." or a.value='Free'" + .")"; + } else { + $where = "a.value<>'no'"; + } + @list = WebGUI::SQL->buildArray("select a.listingId from Matrix_listingData a left join Matrix_field b + on (a.fieldId=b.fieldId) + where a.listingId in (".quoteAndJoin(\@list).") and $where and b.name=".quote($name)); + $count = scalar(@list); + last unless ($count > 0); + } + $sth->finish; + if ($count > 1 && $count < 11) { + return $self->www_compare(@list); + } elsif ($count == 1) { + return $self->www_viewDetail($list[0]); + } else { + my $max = WebGUI::Grouping::isInGroup($self->get("privilegedGroup")) ? $self->get("maxComparisonsPrivileged") : $self->get("maxComparisons"); + $var{isTooMany} = ($count>$max); + $var{isTooFew} = ($count<2); + } + } + $var{'compare.form'} = $self->getCompareForm(@list); + $var{'form.header'} = WebGUI::Form::formHeader({action=>$self->getUrl}) + .WebGUI::Form::hidden({ + name=>"doit", + value=>"1" + }) + .WebGUI::Form::hidden({ + name=>"func", + value=>"search" + }); + $var{'form.footer'} = ""; + $var{'form.keyword'} = WebGUI::Form::text({ + name=>"keyword", + value=>$session{form}{keyword} + }); + $var{'form.submit'} = WebGUI::Form::submit({ + value=>"search" + }); + foreach my $category ($self->getCategories()) { + my $sth = WebGUI::SQL->read("select name, fieldType, label, description from Matrix_field where category = ".quote($category)." order by label"); + my @loop; + while (my $data = $sth->hashRef) { + $data->{description} =~ s/\n//g; + $data->{description} =~ s/\r//g; + $data->{description} =~ s/'/\\\'/g; + $data->{description} =~ s/"/\"/g; + if ($data->{fieldType} ne "goodBad") { + $data->{form} = WebGUI::Form::text({ + name=>$data->{name}, + value=>$session{form}{$data->{name}} + }); + } else { + $data->{form} = WebGUI::Form::checkbox({ + name=>$data->{name}, + value=>"1", + checked=>$session{form}{$data->{name}} + }); + } + push(@loop,$data); + } + $sth->finish; + $var{WebGUI::URL::urlize($category)."_loop"} = \@loop; + } + return $self->processStyle($self->processTemplate(\%var,$self->get("searchTemplateId"))); +} + + +#------------------------------------------------------------------- +sub view { + my $self = shift; + my (%var); + $var{'compare.form'} = $self->getCompareForm; + $var{'search.url'} = $self->getUrl("func=search"); + $var{'isLoggedIn'} = ($session{user}{userId} ne "1"); + $var{'field.list.url'} = $self->getUrl('func=listFields'); + $var{'listing.add.url'} = $self->formatURL("editListing","new"); + + my $data = WebGUI::SQL->quickHashRef("select views, productName, listingId from Matrix_listing + where assetId=".quote($self->getId)." and status='approved' order by views desc limit 1"); + $var{'best.views.url'} = $self->formatURL("viewDetail",$data->{listingId}); + $var{'best.views.count'} = $data->{views}; + $var{'best.views.name'} = $data->{productName}; + my $data = WebGUI::SQL->quickHashRef("select compares, productName, listingId from Matrix_listing + where assetId=".quote($self->getId)." and status='approved' order by compares desc limit 1"); + $var{'best.compares.url'} = $self->formatURL("viewDetail",$data->{listingId}); + $var{'best.compares.count'} = $data->{compares}; + $var{'best.compares.name'} = $data->{productName}; + my $data = WebGUI::SQL->quickHashRef("select clicks, productName, listingId from Matrix_listing + where assetId=".quote($self->getId)." and status='approved' order by clicks desc limit 1"); + $var{'best.clicks.url'} = $self->formatURL("viewDetail",$data->{listingId}); + $var{'best.clicks.count'} = $data->{clicks}; + $var{'best.clicks.name'} = $data->{productName}; + my (@best,@worst); + foreach my $category ($self->getCategories) { + my $sql = " + select + Matrix_listing.productName, + Matrix_listing.listingId, + Matrix_ratingSummary.meanValue, + Matrix_ratingSummary.medianValue, + Matrix_ratingSummary.countValue + from + Matrix_listing + left join + Matrix_ratingSummary + on + Matrix_listing.listingId=Matrix_ratingSummary.listingId and + Matrix_ratingSummary.category=".quote($category)." + where + Matrix_listing.assetId=".quote($self->getId)." and + Matrix_listing.status='approved' and + Matrix_ratingSummary.countValue > 0 + order by + Matrix_ratingSummary.meanValue + "; + my $data = WebGUI::SQL->quickHashRef($sql." desc limit 1"); + push(@best,{ + url=>$self->formatURL("viewDetail",$data->{listingId}), + category=>$category, + name=>$data->{productName}, + mean=>$data->{meanValue}, + median=>$data->{medianValue}, + count=>$data->{countValue} + }); + $data = WebGUI::SQL->quickHashRef($sql." asc limit 1"); + push(@worst,{ + url=>$self->formatURL("viewDetail",$data->{listingId}), + category=>$category, + name=>$data->{productName}, + mean=>$data->{meanValue}, + median=>$data->{medianValue}, + count=>$data->{countValue} + }); + } + $var{'best_rating_loop'} = \@best; + $var{'worst_rating_loop'} = \@worst; + $var{'ratings.details.url'} = $self->getUrl("func=viewRatingDetails"); + my $data = WebGUI::SQL->quickHashRef("select lastUpdated, productName, listingId from Matrix_listing + where assetId=".quote($self->getId)." and status='approved' order by lastUpdated desc limit 1"); + $var{'best.updated.url'} = $self->formatURL("viewDetail",$data->{listingId}); + $var{'best.updated.date'} = WebGUI::DateTime::epochToHuman($data->{lastUpdated},"%z");; + $var{'best.updated.name'} = $data->{productName}; + + # site stats + ($var{'user.count'}) = WebGUI::SQL->quickArray("select count(*) from users"); + ($var{'current.user.count'}) = WebGUI::SQL->quickArray("select count(*)+0 from userSession where lastPageView>".(WebGUI::DateTime::time()-600)); + ($var{'listing.count'}) = WebGUI::SQL->quickArray("select count(*) from Matrix_listing where status = 'approved' and assetId=".quote($self->getId)); + my $sth = WebGUI::SQL->read("select listingId,productName from Matrix_listing where status='pending'"); + while (my ($id,$name) = $sth->array) { + push(@{$var{pending_list}},{ + url=>$self->formatURL("viewDetail",$id), + productName=>$name + }); + } + $sth->finish; + return $self->processTemplate(\%var,$self->get("templateId")); +} + +#------------------------------------------------------------------- +sub www_viewDetail { + my $self = shift; + my $listingId = shift || $session{form}{listingId}; + my $hasRated = shift || $self->hasRated($listingId); + my %var; + my $listing = WebGUI::SQL->getRow("Matrix_listing","listingId",$listingId); + my $forum = WebGUI::Asset::Wobject::Collaboration->new($listing->{forumId}); + $var{"discussion"} = $forum->view; + if ($session{form}{do} eq "sendEmail") { + if ($session{form}{body} ne "") { + my $u = WebGUI::User->new($listing->{maintainerId}); + WebGUI::Mail::send($u->profileField("email"),$listing->{productName}." - ".$session{form}{subject},$session{form}{body},"",$session{form}{from}); + } + $var{'email.wasSent'} = 1; + } else { + incrementCounter($listingId,"views"); + } + $var{'edit.url'} = $self->formatURL("editListing",$listingId); + $var{id} = $listingId; + $var{'user.canEdit'} = ($session{user}{userId} eq $listing->{maintainerId} || $self->canEdit); + $var{'user.canApprove'} = $self->canEdit; + $var{'approve.url'} = $self->getUrl("func=approveListing&listingId=".$listingId."&mlog=".$session{form}{mlog}); + $var{'delete.url'} = $self->getUrl("func=deleteListing&listingId=".$listingId."&mlog=".$session{form}{mlog}); + $var{'isPending'} = ($listing->{status} eq "pending"); + $var{'lastUpdated.epoch'} = $listing->{lastupdated}; + $var{'lastUpdated.date'} = WebGUI::DateTime::epochToHuman($listing->{lastUpdated},"%z"); + $var{description} = $listing->{description}; + $var{productName} = $listing->{productName}; + $var{productUrl} = $listing->{productUrl}; + $var{'productUrl.click'} = $self->formatURL("click",$listingId); + $var{manufacturerName} = $listing->{manufacturerName}; + $var{manufacturerUrl} = $listing->{manufacturerUrl}; + $var{'manufacturerUrl.click'} = $self->getUrl("m=1&func=click&listingId=".$listingId); + $var{versionNumber} = $listing->{versionNumber}; + my $f = WebGUI::HTMLForm->new( + -extras=>'class="content"', + -tableExtras=>'class="content"' + ); + $f->hidden( + -name=>"func", + -value=>"viewDetail" + ); + $f->hidden( + -name=>"do", + -value=>"sendEmail" + ); + $f->hidden( + -name=>"listingId", + -value=>$listingId + ); + $f->email( + -extras=>'class="content"', + -name=>"from", + -value=>$session{user}{email}, + -label=>"Your Email Address" + ); + $f->selectList( + -name=>"subject", + -extras=>'class="content"', + -options=>{ + "Report an error."=>"Report an error.", + "General comment."=>"General comment." + }, + -label=>"Type of Request" + ); + $f->textarea( + -rows=>4, + -extras=>'class="content"', + -columns=>35, + -name=>"body", + -label=>"Comment" + ); + $f->submit( + -extras=>'class="content"', + -value=>"Send..." + ); + $var{'email.form'} = $f->print; + $var{views} = $listing->{views}; + $var{compares} = $listing->{compares}; + $var{clicks} = $listing->{clicks}; + my $sth = WebGUI::SQL->read("select a.value, b.name, b.label, b.description, category from Matrix_listingData a left join + Matrix_field b on a.fieldId=b.fieldId where listingId=".quote($listingId)." order by b.label"); + while (my $data = $sth->hashRef) { + $data->{description} =~ s/\n//g; + $data->{description} =~ s/\r//g; + $data->{description} =~ s/'/\\\'/g; + $data->{description} =~ s/"/\"/g; + $data->{class} = lc($data->{value}); + $data->{class} =~ s/\s/_/g; + $data->{class} =~ s/\W//g; + my $cat = WebGUI::URL::urlize($data->{category})."_loop"; + push(@{$var{$cat}},$data); + } + $sth->finish; + my %rating; + tie %rating, 'Tie::IxHash'; + %rating = ( + 1=>"1 - Worst", + 2=>2, + 3=>3, + 4=>4, + 5=>"5 - Respectable", + 6=>6, + 7=>7, + 8=>8, + 9=>9, + 10=>"10 - Best" + ); + my $ratingsTable = ''; + $f = WebGUI::HTMLForm->new( + -extras=>'class="ratingForm"', + -tableExtras=>'class="ratingForm"' + ); + $f->hidden( + -name=>"listingId", + -value=>$listingId + ); + $f->hidden( + -name=>"func", + -value=>"rate" + ); + foreach my $category ($self->getCategories) { + my ($mean,$median,$count) = WebGUI::SQL->quickArray("select meanValue, medianValue, countValue from Matrix_ratingSummary + where listingId=".quote($listingId)." and category=".quote($category)); + $ratingsTable .= ''; + $f->selectList( + -name=>$category, + -label=>$category, + -value=>[5], + -extras=>'class="ratingForm"', + -options=>\%rating + ); + } + $ratingsTable .= '
MeanMedianCount
'.$category.''.$mean.''.$median.''.$count.'
'; + $f->submit( + -extras=>'class="ratingForm"', + -value=>"Rate", + -label=>'Show Ratings' + ); + if ($hasRated) { + $var{'ratings'} = $ratingsTable; + } else { + $var{'ratings'} = $f->print; + } + return $self->processStyle($self->processTemplate(\%var,$self->get("detailTemplateId"))); +} + + +#----------------------------------------------- +sub www_viewRatingDetails { + my $self = shift; + my %var; + my @ratingloop; + foreach my $category ($self->getCategories) { + my @detailloop; + my $sql = " + select + Matrix_listing.productName, + Matrix_listing.listingId, + Matrix_ratingSummary.meanValue, + Matrix_ratingSummary.medianValue, + Matrix_ratingSummary.countValue + from + Matrix_listing + left join + Matrix_ratingSummary + on + Matrix_listing.listingId=Matrix_ratingSummary.listingId and + Matrix_ratingSummary.category=".quote($category)." + where + Matrix_listing.assetId=".quote($self->getId)." and + Matrix_listing.status='approved' and + Matrix_ratingSummary.countValue > 0 + order by + Matrix_ratingSummary.meanValue desc + "; + my $sth = WebGUI::SQL->read($sql); + while (my $data = $sth->hashRef) { + push(@detailloop,{ + url=>$self->formatURL("viewDetail",$data->{listingId}), + mean=>$data->{meanValue}, + median=>$data->{medianValue}, + count=>$data->{countValue}, + name=>$data->{productName} + }); + } + $sth->finish; + push(@ratingloop,{ + category=>$category, + detail_loop=>\@detailloop + }); + } + $var{rating_loop} = \@ratingloop; + return $self->processStyle($self->processTemplate(\%var,$self->get("ratingDetailTemplateId"))); +} + + + + + +1; + diff --git a/lib/WebGUI/Help/Asset_Matrix.pm b/lib/WebGUI/Help/Asset_Matrix.pm new file mode 100644 index 000000000..15a3d57b3 --- /dev/null +++ b/lib/WebGUI/Help/Asset_Matrix.pm @@ -0,0 +1,162 @@ +package WebGUI::Help::Asset_Matrix; + +our $HELP = { + 'add/edit' => { + title => 'add/edit help title', + body => 'add/edit help body', + related => [ + { + tag => 'search template', + namespace => 'Asset_Matrix' + }, + { + tag => 'compare template', + namespace => 'Asset_Matrix' + }, + { + tag => 'ratings detail template', + namespace => 'Asset_Matrix' + }, + { + tag => 'main template', + namespace => 'Asset_Matrix' + }, + { + tag => 'listing detail template', + namespace => 'Asset_Matrix' + }, + ], + }, + 'search template' => { + title => 'search template help title', + body => 'search template help body', + related => [ + { + tag => 'add/edit', + namespace => 'Asset_Matrix' + }, + { + tag => 'compare template', + namespace => 'Asset_Matrix' + }, + { + tag => 'ratings detail template', + namespace => 'Asset_Matrix' + }, + { + tag => 'main template', + namespace => 'Asset_Matrix' + }, + { + tag => 'listing detail template', + namespace => 'Asset_Matrix' + }, + ], + }, + 'compare template' => { + title => 'compare template help title', + body => 'compare template help body', + related => [ + { + tag => 'add/edit', + namespace => 'Asset_Matrix' + }, + { + tag => 'search template', + namespace => 'Asset_Matrix' + }, + { + tag => 'ratings detail template', + namespace => 'Asset_Matrix' + }, + { + tag => 'main template', + namespace => 'Asset_Matrix' + }, + { + tag => 'listing detail template', + namespace => 'Asset_Matrix' + }, + ], + }, + 'ratings detail template' => { + title => 'ratings detail template help title', + body => 'ratings detail template help body', + related => [ + { + tag => 'add/edit', + namespace => 'Asset_Matrix' + }, + { + tag => 'search template', + namespace => 'Asset_Matrix' + }, + { + tag => 'compare template', + namespace => 'Asset_Matrix' + }, + { + tag => 'main template', + namespace => 'Asset_Matrix' + }, + { + tag => 'listing detail template', + namespace => 'Asset_Matrix' + }, + ], + }, + 'main template' => { + title => 'matrix template help title', + body => 'matrix template help body', + related => [ + { + tag => 'add/edit', + namespace => 'Asset_Matrix' + }, + { + tag => 'search template', + namespace => 'Asset_Matrix' + }, + { + tag => 'compare template', + namespace => 'Asset_Matrix' + }, + { + tag => 'ratings detail template', + namespace => 'Asset_Matrix' + }, + { + tag => 'listing detail template', + namespace => 'Asset_Matrix' + }, + ], + }, + 'listing detail template' => { + title => 'detail template help title', + body => 'detail template help body', + related => [ + { + tag => 'add/edit', + namespace => 'Asset_Matrix' + }, + { + tag => 'search template', + namespace => 'Asset_Matrix' + }, + { + tag => 'compare template', + namespace => 'Asset_Matrix' + }, + { + tag => 'ratings detail template', + namespace => 'Asset_Matrix' + }, + { + tag => 'main template', + namespace => 'Asset_Matrix' + }, + ], + }, +}; + +1; diff --git a/lib/WebGUI/i18n/English/Asset_Matrix.pm b/lib/WebGUI/i18n/English/Asset_Matrix.pm new file mode 100644 index 000000000..219f5b0e5 --- /dev/null +++ b/lib/WebGUI/i18n/English/Asset_Matrix.pm @@ -0,0 +1,685 @@ +package WebGUI::i18n::English::Asset_Matrix; + +our $I18N = { + 'comparison template help body' => { + lastUpdated => 0, + message => q|

The following template variables are available in the comparison template.

+ +

+ isTooMany
+ A condition indicating that the user has selected too many listings to compare. They may only compare Max Comparisons listings at a time. +

+ +

+ + isTooFew
+ A condition indicating that the user has selected too few listings to compare. They must compare at least two listings. +

+ +

+ compare.form
+ The checkbox form that contains all the listings in this matrix. +

+ +

+ + product_loop
+ A loop containing the product information (not contained in categories) for this listing. +

+ +
+

+ name
+ The name of the product. +

+ +

+ version
+ The version number or model number of the product. +

+ +

+ url
+ The URL to the details page for this listing. +

+ +
+ +

+ lastupdated_loop
+ A loop containing the last updated dates for each listing. +

+ +
+

+ lastUpdated
+ + The human readable date that this product was last updated. +

+
+ +

+ category_loop
+ A loop containing all of the category information for each listing. +

+ +
+ +

+ category
+ The name of the current category. +

+ +

+ columnCount
+ The number of products being compared. +

+ +

+ row_loop
+ A loop containing the product data for this field in this category. +

+ +
+

+ column_loop
+ + A loop containing the value data for this field for this product. The first value in this loop is always the field name. +

+ +
+

+ value
+ The value of this field. +

+ +

+ + class
+ The name of the stylesheet class for this field. it is generated by the value with all the spaces replaced by underscores and all the special characters removed. +

+ +

+ description
+ The description for this field. +

+
+ +
+
| + }, + + 'comparison template help title' => { + lastUpdated => 0, + message => q|Matrix Comparison Template| + }, + + 'detail template help body' => { + lastUpdated => 0, + message => q|

The following variables are available in the listing detail template.

+ +

+ discussion
+ The forum attached to this listing. +

+ +

+ email.form
+ + A form to use to send an email to the listing maintainer. +

+ +

+ email.wasSent
+ A condition indicating whether an email message was sent or not. +

+ +

+ edit.url
+ + The URL to the edit page for this listing. +

+ +

+ user.canEdit
+ A condition indicating whether the current user has the privileges necessary to edit this listing. +

+ +

+ user.canApprove
+ + A condition indicating whether the current user has the privileges necessary to approve this listing so it appears on site. +

+ +

+ approve.url
+ The URL to approve this listing. +

+ +

+ delete.url
+ + The URL to delete this listing. +

+ +

+ isPending
+ A condition indicating whether this listing has been approved or not. +

+ +

+ lastUpdated.epoch
+ + The epoch date of when this listing was last updated. +

+ +

+ lastUpdated.date
+ A human readable date of when this listing was last updated. +

+ +

+ id
+ + The unique identifier of this listing. +

+ +

+ description
+ The description of this listing. +

+ +

+ productName
+ + The name of this listing. +

+ +

+ productUrl
+ The manufacturer's URL for this listing. +

+ +

+ productUrl.click
+ + The product URL to use if you want to register the click count for this listing. +

+ +

+ manufacturerName
+ The name of the company that manufactuers theproduct or provides the service represented in this listing. +

+ +

+ manufacturerUrl
+ + The manufacturer's URL. +

+ +

+ manufacturerUrl.click
+ The manufacturer URL to use if you want to register the click count for this listing. +

+ +

+ versionNumber
+ + The version number or model number of this product. +

+ +

+ views
+ The total number of views this listing has received. +

+ +

+ compares
+ + The total number of compares this listing has received. +

+ +

+ clicks
+ The total number of clicks this listing has received. +

+ +

+ ratings
+ + The ratings form (or results) for this listing. +

+ +

+ category_loop
+ A loop is created for each category in this matrix. The name of the loop is the category name with spaces replaced with hypens and a _loop added to the end. So if you have a category called "Bells and Whistles" then the loop would be called "bells-and-whistles_loop". +

+ +
+

+ + value
+ The value of this field. +

+ +

+ name
+ The name of this field. +

+ +

+ + label
+ The label of this field. +

+ +

+ description
+ The description that tells the user what this field represents. +

+ +

+ + category
+ The name the category this field is in. +

+ +

+ class
+ The stylesheet class name for this field. The class is the field value with spaces replaced with underscores and all non alphanumeric characters removed. +

+
+| + }, + + 'detail template help title' => { + lastUpdated => 0, + message => q|Matrix Listing Detail Template| + }, + + 'matrix template help body' => { + lastUpdated => 0, + message => q|

The following variables are available in the main Matrix template.

+ +

+ compare.form
+ The checkbox form that lists all of the comparable items in this matrix. +

+ +

+ + search.url
+ The URL to the matrix search page. +

+ +

+ isLoggedIn
+ A condition indicating whether the current user is logged in to the site. +

+ +

+ + field.list.url
+ The URL to the page where you configure new fields for this matrix. +

+ +

+ listing.add.url
+ The URL to the page where a user can add a new listing to the matrix. +

+ +

+ + best.views.url
+ The URL to the listing that has the most views. +

+ +

+ best.views.count
+ The total number of views of the listing that has the most views. +

+ +

+ + best.views.name
+ The name of the listing that has the most views. +

+ +

+ best.compares.url
+ The URL to the listing that has the most compares. +

+ +

+ + best.compares.count
+ The number of compares of the listing that has the most compares. +

+ +

+ best.compares.name
+ The name of the listing that has the most compares. +

+ +

+ + best.clicks.url
+ The URL of the listing that has the most clicks. +

+ +

+ best.clicks.count
+ The number of clicks of the listing that has the most clicks. +

+ +

+ + best.clicks.name
+ The name of the listing that has the most clicks. +

+ +

+ best_rating_loop
+ A loop containing all of the categories for this matrix and their best ratings. +

+ +
+ +

+ url
+ The URL of the listing that has the best rating for this category. +

+ +

+ category
+ The name of this cateogry. +

+ +

+ name
+ The name of the listing that has the best rating for this category. +

+ +

+ mean
+ The mean (or average) rating of the best listing in this category. +

+ +

+ median
+ The median (or middle) rating of the best listing in this category. +

+ +

+ count
+ The sum of all the votes of the best listing in this category. +

+ +
+ +

+ worst_rating_loop
+ A loop containing all of the categories for this matrix and their worst ratings. +

+ +
+

+ url
+ + The URL of the listing that has the worst rating for this category. +

+ +

+ category
+ The name of this cateogry. +

+ +

+ name
+ + The name of the listing that has the worst rating for this category. +

+ +

+ mean
+ The mean (or average) rating of the worst listing in this category. +

+ +

+ median
+ + The median (or middle) rating of the worst listing in this category. +

+ +

+ count
+ The sum of all the votes of the worst listing in this category. +

+
+ +

+ + ratings.details.url
+ The URL to the ratings details page. +

+ +

+ best.posts.url
+ The URL to the listing that has the most forum posts. +

+ +

+ best.updated.url
+ The URL to the listing that was updated most recently. +

+ +

+ best.updated.date
+ The date of the most recently updated listing. +

+ +

+ + best.updated.name
+ The name of the listing that was most recently updated. +

+ +

+ user.count
+ The total number of registered users on the site. +

+ +

+ + current.user.count
+ The number of users browsing the site right now. +

+ +

+ listing.count
+ The number of listings in this matrix. +

+ +

+ pending_list
+ A loop containing the list of pending listing. +

+

+ url
+ The URL to the pending listing. +

+

+ productName
+ The product title of the pending listing. +

+
+

| + }, + + 'matrix template help title' => { + lastUpdated => 0, + message => q|Matrix Main Template| + }, + + 'ratings detail template help title' => { + lastUpdated => 0, + message => q|Matrix Ratings Detail Template| + }, + + 'ratings detail template help body' => { + lastUpdated => 0, + message => q|

The following variables are available in the ratings detail template.

+ +

+ rating_loop
+ This loop contains a list of the categories in this matrix. +

+ +
+ +

+ category
+ The name of the current category. +

+ +

+ detail_loop
+ A loop containing a list of listings who have had at least 10 ratings votes and are listed in order by average rating from highest to lowest. +

+ +
+

+ url
+ The URL to the detail page for this listing. +

+ +

+ mean
+ + This listing's mean (or average) rating. +

+ +

+ median
+ This listing's median (or middle) rating. +

+ +

+ count
+ + The total score for this listing. +

+ +

+ name
+ The name of this listing. +

+
+
| + }, + + 'search template help body' => { + lastUpdated => 0, + message => q|

The following variables are available in the matrix search template.

+ +

+ compare.form
+ The checkbox form that lists all of the listings in this matrix. +

+ +

+ form.header
+ + The required header component of the search form. +

+ +

+ form.footer
+ The required footer component of the search form. +

+ +

+ form.submit
+ + The default submit button for the search form. +

+ +

+ category_loop
+ A loop is created for each category in this matrix. The category name is "category_loop" where category is the name of the category with spaces replaced with hyphens. So if you had a category called "Bells And Whistles" the loop would be called "bells-and-whistles_loop". +

+ +
+ +

+ name
+ The name of the listing. +

+ +

+ fieldType
+ The type of field specified for this matrix field. +

+ +

+ label
+ The label given to this field that describes what the field represents. +

+ +

+ description
+ A description of the field that gives more detail about the field and is used in the hover over tool tips. +

+ +

+ form
+ The form element representing this field. +

+ +
| + }, + + 'search template help title' => { + lastUpdated => 0, + message => q|Matrix Search Template| + }, + + 'add/edit help title' => { + lastUpdated => 0, + message => q|Matrix, Add/Edit| + }, + + 'add/edit help body' => { + lastUpdated => 0, + message => q|

The Matrix allows you to set up a really powerful comparison system for any manner of item or service.

+ +

+ Categories
+ + Specify one category per line here to define the categories for this matrix. Categories are used to subdivide fields and also represent the things users can rate each listing on. +

+ +

+ Detail Template
+ Select a template to be used to display the detailed information about a listing. +

+ +

+ Rating Detail Template
+ + Select a template to be used to display the detailed ratings information. +

+ +

+ Search Template
+ Select a template to be used to display the search engine interface. +

+ +

+ Compare Template
+ Select a template to be used to show the listing comparison data. +

| + }, +} + +1;