Commit c519aba7 authored by Alexandre Delaunay's avatar Alexandre Delaunay Committed by Johan Cwiklinski

fix nested criteria when searchoption id is not already displayed

fix tests
parent e494bef9
......@@ -440,24 +440,38 @@ class Search {
}
if (count($p['criteria']) > 0) {
foreach ($p['criteria'] as $criterion) {
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;
// use a recursive clojure to push searchoption when using nested criteria
$parse_criteria = function($criteria) use (&$parse_criteria, &$data) {
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;
}
}
}
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;
}
}
}
};
// call the clojure
$parse_criteria($p['criteria']);
}
if (count($p['metacriteria'])) {
......@@ -946,10 +960,15 @@ class Search {
$tmplink = " AND ";
}
// Manage Link if not first item
if (!empty($sql)) {
$LINK = $tmplink;
}
if (isset($criterion['criteria']) && count($criterion['criteria'])) {
$sub_sql = self::constructCriteriaSQL($criterion['criteria'], $data, $searchopt, $is_having);
if (strlen($sub_sql)) {
$sql .= "$tmplink ($sub_sql)";
$sql .= "$LINK ($sub_sql)";
}
} else if (isset($searchopt[$criterion['field']]["usehaving"])) {
if (!$is_having) {
......@@ -957,10 +976,6 @@ class Search {
continue;
}
// Manage Link if not first item
if (!empty($sql)) {
$LINK = $tmplink;
}
// Find key
$item_num = array_search($criterion['field'], $data['tocompute']);
$new_having = self::addHaving($LINK, $NOT, $itemtype,
......@@ -975,10 +990,6 @@ class Search {
continue;
}
// Manage Link if not first item
if (!empty($sql)) {
$LINK = $tmplink;
}
$new_where = self::addWhere($LINK, $NOT, $itemtype, $criterion['field'],
$criterion['searchtype'], $criterion['value'], $meta);
if ($new_where !== false) {
......
......@@ -339,9 +339,9 @@ class Search extends DbTestCase {
'value' => 'test',
], [
'link' => 'OR',
'field' => 'view',
'field' => 2,
'searchtype' => 'contains',
'value' => 'toto',
'value' => 'test2',
], [
'link' => 'AND',
'field' => 3,
......@@ -351,15 +351,14 @@ class Search extends DbTestCase {
'link' => 'AND',
'criteria' => [
[
'link' => 'AND',
'field' => 'view',
'searchtype' => 'contains',
'value' => 'test3',
'field' => 70,
'searchtype' => 'equals',
'value' => 2,
], [
'link' => 'AND+NOT',
'field' => 'view',
'searchtype' => 'contains',
'value' => 'test4',
'link' => 'OR',
'field' => 70,
'searchtype' => 'equals',
'value' => 3,
]
]
]
......@@ -376,18 +375,73 @@ class Search extends DbTestCase {
->array['last_errors']->isIdenticalTo([])
->array['data']->isNotEmpty();
$expected_where = "WHERE\s*`glpi_computers`\.`is_deleted`\s*=\s*0\s*AND\s*`glpi_computers`\.`is_template`\s*=\s*0\s*AND\s*\(\s*`glpi_computers`\.`entities_id`\s*IN\s*\('1',\s*'2',\s*'3'\)\s*OR\s*\(\s*`glpi_computers`\.`is_recursive`='1'\s*AND\s*`glpi_computers`\.`entities_id`\s*IN\s*\('0'\)\s*\)\s*\)\s*AND\s*\(\s*\(\s*`glpi_computers`\.`name`\s*LIKE\s*'%test%'\s*\)\s*AND\s*\(\s*`glpi_softwares`\.`id`\s*=\s*'10784'\)\s*OR\s*\(\s*\(\s*\(\s*`glpi_computers`\.`id`\s*LIKE\s*'%test%'\s*\)\s*OR\s*\(\s*`glpi_computers`\.`name`\s*LIKE\s*'%toto%'\s*\)\s*OR\s*\(\s*`glpi_entities`\.`completename`\s*LIKE\s*'%toto%'\s*\)\s*OR\s*\(\s*`glpi_states`\.`completename`\s*LIKE\s*'%toto%'\s*\)\s*OR\s*\(\s*`glpi_manufacturers`\.`name`\s*LIKE\s*'%toto%'\s*\)\s*OR\s*\(\s*`glpi_computers`\.`serial`\s*LIKE\s*'%toto%'\s*\)\s*OR\s*\(\s*`glpi_computertypes`\.`name`\s*LIKE\s*'%toto%'\s*\)\s*OR\s*\(\s*`glpi_computermodels`\.`name`\s*LIKE\s*'%toto%'\s*\)\s*OR\s*\(\s*`glpi_operatingsystems_.*`\.`name`\s*LIKE\s*'%toto%'\s*\)\s*OR\s*\(\s*`glpi_locations`\.`completename`\s*LIKE\s*'%toto%'\s*\)\s*OR\s*\(\s*CONVERT\(`glpi_computers`\.`date_mod`\s*USING\s*utf8\)\s*LIKE\s*'%toto%'\s*\)\)\s*AND\s*\(\s*`glpi_locations`\.`id`\s*=\s*'11'\)\s*AND\s*\(\s*\(\s*\(\s*\(\s*`glpi_computers`\.`name`\s*LIKE\s*'%test3%'\s*\)\s*OR\s*\(\s*`glpi_entities`\.`completename`\s*LIKE\s*'%test3%'\s*\)\s*OR\s*\(\s*`glpi_states`\.`completename`\s*LIKE\s*'%test3%'\s*\)\s*OR\s*\(\s*`glpi_manufacturers`\.`name`\s*LIKE\s*'%test3%'\s*\)\s*OR\s*\(\s*`glpi_computers`\.`serial`\s*LIKE\s*'%test3%'\s*\)\s*OR\s*\(\s*`glpi_computertypes`\.`name`\s*LIKE\s*'%test3%'\s*\)\s*OR\s*\(\s*`glpi_computermodels`\.`name`\s*LIKE\s*'%test3%'\s*\)\s*OR\s*\(\s*`glpi_operatingsystems_.*`\.`name`\s*LIKE\s*'%test3%'\s*\)\s*OR\s*\(\s*`glpi_locations`\.`completename`\s*LIKE\s*'%test3%'\s*\)\s*OR\s*\(\s*CONVERT\(`glpi_computers`\.`date_mod`\s*USING\s*utf8\)\s*LIKE\s*'%test3%'\s*\)\s*\)\s*AND\s*\(\s*`glpi_computers`\.`name`\s*LIKE\s*'%test4%'\s*\)\s*OR\s*\(\s*`glpi_entities`\.`completename`\s*LIKE\s*'%test4%'\s*\)\s*OR\s*\(\s*`glpi_states`\.`completename`\s*LIKE\s*'%test4%'\s*\)\s*OR\s*\(\s*`glpi_manufacturers`\.`name`\s*LIKE\s*'%test4%'\s*\)\s*OR\s*\(\s*`glpi_computers`\.`serial`\s*LIKE\s*'%test4%'\s*\)\s*OR\s*\(\s*`glpi_computertypes`\.`name`\s*LIKE\s*'%test4%'\s*\)\s*OR\s*\(\s*`glpi_computermodels`\.`name`\s*LIKE\s*'%test4%'\s*\)\s*OR\s*\(\s*`glpi_operatingsystems_.*`\.`name`\s*LIKE\s*'%test4%'\s*\)\s*OR\s*\(\s*`glpi_locations`\.`completename`\s*LIKE\s*'%test4%'\s*\)\s*OR\s*\(\s*CONVERT\(`glpi_computers`\.`date_mod`\s*USING\s*utf8\)\s*LIKE\s*'%test4%'\s*\)\s*\)\s*\)\s*\)\s*\)";
$this->array($data)
->hasKey('sql')
->array['sql']
->hasKey('search');
$this->string($data['sql']['search'])
// join parts
->matches('/INNER JOIN\s*`glpi_computers_softwareversions`\s*AS `glpi_computers_softwareversions_Software`/im')
->matches('/INNER JOIN\s*`glpi_softwareversions`\s*AS `glpi_softwareversions_Software`/im')
->matches('/INNER JOIN\s*`glpi_softwares`\s*ON\s*\(`glpi_softwareversions_Software`\.`softwares_id`\s*=\s*`glpi_softwares`\.`id`\)/im')
// match where parts
->contains("`glpi_computers`.`is_deleted` = 0")
->contains("AND `glpi_computers`.`is_template` = 0")
->contains("`glpi_computers`.`entities_id` IN ('1', '2', '3')")
->contains("OR (`glpi_computers`.`is_recursive`='1'".
" AND `glpi_computers`.`entities_id` IN ('0'))")
->contains("`glpi_computers`.`name` LIKE '%test%'")
->contains("AND (`glpi_softwares`.`id` = '10784')")
->contains("OR (`glpi_computers`.`id` LIKE '%test2%'")
->contains("AND (`glpi_locations`.`id` = '11')")
->contains("(`glpi_users`.`id` = '2')")
->contains("OR (`glpi_users`.`id` = '3')");
}
// Check meta criteria add correct jointures
function testViewCriterion() {
$data = $this->doSearch('Computer', [
'reset' => 'reset',
'is_deleted' => 0,
'start' => 0,
'search' => 'Search',
'criteria' => [
[
'link' => 'AND',
'field' => 'view',
'searchtype' => 'contains',
'value' => 'test',
],
]
]);
// check for sql error (data key missing or empty)
$this->array($data)
->hasKey('data')
->array['last_errors']->isIdenticalTo([])
->array['data']->isNotEmpty();
// Check sql generation
$this->array($data)
->hasKey('sql')
->array['sql']
->hasKey('search')
->string['search']
->contains("INNER JOIN `glpi_computers_softwareversions` AS `glpi_computers_softwareversions_Software`")
->contains("INNER JOIN `glpi_softwareversions` AS `glpi_softwareversions_Software`")
->contains("INNER JOIN `glpi_softwares` ON (`glpi_softwareversions_Software`.`softwares_id` = `glpi_softwares`.`id`) ")
->matches('#'.$expected_where.'#');
->hasKey('search');
$this->string($data['sql']['search'])
->contains("`glpi_computers`.`is_deleted` = 0")
->contains("AND `glpi_computers`.`is_template` = 0")
->contains("`glpi_computers`.`entities_id` IN ('1', '2', '3')")
->contains("OR (`glpi_computers`.`is_recursive`='1'".
" AND `glpi_computers`.`entities_id` IN ('0'))")
->matches("/`glpi_computers`\.`name` LIKE '%test%'/")
->matches("/OR\s*\(`glpi_entities`\.`completename`\s*LIKE '%test%'\s*\)/")
->matches("/OR\s*\(`glpi_states`\.`completename`\s*LIKE '%test%'\s*\)/")
->matches("/OR\s*\(`glpi_manufacturers`\.`name`\s*LIKE '%test%'\s*\)/")
->matches("/OR\s*\(`glpi_computers`\.`serial`\s*LIKE '%test%'\s*\)/")
->matches("/OR\s*\(`glpi_computertypes`\.`name`\s*LIKE '%test%'\s*\)/")
->matches("/OR\s*\(`glpi_computermodels`\.`name`\s*LIKE '%test%'\s*\)/")
->matches("/OR\s*\(`glpi_locations`\.`completename`\s*LIKE '%test%'\s*\)/")
->matches("/OR\s*\(CONVERT\(`glpi_computers`\.`date_mod` USING utf8\)\s*LIKE '%test%'\s*\)\)/");
}
public function testUser() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment