diff --git a/setup.php b/setup.php
index 387359a..1b7b454 100644
--- a/setup.php
+++ b/setup.php
@@ -1,37 +1,37 @@
.
- --------------------------------------------------------------------------
- @package modifications
- @author Stevenes Donato
- @copyright Copyright (c) 2020 Stevenes Donato
- @license GPLv3
- http://www.gnu.org/licenses/gpl.txt
- @link https://github.com/stdonato/glpi-modifications
- @link http://www.glpi-project.org/
- @since 2018
- --------------------------------------------------------------------------
- */
-
-/**
- * @name plugin_mod_install
- * @access public
- * @return boolean
+/*
+ *
+ This file is part of the Modifications plugin.
+
+ Order plugin is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ Stevenes Donato; either version 2 of the License, or
+ (at your option) any later version.
+
+ Order plugin is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GLPI; along with itilcategorygroups. If not, see .
+ --------------------------------------------------------------------------
+ @package modifications
+ @author Stevenes Donato
+ @copyright Copyright (c) 2020 Stevenes Donato
+ @license GPLv3
+ http://www.gnu.org/licenses/gpl.txt
+ @link https://github.com/stdonato/glpi-modifications
+ @link http://www.glpi-project.org/
+ @since 2018
+ --------------------------------------------------------------------------
+ */
+
+/**
+ * @name plugin_mod_install
+ * @access public
+ * @return boolean
*/
@@ -65,7 +65,7 @@ function plugin_version_mod(){
global $DB, $LANG;
return array('name' => __('GLPI Modifications'),
- 'version' => '1.5.3',
+ 'version' => '1.5.4',
'author' => ' Stevenes Donato ',
'license' => 'GPLv2+',
'homepage' => 'https://github.com/stdonato/glpi-modifications',
@@ -88,4 +88,6 @@ function plugin_mod_check_config($verbose=false){
}
return true;
}
+
+
?>
diff --git a/src/inc/auth.class.php b/src/inc/auth.class.php
index 6921f65..147a17b 100644
--- a/src/inc/auth.class.php
+++ b/src/inc/auth.class.php
@@ -664,8 +664,7 @@ function login($login_name, $login_password, $noauto = false, $remember_me = fal
$ds = AuthLdap::connectToServer($ldap_method["host"],
$ldap_method["port"],
$ldap_method["rootdn"],
- Toolbox::decrypt($ldap_method["rootdn_passwd"],
- GLPIKEY),
+ Toolbox::decrypt($ldap_method["rootdn_passwd"]),
$ldap_method["use_tls"],
$ldap_method["deref_option"]);
diff --git a/src/inc/search.class.php b/src/inc/search.class.php
index 4656565..c2c6c59 100644
--- a/src/inc/search.class.php
+++ b/src/inc/search.class.php
@@ -445,27 +445,27 @@ static function prepareDatasForSearch($itemtype, array $params, array $forcedisp
foreach ($criteria as $criterion) {
// recursive call
if (isset($criterion['criteria'])) {
- return $parse_criteria($criterion['criteria']);
- }
-
- // normal behavior
- if (isset($criterion['field'])
- && !in_array($criterion['field'], $data['toview'])) {
- if ($criterion['field'] != 'all'
- && $criterion['field'] != 'view'
- && (!isset($criterion['meta'])
- || !$criterion['meta'])) {
- array_push($data['toview'], $criterion['field']);
- } else if ($criterion['field'] == 'all') {
- $data['search']['all_search'] = true;
- } else if ($criterion['field'] == 'view') {
- $data['search']['view_search'] = true;
+ $parse_criteria($criterion['criteria']);
+ } else {
+ // normal behavior
+ if (isset($criterion['field'])
+ && !in_array($criterion['field'], $data['toview'])) {
+ if ($criterion['field'] != 'all'
+ && $criterion['field'] != 'view'
+ && (!isset($criterion['meta'])
+ || !$criterion['meta'])) {
+ array_push($data['toview'], $criterion['field']);
+ } else if ($criterion['field'] == 'all') {
+ $data['search']['all_search'] = true;
+ } else if ($criterion['field'] == 'view') {
+ $data['search']['view_search'] = true;
+ }
}
- }
- if (isset($criterion['value'])
- && (strlen($criterion['value']) > 0)) {
- $data['search']['no_search'] = false;
+ if (isset($criterion['value'])
+ && (strlen($criterion['value']) > 0)) {
+ $data['search']['no_search'] = false;
+ }
}
}
};
@@ -1140,7 +1140,6 @@ static function constructAdditionalSqlForMetacriteria($criteria = [],
if (!in_array(getTableForItemType($m_itemtype), $already_link_tables)) {
$FROM .= self::addMetaLeftJoin($data['itemtype'], $m_itemtype,
$already_link_tables,
- $criterion['value'] == "NULL" || strstr($criterion['link'], "NOT"),
$sopt["joinparams"]);
}
@@ -1940,14 +1939,6 @@ static function computeTitle($data) {
$gdname = '';
$valuename = '';
- if (isset($criteria['meta']) && $criteria['meta']) {
- $searchoptname = sprintf(__('%1$s / %2$s'),
- $criteria['itemtype'],
- $searchopt[$criteria['field']]["name"]);
- } else {
- $searchoptname = $searchopt[$criteria['field']]["name"];
- }
-
switch ($criteria['field']) {
case "all" :
$titlecontain = sprintf(__('%1$s %2$s'), $titlecontain, __('All'));
@@ -1958,6 +1949,14 @@ static function computeTitle($data) {
break;
default :
+ if (isset($criteria['meta']) && $criteria['meta']) {
+ $searchoptname = sprintf(__('%1$s / %2$s'),
+ $criteria['itemtype'],
+ $searchopt[$criteria['field']]["name"]);
+ } else {
+ $searchoptname = $searchopt[$criteria['field']]["name"];
+ }
+
$titlecontain = sprintf(__('%1$s %2$s'), $titlecontain, $searchoptname);
$itemtype = getItemTypeForTable($searchopt[$criteria['field']]["table"]);
$valuename = '';
@@ -2433,7 +2432,7 @@ static function displayCriteria($request = []) {
global $CFG_GLPI;
if (!isset($request["itemtype"])
- || !isset($request["num"]) ) {
+ || !isset($request["num"])) {
return "";
}
@@ -2543,6 +2542,16 @@ static function displayCriteria($request = []) {
if (isset($criteria['field'])) {
$value = $criteria['field'];
+ } else if (isset($request['from_meta'])
+ && $request['from_meta']
+ && count($values)) {
+ // Get first field of the first category
+ foreach ($values as $categories) {
+ foreach ($categories as $field_id => $field_name) {
+ $value = $field_id;
+ break 2;
+ }
+ }
}
$rand = Dropdown::showFromArray("criteria{$prefix}[$num][field]", $values, [
@@ -2604,7 +2613,7 @@ static function displayMetaCriteria($request = []) {
global $CFG_GLPI;
if (!isset($request["itemtype"])
- || !isset($request["num"]) ) {
+ || !isset($request["num"])) {
return "";
}
@@ -2824,7 +2833,7 @@ static function displaySearchoption($request = []) {
global $CFG_GLPI;
if (!isset($request["itemtype"])
|| !isset($request["field"])
- || !isset($request["num"]) ) {
+ || !isset($request["num"])) {
return "";
}
@@ -3153,7 +3162,9 @@ static function addOrderBy($itemtype, $ID, $order) {
$addtable = '';
- if (($table != getTableForItemType($itemtype))
+ $is_fkey_composite_on_self = getTableNameForForeignKeyField($searchopt[$ID]["linkfield"]) == $table
+ && $searchopt[$ID]["linkfield"] != getForeignKeyFieldForTable($table);
+ if (($is_fkey_composite_on_self || $table != getTableForItemType($itemtype))
&& ($searchopt[$ID]["linkfield"] != getForeignKeyFieldForTable($table))) {
$addtable .= "_".$searchopt[$ID]["linkfield"];
}
@@ -3205,7 +3216,7 @@ static function addOrderBy($itemtype, $ID, $order) {
".$table.$addtable.".$name2 $order,
".$table.$addtable.".`name` $order";
}
- return " ORDER BY `".$table."`.`name` $order";
+ return " ORDER BY `".$table.$addtable."`.`name` $order";
case "glpi_networkequipments.ip" :
case "glpi_ipaddresses.name" :
@@ -3278,6 +3289,7 @@ static function addDefaultToView($itemtype, $params) {
// Add entity view :
if (Session::isMultiEntitiesMode()
+ && $item->isEntityAssign()
&& (isset($CFG_GLPI["union_search_type"][$itemtype])
|| ($item && $item->maybeRecursive())
|| isset($_SESSION['glpiactiveentities']) && (count($_SESSION["glpiactiveentities"]) > 1))) {
@@ -3295,6 +3307,7 @@ static function addDefaultToView($itemtype, $params) {
* @return select string
**/
static function addDefaultSelect($itemtype) {
+ global $DB;
$itemtable = getTableForItemType($itemtype);
$item = null;
@@ -3322,7 +3335,12 @@ static function addDefaultSelect($itemtype) {
if ($itemtable == 'glpi_entities') {
$ret .= "`$itemtable`.`id` AS entities_id, '1' AS is_recursive, ";
} else if ($mayberecursive) {
- $ret .= "`$itemtable`.`entities_id`, `$itemtable`.`is_recursive`, ";
+ $ret .= $DB->quoteName("$itemtable.entities_id").", ";
+ //do not include field if not present in table
+ $item->getEmpty();
+ if (isset($item->fields['is_recursive'])) {
+ $ret .= $DB->quoteName("$itemtable.is_recursive").", ";
+ }
}
return $ret;
}
@@ -3355,7 +3373,9 @@ static function addSelect($itemtype, $ID, $meta = 0, $meta_type = 0) {
$complexjoin = self::computeComplexJoinID($searchopt[$ID]['joinparams']);
}
- if (((($table != getTableForItemType($itemtype))
+ $is_fkey_composite_on_self = getTableNameForForeignKeyField($searchopt[$ID]["linkfield"]) == $table
+ && $searchopt[$ID]["linkfield"] != getForeignKeyFieldForTable($table);
+ if (((($is_fkey_composite_on_self || $table != getTableForItemType($itemtype))
&& (!isset($CFG_GLPI["union_search_type"][$itemtype])
|| ($CFG_GLPI["union_search_type"][$itemtype] != $table)))
|| !empty($complexjoin))
@@ -3558,6 +3578,19 @@ static function addSelect($itemtype, $ID, $meta = 0, $meta_type = 0) {
}
break;
+ case "glpi_itilfollowups.content":
+ case "glpi_tickettasks.content":
+ case "glpi_changetasks.content":
+ // force ordering by date desc
+ return " GROUP_CONCAT(DISTINCT CONCAT(IFNULL($tocompute, '".self::NULLVALUE."'),
+ '".self::SHORTSEP."',$tocomputeid)
+ ORDER BY `$table$addtable`.`date` DESC
+ SEPARATOR '".self::LONGSEP."')
+ AS `".$NAME."`,
+
+ $ADDITONALFIELDS";
+ break;
+
default:
break;
}
@@ -3877,6 +3910,85 @@ static function addDefaultWhere($itemtype) {
$condition = SavedSearch::addVisibilityRestrict();
break;
+ case 'TicketTask':
+ // Filter on is_private
+ $allowed_is_private = [];
+ if (Session::haveRight(TicketTask::$rightname, CommonITILTask::SEEPRIVATE)) {
+ $allowed_is_private[] = 1;
+ }
+ if (Session::haveRight(TicketTask::$rightname, CommonITILTask::SEEPUBLIC)) {
+ $allowed_is_private[] = 0;
+ }
+
+ // If the user can't see public and private
+ if (!count($allowed_is_private)) {
+ $condition = "0 = 1";
+ break;
+ }
+
+ $in = "IN ('" . implode("','", $allowed_is_private) . "')";
+ $condition = "(`glpi_tickettasks`.`is_private` $in ";
+
+ // Check for assigned or created tasks
+ $condition .= "OR `users_id` = " . Session::getLoginUserID() . " ";
+ $condition .= "OR `users_id_tech` = " . Session::getLoginUserID() . " ";
+
+ // Check for parent item visibility unless the user can see all the
+ // possible parents
+ if (!Session::haveRight('ticket', Ticket::READALL)) {
+ $condition .= "AND " . TicketTask::buildParentCondition();
+ }
+
+ $condition .= ")";
+
+ break;
+
+ case 'ITILFollowup':
+ // Filter on is_private
+ $allowed_is_private = [];
+ if (Session::haveRight(ITILFollowup::$rightname, ITILFollowup::SEEPRIVATE)) {
+ $allowed_is_private[] = 1;
+ }
+ if (Session::haveRight(ITILFollowup::$rightname, ITILFollowup::SEEPUBLIC)) {
+ $allowed_is_private[] = 0;
+ }
+
+ // If the user can't see public and private
+ if (!count($allowed_is_private)) {
+ $condition = "0 = 1";
+ break;
+ }
+
+ $in = "IN ('" . implode("','", $allowed_is_private) . "')";
+ $condition = "(`glpi_itilfollowups`.`is_private` $in ";
+
+ // Now filter on parent item visiblity
+ $condition .= "AND (";
+
+ // Filter for "ticket" parents
+ $condition .= ITILFollowup::buildParentCondition(\Ticket::getType());
+ $condition .= "OR ";
+
+ // Filter for "change" parents
+ $condition .= ITILFollowup::buildParentCondition(
+ \Change::getType(),
+ 'changes_id',
+ "glpi_changes_users",
+ "glpi_changes_groups"
+ );
+ $condition .= "OR ";
+
+ // Fitler for "problem" parents
+ $condition .= ITILFollowup::buildParentCondition(
+ \Problem::getType(),
+ 'problems_id',
+ "glpi_problems_users",
+ "glpi_groups_problems"
+ );
+ $condition .= "))";
+
+ break;
+
default :
// Plugin can override core definition for its type
if ($plug = isPluginItemType($itemtype)) {
@@ -3892,7 +4004,6 @@ static function addDefaultWhere($itemtype) {
return $condition;
}
-
/**
* Generic Function to add where to a request
*
@@ -3917,8 +4028,10 @@ static function addWhere($link, $nott, $itemtype, $ID, $searchtype, $val, $meta
$inittable = $table;
$addtable = '';
+ $is_fkey_composite_on_self = getTableNameForForeignKeyField($searchopt[$ID]["linkfield"]) == $table
+ && $searchopt[$ID]["linkfield"] != getForeignKeyFieldForTable($table);
if (($table != 'asset_types')
- && ($table != getTableForItemType($itemtype))
+ && ($is_fkey_composite_on_self || $table != getTableForItemType($itemtype))
&& ($searchopt[$ID]["linkfield"] != getForeignKeyFieldForTable($table))) {
$addtable = "_".$searchopt[$ID]["linkfield"];
$table .= $addtable;
@@ -3950,12 +4063,11 @@ static function addWhere($link, $nott, $itemtype, $ID, $searchtype, $val, $meta
case "date" :
case "date_delay" :
$force_day = true;
- if ($searchopt[$ID]["datatype"] == 'datetime') {
+ if ($searchopt[$ID]["datatype"] == 'datetime'
+ && !(strstr($val, 'BEGIN') || strstr($val, 'LAST') || strstr($val, 'DAY'))
+ ) {
$force_day = false;
}
- if (strstr($val, 'BEGIN') || strstr($val, 'LAST')) {
- $force_day = true;
- }
$val = Html::computeGenericDateTimeSearch($val, $force_day);
@@ -4028,7 +4140,19 @@ static function addWhere($link, $nott, $itemtype, $ID, $searchtype, $val, $meta
case "glpi_users.name" :
if ($itemtype == 'User') { // glpi_users case / not link table
if (in_array($searchtype, ['equals', 'notequals'])) {
- return " $link `$table`.`id`".$SEARCH;
+ $search_str = "`$table`.`id`" . $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))) {
+ $search_str .= " OR `$table`.`id` IS NULL";
+ }
+
+ return " $link ($search_str)";
}
return self::makeTextCriteria("`$table`.`$field`", $val, $nott, $link);
}
@@ -4263,6 +4387,15 @@ static function addWhere($link, $nott, $itemtype, $ID, $searchtype, $val, $meta
}
break;
+ case "glpi_notifications.event" :
+ if (in_array($searchtype, ['equals', 'notequals']) && strpos($val, self::SHORTSEP)) {
+ $not = 'notequals' === $searchtype ? 'NOT' : '';
+ list($itemtype_val, $event_val) = explode(self::SHORTSEP, $val);
+ return " $link $not(`$table`.`event` = '$event_val'
+ AND `$table`.`itemtype` = '$itemtype_val')";
+ }
+ break;
+
}
//// Default cases
@@ -4421,6 +4554,8 @@ static function addWhere($link, $nott, $itemtype, $ID, $searchtype, $val, $meta
return $link." ($tocompute ".$regs[1]." ".$regs[3].") ";
}
if (is_numeric($val)) {
+ $numeric_val = floatval($val);
+
if (isset($searchopt[$ID]["width"])) {
$ADD = "";
if ($nott
@@ -4428,18 +4563,18 @@ static function addWhere($link, $nott, $itemtype, $ID, $searchtype, $val, $meta
$ADD = " OR $tocompute IS NULL";
}
if ($nott) {
- return $link." ($tocompute < ".(intval($val) - $searchopt[$ID]["width"])."
- OR $tocompute > ".(intval($val) + $searchopt[$ID]["width"])."
+ return $link." ($tocompute < ".($numeric_val - $searchopt[$ID]["width"])."
+ OR $tocompute > ".($numeric_val + $searchopt[$ID]["width"])."
$ADD) ";
}
- return $link." (($tocompute >= ".(intval($val) - $searchopt[$ID]["width"])."
- AND $tocompute <= ".(intval($val) + $searchopt[$ID]["width"]).")
+ return $link." (($tocompute >= ".($numeric_val - $searchopt[$ID]["width"])."
+ AND $tocompute <= ".($numeric_val + $searchopt[$ID]["width"]).")
$ADD) ";
}
if (!$nott) {
- return " $link ($tocompute = ".(intval($val)).") ";
+ return " $link ($tocompute = $numeric_val) ";
}
- return " $link ($tocompute <> ".(intval($val)).") ";
+ return " $link ($tocompute <> $numeric_val) ";
}
break;
}
@@ -4682,9 +4817,13 @@ static function addLeftJoin($itemtype, $ref_table, array &$already_link_tables,
$complexjoin = self::computeComplexJoinID($joinparams);
+ $is_fkey_composite_on_self = getTableNameForForeignKeyField($linkfield) == $ref_table
+ && $linkfield != getForeignKeyFieldForTable($ref_table);
+
// Auto link
if (($ref_table == $new_table)
- && empty($complexjoin)) {
+ && empty($complexjoin)
+ && !$is_fkey_composite_on_self) {
$transitemtype = getItemTypeForTable($new_table);
if (Session::haveTranslations($transitemtype, $field)) {
$transAS = $nt.'_trans';
@@ -4932,18 +5071,12 @@ static function addLeftJoin($itemtype, $ref_table, array &$already_link_tables,
* @param $from_type reference item type ID
* @param $to_type item type to add
* @param $already_link_tables2 array of tables already joined
- * @param $nullornott Used LEFT JOIN (null generation)
- * or INNER JOIN for strict join
*
* @return Meta Left join string
**/
static function addMetaLeftJoin($from_type, $to_type, array &$already_link_tables2,
- $nullornott, $joinparams = []) {
-
- $LINK = " INNER JOIN ";
- if ($nullornott) {
- $LINK = " LEFT JOIN ";
- }
+ $joinparams = []) {
+ $LINK = " LEFT JOIN ";
$from_table = getTableForItemType($from_type);
$from_fk = getForeignKeyFieldForTable($from_table);
@@ -5677,16 +5810,24 @@ static function giveItem($itemtype, $ID, array $data, $meta = 0,
}
$color = $_SESSION['glpiduedateok_color'];
- $bar_color = 'green';
if ($less_crit < $less_crit_limit) {
$color = $_SESSION['glpiduedatecritical_color'];
- $bar_color = 'red';
} else if ($less_warn < $less_warn_limit) {
$color = $_SESSION['glpiduedatewarning_color'];
- $bar_color = 'yellow';
}
- // Stevenes Donato
+ if (!isset($so['datatype'])) {
+ $so['datatype'] = 'progressbar';
+ }
+
+ $progressbar_data = [
+ 'text' => Html::convDateTime($data[$ID][0]['name']),
+ 'percent' => $percentage,
+ 'percent_text' => $percentage_text,
+ 'color' => $color
+ ];
+
+ // Stevenes Donato
//bar colors
if($percentage == 100) { $cor = "progress-bar-danger"; }
@@ -5708,7 +5849,7 @@ static function giveItem($itemtype, $ID, array $data, $meta = 0,
}
break;
- // Stevenes Donato
+ // Stevenes Donato
case "glpi_softwarelicenses.number" :
if ($data[$ID][0]['min'] == -1) {
@@ -5907,8 +6048,7 @@ static function giveItem($itemtype, $ID, array $data, $meta = 0,
if ($data[$ID][0]['is_active']) {
return "".
- "";
- "".__('See planning')."";
+ "".__('See planning')."";
} else {
return " ";
}
@@ -7215,7 +7355,7 @@ static function showHeader($type, $rows, $cols, $fixed = 0) {
header('Pragma: private'); /// IE BUG + SSL
header('Cache-control: private, must-revalidate'); /// IE BUG + SSL
header("Content-disposition: filename=glpi.csv");
- header('Content-type: application/octetstream');
+ header('Content-type: text/csv');
// zero width no break space (for excel)
echo"\xEF\xBB\xBF";
break;
@@ -7489,6 +7629,11 @@ static function makeTextSearchValue($val) {
($matches[1] != '^' ? '%' : '') .
trim($matches[2]) .
($matches[3] != '$' ? '%' : '');
+ } else if (isset($matches[1])
+ && strlen(trim($matches[1])) == 1
+ && (!isset($matches[3]) || empty($matches[3]))) {
+ // this case is for search with only ^, so mean the field is not empty / not null
+ $search = '%';
}
return $search;
}