Search::addWhere PHP Method

addWhere() static public method

Generic Function to add where to a request
static public addWhere ( $link, $nott, $itemtype, $ID, $searchtype, $val, $meta ) : select
$link link string
$nott is it a negative search ?
$itemtype item type
$ID ID of the item to search
$searchtype searchtype used (equals or contains)
$val item num in the request
$meta is a meta search (meta=2 in search.class.php) (default 0)
return select string
    static function addWhere($link, $nott, $itemtype, $ID, $searchtype, $val, $meta = 0)
    {
        $searchopt =& self::getOptions($itemtype);
        $table = $searchopt[$ID]["table"];
        $field = $searchopt[$ID]["field"];
        $inittable = $table;
        $addtable = '';
        if ($table != 'asset_types' && $table != getTableForItemType($itemtype) && $searchopt[$ID]["linkfield"] != getForeignKeyFieldForTable($table)) {
            $addtable = "_" . $searchopt[$ID]["linkfield"];
            $table .= $addtable;
        }
        if (isset($searchopt[$ID]['joinparams'])) {
            $complexjoin = self::computeComplexJoinID($searchopt[$ID]['joinparams']);
            if (!empty($complexjoin)) {
                $table .= "_" . $complexjoin;
            }
        }
        if ($meta && getTableForItemType($itemtype) != $table) {
            $table .= "_" . $itemtype;
        }
        // Hack to allow search by ID on every sub-table
        if (preg_match('/^\\$\\$\\$\\$([0-9]+)$/', $val, $regs)) {
            return $link . " (`{$table}`.`id` " . ($nott ? "<>" : "=") . $regs[1] . " " . ($regs[1] == 0 ? " OR `{$table}`.`id` IS NULL" : '') . ") ";
        }
        // Preparse value
        if (isset($searchopt[$ID]["datatype"])) {
            switch ($searchopt[$ID]["datatype"]) {
                case "datetime":
                case "date":
                case "date_delay":
                    $force_day = true;
                    if ($searchopt[$ID]["datatype"] == 'datetime') {
                        $force_day = false;
                    }
                    if (strstr($val, 'BEGIN') || strstr($val, 'LAST')) {
                        $force_day = true;
                    }
                    $val = Html::computeGenericDateTimeSearch($val, $force_day);
                    break;
            }
        }
        switch ($searchtype) {
            case "contains":
                $SEARCH = self::makeTextSearch($val, $nott);
                break;
            case "equals":
                if ($nott) {
                    $SEARCH = " <> '{$val}'";
                } else {
                    $SEARCH = " = '{$val}'";
                }
                break;
            case "notequals":
                if ($nott) {
                    $SEARCH = " = '{$val}'";
                } else {
                    $SEARCH = " <> '{$val}'";
                }
                break;
            case "under":
                if ($nott) {
                    $SEARCH = " NOT IN ('" . implode("','", getSonsOf($inittable, $val)) . "')";
                } else {
                    $SEARCH = " IN ('" . implode("','", getSonsOf($inittable, $val)) . "')";
                }
                break;
            case "notunder":
                if ($nott) {
                    $SEARCH = " IN ('" . implode("','", getSonsOf($inittable, $val)) . "')";
                } else {
                    $SEARCH = " NOT IN ('" . implode("','", getSonsOf($inittable, $val)) . "')";
                }
                break;
        }
        // Plugin can override core definition for its type
        if ($plug = isPluginItemType($itemtype)) {
            $function = 'plugin_' . $plug['plugin'] . '_addWhere';
            if (function_exists($function)) {
                $out = $function($link, $nott, $itemtype, $ID, $val, $searchtype);
                if (!empty($out)) {
                    return $out;
                }
            }
        }
        switch ($inittable . "." . $field) {
            // case "glpi_users_validation.name" :
            case "glpi_users.name":
                if ($itemtype == 'User') {
                    // glpi_users case / not link table
                    if (in_array($searchtype, array('equals', 'notequals'))) {
                        return " {$link} `{$table}`.`id`" . $SEARCH;
                    }
                    return self::makeTextCriteria("`{$table}`.`{$field}`", $val, $nott, $link);
                }
                if ($_SESSION["glpinames_format"] == User::FIRSTNAME_BEFORE) {
                    $name1 = 'firstname';
                    $name2 = 'realname';
                } else {
                    $name1 = 'realname';
                    $name2 = 'firstname';
                }
                if (in_array($searchtype, array('equals', 'notequals'))) {
                    return " {$link} (`{$table}`.`id`" . $SEARCH . ($val == 0 ? " OR `{$table}`.`id` IS" . ($searchtype == "notequals" ? " NOT" : "") . " NULL" : '') . ') ';
                }
                $toadd = '';
                $tmplink = 'OR';
                if ($nott) {
                    $tmplink = 'AND';
                }
                if ($itemtype == 'Ticket' || $itemtype == 'Problem') {
                    if (isset($searchopt[$ID]["joinparams"]["beforejoin"]["table"]) && isset($searchopt[$ID]["joinparams"]["beforejoin"]["joinparams"]) && ($searchopt[$ID]["joinparams"]["beforejoin"]["table"] == 'glpi_tickets_users' || $searchopt[$ID]["joinparams"]["beforejoin"]["table"] == 'glpi_problems_users' || $searchopt[$ID]["joinparams"]["beforejoin"]["table"] == 'glpi_changes_users')) {
                        $bj = $searchopt[$ID]["joinparams"]["beforejoin"];
                        $linktable = $bj['table'] . '_' . self::computeComplexJoinID($bj['joinparams']);
                        //$toadd     = "`$linktable`.`alternative_email` $SEARCH $tmplink ";
                        $toadd = self::makeTextCriteria("`{$linktable}`.`alternative_email`", $val, $nott, $tmplink);
                        if ($val == '^$') {
                            return $link . " ((`{$linktable}`.`users_id` IS NULL)\n                            OR `{$linktable}`.`alternative_email` IS NULL)";
                        }
                    }
                }
                $toadd2 = '';
                if ($nott && $val != 'NULL' && $val != 'null') {
                    $toadd2 = " OR `{$table}`.`{$field}` IS NULL";
                }
                return $link . " (((`{$table}`.`{$name1}` {$SEARCH}\n                            {$tmplink} `{$table}`.`{$name2}` {$SEARCH}\n                            {$tmplink} `{$table}`.`{$field}` {$SEARCH}\n                            {$tmplink} CONCAT(`{$table}`.`{$name1}`, ' ', `{$table}`.`{$name2}`) {$SEARCH} )\n                            {$toadd2}) {$toadd})";
            case "glpi_groups.completename":
                if ($val == 'mygroups') {
                    switch ($searchtype) {
                        case 'equals':
                            return " {$link} (`{$table}`.`id` IN ('" . implode("','", $_SESSION['glpigroups']) . "')) ";
                        case 'notequals':
                            return " {$link} (`{$table}`.`id` NOT IN ('" . implode("','", $_SESSION['glpigroups']) . "')) ";
                        case 'under':
                            $groups = $_SESSION['glpigroups'];
                            foreach ($_SESSION['glpigroups'] as $g) {
                                $groups += getSonsOf($inittable, $g);
                            }
                            $groups = array_unique($groups);
                            return " {$link} (`{$table}`.`id` IN ('" . implode("','", $groups) . "')) ";
                        case 'notunder':
                            $groups = $_SESSION['glpigroups'];
                            foreach ($_SESSION['glpigroups'] as $g) {
                                $groups += getSonsOf($inittable, $g);
                            }
                            $groups = array_unique($groups);
                            return " {$link} (`{$table}`.`id` NOT IN ('" . implode("','", $groups) . "')) ";
                    }
                }
                break;
            case "glpi_auth_tables.name":
                $user_searchopt = self::getOptions('User');
                $tmplink = 'OR';
                if ($nott) {
                    $tmplink = 'AND';
                }
                return $link . " (`glpi_authmails" . $addtable . "_" . self::computeComplexJoinID($user_searchopt[31]['joinparams']) . "`.`name`\n                           {$SEARCH}\n                           {$tmplink} `glpi_authldaps" . $addtable . "_" . self::computeComplexJoinID($user_searchopt[30]['joinparams']) . "`.`name`\n                           {$SEARCH} ) ";
            case "glpi_ipaddresses.name":
                $search = array("/\\&lt;/", "/\\&gt;/");
                $replace = array("<", ">");
                $val = preg_replace($search, $replace, $val);
                if (preg_match("/^\\s*([<>])([=]*)[[:space:]]*([0-9\\.]+)/", $val, $regs)) {
                    if ($nott) {
                        if ($regs[1] == '<') {
                            $regs[1] = '>';
                        } else {
                            $regs[1] = '<';
                        }
                    }
                    $regs[1] .= $regs[2];
                    return $link . " (INET_ATON(`{$table}`.`{$field}`) " . $regs[1] . " INET_ATON('" . $regs[3] . "')) ";
                }
                break;
            case "glpi_tickets.status":
            case "glpi_problems.status":
            case "glpi_changes.status":
                if ($val == 'all') {
                    return "";
                }
                $tocheck = array();
                if ($item = getItemForItemtype($itemtype)) {
                    switch ($val) {
                        case 'process':
                            $tocheck = $item->getProcessStatusArray();
                            break;
                        case 'notclosed':
                            $tocheck = $item->getAllStatusArray();
                            foreach ($item->getClosedStatusArray() as $status) {
                                if (isset($tocheck[$status])) {
                                    unset($tocheck[$status]);
                                }
                            }
                            $tocheck = array_keys($tocheck);
                            break;
                        case 'old':
                            $tocheck = array_merge($item->getSolvedStatusArray(), $item->getClosedStatusArray());
                            break;
                        case 'notold':
                            $tocheck = $item->getAllStatusArray();
                            foreach ($item->getSolvedStatusArray() as $status) {
                                if (isset($tocheck[$status])) {
                                    unset($tocheck[$status]);
                                }
                            }
                            foreach ($item->getClosedStatusArray() as $status) {
                                if (isset($tocheck[$status])) {
                                    unset($tocheck[$status]);
                                }
                            }
                            $tocheck = array_keys($tocheck);
                            break;
                    }
                }
                if (count($tocheck) == 0) {
                    $statuses = $item->getAllStatusArray();
                    if (isset($statuses[$val])) {
                        $tocheck = array($val);
                    }
                }
                if (count($tocheck)) {
                    if ($nott) {
                        return $link . " `{$table}`.`{$field}` NOT IN ('" . implode("','", $tocheck) . "')";
                    }
                    return $link . " `{$table}`.`{$field}` IN ('" . implode("','", $tocheck) . "')";
                }
                break;
            case "glpi_tickets_tickets.tickets_id_1":
                $tmplink = 'OR';
                $compare = '=';
                if ($nott) {
                    $tmplink = 'AND';
                    $compare = '<>';
                }
                $toadd2 = '';
                if ($nott && $val != 'NULL' && $val != 'null') {
                    $toadd2 = " OR `{$table}`.`{$field}` IS NULL";
                }
                return $link . " (((`{$table}`.`tickets_id_1` {$compare} '{$val}'\n                              {$tmplink} `{$table}`.`tickets_id_2` {$compare} '{$val}')\n                             AND `glpi_tickets`.`id` <> '{$val}')\n                            {$toadd2})";
            case "glpi_tickets.priority":
            case "glpi_tickets.impact":
            case "glpi_tickets.urgency":
            case "glpi_problems.priority":
            case "glpi_problems.impact":
            case "glpi_problems.urgency":
            case "glpi_changes.priority":
            case "glpi_changes.impact":
            case "glpi_changes.urgency":
            case "glpi_projects.priority":
                if (is_numeric($val)) {
                    if ($val > 0) {
                        return $link . " `{$table}`.`{$field}` = '{$val}'";
                    }
                    if ($val < 0) {
                        return $link . " `{$table}`.`{$field}` >= '" . abs($val) . "'";
                    }
                    // Show all
                    return $link . " `{$table}`.`{$field}` >= '0' ";
                }
                return "";
            case "glpi_tickets.global_validation":
            case "glpi_ticketvalidations.status":
                if ($val == 'all') {
                    return "";
                }
                $tocheck = array();
                switch ($val) {
                    case 'can':
                        $tocheck = CommonITILValidation::getCanValidationStatusArray();
                        break;
                    case 'all':
                        $tocheck = CommonITILValidation::getAllValidationStatusArray();
                        break;
                }
                if (count($tocheck) == 0) {
                    $tocheck = array($val);
                }
                if (count($tocheck)) {
                    if ($nott) {
                        return $link . " `{$table}`.`{$field}` NOT IN ('" . implode("','", $tocheck) . "')";
                    }
                    return $link . " `{$table}`.`{$field}` IN ('" . implode("','", $tocheck) . "')";
                }
                break;
        }
        //// Default cases
        // Link with plugin tables
        if (preg_match("/^glpi_plugin_([a-z0-9]+)/", $inittable, $matches)) {
            if (count($matches) == 2) {
                $plug = $matches[1];
                $function = 'plugin_' . $plug . '_addWhere';
                if (function_exists($function)) {
                    $out = $function($link, $nott, $itemtype, $ID, $val, $searchtype);
                    if (!empty($out)) {
                        return $out;
                    }
                }
            }
        }
        $tocompute = "`{$table}`.`{$field}`";
        $tocomputetrans = "`" . $table . "_trans`.`value`";
        if (isset($searchopt[$ID]["computation"])) {
            $tocompute = $searchopt[$ID]["computation"];
            $tocompute = str_replace("TABLE", "`{$table}`", $tocompute);
        }
        // Preformat items
        if (isset($searchopt[$ID]["datatype"])) {
            switch ($searchopt[$ID]["datatype"]) {
                case "itemtypename":
                    if (in_array($searchtype, array('equals', 'notequals'))) {
                        return " {$link} (`{$table}`.`{$field}`" . $SEARCH . ') ';
                    }
                    break;
                case "itemlink":
                    if (in_array($searchtype, array('equals', 'notequals', 'under', 'notunder'))) {
                        return " {$link} (`{$table}`.`id`" . $SEARCH . ') ';
                    }
                    break;
                case "datetime":
                case "date":
                case "date_delay":
                    if ($searchopt[$ID]["datatype"] == 'datetime') {
                        // Specific search for datetime
                        if (in_array($searchtype, array('equals', 'notequals'))) {
                            $val = preg_replace("/:00\$/", '', $val);
                            $val = '^' . $val;
                            if ($searchtype == 'notequals') {
                                $nott = !$nott;
                            }
                            return self::makeTextCriteria("`{$table}`.`{$field}`", $val, $nott, $link);
                        }
                    }
                    if ($searchtype == 'lessthan') {
                        $val = '<' . $val;
                    }
                    if ($searchtype == 'morethan') {
                        $val = '>' . $val;
                    }
                    if ($searchtype) {
                        $date_computation = $tocompute;
                    }
                    $search_unit = ' MONTH ';
                    if (isset($searchopt[$ID]['searchunit'])) {
                        $search_unit = $searchopt[$ID]['searchunit'];
                    }
                    if ($searchopt[$ID]["datatype"] == "date_delay") {
                        $delay_unit = ' MONTH ';
                        if (isset($searchopt[$ID]['delayunit'])) {
                            $delay_unit = $searchopt[$ID]['delayunit'];
                        }
                        $add_minus = '';
                        if (isset($searchopt[$ID]["datafields"][3])) {
                            $add_minus = "-`{$table}`.`" . $searchopt[$ID]["datafields"][3] . "`";
                        }
                        $date_computation = "ADDDATE(`{$table}`." . $searchopt[$ID]["datafields"][1] . ",\n                                               INTERVAL (`{$table}`." . $searchopt[$ID]["datafields"][2] . "\n                                                         {$add_minus})\n                                               {$delay_unit})";
                    }
                    if (in_array($searchtype, array('equals', 'notequals'))) {
                        return " {$link} ({$date_computation} " . $SEARCH . ') ';
                    }
                    $search = array("/\\&lt;/", "/\\&gt;/");
                    $replace = array("<", ">");
                    $val = preg_replace($search, $replace, $val);
                    if (preg_match("/^\\s*([<>=]+)(.*)/", $val, $regs)) {
                        if (is_numeric($regs[2])) {
                            return $link . " {$date_computation} " . $regs[1] . "\n                            ADDDATE(NOW(), INTERVAL " . $regs[2] . " {$search_unit}) ";
                        }
                        // ELSE Reformat date if needed
                        $regs[2] = preg_replace('@(\\d{1,2})(-|/)(\\d{1,2})(-|/)(\\d{4})@', '\\5-\\3-\\1', $regs[2]);
                        if (preg_match('/[0-9]{2,4}-[0-9]{1,2}-[0-9]{1,2}/', $regs[2])) {
                            return $link . " {$date_computation} " . $regs[1] . " '" . $regs[2] . "'";
                        }
                        return "";
                    }
                    // ELSE standard search
                    // Date format modification if needed
                    $val = preg_replace('@(\\d{1,2})(-|/)(\\d{1,2})(-|/)(\\d{4})@', '\\5-\\3-\\1', $val);
                    return self::makeTextCriteria($date_computation, $val, $nott, $link);
                case "right":
                    if ($searchtype == 'notequals') {
                        $nott = !$nott;
                    }
                    return $link . ($nott ? ' NOT' : '') . " ({$tocompute} & '{$val}') ";
                case "bool":
                    if (!is_numeric($val)) {
                        if (strcasecmp($val, __('No')) == 0) {
                            $val = 0;
                        } else {
                            if (strcasecmp($val, __('Yes')) == 0) {
                                $val = 1;
                            }
                        }
                    }
                    if ($searchtype == 'notequals') {
                        $nott = !$nott;
                    }
                    // No break here : use number comparaison case
                // No break here : use number comparaison case
                case "count":
                case "number":
                case "decimal":
                case "timestamp":
                    $search = array("/\\&lt;/", "/\\&gt;/");
                    $replace = array("<", ">");
                    $val = preg_replace($search, $replace, $val);
                    if (preg_match("/([<>])([=]*)[[:space:]]*([0-9]+)/", $val, $regs)) {
                        if ($nott) {
                            if ($regs[1] == '<') {
                                $regs[1] = '>';
                            } else {
                                $regs[1] = '<';
                            }
                        }
                        $regs[1] .= $regs[2];
                        return $link . " ({$tocompute} " . $regs[1] . " " . $regs[3] . ") ";
                    }
                    if (is_numeric($val)) {
                        if (isset($searchopt[$ID]["width"])) {
                            $ADD = "";
                            if ($nott && $val != 'NULL' && $val != 'null') {
                                $ADD = " OR {$tocompute} IS NULL";
                            }
                            if ($nott) {
                                return $link . " ({$tocompute} < " . (intval($val) - $searchopt[$ID]["width"]) . "\n                                        OR {$tocompute} > " . (intval($val) + $searchopt[$ID]["width"]) . "\n                                        {$ADD}) ";
                            }
                            return $link . " (({$tocompute} >= " . (intval($val) - $searchopt[$ID]["width"]) . "\n                                      AND {$tocompute} <= " . (intval($val) + $searchopt[$ID]["width"]) . ")\n                                     {$ADD}) ";
                        }
                        if (!$nott) {
                            return " {$link} ({$tocompute} = " . intval($val) . ") ";
                        }
                        return " {$link} ({$tocompute} <> " . intval($val) . ") ";
                    }
                    break;
            }
        }
        // Default case
        if (in_array($searchtype, array('equals', 'notequals', 'under', 'notunder'))) {
            if ((!isset($searchopt[$ID]['searchequalsonfield']) || !$searchopt[$ID]['searchequalsonfield']) && ($table != getTableForItemType($itemtype) || $itemtype == 'AllAssets')) {
                $out = " {$link} (`{$table}`.`id`" . $SEARCH;
            } else {
                $out = " {$link} (`{$table}`.`{$field}`" . $SEARCH;
            }
            if ($searchtype == 'notequals') {
                $nott = !$nott;
            }
            // Add NULL if $val = 0 and not negative search
            // Or negative search on real value
            if (!$nott && $val == 0 || $nott && $val != 0) {
                $out .= " OR `{$table}`.`id` IS NULL";
            }
            $out .= ')';
            return $out;
        }
        $transitemtype = getItemTypeForTable($inittable);
        if (Session::haveTranslations($transitemtype, $field)) {
            return " {$link} (" . self::makeTextCriteria($tocompute, $val, $nott, '') . "\n                          OR " . self::makeTextCriteria($tocomputetrans, $val, $nott, '') . ")";
        }
        return self::makeTextCriteria($tocompute, $val, $nott, $link);
    }

Usage Example

 function showMinimalList($params)
 {
     global $DB, $CFG_GLPI;
     // Instanciate an object to access method
     $item = NULL;
     $itemtype = $this->getType();
     $itemtable = $this->getTable();
     if (class_exists($itemtype)) {
         $item = new $itemtype();
     }
     // Default values of parameters
     $p['link'] = array();
     //
     $p['field'] = array();
     //
     $p['contains'] = array();
     //
     $p['searchtype'] = array();
     //
     $p['sort'] = '1';
     //
     $p['order'] = 'ASC';
     //
     $p['start'] = 0;
     //
     $p['is_deleted'] = 0;
     $p['export_all'] = 0;
     $p['link2'] = '';
     //
     $p['contains2'] = '';
     //
     $p['field2'] = '';
     //
     $p['itemtype2'] = '';
     $p['searchtype2'] = '';
     foreach ($params as $key => $val) {
         $p[$key] = $val;
     }
     if ($p['export_all']) {
         $p['start'] = 0;
     }
     // Manage defautlt seachtype value : for bookmark compatibility
     if (count($p['contains'])) {
         foreach ($p['contains'] as $key => $val) {
             if (!isset($p['searchtype'][$key])) {
                 $p['searchtype'][$key] = 'contains';
             }
         }
     }
     if (is_array($p['contains2']) && count($p['contains2'])) {
         foreach ($p['contains2'] as $key => $val) {
             if (!isset($p['searchtype2'][$key])) {
                 $p['searchtype2'][$key] = 'contains';
             }
         }
     }
     //$target = Toolbox::getItemTypeSearchURL($itemtype);
     $target = $CFG_GLPI["root_doc"] . "/plugins/resources/front/resourceresting.php";
     $limitsearchopt = Search::getCleanedOptions("PluginResourcesResourceResting");
     $LIST_LIMIT = $_SESSION['glpilist_limit'];
     // Set display type for export if define
     $output_type = Search::HTML_OUTPUT;
     if (isset($_GET['display_type'])) {
         $output_type = $_GET['display_type'];
         // Limit to 10 element
         if ($_GET['display_type'] == Search::GLOBAL_SEARCH) {
             $LIST_LIMIT = Search::GLOBAL_DISPLAY_COUNT;
         }
     }
     $PluginResourcesResource = new PluginResourcesResource();
     $entity_restrict = $PluginResourcesResource->isEntityAssign();
     // Get the items to display
     $toview = Search::addDefaultToView($itemtype);
     // Add items to display depending of personal prefs
     $displaypref = DisplayPreference::getForTypeUser("PluginResourcesResourceResting", Session::getLoginUserID());
     if (count($displaypref)) {
         foreach ($displaypref as $val) {
             array_push($toview, $val);
         }
     }
     // Add searched items
     if (count($p['field']) > 0) {
         foreach ($p['field'] as $key => $val) {
             if (!in_array($val, $toview) && $val != 'all' && $val != 'view') {
                 array_push($toview, $val);
             }
         }
     }
     // Add order item
     if (!in_array($p['sort'], $toview)) {
         array_push($toview, $p['sort']);
     }
     // Clean toview array
     $toview = array_unique($toview);
     foreach ($toview as $key => $val) {
         if (!isset($limitsearchopt[$val])) {
             unset($toview[$key]);
         }
     }
     $toview_count = count($toview);
     //// 1 - SELECT
     $query = "SELECT " . Search::addDefaultSelect($itemtype);
     // Add select for all toview item
     foreach ($toview as $key => $val) {
         $query .= Search::addSelect($itemtype, $val, $key, 0);
     }
     $query .= "`" . $itemtable . "`.`id` AS id ";
     //// 2 - FROM AND LEFT JOIN
     // Set reference table
     $query .= " FROM `" . $itemtable . "`";
     // Init already linked tables array in order not to link a table several times
     $already_link_tables = array();
     // Put reference table
     array_push($already_link_tables, $itemtable);
     // Add default join
     $COMMONLEFTJOIN = Search::addDefaultJoin($itemtype, $itemtable, $already_link_tables);
     $query .= $COMMONLEFTJOIN;
     $searchopt = array();
     $searchopt[$itemtype] =& Search::getOptions($itemtype);
     // Add all table for toview items
     foreach ($toview as $key => $val) {
         $query .= Search::addLeftJoin($itemtype, $itemtable, $already_link_tables, $searchopt[$itemtype][$val]["table"], $searchopt[$itemtype][$val]["linkfield"]);
     }
     // Search all case :
     if (in_array("all", $p['field'])) {
         foreach ($searchopt[$itemtype] as $key => $val) {
             // Do not search on Group Name
             if (is_array($val)) {
                 $query .= Search::addLeftJoin($itemtype, $itemtable, $already_link_tables, $searchopt[$itemtype][$key]["table"], $searchopt[$itemtype][$key]["linkfield"]);
             }
         }
     }
     //// 3 - WHERE
     // default string
     $COMMONWHERE = Search::addDefaultWhere($itemtype);
     $first = empty($COMMONWHERE);
     // Add deleted if item have it
     if ($item && $item->maybeDeleted()) {
         $LINK = " AND ";
         if ($first) {
             $LINK = " ";
             $first = false;
         }
         $COMMONWHERE .= $LINK . "`{$itemtable}`.`is_deleted` = '" . $p['is_deleted'] . "' ";
     }
     // Remove template items
     if ($item && $item->maybeTemplate()) {
         $LINK = " AND ";
         if ($first) {
             $LINK = " ";
             $first = false;
         }
         $COMMONWHERE .= $LINK . "`{$itemtable}`.`is_template` = '0' ";
     }
     // Add Restrict to current entities
     if ($entity_restrict) {
         $LINK = " AND ";
         if ($first) {
             $LINK = " ";
             $first = false;
         }
         if ($itemtype == 'Entity') {
             $COMMONWHERE .= getEntitiesRestrictRequest($LINK, $itemtable, 'id', '', true);
         } else {
             if (isset($CFG_GLPI["union_search_type"]["PluginResourcesResource"])) {
                 // Will be replace below in Union/Recursivity Hack
                 $COMMONWHERE .= $LINK . " ENTITYRESTRICT ";
             } else {
                 $COMMONWHERE .= getEntitiesRestrictRequest($LINK, "glpi_plugin_resources_resources", '', '', $PluginResourcesResource->maybeRecursive());
             }
         }
     }
     ///R�cup�ration des groupes de l'utilisateur connect�
     $who = Session::getLoginUserID();
     if (!plugin_resources_haveRight("all", "r")) {
         $LINK = " AND ";
         if ($first) {
             $LINK = " ";
             $first = false;
         }
         $COMMONWHERE .= $LINK . "(`glpi_plugin_resources_resources`.`users_id_recipient` = '{$who}' OR `glpi_plugin_resources_resources`.`users_id` = '{$who}') ";
     }
     $WHERE = "";
     $HAVING = "";
     // Add search conditions
     // If there is search items
     if ($_SESSION["glpisearchcount"][$itemtype] > 0 && count($p['contains']) > 0) {
         for ($key = 0; $key < $_SESSION["glpisearchcount"][$itemtype]; $key++) {
             // if real search (strlen >0) and not all and view search
             if (isset($p['contains'][$key]) && strlen($p['contains'][$key]) > 0) {
                 // common search
                 if ($p['field'][$key] != "all" && $p['field'][$key] != "view") {
                     $LINK = " ";
                     $NOT = 0;
                     $tmplink = "";
                     if (is_array($p['link']) && isset($p['link'][$key])) {
                         if (strstr($p['link'][$key], "NOT")) {
                             $tmplink = " " . str_replace(" NOT", "", $p['link'][$key]);
                             $NOT = 1;
                         } else {
                             $tmplink = " " . $p['link'][$key];
                         }
                     } else {
                         $tmplink = " AND ";
                     }
                     if (isset($searchopt[$itemtype][$p['field'][$key]]["usehaving"])) {
                         // Manage Link if not first item
                         if (!empty($HAVING)) {
                             $LINK = $tmplink;
                         }
                         // Find key
                         $item_num = array_search($p['field'][$key], $toview);
                         $HAVING .= Search::addHaving($LINK, $NOT, $itemtype, $p['field'][$key], $p['searchtype'][$key], $p['contains'][$key], 0, $item_num);
                     } else {
                         // Manage Link if not first item
                         if (!empty($WHERE)) {
                             $LINK = $tmplink;
                         }
                         $WHERE .= Search::addWhere($LINK, $NOT, $itemtype, $p['field'][$key], $p['searchtype'][$key], $p['contains'][$key]);
                     }
                     // view and all search
                 } else {
                     $LINK = " OR ";
                     $NOT = 0;
                     $globallink = " AND ";
                     if (is_array($p['link']) && isset($p['link'][$key])) {
                         switch ($p['link'][$key]) {
                             case "AND":
                                 $LINK = " OR ";
                                 $globallink = " AND ";
                                 break;
                             case "AND NOT":
                                 $LINK = " AND ";
                                 $NOT = 1;
                                 $globallink = " AND ";
                                 break;
                             case "OR":
                                 $LINK = " OR ";
                                 $globallink = " OR ";
                                 break;
                             case "OR NOT":
                                 $LINK = " AND ";
                                 $NOT = 1;
                                 $globallink = " OR ";
                                 break;
                         }
                     } else {
                         $tmplink = " AND ";
                     }
                     // Manage Link if not first item
                     if (!empty($WHERE)) {
                         $WHERE .= $globallink;
                     }
                     $WHERE .= " ( ";
                     $first2 = true;
                     $items = array();
                     if ($p['field'][$key] == "all") {
                         $items = $searchopt[$itemtype];
                     } else {
                         // toview case : populate toview
                         foreach ($toview as $key2 => $val2) {
                             $items[$val2] = $searchopt[$itemtype][$val2];
                         }
                     }
                     foreach ($items as $key2 => $val2) {
                         if (is_array($val2)) {
                             // Add Where clause if not to be done in HAVING CLAUSE
                             if (!isset($val2["usehaving"])) {
                                 $tmplink = $LINK;
                                 if ($first2) {
                                     $tmplink = " ";
                                     $first2 = false;
                                 }
                                 $WHERE .= Search::addWhere($tmplink, $NOT, $itemtype, $key2, $p['searchtype'][$key], $p['contains'][$key]);
                             }
                         }
                     }
                     $WHERE .= " ) ";
                 }
             }
         }
     }
     if (!empty($WHERE) || !empty($COMMONWHERE)) {
         if (!empty($COMMONWHERE)) {
             $WHERE = ' WHERE ' . $COMMONWHERE . (!empty($WHERE) ? ' AND ( ' . $WHERE . ' )' : '');
         } else {
             $WHERE = ' WHERE ' . $WHERE . ' ';
         }
         $first = false;
     }
     $query .= $WHERE;
     //// 7 - Manage GROUP BY
     $GROUPBY = "";
     // Meta Search / Search All / Count tickets
     if (in_array('all', $p['field'])) {
         $GROUPBY = " GROUP BY `" . $itemtable . "`.`id`";
     }
     if (empty($GROUPBY)) {
         foreach ($toview as $key2 => $val2) {
             if (!empty($GROUPBY)) {
                 break;
             }
             if (isset($searchopt[$itemtype][$val2]["forcegroupby"])) {
                 $GROUPBY = " GROUP BY `" . $itemtable . "`.`id`";
             }
         }
     }
     $query .= $GROUPBY;
     //// 4 - ORDER
     $ORDER = " ORDER BY `id` ";
     foreach ($toview as $key => $val) {
         if ($p['sort'] == $val) {
             $ORDER = Search::addOrderBy($itemtype, $p['sort'], $p['order'], $key);
         }
     }
     $query .= $ORDER;
     // Get it from database
     if ($result = $DB->query($query)) {
         $numrows = $DB->numrows($result);
         $globallinkto = Search::getArrayUrlLink("field", $p['field']) . Search::getArrayUrlLink("link", $p['link']) . Search::getArrayUrlLink("contains", $p['contains']) . Search::getArrayUrlLink("field2", $p['field2']) . Search::getArrayUrlLink("contains2", $p['contains2']) . Search::getArrayUrlLink("itemtype2", $p['itemtype2']) . Search::getArrayUrlLink("link2", $p['link2']);
         $parameters = "sort=" . $p['sort'] . "&amp;order=" . $p['order'] . $globallinkto;
         if ($output_type == Search::GLOBAL_SEARCH) {
             if (class_exists($itemtype)) {
                 echo "<div class='center'><h2>" . $this->getTypeName();
                 // More items
                 if ($numrows > $p['start'] + Search::GLOBAL_DISPLAY_COUNT) {
                     echo " <a href='{$target}?{$parameters}'>" . __('All') . "</a>";
                 }
                 echo "</h2></div>\n";
             } else {
                 return false;
             }
         }
         if ($p['start'] < $numrows) {
             // Pager
             if ($output_type == Search::HTML_OUTPUT) {
                 Html::printPager($p['start'], $numrows, $target, $parameters, $itemtype);
             }
             //massive action
             $sel = "";
             if (isset($_GET["select"]) && $_GET["select"] == "all") {
                 $sel = "checked";
             }
             // Add toview elements
             $nbcols = $toview_count;
             if ($output_type == Search::HTML_OUTPUT) {
                 // HTML display - massive modif
                 $nbcols++;
             }
             // Define begin and end var for loop
             // Search case
             $begin_display = $p['start'];
             $end_display = $p['start'] + $LIST_LIMIT;
             // Export All case
             if ($p['export_all']) {
                 $begin_display = 0;
                 $end_display = $numrows;
             }
             // Display List Header
             echo Search::showHeader($output_type, $end_display - $begin_display + 1, $nbcols);
             $header_num = 1;
             // Display column Headers for toview items
             echo Search::showNewLine($output_type);
             // Display column Headers for toview items
             foreach ($toview as $key => $val) {
                 $linkto = '';
                 if (!isset($searchopt[$itemtype][$val]['nosort']) || !$searchopt[$itemtype][$val]['nosort']) {
                     $linkto = "{$target}?itemtype={$itemtype}&amp;sort=" . $val . "&amp;order=" . ($p['order'] == "ASC" ? "DESC" : "ASC") . "&amp;start=" . $p['start'] . $globallinkto;
                 }
                 echo Search::showHeaderItem($output_type, $searchopt[$itemtype][$val]["name"], $header_num, $linkto, $p['sort'] == $val, $p['order']);
             }
             // End Line for column headers
             echo Search::showEndLine($output_type);
             $DB->data_seek($result, $p['start']);
             // Define begin and end var for loop
             // Search case
             $i = $begin_display;
             // Init list of items displayed
             if ($output_type == Search::HTML_OUTPUT) {
                 Session::initNavigateListItems($itemtype);
             }
             // Num of the row (1=header_line)
             $row_num = 1;
             // Display Loop
             while ($i < $numrows && $i < $end_display) {
                 $item_num = 1;
                 $data = $DB->fetch_array($result);
                 $i++;
                 $row_num++;
                 echo Search::showNewLine($output_type, $i % 2);
                 Session::addToNavigateListItems($itemtype, $data['id']);
                 foreach ($toview as $key => $val) {
                     echo Search::showItem($output_type, Search::giveItem($itemtype, $val, $data, $key), $item_num, $row_num, Search::displayConfigItem($itemtype, $val, $data, $key));
                 }
                 echo Search::showEndLine($output_type);
             }
             // Close Table
             $title = "";
             // Create title
             if ($output_type == Search::PDF_OUTPUT_PORTRAIT || $output_type == Search::PDF_OUTPUT_LANDSCAPE) {
                 $title .= __('List of non contract periods', 'resources');
             }
             // Display footer
             echo Search::showFooter($output_type, $title);
             // Pager
             if ($output_type == Search::HTML_OUTPUT) {
                 echo "<br>";
                 Html::printPager($p['start'], $numrows, $target, $parameters);
             }
         } else {
             echo Search::showError($output_type);
         }
     }
 }
All Usage Examples Of Search::addWhere