This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".

The branch, master has been updated
       via  5c72dbf32036283ecec72556f919f95dd61d3cbb (commit)
      from  4fdc095972d45b03a5a1576bdfda1db299fc38aa (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=5c72dbf32036283ecec72556f919f95dd61d3cbb

commit 5c72dbf32036283ecec72556f919f95dd61d3cbb
Author: Franck Villaume <[email protected]>
Date:   Wed Dec 9 23:14:56 2015 +0100

    docman: switch limit result set to paging system. switch search engine to 
common search engine and remove specific docman search engine

diff --git a/src/CHANGES b/src/CHANGES
index 7925ec9..4758c0e 100644
--- a/src/CHANGES
+++ b/src/CHANGES
@@ -2,8 +2,9 @@ FusionForge 6.X:
 * Accounts: minimum password length is now 8
 * Spellcheck (Anders Jonsson)
 * Site Admin: add paging system in userlist page [#799] (TrivialDev)
-* Docman: limit number of returned documents on search query [#794] 
(TrivialDev)
+* Docman: limit number of returned documents on search query. Use paging 
system [#794] (TrivialDev)
 * Docman: limit search using from & to dates [#798] (TrivialDev)
+* Docman: use standard search engine: unify results between 'search in 
project' & search in the docs tab (TrivialDev)
 * Plugin AuthBuiltin: add captcha after 3 attempts with the same login [#795] 
(TrivialDev)
 
 FusionForge 6.0.4:
diff --git a/src/common/docman/views/search.php 
b/src/common/docman/views/search.php
index 8b6548b..2efe35c 100644
--- a/src/common/docman/views/search.php
+++ b/src/common/docman/views/search.php
@@ -34,16 +34,16 @@ global $dirid; // id of doc_group
 global $HTML; // Layout object
 global $warning_msg;
 
+$redirect_url = '/docman/?group_id='.$group_id;
 if (!forge_check_perm('docman', $group_id, 'read')) {
        $warning_msg = _('Document Manager Access Denied');
-       session_redirect('/docman/?group_id='.$group_id);
+       session_redirect($redirect_url);
 }
 
 $is_editor = forge_check_perm('docman', $g->getID(), 'approve');
-$searchString = trim(getStringFromPost('textsearch'));
+$searchString = trim(getStringFromPost('textsearch', null));
 $insideDocuments = getStringFromPost('insideDocuments');
 $subprojectsIncluded = getStringFromPost('includesubprojects');
-$limitNbSearchDocs = getStringFromPost('limitNbSearchDocs');
 $limitByStartDate = getIntFromPost('limitByStartDate', 0);
 $limitByEndDate = getIntFromPost('limitByEndDate', 0);
 $received_begin = getStringFromRequest('start_date', 0);
@@ -51,8 +51,8 @@ $received_end = getStringFromRequest('end_date', 0);
 $allchecked = '';
 $onechecked = '';
 $insideDocumentsCheckbox = '';
-$attrsInputSearchAll = array('type' => 'radio', 'name' => 'search_type', 
'required' => 'required', 'value' => 'all', 'title' => _('All searched words 
are mandatory'));
-$attrsInputSearchOne = array('type' => 'radio', 'name' => 'search_type', 
'required' => 'required', 'value' => 'one', 'title' => _('At least one word 
must be found'));
+$attrsInputSearchAll = array('type' => 'radio', 'name' => 'search_type', 
'required' => 'required', 'value' => 'all', 'title' => _('All searched words 
are mandatory.'));
+$attrsInputSearchOne = array('type' => 'radio', 'name' => 'search_type', 
'required' => 'required', 'value' => 'one', 'title' => _('At least one word 
must be found.'));
 $date_format_js = _('yy-mm-dd');
 $date_format = _('Y-m-d');
 
@@ -96,13 +96,13 @@ echo html_ao('div', array('id' => 
'docman_search_query_ckeckbox'));
 echo html_e('input', $attrsInputSearchAll)._('With all the words');
 echo html_e('input', $attrsInputSearchOne)._('With at least one of words');
 if ($g->useDocmanSearch()) {
-       $attrsInputInsideDocs = array('type' => 'checkbox', 'name'  => 
'insideDocuments', 'value' => 1, 'title' => _('Filename and contents are used 
to match searched words'));
+       $attrsInputInsideDocs = array('type' => 'checkbox', 'name'  => 
'insideDocuments', 'value' => 1, 'title' => _('Filename & contents are used to 
match searched words.'));
        if ($insideDocuments)
                $attrsInputInsideDocs['checked'] = 'checked';
        echo html_e('input', $attrsInputInsideDocs)._('Inside documents');
 }
 $attrsFieldSet = array('id' => 'fieldset1_closed', 'class' => 'coolfieldset');
-if ($limitByStartDate || $limitByEndDate || is_integer($limitNbSearchDocs)) {
+if ($limitByStartDate || $limitByEndDate || $subprojectsIncluded) {
        $attrsFieldSet['id'] = 'fieldset1';
 }
 echo html_ao('fieldset', $attrsFieldSet);
@@ -112,13 +112,12 @@ if ($g->usesPlugin('projects-hierarchy')) {
        $projectsHierarchy = plugin_get_object('projects-hierarchy');
        $projectIDsArray = $projectsHierarchy->getFamily($group_id, 'child', 
true, 'validated');
        if (is_array($projectIDsArray)) {
-               $attrsInputIncludeSubprojects = array('type' => 'checkbox', 
'name'  => 'includesubprojects', 'value' => 1, 'title' => _('search into childs 
following project hierarchy'));
+               $attrsInputIncludeSubprojects = array('type' => 'checkbox', 
'name'  => 'includesubprojects', 'value' => 1, 'title' => _('Search into childs 
following project hierarchy.'));
                if ($subprojectsIncluded)
                        $attrsInputIncludeSubprojects['checked'] = 'checked';
                echo html_e('p', array(), html_e('input', 
$attrsInputIncludeSubprojects)._('Include child projects'));
        }
 }
-echo html_e('p', array(), _('limit search results 
to').html_build_select_box_from_array(array(_('All'), '10', '25', '50', '100'), 
'limitNbSearchDocs', _('All'), 1)._('documents'));
 $attrsInputLimitByStartDate = array('type' => 'checkbox', 'id' => 
'limitByStartDate', 'name' => 'limitByStartDate', 'value' => 1, 'title' => 
_('Set created start date limitation for this search. If not enable, not 
limitation.'));
 $attrsDatePickerLimitByStartDate = array('id' => 'datepicker_start', 'name' => 
'start_date', 'size' => 10, 'maxlength' => 10, 'disabled' => 'disabled');
 if ($limitByStartDate) {
@@ -136,7 +135,7 @@ if ($limitByEndDate) {
        unset($attrsDatePickerLimitByEndDate['disabled']);
        $attrsDatePickerLimitByEndDate['required'] = 'required';
        if ($received_end) {
-               $attrsDatePickerLimitByStartDate['value'] = 
util_html_encode($received_end);
+               $attrsDatePickerLimitByEndDate['value'] = 
util_html_encode($received_end);
        }
 }
 echo html_e('p', array(), _('Set dates')._(': ').html_e('br').
@@ -147,110 +146,39 @@ echo $HTML->addRequiredFieldsInfoBox();
 echo $HTML->closeForm();
 echo html_ac(html_ap() - 1);
 echo html_ao('div', array('id' => 'docman_search_query_result'));
-if ($searchString) {
-       $mots = preg_split("/[\s,]+/",$searchString);
-       $qpa = db_construct_qpa(false, 'SELECT filename, filetype, docid, 
doc_data.stateid as stateid, doc_states.name as statename, title, description, 
createdate, updatedate, doc_group, group_id FROM doc_data, doc_states WHERE 
doc_data.stateid = doc_states.stateid');
-       if (getStringFromPost('search_type') == 'one') {
-               if (count($mots) > 0) {
-                       $qpa = db_construct_qpa($qpa, ' AND (FALSE');
-                       foreach ($mots as $mot) {
-                               $mot = strtolower($mot);
-                               $qpa = db_construct_qpa($qpa, ' OR title LIKE 
$1 OR description LIKE $1 ',
-                                                        array("%$mot%"));
-                               if ($insideDocuments)
-                                       $qpa = db_construct_qpa($qpa, ' OR 
data_words LIKE $1 ', array("%$mot%"));
-                       }
-                       $qpa = db_construct_qpa($qpa, ')');
-               }
-       } else {
-               // search_type = all
-               if (count($mots) > 0) {
-                       $qpa = db_construct_qpa($qpa, ' AND (TRUE');
-                       foreach ($mots as $mot) {
-                               $mot = strtolower($mot);
-                               $qpa = db_construct_qpa($qpa, ' AND (title LIKE 
$1 OR description LIKE $1 ',
-                                                       array("%$mot%"));
-                               if ($insideDocuments)
-                                       $qpa = db_construct_qpa($qpa, ' OR 
data_words LIKE $1 ', array("%$mot%"));
-                               $qpa = db_construct_qpa($qpa, ' ) ', array());
-                       }
-                       $qpa = db_construct_qpa($qpa, ')');
-               }
-       }
-
-       if (!$is_editor) {
-               $qpa = db_construct_qpa($qpa, ' AND doc_data.stateid = 1');
-       } else {
-               $qpa = db_construct_qpa($qpa, ' AND doc_data.stateid != 2');
-       }
-
-       $qpa = db_construct_qpa($qpa, ' AND ( group_id = $1', array($group_id));
-       $params['group_id'] = $group_id;
-       $params['qpa'] = &$qpa;
-       $params['includesubprojects'] = $subprojectsIncluded;
-       plugin_hook('docmansearch_has_hierarchy', $params);
-       $qpa = db_construct_qpa($qpa, ' ) ', array());
-       if ($received_begin) {
-               $arrDateBegin = DateTime::createFromFormat($date_format, 
$received_begin);
-       }
-       if ($received_end) {
-               $arrDateEnd = DateTime::createFromFormat($date_format, 
$received_end);
-       }
-
-       if (isset($arrDateBegin) && !isset($arrDateEnd)) {
-               $qpa = db_construct_qpa($qpa, ' AND doc_data.createdate >= $1', 
array($arrDateBegin->getTimestamp()));
-       } elseif (!isset($arrDateBegin) && isset($arrDateEnd)) {
-               $qpa = db_construct_qpa($qpa, ' AND doc_data.createdate <= $1', 
array($arrDateEnd->getTimestamp()));
-       } elseif (isset($arrDateBegin) && isset($arrDateEnd)) {
-               $qpa = db_construct_qpa($qpa, ' AND doc_data.createdate between 
$1 and $2', array($arrDateBegin->getTimestamp(), $arrDateEnd->getTimestamp()));
-       }
-
-       $qpa = db_construct_qpa($qpa, ' ORDER BY updatedate, createdate');
-       if (is_integer($limitNbSearchDocs)) {
-               $qpa = db_construct_qpa($qpa, ' LIMIT $1', 
array($limitNbSearchDocs));
-       }
+$search_options = array();
+if ($received_begin) {
+       $arrDateBegin = DateTime::createFromFormat($date_format, 
$received_begin);
+       $search_options['date_begin'] = $arrDateBegin->getTimestamp();
+}
+if ($received_end) {
+       $arrDateEnd = DateTime::createFromFormat($date_format, $received_end);
+       $search_options['date_end'] = $arrDateEnd->getTimestamp();
+}
+$search_options['includesubprojects'] = $subprojectsIncluded;
+$search_options['insideDocuments'] = $insideDocuments;
 
-       $result = db_query_qpa($qpa);
-       if (!$result) {
-               echo $HTML->error_msg(_('Database query error'));
-               db_free_result($result);
-       } elseif (db_numrows($result) < 1) {
-               echo $HTML->warning_msg(_('Your search did not match any 
documents.'));
-               db_free_result($result);
-       } else {
-               $resarr = array();
-               while ($arr = db_fetch_array($result)) {
-                       $resarr[] = $arr;
-               }
-               db_free_result($result);
-               $count = 0;
-               $tabletop = array(_('Order'), _('Document'), _('Description'), 
_('Status'), _('Path'));
-               $classth = array('', '', '', '', '');
-               echo $HTML->listTableTop($tabletop, false, 
'sortable_docman_searchfile', 'sortable', $classth);
-               foreach ($resarr as $item) {
-                       $cells = array();
-                       $count++;
-                       $cells[][] = html_e('strong', array(), $count, false);
-                       if ($item['filetype'] == 'URL') {
-                               $cells[][] = util_make_link($item["filename"], 
$item["title"], array(), true);
-                       } else {
-                               $cells[][] = 
util_make_link('/docman/view.php/'.$item["group_id"].'/'.$item["docid"].'/'.urlencode($item["filename"]),
 $item["filename"]).' ('.$item["title"].')';
-                       }
-                       $cells[][] = $item["description"];
-                       $localProject = group_get_object($item['group_id']);
-                       $docGroupObject = new DocumentGroup($localProject, 
$item['doc_group']);
-                       $cells[][] = $item["statename"];
-                       $nextcell = '';
-                       if ($localProject->getUnixName() != $g->getUnixName()) {
-                               $nextcell .= 
util_make_link('/docman/?group_id='.$localProject->getID(), 
$localProject->getPublicName(), array('title' => _('Browse document manager for 
this project.'))).'::';
-                       }
-                       $nextcell .= html_e('i', array(), 
$docGroupObject->getPath(true, true), false);
-                       $cells[][] = $nextcell;
-                       echo $HTML->multiTableRow(array(), $cells);
+if (session_loggedin()) {
+       if (getStringFromRequest('setpaging')) {
+               /* store paging preferences */
+               $paging = getIntFromRequest('nres');
+               if (!$paging) {
+                       $paging = 25;
                }
-               echo $HTML->listTableBottom();
+               $LUSER->setPreference('paging', $paging);
        }
-} elseif (getStringFromServer('REQUEST_METHOD') === 'POST') {
-       echo $HTML->warning_msg(_('Your search is empty.'));
+       /* logged in users get configurable paging */
+       $paging = $LUSER->getPreference('paging');
 }
+
+if(!isset($paging) || !$paging)
+       $paging = 25;
+
+$docsHtmlSearchRenderer = new DocsHtmlSearchRenderer($searchString, $start, 
getStringFromPost('search_type'), $group_id, SEARCH__ALL_SECTIONS, $paging, 
$search_options);
+$docsHtmlSearchRenderer->searchQuery->executeQuery();
+$nbDocs = $docsHtmlSearchRenderer->searchQuery->getRowsCount();
+$max = $docsHtmlSearchRenderer->searchQuery->getRowsTotalCount();
+echo $HTML->paging_top($start, $paging, $nbDocs, $max, 
$redirect_url.'&view=search');
+$docsHtmlSearchRenderer->writeBody();
+echo $HTML->paging_bottom($start, $paging, $nbDocs, 
$redirect_url.'&view=search');
 echo html_ac(html_ap() -2);
diff --git a/src/common/search/DocsSearchQuery.class.php 
b/src/common/search/DocsSearchQuery.class.php
index 5c9427b..24055bd 100644
--- a/src/common/search/DocsSearchQuery.class.php
+++ b/src/common/search/DocsSearchQuery.class.php
@@ -5,7 +5,7 @@
  * Copyright 2004, Dominik Haas
  * Copyright 2009, Roland Mas
  * Copyright (C) 2012 Alain Peyrat - Alcatel-Lucent
- * Copyright 2013, Franck Villaume - TrivialDev
+ * Copyright 2013,2015 Franck Villaume - TrivialDev
  * Copyright 2013, French Ministry of National Education
  * http://fusionforge.org
  *
@@ -47,18 +47,16 @@ class DocsSearchQuery extends SearchQuery {
         * Constructor
         *
         * @param       string  $words words we are searching for
-        * @param       int             $offset offset
+        * @param       int     $offset offset
         * @param       bool    $isExact if we want to search for all the words 
or if only one matching the query is sufficient
-        * @param       int             $groupId group id
+        * @param       int     $groupId group id
         * @param       string  $sections sections to search in
         * @param       bool    $showNonPublic flag if private sections are 
searched too
         */
-       function __construct($words, $offset, $isExact, $groupId, $sections = 
SEARCH__ALL_SECTIONS, $showNonPublic = false) {
+       function __construct($words, $offset, $isExact, $groupId, $sections = 
SEARCH__ALL_SECTIONS, $showNonPublic = false, $rowsPerPage = 
SEARCH__DEFAULT_ROWS_PER_PAGE, $options = array()) {
                $this->groupId = $groupId;
                $this->showNonPublic = $showNonPublic;
-
-               parent::__construct($words, $offset, $isExact);
-
+               parent::__construct($words, $offset, $isExact, $rowsPerPage, 
$options);
                $this->setSections($sections);
        }
 
@@ -71,8 +69,8 @@ class DocsSearchQuery extends SearchQuery {
                if (forge_get_config('use_fti')) {
                        return $this->getFTIQuery();
                } else {
-                       $qpa = db_construct_qpa() ;
-                       $qpa = db_construct_qpa($qpa,
+                       $options = $this->options;
+                       $qpa = db_construct_qpa(false,
                                                 'SELECT x.* FROM (SELECT 
doc_data.docid, doc_data.title, doc_data.filename, doc_data.description, 
doc_groups.groupname, title||$1||description AS full_string_agg FROM doc_data, 
doc_groups WHERE doc_data.doc_group = doc_groups.doc_group AND 
doc_data.group_id = $2',
                                                 array ($this->field_separator,
                                                        $this->groupId)) ;
@@ -86,6 +84,15 @@ class DocsSearchQuery extends SearchQuery {
                        } else {
                                $qpa = db_construct_qpa($qpa, ' AND 
doc_data.stateid = 1');
                        }
+
+                       if (isset($options['date_begin']) && 
!isset($options['date_end'])) {
+                               $qpa = db_construct_qpa($qpa, ' AND 
doc_data.createdate >= $1', array($options['date_begin']));
+                       } elseif (!isset($options['date_begin']) && 
isset($options['date_end'])) {
+                               $qpa = db_construct_qpa($qpa, ' AND 
doc_data.createdate <= $1', array($options['date_end']));
+                       } elseif (isset($options['date_begin']) && 
isset($options['date_end'])) {
+                               $qpa = db_construct_qpa($qpa, ' AND 
doc_data.createdate between $1 and $2', array($options['date_begin'], 
$$options['date_end']));
+                       }
+
                        $qpa = db_construct_qpa($qpa,
                                                 ') AS x WHERE ') ;
                        $qpa = $this->addIlikeCondition ($qpa, 
'full_string_agg') ;
@@ -97,17 +104,25 @@ class DocsSearchQuery extends SearchQuery {
 
        function getFTIQuery() {
                $words = $this->getFTIwords();
-               $group_id=$this->groupId;
-
-               $qpa = db_construct_qpa() ;
-
-               $qpa = db_construct_qpa($qpa,
-                                        'SELECT x.* FROM (SELECT 
doc_data.docid, doc_data.filename, ts_headline(doc_data.title, q) AS title, 
ts_headline(doc_data.description, q) AS description, doc_groups.groupname, 
doc_data.title||$1||description AS full_string_agg, doc_data_idx.vectors FROM 
doc_data, doc_groups, doc_data_idx, to_tsquery($2) AS q',
-                                        array ($this->field_separator,
-                                               $words)) ;
-               $qpa = db_construct_qpa($qpa,
+               $options = $this->options;
+               $group_id = $this->groupId;
+               if (!isset($options['insideDocuments']) || 
!$options['insideDocuments']) {
+                       $qpa = db_construct_qpa(false,
+                                               'SELECT x.* FROM (SELECT 
doc_data.docid, doc_data.filename, ts_headline(doc_data.title, q) AS title, 
ts_headline(doc_data.description, q) AS description, doc_groups.groupname, 
doc_data.title||$1||description AS full_string_agg, doc_data_idx.vectors FROM 
doc_data, doc_groups, doc_data_idx, to_tsquery($2) AS q',
+                                               array ($this->field_separator,
+                                                       $words));
+                       $qpa = db_construct_qpa($qpa,
                                         ' WHERE doc_data.doc_group = 
doc_groups.doc_group AND doc_data.docid = doc_data_idx.docid AND (vectors @@ 
to_tsquery($1)',
                                         array ($words)) ;
+               } else {
+                       $qpa = db_construct_qpa(false,
+                                       'SELECT x.* FROM (SELECT 
doc_data.docid, ts_headline(doc_data.filename, q) AS filename, 
ts_headline(doc_data.title, q) AS title, ts_headline(doc_data.description, q) 
AS description, doc_groups.groupname, 
doc_data.title||$1||description||$1||filename AS full_string_agg, 
doc_data_words_idx.vectors FROM doc_data, doc_groups, doc_data_words_idx, 
to_tsquery($2) AS q',
+                                       array ($this->field_separator,
+                                       $words));
+                       $qpa = db_construct_qpa($qpa,
+                                        ' WHERE doc_data.doc_group = 
doc_groups.doc_group AND doc_data.docid = doc_data_words_idx.docid AND (vectors 
@@ to_tsquery($1)',
+                                        array ($words)) ;
+               }
                $qpa = db_construct_qpa($qpa,
                                         ') AND doc_data.group_id = $1',
                                         array ($group_id)) ;
@@ -123,6 +138,15 @@ class DocsSearchQuery extends SearchQuery {
                        $qpa = db_construct_qpa($qpa,
                                                 ' AND doc_data.stateid = 1') ;
                }
+
+               if (isset($options['date_begin']) && 
!isset($options['date_end'])) {
+                       $qpa = db_construct_qpa($qpa, ' AND doc_data.createdate 
>= $1', array($options['date_begin']));
+               } elseif (!isset($options['date_begin']) && 
isset($options['date_end'])) {
+                       $qpa = db_construct_qpa($qpa, ' AND doc_data.createdate 
<= $1', array($options['date_end']));
+               } elseif (isset($options['date_begin']) && 
isset($options['date_end'])) {
+                       $qpa = db_construct_qpa($qpa, ' AND doc_data.createdate 
between $1 and $2', array($options['date_begin'], $$options['date_end']));
+               }
+
                $qpa = db_construct_qpa($qpa,
                                         ') AS x ') ;
                if (count($this->phrases)) {
@@ -131,8 +155,9 @@ class DocsSearchQuery extends SearchQuery {
                }
                $qpa = db_construct_qpa($qpa,
                                         ' ORDER BY ts_rank(vectors, 
to_tsquery($1)) DESC, groupname ASC, title ASC',
-                                        array($words)) ;
-               return $qpa ;
+                                        array($words));
+
+               return $qpa;
        }
 
        /**
diff --git a/src/common/search/SearchQuery.class.php 
b/src/common/search/SearchQuery.class.php
index 36a645f..644d3ca 100644
--- a/src/common/search/SearchQuery.class.php
+++ b/src/common/search/SearchQuery.class.php
@@ -7,6 +7,7 @@
  * Copyright 2009, Roland Mas
  * Copyright 2010-2011, Franck Villaume - Capgemini
  * Copyright (C) 2012 Alain Peyrat - Alcatel-Lucent
+ * Copyright 2015, Franck Villaume - TrivialDev
  *
  * This file is part of FusionForge. FusionForge is free software;
  * you can redistribute it and/or modify it under the terms of the
@@ -73,6 +74,12 @@ class SearchQuery extends Error {
         * @var array $sections
         */
        var $sections = SEARCH__ALL_SECTIONS;
+       /**
+        * options to filter search
+        *
+        * @var array $options
+        */
+       var $options = array();
 
        var $words = array();
 
@@ -89,7 +96,7 @@ class SearchQuery extends Error {
         * @param       boolean $isExact if we want to search for all the words 
or if only one is sufficient
         * @param       int     $rowsPerPage number of rows per page
         */
-       function __construct($words, $offset, $isExact, $rowsPerPage = 
SEARCH__DEFAULT_ROWS_PER_PAGE) {
+       function __construct($words, $offset, $isExact, $rowsPerPage = 
SEARCH__DEFAULT_ROWS_PER_PAGE, $options = array()) {
                $this->cleanSearchWords($words);
                //We manual escap because every Query in Search escap parameters
                $words = addslashes($words);
@@ -107,6 +114,7 @@ class SearchQuery extends Error {
                $this->offset = $offset;
                $this->isExact = $isExact;
                $this->operator = $this->getOperator();
+               $this->options = $options;
        }
 
        /**
@@ -123,7 +131,7 @@ class SearchQuery extends Error {
 
                $words = preg_replace("/[ \t]+/", ' ', $words);
                if(strlen($words) < 3) {
-                       $this->setError(_('Error: search query too short'));
+                       $this->setError(_('Error') . _(': ') . _('search query 
too short'));
                        return;
                }
                $words = htmlspecialchars($words);
diff --git a/src/db/20151209-docman-use-standardsearchengine.sql 
b/src/db/20151209-docman-use-standardsearchengine.sql
new file mode 100644
index 0000000..e062dfe
--- /dev/null
+++ b/src/db/20151209-docman-use-standardsearchengine.sql
@@ -0,0 +1,137 @@
+CREATE TABLE doc_data_words_idx ( docid integer, group_id integer, vectors 
tsvector );
+CREATE INDEX doc_data_words_idxfti ON doc_data_idx USING gist (vectors);
+CREATE TYPE doc_data_words_results AS ( docid integer, title text, description 
text, data_words text, groupname character varying(255));
+
+CREATE OR REPLACE FUNCTION update_vectors() RETURNS TRIGGER AS '
+DECLARE
+table_name TEXT;
+BEGIN
+       table_name := TG_ARGV[0];
+       -- **** artifact table ****
+       IF table_name = ''artifact'' THEN
+               IF TG_OP = ''DELETE'' THEN
+                     DELETE FROM artifact_idx WHERE 
artifact_id=OLD.artifact_id;
+               ELSE
+                     DELETE FROM artifact_idx WHERE 
artifact_id=NEW.artifact_id;
+                     INSERT INTO artifact_idx (SELECT a.artifact_id, 
to_tsvector(a.artifact_id::text) || to_tsvector(a.summary) || 
to_tsvector(a.details) || coalesce(ff_tsvector_agg(to_tsvector(am.body)), 
to_tsvector('''')) AS vectors FROM artifact a LEFT OUTER JOIN artifact_message 
am USING (artifact_id) WHERE a.artifact_id=NEW.artifact_id GROUP BY 
a.artifact_id, a.summary, a.details);
+               END IF;
+       -- **** artifact_message table ****
+       ELSIF table_name = ''artifact_message'' THEN
+               IF TG_OP = ''DELETE'' THEN
+                     DELETE FROM artifact_idx WHERE 
artifact_id=OLD.artifact_id;
+               ELSE
+                     DELETE FROM artifact_idx WHERE 
artifact_id=NEW.artifact_id;
+                     INSERT INTO artifact_idx (SELECT a.artifact_id, 
to_tsvector(a.artifact_id::text) || to_tsvector(a.summary) || 
to_tsvector(a.details) || coalesce(ff_tsvector_agg(to_tsvector(am.body)), 
to_tsvector('''')) AS vectors FROM artifact a LEFT OUTER JOIN artifact_message 
am USING (artifact_id) WHERE a.artifact_id=NEW.artifact_id GROUP BY 
a.artifact_id, a.summary, a.details);
+               END IF;
+       -- **** doc_data table ****
+       ELSIF table_name = ''doc_data'' THEN
+               IF TG_OP = ''INSERT'' THEN
+                       INSERT INTO doc_data_idx (docid, group_id, vectors) 
VALUES (NEW.docid, NEW.group_id, to_tsvector(coalesce(NEW.title,'''') ||'' ''|| 
coalesce(NEW.description,'''')));
+                       INSERT INTO doc_data_words_idx (docid, group_id, 
vectors) VALUES (NEW.docid, NEW.group_id, to_tsvector(coalesce(NEW.title,'''') 
||'' ''|| coalesce(NEW.description,'''') ||'' ''|| coalesce(NEW.filename,'''') 
||'' ''|| coalesce(NEW.data_words,'''')));
+               ELSIF TG_OP = ''UPDATE'' THEN
+                       UPDATE doc_data_idx SET group_id=NEW.group_id, 
vectors=to_tsvector(coalesce(NEW.title,'''') ||'' ''|| 
coalesce(NEW.description,'''')) WHERE docid=NEW.docid;
+                       UPDATE doc_data_idx SET group_id=NEW.group_id, 
vectors=to_tsvector(coalesce(NEW.title,'''') ||'' ''|| 
coalesce(NEW.description,'''') ||'' ''|| coalesce(NEW.filename,'''') ||'' ''|| 
coalesce(NEW.data_words,'''')) WHERE docid=NEW.docid;
+               ELSIF TG_OP = ''DELETE'' THEN
+                       DELETE FROM doc_data_idx WHERE docid=OLD.docid;
+                       DELETE FROM doc_data_words_idx WHERE docid=OLD.docid;
+               END IF;
+       -- **** forum table ****
+       ELSIF table_name = ''forum'' THEN
+               IF TG_OP = ''INSERT'' THEN
+                       INSERT INTO forum_idx (msg_id, group_id, vectors) 
(SELECT f.msg_id, g.group_id, to_tsvector(coalesce(f.subject,'''') ||'' ''||
+                       coalesce(f.body,'''')) AS vectors FROM forum f, 
forum_group_list g WHERE f.group_forum_id = g.group_forum_id AND f.msg_id = 
NEW.msg_id);
+               ELSIF TG_OP = ''UPDATE'' THEN
+                       UPDATE forum_idx SET 
vectors=to_tsvector(coalesce(NEW.subject,'''') ||'' ''|| 
coalesce(NEW.body,'''')) WHERE msg_id=NEW.msg_id;
+               ELSIF TG_OP = ''DELETE'' THEN
+                       DELETE FROM forum_idx WHERE msg_id=OLD.msg_id;
+               END IF;
+       -- **** frs_file table ****
+       ELSIF table_name = ''frs_file'' THEN
+               IF TG_OP = ''INSERT'' THEN
+                       INSERT INTO frs_file_idx (file_id, release_id, vectors) 
VALUES (NEW.file_id, NEW.release_id, to_tsvector(coalesce(NEW.filename,'''')));
+               ELSIF TG_OP = ''UPDATE'' THEN
+                       UPDATE frs_file_idx SET 
vectors=to_tsvector(coalesce(NEW.filename,'''')), release_id=NEW.release_id 
WHERE file_id=NEW.file_id;
+               ELSIF TG_OP = ''DELETE'' THEN
+                       DELETE FROM frs_file_idx WHERE file_id=OLD.file_id;
+               END IF;
+       -- **** frs_release table ****
+       ELSIF table_name = ''frs_release'' THEN
+               IF TG_OP = ''INSERT'' THEN
+                       INSERT INTO frs_release_idx (release_id, vectors) 
VALUES (NEW.release_id, to_tsvector(coalesce(NEW.changes,'''') ||'' ''|| 
coalesce(NEW.notes,'''') ||'' ''|| coalesce(NEW.name,'''')));
+               ELSIF TG_OP = ''UPDATE'' THEN
+                       UPDATE frs_release_idx SET 
vectors=to_tsvector(coalesce(NEW.changes,'''') ||'' ''|| 
coalesce(NEW.notes,'''') ||'' ''|| coalesce(NEW.name,'''')) WHERE 
release_id=NEW.release_id;
+               ELSIF TG_OP = ''DELETE'' THEN
+                       DELETE FROM frs_release_idx WHERE 
release_id=OLD.release_id;
+                       DELETE FROM frs_file_idx WHERE 
release_id=OLD.release_id;
+               END IF;
+       -- **** groups table ****
+       ELSIF table_name = ''groups'' THEN
+               IF TG_OP = ''INSERT'' THEN
+                       INSERT INTO groups_idx (group_id, vectors) VALUES 
(NEW.group_id, to_tsvector(coalesce(NEW.group_name,'''') ||'' ''|| 
coalesce(NEW.short_description,'''') ||'' ''|| 
coalesce(NEW.unix_group_name,'''')));
+               ELSIF TG_OP = ''UPDATE'' THEN
+                       UPDATE groups_idx SET 
vectors=to_tsvector(coalesce(NEW.group_name,'''') ||'' ''|| 
coalesce(NEW.short_description,'''') ||'' ''|| 
coalesce(NEW.unix_group_name,'''')) WHERE group_id=NEW.group_id;
+               ELSIF TG_OP = ''DELETE'' THEN
+                       DELETE FROM groups_idx WHERE group_id=OLD.group_id;
+               END IF;
+       -- **** news_bytes table ****
+       ELSIF table_name = ''news_bytes'' THEN
+               IF TG_OP = ''INSERT'' THEN
+                       INSERT INTO news_bytes_idx (id, vectors) VALUES 
(NEW.id, to_tsvector(coalesce(NEW.summary,'''') ||'' ''|| 
coalesce(NEW.details,'''')));
+               ELSIF TG_OP = ''UPDATE'' THEN
+                       UPDATE news_bytes_idx SET 
vectors=to_tsvector(coalesce(NEW.summary,'''') ||'' ''|| 
coalesce(NEW.details,'''')) WHERE id=NEW.id;
+               ELSIF TG_OP = ''DELETE'' THEN
+                       DELETE FROM news_bytes_idx WHERE id=OLD.id;
+               END IF;
+       -- **** project_task table ****
+       ELSIF table_name = ''project_task'' THEN
+               IF TG_OP = ''DELETE'' THEN
+                       DELETE FROM project_task_idx WHERE 
project_task_id=OLD.project_task_id;
+               ELSE
+                       DELETE FROM project_task_idx WHERE 
project_task_id=NEW.project_task_id;
+                       INSERT INTO project_task_idx (SELECT t.project_task_id, 
to_tsvector(t.project_task_id::text) || to_tsvector(t.summary) || 
to_tsvector(t.details) || coalesce(ff_tsvector_agg(to_tsvector(tm.body)), 
to_tsvector('''')) AS vectors FROM project_task t LEFT OUTER JOIN 
project_messages tm USING (project_task_id) WHERE 
t.project_task_id=NEW.project_task_id GROUP BY t.project_task_id, t.summary, 
t.details);
+               END IF;
+       -- **** project_messages table ****
+       ELSIF table_name = ''project_messages'' THEN
+               IF TG_OP = ''DELETE'' THEN
+                       DELETE FROM project_task_idx WHERE 
project_task_id=OLD.project_task_id;
+               ELSE
+                       DELETE FROM project_task_idx WHERE 
project_task_id=NEW.project_task_id;
+                       INSERT INTO project_task_idx (SELECT t.project_task_id, 
to_tsvector(t.summary) || to_tsvector(t.details) || 
coalesce(ff_tsvector_agg(to_tsvector(tm.body)), to_tsvector('''')) AS vectors 
FROM project_task t LEFT OUTER JOIN project_messages tm USING (project_task_id) 
WHERE t.project_task_id=NEW.project_task_id GROUP BY t.project_task_id, 
t.summary, t.details);
+               END IF;
+       -- **** skills_data table ****
+       ELSIF table_name = ''skills_data'' THEN
+               IF TG_OP = ''INSERT'' THEN
+                       INSERT INTO skills_data_idx (skills_data_id, vectors) 
VALUES (NEW.skills_data_id, to_tsvector(coalesce(NEW.title,'''') ||'' ''|| 
coalesce(NEW.keywords,'''')));
+               ELSIF TG_OP = ''UPDATE'' THEN
+                       UPDATE skills_data_idx SET 
vectors=to_tsvector(coalesce(NEW.title,'''') ||'' ''|| 
coalesce(NEW.keywords,'''')) WHERE skills_data_id=NEW.skills_data_id;
+               ELSIF TG_OP = ''DELETE'' THEN
+                       DELETE FROM skills_data_idx WHERE 
skills_data_id=OLD.skills_data_id;
+               END IF;
+       -- **** users table ****
+       ELSIF table_name = ''users'' THEN
+               IF TG_OP = ''INSERT'' THEN
+                       INSERT INTO users_idx (user_id, vectors) VALUES 
(NEW.user_id, to_tsvector(coalesce(NEW.user_name,'''') ||'' ''|| 
coalesce(NEW.realname,'''')));
+               ELSIF TG_OP = ''UPDATE'' THEN
+                       UPDATE users_idx SET 
vectors=to_tsvector(coalesce(NEW.user_name,'''') ||'' ''|| 
coalesce(NEW.realname,'''')) WHERE user_id=NEW.user_id;
+               ELSIF TG_OP = ''DELETE'' THEN
+                       DELETE FROM users_idx WHERE user_id=OLD.user_id;
+               END IF;
+       END IF;
+
+       RETURN NEW;
+END;'
+LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION PopulateDocDataWordsIDX() RETURNS int4 AS '
+DECLARE r RECORD;
+
+BEGIN
+    FOR r IN select doc_data.docid as docid, doc_data.filename as filename , 
doc_data.group_id as groupid, doc_data.data_words as datawords, 
doc_groups.groupname as groupname, doc_data.description as description, 
doc_data.title as title from doc_data, doc_groups where doc_data.doc_group = 
doc_groups.doc_group LOOP
+       INSERT into doc_data_words_idx (docid, group_id, vectors) values 
(r.docid, r.groupid, to_tsvector(coalesce(r.title,'''') ||'' ''|| 
coalesce(r.description,'''') ||'' ''|| coalesce(r.filename,'''') ||'' ''|| 
coalesce(r.datawords,'''')));
+    END LOOP;
+       return 1;
+END;
+' LANGUAGE plpgsql;
+
+SELECT PopulateDocDataWordsIDX() as output;
+
diff --git a/src/www/docman/index.php b/src/www/docman/index.php
index a972c41..38a72f6 100644
--- a/src/www/docman/index.php
+++ b/src/www/docman/index.php
@@ -6,7 +6,7 @@
  * Copyright 2002-2003, Tim Perdue/GForge, LLC
  * Copyright 2010-2011, Franck Villaume - Capgemini
  * Copyright (C) 2010-2011 Alain Peyrat - Alcatel-Lucent
- * Copyright 2012-2014, Franck Villaume - TrivialDev
+ * Copyright 2012-2015, Franck Villaume - TrivialDev
  * http://fusionforge.org
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -36,6 +36,7 @@ require_once $gfcommon.'docman/include/utils.php';
 require_once $gfcommon.'include/TextSanitizer.class.php'; // to make the HTML 
input by the user safe to store
 require_once $gfcommon.'reporting/report_utils.php';
 require_once $gfcommon.'reporting/ReportPerGroupDocmanDownloads.class.php';
+require_once 
$gfwww.'search/include/renderers/DocsHtmlSearchRenderer.class.php';
 require_once $gfwww.'include/html.php';
 
 /* are we using docman ? */
diff --git a/src/www/search/include/renderers/DocsHtmlSearchRenderer.class.php 
b/src/www/search/include/renderers/DocsHtmlSearchRenderer.class.php
index 6acffa0..78be225 100644
--- a/src/www/search/include/renderers/DocsHtmlSearchRenderer.class.php
+++ b/src/www/search/include/renderers/DocsHtmlSearchRenderer.class.php
@@ -4,7 +4,7 @@
  *
  * Copyright 2004 (c) Dominik Haas, GForge Team
  * Copyright (C) 2012 Alain Peyrat - Alcatel-Lucent
- * Copyright 2013, Franck Villaume - TrivialDev
+ * Copyright 2013,2015 Franck Villaume - TrivialDev
  * Copyright 2013, French Ministry of National Education
  * http://fusionforge.org
  *
@@ -40,11 +40,11 @@ class DocsHtmlSearchRenderer extends 
HtmlGroupSearchRenderer {
         * @param array|string $sections array of all sections to search in 
(array of strings)
         *
         */
-       function DocsHtmlSearchRenderer($words, $offset, $isExact, $groupId, 
$sections=SEARCH__ALL_SECTIONS) {
+       function DocsHtmlSearchRenderer($words, $offset, $isExact, $groupId, 
$sections = SEARCH__ALL_SECTIONS, $rowsPerPage = SEARCH__DEFAULT_ROWS_PER_PAGE, 
$options = array()) {
 
                $userIsGroupMember = $this->isGroupMember($groupId);
 
-               $searchQuery = new DocsSearchQuery($words, $offset, $isExact, 
$groupId, $sections, $userIsGroupMember);
+               $searchQuery = new DocsSearchQuery($words, $offset, $isExact, 
$groupId, $sections, $userIsGroupMember, $rowsPerPage, $options);
 
                $this->HtmlGroupSearchRenderer(SEARCH__TYPE_IS_DOCS, $words, 
$isExact, $searchQuery, $groupId, 'docman');
 
@@ -62,13 +62,13 @@ class DocsHtmlSearchRenderer extends 
HtmlGroupSearchRenderer {
         * @return string html output
         */
        function getRows() {
-               $rowsCount = $this->searchQuery->getRowsCount();
-               $result =& $this->searchQuery->getResult();
-
                if (!forge_check_perm('docman', $this->groupId, 'read')) {
                        return '';
                }
 
+               $rowsCount = $this->searchQuery->getRowsCount();
+               $result =& $this->searchQuery->getResult();
+
                $return = '';
 
                $lastDocGroup = null;

-----------------------------------------------------------------------

Summary of changes:
 src/CHANGES                                        |   3 +-
 src/common/docman/views/search.php                 | 152 ++++++---------------
 src/common/search/DocsSearchQuery.class.php        |  65 ++++++---
 src/common/search/SearchQuery.class.php            |  12 +-
 ...> 20151209-docman-use-standardsearchengine.sql} |  21 +++
 src/www/docman/index.php                           |   3 +-
 .../renderers/DocsHtmlSearchRenderer.class.php     |  12 +-
 7 files changed, 126 insertions(+), 142 deletions(-)
 copy src/db/{20140304-fix_update_vectors_function.sql => 
20151209-docman-use-standardsearchengine.sql} (81%)


hooks/post-receive
-- 
FusionForge

_______________________________________________
Fusionforge-commits mailing list
[email protected]
http://lists.fusionforge.org/cgi-bin/mailman/listinfo/fusionforge-commits

Reply via email to