Viewing file: searchclause.php (65.63 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
require_once(getabspath('classes/searchclause_base.php'));
class SearchClause extends SearchClauseBase
{
/**
* Array with all session data
* @var array
*/
public $_where = array(); //?
/**
* Name of current table, for which instance of class was created
* @var string
*/
public $tName = "";
/**
* Name of current page
* @var string
*/
public $pageName = "";
/**
* Array of fields for basic search
* @var array
*/
protected $searchFieldsArr = array();
protected $googleLikeFields = array();
/**
* Type of search
* @var string
*/
protected $srchType = 'integrated';
/**
* Session vars pref
* @var string
*/
protected $sessionPrefix = "";
/**
* Indicator, if used search it will be true
* @var Boolean
*/
public $bIsUsedSrch = false;
/**
* An indicator showing if filters functionality is activated
* @var Boolean
*/
public $filtersActivated = false;
/**
* Indicator, if started simple or google-like search"
* @var Boolean
*/
public $simpleSearchActive = false;
/**
* Indicator, if started search is Advanced or from Search Panel
* @var Boolean
*/
protected $advancedSearchActive = false;
/**
* Indicator, if request have agregate fields it will be true
* @type Boolean
*/
protected $haveAggregateFields = false;
protected $panelSearchFields = array(); //?
public $cipherer = null;
public $pSetSearch;
protected $searchOptions = array();
protected $fieldDelimiterLeft = ')';
protected $fieldDelimiterRight = '(';
protected $valueDelimiter = '~';
protected $fieldsUsedForSearch = array();
/**
* Local instance of EditControlsContainer. Use only for compatibility with business templates
* @var object
*/
protected $localEditControls = null;
/**
* Indicator, if used "show basic search options" field it will be true
* @var boolean
*/
protected $isShowSimpleSrchOpt = false;
/**
* The array to store search params ('q', 'qs', 'f')
* extracted from REQUEST to use them for search saving
* @type Array
*/
protected $searchParams = array();
public $savedSearchIsRun = false;
/**
* The associative array containing the filtered fields data
* @var array
*/
protected $filteredFields = array();
/**
* @type Boolean
*/
protected $searchSavingEnabled = false;
protected $dashTName = "";
/**
* If the whole Dashboard (combined) search is in effect
* @type bool
*/
protected $wholeDashboardSearch = false;
protected $dashboardSearchClause = null;
/**
* @type Array
*/
protected $customFieldSQLConditions;
/**
* @constructor
*/
function __construct(&$params)
{
$this->setSearchOptions();
$this->tName = $params['tName'];
$this->sessionPrefix = $params['sessionPrefix'] ? $params['sessionPrefix'] : $this->tName;
$this->cipherer = $params['cipherer'];
$this->pageName = $params['pageName'];
$this->pSetSearch = new ProjectSettings($this->tName, PAGE_SEARCH, $this->pageName);
if( !$this->cipherer )
$this->cipherer = new RunnerCipherer( $this->tName, $this->pSetSearch );
$this->searchFieldsArr = ( $params['searchFieldsArr'] ? $params['searchFieldsArr'] : $this->pSetSearch->getSearchableFields() ); // searchable field (could be added to the search panel)
$this->panelSearchFields = ($params['panelSearchFields'] ? $params['panelSearchFields'] : $this->pSetSearch->getPanelSearchFields()); // fields that are always on the search panel
$this->googleLikeFields = ($params['googleLikeFields'] ? $params['googleLikeFields'] : $this->pSetSearch->getGoogleLikeFields()); // simple search fields
$this->isShowSimpleSrchOpt = $this->pSetSearch->showSimpleSearchOptions();
$this->searchSavingEnabled = $params['searchSavingEnabled'] ? $params['searchSavingEnabled'] : false;
$this->dashTName = $params['dashTName'] ? $params['dashTName'] : "";
if( $params['haveAggregateFields'] )
$this->haveAggregateFields = true;
$this->customFieldSQLConditions = array();
}
/**
* set searchOptions array
*/
protected function setSearchOptions()
{
$this->searchOptions["contains"] = array("option" => "Contains", "not" => false);
$this->searchOptions["equals"] = array("option" => "Equals", "not" => false);
$this->searchOptions["startswith"] = array("option" => "Starts with", "not" => false);
$this->searchOptions["morethan"] = array("option" => "More than", "not" => false);
$this->searchOptions["lessthan"] = array("option" => "Less than", "not" => false);
$this->searchOptions["between"] = array("option" => "Between", "not" => false);
$this->searchOptions["empty"] = array("option" => "Empty", "not" => false);
$this->searchOptions["lessequal"] = array("option" => "More than", "not" => true);
$this->searchOptions["moreequal"] = array("option" => "Less than", "not" => true);
$this->searchOptions["notcontain"] = array("option" => "Contains", "not" => true);
$this->searchOptions["notequal"] = array("option" => "Equals", "not" => true);
$this->searchOptions["notstartwith"] = array("option" => "Starts with", "not" => true);
$this->searchOptions["notmorethan"] = array("option" => "More than", "not" => true);
$this->searchOptions["notlessthan"] = array("option" => "Less than", "not" => true);
$this->searchOptions["notbetween"] = array("option" => "Between", "not" => true);
$this->searchOptions["notempty"] = array("option" => "Empty", "not" => true);
}
/**
* Build where for united search
* Params are common for advanced search and search panel on list
* Use in new projects
*
* @param Array fieldsArr An array of table field names
* @public
* @return string
*/
public function buildItegratedWhere($fieldsArr, $editControls = null)
{
if( !count($fieldsArr) )
return '';
if( is_null($editControls) )
$editControls = $this->getLocalEditControls();
$resWhere = '';
if( !$this->haveAggregateFields || !$this->advancedSearchActive ) //#5083
$resWhere = $this->getSimpleSearchWhere($fieldsArr, $editControls);
$srchCriteriaCombineType = $this->getCriteriaCombineType();
$srchFields = &$this->_where["_srchFields" ];
// if there are fields for build advanced where
$sWhere = '';
if( count($srchFields) )
{
// prepare vars
$sWhere = $srchCriteriaCombineType=="and" ? "(1=1" : "(1=0";
$prevSrchFieldName = '';
// build where
foreach ($srchFields as $ind => $srchF)
{
if( in_array($srchF['fName'], $fieldsArr) && !isset( $this->customFieldSQLConditions[ $srchF['fName'] ] ) )
{
$control = $editControls->getControl($srchF['fName'], SEARCHID_PANEL + $ind);
$where = $control->getSearchWhere($srchF['value1'], $srchF['opt'], $srchF['value2'], $srchF['eType']);
if($where)
{
// add not
if($srchF['not'])
{
$where="not (".$where.")";
}
// and|or depends on search type
if($srchCriteriaCombineType=="and")
{
// add ( if we add new clause block for same field name
$sWhere .= ($prevSrchFieldName != $srchF['fName'] ? ") and (" : " or ").$where;
}
else
{
$sWhere .= " or ".$where;
}
}
$prevSrchFieldName = $srchF['fName'];
}
}
// add ) to final field block clause
$sWhere .= ')';
}
$resWhere = whereAdd($resWhere, $sWhere);
foreach( $this->customFieldSQLConditions as $field => $sql )
{
if( !strlen( $resWhere ) )
$resWhere = "(". $sql .")";
else
{
if( $srchCriteriaCombineType == "and" )
$resWhere.= " and (". $sql .")";
else
$resWhere.= " or (". $sql .")";
}
}
return $resWhere;
}
/**
*
*/
protected function getSimpleSearchWhere($fieldsArr, $editControls)
{
$simpleSrch = $this->_where["_simpleSrch" ];
if( trim($simpleSrch) === '%' )
$simpleSrch = '['.$simpleSrch.']';
$simpleSrchOption = $this->_where["simpleSrchTypeComboOpt" ];
if( ( $simpleSrch == null || !strlen($simpleSrch) ) && $simpleSrchOption != "Empty" )
return "";
// build where for any field contains search
$simpleSrchField = $this->_where["simpleSrchFieldsComboOpt" ];
if( $simpleSrch != null && strlen($simpleSrchField) && !isset( $this->customFieldSQLConditions[ $simpleSrchField ] ) )
{
if( !in_array($simpleSrchField, $fieldsArr) )
return "";
$where = $editControls->getControl( $simpleSrchField, SEARCHID_SIMPLE )->getSearchWhere($simpleSrch, $simpleSrchOption, "", "");
if( $where && $this->_where["simpleSrchTypeComboNot" ] )
$where = "not (". $where .")";
return $where;
}
if( $this->isShowSimpleSrchOpt )
$simpleSrchArr = array( $simpleSrch );
else
$simpleSrchArr = $this->googleLikeParseString( $simpleSrch );
$resWhereArr = array();
$specLookupFields = array();
foreach($simpleSrchArr as $ind => $simpleSrchItem)
{
$sWhere = '';
for($i = 0; $i < count($this->searchFieldsArr); $i++)
{
if( isset( $this->customFieldSQLConditions[ $this->searchFieldsArr[$i] ] ) )
continue;
if( in_array($this->searchFieldsArr[$i], $fieldsArr) && in_array($this->searchFieldsArr[$i], $this->googleLikeFields ) )
{
if( in_array( $this->searchFieldsArr[$i], $specLookupFields ) )
$control = $editControls->getControl($this->searchFieldsArr[$i], SEARCHID_ALL); // $ind = 0
else
$control = $editControls->getControl($this->searchFieldsArr[$i], SEARCHID_ALL + $ind);
$where = $control->getSearchWhere($simpleSrchItem, $simpleSrchOption, "", "");
if( $control->checkIfDisplayFieldSearch( $simpleSrchOption ) )
$specLookupFields[] = $this->searchFieldsArr[$i];
// add not
if(trim($where) != "" && $this->_where["simpleSrchTypeComboNot"])
{
$where ="not (".$where.")";
}
if(trim($where) != "")
{
if($sWhere)
$sWhere.= " or ";
$sWhere.= $where;
}
}
}
if( count($simpleSrchArr) == 1 )
$resWhereArr[] = $sWhere;
elseif( $sWhere )
$resWhereArr[] = "(".$sWhere.")";
}
return implode(" and ", $resWhereArr);
}
/**
*
*/
protected function getLocalEditControls()
{
include_once getabspath("classes/controls/EditControlsContainer.php");
return new EditControlsContainer(null, $this->pSetSearch, PAGE_SEARCH, $this->cipherer);
}
/**
* return where clause
*
* @return string
*/
public function getWhere($fieldsArr, $editControls = null)
{
switch ($this->srchType)
{
case 'showall' :
$sWhere = '';
break;
case 'integrated' :
$sWhere = $this->buildItegratedWhere($fieldsArr, $editControls);
break;
default:
$sWhere = '';
}
return $sWhere;
}
/**
* Get the controls' 'INNER JOIN' clauses combined in a one space separated string
* @param Object editControls An instance of the EditControlsContainer class
* @return String
*/
function getCommonJoinFromParts($editControls)
{
$joinParts = $this->getJoinFromPartsArrayBasingOnSimpleSearch($editControls);
$srchFields = &$this->_where["_srchFields" ];
if( !$srchFields )
$srchFields = array();
// add to an array of the simple search control's clauses the searh fields control's INNER JOIN clauses
foreach($srchFields as $ind => $srchF)
{
if( $srchF['opt'] != "Contains" && $srchF['opt'] != "Starts with" )
continue;
$control = $editControls->getControl($srchF['fName'], SEARCHID_PANEL + $ind);
$clausesData = $control->getSelectColumnsAndJoinFromPart( $srchF['value1'], $srchF['opt'], false);
$joinParts[] = $clausesData["joinFromPart"];
}
return implode(" ", $joinParts);
}
/**
* Get an array of the simle search controls' 'INNER JOIN' clauses
* @param Object editControls An instance of the EditControlsContainer class
* @return Array
*/
protected function getJoinFromPartsArrayBasingOnSimpleSearch($editControls)
{
$joinParts = array();
$simpleSrch = $this->_where["_simpleSrch"];
$simpleSrchOpt = $this->_where["simpleSrchTypeComboOpt"];
if( $this->haveAggregateFields && $this->advancedSearchActive || !strlen($simpleSrch) || $simpleSrchOpt != "Contains" && $simpleSrchOpt != "Starts with" )
return array();
$simleSrchField = $this->_where["simpleSrchFieldsComboOpt"];
if( strlen($simleSrchField) )
{
$control = $editControls->getControl( $simleSrchField, SEARCHID_SIMPLE );
$clausesData = $control->getSelectColumnsAndJoinFromPart( $simpleSrch, $simpleSrchOpt, false);
return array( $clausesData["joinFromPart"] );
}
if( $this->isShowSimpleSrchOpt )
$simpleSrchArr = array($simpleSrch);
else
$simpleSrchArr = $this->googleLikeParseString($simpleSrch);
$joinParts = array();
$skipFields = array();
foreach($simpleSrchArr as $ind => $simpleSrchItem)
{
foreach( $this->searchFieldsArr as $sField )
{
if( in_array($sField, $this->googleLikeFields) && !in_array($sField, $skipFields) )
{
$control = $editControls->getControl($sField, SEARCHID_ALL + $ind);
$clausesData = $control->getSelectColumnsAndJoinFromPart( $simpleSrchItem, $simpleSrchOpt, false );
if( $control->checkIfDisplayFieldSearch( $simpleSrchOpt ) )
$skipFields[] = $sField;
$joinParts[] = $clausesData["joinFromPart"];
}
}
}
return $joinParts;
}
/**
* Get the filter's WHERE clause conditions and fill
* the filteredFields array with fieldes' values
* and WHERE clauses extracted
*/
function processFiltersWhere( $connection )
{
$this->filteredFields = array();
$strFieldWhere = array();
$filtersParams = postvalue('f');
if( !$filtersParams && isset($_SESSION[$this->sessionPrefix."_filters"]) )
$filtersParams = $_SESSION[$this->sessionPrefix."_filters"];
if(!$filtersParams || $filtersParams == 'all')
return;
$filters = $this->parseStringToArray($filtersParams, true);
foreach($filters as $filter)
{
$fName = $this->searchUnEscape( $filter[0] );
$filterType = $filter[1];
$fValue = $this->searchUnEscape( $filter[2] );
$sValue = $this->searchUnEscape( $filter[3] );
$parentValue = array();
if( $filter[4] )
{
$parentValuesString = $this->searchUnEscape( $filter[4] ); // values glued by '|'
$parentValues = $this->getUnescapedFValues( $parentValuesString );
}
$where = $this->getFilterWhereByType( $filterType, $fName, $fValue , $sValue, $parentValues, $connection );
if($where)
{
$strFieldWhere[$fName]["where"][] = $where;
$strFieldWhere[$fName]["value"][] = $fValue;
if($sValue)
$strFieldWhere[$fName]["value"][] = $sValue;
$strFieldWhere[$fName]["parentValues"][] = $parentValues;
}
}
foreach($strFieldWhere as $fName => $fData)
{
$fieldWhere = implode(" or ", $fData["where"]);
$this->filteredFields[$fName] = array("values" => $fData["value"], "where" => $fieldWhere, "parentValues" => $fData["parentValues"] );
}
}
/**
* In case the filter value contains the added partent filters values ("|"-separeated)
* it returns an array of filter's and its parent filters values.
* Otherwise the returning array contains at most the own filter's value
* @param String fValue
* @return Array
*/
protected function getUnescapedFValues($fValue)
{
$start = 0;
$unescapedValues = array();
$valueLength = strlen($fValue);
if( !$valueLength )
return $unescapedValues;
for($i = 0; $i < $valueLength; $i++)
{
if( $fValue[$i] != "|" )
continue;
if( $i > 0 )
{
if( $fValue[$i - 1] == "\\" )
continue;
}
$unescapedValues[] = str_replace( '\\|', '|', substr($fValue, $start, $i - $start) );
$start = $i + 1;
}
if( $start < $valueLength )
$unescapedValues[] = str_replace( '\\|', '|', substr($fValue, $start, $valueLength - $start) );
return $unescapedValues;
}
/**
* Get filter's WHERE clause condition basing on the filter's type
*
* @param String filterType A string representing the filter's type
* @param String fName
* @param String fValue
* @param String dbType
* @return String
*/
function getFilterWhereByType($filterType, $fName, $fValue, $sValue, $parentValues, $connection)
{
$fullFieldName = RunnerPage::_getFieldSQLDecrypt( $fName, $connection, $this->pSetSearch, $this->cipherer );
$fieldType = $this->pSetSearch->getFieldType($fName);
$dateField = IsDateFieldType($fieldType);
$timeField = IsTimeType($fieldType);
include_once getabspath("classes/controls/FilterControl.php");
include_once getabspath("classes/controls/FilterValuesList.php");
include_once getabspath("classes/controls/FilterIntervalSlider.php");
include_once getabspath("classes/controls/FilterIntervalDateSlider.php");
switch($filterType)
{
case 'interval':
$intervalData = $this->pSetSearch->getFilterIntervalDatabyIndex($fName, $fValue);
if( !count($intervalData) )
return "";
include_once getabspath("classes/controls/FilterControl.php");
include_once getabspath("classes/controls/FilterIntervalList.php");
return FilterIntervalList::getIntervalFilterWhere($fName, $intervalData, $this->pSetSearch, $this->cipherer, $this->tName, $connection);
case 'equals':
$filterWhere = FilterValuesList::getFilterWhere( $fName, $fValue, $this->pSetSearch, $fullFieldName, $this->cipherer, $connection );
if( !count($parentValues) )
return $filterWhere;
// return $fullFieldName."=".$this->cipherer->MakeDBValue($fName, $fValue, "", true);
$wheres = array();
$wheres[] = $filterWhere;
$parentFiltersNames = FilterValuesList::getParentFilterFields( $fName, $this->pSetSearch );
foreach( $parentFiltersNames as $key => $parentName )
{
$wheres[] = FilterValuesList::getFilterWhere(
$parentName,
$parentValues[$key],
$this->pSetSearch,
RunnerPage::_getFieldSQLDecrypt($parentName, $connection, $this->pSetSearch, $this->cipherer),
$this->cipherer,
$connection );
}
return "(".implode(" AND ", $wheres).")";
case 'checked':
if($fValue != "on" && $fValue != "off")
return "";
$bNeedQuotes = NeedQuotes($fieldType);
include_once getabspath("classes/controls/Control.php");
include_once getabspath("classes/controls/CheckboxField.php");
return CheckboxField::constructFieldWhere($fullFieldName, $bNeedQuotes, $fValue == "on", $this->pSetSearch->getFieldType($fName), $connection->dbType);
case 'slider':
if($dateField)
return FilterIntervalDateSlider::getDateSliderWhere($fName, $this->pSetSearch, $this->cipherer, $this->tName, $fValue, $sValue, $filterType, $fullFieldName);
if($timeField)
{
include_once getabspath("classes/controls/FilterIntervalTimeSlider.php");
return FilterIntervalTimeSlider::getTimeSliderWhere($fName, $this->pSetSearch, $this->cipherer, $this->tName, $fValue, $sValue, $filterType, $fullFieldName);
}
return $this->cipherer->MakeDBValue($fName, $fValue, "", true)."<=".$fullFieldName." AND ".$fullFieldName."<=".$this->cipherer->MakeDBValue($fName, $sValue, "", true);
case 'moreequal':
if($dateField)
return FilterIntervalDateSlider::getDateSliderWhere($fName, $this->pSetSearch, $this->cipherer, $this->tName, $fValue, $sValue, $filterType, $fullFieldName);
if($timeField)
{
include_once getabspath("classes/controls/FilterIntervalTimeSlider.php");
return FilterIntervalTimeSlider::getTimeSliderWhere($fName, $this->pSetSearch, $this->cipherer, $this->tName, $fValue, $sValue, $filterType, $fullFieldName);
}
return $this->cipherer->MakeDBValue($fName, $fValue, "", true)."<=".$fullFieldName;
case 'lessequal':
if($dateField)
return FilterIntervalDateSlider::getDateSliderWhere($fName, $this->pSetSearch, $this->cipherer, $this->tName, $fValue, $sValue, $filterType, $fullFieldName);
if($timeField)
{
include_once getabspath("classes/controls/FilterIntervalTimeSlider.php");
return FilterIntervalTimeSlider::getTimeSliderWhere($fName, $this->pSetSearch, $this->cipherer, $this->tName, $fValue, $sValue, $filterType, $fullFieldName);
}
return $fullFieldName."<=".$this->cipherer->MakeDBValue($fName, $fValue, "", true);
default:
return "";
}
}
/**
* Parse form with union search REQUEST (for new versions: 6.2 and newest)
* Params are common for advanced search and search panel on list
* Use in new projects
*
* @protected
* @return string
*/
function parseItegratedRequest()
{
global $suggestAllContent;
$_SESSION[$this->sessionPrefix."_qs"] = postvalue('qs');
$_SESSION[$this->sessionPrefix."_q"] = postvalue('q');
$this->fieldsUsedForSearch = array();
$this->_where["simpleSrchTypeComboOpt"] = $suggestAllContent ? "Contains" : "Starts with";
$this->_where["simpleSrchTypeComboNot"] = false;
$this->_where["simpleSrchFieldsComboOpt"] = '';
$tempArr = $this->parseStringToArray( postvalue('qs') );
$simpleQueryArr = $tempArr[0];
if( $this->wholeDashboardSearch )
$simpleQueryArr = $this->getSimpleSearchFromDashboard();
$this->_where["_simpleSrch" ] = $this->searchUnEscape( $simpleQueryArr[0] );
$this->simpleSearchActive = $simpleQueryArr[0] != '';
if($this->simpleSearchActive && $this->wholeDashboardSearch)
{
$this->googleLikeFields = $this->getGoogleLikeFieldsFromDashboard();
}
if(isset($this->searchOptions[$this->getArrayValueByIndex($simpleQueryArr, 2, true)]))
{
$simpleSrchTypeComboNot = $this->searchOptions[$simpleQueryArr[2]]["not"];
$this->_where["simpleSrchTypeComboOpt"] = $this->searchOptions[$simpleQueryArr[2]]["option"];
if (!strlen($this->_where["simpleSrchTypeComboOpt"]))
{
$this->_where["simpleSrchTypeComboOpt"] = $suggestAllContent ? "Contains" : "Starts with";
}
}
$fieldName = trim($this->getArrayValueByIndex($simpleQueryArr, 1, true));
$this->_where["simpleSrchFieldsComboOpt"] = $fieldName;
if($fieldName)
{
$this->fieldsUsedForSearch[$fieldName] = true;
}
$srchCriteriaCombineType = postvalue("criteria");
if( $this->wholeDashboardSearch )
$srchCriteriaCombineType = $this->getCriteriaFromDashboard();
if( !$srchCriteriaCombineType )
$srchCriteriaCombineType = "and";
$this->_where["_srchCriteriaCombineType"] = $srchCriteriaCombineType;
$_SESSION[$this->sessionPrefix."_criteriaSearch"] = $this->getCriteriaCombineType(); //?
$this->_where["_srchFields"] = array();
$this->advancedSearchActive = false;
$searchFieldsArr = $this->parseStringToArray(postvalue('q'), true);
if( $this->wholeDashboardSearch )
$searchFieldsArr = $this->getSearchFieldsFromDashboard();
foreach ($searchFieldsArr as $searchItemArr)
{
if( count($searchItemArr) < 2 )
continue;
$fName = $this->searchUnEscape($searchItemArr[0]);
if (false == in_array($fName, $this->searchFieldsArr))
continue;
$this->advancedSearchActive = true;
$srchF = array();
$srchF['fName'] = $fName;
$srchF['eType'] = $this->getArrayValueByIndex($searchItemArr, 3);
$srchF['value1'] = $this->getArrayValueByIndex($searchItemArr, 2, true);
$opt = $this->getArrayValueByIndex($searchItemArr, 1);
$srchF['not'] = false;
if(isset($this->searchOptions[$opt]))
{
$srchF['not'] = $this->searchOptions[$opt]["not"];
$srchF['opt'] = $this->searchOptions[$opt]["option"];
}
else
{
$srchF['opt'] = $this->getDefaultSearchTypeOption($fName, $this->pSetSearch);
}
if( $this->wholeDashboardSearch )
{
$srchF['not'] = $this->getArrayValueByIndex($searchItemArr, 5);
}
$srchF['value2'] = $this->getArrayValueByIndex($searchItemArr, 4, true);
$this->_where["_srchFields"][] = $srchF;
$this->fieldsUsedForSearch[$fName] = true;
}
// process srch panel attrs, better then use coockies.
$this->_where["_srchOptShowStatus"]= postvalue('srchOptShowStatus')==='1';
$this->_where["_ctrlTypeComboStatus"]= postvalue('ctrlTypeComboStatus')==='1';
$this->_where["srchWinShowStatus"]= postvalue('srchWinShowStatus')==='1';
}
/**
* Get criteria from dashboard search clause
* @return String
*/
protected function getCriteriaFromDashboard()
{
if( $this->dashboardSearchClause )
return $this->dashboardSearchClause->_where['_srchCriteriaCombineType' ];
return "";
}
/**
* Get simple search from dashboard search clause
* @return Array
*/
function getSimpleSearchFromDashboard()
{
if($this->dashboardSearchClause)
return array(0 => $this->dashboardSearchClause->_where['_simpleSrch']);
else
return array(0 => null);
}
/**
* Get search fields from dashboard search clause
* @return Array
*/
function getSearchFieldsFromDashboard()
{
$result = array();
if($this->dashboardSearchClause)
$dashSearchFieldsSession = $this->dashboardSearchClause->_where['_srchFields'];
else
$dashSearchFieldsSession = null;
if ($dashSearchFieldsSession)
{
$dashSettings = new ProjectSettings($this->dashTName, PAGE_DASHBOARD);
$dashSearchFields = $dashSettings->getDashboardSearchFields();
foreach ($dashSearchFieldsSession as $i => $data)
{
foreach ($dashSearchFields[ $data['fName'] ] as $j => $fData)
{
if ($fData['table'] != $this->tName)
continue;
$resutlData = array();
$resutlData[0] = $fData['field'];
foreach ($this->searchOptions as $opt => $optData)
{
if ($data['opt'] == $optData['option'])
{
$resutlData[1] = $opt;
break;
}
}
$resutlData[2] = $data['value1'];
if ($data['eType'])
$resutlData[3] = $data['eType'];
if ($data['value2'])
$resutlData[4] = $data['value2'];
$resutlData[5] = $data['not'];
$result[] = $resutlData;
}
}
}
return $result;
}
/**
* Get google like fields from dashboard
* @return Array
*/
function getGoogleLikeFieldsFromDashboard()
{
$result = array();
$dashSettings = new ProjectSettings($this->dashTName, PAGE_DASHBOARD);
$dashGoogleLikeFields = $dashSettings->getGoogleLikeFields();
$dashSearchFields = $dashSettings->getDashboardSearchFields();
foreach ($dashGoogleLikeFields as $i => $field)
{
foreach ($dashSearchFields[$field] as $j => $data)
{
if( $data['table'] == $this->tName )
$result[] = $data['field'];
}
}
return $result;
}
/**
* @param String inputString
* @return String
*/
function searchUnEscape($inputString)
{
return str_replace("\\\\", "\\",
str_replace("\\".$this->valueDelimiter, $this->valueDelimiter,
str_replace("\\".$this->fieldDelimiterLeft.$this->fieldDelimiterRight,
$this->fieldDelimiterLeft.$this->fieldDelimiterRight, $inputString)));
}
/**
* @param String inputString
* @param Boolean advanced
* @return Array
*/
function parseStringToArray($inputString, $advanced = false)
{
if(0 == strlen($inputString))
return array();
$result = array();
$valuesArray = array();
$startPos = 0;
if($advanced)
$inputString = substr($inputString, 1, strlen($inputString) - 2);
$strLength = strlen($inputString);
for($i = 0; $i < $strLength; $i++)
{
if($inputString[$i] == $this->valueDelimiter)
if($this->isDelimiter($inputString, $startPos, $i))
{
$valuesArray[] = trim( substr($inputString, $startPos, $i - $startPos) );
$startPos = $i + 1;
}
if($i == $strLength - 1 || $inputString[$i] == $this->fieldDelimiterLeft)
if($i == $strLength - 1 || $this->isDelimiter($inputString, $startPos, $i, true))
{
$valuesArray[] = trim( substr($inputString, $startPos, $i - $startPos + ($i == $strLength - 1 ? 1 : 0)) );
$result[] = $valuesArray;
$valuesArray = array();
$startPos = $i + 2;
$i++;
}
}
return $result;
}
/**
* @param &String inputString
* @param Number startPos
* @param Number currentPos
* @param Boolean isFieldDelimiter (optional)
* @return Boolean
*/
function isDelimiter(&$inputString, $startPos, $currentPos, $isFieldDelimiter = false)
{
$backSlahesCount = 0;
for($i = $currentPos - 1; $i >= $startPos; $i--)
{
if($inputString[$i] != '\\')
break;
$backSlahesCount++;
}
$result = $backSlahesCount == 0 || $backSlahesCount % 2 == 0;
if($result && $isFieldDelimiter && strlen($inputString) > $currentPos + 1)
{
return $inputString[$currentPos + 1] == $this->fieldDelimiterRight;
}
return $result;
}
/**
*
*/
function getArrayValueByIndex(&$arr, $index, $isEncoded = false)
{
$result = "";
if(isset($arr[$index]))
{
$result = $arr[$index];
if($isEncoded)
$result = $this->searchUnEscape($result);
}
return $result;
}
/**
*
*/
function getDefaultSearchTypeOption($fName, $pSet)
{
$fType = $pSet->getEditFormat($fName);
$option = "Equals";
if($fType == EDIT_FORMAT_LOOKUP_WIZARD)
{
if ($pSet->multiSelect($fName))
$option = "Contains";
}
elseif ($fType == EDIT_FORMAT_TEXT_FIELD || $fType == EDIT_FORMAT_TEXT_AREA || $fType == EDIT_FORMAT_PASSWORD
|| $fType == EDIT_FORMAT_HIDDEN || $fType == EDIT_FORMAT_READONLY)
{
if(!$this->cipherer->isFieldPHPEncrypted($fName))
$option = "Contains";
}
return $option;
}
/**
*
*/
protected function removeSessionSearchVariables()
{
if ( @$_SESSION[$this->sessionPrefix."_qs"] )
unset($_SESSION[$this->sessionPrefix."_qs"]);
if ( @$_SESSION[$this->sessionPrefix."_q"] )
unset($_SESSION[$this->sessionPrefix."_q"]);
if ( @$_SESSION[$this->sessionPrefix."_criteriaSearch"] )
unset($_SESSION[$this->sessionPrefix."_criteriaSearch"]);
}
/**
* Parse REQUEST
*/
public function parseRequest()
{
global $requestTable, $requestPage;
$this->wholeDashboardSearch = false;
//set session if show all records
if(@$_REQUEST["a"] == "showall" || $requestTable == $this->tName
&& ( $requestPage == "list" || $requestPage == "chart" || $requestPage == "report" || $requestPage == "dashboard" )
&& IsEmptyRequest() )
{
$this->resetSearch();
}
else if( isset($_REQUEST["q"]) || isset($_REQUEST["qs"]) || @$_REQUEST["f"] )
{
$this->srchType = 'integrated';
$this->parseItegratedRequest();
$this->bIsUsedSrch = isset($_REQUEST["q"]) && $_REQUEST["q"] !== "" || isset($_REQUEST["qs"]) && $_REQUEST["qs"] !== "";
$_SESSION[$this->sessionPrefix."_pagenumber"] = 1;
}
else if( $this->dashTName && isset($_SESSION[$this->dashTName.'_advsearch']) )
{
$this->dashboardSearchClause = SearchClause::UnserializeObject($_SESSION[$this->dashTName.'_advsearch']);
$this->wholeDashboardSearch = $this->dashboardSearchClause->bIsUsedSrch;
if( $this->wholeDashboardSearch )
{
$this->srchType = 'integrated';
$this->parseItegratedRequest();
$this->bIsUsedSrch = true;
}
else if( $this->dashboardSearchClause->srchType == 'showall' )
{
$this->_where["_search"] = 0;
$this->srchType = 'showall';
$this->bIsUsedSrch = false;
$this->clearSearch();
$this->simpleSearchActive = false;
$this->removeSessionSearchVariables();
}
}
//set session for filters
if( @$_REQUEST["f"] ) {
$_SESSION[$this->sessionPrefix."_filters"] = $_REQUEST["f"];
$this->filteredFields = array();
}
$this->filtersActivated = isset( $_SESSION[$this->sessionPrefix."_filters"] ) && $_SESSION[$this->sessionPrefix."_filters"] != 'all';
if( $this->searchSavingEnabled )
{
if( isset($_REQUEST["savedSearch"]) )
$this->savedSearchIsRun = true;
else if( ( $this->bIsUsedSrch || $this->filtersActivated ) && !$this->searchHasTheSameSearchParams() || $this->srchType == 'showall' )
$this->savedSearchIsRun = false;
}
}
/**
* Fill the 'searchParams' array with extracted from REQUEST's 'q', 'qs'
* and 'f' params to use them then for a search saving process.
*/
public function storeSearchParamsForLogging()
{
if( !$this->searchSavingEnabled )
return;
if( !isset($_REQUEST["saveSearch"]) && !isset($_REQUEST["deleteSearch"]) )
{
if( $this->srchType == 'showall' )
// reset the simple search and search panel params
$this->searchParams = array( "f" => $this->searchParams["f"] );
else if( !@$_REQUEST["goto"] && !@$_REQUEST["orderby"] && !@$_REQUEST["pagesize"] )
// reset all stored params
$this->searchParams = array();
}
if( isset( $_REQUEST["q"] ) )
{
$this->searchParams["q"] = $_REQUEST["q"];
$this->searchParams["criteria"] = @$_REQUEST["criteria"];
}
if( isset( $_REQUEST["qs"] ) )
$this->searchParams["qs"] = $_REQUEST["qs"];
if( isset( $_REQUEST["f"] ) )
$this->searchParams["f"] = $_REQUEST["f"];
}
/**
* Check if the current REQUEST search params are equal to stored save search params.
* When the pagination or sorting is activated and there are some stored search params
* the current and stored search params are deemed the same
* @return Boolean
*/
public function searchHasTheSameSearchParams()
{
if( @$_REQUEST["goto"] || @$_REQUEST["orderby"] || @$_REQUEST["pagesize"] )
return true;
if( !count($this->searchParams) )
return false;
if( @$_REQUEST["q"] != $this->searchParams["q"] || @$_REQUEST["qs"] != $this->searchParams["qs"] || @$_REQUEST["f"] != $this->searchParams["f"])
return false;
return true;
}
/**
* @return Array
*/
public function getSearchParamsForSaving()
{
return $this->searchParams;
}
/**
* Clears search params
*/
function clearSearch()
{
$this->_where["_simpleSrch"] = '';
$this->_where["_srchCriteriaCombineType"] = "and";
$this->_where["simpleSrchTypeComboOpt"] = "Contains";
$this->_where["simpleSrchTypeComboNot"] = false;
$this->_where["simpleSrchFieldsComboOpt"] = '';
// prepare vars
$this->_where["_srchFields"] = array();
// process srch panel attrs, better then use coockies.
$this->_where["_srchOptShowStatus"]= false;
$this->_where["_ctrlTypeComboStatus"]= false;
$this->_where["srchWinShowStatus"]= false;
$this->fieldsUsedForSearch = array();
}
/**
* @param String fName
* @return Array
*/
public function getSearchCtrlParams($fName)
{
$resArr = array();
$editControls = $this->getLocalEditControls();
if( $this->_where["_srchFields"] )
{
foreach( $this->_where["_srchFields"] as $srchField )
{
if( strtolower( $srchField['fName'] ) == strtolower( $fName ) )
{
$tField = $srchField;
$ctrl = $editControls->getControl( $fName );
$eType = $tField["eType"];
if( $ctrl->checkIfDisplayFieldSearch( $tField["opt"] ) )
$eType = "display";
$tField["value1"] = prepare_for_db( $tField["fName"], $tField["value1"], $eType, "", $this->tName );
$tField["value2"] = prepare_for_db( $tField["fName"], $tField["value2"], $eType, "", $this->tName );
$resArr[] = $tField;
}
}
}
return $resArr;
}
/**
* @return Number
*/
public function getUsedCtrlsCount()
{
if( $this->_where["_srchFields" ] )
return count( $this->_where["_srchFields" ] );
return 0;
}
/**
* Global search params: use and|or, srchType panel|adv and simple search value
* @return array
*/
public function getSearchGlobalParams()
{
return array('simpleSrch' => $this->_where["_simpleSrch" ],
'srchTypeRadio' => $this->getCriteriaCombineType(),
'srchType'=> $this->srchType,
'simpleSrchTypeComboOpt' => $this->_where["simpleSrchTypeComboOpt" ],
'simpleSrchTypeComboNot' => $this->_where["simpleSrchTypeComboNot" ],
'simpleSrchFieldsComboOpt' => $this->_where["simpleSrchFieldsComboOpt" ]
);
}
/**
* Search panel status indicators array. Open|closed etc
* @return array
*/
public function getSrchPanelAttrs()
{
return array('srchOptShowStatus' => ($this->_where["_srchOptShowStatus"] || count($this->panelSearchFields)),
'ctrlTypeComboStatus' => $this->_where["_ctrlTypeComboStatus"],
'srchWinShowStatus' => $this->_where["srchWinShowStatus"]
);
}
/**
* Returns indicator is search was init
* @return Boolean
*/
public function isUsedSrch()
{
return $this->bIsUsedSrch;
}
/**
* Returns indicator is show button 'Show All'
* @return Boolean
*/
public function isShowAll()
{
return $this->bIsUsedSrch;
}
/**
* Check if search functionality is activated
* @return Boolean
*/
public function isSearchFunctionalityActivated()
{
return $this->bIsUsedSrch || $this->filtersActivated || count( $this->getSearchFields() ) > 0;
}
/**
* Checks whether required search fields are used for the searching or not
* @return Boolean
*/
public function isRequiredSearchRunning()
{
if(!$this->bIsUsedSrch)
{
//the search isn't run
return false;
}
if(count($this->pSetSearch)){
$requiredSearchFields = $this->pSetSearch->getSearchRequiredFields();
foreach($requiredSearchFields as $fName)
{
if( !$this->fieldsUsedForSearch[$fName] )
{
//a required search field isn't involved in the current search
return false;
}
}
}
return true;
}
/**
* Forms an array containing the search words and options
*
* @param String fname
* @param Array lookupParams
* @return array | false
*/
public function getSearchToHighlight($fname, $lookupParams = array())
{
// if not in search fields array
if (!in_array($fname, $this->searchFieldsArr))
return false;
$options = array();
//simple search processing
$simpleSearch['fname'] = $this->_where["simpleSrchFieldsComboOpt"];
$opt = $this->_where["simpleSrchTypeComboOpt"];
if($this->isShowSimpleSrchOpt)
$simpleSearch['value'] = array($this->_where["_simpleSrch"]);
else
$simpleSearch['value'] = $this->googleLikeParseString($this->_where["_simpleSrch"]);
if( isset($simpleSearch['value']) && count($simpleSearch['value']) && (!$simpleSearch['fname'] || $simpleSearch['fname'] == $fname) )
{
foreach($simpleSearch['value'] as $simpleSearchValue)
{
if( strlen( trim($simpleSearchValue) ) )
$options[$opt][$fname][] = $simpleSearchValue;
}
}
//integrated search processing
$srchFields = $this->_where["_srchFields"];
if( !$srchFields )
$srchFields = array();
$multiselect = $lookupParams["multiselect"];
$needLookupProcessing = $lookupParams["needLookupProcessing"];
foreach($srchFields as $srchFieldData)
{
if($srchFieldData['fName'] != $fname || $srchFieldData['not'])
{
continue;
}
$opt = $srchFieldData['opt'];
if($opt != "Contains" && $opt != "Equals" && $opt != "Starts with")
{
continue;
}
if($needLookupProcessing && $opt == "Equals")
{
$options[$opt][$srchFieldData['fName']][] = implode(",", splitvalues( $srchFieldData['value1'] ));
continue;
}
if(!$multiselect || $opt != "Contains")
{
$options[$opt][$srchFieldData['fName']][] = $srchFieldData['value1'];
continue;
}
$values = splitvalues( $srchFieldData['value1'] );
foreach($values as $value)
{
$options[$opt][$srchFieldData['fName']][] = $value;
}
}
if($options['Equals'][$fname])
return array("searchWords" => $options['Equals'][$fname], "option" => 'Equals');
if($options['Starts with'][$fname])
return array("searchWords" => $options['Starts with'][$fname], "option" => 'Starts with');
if($options['Contains'][$fname])
return array("searchWords" => $options['Contains'][$fname], "option" => 'Contains');
return false;
}
/**
* Forms an array containing the actual search word and option, if there is at least one word to highlight.
*
* @param String fname
* @param String value
* @param Boolean encoded It indicates if runner_htmlspecialchars should be applied to the search words
* @param Array lookupParams It contains the following propeties:
* String linkFieldValue The value of the link field if the link field differs from the displayed field
* Boolean multiselect An indicator showing if the lookup is multiselect
* Boolean needLookupProcessing An indicator showing if the lookup is tablebased, multiselect, with
* the same link and displayed fields
* @return Array | false
*/
public function getSearchHighlightingData($fname, $value, $encoded, $lookupParams)
{
global $useUTF8;
$searchData = $this->getSearchToHighlight($fname, $lookupParams);
if(!$searchData)
{
return false;
}
$flags = $useUTF8 ? "iu" : "i";
$searchWordArr = array();
$searchOpt = $searchData['option'];
foreach($searchData['searchWords'] as $searchWord)
{
$curSearchWord = $searchWord;
//linkFieldValue and linkFieldValue params are set for lookup contols with distinct Link and Displayed fields only
//originLinkValue param is set for multiselet lookups only
if($searchOpt == 'Contains' && $lookupParams["originLinkValue"] == $searchWord || $searchOpt == 'Equals' && $lookupParams["linkFieldValue"] == $searchWord )
{
return array("searchWords" => array($value), "searchOpt" => $searchData['option']);
}
if($encoded)
{
$curSearchWord = runner_htmlspecialchars($curSearchWord);
}
$pattern = '/'.preg_quote($curSearchWord,"/").'/'.$flags;
if($searchOpt == 'Starts with')
{
$pattern = '/^'.preg_quote($curSearchWord,"/").'/'.$flags;
}
$isMatched = preg_match($pattern, $value, $matches);
if( $isMatched && ( $searchOpt != 'Equals' || $value == $matches[0] ) )
{
//get the actual search word contained in the $value string
$curSearchWord = $matches[0];
$searchWordArr[] = $curSearchWord;
}
}
if(count($searchWordArr))
{
return array("searchWords" => $searchWordArr, "searchOpt" => $searchOpt);
}
return false;
}
/**
* Google-like parse search string
* Input: "a b" c d "e f"
* Output: array("a b", "c", "d", "e f")
*
* @param string $str search string
* @return array
*/
protected function googleLikeParseString($str)
{
$ret = array();
$matches = array();
if(preg_match_all('/(\"[^"]+\")|([^\s]+)/', $str, $matches))
{
foreach($matches[0] as $match)
{
$ret[] = ($match[0] == '"') ? substr($match, 1, -1) : $match;
}
}
return array_unique($ret);
}
/**
* Informs how search criterions are combined.
* Returns "and" or "or";
*
* @return string
*/
public function getCriteriaCombineType()
{
if( $this->_where["_srchCriteriaCombineType"] == "or" )
return "or";
if( $this->simpleSearchActive && !count($this->_where["_srchFields"]) )
return "or";
return "and";
}
/**
*
*/
public static function UnserializeObject($str)
{
if(!$str)
return null;
include_once getabspath("classes/controls/EditControlsContainer.php");
$obj = unserialize($str);
$obj->pSetSearch = new ProjectSettings($obj->tName, PAGE_SEARCH);
$obj->cipherer = new RunnerCipherer($obj->tName, $obj->pSetSearch );
return $obj;
}
/*
public function Serialize()
{
return serialize($this);
// PHP7 can't serialize connection object which is linked through one of the objects
$_pset = $this->pSetSearch;
$_cipherer = $obj->cipherer;
$this->pSetSearch = null;
$obj->cipherer = null;
$ret = serialize($this);
$this->pSetSearch = $_pset;
$obj->cipherer = $_cipherer;
return $ret;
}
*/
/**
* User Search API
* @return Array
*/
public function getSearchFields()
{
$fieldsData = array();
if(count($this->_where["_srchFields" ])>0){ //for asp
foreach( $this->_where["_srchFields" ] as $ind => $sfData )
{
if( !$fieldsData[ $sfData['fName'] ] )
$fieldsData[ $sfData['fName'] ] = array();
$fieldsData[ $sfData['fName'] ][] = SEARCHID_PANEL + $ind;
}
}
if( $this->haveAggregateFields && $this->advancedSearchActive )
return $fieldsData;
$simpleSrch = $this->_where["_simpleSrch" ];
$simpleSrchOption = $this->_where["simpleSrchTypeComboOpt" ];
if( ( $simpleSrch == null || !strlen($simpleSrch) ) && $simpleSrchOption != "Empty" )
return $fieldsData;
$simpleSrchField = $this->_where["simpleSrchFieldsComboOpt" ];
if( $simpleSrch != null && strlen($simpleSrchField) && in_array($simpleSrchField, $this->googleLikeFields) )
{
if( !$fieldsData[ $simpleSrchField ] )
$fieldsData[ $simpleSrchField ] = array();
$fieldsData[ $simpleSrchField ][] = SEARCHID_SIMPLE;
}
if( $this->isShowSimpleSrchOpt )
$simpleSrchArr = array( $simpleSrch );
else
$simpleSrchArr = $this->googleLikeParseString( $simpleSrch );
foreach($simpleSrchArr as $ind => $simpleSrchItem)
{
for($i = 0; $i < count($this->searchFieldsArr); $i++)
{
if ( in_array($this->searchFieldsArr[$i], $this->googleLikeFields) )
{
if( !$fieldsData[ $this->searchFieldsArr[$i] ] )
$fieldsData[ $this->searchFieldsArr[$i] ] = array();
$fieldsData[ $this->searchFieldsArr[$i] ][] = SEARCHID_ALL + $ind;
}
}
}
return $fieldsData;
}
/**
* @return Boolean
*/
public function isSearchPanelByUserApiRun()
{
if ( !count( $this->_where["_srchFields" ] ) )
return false;
foreach( $this->_where["_srchFields" ] as $ind => $sfData )
{
if( $sfData['byUserApi'] )
return true;
}
return false;
}
/**
* User Search API
* @param String field
* @param Number id
* @param Boolean - don't include Search for all fields value. Only individual field search
* @return mixed ( String | null )
*/
public function getFieldValue( $field, $id = null, $returnAllFieldSearch = true )
{
$srchFields = &$this->_where["_srchFields" ];
foreach($srchFields as $ind => $srchF)
{
if( $srchF['fName'] == $field && ( $id == SEARCHID_PANEL + $ind || is_null($id) ) )
return $srchF['value1'];
}
if( $this->haveAggregateFields && $this->advancedSearchActive )
return null;
$simpleSrch = $this->_where["_simpleSrch" ];
$simpleSrchOption = $this->_where["simpleSrchTypeComboOpt" ];
if( ( $simpleSrch == null || !strlen($simpleSrch) ) && $simpleSrchOption != "Empty" || !in_array($field, $this->googleLikeFields) )
return null;
$simpleSrchField = $this->_where["simpleSrchFieldsComboOpt" ];
if( $simpleSrchField == $field && $simpleSrch != null && ( $id == SEARCHID_SIMPLE || is_null($id) ) )
return $simpleSrch;
if( strlen( $simpleSrchField ) )
return null;
if( !$returnAllFieldSearch ) {
return null;
}
if( $this->isShowSimpleSrchOpt )
$simpleSrchArr = array( $simpleSrch );
else
$simpleSrchArr = $this->googleLikeParseString( $simpleSrch );
foreach($simpleSrchArr as $ind => $simpleSrchItem)
{
for($i = 0; $i < count($this->searchFieldsArr); $i++)
{
if ( $this->searchFieldsArr[$i] == $field && ( $id == SEARCHID_ALL + $ind || is_null($id) ) )
return $simpleSrchItem;
}
}
return null;
}
/**
* between case
* User Search API
* @param String field
* @param Number id
* @return mixed ( String | null )
*/
public function getSecondFieldValue( $field, $id = null )
{
$srchFields = &$this->_where["_srchFields" ];
foreach($srchFields as $ind => $srchF)
{
if( $srchF['fName'] == $field && ( $id == SEARCHID_PANEL + $ind || is_null($id) ) )
return $srchF['value2'];
}
return null;
}
/**
* @param String opt
* @param Boolean not
* @return String
*/
protected function getSearchOptionUserText( $opt, $not )
{
switch( $opt )
{
case "Contains":
return $not ? NOT_CONTAINS : CONTAINS;
case "Equals":
return $not ? NOT_EQUALS : EQUALS;
case "Starts with":
return $not ? NOT_STARTS_WITH : STARTS_WITH;
case "More than":
return $not ? NOT_MORE_THAN : MORE_THAN;
case "Less than":
return $not ? NOT_LESS_THAN : LESS_THAN;
case "Between":
return $not ? NOT_BETWEEN : BETWEEN;
case "Empty":
return $not ? NOT_EMPTY : EMPTY_SEARCH;
default:
return CONTAINS;
}
}
/**
* User Search API
* @param String field
* @param Number id
* @return String
*/
public function getSearchOption( $field, $id = null )
{
$srchFields = &$this->_where["_srchFields" ];
foreach($srchFields as $ind => $srchF)
{
if( $srchF['fName'] == $field && ( $id == SEARCHID_PANEL + $ind || is_null($id) ) )
return $this->getSearchOptionUserText( $srchF['opt'], $srchF['not'] );
}
if( $this->haveAggregateFields && $this->advancedSearchActive )
return "";
$simpleSrchOption = $this->_where["simpleSrchTypeComboOpt" ];
if( strlen($simpleSrchOption) )
return $simpleSrchOption;
$simpleSrch = $this->_where["_simpleSrch" ];
if( $simpleSrch == null || !strlen($simpleSrch) )
return "";
return CONTAINS;
}
/**
* User Search API
* Get an all field search control's value
* @return mixed ( String | null )
*/
public function getAllFieldsSearchValue()
{
if( $this->haveAggregateFields && $this->advancedSearchActive )
return null;
return $this->_where["_simpleSrch" ];
}
/**
* Add a new search panel control data
* @param String field
* @param String value1
* @param String value2
* @param String opt
* @param Boolean not
* @return Number
*/
protected function addSPControlData( $field, $value1, $value2, $opt = "", $not = false )
{
if( !in_array($field, $this->searchFieldsArr) )
return -1;
if( !$opt )
$opt = $this->getDefaultSearchTypeOption($field, $this->pSetSearch);
if( !count( $this->_where["_srchFields" ] ) )
$this->_where["_srchFields" ] = array();
$srchFields = &$this->_where["_srchFields" ];
// add a new control on the search panel
$srchF = array();
$srchF['fName'] = $field;
$srchF['eType'] = $this->getSPCtrlEType( $field, $opt );
$srchF['value1'] = $value1;
$srchF['not'] = $not;
$srchF['opt'] = $opt;
$srchF['value2'] = $value2;
$srchF['byUserApi'] = true;
$srchFields[] = $srchF;
$this->srchType = 'integrated';
$this->bIsUsedSrch = true;
return SEARCHID_PANEL + count( $srchFields ) - 1;
}
/**
* @param String fName
* @return String
*/
protected function getSPCtrlEType( $fName, $opt = "" )
{
$editFormat = $this->pSetSearch->getEditFormat( $fName );
if( $editFormat == EDIT_FORMAT_DATE )
{
$dateEditType = $this->pSetSearch->getDateEditType( $fName );
//BOOTSTRAP_LAYOUT?
return "date" . $dateEditType;
}
if( $editFormat == EDIT_FORMAT_CHECKBOX )
return "checkbox";
$editControls = $this->getLocalEditControls();
$ctrl = $editControls->getControl( $fName );
if( $ctrl->checkIfDisplayFieldSearch( $opt ) )
return "display";
return "";
}
/**
* @param String field
* @param String value
* @param Number id
* @return Number
*/
public function setFieldValue( $field, $value, $id = null )
{
if( !in_array($field, $this->searchFieldsArr) )
return -1;
$srchFields = &$this->_where["_srchFields" ];
if( $this->isShowSimpleSrchOpt && ( !strlen( $this->_where["simpleSrchFieldsComboOpt" ] ) || $this->_where["simpleSrchFieldsComboOpt" ] == $field )
&& $this->_where["_simpleSrch" ] == '' && ( $id == SEARCHID_SIMPLE || !count($srchFields) && is_null($id) ) )
{
$this->_where["simpleSrchFieldsComboOpt" ] = $field;
$this->_where["_simpleSrch" ] = $value;
return SEARCHID_SIMPLE;
}
foreach($srchFields as $ind => $srchF)
{
if( $srchF['fName'] == $field && ( $id == SEARCHID_PANEL + $ind || is_null($id) ) )
{
$srchFields[ $ind ]['value1'] = $value;
return SEARCHID_PANEL + $ind;
}
}
$newId = $this->addSPControlData( $field, $value, "", "" );
return $newId;
}
/**
* User Search API
* between case
* @param String field
* @param String value
* @param Number id
* @return Number
*/
public function setSecondFieldValue( $field, $value, $id = null )
{
if( !in_array($field, $this->searchFieldsArr) )
return -1;
$srchFields = &$this->_where["_srchFields" ];
foreach($srchFields as $ind => $srchF)
{
if( $srchF['fName'] == $field && ( $id == SEARCHID_PANEL + $ind || is_null($id) ) )
{
$srchFields[ $ind ]['value2'] = $value;
return SEARCHID_PANEL + $ind;
}
}
$newId = $this->addSPControlData( $field, "" , $value, "Between" );
return $newId;
}
/**
* Get the searchOptions prop's key
* @param String opt
* @return String
*/
protected function convertUserSearchOption( $opt )
{
switch( $opt )
{
case CONTAINS:
return "contains";
case EQUALS:
return "equals";
case STARTS_WITH:
return "startswith";
case MORE_THAN:
return "morethan";
case LESS_THAN:
return "lessthan";
case BETWEEN:
return "between";
case EMPTY_SEARCH:
return "empty";
case NOT_CONTAINS:
return "notcontain";
case NOT_EQUALS:
return "notequal";
case NOT_STARTS_WITH:
return "notstartwith";
case NOT_MORE_THAN:
return "notmorethan";
case NOT_LESS_THAN:
return "notlessthan";
case NOT_BETWEEN:
return "notbetween";
case NOT_EMPTY:
return "notempty";
default:
return "contains";
}
}
/**
* User Search API
* @param String field
* @param String opt
* @param Number id
* @return Number
*/
public function setSearchOption( $field, $opt, $id = null )
{
if( !in_array($field, $this->searchFieldsArr) )
return -1;
$srchFields = &$this->_where["_srchFields" ];
if( $this->isShowSimpleSrchOpt && ( !strlen( $this->_where["simpleSrchFieldsComboOpt" ] ) || $this->_where["simpleSrchFieldsComboOpt" ] == $field )
&& ( $id == SEARCHID_SIMPLE || !count($srchFields) && is_null($id) ) )
{
$this->_where["simpleSrchFieldsComboOpt" ] = $field;
$simpleSrchOption = $this->_where["simpleSrchTypeComboOpt" ] = $opt;
return SEARCHID_SIMPLE;
}
$opt = $this->convertUserSearchOption( $opt );
foreach($srchFields as $ind => $srchF)
{
if( $srchF['fName'] == $field && ( $id == SEARCHID_PANEL + $ind || is_null($id) ) )
{
if( isset($this->searchOptions[$opt]) )
{
$srchFields[ $ind ]['not'] = $this->searchOptions[$opt]["not"];
$srchFields[ $ind ]['opt'] = $this->searchOptions[$opt]["option"];
}
return SEARCHID_PANEL + $ind;
}
}
}
/**
* User Search API
* @param String field
* @param String value
*/
public function addFieldValue( $field, $value )
{
return $this->addSPControlData( $field, $value, "", "" );
}
/**
* User Search API
* @param String value
*/
public function setAllFieldsSearchValue( $value )
{
global $suggestAllContent;
if( !$this->haveAggregateFields || !$this->advancedSearchActive /* + ? */)
{
$this->_where["_simpleSrch" ] = $value;
$this->_where["simpleSrchTypeComboOpt"] = $suggestAllContent ? "Contains" : "Starts with";
$this->_where["simpleSrchTypeComboNot"] = false;
}
}
/**
* User Search API
* @param String field
* @param String sqlCondition
*/
public function setSearchSQL( $field, $sqlCondition )
{
if( in_array( $field, $this->searchFieldsArr) )
$this->customFieldSQLConditions[ $field ] = $sqlCondition;
}
/**
*
* @return SearchClause
*/
public static function getSearchObject( $tName = "", $dashTName = "", $sessionPrefix = "", $cipherer = null,
$searchSavingEnabled = false, $pSet = null, $useCurrPageSettings = false )
{
global $strTableName, $_cachedSeachClauses;
if( !$tName )
$tName = $strTableName;
if( !$sessionPrefix )
$sessionPrefix = $dashTName ? $dashTName."_".$tName : $tName;
if ( !postvalue("saveSearch") )
$searchSavingEnabled = true;
if( $_cachedSeachClauses[ $sessionPrefix ] )
return $_cachedSeachClauses[ $sessionPrefix ];
if( $tName != $strTableName ) //dashboard ??
$currentSearchClause = SearchClause::getSearchObject( $strTableName );
if( isset( $_SESSION[ $sessionPrefix.'_advsearch' ] ) )
{
$searchClauseObj = SearchClause::UnserializeObject( $_SESSION[ $sessionPrefix.'_advsearch' ] );
}
else
{
$params = array();
$params['tName'] = $tName;
$params['dashTName'] = $dashTName;
$params['sessionPrefix'] = $sessionPrefix;
$params['searchSavingEnabled'] = $searchSavingEnabled;
if( $cipherer )
$params['cipherer'] = $cipherer;
if( !$pSet )
$pSet = new ProjectSettings( $tName ); ///?
$params['pageName'] = $pSet->pageName();
if( $useCurrPageSettings ) // send to SearchClause inst ?
{
$params['searchFieldsArr'] = $pSet->getSearchableFields();
}
$params['haveAggregateFields'] = count( $pSet->getListOfFieldsByExprType( true ) ) > 0;
$searchClauseObj = new SearchClause( $params );
}
$searchClauseObj->parseRequest();
$_cachedSeachClauses[ $sessionPrefix ] = $searchClauseObj;
return $searchClauseObj;
}
/**
* Returns array of active filter data.
* fieldName => array (
* "values" => array of values
* "sValues" => array of formatted values
* "parentValues" => parent values for dependent filters
* "type" => filter type
* )
*/
public function getFilteredFields() {
if( $this->filteredFields )
return $this->filteredFields;
$filtersParams = postvalue('f');
if( !$filtersParams && isset($_SESSION[$this->sessionPrefix."_filters"]) )
$filtersParams = $_SESSION[$this->sessionPrefix."_filters"];
if(!$filtersParams || $filtersParams == 'all')
return array();
$filters = $this->parseStringToArray($filtersParams, true);
foreach($filters as $filter)
{
$fName = $this->searchUnEscape( $filter[0] );
if( !$this->filteredFields[$fName] ) {
$this->filteredFields[$fName] = array( "values"=> array(), "parentValues" => array(), "sValues" => array() );
}
$fieldArr = &$this->filteredFields[$fName];
$fieldArr["type"] = $filter[1];
$fieldArr["values"][] = $this->searchUnEscape( $filter[2] );
$fieldArr["sValues"][] = $this->searchUnEscape( $filter[3] );
$parentValue = array();
if( $filter[4] )
{
$parentValuesString = $this->searchUnEscape( $filter[4] ); // values glued by '|'
$parentValue = $this->getUnescapedFValues( $parentValuesString );
}
$fieldArr["parentValues"][] = $parentValue;
}
return $this->filteredFields;
}
/**
*/
function getFilterCondition( $controls, $ignoreFilterField = "" )
{
$fields = $this->getFilteredFields();
$conditions = array();
foreach( $fields as $f => $fieldArr ) {
if( $f == $ignoreFilterField ) {
continue;
}
$fieldConditions = array();
foreach( $fieldArr["values"] as $i => $val ) {
$fieldConditions[] = $this->getFilterConditionByType( $fieldArr["type"], $f, $val , $fieldArr["sValues"][$i], $fieldArr["parentValues"][$i] );
}
$conditions[] = DataCondition::_Or( $fieldConditions );
}
return DataCondition::_And( $conditions );
/*
$this->filteredFields = array();
$strFieldWhere = array();
$filtersParams = postvalue('f');
if( !$filtersParams && isset($_SESSION[$this->sessionPrefix."_filters"]) )
$filtersParams = $_SESSION[$this->sessionPrefix."_filters"];
if(!$filtersParams || $filtersParams == 'all')
return;
$filters = $this->parseStringToArray($filtersParams, true);
$fieldConditions = array();
foreach($filters as $filter)
{
$fName = $this->searchUnEscape( $filter[0] );
if( $fName == $ignoreFilterField ) {
continue;
}
if( !$this->filteredFields[$fName] ) {
$this->filteredFields[$fName] = array( "values"=> array(), "parentValues" => array() );
}
$filterType = $filter[1];
$fValue = $this->searchUnEscape( $filter[2] );
$sValue = $this->searchUnEscape( $filter[3] );
$parentValue = array();
if( $filter[4] )
{
$parentValuesString = $this->searchUnEscape( $filter[4] ); // values glued by '|'
$parentValues = $this->getUnescapedFValues( $parentValuesString );
$this->filteredFields[$fName]["parentValues"] = $parentValues;
}
if( !$fieldConditions[ $fName ] ) {
$fieldConditions[ $fName ] = array();
}
$fieldConditions[ $fName ][] = $this->getFilterConditionByType( $filterType, $fName, $fValue , $sValue, $parentValues );
$this->filteredFields[$fName]["values"][] = $fValue;
// $this->filteredFields[$fName] = array("values" => $fData["value"], "where" => $fieldWhere, "parentValues" => $fData["parentValues"] );
}
// combine conditions. Conditions for the same field are combined with OR, the results are with AND
$conditions = array();
foreach( $fieldConditions as $fc ) {
$conditions[] = DataCondition::_Or( $fc );
}
return DataCondition::_And( $conditions );
*/
}
/**
* Get filter's WHERE clause condition basing on the filter's type
*
* @param String filterType A string representing the filter's type
* @param String fName
* @param String sValue - second value ( for sliders )
* @param String dbType
* @return String
*/
function getFilterConditionByType($filterType, $fName, $fValue, $sValue, $parentValues )
{
include_once getabspath("classes/controls/FilterControl.php");
include_once getabspath("classes/controls/FilterValuesList.php");
include_once getabspath("classes/controls/FilterBoolean.php");
include_once getabspath("classes/controls/FilterIntervalList.php");
include_once getabspath("classes/controls/FilterIntervalSlider.php");
switch($filterType)
{
case 'equals':
$self = FilterValuesList::getFilterCondition( $fName, $fValue, $this->pSetSearch );
if( !count($parentValues) )
return $self;
$conditions = array( $self );
$parentFiltersNames = FilterValuesList::getParentFilterFields( $fName, $this->pSetSearch );
foreach( $parentFiltersNames as $key => $parentName )
{
$conditions[] = FilterValuesList::getFilterCondition(
$parentName,
$parentValues[$key],
$this->pSetSearch );
}
return DataCondition::_And( $conditions );
case 'interval':
return FilterIntervalList::getFilterCondition( $fName, $fValue, $this->pSetSearch );
case 'checked':
return FilterBoolean::getFilterCondition( $fName, $fValue, $this->pSetSearch );
case 'slider':
case 'moreequal':
case 'lessequal':
return FilterIntervalSlider::getFilterCondition( $fName, $fValue, $this->pSetSearch, $sValue );
default:
return null;
}
}
public function getSearchDataCondition( $editControls = null )
{
if( is_null($editControls) )
$editControls = $this->getLocalEditControls();
//#5083 ???
$simpleCondition = $this->getSimpleSearchCondition( $editControls );
$searchCombineType = $this->getCriteriaCombineType();
$searchFields = &$this->_where["_srchFields" ];
$fieldConditions = array();
foreach ($searchFields as $ind => $srchF)
{
$field = $srchF['fName'];
if( isset( $this->customFieldSQLConditions[ $field ] ) ) {
continue;
}
if( !isset( $fieldConditions[ $field ] ) ) {
$fieldConditions[ $field ] = array();
}
$control = $editControls->getControl( $field, SEARCHID_PANEL );
$fieldConditions[ $field ][] = $control->getSearchCondition( $srchF['value1'], $srchF['opt'], $srchF['value2'], $srchF['not'] );
}
foreach( $this->customFieldSQLConditions as $field => $sql )
{
$fieldConditions[ $field ] = array( DataCondition::SQLCondition( $sql ) );
}
$conditions = array( $simpleCondition );
foreach( $fieldConditions as $f => $fc ) {
$conditions[] = DataCondition::_Or( $fc );
}
return DataCondition::_And( $conditions );
}
protected function getSimpleSearchCondition( $editControls )
{
$searchFor = $this->_where["_simpleSrch" ];
$searchOption = $this->_where["simpleSrchTypeComboOpt" ];
$searchField = $this->_where["simpleSrchFieldsComboOpt" ];
$searchNot = $this->_where["simpleSrchTypeComboNot" ];
if( $searchFor == "" && $searchOption != "Empty" )
return null;
if( $searchField && !isset( $this->customFieldSQLConditions[ $searchField ] ) )
{
$cond = $editControls->getControl( $searchField, SEARCHID_SIMPLE )->getSearchCondition( $searchFor, $searchOption );
if( $searchNot ) {
$cond = DataCondition::_Not( $cond );
}
return $cond;
}
$searchForValues = $this->googleLikeParseString( $searchFor );
$valueConditions = array();
foreach( $this->searchFieldsArr as $field ) {
if( !in_array( $field, $this->googleLikeFields ) ) {
continue;
}
if( isset( $this->customFieldSQLConditions[ $field ] ) ) {
continue;
}
foreach($searchForValues as $ind => $searchValue ) {
if( !isset( $valueConditions[$ind] ) ) {
$valueConditions[$ind] = array();
}
$control = $editControls->getControl( $field, SEARCHID_ALL );
$valueConditions[$ind][] = $control->getSearchCondition( $searchFor, $searchOption );
}
}
/**
* All user-entered values must be found in a record no matter where.
* The resulting condition must be like:
* ( field1 == value1 || field2 == value1) && ( field1 == value2 || field2 == value2 )
*/
$conditions = array();
foreach( $valueConditions as $c ) {
$conditions[] = DataCondition::_Or( $c );
}
return DataCondition::_And( $conditions );
}
/**
* @return Boolean
*/
public function searchStarted() {
return $this->srchType !== 'showall';
}
public function resetSearch() {
$this->_where["_search"] = 0;
$this->srchType = 'showall';
$this->bIsUsedSrch = false;
$this->clearSearch();
$_SESSION[$this->sessionPrefix."_pagenumber"] = 1;
$this->removeSessionSearchVariables();
$this->simpleSearchActive = false;
}
}
?>
|