- Added keyword tagging api.
This commit is contained in:
parent
83310ba311
commit
23fa0283b3
11 changed files with 354 additions and 12 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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}}) {
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
|
|
|
|||
|
|
@ -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
250
lib/WebGUI/Keyword.pm
Normal 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;
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
52
t/Keyword.t
Normal 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()");
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue