webgui/lib/WebGUI/Keyword.pm
2007-12-17 22:22:06 +00:00

288 lines
7.3 KiB
Perl

package WebGUI::Keyword;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2007 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::InsideOut qw(public register id);
use HTML::TagCloud;
use WebGUI::Paginator;
=head1 NAME
Package WebGUI::Keyword
=head1 DESCRIPTION
This package provides an API to create and modify keywords used by the asset sysetm.
Assets can use the C<keywords> property to set keywords automatically. See
WebGUI::Asset::update() for more details.
=head1 SYNOPSIS
use WebGUI::Keyword;
=head1 METHODS
These methods are available from this class:
=cut
#-------------------------------------------------------------------
=head2 session ( )
Returns a reference to the current session.
=cut
public session => my %session;
#-------------------------------------------------------------------
=head2 deleteKeywordsForAsset ( $asset )
Removes all keywords from an asset.
=head3 asset
The asset to delete the keywords from.
=cut
sub deleteKeywordsForAsset {
my $self = shift;
my $asset = shift;
$self->session->db->write("delete from assetKeyword where assetId=?", [$asset->getId]);
}
#-------------------------------------------------------------------
=head2 deleteKeyword ( { keyword => $keyword } )
Removes a particular keyword from the system entirely.
=head3 keyword
The keyword to remove.
=cut
sub deleteKeyword {
my $self = shift;
my $options = shift;
$self->session->db->write("delete from assetKeyword where keyword=?", [$options->{keyword}]);
}
#-------------------------------------------------------------------
=head2 generateCloud ( { startAsset => $asset, displayFunc => "viewKeyword" } )
Generates a block of HTML that represents the prevelence of one keyword compared to another.
=head3 displayAsset
The asset that contains the function to display a list of assets related to a given keyword. If not specified the
startAsset will be used.
=head3 displayFunc
The www func that will be called on the displayAsset to display the list of assets associated to a given keyword.
=head3 cloudLevels
How many levels of keyword sizes should there be displayed in the cloud. Defaults to 24. Range between 2 and 24.
=head3 startAsset
The starting point in the asset tree to search for keywords, so you can show a cloud for just a subsection of the
site.
=head3 maxKeywords
The maximum number of keywords to display in the cloud. Defaults to 50. Valid range between 1 and 50, inclusive.
=cut
sub generateCloud {
my $self = shift;
my $options = shift;
my $display = $options->{displayAsset} || $options->{startAsset};
my $sth = $self->session->db->read("select count(*) as keywordTotal, keyword from assetKeyword
left join asset using (assetId) where lineage like ? group by keyword order by keywordTotal limit 50",
[ $options->{startAsset}->get("lineage").'%' ]);
my $cloud = HTML::TagCloud->new(levels=>$options->{cloudLevels} || 24);
while (my ($count, $keyword) = $sth->array) {
$cloud->add($keyword, $display->getUrl("func=".$options->{displayFunc}.";keyword=".$keyword), $count);
}
return $cloud->html_and_css($options->{maxKeywords});
}
#-------------------------------------------------------------------
=head2 getKeywordsForAsset ( { asset => $asset } )
Returns a string of keywords separated by spaces.
=head3 asset
An asset that you want to get the keywords for.
=head3 asArrayRef
A boolean, that if set to 1 will return the keywords as an array reference rather than a string.
=cut
sub getKeywordsForAsset {
my ($self, $options) = @_;
my @keywords = $self->session->db->buildArray("select keyword from assetKeyword where assetId=?",
[$options->{asset}->getId]);
if ($options->{asArrayRef}) {
return \@keywords;
}
else {
return join(" ", @keywords);
}
}
#-------------------------------------------------------------------
=head2 getMatchingAssets ( { startAsset => $asset, keyword => $keyword } )
Returns an array reference of asset ids matching the start point + keyword.
=head3 startAsset
An asset object where you'd like to start searching for matching keywords.
=head3 keyword
The keyword to match.
=head3 usePaginator
Instead of returning an array reference of assetId's, return a paginator object.
=cut
sub getMatchingAssets {
my ($self, $options) = @_;
my $query = "select assetKeyword.assetId from assetKeyword left join asset using (assetId)
where lineage like ? and keyword=? order by creationDate desc";
my $params = [$options->{startAsset}->get("lineage").'%', $options->{keyword}];
if ($options->{usePaginator}) {
my $p = WebGUI::Paginator->new($self->session);
$p->setDataByQuery($query, undef, undef, $params);
return $p;
}
else {
return $self->session->db->buildArrayRef($query, $params);
}
}
#-------------------------------------------------------------------
=head2 new ( $session )
Constructor.
=head3 session
A reference to the current session.
=cut
sub new {
my $class = shift;
my $session = shift;
my $self = bless \do {my $s}, $class;
register($self);
$session{id $self} = $session;
return $self;
}
#-------------------------------------------------------------------
=head2 replaceKeyword ( { currentKeyword => $keyword1, newKeyword => $keyword2 } )
Changes a keyword from one thing to another thing throughout the system.
=head3 currentKeyword
Whatever the keyword is now. Example: "apples"
=head3 newKeyword
Whatever you want it to be. Example; "apple"
=cut
sub replaceKeyword {
my ($self, $options) = @_;
$self->session->db->write("update assetKeyword set keyword=? where keyword=?",
[$options->{newKeyword}, $options->{currentKeyword}]);
}
#-------------------------------------------------------------------
=head2 setKeywordsForAsset ( { asset => $asset, keywords => $keywords } )
Sets the keywords for an asset.
=head3 asset
An asset that you want to set the keywords for.
=head3 keywords
Either a string of space-separated keywords, or an array reference of keywords to assign to the asset.
=cut
sub setKeywordsForAsset {
my $self = shift;
my $options = shift;
my $keywords = [];
if (ref $options->{keywords} eq "ARRAY") {
$keywords = $options->{keywords};
}
else {
@{$keywords} = split(" ", $options->{keywords});
}
$self->deleteKeywordsForAsset($options->{asset});
my $assetId = $options->{asset}->getId;
if (scalar(@{$keywords})) {
my $sth = $self->session->db->prepare("insert into assetKeyword (assetId, keyword) values (?,?)");
foreach my $keyword (@{$keywords}) {
next if ($keyword eq "");
$sth->execute([$assetId, lc($keyword)]);
}
}
else {
$self->deleteKeywordsForAsset($options->{asset});
}
}
1;