fixed: Server side spellchecker doesn't work
This commit is contained in:
parent
26cc8ad9df
commit
2b8d9a7b48
9 changed files with 559 additions and 154 deletions
|
|
@ -20,9 +20,6 @@ use WebGUI::Form;
|
|||
use WebGUI::Utility;
|
||||
use WebGUI::International;
|
||||
use JSON;
|
||||
BEGIN {
|
||||
eval { require Text::Aspell }; # Optional
|
||||
}
|
||||
|
||||
our @ISA = qw(WebGUI::Asset);
|
||||
|
||||
|
|
@ -494,7 +491,9 @@ sub getRichEditor {
|
|||
);
|
||||
foreach my $button (@toolbarButtons) {
|
||||
if ($button eq "spellchecker" && $self->session->config->get('availableDictionaries')) {
|
||||
push(@plugins,"spellchecker");
|
||||
push(@plugins,"-wgspellchecker");
|
||||
$loadPlugins{wgspellchecker} = $self->session->url->extras("tinymce-webgui/plugins/wgspellchecker/editor_plugin.js");
|
||||
$config{spellchecker_rpc_url} = $self->session->url->gateway('', "op=spellCheck");
|
||||
$config{spellchecker_languages} =
|
||||
join(',', map { ($_->{default} ? '+' : '').$_->{name}.'='.$_->{id} } @{$self->session->config->get('availableDictionaries')});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,21 @@ package WebGUI::Operation::SpellCheck;
|
|||
#-------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
use Encode;
|
||||
# Optional, but if unavailable, spell checking will have no effect.
|
||||
eval 'use Text::Aspell';
|
||||
use WebGUI::Utility;
|
||||
use File::Path qw(mkpath);
|
||||
# Optional, but if unavailable, spell checking will have no effect.
|
||||
my $spellerAvailable;
|
||||
BEGIN {
|
||||
eval {
|
||||
require Text::Aspell;
|
||||
};
|
||||
$spellerAvailable = 1
|
||||
unless $@;
|
||||
};
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Operation::Spellcheck
|
||||
Package WebGUI::Operation::SpellCheck
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
|
@ -28,7 +35,7 @@ Operation for server side spellchecking functions.
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 _getSpeller ( session )
|
||||
=head2 _getSpeller ( session , language )
|
||||
|
||||
Returns an instanciated Text::Aspell object.
|
||||
|
||||
|
|
@ -36,99 +43,145 @@ Returns an instanciated Text::Aspell object.
|
|||
|
||||
An instanciated session object.
|
||||
|
||||
=head3 language
|
||||
|
||||
The language code to use for spell checking.
|
||||
|
||||
=cut
|
||||
|
||||
sub _getSpeller {
|
||||
my ($baseDir, $userDir, $homeDir);
|
||||
my $session = shift;
|
||||
return undef unless Text::Aspell->can('new');
|
||||
my $speller = Text::Aspell->new;
|
||||
my $session = shift;
|
||||
my $lang = shift;
|
||||
die "Server side spellcheck not available\n"
|
||||
unless $spellerAvailable;
|
||||
# Get language
|
||||
my $speller = Text::Aspell->new;
|
||||
die "Language not available in server side spellcheck"
|
||||
unless (isIn($lang, map {m/^.*?:([^:]*):.*?$/} $speller->list_dictionaries));
|
||||
|
||||
# Get language
|
||||
my $lang = $session->form->process('lang');
|
||||
return undef unless (isIn($lang, map {m/^.*?:([^:]*):.*?$/} $speller->list_dictionaries));
|
||||
# User homedir
|
||||
my $homeDir = $session->config->get('uploadsPath').'/dictionaries/';
|
||||
|
||||
# User homedir
|
||||
my $userId = $session->user->userId;
|
||||
my $userId = $session->user->userId;
|
||||
if (length($userId) < 22) {
|
||||
$homeDir .= "oldIds/$userId";
|
||||
}
|
||||
else {
|
||||
$userId =~ m/^(.{2})(.{2})/;
|
||||
$homeDir .= "$1/$2/$userId";
|
||||
}
|
||||
mkpath($homeDir) unless (-e $homeDir);
|
||||
|
||||
$baseDir = $session->config->get('uploadsPath').'/dictionaries/';
|
||||
|
||||
if (length($userId) < 22) {
|
||||
$userDir = 'oldIds/'.$userId;
|
||||
|
||||
mkdir($baseDir.$userDir) unless (-e $baseDir.$userDir);
|
||||
} else {
|
||||
$userDir = $userId;
|
||||
$userDir =~ s/^(.{2})(.{2})*$/$1\/$2\/$userId/;
|
||||
|
||||
mkdir($baseDir.$1) unless (-e $baseDir.$1);
|
||||
mkdir($baseDir.$1.'/'.$2) unless (-e $baseDir.$1.'/'.$2);
|
||||
}
|
||||
|
||||
$homeDir = $baseDir.$userDir;
|
||||
|
||||
mkdir($homeDir) unless (-e $homeDir);
|
||||
|
||||
# Set speller options.
|
||||
$speller->set_option('home-dir', $homeDir);
|
||||
$speller->set_option('lang', $lang);
|
||||
|
||||
return $speller;
|
||||
# Set speller options.
|
||||
$speller->set_option('home-dir', $homeDir);
|
||||
$speller->set_option('lang', $lang);
|
||||
return $speller;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 _processOutput ( session, words, [ id, [ command ] ] )
|
||||
=head2 addWord ( $session, $language, $word )
|
||||
|
||||
Processes the wordlist and generates an XML string that the TinyMCE spellchecker
|
||||
plugin can grok.
|
||||
Adds a word sent by the tinymce spellchecker plugin to the personal dictionary
|
||||
of the the current user.
|
||||
|
||||
=head3 session
|
||||
=head3 $session
|
||||
|
||||
The instanciated session object.
|
||||
The instanciated session object
|
||||
|
||||
=head3 words
|
||||
=head3 $language
|
||||
|
||||
An arrayref containing the words that you want to send back to the spellchecker
|
||||
plugin.
|
||||
The dictionary language to use.
|
||||
|
||||
=head3 id
|
||||
=head3 $word
|
||||
|
||||
The id that the tinyMCE spellchecker plugin assigined to this specific action.
|
||||
If not specified the value of the formparam 'id' will be sent.
|
||||
|
||||
=head3 command
|
||||
|
||||
The spellchecker plugin command that has been issued. If omitted the value of
|
||||
formparam 'cmd' will be used.
|
||||
The word to add to the dictionary.
|
||||
|
||||
=cut
|
||||
|
||||
sub _processOutput {
|
||||
my $session = shift;
|
||||
my $words = shift || [];
|
||||
my $id = shift || $session->form->process('id');
|
||||
my $command = shift || $session->form->process('cmd');
|
||||
|
||||
$session->http->setMimeType('text/xml; charset=utf-8');
|
||||
my $output = '<?xml version="1.0" encoding="utf-8" ?>'."\n";
|
||||
sub addWord {
|
||||
my $session = shift;
|
||||
my $language = shift;
|
||||
my $word = shift;
|
||||
die "You must be logged in to add words to your dictionary.\n:"
|
||||
if ($session->user->userId eq '1');
|
||||
my $speller = _getSpeller($session, $language);
|
||||
$speller->add_to_personal($word);
|
||||
$speller->save_all_word_lists;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (scalar(@$words) == 0) {
|
||||
$output .= '<res id="'.$id.'" cmd="'.$command.'"></res>';
|
||||
}
|
||||
else {
|
||||
$output .= '<res id="'.$id.'" cmd="'.$command.'">'.encode_utf8(join(" ", @$words)).'</res>';
|
||||
}
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
return $output;
|
||||
=head2 checkWords ( $session, $language, \@words )
|
||||
|
||||
Check the spelling on a list of words and returns a list of misspelled words as an array reference
|
||||
|
||||
=head3 $session
|
||||
|
||||
The instanciated session object
|
||||
|
||||
=head3 $language
|
||||
|
||||
The dictionary language to use.
|
||||
|
||||
=head3 \@word
|
||||
|
||||
The words to check the spelling of as an array reference.
|
||||
|
||||
=cut
|
||||
|
||||
sub checkWords {
|
||||
my $session = shift;
|
||||
my $language = shift;
|
||||
my $words = shift;
|
||||
my $speller = _getSpeller($session, $language);
|
||||
my @result;
|
||||
foreach my $word (@$words) {
|
||||
unless ($speller->check($word)) {
|
||||
push(@result, $word);
|
||||
}
|
||||
}
|
||||
return \@result;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getSuggestions ( $session, $language, $word )
|
||||
|
||||
Returns a list of suggested words for a misspelled word sent by the
|
||||
tinyMCE spellchecker as an array reference.
|
||||
|
||||
=head3 $session
|
||||
|
||||
The instanciated session object.
|
||||
|
||||
=head3 $language
|
||||
|
||||
The dictionary language to use.
|
||||
|
||||
=head3 $word
|
||||
|
||||
The misspelled word to get suggestions for.
|
||||
|
||||
=cut
|
||||
|
||||
sub getSuggestions {
|
||||
my $session = shift;
|
||||
my $language = shift;
|
||||
my $word = shift;
|
||||
my $speller = _getSpeller($session, $language);
|
||||
my @result = $speller->suggest($word);
|
||||
return \@result;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_spellCheck ( session )
|
||||
|
||||
Fetches the the text to be checked as sent by the tinyMCE spellchecker and
|
||||
returns a list of erroneous words in the correct XML format.
|
||||
Fetches the JSON data sent by the TinyMCE spell checker and dispatches
|
||||
to the correct sub to handle each request type. Encodes the result
|
||||
as a JSON string to be sent back to the client.
|
||||
|
||||
=head3 session
|
||||
|
||||
|
|
@ -137,87 +190,37 @@ The instanciated session object.
|
|||
=cut
|
||||
|
||||
sub www_spellCheck {
|
||||
my $session = shift;
|
||||
my (@result, $output);
|
||||
my $session = shift;
|
||||
# JSON data is sent directly as POST data, read it into a scalar then decode
|
||||
my $data = '';
|
||||
while ($session->request->read(my $buffer, 1024)) {
|
||||
$data .= $buffer;
|
||||
}
|
||||
my $params = JSON->new->utf8->decode($data);
|
||||
|
||||
my $speller = _getSpeller($session);
|
||||
return _processOutput($session) unless (defined($speller));
|
||||
|
||||
# Set speller options?
|
||||
|
||||
# Get form params
|
||||
my $check = $session->form->process('check');
|
||||
my $command = $session->form->process('cmd');
|
||||
my $language = $session->form->process('lang');
|
||||
my $mode = $session->form->process('mode');
|
||||
my $id = $session->form->process('id');
|
||||
|
||||
# Check it!
|
||||
my @words = split(/\s/, $check);
|
||||
|
||||
foreach my $word (@words) {
|
||||
unless ($speller->check($word)) {
|
||||
push(@result, $word);
|
||||
}
|
||||
}
|
||||
|
||||
return _processOutput($session, \@result);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_suggestWords ( session )
|
||||
|
||||
Returns a list of suggested words in the correct XML format for a misspelled
|
||||
word sent by the tinyMCE spellchecker.
|
||||
|
||||
=head3 session
|
||||
|
||||
The instanciated session object.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_suggestWords {
|
||||
my $session = shift;
|
||||
|
||||
my $speller = _getSpeller($session);
|
||||
return _processOutput($session) unless (defined($speller));
|
||||
my $check = $session->form->process('check');
|
||||
|
||||
my @result = $speller->suggest($check);
|
||||
|
||||
return _processOutput($session, \@result);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_addWordToDictionary ( session )
|
||||
|
||||
Adds a word sent by the tinymce spellchecker plugin to the personal dictionary
|
||||
of the the current user.
|
||||
|
||||
=head3 session
|
||||
|
||||
The instanciated session object
|
||||
|
||||
=cut
|
||||
|
||||
sub www_addWordToDictionary {
|
||||
my $session = shift;
|
||||
|
||||
# Visitors do not have a personal dictionary
|
||||
return _processOutput($session, ['You must be logged in to add words to your dictionary.']) if ($session->user->userId eq '1');
|
||||
|
||||
my $speller = _getSpeller($session);
|
||||
return _processOutput($session) unless (defined($speller));
|
||||
my $check = $session->form->process('check');
|
||||
|
||||
if ($check) {
|
||||
$speller->add_to_personal($check);
|
||||
$speller->save_all_word_lists;
|
||||
}
|
||||
|
||||
return _processOutput($session);
|
||||
my $result;
|
||||
# dispatch to different subs based on the 'method' in the JSON data
|
||||
my %dispatch = (
|
||||
checkWords => \&checkWords,
|
||||
getSuggestions => \&getSuggestions,
|
||||
addWord => \&addWord,
|
||||
);
|
||||
if (exists $dispatch{$params->{method}}) {
|
||||
eval {
|
||||
# get results from sub and build result data
|
||||
$result = { result => $dispatch{$params->{method}}->($session, @{ $params->{params} }) };
|
||||
};
|
||||
if ($@) {
|
||||
$result = {error => {errstr => $@}};
|
||||
}
|
||||
}
|
||||
else {
|
||||
$result = {error => {errstr => "Invalid request"}};
|
||||
}
|
||||
# add request id and send to client as JSON blob
|
||||
$result->{id} = $params->{id};
|
||||
$session->http->setMimeType("text/plain; charset=utf-8");
|
||||
return JSON->new->encode($result);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue