271 lines
5.8 KiB
Plaintext
271 lines
5.8 KiB
Plaintext
|
/**
|
||
|
* Search results found
|
||
|
*
|
||
|
* @var array
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected array $found = [];
|
||
|
|
||
|
/**
|
||
|
* Search Config
|
||
|
*
|
||
|
* @var Config
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected Config $config;
|
||
|
|
||
|
/**
|
||
|
* Search Engine
|
||
|
*
|
||
|
* @var SearchEngine
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected SearchEngine $search;
|
||
|
|
||
|
/**
|
||
|
* Constructor
|
||
|
*
|
||
|
* @param Config|null $config The search config object.
|
||
|
* @param SearchEngine|null $search The search engine object.
|
||
|
*
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
public function __construct(?Config $config = null, ?SearchEngine $search = null)
|
||
|
{
|
||
|
$this->config = $config ?: Factory::_('Config');
|
||
|
$this->search = $search ?: Factory::_('Search');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get found values
|
||
|
*
|
||
|
* @param string $table The table being searched
|
||
|
*
|
||
|
* @return array|null
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
public function get(string $table): ?array
|
||
|
{
|
||
|
if (isset($this->found[$table]))
|
||
|
{
|
||
|
return $this->found[$table];
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Search inside a value
|
||
|
*
|
||
|
* @param mixed $value The field value
|
||
|
* @param int $id The item ID
|
||
|
* @param string $field The field key
|
||
|
* @param string $table The table
|
||
|
*
|
||
|
* @return bool
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
public function value($value, int $id, string $field, string $table): bool
|
||
|
{
|
||
|
// search the mixed value
|
||
|
$found = $this->searchValue($value);
|
||
|
|
||
|
// check if we found any match
|
||
|
if (ArrayHelper::check($found))
|
||
|
{
|
||
|
foreach ($found as $line => $line_value)
|
||
|
{
|
||
|
// may not be needed... but being old school
|
||
|
$this->prep($id, $field, $table);
|
||
|
|
||
|
// load the detail into our multidimensional array... lol
|
||
|
// Table->Item_id->Field_name->Line_number = marked_full_line
|
||
|
// Search Example: soon...
|
||
|
// Marked Line Example: Soon....
|
||
|
$this->found[$table][$id][$field][$line] = $line_value;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Empty the found values
|
||
|
*
|
||
|
* @param string $table The table being searched
|
||
|
*
|
||
|
* @return void
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
public function reset(string $table)
|
||
|
{
|
||
|
unset($this->found[$table]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Search inside a string
|
||
|
*
|
||
|
* @param mixed $value The field value
|
||
|
*
|
||
|
* @return array|null
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected function searchValue($value): ?array
|
||
|
{
|
||
|
// check if this is an array
|
||
|
$found = null;
|
||
|
|
||
|
// I know this is a little crazy... TODO refactor into recursion functions
|
||
|
// the possibility of searching sub-forms in sub-forms
|
||
|
if (ArrayHelper::check($value))
|
||
|
{
|
||
|
// first layer
|
||
|
foreach ($value as $keys => $rows)
|
||
|
{
|
||
|
if (ArrayHelper::check($rows))
|
||
|
{
|
||
|
// second layer
|
||
|
foreach ($rows as $key => $row)
|
||
|
{
|
||
|
if (ArrayHelper::check($row))
|
||
|
{
|
||
|
// third layer
|
||
|
foreach ($row as $ke => $ro)
|
||
|
{
|
||
|
if (ArrayHelper::check($ro))
|
||
|
{
|
||
|
// forth layer
|
||
|
foreach ($ro as $k => $r)
|
||
|
{
|
||
|
if (StringHelper::check($r) && ($_found = $this->string($r)) !== null)
|
||
|
{
|
||
|
foreach ($_found as $_n => $_f)
|
||
|
{
|
||
|
$found[$keys . '.' . $key . '.' . $ke . '.' . $k . '.' . $_n] = $_f;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
elseif (StringHelper::check($ro) && ($_found = $this->string($ro)) !== null)
|
||
|
{
|
||
|
foreach ($_found as $_n => $_f)
|
||
|
{
|
||
|
$found[$keys. '.' . $key . '.' . $ke . '.' . $_n] = $_f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
elseif (StringHelper::check($row) && ($_found = $this->string($row)) !== null)
|
||
|
{
|
||
|
foreach ($_found as $_n => $_f)
|
||
|
{
|
||
|
$found[$keys. '.' . $key . '.' . $_n] = $_f;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
elseif (StringHelper::check($rows) && ($_found = $this->string($rows)) !== null)
|
||
|
{
|
||
|
foreach ($_found as $_n => $_f)
|
||
|
{
|
||
|
$found[$keys. '.' . $_n] = $_f;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
elseif (StringHelper::check($value))
|
||
|
{
|
||
|
$found = $this->string($value);
|
||
|
}
|
||
|
|
||
|
return $found;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Search inside a string
|
||
|
*
|
||
|
* @param string $value The field value
|
||
|
*
|
||
|
* @return array|null
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected function string(string $value): ?array
|
||
|
{
|
||
|
// line counter
|
||
|
$line = 1;
|
||
|
|
||
|
// we count every field we search
|
||
|
$this->fieldCounter();
|
||
|
|
||
|
// check if string has a new line
|
||
|
if (\preg_match('/\R/', $value))
|
||
|
{
|
||
|
$search_array = \preg_split('/\R/', $value);
|
||
|
|
||
|
// start search bucket
|
||
|
$found = [];
|
||
|
|
||
|
// loop over the lines
|
||
|
foreach ($search_array as $line_value)
|
||
|
{
|
||
|
if (($_found = $this->search->string($line_value)) !== null)
|
||
|
{
|
||
|
$found[$line] = $_found;
|
||
|
}
|
||
|
|
||
|
// next line
|
||
|
$line++;
|
||
|
}
|
||
|
|
||
|
if (ArrayHelper::check($found))
|
||
|
{
|
||
|
return $found;
|
||
|
}
|
||
|
}
|
||
|
elseif (($found = $this->search->string($value)) !== null)
|
||
|
{
|
||
|
return [$line => $found];
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Prep the bucket
|
||
|
*
|
||
|
* @param int $id The item ID
|
||
|
* @param string $field The field key
|
||
|
* @param string $table The table
|
||
|
*
|
||
|
* @return void
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected function prep(int $id, string $field, string $table)
|
||
|
{
|
||
|
if (empty($this->found[$table]))
|
||
|
{
|
||
|
$this->found[$table] = [];
|
||
|
}
|
||
|
if (empty($this->found[$table][$id]))
|
||
|
{
|
||
|
$this->found[$table][$id] = [];
|
||
|
}
|
||
|
if (empty($this->found[$table][$id][$field]))
|
||
|
{
|
||
|
$this->found[$table][$id][$field] = [];
|
||
|
}
|
||
|
// we should add a call to get the item name if the table has a name field TODO
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* we count every field being searched
|
||
|
*
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected function fieldCounter()
|
||
|
{
|
||
|
// we count every field we search
|
||
|
$this->config->field_counter += 1;
|
||
|
}
|