Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1159836
search_helper.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Sep 18, 5:47 PM
Size
27 KB
Mime Type
text/x-php
Expires
Sat, Sep 20, 5:47 PM (1 h, 53 m)
Engine
blob
Format
Raw Data
Handle
750148
Attached To
rINP In-Portal
search_helper.php
View Options
<?php
/**
* @version $Id: search_helper.php 16797 2024-08-16 08:27:01Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined
(
'FULL_PATH'
)
or
die
(
'restricted access!'
);
class
kSearchHelper
extends
kHelper
{
/**
* Perform Exact Search flag
*
* @var bool
* @access protected
*/
protected
$_performExactSearch
=
true
;
public
function
__construct
()
{
parent
::
__construct
();
$this
->
_performExactSearch
=
$this
->
Application
->
ConfigValue
(
'PerformExactSearch'
);
}
/**
* Splits search phrase into keyword using quotes,plus and minus sings and spaces as split criteria
*
* @param string $keyword
* @return Array
* @access public
*/
public
function
splitKeyword
(
$keyword
)
{
if
(
$this
->
Application
->
ConfigValue
(
'CheckStopWords'
)
)
{
$keyword_after_remove
=
$this
->
_removeStopWords
(
$keyword
);
if
(
$keyword_after_remove
)
{
// allow to search through stop word grid
$keyword
=
$keyword_after_remove
;
}
}
$final
=
Array
();
$quotes_re
=
'/([+
\-
]?)"(.*?)"/'
;
$no_quotes_re
=
'/([+
\-
]?)([^ ]+)/'
;
preg_match_all
(
$quotes_re
,
$keyword
,
$res
);
foreach
(
$res
[
2
]
as
$index
=>
$kw
)
{
$final
[
$kw
]
=
$res
[
1
][
$index
];
}
$keyword
=
preg_replace
(
$quotes_re
,
''
,
$keyword
);
preg_match_all
(
$no_quotes_re
,
$keyword
,
$res
);
foreach
(
$res
[
2
]
as
$index
=>
$kw
)
{
$final
[
$kw
]
=
$res
[
1
][
$index
];
}
if
(
$this
->
_performExactSearch
)
{
foreach
(
$final
AS
$kw
=>
$plus_minus
)
{
if
(
!
$plus_minus
)
{
$final
[
$kw
]
=
'+'
;
}
}
}
return
$final
;
}
function
getPositiveKeywords
(
$keyword
)
{
$keywords
=
$this
->
splitKeyword
(
$keyword
);
$ret
=
Array
();
foreach
(
$keywords
as
$keyword
=>
$sign
)
{
if
(
$sign
==
'+'
||
$sign
==
''
)
{
$ret
[]
=
$keyword
;
}
}
return
$ret
;
}
/**
* Replace wildcards to match MySQL
*
* @param string $keyword
* @return string
*/
function
transformWildcards
(
$keyword
)
{
return
str_replace
(
Array
(
'%'
,
'_'
,
'*'
,
'?'
)
,
Array
(
'
\%
'
,
'
\_
'
,
'%'
,
'_'
),
$keyword
);
}
function
buildWhereClause
(
$keyword
,
$fields
)
{
$keywords
=
$this
->
splitKeyword
(
$this
->
transformWildcards
(
$keyword
)
);
$normal_conditions
=
$plus_conditions
=
$minus_conditions
=
Array
();
foreach
(
$keywords
as
$keyword
=>
$sign
)
{
$keyword
=
$this
->
Conn
->
escape
(
$keyword
);
switch
(
$sign
)
{
case
'+'
:
$plus_conditions
[]
=
implode
(
" LIKE '%"
.
$keyword
.
"%' OR "
,
$fields
)
.
" LIKE '%"
.
$keyword
.
"%'"
;
break
;
case
'-'
:
$condition
=
Array
();
foreach
(
$fields
as
$field
)
{
$condition
[]
=
$field
.
" NOT LIKE '%"
.
$keyword
.
"%' OR "
.
$field
.
' IS NULL'
;
}
$minus_conditions
[]
=
'('
.
implode
(
') AND ('
,
$condition
)
.
')'
;
break
;
case
''
:
$normal_conditions
[]
=
implode
(
" LIKE '%"
.
$keyword
.
"%' OR "
,
$fields
)
.
" LIKE '%"
.
$keyword
.
"%'"
;
break
;
}
}
// building where clause
if
(
$normal_conditions
)
{
$where_clause
=
'('
.
implode
(
') OR ('
,
$normal_conditions
)
.
')'
;
}
else
{
$where_clause
=
'1'
;
}
if
(
$plus_conditions
)
{
$where_clause
=
'('
.
$where_clause
.
') AND ('
.
implode
(
') AND ('
,
$plus_conditions
)
.
')'
;
}
if
(
$minus_conditions
)
{
$where_clause
=
'('
.
$where_clause
.
') AND ('
.
implode
(
') AND ('
,
$minus_conditions
)
.
')'
;
}
return
$where_clause
;
}
/**
* Returns additional information about search field
*
* @param kDBList $object
* @param string $field_name
* @return Array
*/
function
_getFieldInformation
(&
$object
,
$field_name
)
{
$sql_filter_type
=
$object
->
isVirtualField
(
$field_name
)
?
'having'
:
'where'
;
$field_options
=
$object
->
GetFieldOptions
(
$field_name
);
$table_name
=
''
;
$field_type
=
isset
(
$field_options
[
'type'
])
?
$field_options
[
'type'
]
:
'string'
;
if
(
preg_match
(
'/(.*)
\.
(.*)/'
,
$field_name
,
$regs
))
{
$table_name
=
'`'
.
$regs
[
1
].
'`.'
;
// field from external table
$field_name
=
$regs
[
2
];
}
elseif
(
$sql_filter_type
==
'where'
)
{
$table_name
=
'`'
.
$object
->
TableName
.
'`.'
;
// field from local table
}
$table_name
=
(
$sql_filter_type
==
'where'
)
?
$table_name
:
''
;
// Replace wid inside table name to WID_MARK constant value.
$is_temp_table
=
preg_match
(
'/(.*)'
.
TABLE_PREFIX
.
'ses_[
\d
]+(_[
\d
]+){0,1}_edit_(.*)/'
,
$table_name
,
$regs
);
// The EDIT_MARK will be replaced with sid[_main_wid] in AddFilters.
if
(
$is_temp_table
)
{
$table_name
=
$regs
[
1
]
.
TABLE_PREFIX
.
'ses_'
.
EDIT_MARK
.
'_edit_'
.
$regs
[
3
];
}
return
Array
(
$field_name
,
$field_type
,
$table_name
,
$sql_filter_type
);
}
/**
* Removes stop words from keyword
*
* @param string $keyword
* @return string
*/
function
_removeStopWords
(
$keyword
)
{
static
$stop_words
=
Array
();
if
(!
$stop_words
)
{
$sql
=
'SELECT StopWord
FROM '
.
$this
->
Application
->
getUnitOption
(
'stop-word'
,
'TableName'
)
.
'
ORDER BY LENGTH(StopWord) DESC, StopWord ASC'
;
$stop_words
=
$this
->
Conn
->
GetCol
(
$sql
);
foreach
(
$stop_words
as
$index
=>
$stop_word
)
{
$stop_words
[
$index
]
=
'/(^| )'
.
preg_quote
(
$stop_word
,
'/'
)
.
'( |$)/'
;
}
}
$keyword
=
preg_replace
(
$stop_words
,
' '
,
$keyword
);
return
trim
(
preg_replace
(
'/[ ]+/'
,
' '
,
$keyword
)
);
}
/**
* Performs new search on a given grid
*
* @param kEvent $event
* @return void
* @access public
*/
public
function
performSearch
(
$event
)
{
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
// process search keyword
$search_keyword
=
$this
->
Application
->
GetVar
(
$event
->
getPrefixSpecial
(
true
)
.
'_search_keyword'
);
$this
->
Application
->
StoreVar
(
$event
->
getPrefixSpecial
()
.
'_search_keyword'
,
$search_keyword
);
$custom_filter
=
$this
->
processCustomFilters
(
$event
);
if
(
!
$search_keyword
&&
$custom_filter
===
false
)
{
$this
->
resetSearch
(
$event
);
return
;
}
if
(
$search_keyword
)
{
$this
->
processAutomaticFilters
(
$event
,
$search_keyword
,
$custom_filter
);
}
}
/**
* Creates filtering sql clauses based on given search restrictions
*
* @param kEvent $event
* @param string $search_keyword
* @param Array $custom_filter
* @return void
*/
function
processAutomaticFilters
(
$event
,
$search_keyword
,
$custom_filter
)
{
$grid_name
=
$this
->
Application
->
GetVar
(
'grid_name'
);
$grids
=
$this
->
Application
->
getUnitOption
(
$event
->
Prefix
,
'Grids'
);
$search_fields
=
array_keys
(
$grids
[
$grid_name
][
'Fields'
]);
$search_filter
=
Array
();
/** @var kDBList $object */
$object
=
$event
->
getObject
();
foreach
(
$search_fields
as
$search_field
)
{
$custom_search
=
isset
(
$custom_filter
[
$search_field
]);
$filter_data
=
$this
->
getSearchClause
(
$object
,
$search_field
,
$search_keyword
,
$custom_search
);
if
(
$filter_data
)
{
$search_filter
[
$search_field
]
=
$filter_data
;
}
else
{
unset
(
$search_filter
[
$search_field
]);
}
}
$this
->
Application
->
StoreVar
(
$event
->
getPrefixSpecial
().
'_search_filter'
,
serialize
(
$search_filter
)
);
}
/**
* Returns search clause for any particular field
*
* @param kDBList $object
* @param string $field_name
* @param string $search_keyword what we are searching (false, when building custom filter clause)
* @param string $custom_search already found using custom filter
* @return Array
*/
function
getSearchClause
(&
$object
,
$field_name
,
$search_keyword
,
$custom_search
)
{
if
(
$object
->
isVirtualField
(
$field_name
)
&&
!
$object
->
isCalculatedField
(
$field_name
))
{
// Virtual field, that is shown in grid, but it doesn't have corresponding calculated field.
// Happens, when field value is calculated on the fly (during grid display) and it is not searchable.
return
''
;
}
$search_keywords
=
$this
->
splitKeyword
(
$search_keyword
);
list
(
$field_name
,
$field_type
,
$table_name
,
$sql_filter_type
)
=
$this
->
_getFieldInformation
(
$object
,
$field_name
);
$filter_value
=
''
;
// get field clause by formatter name and/or parameters
$field_options
=
$object
->
GetFieldOptions
(
$field_name
);
$formatter
=
getArrayValue
(
$field_options
,
'formatter'
);
switch
(
$formatter
)
{
case
'kOptionsFormatter'
:
$search_keys
=
Array
();
if
(
$custom_search
===
false
)
{
// if keywords passed through simple search filter (on each grid)
$use_phrases
=
getArrayValue
(
$field_options
,
'use_phrases'
);
$multiple
=
array_key_exists
(
'multiple'
,
$field_options
)
&&
$field_options
[
'multiple'
];
foreach
(
$field_options
[
'options'
]
as
$key
=>
$val
)
{
$match_to
=
mb_strtolower
(
$use_phrases
?
$this
->
Application
->
Phrase
(
$val
)
:
$val
);
foreach
(
$search_keywords
as
$keyword
=>
$sign
)
{
// doesn't support wildcards
if
(
strpos
(
$match_to
,
mb_strtolower
(
$keyword
))
===
false
)
{
if
(
$sign
==
'+'
)
{
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` = NULL'
;
break
;
}
else
{
continue
;
}
}
if
(
$sign
==
'+'
||
$sign
==
''
)
{
// don't add single quotes to found option ids when multiselect (but escape string anyway)
$search_keys
[
$key
]
=
$multiple
?
$this
->
Conn
->
escape
(
$key
)
:
$this
->
Conn
->
qstr
(
$key
);
}
elseif
(
$sign
==
'-'
)
{
// if same value if found as exclusive too, then remove from search result
unset
(
$search_keys
[
$key
]);
}
}
}
}
if
(
$search_keys
)
{
if
(
$multiple
)
{
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` LIKE "%|'
.
implode
(
'|%" OR '
.
$table_name
.
'`'
.
$field_name
.
'` LIKE "%|'
,
$search_keys
)
.
'|%"'
;
}
else
{
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` IN ('
.
implode
(
','
,
$search_keys
).
')'
;
}
}
$field_processed
=
true
;
break
;
case
'kDateFormatter'
:
// if date is searched using direct filter, then do nothing here, otherwise search using LIKE clause
$field_processed
=
(
$custom_search
!==
false
)
?
true
:
false
;
break
;
default
:
$field_processed
=
false
;
break
;
}
// if not already processed by formatter, then get clause by field type
if
(!
$field_processed
&&
$search_keywords
)
{
switch
(
$field_type
)
{
case
'int'
:
case
'integer'
:
case
'numeric'
:
$search_keys
=
Array
();
foreach
(
$search_keywords
as
$keyword
=>
$sign
)
{
if
(!
is_numeric
(
$keyword
)
||
(
$sign
==
'-'
))
{
continue
;
}
$search_keys
[]
=
$this
->
Conn
->
qstr
(
$keyword
);
}
if
(
$search_keys
)
{
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` IN ('
.
implode
(
','
,
$search_keys
).
')'
;
}
break
;
case
'double'
:
case
'float'
:
case
'real'
:
$search_keys
=
Array
();
foreach
(
$search_keywords
as
$keyword
=>
$sign
)
{
$keyword
=
str_replace
(
','
,
'.'
,
$keyword
);
if
(!
is_numeric
(
$keyword
)
||
(
$sign
==
'-'
))
continue
;
$search_keys
[]
=
'ABS('
.
$table_name
.
'`'
.
$field_name
.
'` - '
.
$this
->
Conn
->
qstr
(
$keyword
).
') <= 0.0001'
;
}
if
(
$search_keys
)
{
$filter_value
=
'('
.
implode
(
') OR ('
,
$search_keys
).
')'
;
}
break
;
case
'string'
:
$filter_value
=
$this
->
buildWhereClause
(
$search_keyword
,
Array
(
$table_name
.
'`'
.
$field_name
.
'`'
));
break
;
}
}
if
(
$filter_value
)
{
return
Array
(
'type'
=>
$sql_filter_type
,
'value'
=>
$filter_value
);
}
return
false
;
}
/**
* Processes custom filters from submit
*
* @param kEvent $event
* @return Array|bool
*/
function
processCustomFilters
(
$event
)
{
$grid_name
=
$this
->
Application
->
GetVar
(
'grid_name'
);
// update "custom filter" with values from submit: begin
$view_name
=
$this
->
Application
->
RecallVar
(
$event
->
getPrefixSpecial
().
'_current_view'
);
$custom_filters
=
$this
->
Application
->
RecallPersistentVar
(
$event
->
getPrefixSpecial
().
'_custom_filter.'
.
$view_name
/*, ALLOW_DEFAULT_SETTINGS*/
);
if
(
$custom_filters
)
{
$custom_filters
=
unserialize
(
$custom_filters
);
$custom_filter
=
isset
(
$custom_filters
[
$grid_name
])
?
$custom_filters
[
$grid_name
]
:
Array
();
}
else
{
$custom_filter
=
Array
();
}
// submit format custom_filters[prefix_special][field]
$submit_filters
=
$this
->
Application
->
GetVar
(
'custom_filters'
);
if
(
$submit_filters
)
{
$submit_filters
=
getArrayValue
(
$submit_filters
,
$event
->
getPrefixSpecial
(),
$grid_name
);
if
(
$submit_filters
)
{
foreach
(
$submit_filters
as
$field_name
=>
$field_options
)
{
$filter_type
=
key
(
$field_options
);
$field_value
=
$field_options
[
$filter_type
];
$is_empty
=
strlen
(
is_array
(
$field_value
)
?
implode
(
''
,
$field_value
)
:
$field_value
)
==
0
;
if
(
$is_empty
)
{
if
(
isset
(
$custom_filter
[
$field_name
]))
{
// use isset, because non-existing key will cause "php notice"!
unset
(
$custom_filter
[
$field_name
][
$filter_type
]);
// remove filter
if
(!
$custom_filter
[
$field_name
])
{
// if no filters left for field, then delete record at all
unset
(
$custom_filter
[
$field_name
]);
}
}
}
else
{
$custom_filter
[
$field_name
][
$filter_type
][
'submit_value'
]
=
$field_value
;
}
}
}
}
if
(
$custom_filter
)
{
$custom_filters
[
$grid_name
]
=
$custom_filter
;
}
else
{
unset
(
$custom_filters
[
$grid_name
]);
}
// update "custom filter" with values from submit: end
if
(!
$custom_filter
)
{
// in case when no filters specified, there are nothing to process
$this
->
Application
->
StorePersistentVar
(
$event
->
getPrefixSpecial
().
'_custom_filter.'
.
$view_name
,
serialize
(
$custom_filters
)
);
return
false
;
}
$object
=
$event
->
getObject
();
// don't recall it each time in getCustomFilterSearchClause
$grid_info
=
$this
->
Application
->
getUnitOption
(
$event
->
Prefix
.
'.'
.
$grid_name
,
'Grids'
);
foreach
(
$custom_filter
as
$field_name
=>
$field_options
)
{
$filter_type
=
key
(
$field_options
);
$field_options
=
$field_options
[
$filter_type
];
$field_options
[
'grid_options'
]
=
$grid_info
[
'Fields'
][
$field_name
];
$field_options
=
$this
->
getCustomFilterSearchClause
(
$object
,
$field_name
,
$filter_type
,
$field_options
);
if
(
$field_options
[
'value'
])
{
unset
(
$field_options
[
'grid_options'
]);
$custom_filter
[
$field_name
][
$filter_type
]
=
$field_options
;
}
}
$custom_filters
[
$grid_name
]
=
$custom_filter
;
$this
->
Application
->
StorePersistentVar
(
$event
->
getPrefixSpecial
().
'_custom_filter.'
.
$view_name
,
serialize
(
$custom_filters
)
);
return
$custom_filter
;
}
/**
* Checks, that range filters "To" part is defined for given grid
*
* @param string $prefix_special
* @param string $grid_name
* @return bool
*/
function
rangeFiltersUsed
(
$prefix_special
,
$grid_name
)
{
static
$cache
=
Array
();
$cache_key
=
$prefix_special
.
$grid_name
;
if
(
array_key_exists
(
$cache_key
,
$cache
))
{
return
$cache
[
$cache_key
];
}
$view_name
=
$this
->
Application
->
RecallVar
(
$prefix_special
.
'_current_view'
);
$custom_filters
=
$this
->
Application
->
RecallPersistentVar
(
$prefix_special
.
'_custom_filter.'
.
$view_name
/*, ALLOW_DEFAULT_SETTINGS*/
);
if
(!
$custom_filters
)
{
// filters not defined for given prefix
$cache
[
$cache_key
]
=
false
;
return
false
;
}
$custom_filters
=
unserialize
(
$custom_filters
);
if
(!
is_array
(
$custom_filters
)
||
!
array_key_exists
(
$grid_name
,
$custom_filters
))
{
// filters not defined for given grid
$cache
[
$cache_key
]
=
false
;
return
false
;
}
$range_filter_defined
=
false
;
$custom_filter
=
$custom_filters
[
$grid_name
];
foreach
(
$custom_filter
as
$field_name
=>
$field_options
)
{
$filter_type
=
key
(
$field_options
);
$field_options
=
$field_options
[
$filter_type
];
if
(
strpos
(
$filter_type
,
'range'
)
===
false
)
{
continue
;
}
$to_value
=
(
string
)
$field_options
[
'submit_value'
][
'to'
];
if
(
$to_value
!==
''
)
{
$range_filter_defined
=
true
;
break
;
}
}
$cache
[
$cache_key
]
=
$range_filter_defined
;
return
$range_filter_defined
;
}
/**
* Return numeric range filter value + checking that it's number
*
* @param Array $value array containing range filter value
* @return unknown
*/
function
getRangeValue
(
$value
)
{
// fix user typing error, since MySQL only sees "." as decimal separator
$value
=
str_replace
(
','
,
'.'
,
$value
);
return
strlen
(
$value
)
&&
is_numeric
(
$value
)
?
$this
->
Conn
->
qstr
(
$value
)
:
false
;
}
/**
* Returns filter clause
*
* @param kDBItem $object
* @param string $field_name
* @param string $filter_type
* @param Array $field_options
* @return Array
*/
function
getCustomFilterSearchClause
(&
$object
,
$field_name
,
$filter_type
,
$field_options
)
{
// this is usually used for mutlilingual fields and date fields
if
(
isset
(
$field_options
[
'grid_options'
][
'sort_field'
]))
{
$field_name
=
$field_options
[
'grid_options'
][
'sort_field'
];
}
list
(
$field_name
,
$field_type
,
$table_name
,
$sql_filter_type
)
=
$this
->
_getFieldInformation
(
$object
,
$field_name
);
$filter_value
=
''
;
switch
(
$filter_type
)
{
case
'range'
:
$from
=
$this
->
getRangeValue
(
$field_options
[
'submit_value'
][
'from'
]);
$to
=
$this
->
getRangeValue
(
$field_options
[
'submit_value'
][
'to'
]);
if
(
$from
!==
false
&&
$to
!==
false
)
{
// add range filter
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` >= '
.
$from
.
' AND '
.
$table_name
.
'`'
.
$field_name
.
'` <= '
.
$to
;
}
elseif
(
$field_type
==
'int'
||
$field_type
==
'integer'
)
{
if
(
$from
!==
false
)
{
// add equals filter on $from
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` = '
.
$from
;
}
elseif
(
$to
!==
false
)
{
// add equals filter on $to
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` = '
.
$to
;
}
}
else
{
// MySQL can't compare values in "float" type columns using "=" operator
if
(
$from
!==
false
)
{
// add equals filter on $from
$filter_value
=
'ABS('
.
$table_name
.
'`'
.
$field_name
.
'` - '
.
$from
.
') <= 0.0001'
;
}
elseif
(
$to
!==
false
)
{
// add equals filter on $to
$filter_value
=
'ABS('
.
$table_name
.
'`'
.
$field_name
.
'` - '
.
$to
.
') <= 0.0001'
;
}
}
break
;
case
'date_range'
:
$from
=
$this
->
processRangeField
(
$object
,
$field_name
,
$field_options
[
'submit_value'
],
'from'
);
$to
=
$this
->
processRangeField
(
$object
,
$field_name
,
$field_options
[
'submit_value'
],
'to'
);
$day_seconds
=
23
*
60
*
60
+
59
*
60
+
59
;
if
(
is_numeric
(
$from
)
&&
$to
===
null
&&
date
(
'H:i:s'
,
$from
)
==
'00:00:00'
)
{
$to
=
$from
+
$day_seconds
;
}
elseif
(
$from
===
null
&&
is_numeric
(
$to
)
&&
date
(
'H:i:s'
,
$to
)
==
'00:00:00'
)
{
$from
=
$to
;
$to
+=
$day_seconds
;
}
if
(
is_numeric
(
$from
)
&&
$to
===
null
||
$from
===
null
&&
is_numeric
(
$to
)
)
{
$from
=
$from
===
null
?
$to
:
$from
;
$to
=
$from
;
}
if
(
is_numeric
(
$from
)
&&
is_numeric
(
$to
)
)
{
$from
=
strtotime
(
date
(
'Y-m-d H:i'
,
$from
)
.
':00'
,
$from
);
$to
=
strtotime
(
date
(
'Y-m-d H:i'
,
$to
)
.
':59'
,
$to
);
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` >= '
.
$from
.
' AND '
.
$table_name
.
'`'
.
$field_name
.
'` <= '
.
$to
;
}
else
{
$filter_value
=
'FALSE'
;
}
break
;
case
'equals'
:
case
'options'
:
$field_value
=
strlen
(
$field_options
[
'submit_value'
])
?
$this
->
Conn
->
qstr
(
$field_options
[
'submit_value'
])
:
false
;
if
(
$field_value
)
{
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` = '
.
$field_value
;
}
break
;
case
'picker'
:
$field_value
=
strlen
(
$field_options
[
'submit_value'
])
?
$this
->
Conn
->
escape
(
$field_options
[
'submit_value'
])
:
false
;
if
(
$field_value
)
{
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` LIKE "%|'
.
$field_value
.
'|%"'
;
}
break
;
case
'multioptions'
:
$field_value
=
$field_options
[
'submit_value'
];
if
(
$field_value
)
{
$field_value
=
explode
(
'|'
,
substr
(
$field_value
,
1
,
-
1
));
$multiple
=
$object
->
GetFieldOption
(
$field_name
,
'multiple'
);
$field_value
=
$this
->
Conn
->
qstrArray
(
$field_value
,
$multiple
?
'escape'
:
'qstr'
);
if
(
$multiple
)
{
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` LIKE "%|'
.
implode
(
'|%" OR '
.
$table_name
.
'`'
.
$field_name
.
'` LIKE "%|'
,
$field_value
)
.
'|%"'
;
}
else
{
$filter_value
=
$table_name
.
'`'
.
$field_name
.
'` IN ('
.
implode
(
','
,
$field_value
)
.
')'
;
}
}
break
;
case
'like'
:
$filter_value
=
$this
->
buildWhereClause
(
$field_options
[
'submit_value'
],
Array
(
$table_name
.
'`'
.
$field_name
.
'`'
));
break
;
default
:
break
;
}
$field_options
[
'sql_filter_type'
]
=
$sql_filter_type
;
$field_options
[
'value'
]
=
$filter_value
;
return
$field_options
;
}
/**
* Enter description here...
*
* @param kdbItem $object
* @param string $search_field
* @param string $value
* @param string $type
* @param string $format_option_prefix Format option prefix.
*/
function
processRangeField
(&
$object
,
$search_field
,
$value
,
$type
,
$format_option_prefix
=
''
)
{
$value_by_type
=
$value
[
$type
];
if
(
!
strlen
(
$value_by_type
)
)
{
return
null
;
}
$options
=
$object
->
GetFieldOptions
(
$search_field
);
$dt_separator
=
array_key_exists
(
'date_time_separator'
,
$options
)
?
$options
[
'date_time_separator'
]
:
' '
;
$value_by_type
=
trim
(
$value_by_type
,
$dt_separator
);
// trim any
$tmp_value
=
explode
(
$dt_separator
,
$value_by_type
,
2
);
if
(
count
(
$tmp_value
)
==
1
)
{
$time_format
=
$this
->
_getInputTimeFormat
(
$options
,
$format_option_prefix
.
'time_format'
);
if
(
$time_format
)
{
// time is missing, but time format available -> guess time and add to date
$time
=
adodb_mktime
(
0
,
0
,
0
);
$time
=
adodb_date
(
$time_format
,
$time
);
$value_by_type
.=
$dt_separator
.
$time
;
}
}
/** @var kFormatter $formatter */
$formatter
=
$this
->
Application
->
recallObject
(
$options
[
'formatter'
]);
$format
=
$options
[
$format_option_prefix
.
'format'
];
$value_ts
=
$formatter
->
Parse
(
$value_by_type
,
$search_field
,
$object
,
$format
);
if
(
$object
->
GetErrorPseudo
(
$search_field
)
)
{
// invalid format -> ignore this date in search
$object
->
RemoveError
(
$search_field
);
if
(
$format_option_prefix
==
'input_'
)
{
return
false
;
}
return
$this
->
processRangeField
(
$object
,
$search_field
,
$value
,
$type
,
'input_'
);
}
return
$value_ts
;
}
/**
* Returns InputTimeFormat using given field options
*
* @param Array $field_options
* @param string $format_option_name Format option name.
* @return string
*/
function
_getInputTimeFormat
(
$field_options
,
$format_option_name
=
'input_time_format'
)
{
if
(
array_key_exists
(
$format_option_name
,
$field_options
)
)
{
return
$field_options
[
$format_option_name
];
}
/** @var LanguagesItem $lang_current */
$lang_current
=
$this
->
Application
->
recallObject
(
'lang.current'
);
$field_name
=
str_replace
(
' '
,
''
,
ucwords
(
str_replace
(
'_'
,
' '
,
$format_option_name
)));
return
$lang_current
->
GetDBField
(
$field_name
);
}
/**
* Resets current search
*
* @param kEvent $event
*/
function
resetSearch
(
$event
)
{
$this
->
Application
->
RemoveVar
(
$event
->
getPrefixSpecial
().
'_search_filter'
);
$this
->
Application
->
RemoveVar
(
$event
->
getPrefixSpecial
().
'_search_keyword'
);
$view_name
=
$this
->
Application
->
RecallVar
(
$event
->
getPrefixSpecial
().
'_current_view'
);
$this
->
Application
->
RemovePersistentVar
(
$event
->
getPrefixSpecial
().
'_custom_filter.'
.
$view_name
);
}
/**
* Creates filters based on "types" & "except" parameters from PrintList
*
* @param kEvent $event
* @param Array $type_clauses
* @param string $types
* @param string $except_types
*/
function
SetComplexFilter
(
$event
,
&
$type_clauses
,
$types
,
$except_types
)
{
/** @var kMultipleFilter $includes_or_filter */
$includes_or_filter
=
$this
->
Application
->
makeClass
(
'kMultipleFilter'
,
Array
(
kDBList
::
FLT_TYPE_OR
));
/** @var kMultipleFilter $excepts_and_filter */
$excepts_and_filter
=
$this
->
Application
->
makeClass
(
'kMultipleFilter'
,
Array
(
kDBList
::
FLT_TYPE_AND
));
/** @var kMultipleFilter $includes_or_filter_h */
$includes_or_filter_h
=
$this
->
Application
->
makeClass
(
'kMultipleFilter'
,
Array
(
kDBList
::
FLT_TYPE_OR
));
/** @var kMultipleFilter $excepts_and_filter_h */
$excepts_and_filter_h
=
$this
->
Application
->
makeClass
(
'kMultipleFilter'
,
Array
(
kDBList
::
FLT_TYPE_AND
));
if
(
$types
)
{
$types
=
explode
(
','
,
$types
);
foreach
(
$types
as
$type
)
{
$type
=
trim
(
$type
);
if
(
isset
(
$type_clauses
[
$type
])
)
{
if
(
$type_clauses
[
$type
][
'having_filter'
]
)
{
$includes_or_filter_h
->
addFilter
(
'filter_'
.
$type
,
$type_clauses
[
$type
][
'include'
]);
}
else
{
$includes_or_filter
->
addFilter
(
'filter_'
.
$type
,
$type_clauses
[
$type
][
'include'
]);
}
}
}
}
if
(
$except_types
)
{
$except_types
=
explode
(
','
,
$except_types
);
foreach
(
$except_types
as
$type
)
{
$type
=
trim
(
$type
);
if
(
isset
(
$type_clauses
[
$type
])
)
{
if
(
$type_clauses
[
$type
][
'having_filter'
]
)
{
$excepts_and_filter_h
->
addFilter
(
'filter_'
.
$type
,
$type_clauses
[
$type
][
'except'
]);
}
else
{
$excepts_and_filter
->
addFilter
(
'filter_'
.
$type
,
$type_clauses
[
$type
][
'except'
]);
}
}
}
}
/** @var kDBList $object */
$object
=
$event
->
getObject
();
$object
->
addFilter
(
'includes_filter'
,
$includes_or_filter
);
$object
->
addFilter
(
'excepts_filter'
,
$excepts_and_filter
);
$object
->
addFilter
(
'includes_filter_h'
,
$includes_or_filter_h
,
kDBList
::
HAVING_FILTER
);
$object
->
addFilter
(
'excepts_filter_h'
,
$excepts_and_filter_h
,
kDBList
::
HAVING_FILTER
);
}
/**
* Ensures empty search table
*
* @return void
*/
public
function
ensureEmptySearchTable
()
{
$search_table
=
$this
->
getSearchTable
();
$sql
=
'CREATE TABLE IF NOT EXISTS '
.
$search_table
.
' (
`Relevance` decimal(8,5) DEFAULT NULL,
`ItemId` int(11) NOT NULL DEFAULT 0,
`ResourceId` int(11) DEFAULT NULL,
`ItemType` int(1) NOT NULL DEFAULT 0,
`EdPick` tinyint(4) NOT NULL DEFAULT 0,
KEY `ResourceId` (`ResourceId`),
KEY `Relevance` (`Relevance`)
) ENGINE = MEMORY'
;
$this
->
Conn
->
Query
(
$sql
);
$sql
=
'TRUNCATE TABLE '
.
$search_table
;
$this
->
Conn
->
Query
(
$sql
);
}
/**
* Search table name
*
* @return string
*/
public
function
getSearchTable
()
{
try
{
$sid
=
$this
->
Application
->
GetSID
(
Session
::
PURPOSE_REFERENCE
);
}
catch
(
RuntimeException
$e
)
{
// 1. Put some real variable into session, or otherwise it won't even save to the database.
$this
->
Application
->
StoreVar
(
'search_made'
,
'yes'
);
// 2. Create session on they fly to store search results.
$this
->
Application
->
Session
->
SaveData
();
// 3. Get ID of the created session.
$sid
=
$this
->
Application
->
GetSID
(
Session
::
PURPOSE_REFERENCE
);
}
return
TABLE_PREFIX
.
'ses_'
.
$sid
.
'_'
.
TABLE_PREFIX
.
'Search'
;
}
}
Event Timeline
Log In to Comment