merged from HEAD

This commit is contained in:
David Delikat 2009-03-25 14:45:27 +00:00
commit daf279f8d2
39 changed files with 1332 additions and 139 deletions

View file

@ -245,7 +245,6 @@ sub getEditFormUploadControl {
return $html;
}
#-------------------------------------------------------------------
sub getFileUrl {
my $self = shift;
@ -559,10 +558,11 @@ sub www_edit {
#-------------------------------------------------------------------
sub www_view {
my $self = shift;
return $self->session->privilege->noAccess() unless $self->canView;
# Check to make sure it's not in the trash or some other weird place
if ($self->get("state") ne "published") {
my $i18n = WebGUI::International->new($self->session,'Asset_File');

View file

@ -112,6 +112,10 @@ sub definition {
fieldType => 'textarea',
defaultValue => 'style="border-style:none;"',
},
annotations => {
fieldType => 'textarea',
defaultValue => '',
},
},
};
return $class->SUPER::definition($session,$definition);
@ -236,17 +240,32 @@ sub view {
return $out if $out;
}
my %var = %{$self->get};
my ($crop_js, $domMe) = $self->annotate_js({ just_image => 1 });
if ($crop_js) {
my ($style, $url) = $self->session->quick(qw(style url));
$style->setLink($url->extras('yui/build/fonts/fonts-min.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/container/assets/container.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setScript($url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/container/container-min.js'), {type=>'text/javascript'});
}
$var{controls} = $self->getToolbar;
$var{fileUrl} = $self->getFileUrl;
$var{fileIcon} = $self->getFileIconUrl;
$var{thumbnail} = $self->getThumbnailUrl;
my $out = $self->processTemplate(\%var,undef,$self->{_viewTemplate});
$var{annotateJs} = "$crop_js$domMe";
$var{parameters} = sprintf("id=%s", $self->getId());
my $form = $self->session->form;
my $out = $self->processTemplate(\%var,undef,$self->{_viewTemplate});
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) {
WebGUI::Cache->new($self->session,"view_".$self->getId)->set($out,$self->get("cacheTimeout"));
}
return $out;
}
#----------------------------------------------------------------------------
=head2 setFile ( filename )
@ -268,6 +287,10 @@ sub www_edit {
return $self->session->privilege->locked() unless $self->canEditIfLocked;
my $i18n = WebGUI::International->new($self->session, 'Asset_Image');
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=resize'),$i18n->get("resize image")) if ($self->get("filename"));
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=rotate'),$i18n->get("rotate image")) if ($self->get("filename"));
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=crop'),$i18n->get("crop image")) if ($self->get("filename"));
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=annotate'),$i18n->get("annotate image")) if ($self->get("filename"));
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=undo'),$i18n->get("undo image")) if ($self->get("filename"));
my $tabform = $self->getEditForm;
$tabform->getTab("display")->template(
-value=>$self->get("templateId"),
@ -278,6 +301,283 @@ sub www_edit {
return $self->getAdminConsole->render($tabform->print,$i18n->get("edit image"));
}
#-------------------------------------------------------------------
sub www_undo {
my $self = shift;
my $previous = (@{$self->getRevisions()})[1];
# instantiate assetId
if ($previous) {
# my $session = $self->session;
# my $cache = WebGUI::Cache->new($self->session, ["asset",$self->getId,$self->getRevisionDate]);
# $cache->flush;
# my $cache = WebGUI::Cache->new($previous->session, ["asset",$previous->getId,$previous->getRevisionDate]);
# $cache->flush;
$self = $self->purgeRevision();
# $self = undef;
# $self = WebGUI::Asset->new($previous->session, $previous->getId, ref $previous, $previous->getRevisionDate);
$self = $previous;
$self->generateThumbnail;
}
return $self->www_edit();
}
#-------------------------------------------------------------------
#
# All of the images will have to change to support annotate.
# The revision system doesn't support the blobs, it seems.
# All of the image operations will have to be updated to support annotations.
#
sub www_annotate {
my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit;
return $self->session->privilege->locked() unless $self->canEditIfLocked;
if (1) {
my $newSelf = $self->addRevision();
delete $newSelf->{_storageLocation};
$newSelf->getStorageLocation->annotate($newSelf->get("filename"),$newSelf,$newSelf->session->form);
$newSelf->setSize($newSelf->getStorageLocation->getFileSize($newSelf->get("filename")));
$self = $newSelf;
$self->generateThumbnail;
}
my ($style, $url) = $self->session->quick(qw(style url));
# $style->setLink($url->extras('annotate/imageMap.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/resize/assets/skins/sam/resize.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/fonts/fonts-min.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/imagecropper/assets/skins/sam/imagecropper.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setScript($url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/element/element-beta-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/dragdrop/dragdrop-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/resize/resize-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/imagecropper/imagecropper-beta-min.js'), {type=>'text/javascript'});
# my $imageAsset = $self->session->db->getRow("ImageAsset","assetId",$self->getId);
my @pieces = split(/\n/, $self->get('annotations'));
# my ($top_left, $width_height, $note) = split(/\n/, $imageAsset->{annotations});
my ($img_null, $tooltip_block, $tooltip_none) = ('', '', '');
for (my $i = 0; $i < $#pieces; $i += 3) {
$img_null .= "YAHOO.img.container.tt$i = null;\n";
$tooltip_block .= "YAHOO.util.Dom.setStyle('tooltip$i', 'display', 'block');\n";
$tooltip_none .= "YAHOO.util.Dom.setStyle('tooltip$i', 'display', 'none');\n";
my $j = $i + 2;
# warn("i: $i: ", $self->session->form->process("delAnnotate$i"));
}
my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" id="yui_img" /></div>';
my ($width, $height) = $self->getStorageLocation->getSize($self->get("filename"));
my @checkboxes = ();
my $i18n = WebGUI::International->new($self->session,"Asset_Image");
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image"));
$f->hidden(
-name=>"func",
-value=>"annotate"
);
$f->text(
-label=>$i18n->get('annotate image'),
-value=>'',
-hoverHelp=>$i18n->get('annotate image description'),
-name=>'annotate_text'
);
$f->integer(
-label=>$i18n->get('top'),
-name=>"annotate_top",
-value=>,
);
$f->integer(
-label=>$i18n->get('left'),
-name=>"annotate_left",
-value=>,
);
$f->integer(
-label=>$i18n->get('width'),
-name=>"annotate_width",
-value=>,
);
$f->integer(
-label=>$i18n->get('height'),
-name=>"annotate_height",
-value=>,
);
$f->button(
-value=>$i18n->get('annotate'),
-extras=>'onclick="switchState();"',
);
$f->submit;
my ($crop_js, $domMe) = $self->annotate_js();
return $self->getAdminConsole->render($f->print."$image$crop_js$domMe",$i18n->get("annotate image"));
}
#-------------------------------------------------------------------
sub annotate_js {
my $self = shift;
my $opts = shift;
my @pieces = split(/\n/, $self->get('annotations'));
# warn("pieces: $#pieces: ". $self->getId());
return "" if !@pieces && $opts->{just_image};
my ($img_null, $tooltip_block, $tooltip_none) = ('', '', '');
for (my $i = 0; $i < $#pieces; $i += 3) {
$img_null .= "YAHOO.img.container.tt$i = null;\n";
$tooltip_block .= "YAHOO.util.Dom.setStyle('tooltip$i', 'display', 'block');\n";
$tooltip_none .= "YAHOO.util.Dom.setStyle('tooltip$i', 'display', 'none');\n";
my $j = $i + 2;
# warn("i: $i: ", $self->session->form->process("delAnnotate$i"));
}
my $id = $$opts{just_image} ? $self->getId : "yui_img";
my $crop_js = qq(
<script type="text/javascript">
var crop;
function switchState() {
$img_null
if (crop) {
crop.destroy();
crop = null;
$tooltip_block
}
else {
crop = new YAHOO.widget.ImageCropper('$id', {
initialXY: [20, 20],
keyTick: 5,
shiftKeyTick: 50
});
crop.on('moveEvent', function() {
var region = crop.getCropCoords();
element = document.getElementById('annotate_width_formId');
element.value = region.width;
element = document.getElementById('annotate_height_formId');
element.value = region.height;
element = document.getElementById('annotate_top_formId');
element.value = region.top;
element = document.getElementById('annotate_left_formId');
element.value = region.left;
});
$tooltip_none
}
}
</script>
);
my $hotspots = '';
my $domMe = '';
for (my $i = 0; $i < $#pieces; $i += 3) {
my $top_left = $pieces[$i];
my $width_height = $pieces[$i + 1];
my $note = $pieces[$i + 2];
if ($top_left =~ /top: (\d+)px; left: (\d+)px;/) {
$top_left = "xy[0]+$1, xy[1]+$2";
}
my ($width, $height) = ("", "");
if ($width_height =~ /width: (\d+)px; height: (\d+)px;/) {
($width, $height) = ("$1px", "$2px");
}
# next if 3 == $i;
warn('next');
$domMe .= qq(
<style type="text/css">
div#tooltip$i { position: absolute; border:1px solid; }
</style>
<span id=span_tooltip$i>
</span>
<script type="text/javascript">
function on_load_$i() {
var xy = YAHOO.util.Dom.getXY('$id');
document.getElementById('span_tooltip$i').innerHTML = "<div id=tooltip$i style='border:1px solid;'></div>";
YAHOO.util.Dom.setStyle('tooltip$i', 'display', 'block');
YAHOO.util.Dom.setStyle('tooltip$i', 'height', '$height');
YAHOO.util.Dom.setStyle('tooltip$i', 'width', '$width');
YAHOO.util.Dom.setXY('span_tooltip$i', [$top_left]);
YAHOO.util.Dom.setXY('tooltip$i', [$top_left]);
YAHOO.namespace("img.container");
YAHOO.img.container.tt$i = new YAHOO.widget.Tooltip("tt$i", { showdelay: 0, visible: true, context:"tooltip$i", position:"relative", container:"tooltip$i", text:"$note" });
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", on_load_$i, false);
}
else if (window.attachEvent){
window.attachEvent('onload', on_load_$i);
}
</script>
);
}
return($crop_js, $domMe);
}
#-------------------------------------------------------------------
sub www_rotate {
my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit;
return $self->session->privilege->locked() unless $self->canEditIfLocked;
# warn(sprintf("Rotate_formId: %s", $self->session->form->process("Rotate")));
if (defined $self->session->form->process("Rotate")) {
my $newSelf = $self->addRevision();
delete $newSelf->{_storageLocation};
$newSelf->getStorageLocation->rotate($newSelf->get("filename"),$newSelf->session->form->process("Rotate"));
$newSelf->setSize($newSelf->getStorageLocation->getFileSize($newSelf->get("filename")));
$self = $newSelf;
$self->generateThumbnail;
}
my ($x, $y) = $self->getStorageLocation->getSizeInPixels($self->get("filename"));
##YUI specific datatable CSS
my ($style, $url) = $self->session->quick(qw(style url));
my $img_name = $self->getStorageLocation->getUrl($self->get("filename"));
my $img_file = $self->get("filename");
my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" id="yui_img" /></div>';
my $i18n = WebGUI::International->new($self->session,"Asset_Image");
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image"));
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
$f->hidden(
-name=>"func",
-value=>"rotate"
);
$f->button(
-value=>"Left",
-extras=>qq(onclick="var deg = document.getElementById('Rotate_formId').value; deg = parseInt(deg) + 90; document.getElementById('Rotate_formId').value = deg;"),
);
$f->button(
-value=>"Right",
-extras=>qq(onclick="var deg = document.getElementById('Rotate_formId').value; deg = parseInt(deg) - 90; document.getElementById('Rotate_formId').value = deg;"),
);
$f->integer(
-label=>$i18n->get('degree'),
-name=>"Rotate",
-value=>0,
);
$f->submit;
return $self->getAdminConsole->render($f->print.$image,$i18n->get("rotate image"));
}
#-------------------------------------------------------------------
sub www_resize {
my $self = shift;
@ -289,7 +589,59 @@ sub www_resize {
$newSelf->getStorageLocation->resize($newSelf->get("filename"),$newSelf->session->form->process("newWidth"),$newSelf->session->form->process("newHeight"));
$newSelf->setSize($newSelf->getStorageLocation->getFileSize($newSelf->get("filename")));
$self = $newSelf;
$self->generateThumbnail;
}
my ($x, $y) = $self->getStorageLocation->getSizeInPixels($self->get("filename"));
##YUI specific datatable CSS
my ($style, $url) = $self->session->quick(qw(style url));
$style->setLink($url->extras('yui/build/fonts/fonts-min.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/resize/assets/skins/sam/resize.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setScript($url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/element/element-beta-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/dragdrop/dragdrop-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/resize/resize-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/animation/animation-min.js'), {type=>'text/javascript'});
my $resize_js = qq(
<script>
(function() {
var Dom = YAHOO.util.Dom,
Event = YAHOO.util.Event;
var resize = new YAHOO.util.Resize('yui_img', {
handles: 'all',
knobHandles: true,
height: '${x}px',
width: '${y}px',
proxy: true,
ghost: true,
status: true,
draggable: false,
ratio: true,
animate: true,
animateDuration: .75,
animateEasing: YAHOO.util.Easing.backBoth
});
resize.on('startResize', function() {
this.getProxyEl().innerHTML = '<img src="' + this.get('element').src + '" style="height: 100%; width: 100%;">';
Dom.setStyle(this.getProxyEl().firstChild, 'opacity', '.25');
}, resize, true);
resize.on('resize', function(e) {
element = document.getElementById('newWidth_formId');
element.value = e.width;
element = document.getElementById('newHeight_formId');
element.value = e.height;
}, resize, true);
})();
</script>
);
my $i18n = WebGUI::International->new($self->session,"Asset_Image");
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image"));
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
@ -297,7 +649,6 @@ sub www_resize {
-name=>"func",
-value=>"resize"
);
my ($x, $y) = $self->getStorageLocation->getSizeInPixels($self->get("filename"));
$f->readOnly(
-label=>$i18n->get('image size'),
-hoverHelp=>$i18n->get('image size description'),
@ -316,15 +667,121 @@ sub www_resize {
-value=>$y,
);
$f->submit;
my $image = '<div align="center"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" /></div>';
my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" id="yui_img" /></div>'.$resize_js;
return $self->getAdminConsole->render($f->print.$image,$i18n->get("resize image"));
}
#-------------------------------------------------------------------
sub www_crop {
my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit;
return $self->session->privilege->locked() unless $self->canEditIfLocked;
if ($self->session->form->process("Width") || $self->session->form->process("Height")
|| $self->session->form->process("Top") || $self->session->form->process("Left")) {
my $newSelf = $self->addRevision();
delete $newSelf->{_storageLocation};
$newSelf->getStorageLocation->crop(
$newSelf->get("filename"),
$newSelf->session->form->process("Width"),
$newSelf->session->form->process("Height"),
$newSelf->session->form->process("Top"),
$newSelf->session->form->process("Left")
);
$self = $newSelf;
$self->generateThumbnail;
}
my $filename = $self->get("filename");
##YUI specific datatable CSS
my ($style, $url) = $self->session->quick(qw(style url));
my $crop_js = qq(
<script>
(function() {
var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, results = null;
Event.onDOMReady(function() {
var crop = new YAHOO.widget.ImageCropper('yui_img', {
initialXY: [20, 20],
keyTick: 5,
shiftKeyTick: 50
});
crop.on('moveEvent', function() {
var region = crop.getCropCoords();
element = document.getElementById('Width_formId');
element.value = region.width;
element = document.getElementById('Height_formId');
element.value = region.height;
element = document.getElementById('Top_formId');
element.value = region.top;
element = document.getElementById('Left_formId');
element.value = region.left;
});
});
})();
</script>
);
$style->setLink($url->extras('yui/build/resize/assets/skins/sam/resize.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/fonts/fonts-min.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/imagecropper/assets/skins/sam/imagecropper.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setScript($url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/element/element-beta-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/dragdrop/dragdrop-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/resize/resize-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/imagecropper/imagecropper-beta-min.js'), {type=>'text/javascript'});
my $i18n = WebGUI::International->new($self->session,"Asset_Image");
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image"));
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
$f->hidden(
-name=>"degree",
-value=>"0"
);
$f->hidden(
-name=>"func",
-value=>"crop"
);
my ($x, $y) = $self->getStorageLocation->getSizeInPixels($filename);
$f->integer(
-label=>$i18n->get('width'),
-hoverHelp=>$i18n->get('new width description'),
-name=>"Width",
-value=>$x,
);
$f->integer(
-label=>$i18n->get('height'),
-hoverHelp=>$i18n->get('new height description'),
-name=>"Height",
-value=>$y,
);
$f->integer(
-label=>$i18n->get('top'),
-hoverHelp=>$i18n->get('new width description'),
-name=>"Top",
-value=>$x,
);
$f->integer(
-label=>$i18n->get('left'),
-hoverHelp=>$i18n->get('new height description'),
-name=>"Left",
-value=>$y,
);
$f->submit;
my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($filename).'" style="border-style:none;" alt="'.$filename.'" id="yui_img" /></div>'.$crop_js;
return $self->getAdminConsole->render($f->print.$image,$i18n->get("crop image"));
}
#-------------------------------------------------------------------
# Use superclass method for now.
sub www_view {
my $self = shift;
$self->SUPER::www_view;
return($self->SUPER::www_view);
}
#sub www_view {

View file

@ -1424,8 +1424,6 @@ sub www_edit {
richEditId=>$self->getThread->getParent->get("richEditor")
});
##Edit variables just for Threads
$session->log->warn("className: $className");
$session->log->warn("canEdit parent: ". $self->getThread->getParent->canEdit);
if ($className eq 'WebGUI::Asset::Post::Thread' && $self->getThread->getParent->canEdit) {
$var{'sticky.form'} = WebGUI::Form::yesNo($session, {
name=>'isSticky',

View file

@ -35,11 +35,11 @@ using the RSSFromParent asset.
=cut
sub definition {
my $class = shift;
my $session = shift;
my $definition = shift;
my %properties;
tie %properties, 'Tie::IxHash';
my $class = shift;
my $session = shift;
my $definition = shift;
my %properties;
tie %properties, 'Tie::IxHash';
my $i18n = WebGUI::International->new($session, 'Asset_RSSCapable');
# We do this prefixing to avoid name collisions because properties aren't namespaced.
@ -58,6 +58,13 @@ sub definition {
label => $i18n->get('rssTemplateId label'),
hoverHelp => $i18n->get('rssTemplateId hoverHelp')
},
rssCapableRssLimit => { tab => 'display',
fieldType => 'integer',
defaultValue => 10,
namespace => 'RSSCapable/RSS',
label => $i18n->get('rssLimit label'),
hoverHelp => $i18n->get('rssLimit hoverHelp')
},
rssCapableRssFromParentId => { fieldType => 'hidden',
noFormPost => 1,
defaultValue => undef,
@ -65,12 +72,12 @@ sub definition {
);
push @$definition, { assetName => $i18n->get('assetName'),
tableName => 'RSSCapable',
autoGenerateForms => 1,
className => 'WebGUI::Asset::RSSCapable',
icon => 'rssCapable.gif',
properties => \%properties
};
tableName => 'RSSCapable',
autoGenerateForms => 1,
className => 'WebGUI::Asset::RSSCapable',
icon => 'rssCapable.gif',
properties => \%properties
};
return $class->NEXT::definition($session, $definition);
}

View file

@ -131,7 +131,7 @@ sub www_view {
my $self = shift;
return '' unless $self->session->asset->getId eq $self->getId;
return '' unless $self->getParent->isa('WebGUI::Asset::RSSCapable');
return '' unless $self->getParent->canView; # Go to parent for auth
return '' unless $self->getParent->canView; # Go to parent for auth
my $parent = $self->getParent;
my $template = WebGUI::Asset::Template->new($self->session, $parent->get('rssCapableRssTemplateId'));
$template->prepare($self->getMetaDataAsTemplateVariables);

View file

@ -861,6 +861,7 @@ SQL
my $datetime = $self->session->datetime;
my @posts;
my $rssLimit = $self->get('rssCapableRssLimit') || 10;
for my $postId (@postIds) {
my $post = WebGUI::Asset->new($self->session, $postId, 'WebGUI::Asset::Post::Thread');
my $postUrl = $siteUrl . $post->getUrl;
@ -896,6 +897,8 @@ SQL
userDefined4 => $post->get("userDefined4"),
userDefined5 => $post->get("userDefined5"),
};
last if $rssLimit <= scalar(@posts);
}
return @posts;

View file

@ -238,6 +238,14 @@ sub definition {
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")
},
);
push(@{$definition}, {
assetName=>$i18n->get('assetName'),
@ -520,6 +528,7 @@ sub view {
$self->session->style->setScript($self->session->url->extras('wobject/Matrix/matrix.js'), {type =>
'text/javascript'});
my ($varStatistics,$varStatisticsEncoded);
my $var = $self->get;
$var->{isLoggedIn} = ($self->session->user->userId ne "1");
$var->{addMatrixListing_url} = $self->getUrl('func=add;class=WebGUI::Asset::MatrixListing');
@ -527,90 +536,104 @@ sub view {
$var->{exportAttributes_url} = $self->getUrl('func=exportAttributes');
$var->{listAttributes_url} = $self->getUrl('func=listAttributes');
$var->{search_url} = $self->getUrl('func=search');
# Get the MatrixListing with the most views as an object using getLineage.
my ($bestViews_listing) = @{ $self->getLineage(['descendants'], {
if ($self->canEdit){
# Get all the MatrixListings that are still pending.
my @pendingListings = @{ $self->getLineage(['descendants'], {
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
orderByClause => "revisionDate asc",
returnObjects => 1,
statusToInclude => ['pending'],
}) };
foreach my $pendingListing (@pendingListings){
push (@{ $var->{pending_loop} }, {
url => $pendingListing->getUrl
."?func=view;revision=".$pendingListing->get('revisionDate'),
name => $pendingListing->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{
# 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){
$var->{bestViews_url} = $bestViews_listing->getUrl;
$var->{bestViews_count} = $bestViews_listing->get('views');
$var->{bestViews_name} = $bestViews_listing->get('title');
$var->{bestViews_sortButton} = "<span id='sortByViews'><button type='button'>Sort by views</button></span><br />";
}
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'>Sort by views</button></span><br />";
}
# Get the MatrixListing with the most compares as an object using getLineage.
# Get the MatrixListing with the most compares as an object using getLineage.
my ($bestCompares_listing) = @{ $self->getLineage(['descendants'], {
my ($bestCompares_listing) = @{ $self->getLineage(['descendants'], {
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
joinClass => "WebGUI::Asset::MatrixListing",
orderByClause => "compares desc",
limit => 1,
returnObjects => 1,
}) };
if($bestCompares_listing){
$var->{bestCompares_url} = $bestCompares_listing->getUrl;
$var->{bestCompares_count} = $bestCompares_listing->get('compares');
$var->{bestCompares_name} = $bestCompares_listing->get('title');
$var->{bestCompares_sortButton} = "<span id='sortByCompares'><button type='button'>Sort by compares</button></span><br />";
}
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'>Sort by compares</button></span><br />";
}
# Get the MatrixListing with the most clicks as an object using getLineage.
my ($bestClicks_listing) = @{ $self->getLineage(['descendants'], {
# 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){
$var->{bestClicks_url} = $bestClicks_listing->getUrl;
$var->{bestClicks_count} = $bestClicks_listing->get('clicks');
$var->{bestClicks_name} = $bestClicks_listing->get('title');
$var->{bestClicks_sortButton} = "<span id='sortByClicks'><button type='button'>Sort by clicks</button></span><br />";
}
# Get the 5 MatrixListings that were last updated as objects using getLineage.
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'>Sort by clicks</button></span><br />";
}
my @lastUpdatedListings = @{ $self->getLineage(['descendants'], {
# Get the 5 MatrixListings that were last updated as objects using getLineage.
my @lastUpdatedListings = @{ $self->getLineage(['descendants'], {
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
joinClass => "WebGUI::Asset::MatrixListing",
orderByClause => "lastUpdated desc",
limit => 5,
returnObjects => 1,
}) };
foreach my $lastUpdatedListing (@lastUpdatedListings){
push (@{ $var->{last_updated_loop} }, {
foreach my $lastUpdatedListing (@lastUpdatedListings){
push (@{ $varStatistics->{last_updated_loop} }, {
url => $lastUpdatedListing->getUrl,
name => $lastUpdatedListing->get('title'),
lastUpdated => $self->session->datetime->epochToHuman($lastUpdatedListing->get('lastUpdated'),"%z")
});
}
$var->{lastUpdated_sortButton} = "<span id='sortByUpdated'><button type='button'>Sort by updated</button></span><br />";
}
$var->{lastUpdated_sortButton} = "<span id='sortByUpdated'><button type='button'>Sort by updated</button></span><br />";
# For each category, get the MatrixListings with the best ratings.
# Get all the MatrixListings that are still pending.
my @pendingListings = @{ $self->getLineage(['descendants'], {
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
orderByClause => "revisionDate asc",
returnObjects => 1,
statusToInclude => ['pending'],
}) };
foreach my $pendingListing (@pendingListings){
push (@{ $var->{pending_loop} }, {
url => $pendingListing->getUrl
."?func=view;revision=".$pendingListing->get('revisionDate'),
name => $pendingListing->get('title'),
});
}
# For each category, get the MatrixListings with the best ratings.
foreach my $category (keys %{$self->getCategories}) {
foreach my $category (keys %{$self->getCategories}) {
my $data;
my $sql = "
select
@ -641,7 +664,7 @@ sub view {
order by rating.meanValue ";
$data = $db->quickHashRef($sql." desc limit 1",[$category,$self->getId]);
push(@{ $var->{best_rating_loop} },{
push(@{ $varStatistics->{best_rating_loop} },{
url=>'/'.$data->{url},
category=>$category,
name=>$data->{productName},
@ -650,7 +673,7 @@ sub view {
count=>$data->{countValue}
});
$data = $db->quickHashRef($sql." asc limit 1",[$category,$self->getId]);
push(@{ $var->{worst_rating_loop} },{
push(@{ $varStatistics->{worst_rating_loop} },{
url=>'/'.$data->{url},
category=>$category,
name=>$data->{productName},
@ -658,9 +681,9 @@ sub view {
median=>$data->{medianValue},
count=>$data->{countValue}
});
}
}
$var->{listingCount} = scalar $db->buildArray("
$varStatistics->{listingCount} = scalar $db->buildArray("
select *
from asset, assetData
where asset.assetId=assetData.assetId
@ -670,7 +693,17 @@ sub view {
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});
}
@ -977,14 +1010,31 @@ sub www_getCompareFormData {
my $form = $session->form;
my $sort = shift || $session->scratch->get('matrixSort') || $self->get('defaultSort');
my $sortDirection = ' desc';
# if ( WebGUI::Utility::isIn($sort, qw(revisionDate score)) ) {
# $sortDirection = " desc";
# }
my @results;
my @listingIds = $self->session->form->checkList("listingId");
$self->session->http->setMimeType("application/json");
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_//;
$attributeId =~ s/_____/-/g;
$parameter->{attributeId} = $attributeId;
push(@searchParamList,'"'.$parameter->{attributeId}.'"');
push(@searchParams,$parameter);
}
}
$searchParamList = join(',',@searchParamList);
@searchParams_sorted = sort { $b->{value} <=> $a->{value} } @searchParams;
}
my $sql = "
select
assetData.title,
@ -1005,31 +1055,18 @@ assetData.revisionDate
and assetData.revisionDate = (SELECT max(revisionDate) from assetData where assetId=asset.assetId and status='approved')
and status='approved'
order by ".$sort.$sortDirection;
my $sth = $self->session->db->read($sql,[$self->getId]);
my @results;
@results = @{ $session->db->buildArrayRefOfHashRefs($sql,[$self->getId]) };
my (@searchParams,@searchParams_sorted);
my $gateway = $self->session->config->get("gateway");
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_//;
$attributeId =~ s/_____/-/g;
$parameter->{attributeId} = $attributeId;
push(@searchParams,$parameter);
}
}
}
@searchParams_sorted = sort { $b->{value} <=> $a->{value} } @searchParams;
foreach my $result (@results){
if($form->process("search")){
while (my $result = $sth->hashRef) {
my $matrixListing_attributes = $session->db->buildHashRefOfHashRefs("
select value, fieldType, attributeId from Matrix_attribute
left join MatrixListing_attribute as listing using(attributeId)
where listing.matrixListingId = ? order by value asc",
where listing.matrixListingId = ?
and attributeId IN(".$searchParamList.")",
[$result->{assetId}],'attributeId');
PARAM: foreach my $param (@searchParams_sorted) {
my $fieldType = $matrixListing_attributes->{$param->{attributeId}}->{fieldType};
@ -1046,20 +1083,27 @@ assetData.revisionDate
$result->{checked} = 'checked';
}
}
}
else{
$result->{assetId} =~ s/-/_____/g;
if(WebGUI::Utility::isIn($result->{assetId},@listingIds)){
$result->{checked} = 'checked';
}
}
$result->{assetId} =~ s/-/_____/g;
$result->{url} = $session->url->gateway($result->{url});
$result->{url} = $gateway."/".$result->{url};
push @results, $result;
}
}else{
while (my $result = $sth->hashRef) {
$result->{assetId} =~ s/-/_____/g;
if(WebGUI::Utility::isIn($result->{assetId},@listingIds)){
$result->{checked} = 'checked';
}
$result->{url} = $gateway."/".$result->{url};
push @results, $result;
}
}
$sth->finish;
my $jsonOutput;
$jsonOutput->{ResultSet} = {Result=>\@results};
my $encodedOutput = JSON->new->encode($jsonOutput);
return $encodedOutput;
}

View file

@ -1219,8 +1219,10 @@ sub prepareShowSurveyTemplate {
my %text = ( 'Text', 1, 'Email', 1, 'Phone Number', 1, 'Text Date', 1, 'Currency', 1 );
my %slider = ( 'Slider', 1, 'Dual Slider - Range', 1, 'Multi Slider - Allocate', 1 );
my %dateType = ( 'Date', 1, 'Date Range', 1 );
my %dateShort = ( 'Year Month', 1 );
my %fileUpload = ( 'File Upload', 1 );
my %hidden = ( 'Hidden', 1 );
use Data::Dumper;
foreach my $q (@$questions) {
if ( $fileUpload{ $q->{questionType} } ) { $q->{fileLoader} = 1; }
@ -1236,6 +1238,26 @@ sub prepareShowSurveyTemplate {
elsif ( $dateType{ $q->{questionType} } ) {
$q->{dateType} = 1;
}
elsif ( $dateShort{ $q->{questionType} } ) {
$q->{dateShort} = 1;
foreach my $a(@{$q->{answers}}){
$a->{months} = [
{'month' => ''},
{'month' => 'January'},
{'month' => 'February'},
{'month' => 'March'},
{'month' => 'April'},
{'month' => 'May'},
{'month' => 'June'},
{'month' => 'July'},
{'month' => 'August'},
{'month' => 'September'},
{'month' => 'October'},
{'month' => 'November'},
{'month' => 'December'}
];
}
}
elsif ( $slider{ $q->{questionType} } ) {
$q->{slider} = 1;
if ( $q->{questionType} eq 'Dual Slider - Range' ) {

View file

@ -115,6 +115,7 @@ my @SPECIAL_QUESTION_TYPES = (
'File Upload',
'Date',
'Date Range',
'Year Month',
'Hidden',
);

View file

@ -308,6 +308,42 @@ sub duplicate {
return $newAsset;
}
#-------------------------------------------------------------------
=head2 duplicateThing ( thingId )
Duplicates a thing.
=head3 thingId
The id of the Thing that will be duplicated.
=cut
sub duplicateThing {
my $self = shift;
my $oldThingId = shift;
my $db = $self->session->db;
my $thingProperties = $self->getThing($oldThingId);
$thingProperties->{thingId} = 'new';
$thingProperties->{label} = $thingProperties->{label}.' (copy)';
my $newThingId = $self->addThing($thingProperties);
my $fields = $db->buildArrayRefOfHashRefs('select * from Thingy_fields where assetId=? and thingId=?'
,[$self->getId,$oldThingId]);
foreach my $field (@$fields) {
# set thingId to newly created thing's id.
$field->{thingId} = $newThingId;
$self->addField($field,0);
}
return $newThingId;
}
#-------------------------------------------------------------------
=head2 deleteField ( fieldId , thingId )
@ -1436,6 +1472,26 @@ sub www_deleteFieldConfirm {
return 1;
}
#-------------------------------------------------------------------
=head2 www_duplicateThing ( )
Duplicates a Thing.
=cut
sub www_duplicateThing {
my $self = shift;
my $session = $self->session;
my $thingId = $session->form->process("thingId");
return $session->privilege->insufficient() unless $self->canEdit;
$self->duplicateThing($thingId);
return $self->www_manage;
}
#-------------------------------------------------------------------
=head2 www_copyThingData( )
@ -2868,6 +2924,8 @@ sub www_manage {
"",$i18n->get('delete thing warning')),
'thing_editUrl' => $session->url->append($url, 'func=editThing;thingId='.$thing->{thingId}),
'thing_editIcon' => $session->icon->edit('func=editThing;thingId='.$thing->{thingId}),
'thing_copyUrl' => $session->url->append($url, 'func=duplicateThing;thingId='.$thing->{thingId}),
'thing_copyIcon' => $session->icon->copy('func=duplicateThing;thingId='.$thing->{thingId}),
'thing_addUrl' => $session->url->append($url,
'func=editThingData;thingId='.$thing->{thingId}.';thingDataId=new'),
'thing_searchUrl' => $session->url->append($url, 'func=search;thingId='.$thing->{thingId}),