more search related changes

This commit is contained in:
JT Smith 2006-01-22 03:31:37 +00:00
parent 9c7e8699a2
commit 66baa5cea2
8 changed files with 9 additions and 1074 deletions

View file

@ -33,8 +33,7 @@ sub addSearchEngine {
assetId varchar(22) binary not null primary key,
title varchar(255),
synopsis text,
startDate bigint,
endDate bigint,
url varchar(255),
creationDate bigint,
revisionDate bigint,
ownerUserId varchar(22) binary,
@ -85,6 +84,9 @@ sub removeFiles {
unlink '../../lib/WebGUI/Setting.pm';
unlink '../../lib/WebGUI/Grouping.pm';
unlink '../../lib/WebGUI/Asset/Wobject/IndexedSearch.pm';
unlink '../../lib/WebGUI/Help/Asset_IndexedSearch.pm';
unlink '../../lib/WebGUI/i18n/Asset_IndexedSearch.pm';
unlink '../../sbin/Hourly/IndexedSearch_buildIndex.pm';
rmtree('../../lib/WebGUI/Asset/Wobject/IndexedSearch');
}

View file

@ -1,572 +0,0 @@
package WebGUI::Asset::Wobject::IndexedSearch;
use strict;
use Time::HiRes;
use WebGUI::Asset::Wobject::IndexedSearch::Search;
use WebGUI::HTMLForm;
use WebGUI::HTML;
use WebGUI::Macro;
use WebGUI::International;
use WebGUI::SQL;
use Tie::IxHash;
use WebGUI::Utility;
use WebGUI::Paginator;
use WebGUI::Asset::Wobject;
our @ISA = qw(WebGUI::Asset::Wobject);
#-------------------------------------------------------------------
sub definition {
my $class = shift;
my $session = shift; use WebGUI; WebGUI::dumpSession($session);
my $definition = shift;
my $i18n = WebGUI::International->new($session,"Asset_IndexedSearch");
push (@{$definition}, {
tableName=>'IndexedSearch',
className=>'WebGUI::Asset::Wobject::IndexedSearch',
assetName=>$i18n->get('assetName'),
properties=>{
templateId=>{
fieldType=>"template",
defaultValue=>"PBtmpl0000000000000034"
},
indexName=>{
fieldType=>'text',
defaultValue=>'default'
},
searchRoot=>{
fieldType=>'checkList',
defaultValue=>'any'
},
forceSearchRoots=>{
fieldType=>'yesNo',
defaultValue=>1
},
users=>{
fieldType=>'selectList',
defaultValue=>'any'
},
namespaces=>{
fieldType=>'selectList',
defaultValue=>'any'
},
contentTypes=>{
fieldType=>'selectList',
defaultValue=>'any'
},
paginateAfter=>{
defaultValue=>10
},
highlight=>{
defaultValue=>1
},
previewLength=>{
defaultValue=>130
},
highlight_1=>{
defaultValue=>'#ffff66'
},
highlight_2=>{
defaultValue=>'#A0FFFF'
},
highlight_3=>{
defaultValue=>'#99ff99'
},
highlight_4=>{
defaultValue=>'#ff9999'
},
highlight_5=>{
defaultValue=>'#ff66ff'
},
}
});
return $class->SUPER::definition($session, $definition);
}
#-------------------------------------------------------------------
sub getUiLevel {
return 5;
}
#-------------------------------------------------------------------
sub getEditForm {
my $self = shift;
my (@data, %indexName);
my $tabform = $self->SUPER::getEditForm();
tie my %searchRoot, 'Tie::IxHash';
# Unconditional read to catch intallation errors.
my $i18n = WebGUI::International->new($self->session,"Asset_IndexedSearch");
my $sth = $self->session->db->unconditionalRead("select distinct(indexName), indexName from IndexedSearch_docInfo");
unless ($sth->errorCode < 1) {
return "<p><b>" . $i18n->get(1) . $sth->errorMessage."</b></p>";
}
while (@data = $sth->array) {
$indexName{$data[0]} = $data[1];
}
$sth->finish;
unless(%indexName) {
return "<p><b>" . $i18n->get(2) .
"<p>" . $i18n->get(3) . "</p></b></p>";
}
# Index to use
# $tabform->getTab("properties")->radioList( -name=>'indexName',
# -options=>\%indexName,
# -label=>$i18n->get(5),
# -value=>$self->getValue("indexName"),
# -vertical=>1
# );
# NOTE: For now we're limiting each site to one index. Will allow more in the future.
$tabform->getTab("properties")->hidden(
-name=>"indexName",
-value=>"IndexedSearch_default"
);
# Page roots
#%searchRoot = ( 'any'=>$i18n->get(15),
# $session{page}{pageId}=>$i18n->get(4),
# $self->session->db->buildHash("select pageId,title from page where parentId='0' and isSystem<>1 order by title")
# );
#$tabform->getTab("properties")->checkList ( -name=>'searchRoot',
# -options=>\%searchRoot,
# -label=>$i18n->get(6),
# -value=>[ split("\n", $self->getValue("searchRoot")) ],
# -multiple=>1,
# -vertical=>1,
# );
$tabform->getTab("properties")->yesNo(
-name=>'forceSearchRoots',
-label=>$i18n->get('force search roots'),
-value=>$self->getValue("forceSearchRoots")
);
# Content of specific user
$tabform->getTab("properties")->selectList ( -name=>'users',
-options=>$self->_getUsers(),
-label=>$i18n->get(7),
-value=>[ split("\n", $self->getValue("users")) ],
-multiple=>1,
-size=>5
);
# Content in specific namespaces
$tabform->getTab("properties")->selectList ( -name=>'namespaces',
-options=>$self->_getNamespaces,
-label=>$i18n->get(8),
-value=>[ split("\n", $self->getValue("namespaces")) ],
-multiple=>1,
-size=>5
);
# Only specific content types
my $contentTypes = $self->_getContentTypes();
delete $contentTypes->{content};
$tabform->getTab("properties")->checkList ( -name=>'contentTypes',
-options=>$contentTypes,
-label=>$i18n->get(10),
-value=>[ split("\n", $self->getValue("contentTypes")) ],
-multiple=>1,
-vertical=>1,
);
$tabform->getTab("display")->template(
-value=>$self->getValue("templateId"),
-namespace=>"IndexedSearch"
);
$tabform->getTab("display")->integer ( -name=>'paginateAfter',
-label=>$i18n->get(11),
-value=>$self->getValue("paginateAfter"),
);
$tabform->getTab("display")->integer ( -name=>'previewLength',
-label=>$i18n->get(12),
-value=>$self->getValue("previewLength"),
);
$tabform->getTab("display")->yesNo ( -name=>'highlight',
-label=>$i18n->get(13),
-value=>$self->getValue("highlight"),
);
# Color picker for highlight colors
$tabform->getTab("display")->raw ( -value=>'
<script type="text/javascript" src="'.$self->session->config->get("extrasURL").'/wobject/IndexedSearch/ColorPicker2.js"></script>
<script type="text/javascript">
var cp = new ColorPicker("window");
</script>'
);
for (1..5) {
my $highlight = "highlight_$_";
$tabform->getTab("display")->text ( -name=>$highlight,
-label=>$i18n->get(14) ." $_:",
-size=>7,
-value=>$self->getValue($highlight),
-subtext=>qq{
<a href="#" onclick="cp.select($highlight,'$highlight');
return false;" name="$highlight" id="$highlight">Pick</a>}
);
}
return $tabform;
}
#-------------------------------------------------------------------
sub getIcon {
my $self = shift;
my $small = shift;
return $self->session->config->get("extrasURL").'/assets/small/search.gif' if ($small);
return $self->session->config->get("extrasURL").'/assets/search.gif';
}
#-------------------------------------------------------------------
sub view {
my $self = shift;
my (%var, @resultsLoop);
# Do some query handling
$var{exactPhrase} = $self->session->form->process("exactPhrase");
$var{allWords} = $self->session->form->process("allWords");
$var{atLeastOne} = $self->session->form->process("atLeastOne");
$var{without} = $self->session->form->process("without");
$var{query} = $self->session->form->process("query");
$var{query} .= qq/ +"$var{exactPhrase}"/ if ($var{exactPhrase});
$var{query} .= " ".join(" ",map("+".$_,split(/\s+/,$var{allWords}))) if ($var{allWords});
$var{query} .= qq{ $var{atLeastOne}} if ($var{atLeastOne});
$var{query} .= " ".join(" ",map("-".$_,split(/\s+/,$var{without}))) if ($var{without});
# Remove macro's from query
my $query = $var{query};
WebGUI::Macro::negate(\$query);
$var{query} = $query;
# Set some standard vars
my $i18n = WebGUI::International->new($self->session,"Asset_IndexedSearch");
$var{submit} = WebGUI::Form::submit($self->session,{value=>$i18n->get(16)});
$var{actionURL} = $self->getUrl;
$var{"int.search"} = $i18n->get(16);
$var{numberOfResults} = '0';
$var{"select_".$self->getValue("paginateAfter")} = "selected";
# Do the search
my $startTime = Time::HiRes::time();
my $filter = $self->_buildFilter;
my $search = WebGUI::Asset::Wobject::IndexedSearch::Search->new($self->getValue('indexName'));
$search->open;
my $results = $search->search($var{query},$filter);
$var{duration} = Time::HiRes::time() - $startTime;
$var{duration} = sprintf("%.3f", $var{duration}); # Duration rounded to 3 decimal places
# Let's see if the search returned any results
if (defined ($results)) {
$var{numberOfResults} = scalar(@$results);
# Deal with pagination
my $url = "query=".$self->session->url->escape($var{query});
map {$url .= "&users=".$self->session->url->escape($_)} $self->session->request->param('users');
map {$url .= "&namespaces=".$self->session->url->escape($_)} $self->session->request->param('namespaces');
map {$url .= "&contentTypes=".$self->session->url->escape($_)} $self->session->request->param('contentTypes');
$url .= "&paginateAfter=".$self->getValue("paginateAfter");
my $p = WebGUI::Paginator->new($self->session,$self->session->url->page($url), $self->getValue("paginateAfter"));
$p->setDataByArrayRef($results);
$var{startNr} = 1;
if($self->session->form->process("pn")) {
$var{startNr} = (($self->session->form->process("pn") - 1) * $self->getValue("paginateAfter")) + 1;
}
my @highlightColors = map { $self->getValue("highlight_$_") } (1..5);
$var{queryHighlighted} = $search->highlight($var{query}, undef, \@highlightColors);
# Get result details for this page
if($p->getPageNumber > $p->getNumberOfPages) {
$var{numberOfResults} = 0;
$var{resultsLoop} = [];
} else {
$var{resultsLoop} = $search->getDetails($p->getPageData,
highlightColors => \@highlightColors,
previewLength => $self->getValue('previewLength'),
highlight => $self->getValue('highlight')
);
# Pagination variables
$var{endNr} = $var{startNr}+(scalar(@{$var{resultsLoop}}))-1;
$p->appendTemplateVars(\%var);
}
}
# Create a loop with namespaces
$var{namespaces} = [];
my $namespaces = $self->_getNamespaces('restricted');
foreach(keys %$namespaces) {
my $selected = 0;
if (scalar $self->session->request->param('namespaces')) {
$selected = isIn($_, $self->session->request->param('namespaces'));
} else {
$selected = ($self->session->form->process("namespaces") =~ /$_/);
}
push(@{$var{namespaces}}, { value => $_, name => $namespaces->{$_}, selected => $selected });
}
# Create a loop with contentTypes
#
# And while we are busy we also create a loop with simplified contentTypes
# This means: wobject, page, wobjectDetail are masked in one option: content
$var{contentTypes} = [];
$var{contentTypesSimple} = [];
my $contentTypes = $self->_getContentTypes('restricted');
foreach(keys %$contentTypes) {
my $selected = 0;
if (scalar $self->session->request->param('contentTypes')) {
$selected = isIn($_, $self->session->request->param('contentTypes'));
} else {
$selected = ($self->session->form->process("contentTypes") =~ /$_/);
}
unless(/^content$/) { # No shortcut in the detailed contentType list
push(@{$var{contentTypes}}, { value => $_,
name => $contentTypes->{$_},
selected => $selected,
'type_'.$_ => 1 });
}
unless(/^page|wobject|wobjectDetail$/) { # No details in the simple contentType list
push(@{$var{contentTypesSimple}}, { value => $_,
name => $contentTypes->{$_},
selected => $selected,
'type_'.$_ => 1 });
}
}
# Create a loop with users
$var{users} = [];
my $users = $self->_getUsers('restricted');
foreach(keys %$users) {
my $selected = 0;
if (scalar $self->session->request->param('users')) {
$selected = isIn($_, $self->session->request->param('users'));
} else {
$selected = ($self->session->form->process("users") =~ /$_/);
}
push(@{$var{users}}, { value => $_, name => $users->{$_}, selected => $selected });
}
# Create a loop with searchable page roots
my $rootData;
my @roots = split(/\n/, $self->get('searchRoot'));
my %checked = map {$_=>1} $self->session->request->param("searchRoot");
#if (isIn('any', @roots)) {
# foreach $rootData (WebGUI::Page->getAnonymousRoot->daughters) {
# push (@{$var{searchRoots}}, {
# value => $rootData->{'pageId'},
# menuTitle => $rootData->{'menuTitle'},
# title => $rootData->{'title'},
# urlizedTitle => $rootData->{'urlizedTitle'},
# checked => $checked{$rootData->{'pageId'}},
# });
# $var{"rootPage.".$rootData->{'urlizedTitle'}.".id"} = $rootData->{'pageId'};
# $var{"rootPage.".$rootData->{'urlizedTitle'}.".checked"} = $checked{$rootData->{'pageId'}};
# }
#} else {
# foreach (@roots) {
# $rootData = WebGUI::Page->new($_);
# push (@{$var{searchRoots}}, {
# value => $rootData->get('pageId'),
# menuTitle => $rootData->get('menuTitle'),
# title => $rootData->get('title'),
# urlizedTitle => $rootData->get('urlizedTitle'),
# checked => $checked{$rootData->get('pageId')},
# });
# $var{"rootPage.".$rootData->get('urlizedTitle').".id"} = $rootData->get('pageId');
# $var{"rootPage.".$rootData->get('urlizedTitle').".checked"} = $checked{$rootData->get('pageId')};
# }
#}
$var{"anyRootPage.checked"} = $checked{'any'};
# close the search
$search->close;
return $self->processTemplate(\%var, $self->get("templateId"));
}
#-------------------------------------------------------------------
sub www_edit {
my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit;
$self->getAdminConsole->setHelp("search add/edit", "Asset_IndexedSearch");
my $form = $self->getEditForm;
my $output = $form;
$output = $form->print unless $form =~ /^<p><b/;
my $i18n = WebGUI::International->new($self->session,"Asset_IndexedSearch");
return $self->getAdminConsole->render($output,$i18n->get("26"));
}
#-------------------------------------------------------------------
sub www_view {
my $self = shift;
return $self->SUPER::www_view(1);
}
#-------------------------------------------------------------------
sub _buildPageList {
my ($self, @userSpecifiedRoots, @roots, @allowedRoots, $pageId, @pages);
$self = shift;
@userSpecifiedRoots = $self->session->request->param("searchRoot");
if ((scalar(@userSpecifiedRoots) == 0)
|| ($self->getValue("forceSearchRoots"))
|| (isIn('any', @userSpecifiedRoots))
) {
@roots = split(/\n+/i, $self->get("searchRoot"));
} else {
@allowedRoots = split(/\n+/, $self->get("searchRoot"));
foreach (@userSpecifiedRoots) {
push (@roots, $_) if (isIn($_, @allowedRoots));
}
}
#foreach $pageId (@roots) {
# WebGUI::Page->new($pageId)->traversePreOrder(
# sub {
# push(@pages, $_[0]->get('pageId'));
# }
# );
#}
return [ @pages ];
}
#-------------------------------------------------------------------
sub _buildFilter {
my $self = shift;
my %filter = ();
# # pages
# if($self->get('searchRoot') !~ /any/i) {
# $filter{assetId} = $self->_buildPageList;
# }
# content-types
if($self->session->form->process("contentTypes") && ! isIn('any', $self->session->request->param('contentTypes'))) {
$filter{contentType} = [ $self->session->request->param('contentTypes') ];
# contentType "content" is a shortcut for "page", "wobject" and "wobjectDetail"
if (isIn('content', $self->session->request->param('contentTypes'))) {
push(@{$filter{contentType}}, qw/Asset assetDetail/);
}
} elsif ($self->getValue('contentTypes') !~ /any/i) {
$filter{contentType} = [ split(/\n/, $self->getValue('contentTypes')) ];
}
# users
if($self->session->form->process("users") && ! isIn('any', $self->session->request->param('users'))) {
$filter{ownerId} = [];
foreach my $user ($self->session->request->param('users')) {
if ($user =~ /\D/) {
$user =~ s/\*/%/g;
($user) = $self->session->db->buildArray("select userId from users where username like ".$self->session->db->quote($user));
}
push(@{$filter{ownerId}}, $self->session->db->quote($user)) if ($user =~ /^\d+$/);
}
} elsif ($self->getValue('users') !~ /any/i) {
$filter{ownerId} = [ split(/\n/, $self->getValue('users')) ];
}
# namespaces
if($self->session->form->process("namespaces") && ! isIn('any', $self->session->request->param('namespaces'))) {
$filter{namespace} = [ $self->session->request->param('namespaces') ];
} elsif ($self->getValue('namespaces') !~ /any/i) {
$filter{namespace} = [ split(/\n/, $self->getValue('namespaces')) ];
}
# delete $filter{ownerId} if it is an empty array reference
if(exists($filter{ownerId})) {
delete $filter{ownerId} unless (scalar(@{$filter{ownerId}}));
}
return \%filter;
}
#-------------------------------------------------------------------
sub _getNamespaces {
my ($self, $restricted) = @_;
my %international;
foreach my $class (@{$self->session->config->get("assets")}) {
my $load = 'use '.$class;
eval($load);
if ($@) {
$self->session->errorHandler->warn("Couldn't compile ".$class." because ".$@);
} else {
$international{$class} = eval{$class->getName()};
}
}
my $i18n = WebGUI::International->new($self->session,"Asset_IndexedSearch");
tie my %namespaces, 'Tie::IxHash';
if ($restricted and $self->get('namespaces') !~ /any/i) {
$namespaces{any} = $i18n->get(18);
foreach (split/\n/, $self->get('namespaces')) {
$namespaces{$_} = $international{$_} || ucfirst($_);
}
} else {
$namespaces{any} = $i18n->get(18);
foreach ($self->session->db->buildArray("select distinct(namespace) from IndexedSearch_docInfo order by namespace")) {
$namespaces{$_} = $international{$_} ||ucfirst($_);
}
}
return \%namespaces;
}
#-------------------------------------------------------------------
sub _getContentTypes {
my ($self, $restricted) = @_;
my $i18n = WebGUI::International->new($self->session,"Asset_IndexedSearch");
my %international = ( 'page' => $i18n->get('page'),
'wobject' => $i18n->get(19),
'wobjectDetail' => $i18n->get(20),
'content' =>$i18n->get(21),
'discussion' => $i18n->get('discussion'),
'profile' => $i18n->get(22),
'any' => $i18n->get(23),
);
tie my %contentTypes, 'Tie::IxHash';
if ($restricted and $self->get('contentTypes') !~ /any/i) {
$contentTypes{any} = $international{any};
$contentTypes{content} = $international{content}; # shortcut for page, wobject and wobjectDetail
foreach (split/\n/, $self->get('contentTypes')) {
$contentTypes{$_} = $international{$_};
}
} else {
%contentTypes = ( 'any' => $international{any},
'content' => $international{content}, # shortcut for page, wobject and wobjectDetail
);
foreach ($self->session->db->buildArray("select distinct(contentType) from IndexedSearch_docInfo order by contentType")) {
$contentTypes{$_} = $international{$_} || ucfirst($_);
}
}
return \%contentTypes;
}
#-------------------------------------------------------------------
sub _getSearchablePages {
my $self = shift;
my $searchRoot = shift;
my %pages;
my $sth = $self->session->db->read("select assetId from asset where parentId = ".$self->session->db->quote($searchRoot));
while (my %data = $sth->hash) {
$pages{$data{assetId}} = 1;
%pages = (%pages, $self->_getSearchablePages($data{assetId}) );
}
return %pages;
}
#-------------------------------------------------------------------
sub _getUsers {
my ($self, $restricted) = @_;
tie my %users, 'Tie::IxHash';
my $i18n = WebGUI::International->new($self->session,"Asset_IndexedSearch");
if ($restricted and $self->get('users') !~ /any/i) {
$users{any} = $i18n->get(25);
foreach (split/\n/, $self->get('users')) {
$users{$_} = $_;
}
} else {
%users = ( 'any' => $i18n->get(25),
$self->session->db->buildHash("select userId, username from users order by username")
);
}
return \%users;
}
1;

View file

@ -1,59 +0,0 @@
package WebGUI::Asset::Wobject::IndexedSearch::Search;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2004 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 DBIx::FullTextSearch;
#use WebGUI::SQL;
#use WebGUI::HTML;
#use DBIx::FullTextSearch::StopList;
#use WebGUI::Utility;
#use HTML::Highlight;
#use WebGUI::Macro;
=head1 NAME
Package WebGUI::Wobject::IndexedSearch::Search
=head1 DESCRIPTION
Search implementation for WebGUI.
=head1 SYNOPSIS
use WebGUI::Wobject::IndexedSearch::Search;
my $search = WebGUI::Wobject::IndexedSearch::Search->new();
$search->indexDocument( { text => 'Index this text',
location => 'http://www.mysite.com/index.pl/faq#45',
languageId => 3,
namespace => 'FAQ'
});
my $hits = search->search("+foo -bar koo",{ namespace = ['Article', 'FAQ']} );
$search->close;
=head1 SEE ALSO
This package is an extension to DBIx::FullTextSearch and HTML::Highlight.
See that packages for documentation of their methods.
=head1 METHODS
These methods are available from this package:
=cut
1;

View file

@ -1,38 +0,0 @@
package WebGUI::Help::Asset_IndexedSearch;
our $HELP = {
'indexed search add/edit' => {
title => '26',
body => '27',
fields => [
],
related => [
{
tag => 'wobjects using',
namespace => 'Wobject'
},
{
tag => 'indexed search template',
namespace => 'Asset_IndexedSearch'
}
]
},
'indexed search template' => {
title => '29',
body => '28',
fields => [
],
related => [
{
tag => 'wobjects using',
namespace => 'Wobject'
},
{
tag => 'indexed search add/edit',
namespace => 'Asset_IndexedSearch'
}
]
},
};
1;

View file

@ -84,13 +84,13 @@ sub getAssets {
=head2 getResultSet ( )
Returns a WebGUI::SQL::ResultSet object containing the search results with columns labeled "assetId", "title", "synopsis", "ownerUserId", "groupIdView", "groupIdEdit", "creationDate", "revisionDate", "startDate", "endDate", and "className".
Returns a WebGUI::SQL::ResultSet object containing the search results with columns labeled "assetId", "title", "url", "synopsis", "ownerUserId", "groupIdView", "groupIdEdit", "creationDate", "revisionDate", and "className".
=cut
sub getResultSet {
my $self = shift;
my $query = "select assetId, title, synopsis, ownerUserId, groupIdView, groupIdEdit, creationDate, revisionDate, startDate, endDate, className
my $query = "select assetId, title, url, synopsis, ownerUserId, groupIdView, groupIdEdit, creationDate, revisionDate, className
from assetIndex where isPublic=? and (".$self->{_query}.")";
my $rs = $self->session->db->prepare($self->{_query});
$rs->execute([$self->{_isPublic},@{$self->{_params}}]);

View file

@ -112,9 +112,9 @@ sub create {
$url =~ s/\/|\-|\_/ /g;
my $description = WebGUI::HTML::filter($asset->get('description'), "all");
my $keywords = join(" ",$asset->get("title"), $asset->get("menuTitle"), $asset->get("synopsis"), $url, $description);
my $add = $self->session->db->prepare("insert into assetIndex (assetId, title, startDate, endDate, creationDate, revisionDate,
ownerUserId, groupIdView, groupIdEdit, lineage, className, synopsis, keywords) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )");
$add->execute([$asset->getId, $asset->get("title"), $asset->get("startDate"), $asset->get("endDate"), $asset->get("creationDate"),
my $add = $self->session->db->prepare("insert into assetIndex (assetId, title, url, creationDate, revisionDate,
ownerUserId, groupIdView, groupIdEdit, lineage, className, synopsis, keywords) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )");
$add->execute([$asset->getId, $asset->get("title"), $asset->get("url"), $asset->get("creationDate"),
$asset->get("revisionDate"), $asset->get("ownerUserId"), $asset->get("groupIdView"), $asset->get("groupIdEdit"),
$asset->get("lineage"), $asset->get("className"), $asset->get("synopsis"), $keywords]);
return $self;

View file

@ -1,287 +0,0 @@
package WebGUI::i18n::English::Asset_IndexedSearch;
our $I18N = {
'11' => {
message => q|Paginate after|,
lastUpdated => 1066252409
},
'21' => {
message => q|Content|,
lastUpdated => 1066765681
},
'7' => {
message => q|Only results created by|,
lastUpdated => 1066252303
},
'26' => {
message => q|Search, Add/Edit|,
lastUpdated => 1067346336
},
'assetName' => {
message => q|Search|,
lastUpdated => 1066593262
},
'2' => {
message => q|No index created. The scheduler must run and create the index first.|,
lastUpdated => 1066252099
},
'22' => {
message => q|Profile|,
lastUpdated => 1066765844
},
'1' => {
message => q|Table Search_docInfo can't be opened.|,
lastUpdated => 1066252055
},
'18' => {
message => q|Any namespace|,
lastUpdated => 1066593420
},
'23' => {
message => q|Any Content Type|,
lastUpdated => 1066766053
},
'16' => {
message => q|Search|,
lastUpdated => 1066565087
},
'13' => {
message => q|Highlight results ?|,
lastUpdated => 1066252498
},
'29' => {
message => q|Search template|,
lastUpdated => 1070202588
},
'27' => {
message => q|
<P>The Search adds advanced search capabilities to your WebGUI site. </P>
<P><STRONG>Index to use</STRONG><BR>
The Search uses an index to retrieve it's
results from. Indexes are created with the scheduler. You can create more then one index. Choose here which index to use.</P>
<P><STRONG>Search through</STRONG><BR>
By default all pages are searched. You can
limit the search to certain page roots. Multiple choices are allowed.</P>
<P><STRONG>Only results created by</STRONG><BR>
You can limit the results to
items created by certain users. By default items from any user are returned.</P>
<P><STRONG>Only results in namespace</STRONG><BR>
By default all namespaces are
searched. You can limit the search to certain namespaces. An example of usage is
to search only in products.</P>
<P><STRONG>Only results in language</STRONG><BR>
If you have a multi-lingual
site, you can use this option to limit the search results to a certain
language.</P>
<P><STRONG>Only results of type</STRONG><BR>
You can limit the search to certain
types of content.</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P align=left><EM>Discussion:</EM> Messages on the forums, discussions on
articles or USS.<BR><EM>Help:</EM> Content in the online WebGUI help
system<BR><EM>Page:</EM><STRONG> </STRONG>Page title and
synopsis<BR><EM>Profile:</EM> User Profiles<BR><EM>Wobject: </EM>Wobject Title
and Description<BR><EM>Wobject details: </EM>All other wobject data. For example
FAQ question, Calendar item, etc.</P></BLOCKQUOTE>
<P dir=ltr align=left><b>Force users to use selected roots</b><br>Enabling this option will cause the search to be over all of the selected page roots regardless of what the user entered via the search form.</b></p>
<P dir=ltr align=left><STRONG>Template<BR></STRONG>Select a template to layout
your Search. The different templates have different functionality.</P>
<P dir=ltr align=left><STRONG>Paginate after<BR></STRONG>The number of results
you'd like to display on a page.</P>
<P dir=ltr align=left><STRONG>Context preview length<BR></STRONG>The maximum
number of characters in each of the context sections. Default is 130 characters.
A negative length gives the complete body, while a preview length of null gives
no preview.</P>
<P dir=ltr align=left><STRONG>Highlight results ?<BR></STRONG>If you want to
highlight the search results in the preview you'll want to check this box.</P>
<P dir=ltr align=left><STRONG>Highlight color n<BR></STRONG>The colors that are
used to highlight the corresponding words in the query.</P>|,
lastUpdated => 1101773588
},
'25' => {
message => q|Any user|,
lastUpdated => 1066766053
},
'6' => {
message => q|Search through|,
lastUpdated => 1066252264
},
'28' => {
message => q|
<P>This is the list of template variables available for
search templates:</P>
<P><STRONG>query</STRONG><BR>
Contains the value of the <EM>query</EM> form
variable. <BR>The <EM>allWords</EM>, <EM>atLeastOne</EM>, <EM>exactPhrase</EM>
and <EM>without</EM> values are appended to this variable.</P>
<P><STRONG>queryHighlighted</STRONG><BR>
Same as <STRONG>query</STRONG> but highlighted.</P>
<P><STRONG>allWords</STRONG><BR>
Contains the value of the <EM>allWords</EM> form variable.</P>
<P><STRONG>atLeastOne</STRONG><BR>
Contains the value of the <EM>atLeastOne</EM> form variable.</P>
<P><STRONG>exactPhrase</STRONG><BR>
Contains the value of the <EM>exactPhrase</EM> form variable.</P>
<P><STRONG>without</STRONG><BR>
Contains the value of the <EM>without</EM> form variable.</P>
<P><STRONG>duration</STRONG><BR>
The duration of the search process in seconds.</P>
<P><STRONG>numberOfResults</STRONG><BR>
The number of results.</P>
<P><STRONG>startNr</STRONG><BR>
The number of the first search result on the page.</P>
<P><STRONG>endNr</STRONG><BR>
The number of the last search result on the page.</P>
<P><STRONG>submit</STRONG><BR>
A form button with the word "Search" printed on it.</P>
<P><STRONG>wid</STRONG><BR>
The wobject Id of this wobject.</P>
<P><STRONG>resultsLoop</STRONG><BR>
A loop containing the search results. Inside the loop the following template variables are available:</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P><STRONG>username</STRONG><BR>
The username of the person that created this search result.</P>
<P><STRONG>ownerId</STRONG><BR>
The Id of the person that created this search result.</P>
<P><STRONG>userProfile</STRONG><BR>
An url to the profile of the creator of this search result.</P>
<P><STRONG>header</STRONG><BR>The title of the search result. (This can be the
subject of a message, the question of a FAQ, the title of an Article, etc)</P>
<P><STRONG>body</STRONG><BR>A preview of the content of the search result.</P>
<P><STRONG>namespace</STRONG><BR>The namespace in which this search result
resides.</P>
<P><STRONG>location</STRONG><BR>The URL of this search result.</P>
<P><STRONG>crumbtrail</STRONG><BR>A crumbtrail to this search result.</P>
<P><STRONG>contentType</STRONG><BR>The type of this search
result.</P></BLOCKQUOTE>
<P dir=ltr>The loops <STRONG>contentTypes</STRONG>,
<STRONG>contentTypesSimple</STRONG>, <STRONG>languages</STRONG>,
<STRONG>namespaces</STRONG> and <STRONG>users</STRONG> all look the same.
They can be used to create a select list, radio list or check list so users can
refine their search.</P>
<P dir=ltr>This template variables are available inside the loops:</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P dir=ltr><STRONG>name</STRONG><BR>The (possibly internationalized) name of the
option.<BR><BR><STRONG>value<BR></STRONG>The value of the
option.<BR><BR><STRONG>selected<BR></STRONG>A conditional indicating whether
this option is selected or not.</P></BLOCKQUOTE>
<P dir=ltr><B>searchRoots</B><BR>A loop containing the available roots to search through.
<BLOCKQUOTE dir=ltr><P dir=ltr>
<b>title</b><br>The title of the pageroot.<br><br>
<b>urlizedTitle</b><br>The urlizedTitle of the pageroot.<br><br>
<b>menuTitle</b><br>The menu title of the pageroot.<br><br>
<b>value</b><br>The value you should pass as a form param.<br><br>
<b>checked</b><br>True if this pageroot is selected.<br><br>
</p></blockquote>
<p dir=ltr><b>rootPage.<i>urlizedTitle</i>.id</b><br>
This is a direct link to the value property of the rootpage identified with <i>urlizedTitle</i> that is also given by the value property of the <B>searchRoots</B> loop.</p>
<p dir=ltr><b>rootPage.<i>urlizedTitle</i>.checked</b><br>
This is a direct link to the checked property of the rootpage identified with <i>urlizedTitle</i> that is also given by the checked property of the <B>searchRoots</B> loop.</p>
<P><B>firstPage</B><BR>A link to the first page in the paginator.
<P><B>lastPage</B><BR>A link to the last page in the paginator.
<P><B>nextPage</B><BR>A link to the next page forward in the paginator.
<P><B>previousPage</B><BR>A link to the next page backward in the paginator.
<P><B>pageList</B><BR>A list of links to all the pages in the paginator.
<P><B>multiplePages</B><BR>A conditional indicating whether there is more than
one page in the paginator.
<P><B>isFirstPage</B><BR>A conditional indicating whether the visitor is viewing
the first page.
<P><B>isLastPage</B><BR>A conditional indicating whether the visitor is viewing
the last page.</P>|,
lastUpdated => 1101773812
},
'3' => {
message => q|Please refer to the documentation for more info.|,
lastUpdated => 1066252166
},
'9' => {
message => q|Only results in language|,
lastUpdated => 1066252363
},
'12' => {
message => q|Context preview length|,
lastUpdated => 1066252463
},
'15' => {
message => q|All pages|,
lastUpdated => 1066253116
},
'14' => {
message => q|Highlight color|,
lastUpdated => 1066252536
},
'20' => {
message => q|Wobject details|,
lastUpdated => 1066765556
},
'8' => {
message => q|Only results in namespace|,
lastUpdated => 1066252344
},
'4' => {
message => q|This page|,
lastUpdated => 1066252218
},
'24' => {
message => q|Any language|,
lastUpdated => 1066766053
},
'force search roots' => {
message => q|Force users to use the selected roots|,
lastUpdated => 1133844716
},
'19' => {
message => q|Wobject|,
lastUpdated => 1066765495
},
'10' => {
message => q|Only results of type|,
lastUpdated => 1066252387
},
'5' => {
message => q|Index to use|,
lastUpdated => 1066252241
},
'page' => {
message => q|Page|,
lastUpdated => 1109789907,
},
'discussion' => {
message => q|Discussion|,
lastUpdated => 1109789911,
},
};
1;

View file

@ -1,111 +0,0 @@
package Hourly::IndexedSearch_buildIndex;
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2004 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 DBI;
use strict;
use WebGUI::DateTime;
use WebGUI::Session;
use WebGUI::Utility;
use WebGUI::SQL;
use WebGUI::URL;
use WebGUI::Asset::Wobject::IndexedSearch::Search;
#-------------------------------------------------------------------
sub process {
#disabled until 6.8
return "";
my $indexName = 'IndexedSearch_default';
my $htmlFilter = 'all';
my $stopList = 'none';
my $stemmer = 'none';
my $backend = 'phrase';
my $verbose = shift;
my ($dateIndexed) = WebGUI::SQL->quickArray("select max(dateIndexed) from IndexedSearch_docInfo where indexName = ".quote($indexName));
if (WebGUI::DateTime::time()-$dateIndexed < 86400) {
print " - Recently Indexed: Skipping " if ($verbose);
return "";
}
print "\n";
undef $stopList if ($stopList eq 'none');
undef $stemmer if ($stemmer eq 'none');
my $indexInfo = getIndexerParams();
my $search = WebGUI::Asset::Wobject::IndexedSearch::Search->new($indexName);
$search->recreate('','',stemmer => $stemmer, stoplist => $stopList, backend => $backend);
my $startTime = WebGUI::DateTime::time();
foreach my $asset (keys %{$indexInfo}) {
print "Doing: $asset\n"; # DEBUG
my $sth = WebGUI::SQL->read($indexInfo->{$asset}{sql});
my $total = $sth->rows;
my $actual = 1;
while (my %data = $sth->hash) {
if ($verbose) {
print "\r\t\tIndexing $asset data ($total items) ...".
(" " x (30 - (length($asset)) - length("$total"))).
int(($actual/$total)*100)." % ";
}
my $textToIndex = "";
foreach my $field (@{$indexInfo->{$asset}{fieldsToIndex}}) {
if($field =~ /^\s*select/i) {
my $sql = eval 'sprintf("%s","'.$field.'")';
$textToIndex .= join("\n", WebGUI::SQL->buildArray($sql));
} else {
$textToIndex .= $data{$field}."\n";
}
}
$textToIndex = WebGUI::HTML::filter($textToIndex,$htmlFilter);
my $url = eval $indexInfo->{$asset}{url};
my $headerShortcut = eval 'sprintf("%s","'.$indexInfo->{$asset}{headerShortcut}.'")';
my $bodyShortcut = eval 'sprintf("%s","'.$indexInfo->{$asset}{bodyShortcut}.'")';
$search->indexDocument({
text => $textToIndex,
assetId => $data{assetId},
groupIdView => $data{groupIdView},
special_groupIdView => $data{special_groupIdView},
namespace => $asset,
location => $url,
headerShortcut => $headerShortcut,
bodyShortcut => $bodyShortcut,
contentType => $indexInfo->{$asset}{contentType},
ownerId => $data{ownerId}
});
$actual++;
}
print "\n" if ($verbose && $total);
}
print "\t\t".(($search->getDocId -1)." WebGUI items indexed in ".(time() - $startTime)." seconds.\n\t") if ($verbose);
$search->close;
}
#-------------------------------------------------------------------
sub getIndexerParams {
my $now = WebGUI::DateTime::time();
# don't add indexer parameters here. Rather edit the corresponding file in WebGUI/Asset/Wobject/*.pm
my %params;
foreach my $class (@{$session{config}{assets}}) {
my $load = 'use '.$class;
eval($load);
if ($@) {
WebGUI::ErrorHandler::warn("Couldn't compile ".$class." because ".$@);
} else {
my $assetIndexParams = eval{$class->getIndexerParams($now)};
if (ref $assetIndexParams eq 'HASH') {
%params = (%params, %{$assetIndexParams});
}
}
}
#use Data::Dumper ; die Dumper(\%params);
return \%params;
}
1;