1499 lines
53 KiB
Perl
1499 lines
53 KiB
Perl
package WebGUI::Asset::Wobject::Matrix;
|
|
|
|
use strict;
|
|
our $VERSION = "2.0.0";
|
|
|
|
#-------------------------------------------------------------------
|
|
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
|
#-------------------------------------------------------------------
|
|
# Please read the legal notices (docs/legal.txt) and the license
|
|
# (docs/license.txt) that came with this distribution before using
|
|
# this software.
|
|
#-------------------------------------------------------------------
|
|
# http://www.plainblack.com info@plainblack.com
|
|
#-------------------------------------------------------------------
|
|
|
|
use Tie::IxHash;
|
|
use JSON;
|
|
use WebGUI::International;
|
|
use WebGUI::Utility;
|
|
use WebGUI::Asset::MatrixListing;
|
|
use base 'WebGUI::Asset::Wobject';
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
=head2 canAddMatrixListing ( )
|
|
|
|
Returns true if able to add MatrixListings.
|
|
|
|
=cut
|
|
|
|
sub canAddMatrixListing {
|
|
my $self = shift;
|
|
my $user = $self->session->user;
|
|
|
|
# Users in the groupToAdd group can add listings
|
|
if ( $user->isInGroup( $self->get("groupToAdd") ) ) {
|
|
return 1;
|
|
}
|
|
# Users who can edit matrix can add listings
|
|
else {
|
|
return $self->canEdit;
|
|
}
|
|
|
|
}
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
=head2 canEdit ( [userId] )
|
|
|
|
Returns true if the user can edit this Matrix.
|
|
|
|
Also checks if a user is adding a Matrix Listing and allows them to if they are
|
|
part of the C<groupToAdd> group.
|
|
|
|
=cut
|
|
|
|
sub canEdit {
|
|
my $self = shift;
|
|
my $userId = shift || $self->session->user->userId;
|
|
|
|
my $form = $self->session->form;
|
|
if ( $form->get('func') eq "editSave" && $form->get('assetId') eq "new" && $form->get( 'class' )->isa(
|
|
'WebGUI::Asset::MatrixListing' ) ) {
|
|
return $self->canAddMatrixListing();
|
|
}
|
|
else {
|
|
if ($userId eq $self->get("ownerUserId")) {
|
|
return 1;
|
|
}
|
|
my $user = WebGUI::User->new($self->session, $userId);
|
|
return $user->isInGroup($self->get("groupIdEdit"));
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 definition ( )
|
|
|
|
defines wobject properties for Matrix instances.
|
|
|
|
=cut
|
|
|
|
sub definition {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
my $definition = shift;
|
|
my $i18n = WebGUI::International->new($session, 'Asset_Matrix');
|
|
|
|
my %properties;
|
|
tie %properties, 'Tie::IxHash';
|
|
%properties = (
|
|
templateId =>{
|
|
fieldType =>"template",
|
|
defaultValue =>'matrixtmpl000000000001',
|
|
tab =>"display",
|
|
noFormPost =>0,
|
|
namespace =>"Matrix",
|
|
hoverHelp =>$i18n->get('template description'),
|
|
label =>$i18n->get('template label'),
|
|
},
|
|
searchTemplateId=>{
|
|
defaultValue =>"matrixtmpl000000000005",
|
|
fieldType =>"template",
|
|
tab =>"display",
|
|
namespace =>"Matrix/Search",
|
|
hoverHelp =>$i18n->get('search template description'),
|
|
label =>$i18n->get('search template label'),
|
|
},
|
|
detailTemplateId=>{
|
|
defaultValue =>"matrixtmpl000000000003",
|
|
fieldType =>"template",
|
|
tab =>"display",
|
|
namespace =>"Matrix/Detail",
|
|
hoverHelp =>$i18n->get('detail template description'),
|
|
label =>$i18n->get('detail template label'),
|
|
},
|
|
compareTemplateId=>{
|
|
defaultValue =>"matrixtmpl000000000002",
|
|
fieldType =>"template",
|
|
tab =>"display",
|
|
namespace =>"Matrix/Compare",
|
|
hoverHelp =>$i18n->get('compare template description'),
|
|
label =>$i18n->get('compare template label'),
|
|
},
|
|
editListingTemplateId=>{
|
|
defaultValue =>"matrixtmpl000000000004",
|
|
fieldType =>"template",
|
|
tab =>"display",
|
|
namespace =>"Matrix/EditListing",
|
|
hoverHelp =>$i18n->get('edit listing template description'),
|
|
label =>$i18n->get('edit listing template label'),
|
|
},
|
|
screenshotsTemplateId=>{
|
|
defaultValue =>"matrixtmpl000000000006",
|
|
fieldType =>"template",
|
|
tab =>"display",
|
|
namespace =>"Matrix/Screenshots",
|
|
hoverHelp =>$i18n->get('screenshots template description'),
|
|
label =>$i18n->get('screenshots template label'),
|
|
},
|
|
screenshotsConfigTemplateId=>{
|
|
defaultValue =>"matrixtmpl000000000007",
|
|
fieldType =>"template",
|
|
tab =>"display",
|
|
namespace =>"Matrix/ScreenshotsConfig",
|
|
hoverHelp =>$i18n->get('screenshots config template description'),
|
|
label =>$i18n->get('screenshots config template label'),
|
|
},
|
|
defaultSort=>{
|
|
fieldType =>"selectBox",
|
|
tab =>"display",
|
|
options =>{
|
|
score => $i18n->get('sort by score label'),
|
|
title => $i18n->get('sort alpha numeric label'),
|
|
lineage => $i18n->get('sort by asset rank label'),
|
|
lastUpdated => $i18n->get('sort by last updated label'),
|
|
},
|
|
defaultValue =>"title",
|
|
hoverHelp =>$i18n->get('default sort description'),
|
|
label =>$i18n->get('default sort label'),
|
|
},
|
|
compareColorNo=>{
|
|
fieldType =>"color",
|
|
tab =>"display",
|
|
defaultValue =>"#ffaaaa",
|
|
hoverHelp =>$i18n->get('compare color no description'),
|
|
label =>$i18n->get('compare color no label'),
|
|
},
|
|
compareColorLimited=>{
|
|
fieldType =>"color",
|
|
tab =>"display",
|
|
defaultValue =>"#ffffaa",
|
|
hoverHelp =>$i18n->get('compare color limited description'),
|
|
label =>$i18n->get('compare color limited label'),
|
|
},
|
|
compareColorCostsExtra=>{
|
|
fieldType =>"color",
|
|
tab =>"display",
|
|
defaultValue =>"#ffffaa",
|
|
hoverHelp =>$i18n->get('compare color costs extra description'),
|
|
label =>$i18n->get('compare color costs extra label'),
|
|
},
|
|
compareColorFreeAddOn=>{
|
|
fieldType =>"color",
|
|
tab =>"display",
|
|
defaultValue =>"#ffffaa",
|
|
hoverHelp =>$i18n->get('compare color free add on description'),
|
|
label =>$i18n->get('compare color free add on label'),
|
|
},
|
|
compareColorYes=>{
|
|
fieldType =>"color",
|
|
tab =>"display",
|
|
defaultValue =>"#aaffaa",
|
|
hoverHelp =>$i18n->get('compare color yes description'),
|
|
label =>$i18n->get('compare color yes label'),
|
|
},
|
|
maxScreenshotWidth=>{
|
|
fieldType =>"integer",
|
|
tab =>"display",
|
|
defaultValue =>"800",
|
|
hoverHelp =>$i18n->get('max screenshot width description'),
|
|
label =>$i18n->get('max screenshot width label'),
|
|
},
|
|
maxScreenshotHeight=>{
|
|
fieldType =>"integer",
|
|
tab =>"display",
|
|
defaultValue =>"600",
|
|
hoverHelp =>$i18n->get('max screenshot height description'),
|
|
label =>$i18n->get('max screenshot height label'),
|
|
},
|
|
categories=>{
|
|
fieldType =>"textarea",
|
|
tab =>"properties",
|
|
defaultValue =>$i18n->get('categories default value'),
|
|
hoverHelp =>$i18n->get('categories description'),
|
|
label =>$i18n->get('categories label'),
|
|
subtext =>$i18n->get('categories subtext'),
|
|
},
|
|
maxComparisons=>{
|
|
fieldType =>"integer",
|
|
tab =>"properties",
|
|
defaultValue =>25,
|
|
hoverHelp =>$i18n->get('max comparisons description'),
|
|
label =>$i18n->get('max comparisons label'),
|
|
},
|
|
maxComparisonsPrivileged=>{
|
|
fieldType =>"integer",
|
|
tab =>"properties",
|
|
defaultValue =>10,
|
|
hoverHelp =>$i18n->get('max comparisons privileged description'),
|
|
label =>$i18n->get('max comparisons privileged label'),
|
|
},
|
|
maxComparisonsGroup=>{
|
|
fieldType =>"group",
|
|
tab =>"properties",
|
|
hoverHelp =>$i18n->get('maxgroup description'),
|
|
label =>$i18n->get('maxgroup label'),
|
|
},
|
|
maxComparisonsGroupInt=>{
|
|
fieldType =>"integer",
|
|
tab =>"properties",
|
|
defaultValue =>25,
|
|
hoverHelp =>$i18n->get('maxgroup per description'),
|
|
label =>$i18n->get('maxgroup per label'),
|
|
},
|
|
groupToAdd=>{
|
|
fieldType =>"group",
|
|
tab =>"security",
|
|
defaultValue =>2,
|
|
hoverHelp =>$i18n->get('group to add description'),
|
|
label =>$i18n->get('group to add label'),
|
|
},
|
|
submissionApprovalWorkflowId=>{
|
|
fieldType =>"workflow",
|
|
tab =>"security",
|
|
type =>'WebGUI::VersionTag',
|
|
defaultValue =>"pbworkflow000000000003",
|
|
hoverHelp =>$i18n->get('submission approval workflow description'),
|
|
label =>$i18n->get('submission approval workflow label'),
|
|
},
|
|
ratingsDuration=>{
|
|
fieldType =>"interval",
|
|
tab =>"properties",
|
|
defaultValue =>7776000, # 3 months 3*30*24*60*60
|
|
hoverHelp =>$i18n->get('ratings duration description'),
|
|
label =>$i18n->get('ratings duration label'),
|
|
},
|
|
statisticsCacheTimeout => {
|
|
tab => "display",
|
|
fieldType => "interval",
|
|
defaultValue => 3600,
|
|
uiLevel => 8,
|
|
label => $i18n->get("statistics cache timeout label"),
|
|
hoverHelp => $i18n->get("statistics cache timeout description")
|
|
},
|
|
listingsCacheTimeout => {
|
|
tab => "display",
|
|
fieldType => "interval",
|
|
defaultValue => 3600,
|
|
uiLevel => 8,
|
|
label => $i18n->get("listings cache timeout label"),
|
|
hoverHelp => $i18n->get("listings cache timeout description")
|
|
},
|
|
);
|
|
push(@{$definition}, {
|
|
assetName=>$i18n->get('assetName'),
|
|
icon=>'matrix.gif',
|
|
autoGenerateForms=>1,
|
|
tableName=>'Matrix',
|
|
className=>'WebGUI::Asset::Wobject::Matrix',
|
|
properties=>\%properties
|
|
});
|
|
return $class->SUPER::definition($session, $definition);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 deleteAttribute ( attributeId )
|
|
|
|
Deletes an attribute and listing data for this attribute from Collateral.
|
|
|
|
=head3 attributeId
|
|
|
|
The id of the attribute that should be deleted.
|
|
|
|
=cut
|
|
|
|
sub deleteAttribute {
|
|
|
|
my $self = shift;
|
|
my $attributeId = shift;
|
|
|
|
$self->deleteCollateral("Matrix_attribute","attributeId",$attributeId);
|
|
$self->session->db->write("delete from MatrixListing_attribute where attributeId=? and matrixId=?",
|
|
[$attributeId,$self->getId]);
|
|
|
|
# recalculate scores for MatrixListings
|
|
my $listingIter = $self->getLineageIterator(['descendants'], {
|
|
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
|
|
});
|
|
while ( 1 ) {
|
|
my $listing;
|
|
eval { $listing = $listingIter->() };
|
|
if ( my $x = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound') ) {
|
|
$self->session->log->error($x->full_message);
|
|
next;
|
|
}
|
|
last unless $listing;
|
|
$listing->updateScore;
|
|
}
|
|
|
|
return undef;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 duplicate ( )
|
|
|
|
duplicates a Matrix.
|
|
|
|
=cut
|
|
|
|
sub duplicate {
|
|
my $self = shift;
|
|
my $newAsset = $self->SUPER::duplicate(@_);
|
|
return $newAsset;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 editAttributeSave ( attributeProperties )
|
|
|
|
Saves an attribute.
|
|
|
|
=head3 attributeProperties
|
|
|
|
A hashref containing the properties of the attribute.
|
|
|
|
=cut
|
|
|
|
sub editAttributeSave {
|
|
my $self = shift;
|
|
my $attributeProperties = shift;
|
|
my $session = $self->session;
|
|
my $form = $session->form;
|
|
|
|
return $session->privilege->insufficient() unless $self->canEdit;
|
|
|
|
my $attributeId = $self->setCollateral("Matrix_attribute","attributeId",$attributeProperties,0,1);
|
|
|
|
return $attributeId;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getAttribute ( attributeId )
|
|
|
|
Returns a hash reference of the properties of an attribute.
|
|
|
|
=head3 attributeId
|
|
|
|
The unique id of an attribute.
|
|
|
|
=cut
|
|
|
|
sub getAttribute {
|
|
my ($self, $attributeId) = @_;
|
|
return $self->session->db->quickHashRef("select * from Matrix_attribute where attributeId=?",[$attributeId]);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getCategories ( )
|
|
|
|
Returns the categories for this Matrix as a hashref.
|
|
|
|
=cut
|
|
|
|
sub getCategories {
|
|
my $self = shift;
|
|
my %categories;
|
|
tie %categories, 'Tie::IxHash';
|
|
|
|
my $categories = $self->getValue("categories");
|
|
$categories =~ s/\r//g;
|
|
chomp($categories);
|
|
|
|
my @categories = split(/\n/,$categories);
|
|
foreach my $category (@categories) {
|
|
$categories{$category} = $category;
|
|
}
|
|
return \%categories;
|
|
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getCompareColor ( )
|
|
|
|
Returns the compare color for a MatrixCompare value.
|
|
|
|
=head3 value
|
|
|
|
The value of a MatrixCompare form field.
|
|
|
|
=cut
|
|
|
|
sub getCompareColor {
|
|
|
|
my $self = shift;
|
|
my $value = shift;
|
|
|
|
if($value == 0){
|
|
return $self->get('compareColorNo');
|
|
}
|
|
elsif($value == 1){
|
|
return $self->get('compareColorLimited');
|
|
}
|
|
elsif($value == 2){
|
|
return $self->get('compareColorCostsExtra');
|
|
}
|
|
elsif($value == 3){
|
|
return $self->get('compareColorFreeAddOn');
|
|
}
|
|
elsif($value == 4){
|
|
return $self->get('compareColorYes');
|
|
}
|
|
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getCompareForm ( )
|
|
|
|
Returns the compare form.
|
|
|
|
=cut
|
|
|
|
sub getCompareForm {
|
|
my $self = shift;
|
|
|
|
my $form = WebGUI::Form::formHeader($self->session,{action=>$self->getUrl,extras=>'name="doCompare"'})
|
|
."<br />"
|
|
.WebGUI::Form::hidden($self->session, {
|
|
name=>"func",
|
|
value=>"compare"
|
|
})
|
|
.'<div id="compareForm"></div> '
|
|
."<br />"
|
|
.WebGUI::Form::formFooter($self->session);
|
|
|
|
my $maxComparisons;
|
|
if($self->session->user->isVisitor){
|
|
$maxComparisons = $self->get('maxComparisons');
|
|
}
|
|
elsif($self->session->user->isInGroup( $self->get("maxComparisonsGroup") )) {
|
|
$maxComparisons = $self->get('maxComparisonsGroupInt');
|
|
}
|
|
else{
|
|
$maxComparisons = $self->get('maxComparisonsPrivileged');
|
|
}
|
|
$maxComparisons += 0;
|
|
$form .= "\n<script type='text/javascript'>\n".
|
|
'var maxComparisons = '.$maxComparisons.";\n".
|
|
"var matrixUrl = '".$self->getUrl."';\n".
|
|
"\n</script>\n";
|
|
return $form;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getListings ( )
|
|
|
|
Returns the listings as an arrayRef of hashRefs.
|
|
|
|
=head3 sort
|
|
|
|
The criterium by which the listings should be sorted.
|
|
|
|
=cut
|
|
|
|
sub getListings {
|
|
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $sort = shift || $session->scratch->get('matrixSort') || $self->get('defaultSort');
|
|
my $versionTag = WebGUI::VersionTag->getWorking($session, 1);
|
|
my ($listings, $listingsEncoded);
|
|
|
|
my $noCache =
|
|
$session->var->isAdminOn
|
|
|| $self->get("listingsCacheTimeout") <= 10
|
|
|| ($versionTag && $versionTag->getId eq $self->get("tagId"));
|
|
unless ($noCache) {
|
|
$listingsEncoded = WebGUI::Cache->new($session,"matrixListings_".$self->getId)->get;
|
|
}
|
|
|
|
if ($listingsEncoded){
|
|
$listings = JSON->new->decode($listingsEncoded);
|
|
}
|
|
else{
|
|
my $sortDirection = ' desc';
|
|
if ($sort eq 'title'){
|
|
$sortDirection = ' asc';
|
|
}
|
|
|
|
my $sql = "
|
|
select
|
|
assetData.title,
|
|
assetData.url,
|
|
listing.assetId,
|
|
listing.views,
|
|
listing.compares,
|
|
listing.clicks,
|
|
listing.lastUpdated
|
|
from asset
|
|
left join assetData using(assetId)
|
|
left join MatrixListing as listing on listing.assetId = assetData.assetId and listing.revisionDate =
|
|
assetData.revisionDate
|
|
where
|
|
asset.parentId=?
|
|
and asset.state='published'
|
|
and asset.className='WebGUI::Asset::MatrixListing'
|
|
and assetData.revisionDate = (SELECT max(revisionDate) from assetData where assetId=asset.assetId and status='approved')
|
|
and status='approved'
|
|
order by ".$sort.$sortDirection;
|
|
|
|
$listings = $session->db->buildArrayRefOfHashRefs($sql,[$self->getId]);
|
|
|
|
foreach my $listing (@{$listings}) {
|
|
$listing->{url} = $session->url->gateway($listing->{url});
|
|
}
|
|
|
|
$listingsEncoded = JSON->new->encode($listings);
|
|
WebGUI::Cache->new($session,"matrixListings_".$self->getId)->set(
|
|
$listingsEncoded,$self->get("listingsCacheTimeout")
|
|
);
|
|
}
|
|
return $listings;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getEditForm ( )
|
|
|
|
returns the tabform object that will be used in generating the edit page for Matrix.
|
|
|
|
=cut
|
|
|
|
sub getEditForm {
|
|
my $self = shift;
|
|
my $tabform = $self->SUPER::getEditForm();
|
|
return $tabform;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 prepareView ( )
|
|
|
|
See WebGUI::Asset::prepareView() for details.
|
|
|
|
=cut
|
|
|
|
sub prepareView {
|
|
my $self = shift;
|
|
|
|
$self->SUPER::prepareView();
|
|
my $template = WebGUI::Asset::Template->new($self->session, $self->get("templateId"));
|
|
if (!$template) {
|
|
WebGUI::Error::ObjectNotFound::Template->throw(
|
|
error => qq{Template not found},
|
|
templateId => $self->get("templateId"),
|
|
assetId => $self->getId,
|
|
);
|
|
}
|
|
$template->prepare;
|
|
$self->{_viewTemplate} = $template;
|
|
|
|
return undef;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 purge ( )
|
|
|
|
removes collateral data associated with a Matrix when the system
|
|
purges it's data.
|
|
|
|
=cut
|
|
|
|
sub purge {
|
|
my $self = shift;
|
|
|
|
$self->session->db->write("delete from Matrix_attribute where assetId=?",[$self->getId]);
|
|
return $self->SUPER::purge;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 view ( )
|
|
|
|
method called by the www_view method. Returns a processed template
|
|
to be displayed within the page style.
|
|
|
|
=cut
|
|
|
|
sub view {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $db = $session->db;
|
|
my $url = $session->url;
|
|
my $style = $session->style;
|
|
my $i18n = WebGUI::International->new($session, 'Asset_Matrix');
|
|
|
|
# javascript and css files for compare form datatable
|
|
$style->setLink($url->extras('yui/build/datatable/assets/skins/sam/datatable.css'),
|
|
{type =>'text/css', rel=>'stylesheet'});
|
|
|
|
$style->setScript($url->extras('yui/build/utilities/utilities.js'), {type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/json/json-min.js'), {type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/datasource/datasource-min.js'), {type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/datatable/datatable-min.js'), {type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/button/button-min.js'), {type => 'text/javascript'});
|
|
|
|
my ($varStatistics,$varStatisticsEncoded);
|
|
my $var = $self->get;
|
|
$var->{isLoggedIn} = ($session->user->userId ne "1");
|
|
$var->{addMatrixListing_url} = $self->getUrl('func=add;class=WebGUI::Asset::MatrixListing');
|
|
$var->{exportAttributes_url} = $self->getUrl('func=exportAttributes');
|
|
$var->{listAttributes_url} = $self->getUrl('func=listAttributes');
|
|
$var->{search_url} = $self->getUrl('func=search');
|
|
$var->{matrix_url} = $self->getUrl();
|
|
|
|
my $maxComparisons;
|
|
if($session->user->isVisitor){
|
|
$maxComparisons = $self->get('maxComparisons');
|
|
}
|
|
elsif($session->user->isInGroup( $self->get("maxComparisonsGroup") )) {
|
|
$maxComparisons = $self->get('maxComparisonsGroupInt');
|
|
}
|
|
else{
|
|
$maxComparisons = $self->get('maxComparisonsPrivileged');
|
|
}
|
|
$maxComparisons += 0;
|
|
$var->{maxComparisons} = $maxComparisons;
|
|
|
|
if ($self->canEdit){
|
|
# Get all the MatrixListings that are still pending.
|
|
my $pendingIter = $self->getLineageIterator(['descendants'], {
|
|
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
|
|
orderByClause => "revisionDate asc",
|
|
statusToInclude => ['pending'],
|
|
});
|
|
while ( 1 ) {
|
|
my $pending;
|
|
eval { $pending = $pendingIter->() };
|
|
if ( my $x = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound') ) {
|
|
$session->log->error($x->full_message);
|
|
next;
|
|
}
|
|
last unless $pending;
|
|
push (@{ $var->{pending_loop} }, {
|
|
url => $pending->getUrl
|
|
."?func=view;revision=".$pending->get('revisionDate'),
|
|
name => $pending->get('title'),
|
|
});
|
|
}
|
|
}
|
|
|
|
my $versionTag = WebGUI::VersionTag->getWorking($session, 1);
|
|
my $noCache =
|
|
$session->var->isAdminOn
|
|
|| $self->get("statisticsCacheTimeout") <= 10
|
|
|| ($versionTag && $versionTag->getId eq $self->get("tagId"));
|
|
unless ($noCache) {
|
|
$varStatisticsEncoded = WebGUI::Cache->new($session,"matrixStatistics_".$self->getId)->get;
|
|
}
|
|
|
|
if ($varStatisticsEncoded){
|
|
$varStatistics = JSON->new->decode($varStatisticsEncoded);
|
|
}
|
|
else{
|
|
$varStatistics->{alphanumeric_sortButton} = "<span id='sortByName'><button type='button'>"
|
|
. $i18n->get('Sort by name')
|
|
. "</button></span><br />";
|
|
|
|
# Get the MatrixListing with the most views as an object using getLineage.
|
|
my ($bestViews_listing) = @{ $self->getLineage(['descendants'], {
|
|
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
|
|
joinClass => "WebGUI::Asset::MatrixListing",
|
|
orderByClause => "views desc",
|
|
limit => 1,
|
|
returnObjects => 1,
|
|
}) };
|
|
if($bestViews_listing){
|
|
$varStatistics->{bestViews_url} = $bestViews_listing->getUrl;
|
|
$varStatistics->{bestViews_count} = $bestViews_listing->get('views');
|
|
$varStatistics->{bestViews_name} = $bestViews_listing->get('title');
|
|
$varStatistics->{bestViews_sortButton} = "<span id='sortByViews'><button type='button'>"
|
|
. $i18n->get('Sort by views')
|
|
. "</button></span><br />";
|
|
}
|
|
|
|
# Get the MatrixListing with the most compares as an object using getLineage.
|
|
|
|
my ($bestCompares_listing) = @{ $self->getLineage(['descendants'], {
|
|
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
|
|
joinClass => "WebGUI::Asset::MatrixListing",
|
|
orderByClause => "compares desc",
|
|
limit => 1,
|
|
returnObjects => 1,
|
|
}) };
|
|
if($bestCompares_listing){
|
|
$varStatistics->{bestCompares_url} = $bestCompares_listing->getUrl;
|
|
$varStatistics->{bestCompares_count} = $bestCompares_listing->get('compares');
|
|
$varStatistics->{bestCompares_name} = $bestCompares_listing->get('title');
|
|
$varStatistics->{bestCompares_sortButton} = "<span id='sortByCompares'><button type='button'>"
|
|
. $i18n->get('Sort by compares')
|
|
. "</button></span><br />";
|
|
}
|
|
|
|
# Get the MatrixListing with the most clicks as an object using getLineage.
|
|
my ($bestClicks_listing) = @{ $self->getLineage(['descendants'], {
|
|
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
|
|
joinClass => "WebGUI::Asset::MatrixListing",
|
|
orderByClause => "clicks desc",
|
|
limit => 1,
|
|
returnObjects => 1,
|
|
}) };
|
|
if($bestClicks_listing){
|
|
$varStatistics->{bestClicks_url} = $bestClicks_listing->getUrl;
|
|
$varStatistics->{bestClicks_count} = $bestClicks_listing->get('clicks');
|
|
$varStatistics->{bestClicks_name} = $bestClicks_listing->get('title');
|
|
$varStatistics->{bestClicks_sortButton} = "<span id='sortByClicks'><button type='button'>"
|
|
. $i18n->get('Sort by clicks')
|
|
. "</button></span><br />";
|
|
}
|
|
|
|
# Get the 5 MatrixListings that were last updated as objects using getLineage.
|
|
|
|
my $lastUpdatedIter = $self->getLineageIterator(['descendants'], {
|
|
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
|
|
joinClass => "WebGUI::Asset::MatrixListing",
|
|
orderByClause => "lastUpdated desc",
|
|
});
|
|
for ( 1..5 ) {
|
|
my $lastUpdated;
|
|
eval { $lastUpdated = $lastUpdatedIter->() };
|
|
if ( my $x = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound') ) {
|
|
$session->log->error($x->full_message);
|
|
next;
|
|
}
|
|
last unless $lastUpdated;
|
|
push (@{ $varStatistics->{last_updated_loop} }, {
|
|
url => $lastUpdated->getUrl,
|
|
name => $lastUpdated->get('title'),
|
|
lastUpdated => $session->datetime->epochToHuman($lastUpdated->get('lastUpdated'),"%z")
|
|
});
|
|
}
|
|
$varStatistics->{lastUpdated_sortButton} = "<span id='sortByUpdated'><button type='button'>"
|
|
. $i18n->get('Sort by updated')
|
|
. "</button></span><br />";
|
|
|
|
# For each category, get the MatrixListings with the best ratings.
|
|
|
|
foreach my $category (keys %{$self->getCategories}) {
|
|
my $data;
|
|
my $sql = "
|
|
select
|
|
assetData.title as productName,
|
|
assetData.url,
|
|
rating.listingId,
|
|
rating.meanValue,
|
|
rating.medianValue,
|
|
rating.countValue,
|
|
asset.parentId
|
|
from
|
|
MatrixListing_ratingSummary as rating
|
|
left join asset on (rating.listingId = asset.assetId)
|
|
left join assetData on assetData.assetId = rating.listingId
|
|
where
|
|
rating.category =?
|
|
and asset.parentId=?
|
|
and asset.state='published'
|
|
and rating.countValue >= 10
|
|
and assetData.revisionDate=(
|
|
select
|
|
max(revisionDate)
|
|
from
|
|
assetData
|
|
where
|
|
assetData.assetId=asset.assetId
|
|
and (status='approved' or status='archived')
|
|
)
|
|
group by
|
|
assetData.assetId
|
|
order by rating.meanValue ";
|
|
|
|
$data = $db->quickHashRef($sql." desc limit 1",[$category,$self->getId]);
|
|
push(@{ $varStatistics->{best_rating_loop} },{
|
|
url => $session->url->gateway($data->{url}),
|
|
category => $category,
|
|
name => $data->{productName},
|
|
mean => 0+$data->{meanValue},
|
|
median => 0+$data->{medianValue},
|
|
count => 0+$data->{countValue}
|
|
});
|
|
$data = $db->quickHashRef($sql." asc limit 1",[$category,$self->getId]);
|
|
push(@{ $varStatistics->{worst_rating_loop} },{
|
|
url => $session->url->gateway($data->{url}),
|
|
category => $category,
|
|
name => $data->{productName},
|
|
mean => 0+$data->{meanValue},
|
|
median => 0+$data->{medianValue},
|
|
count => 0+$data->{countValue}
|
|
});
|
|
}
|
|
|
|
$varStatistics->{listingCount} = scalar $db->buildArray("
|
|
select *
|
|
from asset, assetData
|
|
where asset.assetId=assetData.assetId
|
|
and asset.parentId=?
|
|
and asset.state='published'
|
|
and asset.className='WebGUI::Asset::MatrixListing'
|
|
and assetData.status='approved'
|
|
group by asset.assetId",
|
|
[$self->getId]);
|
|
|
|
$varStatisticsEncoded = JSON->new->encode($varStatistics);
|
|
WebGUI::Cache->new($session,"matrixStatistics_".$self->getId)->set(
|
|
$varStatisticsEncoded,$self->get("statisticsCacheTimeout")
|
|
);
|
|
}
|
|
|
|
foreach my $statistic (keys %{$varStatistics}) {
|
|
$var->{$statistic} = $varStatistics->{$statistic};
|
|
}
|
|
|
|
return $self->processTemplate($var, undef, $self->{_viewTemplate});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_compare ( )
|
|
|
|
Returns the compare screen
|
|
|
|
=head3 listingIds
|
|
|
|
An array of listingIds that should be selected in the compare form.
|
|
|
|
=cut
|
|
|
|
sub www_compare {
|
|
|
|
my $self = shift;
|
|
my $var = $self->get;
|
|
my $session = $self->session;
|
|
my $style = $session->style;
|
|
my $url = $session->url;
|
|
my @listingIds = @_;
|
|
my @responseFields;
|
|
|
|
unless (scalar(@listingIds)) {
|
|
@listingIds = $self->session->form->checkList("listingId");
|
|
}
|
|
|
|
$style->setScript($url->extras('yui/build/utilities/utilities.js'),
|
|
{type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/json/json-min.js'),
|
|
{type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/datasource/datasource-min.js'),
|
|
{type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/datatable/datatable-min.js'),
|
|
{type =>'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/button/button-min.js'),
|
|
{type =>'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/container/container-min.js'),
|
|
{type =>'text/javascript'});
|
|
$style->setLink($url->extras('yui/build/datatable/assets/skins/sam/datatable.css'),
|
|
{type =>'text/css', rel=>'stylesheet'});
|
|
$style->setScript($url->extras('hoverhelp.js'),
|
|
{type => 'text/javascript'});
|
|
$style->setLink($url->extras('hoverhelp.css'),
|
|
{type =>'text/css', rel=>'stylesheet'});
|
|
|
|
my $maxComparisons;
|
|
if($self->session->user->isVisitor){
|
|
$maxComparisons = $self->get('maxComparisons');
|
|
}
|
|
elsif($self->session->user->isInGroup( $self->get("maxComparisonsGroup") )) {
|
|
$maxComparisons = $self->get('maxComparisonsGroupInt');
|
|
}
|
|
else{
|
|
$maxComparisons = $self->get('maxComparisonsPrivileged');
|
|
}
|
|
$maxComparisons += 0;
|
|
|
|
foreach my $listingId (@listingIds){
|
|
my $listingId_safe = $listingId;
|
|
$listingId_safe =~ s/-/_____/g;
|
|
push(@responseFields, $listingId_safe, $listingId_safe."_compareColor");
|
|
}
|
|
|
|
$var->{maxComparisons} = $maxComparisons;
|
|
$var->{matrixUrl} = $self->getUrl;
|
|
$var->{listingIds} = join(", ",map {'"'.$_.'"'} @listingIds);
|
|
$var->{responseFields} = '"attributeId", "name", "description","fieldType", "checked", '
|
|
.join(", ",map{'"'.$_.'"'} @responseFields);
|
|
|
|
return $self->processStyle($self->processTemplate($var,$self->get("compareTemplateId")));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_deleteAttribute ( )
|
|
|
|
Deletes an Attribute, including listing data for this attribute.
|
|
|
|
=cut
|
|
|
|
sub www_deleteAttribute {
|
|
my $self = shift;
|
|
my $attributeId = $self->session->form->process("attributeId");
|
|
|
|
return $self->session->privilege->insufficient() unless $self->canEdit;
|
|
|
|
$self->deleteAttribute($attributeId);
|
|
|
|
return $self->www_listAttributes;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_deleteStickied ( )
|
|
|
|
Sets the sort scratch variable.
|
|
|
|
=cut
|
|
|
|
sub www_deleteStickied {
|
|
|
|
my $self = shift;
|
|
|
|
if(my $attributeId = $self->session->form->process("attributeId")){
|
|
$self->session->scratch->delete('stickied_'.$attributeId);
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_editAttribute ( )
|
|
|
|
Shows a form to edit or add an attribute.
|
|
|
|
=cut
|
|
|
|
sub www_editAttribute {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my ($attributeId, $attribute);
|
|
|
|
return $session->privilege->insufficient() unless $self->canEdit;
|
|
my $i18n = WebGUI::International->new($session, "Asset_Matrix");
|
|
|
|
$attributeId = $session->form->process("attributeId") || 'new';
|
|
|
|
unless($attributeId eq 'new'){
|
|
$attribute = $self->getAttribute($attributeId);
|
|
}
|
|
|
|
my $form = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
|
|
$form->hidden(
|
|
-name =>"func",
|
|
-value =>"editAttributeSave"
|
|
);
|
|
$form->hidden(
|
|
-name =>"attributeId",
|
|
-value =>$attributeId,
|
|
);
|
|
$form->text(
|
|
-name =>"name",
|
|
-value =>$attribute->{name},
|
|
-label =>$i18n->get('attribute name label'),
|
|
-hoverHelp =>$i18n->get('attribute name description'),
|
|
);
|
|
$form->textarea(
|
|
-name =>"description",
|
|
-value =>$attribute->{description},
|
|
-label =>$i18n->get('attribute description label'),
|
|
-hoverHelp =>$i18n->get('attribute description description'),
|
|
);
|
|
$form->matrixFieldType(
|
|
-name =>"fieldType",
|
|
-value =>$attribute->{fieldType},
|
|
-label =>$i18n->get('fieldType label'),
|
|
-hoverHelp =>$i18n->get('fieldType description'),
|
|
);
|
|
my $defaultValueForm = WebGUI::Form::Text($self->session, {
|
|
name=>"defaultValue",
|
|
value=>$attribute->{defaultValue},
|
|
resizable=>0,
|
|
});
|
|
my $optionsForm = WebGUI::Form::Textarea($self->session, {
|
|
name=>"options",
|
|
value=>$attribute->{options},
|
|
});
|
|
|
|
my $html = "\n<tr><td colspan='2'>\n";
|
|
$html .= "\t<div id='optionsAndDefaultValue_module'>\n";
|
|
$html .= "\t<div class='bd' style='padding:0px;'>\n";
|
|
$html .= "\t<table cellpadding='0' cellspacing='0' style='width: 100%;'>\n";
|
|
|
|
$html .= "\t<tr><td class='formDescription' valign='top' style='width:180px'>"
|
|
.$i18n->get('attribute defaultValue label')
|
|
."<div class='wg-hoverhelp'>".$i18n->get('attribute defaultValue description')."</div></td>"
|
|
."<td valign='top' class='tableData' style='padding-left:4px'>"
|
|
.$defaultValueForm."</td>"
|
|
."\t\n</tr>\n";
|
|
|
|
$html .= "\t<tr><td class='formDescription' valign='top' style='width:180px'>"
|
|
.$i18n->get('attribute options label')
|
|
."<div class='wg-hoverhelp'>".$i18n->get('attribute options description')."</div></td>"
|
|
."<td valign='top' class='tableData' style='padding-left:4px'>"
|
|
.$optionsForm."</td>"
|
|
."\t\n</tr>\n";
|
|
|
|
|
|
$html .= "\t</table>";
|
|
$html .= "\t\n</div>\t\n</div>\n";
|
|
$html .= "</td></tr>";
|
|
|
|
$html .= "<script type='text/javascript'>\n"
|
|
."var optionsAndDefaultValue_module = new YAHOO.widget.Module('optionsAndDefaultValue_module',"
|
|
."{visible:false});\n"
|
|
."optionsAndDefaultValue_module.render();\n"
|
|
."YAHOO.util.Event.onContentReady('fieldType_formId', checkFieldType);\n"
|
|
."YAHOO.util.Event.addListener('fieldType_formId', 'change', checkFieldType);\n"
|
|
."var hasOptions = {'SelectBox': true,'Combo': true};\n"
|
|
."function checkFieldType(){\n"
|
|
." if (this.value in hasOptions){\n"
|
|
." optionsAndDefaultValue_module.show();\n"
|
|
." }else{\n"
|
|
." optionsAndDefaultValue_module.hide();\n"
|
|
." }\n"
|
|
."}\n"
|
|
."</script>\n";
|
|
|
|
$form->raw($html);
|
|
|
|
$form->selectBox(
|
|
-name =>"category",
|
|
-value =>[$attribute->{category}],
|
|
-label =>$i18n->get('category label'),
|
|
-hoverHelp =>$i18n->get('category description'),
|
|
-options =>$self->getCategories,
|
|
);
|
|
$form->submit;
|
|
return $self->getAdminConsole->render($form->print, $i18n->get('edit attribute title'));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_editAttributeSave ( )
|
|
|
|
Processes and saves an attribute.
|
|
|
|
=cut
|
|
|
|
sub www_editAttributeSave {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $form = $session->form;
|
|
|
|
return $session->privilege->insufficient() unless $self->canEdit;
|
|
|
|
my $attributeProperties = {
|
|
attributeId =>$form->process("attributeId") || 'new',
|
|
assetId =>$self->getId,
|
|
name =>$form->process('name'),
|
|
description =>$form->process('description'),
|
|
fieldType =>$form->process('fieldType'),
|
|
options =>$form->process('options'),
|
|
defaultValue =>$form->process('defaultValue'),
|
|
category =>$form->process('category'),
|
|
};
|
|
|
|
$self->editAttributeSave($attributeProperties);
|
|
|
|
return $self->www_listAttributes;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_exportAttributes ( )
|
|
|
|
Exports search attributes as csv.
|
|
|
|
=cut
|
|
|
|
sub www_exportAttributes {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $output = WebGUI::Text::joinCSV("name","description","category");
|
|
|
|
my $attributes = $session->db->read("select name, description, category
|
|
from Matrix_attribute where assetId = ? order by category, name",[$self->getId]);
|
|
|
|
while (my $attribute = $attributes->hashRef) {
|
|
$output .= "\n".WebGUI::Text::joinCSV($attribute->{name},$attribute->{description},$attribute->{category});
|
|
}
|
|
|
|
my $fileName = "export_matrix_attributes.csv";
|
|
$self->session->http->setFilename($fileName,"application/octet-stream");
|
|
$self->session->http->sendHeader;
|
|
return $output;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_getCompareFormData ( )
|
|
|
|
Returns the compare form data as JSON.
|
|
|
|
=head3 sort
|
|
|
|
The criterium by which the listings should be sorted.
|
|
|
|
=cut
|
|
|
|
sub www_getCompareFormData {
|
|
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $form = $session->form;
|
|
my $sort = shift || $session->scratch->get('matrixSort') || $self->get('defaultSort');
|
|
my $sortDirection = ' desc';
|
|
if ($sort eq 'title'){
|
|
$sortDirection = ' asc';
|
|
}
|
|
|
|
my @listingIds = $session->form->checkList("listingId");
|
|
|
|
$session->http->setMimeType("application/json");
|
|
my $db = $session->db;
|
|
|
|
my (@searchParams,@searchParams_sorted,@searchParamList,$searchParamList);
|
|
if($form->process("search")){
|
|
foreach my $param ($form->param) {
|
|
if($param =~ m/^search_/){
|
|
my $parameter;
|
|
$parameter->{name} = $param;
|
|
$parameter->{value} = $form->process($param);
|
|
my $attributeId = $param;
|
|
$attributeId =~ s/^search_//;
|
|
$parameter->{attributeId} = $attributeId;
|
|
push(@searchParamList, $db->quote($parameter->{attributeId}) );
|
|
push(@searchParams, $parameter);
|
|
}
|
|
}
|
|
if (! scalar @searchParamList) {
|
|
##Use defaults for all form values
|
|
foreach my $category (keys %{$self->getCategories}) {
|
|
my $attributes = $db->read("select * from Matrix_attribute where category =? and assetId = ?",
|
|
[$category,$self->getId]);
|
|
while (my $attribute = $attributes->hashRef) {
|
|
push @searchParamList, $db->quote($attribute->{attributeId});
|
|
push @searchParams, {
|
|
name => $attribute->{name},
|
|
value => $attribute->{defaultValue},
|
|
attributeId => $attribute->{attributeId},
|
|
};
|
|
}
|
|
}
|
|
}
|
|
$searchParamList = join(',',@searchParamList);
|
|
@searchParams_sorted = sort { $b->{value} <=> $a->{value} } @searchParams;
|
|
}
|
|
|
|
my @results;
|
|
if($form->process("search")) {
|
|
if ($searchParamList) {
|
|
RESULT: foreach my $result (@{$self->getListings}) {
|
|
my $checked = '';
|
|
my $matrixListing_attributes = $session->db->buildHashRefOfHashRefs("
|
|
select value, fieldType, attributeId from Matrix_attribute
|
|
left join MatrixListing_attribute as listing using(attributeId)
|
|
where listing.matrixListingId = ?
|
|
and attributeId IN(".$searchParamList.")",
|
|
[$result->{assetId}],'attributeId');
|
|
##Searching is AND based.
|
|
PARAM: foreach my $param (@searchParams_sorted) {
|
|
my $fieldType = $matrixListing_attributes->{$param->{attributeId}}->{fieldType};
|
|
my $listingValue = $matrixListing_attributes->{$param->{attributeId}}->{value};
|
|
if(($fieldType eq 'MatrixCompare') && ($listingValue < $param->{value})){
|
|
$checked = '';
|
|
last PARAM;
|
|
}
|
|
elsif(($fieldType ne 'MatrixCompare' && $fieldType ne '') && ($param->{value} ne $listingValue)){
|
|
$checked = '';
|
|
last PARAM;
|
|
}
|
|
else{
|
|
$checked = 'checked';
|
|
}
|
|
}
|
|
push @results, $result if $checked eq 'checked';
|
|
}
|
|
}
|
|
else {
|
|
foreach my $result (@{$self->getListings}) {
|
|
push @results, $result;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
foreach my $result (@{$self->getListings}) {
|
|
if(WebGUI::Utility::isIn($result->{assetId},@listingIds)){
|
|
$result->{checked} = 'checked';
|
|
}
|
|
push @results, $result;
|
|
}
|
|
}
|
|
|
|
my $jsonOutput;
|
|
$jsonOutput->{ResultSet} = {Result=>\@results};
|
|
|
|
my $encodedOutput = JSON->new->encode($jsonOutput);
|
|
|
|
return $encodedOutput;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_getCompareListData ( )
|
|
|
|
Returns the compare list data as JSON.
|
|
|
|
=head3 listingIds
|
|
|
|
An array of listingIds that should be shown in the compare list datatable.
|
|
|
|
=cut
|
|
|
|
sub www_getCompareListData {
|
|
|
|
my $self = shift;
|
|
my $listingIds = shift;
|
|
my $session = $self->session;
|
|
my $i18n = WebGUI::International->new($session,'Asset_Matrix');
|
|
my (@results,@columnDefs,@listingIds);
|
|
|
|
if ($listingIds) {
|
|
@listingIds = @{$listingIds};
|
|
}
|
|
else{
|
|
@listingIds = $self->session->form->checkList("listingId");
|
|
}
|
|
my @responseFields = ("attributeId", "name", "description","fieldType", "checked");
|
|
|
|
foreach my $listingId (@listingIds){
|
|
my $listing = WebGUI::Asset::MatrixListing->new($session,$listingId);
|
|
$listing->incrementCounter("compares");
|
|
my $listingId_safe = $listingId;
|
|
$listingId_safe =~ s/-/_____/g;
|
|
push(@columnDefs,{
|
|
key =>$listingId_safe,
|
|
label =>$listing->get('title').' '.$listing->get('version'),
|
|
formatter =>"formatColors",
|
|
url =>$listing->getUrl,
|
|
lastUpdated =>$session->datetime->epochToHuman( $listing->get('lastUpdated'),"%z" ),
|
|
});
|
|
push(@responseFields, $listingId_safe, $listingId_safe."_compareColor");
|
|
}
|
|
push(@results,{name=>$i18n->get('last updated label'),fieldType=>'lastUpdated'});
|
|
|
|
my $jsonOutput;
|
|
$jsonOutput->{ColumnDefs} = \@columnDefs;
|
|
$jsonOutput->{ResponseFields} = \@responseFields;
|
|
|
|
foreach my $category (keys %{$self->getCategories}) {
|
|
push(@results,{name=>$category,fieldType=>'category'});
|
|
my $fields = " a.name, a.fieldType, a.attributeId, a.description ";
|
|
my $from = "from Matrix_attribute a";
|
|
my $tableCount = "b";
|
|
my $where;
|
|
foreach my $listingId (@listingIds) {
|
|
my $listingId_safe = $listingId;
|
|
$listingId_safe =~ s/-/_____/g;
|
|
$fields .= ", ".$tableCount.".value as `$listingId_safe`";
|
|
$from .= " left join MatrixListing_attribute ".$tableCount." on a.attributeId=".$tableCount.".attributeId";
|
|
$where .= "and ".$tableCount.".matrixListingId=?";
|
|
$tableCount++;
|
|
}
|
|
push(@results, @{ $self->session->db->buildArrayRefOfHashRefs(
|
|
"select $fields $from where a.category=? and a.assetId=? ".$where." order by a.name",
|
|
[$category,$self->getId,@listingIds]
|
|
) });
|
|
}
|
|
|
|
foreach my $result (@results){
|
|
if($result->{fieldType} eq 'category'){
|
|
# Row starting with a category label shows the listing name in each column
|
|
foreach my $columnDef (@columnDefs) {
|
|
$result->{$columnDef->{key}} = $columnDef->{label};
|
|
}
|
|
}
|
|
elsif($result->{fieldType} eq 'lastUpdated'){
|
|
foreach my $columnDef (@columnDefs) {
|
|
$result->{$columnDef->{key}} = $columnDef->{lastUpdated};
|
|
}
|
|
}
|
|
else{
|
|
foreach my $listingId (@listingIds) {
|
|
$result->{attributeId} =~ s/-/_____/g;
|
|
my $listingId_safe = $listingId;
|
|
$listingId_safe =~ s/-/_____/g;
|
|
if ($result->{fieldType} eq 'MatrixCompare'){
|
|
my $originalValue = $result->{$listingId_safe};
|
|
$result->{$listingId_safe.'_compareColor'} = $self->getCompareColor($result->{$listingId_safe});
|
|
$result->{$listingId_safe} = WebGUI::Form::MatrixCompare->new( $self->session,
|
|
{ value=>$result->{$listingId_safe} },defaultValue=>0)->getValueAsHtml;
|
|
}
|
|
if($session->scratch->get('stickied_'.$result->{attributeId})){
|
|
# $self->session->errorHandler->warn("found checked stickie: ".$result->{attributeId});
|
|
$result->{checked} = 'checked';
|
|
}
|
|
else{
|
|
$result->{checked} = '';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$jsonOutput->{ResultSet} = {Result=>\@results};
|
|
$session->http->setMimeType("application/json");
|
|
|
|
return JSON->new->encode($jsonOutput);
|
|
}
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_listAttributes ( )
|
|
|
|
Lists all attributes of this Matrix.
|
|
|
|
=cut
|
|
|
|
sub www_listAttributes {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
|
|
return $session->privilege->insufficient() unless($self->canEdit);
|
|
|
|
my $i18n = WebGUI::International->new($session,'Asset_Matrix');
|
|
my $console = $self->getAdminConsole();
|
|
my $attributes = $session->db->read("select attributeId, name from Matrix_attribute where assetId=? order by name"
|
|
,[$self->getId]);
|
|
my $output = '';
|
|
while (my $attribute = $attributes->hashRef) {
|
|
$output .= $session->icon->delete(
|
|
"func=deleteAttribute;attributeId=".$attribute->{attributeId},
|
|
$self->getUrl,$i18n->get("delete attribute confirm message")
|
|
)
|
|
. $session->icon->edit("func=editAttribute;attributeId=".$attribute->{attributeId})
|
|
. ' '
|
|
. $attribute->{name}
|
|
."<br />\n";
|
|
}
|
|
$console->addSubmenuItem($self->getUrl("func=editAttribute;attributeId=new"), $i18n->get('add attribute label'));
|
|
$console->addSubmenuItem($self->getUrl, $i18n->get('Return to Matrix'));
|
|
return $console->render($output, $i18n->get('list attributes title'));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_search ( )
|
|
|
|
Returns the search screen. Uses www_getCompareFormData with search=1 for doing AJAX requests.
|
|
|
|
=cut
|
|
|
|
sub www_search {
|
|
|
|
my $self = shift;
|
|
my $var = $self->get;
|
|
my $session = $self->session;
|
|
my $db = $session->db;
|
|
my $url = $session->url;
|
|
my $style = $session->style;
|
|
|
|
$var->{compareForm} = $self->getCompareForm;
|
|
$style->setScript($url->extras('yui/build/utilities/utilities.js'),
|
|
{type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/json/json-min.js'),
|
|
{type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/datasource/datasource-min.js'),
|
|
{type => 'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/datatable/datatable-min.js'),
|
|
{type =>'text/javascript'});
|
|
$style->setScript($url->extras('yui/build/button/button-min.js'),
|
|
{type =>'text/javascript'});
|
|
$style->setLink($url->extras('yui/build/datatable/assets/skins/sam/datatable.css'),
|
|
{type =>'text/css', rel=>'stylesheet'});
|
|
|
|
foreach my $category (keys %{$self->getCategories}) {
|
|
my $attributes;
|
|
my @attribute_loop;
|
|
my $categoryLoopName = $url->urlize($category)."_loop";
|
|
$attributes = $db->read("select * from Matrix_attribute where category =? and assetId = ?",
|
|
[$category,$self->getId]);
|
|
while (my $attribute = $attributes->hashRef) {
|
|
$attribute->{label} = $attribute->{name};
|
|
$attribute->{id} = $attribute->{attributeId};
|
|
$attribute->{id} =~ s/-/_____/g;
|
|
$attribute->{extras} = " class='attributeSelect'";
|
|
if($attribute->{fieldType} eq 'Combo'){
|
|
$attribute->{fieldType} = 'SelectBox';
|
|
my %options;
|
|
tie %options, 'Tie::IxHash';
|
|
%options = $db->buildHash('select value, value from MatrixListing_attribute
|
|
where attributeId = ? order by value',[$attribute->{attributeId}]);
|
|
$options{'blank'} = 'blank';
|
|
$attribute->{options} = \%options;
|
|
$attribute->{value} = 'blank';
|
|
$attribute->{extras} .= " style='width:120px'";
|
|
}
|
|
$attribute->{form} = WebGUI::Form::DynamicField->new($self->session,%{$attribute})->toHtml;
|
|
push(@attribute_loop,$attribute);
|
|
}
|
|
$var->{$categoryLoopName} = \@attribute_loop;
|
|
push(@{$var->{category_loop}},{
|
|
categoryLabel => $category,
|
|
attribute_loop => \@attribute_loop,
|
|
});
|
|
}
|
|
|
|
return $self->processStyle($self->processTemplate($var,$self->get("searchTemplateId")));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_setSort ( )
|
|
|
|
Sets the sort scratch variable.
|
|
|
|
=cut
|
|
|
|
sub www_setSort {
|
|
|
|
my $self = shift;
|
|
|
|
if(my $sort = $self->session->form->process("sort")){
|
|
$self->session->scratch->set('matrixSort',$sort);
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_setStickied ( )
|
|
|
|
Sets the stickied scratch variable.
|
|
|
|
=cut
|
|
|
|
sub www_setStickied {
|
|
|
|
my $self = shift;
|
|
|
|
if(my $attributeId = $self->session->form->process("attributeId")){
|
|
$self->session->scratch->set('stickied_'.$attributeId,1);
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
1;
|