Source for file pnuser.php
Documentation is available at pnuser.php
* Zikula Application Framework
* @copyright (c) 2002, Zikula Development Team
* @link http://www.zikula.org
* @version $Id: pnuser.php 24353 2008-06-08 10:41:06Z jornlind $
* @license GNU/GPL - http://www.gnu.org/copyleft/gpl.html
* @package Zikula_System_Modules
* @author Stefano Garuti (ported to pnAPI)
* This function is the default function. Call the function to show the search form.
* @return string HTML string templated
// Return the output that has been generated by this function
return $pnRender->fetch('search_user_main.htm');
* Splits the query string into words suitable for a mysql query
* This function is ported 'as is' from the old, nonAPI, module
* it is called from each plugin so we can't delete it or change it's name
* @param string $q the string to parse and split
* @param string $dbwildcard wrap each word in a DB wildcard character (%)
* @return array an array of words optionally surrounded by '%'
$qwords = preg_split('/ /', $stripped, - 1, PREG_SPLIT_NO_EMPTY);
foreach($qwords as $word) {
$w[] = '%' . $word . '%';
* Contruct part of a where clause out of the supplied search parameters
if (!isset ($args) || empty($args) || !isset ($fields) || empty($fields)) {
if (!empty($args['q'])) {
$q = str_replace('%', '\\%', $q); // Don't allow user input % as wildcard
if ($args['searchtype'] !== 'EXACT') {
$connector = $args['searchtype'] == 'AND' ? ' AND ' : ' OR ';
$searchwords = array("%{$q}%");
foreach($searchwords as $word) {
$where .= (!$start ? $connector : '') . ' (';
// I'm not sure if "LIKE" is the best solution in terms of DB portability (PC)
foreach ($fields as $field) {
$where .= "{ $field} LIKE ' $word' OR ";
$where = substr($where, 0 , - 4);
// Check if we're in a multilingual setup
$where .= "AND ({$mlfield} = '$currentlang' OR {$mlfield} = '')";
* Generate complete search form
* Generate the whole search form, including the various plugins options.
* It uses the Search API's getallplugins() function to find plugins.
* @return string HTML string templated
// get parameter from input
$vars['numlimit'] = pnModGetVar('Search', 'itemsperpage', 25);
// this var allows the headers to not be displayed
if (!isset ($vars['titles']))
if (!isset ($vars['searchtype']) || empty($vars['searchtype'])) {
$vars['searchtype'] = 'AND';
if (!isset ($vars['searchorder']) || empty($vars['searchorder'])) {
$vars['searchorder'] = 'newest';
// reset the session vars for a new search
// get all the search plugins
$search_modules = pnModAPIFunc('Search', 'user', 'getallplugins');
if (count($search_modules) > 0) {
$plugin_options = array();
foreach($search_modules as $mods) {
// as every search plugins return a formatted html string
// we assign it to a generic holder named 'plugin_options'
// maybe in future this will change
// we should retrieve from the plugins an array of values
// and formatting it here according with the module's template
// we have also to provide some trick to assure the 'backward compatibility'
$plugin_options[$mods['title']] = pnModAPIFunc($mods['title'], 'search', 'options', $vars);
// add content to template
$pnRender->assign($vars);
$pnRender->assign('plugin_options', $plugin_options);
// Return the output that has been generated by this function
return $pnRender->fetch('search_user_form.htm');
// Return the output that has been generated by this function
return $pnRender->fetch('search_user_noplugins.htm');
/** Class for doing module based access check and URL creation of search result
* - The module based access is somewhat deprecated (it still works but is not
* used since it makes it impossible to count the number of search result).
* - The URL for each found item is created here. By doing this we only create
* URLs for results the user actually view and save some time this way.
* @package Zikula_System_Modules
// This variable contains a table of all search plugins (indexed by module name)
// This method is called by DBUtil::selectObjectArrayFilter() for each and every search result.
// A return value of true means "keep result" - false means "discard".
// The decision is delegated to the search plugin (module) that generated the result
$module = $datarow['module'];
// Get plugin information
if (isset ($mod['functions'])) {
foreach ($mod['functions'] as $contenttype => $function) {
// Delegate check to search plugin
// (also allow plugin to write 'url' => ... into $datarow by passing it by reference)
$ok = $ok && pnModAPIFunc($mod['title'], 'search', $function. '_check',
array('datarow' => &$datarow,
'contenttype' => $contenttype));
* Perform the search then show the results
* This function includes all the search plugins, then call every one passing
* an array that contains the string to search for, the boolean operators.
* @return string HTML string templated
// get parameter from HTTP input
$vars['numlimit'] = pnModGetVar('Search', 'itemsperpage', 25);
// $firstpage is used to identify the very first result page
// - and to disable calls to plugins on the following pages
$firstPage = !isset ($_REQUEST['page']);
// The modulename exists in this array as key, if the checkbox was filled
// All formular data from the modules search plugins is contained in:
if (!isset ($vars['searchtype']) || empty($vars['searchtype'])) {
$vars['searchtype'] = 'AND';
if (!isset ($vars['searchorder']) || empty($vars['searchorder'])) {
$vars['searchorder'] = 'newest';
if (!isset ($active) || !is_array($active) || empty($active)) {
if (!isset ($modvar) || !is_array($modvar) || empty($modvar)) {
// work out row index from page number
$vars['startnum'] = (($vars['page'] - 1) * $vars['numlimit']) + 1;
return pnRedirect(pnModUrl('Search', 'user', 'main'));
// get all the search plugins
$search_modules = pnModAPIFunc('Search', 'user', 'getallplugins');
// Create output object and check caching
$pnRender->cache_id = md5($vars['q'] . $vars['searchtype'] . $vars['searchorder'] . pnUserGetVar('uid')) . $vars['page'];
// check if the contents are cached.
if ($pnRender->is_cached('search_user_results.htm')) {
return $pnRender->fetch('search_user_results.htm');
// load the extra language file
$searchTable = $pntable['search_result'];
$searchColumn = $pntable['search_result_column'];
// Create restriction on result table (so user only sees own results)
$userResultWhere = "$searchColumn[session] = '" . session_id() . "'";
// Do all the heavy database stuff on the first page only
// Clear current search result for current user - before showing the first page
// Clear also older searches from other users.
$where = $userResultWhere;
if ($dbType== 'postgres') {
$where .= " OR $searchColumn[found] + INTERVAL '8 HOUR' < NOW()" ;
$where .= " OR DATE_ADD($searchColumn[found], INTERVAL 8 HOUR) < NOW()" ;
// Ask active modules to find their items and put them into $searchTable for the current user
// At the same time convert modules list from numeric index to modname index
$searchModulesByName = array();
foreach($search_modules as $mod) {
// check we've a valid search plugin
if (isset ($mod['functions']) && (empty($active) || isset ($active[$mod['title']]))) {
foreach ($mod['functions'] as $contenttype => $function) {
if (isset ($modvar[$mod['title']])) {
$searchModulesByName[$mod['name']] = $mod;
$ok = pnModAPIFunc($mod['title'], 'search', $function, $param);
LogUtil::registerError ("Internal error: module $mod[title] returned false in search function '$function'");
return pnRedirect(pnModUrl('Search', 'user', 'main'));
// Count number of found results
// Fetch search result - do sorting and paging in database
// Figure out what to sort by
switch ($vars['searchorder']) {
// Get next N results from the current user's result set
// The "checker" object is used to:
// 1) do secondary access control (deprecated more or less)
// 2) let the modules add "url" to the found (and viewed) items
$vars['startnum']- 1, $vars['numlimit'], '',
// Get number of chars to display in search summaries
if (empty($limitsummary)) {
$pnRender->assign('resultcount', $resultCount);
$pnRender->assign('results', $sqlResult);
$pnRender->assign($vars);
$pnRender->assign('limitsummary', $limitsummary);
// Return the output that has been generated by this function
return $pnRender->fetch('search_user_results.htm');
* display a list of recent searches
// Get parameters from whatever input we need.
// we need this value multiple times, so we keep it
$items = pnModApiFunc('Search', 'user', 'getall', array('startnum' => $startnum, 'numitems' => $itemsperpage, 'sortorder' => 'date'));
// Create output object - this object will store all of our output so that
// we can return it easily when required
// assign the results to the template
$pnRender->assign('recentsearches', $items);
// assign the values for the smarty plugin to produce a pager in case of there
// being many items to display.
$pnRender->assign('pager', array('numitems' => pnModAPIFunc('Search', 'user', 'countitems'),
'itemsperpage' => $itemsperpage));
// Return the output that has been generated by this function
return $pnRender->fetch('search_user_recent.htm');
|