- Added keyword tagging api.

This commit is contained in:
JT Smith 2007-07-07 04:37:38 +00:00
parent 83310ba311
commit 23fa0283b3
11 changed files with 354 additions and 12 deletions

View file

@ -4,6 +4,7 @@
WebGUI::Operation::FormHelpers::www_formHelper and
WebGUI::Operation::Workflow::www_activityHelper for details.
- Added pagination to purchase history in commerce.
- Added keyword tagging api.
- improved performance of EMS
- upgraded YUI to 2.2.2 and YUI-ext to 1.0.1a
- Improved error handling in Spectre when WebGUI hands it bad data.

View file

@ -21,9 +21,13 @@ save you many hours of grief.
the userProfileData table will need to be updated to reflect these
changes.
* WebGUI now requires the following additional perl modules to operate:
* WebGUI now requires the following additional perl modules to operate,
and you should install them prior to upgrading:
Config::JSON
Text::CSV_XS
Class::InsideOut
HTML::TagCloud
* Any customizations made to the Inbox or Inbox/Message tempalates
will be lost. Please back up your custom templates before running

File diff suppressed because one or more lines are too long

View file

@ -21,6 +21,7 @@ my $quiet; # this line required
my $session = start(); # this line required
addRealtimeWorkflow($session);
addKeywordTagging($session);
addGroupingsIndexOnUserId($session);
fixProfileDataWithoutFields($session);
buildNewUserProfileTable($session);
@ -33,6 +34,19 @@ addHttpProxyUrlPatternFilter($session);
finish($session); # this line required
#-------------------------------------------------
sub addKeywordTagging {
my $session = shift;
print "\tAdding a keyword tagging system.\n" unless ($quiet);
$session->db->write("create table assetKeyword (
keyword varchar(64) not null,
assetId varchar(22) binary not null,
primary key (keyword, assetId),
index keyword (keyword),
index assetId (assetId)
)");
}
#-------------------------------------------------
sub addNewsletter {
my $session = shift;

View file

@ -29,6 +29,8 @@ use WebGUI::Cache;
use WebGUI::Form;
use WebGUI::HTML;
use WebGUI::HTMLForm;
use WebGUI::Keyword;
use WebGUI::Search::Index;
use WebGUI::TabForm;
use WebGUI::Utility;
@ -570,7 +572,8 @@ Returns a reference to a list of properties (or specified property) of an Asset.
=head3 propertyName
Any of the values associated with the properties of an Asset. Default choices are "title", "menutTitle", "synopsis", "url", "groupIdEdit", "groupIdView", "ownerUserId", and "assetSize".
Any of the values associated with the properties of an Asset. Default choices are "title", "menutTitle",
"synopsis", "url", "groupIdEdit", "groupIdView", "ownerUserId", "keywords", and "assetSize".
=cut
@ -578,6 +581,9 @@ sub get {
my $self = shift;
my $propertyName = shift;
if (defined $propertyName) {
if ($propertyName eq "keywords") {
return WebGUI::Keyword->new($self->session)->getKeywordsForAsset({asset => $self});
}
return $self->{_properties}{$propertyName};
}
my %copyOfHashRef = %{$self->{_properties}};
@ -1906,6 +1912,7 @@ sub session {
return $self->{_session};
}
#-------------------------------------------------------------------
=head2 setSize ( [extra] )
@ -1965,6 +1972,10 @@ Hash reference of properties and values to set.
sub update {
my $self = shift;
my $properties = shift;
if (exists $properties->{keywords}) {
WebGUI::Keyword->new($self->session)->setKeywordsForAsset(
{keywords=>$properties->{keywords}, asset=>$self});
}
foreach my $definition (@{$self->definition($self->session)}) {
my @setPairs;
foreach my $property (keys %{$definition->{properties}}) {

View file

@ -155,6 +155,10 @@ sub getEditForm {
formSubmit => WebGUI::Form::submit($session, { value => 'Save' }),
formProtect => WebGUI::Form::yesNo($session, { name => "isProtected", value=>$self->getValue("isProtected")}),
formAttachment => '',
formKeywords => WebGUI::Form::text($session, {
name => "keywords",
value => WebGUI::Keyword->new($session)->getKeywordsForAsset({asset=>$self}),
});
allowsAttachments => $wiki->get("maxAttachments"),
formFooter => WebGUI::Form::formFooter($session),
isNew => ($self->getId eq "new"),

View file

@ -121,12 +121,13 @@ sub purge {
(defined $kid) ? $kid->purge :
$self->session->errorHandler->warn("getLineage returned an undefined object in the AssetTrash->purge method. Unable to purge asset.");
}
WebGUI::Keyword->new($self->session)->deleteKeywordsForAsset($self->getId);
WebGUI::Search::Index->new($self)->delete;
$self->session->db->beginTransaction;
$self->session->db->write("delete from metaData_values where assetId = ".$self->session->db->quote($self->getId));
foreach my $definition (@{$self->definition($self->session)}) {
$self->session->db->write("delete from ".$definition->{tableName}." where assetId=".$self->session->db->quote($self->getId));
}
$self->session->db->write("delete from metaData_values where assetId = ".$self->session->db->quote($self->getId));
$self->session->db->write("delete from assetIndex where assetId=".$self->session->db->quote($self->getId));
$self->session->db->write("delete from asset where assetId=".$self->session->db->quote($self->getId));
$self->session->db->commit;
$self->purgeCache;

250
lib/WebGUI/Keyword.pm Normal file
View file

@ -0,0 +1,250 @@
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;
=head1 NAME
Package WebGUI::Keyword
=head1 DESCRIPTION
This package provides an API to create and modify keywords used by the asset sysetm.
=head1 SYNOPSIS
use WebGUI::Keyword;
=head1 METHODS
These methods are available from this class:
=cut
# begin inside out object
{
#-------------------------------------------------------------------
=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 10.
=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} || 10);
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 = shift;
my $options = shift;
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 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;
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)]);
}
}
# end inside out object
}
1;

View file

@ -125,7 +125,10 @@ sub create {
my $url = $asset->get("url");
$url =~ s/\/|\-|\_/ /g;
my $description = WebGUI::HTML::filter($asset->get('description'), "all");
my $keywords = WebGUI::HTML::filter(join(" ",$asset->get("title"), $asset->get("menuTitle"), $asset->get("synopsis"), $url, $description), "all");
my $keywords = join(" ",$asset->get("title"), $asset->get("menuTitle"), $asset->get("synopsis"), $url,
$description);
$keywords .= WebGUI::Keyword->new($self->session)->getKeywordsForAsset({asset=>$asset});
$keywords = WebGUI::HTML::filter($keywords, "all");
my $synopsis = $asset->get("synopsis") || substr($description,0,255) || substr($keywords,0,255);
#-------------------- added by zxp for chinese word segment

View file

@ -120,6 +120,8 @@ checkModule("Color::Calc");
checkModule("Text::Aspell",0.01,2);
checkModule("Locale::US");
checkModule("Weather::Com::Finder","0.5.1");
checkModule("Class::InsideOut","1.06");
checkModule("HTML::TagCloud","0.34");
###################################

52
t/Keyword.t Normal file
View file

@ -0,0 +1,52 @@
#-------------------------------------------------------------------
# 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
#-------------------------------------------------------------------
use FindBin;
use strict;
use lib "$FindBin::Bin/lib";
use WebGUI::Test;
use WebGUI::Session;
use WebGUI::Keyword;
use WebGUI::Asset;
# load your modules here
use Test::More tests => 9; # increment this value for each test you create
my $session = WebGUI::Test->session;
# put your tests here
my $home = WebGUI::Asset->getDefault($session);
isa_ok($home, "WebGUI::Asset");
my $keyword = WebGUI::Keyword->new($session);
isa_ok($keyword, "WebGUI::Keyword");
$keyword->setKeywordsForAsset({ asset=>$home, keywords=>"test key word foo bar"});
my ($count) = $session->db->quickArray("select count(*) from assetKeyword where assetId=?", [$home->getId]);
is($count, 5, "setKeywordsForAsset() create");
$keyword->setKeywordsForAsset({ asset=>$home, keywords=>"webgui rules"});
my ($count) = $session->db->quickArray("select count(*) from assetKeyword where assetId=?", [$home->getId]);
is($count, 2, "setKeywordsForAsset() update");
is(scalar(@{$keyword->getKeywordsForAsset({ asset=>$home, asArrayRef=>1})}), 2, "getKeywordsForAsset()");
like($keyword->generateCloud({startAsset=>$home, displayFunc=>"showKeyword" }), qr/rules/, "getLatestVersionNumber()");
$keyword->replaceKeyword({currentKeyword => "rules", newKeyword=>"owns"});
like($keyword->getKeywordsForAsset({asset=>$home }), qr/owns/, "getLatestVersionNumber()");
$keyword->deleteKeyword({keyword => "owns"});
unlike($keyword->getKeywordsForAsset({asset=>$home }), qr/owns/, "getLatestVersionNumber()");
$keyword->deleteKeywordsForAsset($home);
is(scalar(@{$keyword->getKeywordsForAsset({ asset=>$home, asArrayRef=>1})}), 0, "getKeywordsForAsset()");