From ff0299c9feeeb22d8ceeae4219bd6293605fe190 Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phane=20Jacob?= Date: Mon, 14 Mar 2011 11:10:42 +0100 Subject: [PATCH] Adds tool to search in nl archives (Closes #664). MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Jacob --- ChangeLog | 1 + include/newsletter.inc.php | 62 ++++++++++++++++++++++++++++++++ modules/axletter.php | 1 + modules/epletter.php | 1 + modules/newsletter.php | 50 ++++++++++++++++++++++++++ modules/xnetnl.php | 1 + templates/newsletter/index.tpl | 2 ++ templates/newsletter/search.tpl | 79 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 197 insertions(+) create mode 100644 templates/newsletter/search.tpl diff --git a/ChangeLog b/ChangeLog index 8d90d6c..db63ff6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,7 @@ Bug/Wish: - #1404: Implements best_domain -JAC * Newsletter: + - #664: Adds tool to search in nl archives -JAC - #908: Displays remaining lines and characters in submission -JAC * Payments: diff --git a/include/newsletter.inc.php b/include/newsletter.inc.php index 0ee1423..7675813 100644 --- a/include/newsletter.inc.php +++ b/include/newsletter.inc.php @@ -47,6 +47,11 @@ class NewsLetter const GROUP_AX = 'AX'; const GROUP_EP = 'Ecole'; + // Searches on mutiple fields + const SEARCH_ALL = 'all'; + const SEARCH_TITLE = 'title'; + + // {{{ Constructor, NewsLetter retrieval (forGroup, getAll) public function __construct($id) @@ -251,6 +256,63 @@ class NewsLetter } } + /** Returns a list of either issues or articles corresponding to the search. + * @p $search The searched pattern. + * @p $field The fields where to search, if none given, search in all possible fields. + * @return The list of object found. + */ + public function issueSearch($search, $field, $user) + { + $search = XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $search); + if ($field == self::SEARCH_ALL) { + $where = '(title ' . $search . ' OR mail_title ' . $search . ' OR head ' . $search . ' OR signature ' . $search . ')'; + } elseif ($field == self::SEARCH_TITLE) { + $where = '(title ' . $search . ' OR mail_title ' . $search . ')'; + } else { + $where = $field . $search; + } + $list = XDB::fetchColumn('SELECT DISTINCT(id) + FROM newsletter_issues + WHERE nlid = {?} AND state = \'sent\' AND ' . $where . ' + ORDER BY date DESC', + $this->id); + + $issues = array(); + foreach ($list as $id) { + $issue = new NLIssue($id, $this, false); + if ($issue->checkUser($user)) { + $issues[] = $issue; + } + } + return $issues; + } + + public function articleSearch($search, $field, $user) + { + $search = XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $search); + if ($field == self::SEARCH_ALL) { + $where = '(a.title ' . $search . ' OR a.body ' . $search . ' OR a.append ' . $search . ')'; + } else { + $where = 'a.' . $field . $search; + } + $list = XDB::fetchAllAssoc('SELECT i.short_name, a.aid, i.id, a.title + FROM newsletter_art AS a + INNER JOIN newsletter_issues AS i ON (a.id = i.id) + WHERE i.nlid = {?} AND i.state = \'sent\' AND ' . $where . ' + GROUP BY a.id, a.aid + ORDER BY i.date DESC, a.aid', + $this->id); + + $articles = array(); + foreach ($list as $item) { + $issue = new NLIssue($item['id'], $this, false); + if ($issue->checkUser($user)) { + $articles[] = $item; + } + } + return $articles; + } + // }}} // {{{ Subscription related function diff --git a/modules/axletter.php b/modules/axletter.php index 9ffb0e3..99d45ad 100644 --- a/modules/axletter.php +++ b/modules/axletter.php @@ -29,6 +29,7 @@ class AXLetterModule extends NewsletterModule 'ax' => $this->make_hook('nl', AUTH_COOKIE), 'ax/out' => $this->make_hook('out', AUTH_PUBLIC), 'ax/show' => $this->make_hook('nl_show', AUTH_COOKIE), + 'ax/search' => $this->make_hook('nl_search', AUTH_COOKIE), 'ax/admin' => $this->make_hook('admin_nl', AUTH_MDP), 'ax/admin/edit' => $this->make_hook('admin_nl_edit', AUTH_MDP), 'ax/admin/edit/valid' => $this->make_hook('admin_nl_valid', AUTH_MDP), diff --git a/modules/epletter.php b/modules/epletter.php index 285242e..af633f8 100644 --- a/modules/epletter.php +++ b/modules/epletter.php @@ -29,6 +29,7 @@ class EPLetterModule extends NewsletterModule 'epletter' => $this->make_hook('nl', AUTH_COOKIE), 'epletter/out' => $this->make_hook('out', AUTH_PUBLIC), 'epletter/show' => $this->make_hook('nl_show', AUTH_COOKIE), + 'epletter/search' => $this->make_hook('nl_search', AUTH_COOKIE), 'epletter/admin' => $this->make_hook('admin_nl', AUTH_MDP), 'epletter/admin/edit' => $this->make_hook('admin_nl_edit', AUTH_MDP), 'epletter/admin/edit/valid' => $this->make_hook('admin_nl_valid', AUTH_MDP), diff --git a/modules/newsletter.php b/modules/newsletter.php index 632f375..7691cae 100644 --- a/modules/newsletter.php +++ b/modules/newsletter.php @@ -26,6 +26,7 @@ class NewsletterModule extends PLModule return array( 'nl' => $this->make_hook('nl', AUTH_COOKIE), 'nl/show' => $this->make_hook('nl_show', AUTH_COOKIE), + 'nl/search' => $this->make_hook('nl_search', AUTH_COOKIE), 'nl/submit' => $this->make_hook('nl_submit', AUTH_MDP), 'nl/remaining' => $this->make_hook('nl_remaining', AUTH_MDP), 'admin/nls' => $this->make_hook('admin_nl_groups', AUTH_MDP, 'admin'), @@ -92,6 +93,55 @@ class NewsletterModule extends PLModule } } + function handler_nl_search($page) + { + S::assert_xsrf_token(); + $nl = $this->getNl(); + if (!$nl) { + return PL_NOT_FOUND; + } + + if (!Post::has('nl_search')) { + pl_redirect($nl->prefix()); + } + + $nl_search = Post::t('nl_search'); + $nl_search_type = Post::t('nl_search_type'); + if (!$nl_search || !($nl_search_type > 0 && $nl_search_type < 10)) { + $page->trigErrorRedirect('La recherche est vide ou erronée.', $nl->prefix()); + } + + $page->changeTpl('newsletter/search.tpl'); + $user = S::user(); + $fields = array(1 => 'all', 2 => 'all', 3 => 'title', 4 => 'body', 5 => 'append', 6 => 'all', 7 => 'title', 8 => 'head', 9 => 'signature'); + $res_articles = $res_issues = array(); + if ($nl_search_type < 6) { + $res_articles = $nl->articleSearch($nl_search, $fields[$nl_search_type], $user); + } + if ($nl_search_type > 5 || $nl_search_type == 1) { + $res_issues = $nl->issueSearch($nl_search, $fields[$nl_search_type], $user); + } + + $articles_count = count($res_articles); + $issues_count = count($res_issues); + $results_count = $articles_count + $issues_count; + if ($results_count > 200) { + $page->trigError('Recherche trop générale.'); + } elseif ($results_count == 0) { + $page->trigWarning('Aucun résultat pour cette recherche.'); + } else { + $page->assign('res_articles', $res_articles); + $page->assign('res_issues', $res_issues); + $page->assign('articles_count', $articles_count); + $page->assign('issues_count', $issues_count); + } + + $page->assign_by_ref('nl', $nl); + $page->assign('nl_search', $nl_search); + $page->assign('nl_search_type', $nl_search_type); + $page->assign('results_count', $results_count); + } + function handler_nl_submit($page) { $page->changeTpl('newsletter/submit.tpl'); diff --git a/modules/xnetnl.php b/modules/xnetnl.php index aa769be..a5a25ed 100644 --- a/modules/xnetnl.php +++ b/modules/xnetnl.php @@ -28,6 +28,7 @@ class XnetNlModule extends NewsletterModule return array( '%grp/nl' => $this->make_hook('nl', AUTH_MDP), '%grp/nl/show' => $this->make_hook('nl_show', AUTH_MDP), + '%grp/nl/search' => $this->make_hook('nl_search', AUTH_MDP), '%grp/admin/nl' => $this->make_hook('admin_nl', AUTH_MDP, 'groupadmin'), '%grp/admin/nl/edit' => $this->make_hook('admin_nl_edit', AUTH_MDP, 'groupadmin'), '%grp/admin/nl/edit/cancel' => $this->make_hook('admin_nl_cancel', AUTH_MDP, 'groupadmin'), diff --git a/templates/newsletter/index.tpl b/templates/newsletter/index.tpl index 1978e44..990722c 100644 --- a/templates/newsletter/index.tpl +++ b/templates/newsletter/index.tpl @@ -52,6 +52,8 @@ Tu n'es actuellement pas inscrit à la {$nl->name}. {/if} +{include file="newsletter/search.tpl" nl_search_type="1" nl_search=""} +

Les archives

diff --git a/templates/newsletter/search.tpl b/templates/newsletter/search.tpl new file mode 100644 index 0000000..445f7d7 --- /dev/null +++ b/templates/newsletter/search.tpl @@ -0,0 +1,79 @@ +{**************************************************************************} +{* *} +{* Copyright (C) 2003-2011 Polytechnique.org *} +{* http://opensource.polytechnique.org/ *} +{* *} +{* This program is free software; you can redistribute it and/or modify *} +{* it under the terms of the GNU General Public License as published by *} +{* the Free Software Foundation; either version 2 of the License, or *} +{* (at your option) any later version. *} +{* *} +{* This program is distributed in the hope that it will be useful, *} +{* but WITHOUT ANY WARRANTY; without even the implied warranty of *} +{* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *} +{* GNU General Public License for more details. *} +{* *} +{* You should have received a copy of the GNU General Public License *} +{* along with this program; if not, write to the Free Software *} +{* Foundation, Inc., *} +{* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *} +{* *} +{**************************************************************************} + +{if $nl_search} +

+ {$nl->name} +

+{/if} + +

Rechercher dans les archives

+ + + {xsrf_token_field} +

+ + +

+

+ + +{if $nl_search} +

{$results_count} résultat{if $results_count > 1}s{/if} pour cette recherche

+ +{if t($res_articles) && $res_articles|@count} +{$articles_count} article{if $articles_count > 1}s{/if} correspondant{if $articles_count > 1}s{/if} : + +{/if} + +{if t($res_issues) && $res_issues|@count} +{$issues_count} lettre{if $issues_count > 1}s{/if} correspondate{if $issues_count > 1}s{/if} : + +{/if} + +{/if} + +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *} -- 2.1.4