Rough conversion of Comments and Installable to Moose.
This commit is contained in:
parent
a37b1c725b
commit
2b39e16cc8
2 changed files with 20 additions and 41 deletions
|
|
@ -1,363 +0,0 @@
|
|||
package WebGUI::AssetAspect::Comments;
|
||||
|
||||
=head1 LEGAL
|
||||
|
||||
-------------------------------------------------------------------
|
||||
WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||
-------------------------------------------------------------------
|
||||
Please read the legal notices (docs/legal.txt) and the license
|
||||
(docs/license.txt) that came with this distribution before using
|
||||
this software.
|
||||
-------------------------------------------------------------------
|
||||
http://www.plainblack.com info@plainblack.com
|
||||
-------------------------------------------------------------------
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use Class::C3;
|
||||
use JSON;
|
||||
use Tie::IxHash;
|
||||
use WebGUI::Exception;
|
||||
use WebGUI::Form;
|
||||
use WebGUI::HTML;
|
||||
use WebGUI::Utility;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::AssetAspect::Comments
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is an aspect which makes adding comments to existing assets trivial.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Class::C3;
|
||||
use base qw(WebGUI::AssetAspect::Comments WebGUI::Asset);
|
||||
|
||||
And then where-ever you would call $self->SUPER::someMethodName call $self->next::method instead.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
These methods are available from this class:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 addComment ( comment [, rating, user ] )
|
||||
|
||||
Posts a comment.
|
||||
|
||||
=head3 comment
|
||||
|
||||
A string that acts as a comment from a user.
|
||||
|
||||
=head3 rating
|
||||
|
||||
Defaults to 0. An integer between 0 and 5 inclusive. 0 represents N/A, 1 represents a negative rating, 3 represents a neutral rating, and 5 represents a positive rating.
|
||||
|
||||
=head3 user
|
||||
|
||||
Defaults to the current user. A WebGUI::User object.
|
||||
|
||||
=cut
|
||||
|
||||
sub addComment {
|
||||
my ($self, $comment, $rating, $user) = @_;
|
||||
my $session = $self->session;
|
||||
$user ||= $session->user;
|
||||
$rating ||= 0;
|
||||
|
||||
# add the new comment to the list of comments
|
||||
my $comments = $self->get('comments');
|
||||
push @$comments, {
|
||||
id => $session->id->generate,
|
||||
alias => $user->profileField('alias'),
|
||||
userId => $user->userId,
|
||||
comment => $comment,
|
||||
rating => $rating,
|
||||
date => time(),
|
||||
ip => $session->var->get('lastIP'),
|
||||
};
|
||||
|
||||
# calculate average
|
||||
my $sum = 0;
|
||||
my $count = 0;
|
||||
foreach my $comment (@$comments) {
|
||||
next unless $comment->{rating} > 0; # skip n/a ratings
|
||||
$count++;
|
||||
$sum += $comment->{rating};
|
||||
}
|
||||
my $average = 0;
|
||||
if ($count > 0) {
|
||||
$average = $sum/$count;
|
||||
}
|
||||
|
||||
# update the database
|
||||
$self->update({comments=>$comments, averageCommentRating=>$average});
|
||||
|
||||
# add karma
|
||||
if ($session->setting->get('useKarma')) {
|
||||
unless ($user->isVisitor) {
|
||||
$user->karma($self->getKarmaAmountPerComment, $self->getId, 'Left comment for '.$self->getName.' '.$self->getTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 canComment ()
|
||||
|
||||
Returns a boolean indicating whether the current user can post a comment.
|
||||
|
||||
=cut
|
||||
|
||||
sub canComment {
|
||||
my $self = shift;
|
||||
return $self->session->user->isInGroup($self->getGroupToComment) || $self->canEdit;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 definition
|
||||
|
||||
Extends the definition to add the comments and averageCommentRating fields.
|
||||
|
||||
=cut
|
||||
|
||||
sub definition {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
my $definition = shift;
|
||||
my %properties;
|
||||
tie %properties, 'Tie::IxHash';
|
||||
%properties = (
|
||||
comments => {
|
||||
noFormPost => 1,
|
||||
fieldType => "hidden",
|
||||
defaultValue => [],
|
||||
},
|
||||
averageCommentRating => {
|
||||
noFormPost => 1,
|
||||
fieldType => "hidden",
|
||||
defaultValue => 0,
|
||||
},
|
||||
);
|
||||
push(@{$definition}, {
|
||||
autoGenerateForms => 1,
|
||||
tableName => 'assetAspectComments',
|
||||
className => 'WebGUI::Asset::Sku::BazaarItem',
|
||||
properties => \%properties
|
||||
});
|
||||
return $class->next::method($session, $definition);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 deleteComment ( id )
|
||||
|
||||
Deletes a comment.
|
||||
|
||||
=head3 id
|
||||
|
||||
The GUID for the comment to delete.
|
||||
|
||||
=cut
|
||||
|
||||
sub deleteComment {
|
||||
my ($self, $id) = @_;
|
||||
my $session = $self->session;
|
||||
|
||||
# remove the comment from the list of comments and calculate the average
|
||||
my $comments = $self->get('comments');
|
||||
my @updatedComments;
|
||||
my $sum = 0;
|
||||
my $count = 0;
|
||||
my $userId;
|
||||
foreach my $comment (@$comments) {
|
||||
if ($comment->{id} eq $id) {
|
||||
$userId = $comment->{userId};
|
||||
next;
|
||||
}
|
||||
push @updatedComments, $comment;
|
||||
next unless $comment->{rating} > 0; # skip n/a ratings
|
||||
$count++;
|
||||
$sum += $comment->{rating};
|
||||
}
|
||||
|
||||
# update the database
|
||||
my $average = 0;
|
||||
if ($count > 0) {
|
||||
$average = $sum/$count;
|
||||
}
|
||||
$self->update({comments=>\@updatedComments, averageCommentRating=>$average});
|
||||
|
||||
# remove karma
|
||||
if ($session->setting->get('useKarma')) {
|
||||
if (defined $userId) {
|
||||
my $user = WebGUI::User->new($session, $userId);
|
||||
unless ($user->isVisitor) {
|
||||
$user->karma(($self->getKarmaAmountPerComment * -1), $self->getId, 'Deleted comment for '.$self->getName.' '.$self->getTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 get ()
|
||||
|
||||
See SUPER::get(). Extends the get() method to automatically decode the comments field into a Perl hash structure.
|
||||
|
||||
=cut
|
||||
|
||||
sub get {
|
||||
my $self = shift;
|
||||
my $param = shift;
|
||||
if ($param eq 'comments') {
|
||||
return JSON->new->decode($self->next::method('comments')||'[]');
|
||||
}
|
||||
return $self->next::method($param, @_);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getAverageCommentRatingIcon ()
|
||||
|
||||
Returns the HTML needed to render the average rating icon.
|
||||
|
||||
=cut
|
||||
|
||||
sub getAverageCommentRatingIcon {
|
||||
my $self = shift;
|
||||
return q{<img src="}.$self->session->url->extras('form/CommentRating/'.round($self->get('averageCommentRating'),0).'.png').q{" style="vertical-align: middle;" alt="}.$self->get('averageCommentRating').q{" />};
|
||||
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getFormattedComments ()
|
||||
|
||||
Returns an HTML string listing the comments so far and the leave a comment form if the user canComment().
|
||||
|
||||
=cut
|
||||
|
||||
sub getFormattedComments {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $url = $session->url;
|
||||
my $out = '<div class="assetAspectComments">';
|
||||
my $canEdit = $self->canEdit;
|
||||
my $comments = $self->get('comments');
|
||||
foreach my $comment (@$comments) {
|
||||
$out .= q{<div class="assetAspectComment"><img src="}.$url->extras('form/CommentRating/'.$comment->{rating}.'.png').q{" alt="}.$comment->{rating}.q{" style="vertical-align: bottom;" />};
|
||||
if ($canEdit) {
|
||||
$out .= q{ <a href="}.$self->getUrl("func=deleteComment;commentId=".$comment->{id}).q{">[X]</a> };
|
||||
}
|
||||
$out .= q{<b>}.$comment->{alias}.q{:</b> "}.WebGUI::HTML::format($comment->{comment},'text').q{"</div>};
|
||||
}
|
||||
if ($self->canComment) {
|
||||
$out .= '<div class="assetAspectCommentForm">';
|
||||
$out .= WebGUI::Form::formHeader($session, {action=>$self->getUrl});
|
||||
$out .= WebGUI::Form::hidden($session, {name=>"func",value=>"addComment"});
|
||||
$out .= WebGUI::Form::textarea($session, {name=>"comment"});
|
||||
$out .= WebGUI::Form::commentRating($session, {name=>"rating"});
|
||||
$out .= WebGUI::Form::submit($session);
|
||||
$out .= WebGUI::Form::formFooter($session);
|
||||
$out .= '</div>';
|
||||
}
|
||||
$out .= '</div>';
|
||||
return $out;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getGroupToComment ()
|
||||
|
||||
Returns '2' aka Registered Users. However, should be overridden by subclasses that wish to make this a settable property.
|
||||
|
||||
=cut
|
||||
|
||||
sub getGroupToComment {
|
||||
return '2';
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getKarmaAmountPerComment ()
|
||||
|
||||
Returns 3. However, should be overridden by subclasses that wish to make this a settable property.
|
||||
|
||||
=cut
|
||||
|
||||
sub getKarmaAmountPerComment {
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 update ()
|
||||
|
||||
See SUPER::update(). Extends the update() method to encode the comments field into something storable in the database.
|
||||
|
||||
=cut
|
||||
|
||||
sub update {
|
||||
my $self = shift;
|
||||
my $properties = shift;
|
||||
if (exists $properties->{comments}) {
|
||||
my $comments = $properties->{comments};
|
||||
if (ref $comments ne 'ARRAY') {
|
||||
$comments = eval{JSON->new->decode($comments)};
|
||||
if (WebGUI::Error->caught || ref $comments ne 'ARRAY') {
|
||||
$comments = [];
|
||||
}
|
||||
}
|
||||
$properties->{comments} = JSON->new->encode($comments);
|
||||
}
|
||||
$self->next::method($properties, @_);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_addComment ()
|
||||
|
||||
Posts a comment after verifying the user's privileges.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_addComment {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $session->privilege->insufficient() unless ($self->canComment);
|
||||
my $form = $session->form;
|
||||
my $comment = $form->get('comment','textarea');
|
||||
WebGUI::Macro::negate(\$comment);
|
||||
if ($comment ne '') {
|
||||
$self->addComment($comment, $form->get('rating','commentRating'));
|
||||
}
|
||||
$self->www_view;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_deleteComment ()
|
||||
|
||||
Removes a comment.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_deleteComment {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $session->privilege->insufficient() unless ($self->canEdit);
|
||||
$self->deleteComment($session->form->get('commentId'));
|
||||
$self->www_view;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
|
@ -1,214 +0,0 @@
|
|||
package WebGUI::AssetAspect::Installable;
|
||||
|
||||
use strict;
|
||||
use Class::C3;
|
||||
|
||||
use WebGUI::Asset;
|
||||
use WebGUI::Form::DynamicField;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
WebGUI::AssetAspect::Installable -- Make your asset installable
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
package WebGUI::Asset::MyAsset;
|
||||
use base ( 'WebGUI::AssetAspect::Installable', 'WebGUI::Asset' );
|
||||
|
||||
# Override the install method to install collateral tables
|
||||
sub install {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
$self->next::method( $session );
|
||||
}
|
||||
|
||||
# Override the uninstall method to remove collateral tables
|
||||
sub uninstall {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
$self->next::method( $session );
|
||||
}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This aspect adds installing and uninstalling to your asset class.
|
||||
|
||||
For most purposes, just inheriting from this aspect will suffice.
|
||||
|
||||
If you need to install collateral information or otherwise, override the
|
||||
C<install> method, but make sure to call the superclass before you try
|
||||
anything else.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 install ( session )
|
||||
|
||||
Install the asset. C<session> is a WebGUI::Session object from the site to
|
||||
install the asset into.
|
||||
|
||||
=cut
|
||||
|
||||
sub install {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
|
||||
### Install the first member of the definition
|
||||
my $definition = $class->definition($session);
|
||||
my $installDef = shift @{$definition};
|
||||
|
||||
# Make the table according to WebGUI::Form::Control's databaseFieldType
|
||||
my $sql
|
||||
= q{CREATE TABLE `}
|
||||
. $installDef->{tableName} . q{` ( }
|
||||
. q{`assetId` CHAR(22) BINARY NOT NULL, }
|
||||
. q{`revisionDate` BIGINT NOT NULL, };
|
||||
for my $column ( keys %{ $installDef->{properties} } ) {
|
||||
my $control = WebGUI::Form::DynamicField->new( $session, %{ $installDef->{properties}->{$column} } );
|
||||
$sql .= q{`} . $column . q{` } . $control->getDatabaseFieldType . q{, };
|
||||
|
||||
}
|
||||
$sql .= q{ PRIMARY KEY ( assetId, revisionDate ) ) };
|
||||
|
||||
$session->db->write($sql);
|
||||
|
||||
# Write to the configuration
|
||||
$session->config->addToHash( "assets", $installDef->{className}, { category => "basic" } );
|
||||
|
||||
return;
|
||||
} ## end sub install
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 isInstalled ( session )
|
||||
|
||||
Returns true if the asset is installed. By default, only checks for the
|
||||
last database table.
|
||||
|
||||
=cut
|
||||
|
||||
sub isInstalled {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
|
||||
my $tableName = $class->definition($session)->[0]->{tableName};
|
||||
my $exists = $session->db->quickScalar( "SHOW TABLES LIKE ?", [$tableName], );
|
||||
|
||||
return $exists ? 1 : 0;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 uninstall ( session )
|
||||
|
||||
Unnstall the asset. C<session> is a WebGUI::Session object from the site to
|
||||
uninstall the asset from.
|
||||
|
||||
=cut
|
||||
|
||||
sub uninstall {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
|
||||
### Uninstall the first member of the definition
|
||||
my $definition = $class->definition($session);
|
||||
my $installDef = shift @{$definition};
|
||||
|
||||
### Remove all assets contained in the table
|
||||
my $sth = $session->db->read("SELECT assetId FROM `$installDef->{tableName}`");
|
||||
while ( my ($assetId) = $sth->array ) {
|
||||
my $asset = WebGUI::Asset->newById( $session, $assetId );
|
||||
$asset->purge;
|
||||
}
|
||||
|
||||
# Drop the table
|
||||
my $sql = q{DROP TABLE `} . $installDef->{tableName} . q{`};
|
||||
|
||||
$session->db->write($sql);
|
||||
$session->config->deleteFromHash( "assets", $installDef->{className} );
|
||||
|
||||
return;
|
||||
} ## end sub uninstall
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 upgrade ( session )
|
||||
|
||||
Upgrade an existing installation of this asset. Try to reconcile the current
|
||||
table with the current definition and modify the table if necessary.
|
||||
|
||||
=cut
|
||||
|
||||
sub upgrade {
|
||||
my ( $class, $session ) = @_;
|
||||
unless ( defined $session && $session->isa('WebGUI::Session') ) {
|
||||
WebGUI::Error::InvalidObject->throw(
|
||||
expected => 'WebGUI::Session',
|
||||
got => ( ref $session ),
|
||||
error => 'Need a session.'
|
||||
);
|
||||
}
|
||||
my $db = $session->db;
|
||||
my $dbh = $db->dbh;
|
||||
my $definition = $class->definition($session);
|
||||
my $properties = $definition->[0]->{properties};
|
||||
my $tableName = $dbh->quote_identifier( $definition->[0]->{tableName} );
|
||||
|
||||
# find out what fields already exist
|
||||
my %tableFields = ();
|
||||
my $sth = $db->read( "DESCRIBE " . $tableName );
|
||||
while ( my ( $col, $type, $null, $key, $default ) = $sth->array ) {
|
||||
next if ( grep { $_ eq $col } 'assetId', 'revisionDate' );
|
||||
$tableFields{$col} = { type => $type, };
|
||||
}
|
||||
|
||||
# update existing and create new fields
|
||||
foreach my $property ( keys %{$properties} ) {
|
||||
my $control = WebGUI::Form::DynamicField->new( $session, %{ $properties->{$property} }, );
|
||||
my $fieldType = $control->getDatabaseFieldType;
|
||||
if ( exists $tableFields{$property} ) {
|
||||
my $changed = 0;
|
||||
|
||||
# parse database table field type
|
||||
$tableFields{$property}{type} =~ m/^(\w+)(\([\d\s,]+\))?$/;
|
||||
my ( $tableFieldType, $tableFieldLength ) = ( $1, $2 );
|
||||
|
||||
# parse form field type
|
||||
$fieldType =~ m/^(\w+)(\([\d\s,]+\))?\s*(binary)?$/;
|
||||
my ( $formFieldType, $formFieldLength ) = ( $1, $2 );
|
||||
|
||||
# compare table parts to definition
|
||||
$changed = 1 if ( $tableFieldType ne $formFieldType );
|
||||
$changed = 1 if ( $tableFieldLength ne $formFieldLength );
|
||||
|
||||
# modify if necessary
|
||||
if ($changed) {
|
||||
$db->write( "alter table $tableName change column "
|
||||
. $dbh->quote_identifier($property) . " "
|
||||
. $dbh->quote_identifier($property)
|
||||
. " $fieldType " );
|
||||
}
|
||||
} ## end if ( exists $tableFields...
|
||||
else {
|
||||
$db->write( "alter table $tableName add column " . $dbh->quote_identifier($property) . " $fieldType " );
|
||||
}
|
||||
delete $tableFields{$property};
|
||||
} ## end foreach my $property ( keys...
|
||||
|
||||
# delete fields that are no longer in the definition
|
||||
foreach my $property ( keys %tableFields ) {
|
||||
if ( $tableFields{$property}{key} ) {
|
||||
$db->write( "alter table $tableName drop index " . $dbh->quote_identifier($property) );
|
||||
}
|
||||
$db->write( "alter table $tableName drop column " . $dbh->quote_identifier($property) );
|
||||
}
|
||||
return 1;
|
||||
} ## end sub upgrade
|
||||
|
||||
# TODO: Add updateTemplates and getTemplatePackage
|
||||
# or some other manner of installing and maintaining default template package
|
||||
|
||||
1;
|
||||
Loading…
Add table
Add a link
Reference in a new issue