mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-14 14:18:44 +02:00
N°8178 - Respect "high_cardinality_classes" parameter on search operation (#870)
This commit is contained in:
@@ -193,6 +193,7 @@ return array(
|
||||
'Combodo\\iTop\\Application\\Helper\\CKEditorHelper' => $baseDir . '/sources/Application/Helper/CKEditorHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\ExportHelper' => $baseDir . '/sources/Application/Helper/ExportHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\FormHelper' => $baseDir . '/sources/Application/Helper/FormHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\SearchHelper' => $baseDir . '/sources/Application/Helper/SearchHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\Session' => $baseDir . '/sources/Application/Helper/Session.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\WebResourcesHelper' => $baseDir . '/sources/Application/Helper/WebResourcesHelper.php',
|
||||
'Combodo\\iTop\\Application\\Newsroom\\iTopNewsroomProvider' => $baseDir . '/sources/Application/Newsroom/iTopNewsroomProvider.php',
|
||||
|
||||
@@ -548,6 +548,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Application\\Helper\\CKEditorHelper' => __DIR__ . '/../..' . '/sources/Application/Helper/CKEditorHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\ExportHelper' => __DIR__ . '/../..' . '/sources/Application/Helper/ExportHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\FormHelper' => __DIR__ . '/../..' . '/sources/Application/Helper/FormHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\SearchHelper' => __DIR__ . '/../..' . '/sources/Application/Helper/SearchHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\Session' => __DIR__ . '/../..' . '/sources/Application/Helper/Session.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\WebResourcesHelper' => __DIR__ . '/../..' . '/sources/Application/Helper/WebResourcesHelper.php',
|
||||
'Combodo\\iTop\\Application\\Newsroom\\iTopNewsroomProvider' => __DIR__ . '/../..' . '/sources/Application/Newsroom/iTopNewsroomProvider.php',
|
||||
|
||||
73
pages/UI.php
73
pages/UI.php
@@ -5,6 +5,7 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\Helper\SearchHelper;
|
||||
use Combodo\iTop\Application\Helper\Session;
|
||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||
@@ -126,72 +127,6 @@ function SetObjectBreadCrumbEntry(DBObject $oObj, WebPage $oPage)
|
||||
$oPage->SetBreadCrumbEntry("ui-details-$sClass-".$oObj->GetKey(), $oObj->Get('friendlyname'), MetaModel::GetName($sClass).': '.$oObj->Get('friendlyname'), '', $sIcon, $sIconType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the result of a search request
|
||||
* @param $oP WebPage Web page for the output
|
||||
* @param $oFilter DBSearch The search of objects to display
|
||||
* @param $bSearchForm boolean Whether or not to display the search form at the top the page
|
||||
* @param $sBaseClass string The base class for the search (can be different from the actual class of the results)
|
||||
* @param $sFormat string The format to use for the output: csv or html
|
||||
* @param $bDoSearch bool True to display the search results below the search form
|
||||
* @param $bSearchFormOpen bool True to display the search form fully expanded (only if $bSearchForm of course)
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
*/
|
||||
function DisplaySearchSet($oP, $oFilter, $bSearchForm = true, $sBaseClass = '', $sFormat = '', $bDoSearch = true, $bSearchFormOpen = true, $aParams = [])
|
||||
{
|
||||
//search block
|
||||
$oBlockForm = null;
|
||||
if ($bSearchForm) {
|
||||
$aParams['open'] = $bSearchFormOpen;
|
||||
if (false === isset($aParams['table_id'])) {
|
||||
$aParams['table_id'] = 'result_1';
|
||||
}
|
||||
if (!empty($sBaseClass)) {
|
||||
$aParams['baseClass'] = $sBaseClass;
|
||||
}
|
||||
$oBlockForm = new DisplayBlock($oFilter, 'search', false /* Asynchronous */, $aParams);
|
||||
|
||||
if (!$bDoSearch) {
|
||||
$oBlockForm->Display($oP, 0);
|
||||
}
|
||||
}
|
||||
if ($bDoSearch) {
|
||||
if (strtolower($sFormat) == 'csv') {
|
||||
$oBlock = new DisplayBlock($oFilter, 'csv', false);
|
||||
// Adjust the size of the Textarea containing the CSV to fit almost all the remaining space
|
||||
$oP->add_ready_script(" $('#1>textarea').height($('#1').parent().height() - $('#0').outerHeight() - 30).width( $('#1').parent().width() - 20);"); // adjust the size of the block
|
||||
} else {
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
|
||||
// Breadcrumb
|
||||
//$iCount = $oBlock->GetDisplayedCount();
|
||||
$sPageId = "ui-search-".$oFilter->GetClass();
|
||||
$sLabel = MetaModel::GetName($oFilter->GetClass());
|
||||
$oP->SetBreadCrumbEntry($sPageId, $sLabel, '', '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
}
|
||||
if ($bSearchForm) {
|
||||
//add search block
|
||||
$sTableId = utils::ReadParam('_table_id_', null, false, 'raw_data');
|
||||
if ($sTableId == '') {
|
||||
$sTableId = 'result_1';
|
||||
}
|
||||
$aExtraParams['table_id'] = $sTableId;
|
||||
$aExtraParams['submit_on_load'] = false;
|
||||
$oUIBlockForm = $oBlockForm->GetDisplay($oP, 'search_1', $aExtraParams);
|
||||
//add result block
|
||||
$oUIBlock = $oBlock->GetDisplay($oP, $sTableId);
|
||||
$oUIBlock->AddCSSClasses(['display_block', 'sf_results_area']);
|
||||
$oUIBlock->AddDataAttribute('target', 'search_results');
|
||||
//$oUIBlockForm->AddSubBlock($oUIBlock);
|
||||
$oP->AddUiBlock($oUIBlockForm);
|
||||
$oUIBlockForm->AddSubBlock($oUIBlock);
|
||||
} else {
|
||||
$oBlock->Display($oP, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a form (checkboxes) to select the objects for which to apply a given action
|
||||
* Only the objects for which the action is valid can be checked. By default all valid objects are checked
|
||||
@@ -460,7 +395,7 @@ try {
|
||||
$sOQL = "SELECT $sOQLClass $sOQLClause";
|
||||
try {
|
||||
$oFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
DisplaySearchSet($oP, $oFilter, $bSearchForm, $sBaseClass, $sFormat);
|
||||
SearchHelper::DisplaySearchSet($oP, $oFilter, $bSearchForm, $sBaseClass, $sFormat);
|
||||
} catch (CoreException $e) {
|
||||
$oFilter = new DBObjectSearch($sOQLClass);
|
||||
$oSet = new DBObjectSet($oFilter);
|
||||
@@ -487,7 +422,7 @@ try {
|
||||
}
|
||||
$oP->set_title(Dict::S('UI:SearchResultsPageTitle'));
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
DisplaySearchSet($oP, $oFilter, $bSearchForm, '' /* sBaseClass */, $sFormat, $bDoSearch, true /* Search Form Expanded */);
|
||||
SearchHelper::DisplaySearchSet($oP, $oFilter, $bSearchForm, '' /* sBaseClass */, $sFormat, $bDoSearch, true /* Search Form Expanded */);
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -509,7 +444,7 @@ try {
|
||||
// $sParams = utils::ReadParam('aParams', '{}', false, \utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
|
||||
// $aParams = json_decode($sParams, true);
|
||||
|
||||
DisplaySearchSet($oP, $oFilter, $bSearchForm, '' /* sBaseClass */, $sFormat); //, true, true, $aParams
|
||||
SearchHelper::DisplaySearchSet($oP, $oFilter, $bSearchForm, '' /* sBaseClass */, $sFormat); //, true, true, $aParams
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
87
sources/Application/Helper/SearchHelper.php
Normal file
87
sources/Application/Helper/SearchHelper.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2026 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\Helper;
|
||||
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use DBSearch;
|
||||
use DisplayBlock;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
|
||||
class SearchHelper
|
||||
{
|
||||
/**
|
||||
* Displays the result of a search request
|
||||
* @param $oP WebPage Web page for the output
|
||||
* @param $oFilter DBSearch The search of objects to display
|
||||
* @param $bSearchForm boolean Whether or not to display the search form at the top the page
|
||||
* @param $sBaseClass string The base class for the search (can be different from the actual class of the results)
|
||||
* @param $sFormat string The format to use for the output: csv or html
|
||||
* @param $bDoSearch bool True to display the search results below the search form
|
||||
* @param $bSearchFormOpen bool True to display the search form fully expanded (only if $bSearchForm of course)
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
*/
|
||||
public static function DisplaySearchSet($oP, $oFilter, $bSearchForm = true, $sBaseClass = '', $sFormat = '', $bDoSearch = true, $bSearchFormOpen = true, $aParams = []): void
|
||||
{
|
||||
//search block
|
||||
$oBlockForm = null;
|
||||
if ($bSearchForm) {
|
||||
$aParams['open'] = $bSearchFormOpen;
|
||||
if (false === isset($aParams['table_id'])) {
|
||||
$aParams['table_id'] = 'result_1';
|
||||
}
|
||||
if (!empty($sBaseClass)) {
|
||||
$aParams['baseClass'] = $sBaseClass;
|
||||
}
|
||||
$oBlockForm = new DisplayBlock($oFilter, 'search', false /* Asynchronous */, $aParams);
|
||||
|
||||
if (!$bDoSearch) {
|
||||
$oBlockForm->Display($oP, 0);
|
||||
}
|
||||
}
|
||||
if ($bDoSearch) {
|
||||
if (strtolower($sFormat) == 'csv') {
|
||||
$oBlock = new DisplayBlock($oFilter, 'csv', false);
|
||||
// Adjust the size of the Textarea containing the CSV to fit almost all the remaining space
|
||||
$oP->add_ready_script(" $('#1>textarea').height($('#1').parent().height() - $('#0').outerHeight() - 30).width( $('#1').parent().width() - 20);"); // adjust the size of the block
|
||||
} else {
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
|
||||
// Breadcrumb
|
||||
//$iCount = $oBlock->GetDisplayedCount();
|
||||
$sPageId = "ui-search-".$oFilter->GetClass();
|
||||
$sLabel = MetaModel::GetName($oFilter->GetClass());
|
||||
$oP->SetBreadCrumbEntry($sPageId, $sLabel, '', '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
}
|
||||
if ($bSearchForm) {
|
||||
//add search block
|
||||
$sTableId = utils::ReadParam('_table_id_', null, false, 'raw_data');
|
||||
if ($sTableId == '') {
|
||||
$sTableId = 'result_1';
|
||||
}
|
||||
$aExtraParams['table_id'] = $sTableId;
|
||||
$aExtraParams['submit_on_load'] = false;
|
||||
$oUIBlockForm = $oBlockForm->GetDisplay($oP, 'search_1', $aExtraParams);
|
||||
|
||||
// If the class is not high cardinality, we can display the results directly in the same page
|
||||
if (!utils::IsHighCardinality($oFilter->GetClass())) {
|
||||
//add result block
|
||||
$oUIBlock = $oBlock->GetDisplay($oP, $sTableId);
|
||||
$oUIBlock->AddCSSClasses(['display_block', 'sf_results_area']);
|
||||
$oUIBlock->AddDataAttribute('target', 'search_results');
|
||||
$oUIBlockForm->AddSubBlock($oUIBlock);
|
||||
}
|
||||
|
||||
$oP->AddUiBlock($oUIBlockForm);
|
||||
} else {
|
||||
$oBlock->Display($oP, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2026 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Application\Helper;
|
||||
|
||||
use Combodo\iTop\Application\Helper\SearchHelper;
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use DBSearch;
|
||||
use MetaModel;
|
||||
|
||||
class SearchHelperTest extends ItopDataTestCase
|
||||
{
|
||||
protected static array $aHighCardinalityClasses = [];
|
||||
protected static bool $bSearchManualSubmit = false;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
self::$aHighCardinalityClasses = MetaModel::GetConfig()->Get('high_cardinality_classes');
|
||||
self::$bSearchManualSubmit = MetaModel::GetConfig()->Get('search_manual_submit');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
MetaModel::GetConfig()->Set('high_cardinality_classes', static::$aHighCardinalityClasses);
|
||||
MetaModel::GetConfig()->Set('search_manual_submit', static::$bSearchManualSubmit);
|
||||
}
|
||||
|
||||
public function testDisplaySearchSetWithNoHighCardinalityClassesAddsResultSubBlock(): void
|
||||
{
|
||||
MetaModel::GetConfig()->Set('high_cardinality_classes', []);
|
||||
MetaModel::GetConfig()->Set('search_manual_submit', false);
|
||||
|
||||
$oP = new iTopWebPage('SearchHelperTest');
|
||||
$oFilter = DBSearch::FromOQL('SELECT UserRequest');
|
||||
SearchHelper::DisplaySearchSet($oP, $oFilter);
|
||||
$oContentLayout = $oP->GetContentLayout();
|
||||
$this->assertTrue($oContentLayout->HasSubBlock('search_1'));
|
||||
$oSearchBlock = $oContentLayout->getSubBlock('search_1');
|
||||
$this->assertTrue($oSearchBlock->HasSubBlock('result_1'));
|
||||
|
||||
if (ob_get_level() > 0) {
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
|
||||
public function testDisplaySearchSetWithHighCardinalityClassesDoesNotAddResultSubBlock(): void
|
||||
{
|
||||
MetaModel::GetConfig()->Set('high_cardinality_classes', ['UserRequest']);
|
||||
MetaModel::GetConfig()->Set('search_manual_submit', false);
|
||||
|
||||
$oP = new iTopWebPage('SearchHelperTest');
|
||||
$oFilter = DBSearch::FromOQL('SELECT UserRequest');
|
||||
SearchHelper::DisplaySearchSet($oP, $oFilter);
|
||||
$oContentLayout = $oP->GetContentLayout();
|
||||
$this->assertTrue($oContentLayout->HasSubBlock('search_1'));
|
||||
$oSearchBlock = $oContentLayout->getSubBlock('search_1');
|
||||
$this->assertFalse($oSearchBlock->HasSubBlock('result_1'));
|
||||
|
||||
if (ob_get_level() > 0) {
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
|
||||
public function testDisplaySearchSetWithSearchManualSubmitAndWithoutHighCardinalityClassesDoesNotAddResultSubBlock(): void
|
||||
{
|
||||
MetaModel::GetConfig()->Set('high_cardinality_classes', []);
|
||||
MetaModel::GetConfig()->Set('search_manual_submit', true);
|
||||
|
||||
$oP = new iTopWebPage('SearchHelperTest');
|
||||
$oFilter = DBSearch::FromOQL('SELECT UserRequest');
|
||||
SearchHelper::DisplaySearchSet($oP, $oFilter);
|
||||
$oContentLayout = $oP->GetContentLayout();
|
||||
$this->assertTrue($oContentLayout->HasSubBlock('search_1'));
|
||||
$oSearchBlock = $oContentLayout->getSubBlock('search_1');
|
||||
$this->assertFalse($oSearchBlock->HasSubBlock('result_1'));
|
||||
|
||||
if (ob_get_level() > 0) {
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user