Example #1
0
 /**
  *
  * @desc This function performs a generic search
  * 		against the database. Originaly from the mambot
  * 		but enhanced for wider searches
  * @param array $ of arrays $searchArray The lists of what to search for
  * 		i.e.: array( array( 'phrase'=>'search phrases', mode=>'exact'),
  * 			         array( 'phrase=>'.....
  * 		Currently only uses the FIRST array request. (FUTURE: multiples)
  * @param string $ The ordering of the results (newest...etc).
  * 		Prefix with a '-' to reverse the ordering.
  * @param int $ the categories to search for (0=all)
  * @param mixed $ Either an array of terms to return or '*'
  * 		(Array is 'column-name' => 'return name'.)
  * @param array $ List of options for searching
  *
  * NOTE: We are NOT assured that we have $_DOCMAN and all the other goodies.
  * 	    (we may be just from mambot)
  */
 function search(&$searchArray, $ordering = '', $cats = '', $columns = '', $options = array())
 {
     global $database, $my, $_DOCMAN;
     $_DMUSER = $_DOCMAN->getUser();
     $searchterms = array_pop($searchArray);
     // Only do one (for now)
     if (empty($options)) {
         $options = array('search_name', 'search_description');
     }
     if ($ordering == '') {
         $ordering = 'newest';
     }
     $registered = $_DOCMAN->getCfg('registered');
     $perpage = $_DOCMAN->getCfg('perpage');
     $authorCan = $_DOCMAN->getCfg('author_can', '9999');
     $userid = intval($my->id);
     // Guests who can browse can also search for documents
     //if (! $registered > 0) {
     //    return array();
     //}
     // Fetch 'acl' stuff. (Switch to class later?)
     /*
             $specials = array('super administrator', 'manager', 'administrator');
             $specialcompat = $_DOCMAN->getCfg('specialcompat', _DM_SPECIALCOMPAT_DM13);
             if($specialcompat == _DM_SPECIALCOMPAT_J10) {
                 $specials[] = 'author';
                 $specials[] = 'editor';
                 $specials[] = 'publisher';
             }
             $isAdmin = (in_array( strtolower($my->usertype), $specials));
     */
     $isAdmin = $_DMUSER->isAdmin;
     // -------------------------------------
     // Fetch the search options. Passed in options array
     // -------------------------------------
     $search_col = array();
     if (is_array($options)) {
         if (in_array('search_name', $options)) {
             $search_col[] = 'DM.dmname ';
         }
         if (in_array('search_description', $options) || in_array('search_desc', $options)) {
             $search_col[] = 'DM.dmdescription ';
         }
         if (in_array('search_cat', $options)) {
             $search_col[] = "CAT.title ";
             $search_col[] = "CAT.name ";
             $search_col[] = "SUB.title ";
             $search_col[] = "SUB.name ";
         }
     }
     if (count($search_col) == 0) {
         return array();
         // Have to search SOMETHING!
     }
     // BUILD QUERY PARTS
     $search_mode = $searchterms['search_mode'];
     $text = trim($searchterms['search_phrase']);
     // fix for http://joomlacode.org/gf/project/docman/tracker/?action=TrackerItemEdit&tracker_item_id=7999
     $text = htmlentities($text, ENT_QUOTES);
     if (!$text) {
         return array();
     }
     // (1) Format search 'phrase' into SQL
     $invert = false;
     if (substr($search_mode, 0, 1) == '-') {
         $invert = true;
         $search_mode = substr($search_mode, 1);
     }
     $wheres = array();
     switch ($search_mode) {
         case 'exact':
             foreach ($search_col as $col) {
                 $wheres[] = $col . "LIKE '%{$text}%'";
             }
             $where = '(' . implode(') OR (', $wheres) . ')';
             break;
         case 'any':
             // Fall through for regex
             $text = implode('|', explode(' ', $text));
         case 'regex':
             foreach ($search_col as $col) {
                 $wheres[] = $col . "RLIKE '{$text}'";
             }
             $where = '(' . implode(' OR ', $wheres) . ')';
             break;
         case 'all':
         default:
             $words = explode(' ', $text);
             foreach ($search_col as $col) {
                 $wheres2 = array();
                 foreach ($words as $word) {
                     $wheres2[] = $col . "LIKE '%{$word}%'";
                 }
                 $wheres[] = implode(' AND ', $wheres2);
             }
             $where = '(' . implode(') OR (', $wheres) . ')';
             break;
     }
     if ($invert) {
         $where = 'NOT ( ' . $where . ')';
     }
     // DEBUG:
     // echo "<pre>WHERE is: $where</pre>";
     // (2) Create the 'ORDER BY' section based on user request
     $_DM_SEARCH_SORT_ORDER = array('newest' => 'DM.dmlastupdateon DDD', 'oldest' => 'DM.dmlastupdateon AAA', 'popular' => 'DM.dmcounter DDD', 'alpha' => 'DM.dmname AAA', 'category' => 'CAT.title AAA, SUB.title AAA, DM.dmname AAA');
     $_DM_SEARCH_PATTERN = array('/DDD/', '/AAA/');
     $invert = false;
     if (substr($ordering, 0, 1) == '-') {
         $ordering = substr($ordering, 1);
         $invert = true;
     }
     $order = $_DM_SEARCH_SORT_ORDER[$ordering];
     if ($invert) {
         $order = preg_replace($_DM_SEARCH_PATTERN, array('ASC', 'DESC'), $order);
     } else {
         $order = preg_replace($_DM_SEARCH_PATTERN, array('DESC', 'ASC'), $order);
     }
     // (3) SQL WHERE portion based on user access priviledges
     if ($isAdmin) {
         $user_filter = " (SUB.access=" . _DM_ACCESS_PUBLIC . " OR   SUB.access=" . _DM_ACCESS_REGISTERED . ")";
     } else {
         if ($userid > 0) {
             // Logged IN
             $user_groups = DOCMAN_Docs::_dmCheckGroupsUserIn();
             $user_filter = "(" . "\n    DM.dmowner=" . _DM_PERMIT_EVERYONE . "\n OR DM.dmowner=" . _DM_PERMIT_REGISTERED . "\n OR DM.dmowner=" . $userid . "\n OR DM.dmowner IN ({$user_groups}) " . "\n OR DM.dmmantainedby=" . $userid . "\n OR DM.dmmantainedby IN ({$user_groups}) ";
             if ($authorCan > 0) {
                 $user_filter .= "\n OR DM.dmsubmitedby = {$userid}";
             }
             $user_filter .= ")" . "\n AND (SUB.access=" . _DM_ACCESS_PUBLIC . "\n OR   SUB.access=" . _DM_ACCESS_REGISTERED . ")";
         } else {
             // NOT logged in
             $user_filter = " DM.dmowner=" . _DM_PERMIT_EVERYONE . "\n AND SUB.access=" . _DM_ACCESS_PUBLIC;
         }
         // endif $userid
     }
     // endif isAdmin
     // (4)Build up the category list (if they selected it)
     if ($cats != '' && $cats != 0) {
         $user_filter .= "\n AND DM.catid ";
         if (is_array($cats)) {
             $user_filter .= 'IN (' . implode(',', $cats) . ')';
         } else {
             $user_filter .= "= {$cats}";
         }
     }
     // (5) Build up list of columns to return
     if (is_array($columns)) {
         foreach ($columns as $key => $value) {
             $list[] = "\n\t{$key}  AS {$value}";
         }
         $list_terms = implode(',', $list);
     } else {
         if ($columns != '' && $columns != '*') {
             $list_terms = $columns;
         } else {
             $list_terms = 'DM.* , DM.catid AS docman_catid';
         }
     }
     // (*) Build final query for SQL lookup
     $query = "SELECT {$list_terms} " . "\nFROM #__docman AS DM " . "\nLEFT JOIN #__categories AS SUB ON SUB.id = DM.catid" . "\nLEFT JOIN #__categories AS CAT ON CAT.id = SUB.parent_id" . "\nWHERE {$user_filter} " . "\n  AND DM.published=1 AND DM.approved=1" . "\n  AND ({$where}) " . "\nORDER BY {$order}";
     // TODO: add proper pagination instead of hardcoded limit?
     $database->setQuery($query, 0, 20);
     $rows = $database->loadObjectList();
     $cache = array();
     // Fill in the correct sections
     for ($r = 0; $r < count($rows); $r++) {
         $rows[$r]->section = @$options['section_prefix'] . DOCMAN_Docs::_dmSearchSection($rows[$r]->catid, $cache, '/') . @$options['section_suffix'];
     }
     // FINAL SORT:
     // We couldn't sort by category until now (we didn't HAVE a category)
     if ($order == 'category') {
         if ($invert) {
             usort($rows, create_function("{$a},{$b}", "return strcasecmp({$a->section} . {$a->dmname} , {$b->section} . {$b->dmname});"));
         } else {
             usort($rows, create_function("{$a},{$b}", "return strcasecmp({$b->section} . {$b->dmname} , {$a->section} . {$a->dmname});"));
         }
     }
     return $rows;
 }