Adds more classes, and refactoring to the search feature. Adds test search to search page. #952

This commit is contained in:
Llewellyn van der Merwe 2022-09-16 23:41:41 +02:00
parent d757e14fac
commit c53ece2a2d
Signed by untrusted user: Llewellyn
GPG Key ID: A9201372263741E7
22 changed files with 845 additions and 91 deletions

View File

@ -140,14 +140,14 @@ TODO
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io) + *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder) + *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
+ *First Build*: 30th April, 2015 + *First Build*: 30th April, 2015
+ *Last Build*: 14th September, 2022 + *Last Build*: 16th September, 2022
+ *Version*: 3.1.5 + *Version*: 3.1.5
+ *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved.
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt + *License*: GNU General Public License version 2 or later; see LICENSE.txt
+ *Line count*: **330282** + *Line count*: **331035**
+ *Field count*: **2002** + *Field count*: **2002**
+ *File count*: **2161** + *File count*: **2166**
+ *Folder count*: **374** + *Folder count*: **375**
> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com). > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com).
> Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) > Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)

View File

@ -140,14 +140,14 @@ TODO
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io) + *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder) + *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
+ *First Build*: 30th April, 2015 + *First Build*: 30th April, 2015
+ *Last Build*: 14th September, 2022 + *Last Build*: 16th September, 2022
+ *Version*: 3.1.5 + *Version*: 3.1.5
+ *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved.
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt + *License*: GNU General Public License version 2 or later; see LICENSE.txt
+ *Line count*: **330282** + *Line count*: **331035**
+ *Field count*: **2002** + *Field count*: **2002**
+ *File count*: **2161** + *File count*: **2166**
+ *Folder count*: **374** + *Folder count*: **375**
> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com). > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com).
> Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) > Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)

View File

@ -7760,7 +7760,6 @@ COM_COMPONENTBUILDER_MODEL_AFTER_MODELLING="Model (after modelling)"
COM_COMPONENTBUILDER_MODEL_BEFORE_MODELLING="Model (before modelling)" COM_COMPONENTBUILDER_MODEL_BEFORE_MODELLING="Model (before modelling)"
COM_COMPONENTBUILDER_MODULE="Module" COM_COMPONENTBUILDER_MODULE="Module"
COM_COMPONENTBUILDER_MODULES="Modules" COM_COMPONENTBUILDER_MODULES="Modules"
COM_COMPONENTBUILDER_MORE_SOON="More soon"
COM_COMPONENTBUILDER_MOVE="Move" COM_COMPONENTBUILDER_MOVE="Move"
COM_COMPONENTBUILDER_NAME="Name" COM_COMPONENTBUILDER_NAME="Name"
COM_COMPONENTBUILDER_NAME_ASC="Name (Asc)" COM_COMPONENTBUILDER_NAME_ASC="Name (Asc)"

View File

@ -3622,17 +3622,17 @@ class ComponentbuilderModelAjax extends ListModel
int $matchCase, int $wholeWord, int $regexSearch, int $componentId): ?array int $matchCase, int $wholeWord, int $regexSearch, int $componentId): ?array
{ {
// check if this is a valid table // check if this is a valid table
if (SearchFactory('Table')->exist($tableName)) if (SearchFactory::_('Table')->exist($tableName))
{ {
// load the configurations // load the configurations
SearchFactory('Config')->table_name = $tableName; SearchFactory::_('Config')->table_name = $tableName;
SearchFactory('Config')->search_value = $searchValue; SearchFactory::_('Config')->search_value = $searchValue;
SearchFactory('Config')->match_case = $matchCase; SearchFactory::_('Config')->match_case = $matchCase;
SearchFactory('Config')->whole_word = $wholeWord; SearchFactory::_('Config')->whole_word = $wholeWord;
SearchFactory('Config')->regex_search = $regexSearch; SearchFactory::_('Config')->regex_search = $regexSearch;
SearchFactory('Config')->component_id = $componentId; SearchFactory::_('Config')->component_id = $componentId;
if (($items = SearchFactory('Agent')->find()) !== null) if (($items = SearchFactory::_('Agent')->find()) !== null)
{ {
return ['success' => JText::sprintf('COM_COMPONENTBUILDER_WE_FOUND_SOME_INSTANCES_IN_S', $tableName), 'items' => $items]; return ['success' => JText::sprintf('COM_COMPONENTBUILDER_WE_FOUND_SOME_INSTANCES_IN_S', $tableName), 'items' => $items];
} }

View File

@ -16,6 +16,7 @@ JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html');
JHtml::_('behavior.formvalidator'); JHtml::_('behavior.formvalidator');
JHtml::_('formbehavior.chosen', 'select'); JHtml::_('formbehavior.chosen', 'select');
JHtml::_('behavior.keepalive'); JHtml::_('behavior.keepalive');
use VDM\Joomla\Componentbuilder\Search\Factory as SearchFactory;
?> ?>
<?php if ($this->canDo->get('search.access')): ?> <?php if ($this->canDo->get('search.access')): ?>
<script type="text/javascript"> <script type="text/javascript">
@ -41,7 +42,29 @@ JHtml::_('behavior.keepalive');
<?php else : ?> <?php else : ?>
<div id="j-main-container"> <div id="j-main-container">
<?php endif; ?> <?php endif; ?>
<?php echo JText::_('COM_COMPONENTBUILDER_MORE_SOON'); ?> <?php
// lets do some tests with the API
$tableName = 'admin_view';
$searchValue = ' array(';
// set the search configurations
SearchFactory::_('Config')->table_name = $tableName;
SearchFactory::_('Config')->search_value = $searchValue;
SearchFactory::_('Config')->match_case = 0;
SearchFactory::_('Config')->whole_word = 0;
SearchFactory::_('Config')->regex_search = 0;
SearchFactory::_('Config')->component_id = 0;
if (($items = SearchFactory::_('Agent')->find()) !== null)
{
echo JText::sprintf('COM_COMPONENTBUILDER_WE_FOUND_SOME_INSTANCES_IN_S', $tableName) . '<br /><pre>';
var_dump($items);
echo '</pre>';
}
else
{
echo JText::sprintf('COM_COMPONENTBUILDER_NO_INSTANCES_WHERE_FOUND_S', $tableName);
}
?>
</div> </div>
<input type="hidden" name="task" value="" /> <input type="hidden" name="task" value="" />
<?php echo JHtml::_('form.token'); ?> <?php echo JHtml::_('form.token'); ?>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="4" method="upgrade"> <extension type="component" version="4" method="upgrade">
<name>COM_COMPONENTBUILDER</name> <name>COM_COMPONENTBUILDER</name>
<creationDate>14th September, 2022</creationDate> <creationDate>16th September, 2022</creationDate>
<author>Llewellyn van der Merwe</author> <author>Llewellyn van der Merwe</author>
<authorEmail>joomla@vdm.io</authorEmail> <authorEmail>joomla@vdm.io</authorEmail>
<authorUrl>https://dev.vdm.io</authorUrl> <authorUrl>https://dev.vdm.io</authorUrl>

View File

@ -125,7 +125,7 @@ class Agent
$set++; $set++;
} }
return $this->search->found($table); return $this->search->get($table);
} }
/** /**

View File

@ -117,7 +117,7 @@ class Replace implements ReplaceInterface
{ {
foreach ($item as $field => $value) foreach ($item as $field => $value)
{ {
if ($field !== 'id' && ($_value = $this->update->value($value, $id, $field, $table)) !== null) if ($field !== 'id' && ($_value = $this->update->value($value)) !== null)
{ {
if (empty($this->updated[$table][$id])) if (empty($this->updated[$table][$id]))
{ {

View File

@ -12,9 +12,11 @@
namespace VDM\Joomla\Componentbuilder\Search\Agent; namespace VDM\Joomla\Componentbuilder\Search\Agent;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Search\Factory; use VDM\Joomla\Componentbuilder\Search\Factory;
use VDM\Joomla\Componentbuilder\Search\Config; use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface as SearchEngine;
use VDM\Joomla\Componentbuilder\Search\Table; use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchInterface;
/** /**
@ -22,52 +24,265 @@ use VDM\Joomla\Componentbuilder\Search\Table;
* *
* @since 3.2.0 * @since 3.2.0
*/ */
class Search class Search implements SearchInterface
{ {
/** /**
* Search Config * Search results found
* *
* @var Config * @var array
* @since 3.2.0 * @since 3.2.0
*/ */
protected Config $config; protected array $found = [];
/** /**
* Table * Search Engine
* *
* @var Table * @var SearchEngine
* @since 3.2.0 * @since 3.2.0
*/ */
protected Table $table; protected SearchEngine $search;
/** /**
* Constructor * Constructor
* *
* @param Config|null $config The search config object. * @param SearchEngine|null $search The search engine object.
* @param Table|null $table The search table object.
* *
* @since 3.2.0 * @since 3.2.0
*/ */
public function __construct(?Config $config = null, ?Table $table = null) public function __construct(?SearchEngine $search = null)
{ {
$this->config = $config ?: Factory::_('Config'); $this->search = $search ?: Factory::_('Search');
$this->table = $table ?: Factory::_('Table'); }
/**
* 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 * Search inside a value
* *
* @param mixed $value The field value * @param mixed $value The field value
* @param int $id The item ID * @param int $id The item ID
* @param string $field The field key * @param string $field The field key
* @param string|null $table The table * @param string $table The table
* *
* @return bool * @return bool
* @since 3.2.0 * @since 3.2.0
*/ */
public function value($value, int $id, string $field, ?string $table = null): bool public function value($value, int $id, string $field, string $table): bool
{ {
return true; // 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))
{
if (($_found = $this->string($r)) !== null)
{
foreach ($_found as $_n => $_f)
{
$found[$keys . '.' . $key . '.' . $ke . '.' . $k . '.' . $_n] = $_f;
}
}
}
}
}
elseif (StringHelper::check($ro))
{
if (($_found = $this->string($ro)) !== null)
{
foreach ($_found as $_n => $_f)
{
$found[$keys. '.' . $key . '.' . $ke . '.' . $_n] = $_f;
}
}
}
}
}
elseif (StringHelper::check($row))
{
if (($_found = $this->string($row)) !== null)
{
foreach ($_found as $_n => $_f)
{
$found[$keys. '.' . $key . '.' . $_n] = $_f;
}
}
}
}
}
elseif (StringHelper::check($rows))
{
if (($_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;
// 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] = [];
}
} }
} }

View File

@ -12,9 +12,10 @@
namespace VDM\Joomla\Componentbuilder\Search\Agent; namespace VDM\Joomla\Componentbuilder\Search\Agent;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Search\Factory; use VDM\Joomla\Componentbuilder\Search\Factory;
use VDM\Joomla\Componentbuilder\Search\Config; use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface as SearchEngine;
use VDM\Joomla\Componentbuilder\Search\Table;
/** /**
@ -25,49 +26,113 @@ use VDM\Joomla\Componentbuilder\Search\Table;
class Update class Update
{ {
/** /**
* Search Config * Search Engine
* *
* @var Config * @var SearchEngine
* @since 3.2.0 * @since 3.2.0
*/ */
protected Config $config; protected SearchEngine $search;
/**
* Table
*
* @var Table
* @since 3.2.0
*/
protected Table $table;
/** /**
* Constructor * Constructor
* *
* @param Config|null $config The search config object. * @param SearchEngine|null $search The search engine object.
* @param Table|null $table The search table object.
* *
* @since 3.2.0 * @since 3.2.0
*/ */
public function __construct(?Config $config = null, ?Table $table = null) public function __construct(?SearchEngine $search = null)
{ {
$this->config = $config ?: Factory::_('Config'); $this->search = $search ?: Factory::_('Search');
$this->table = $table ?: Factory::_('Table');
} }
/** /**
* Update value * Update the value
* *
* @param mixed $value The field value * @param mixed $value The field value
* @param int $id The item ID * @param int $line The line to update (0 = all)
* @param string $field The field key
* @param string|null $table The table
* *
* @return mixed * @return mixed
* @since 3.2.0 * @since 3.2.0
*/ */
public function value($value, int $id, string $field, ?string $table = null) public function value($value, int $line = 0)
{ {
return $value; // update the value
$update = $this->updateValue($value, $line);
// was anything updated
if ($value === $update)
{
return null;
}
return $update;
}
/**
* Update all search-replace instances inside a value
*
* @param mixed $value The field value
* @param int $line The line to update (0 = all)
*
* @return mixed
* @since 3.2.0
*/
protected function updateValue($value, int $line = 0)
{
if (ArrayHelper::check($value))
{
echo '<pre>'; var_dump($value); exit;
}
elseif (StringHelper::check($value))
{
return $this->string($value, $line);
}
else
{
// this should not happen
echo '<pre>Error:<br />'; var_dump($value); exit;
}
}
/**
* Update all search-replace instances inside a string
*
* @param string $value The field value
* @param int $line The line to update (0 = all)
*
* @return string
* @since 3.2.0
*/
protected function string(string $value, int $line = 0): string
{
// check if string has a new line
if (\preg_match('/\R/', $value) && $line > 0)
{
// line counter
$line_number = 1;
$search_array = \preg_split('/\R/', $value);
// loop over the lines
foreach ($search_array as $nr => $line_value)
{
if ($line_number == $line)
{
$search_array[$nr] = $this->search->replace($line_value);
// since we are targeting on line (and possibly one number)
// this can only happen once, and so we return at this point
return implode(PHP_EOL, $search_array);
}
// next line
$line_number++;
}
// no update took place so we just return the original value
return $value;
}
return $this->search->replace($value);
} }
} }

View File

@ -25,10 +25,10 @@ class Config extends BaseConfig
/** /**
* get posted search value * get posted search value
* *
* @return string Raw search value * @return string|null Raw search value
* @since 3.2.0 * @since 3.2.0
*/ */
protected function getSearchvalue(): string protected function getSearchvalue(): ?string
{ {
return $this->input->post->get('search_value', null, 'RAW'); return $this->input->post->get('search_value', null, 'RAW');
} }
@ -36,10 +36,10 @@ class Config extends BaseConfig
/** /**
* get posted replace value * get posted replace value
* *
* @return string Raw replace value * @return string|null Raw replace value
* @since 3.2.0 * @since 3.2.0
*/ */
protected function getReplacevalue(): string protected function getReplacevalue(): ?string
{ {
return $this->input->post->get('replace_value', null, 'RAW'); return $this->input->post->get('replace_value', null, 'RAW');
} }

View File

@ -60,6 +60,7 @@ interface FindInterface
* @return void * @return void
* @since 3.2.0 * @since 3.2.0
*/ */
public function reset(?string $table = null); public function reset(?string $table = null);
} }

View File

@ -34,15 +34,15 @@ interface ModelInterface
/** /**
* Model the values of an item * Model the values of an item
* Example: $this->item('table_name', Object); * Example: $this->item(Object, 'table_name');
* *
* @param string $table The table * @param object $item The item object
* @param object $item The item object * @param string|null $table The table
* *
* @return object * @return object|null
* @since 3.2.0 * @since 3.2.0
*/ */
public function item(object $item, ?string $table = null): object; public function item(object $item, ?string $table = null): ?object;
/** /**
* Model the values of multiple items * Model the values of multiple items

View File

@ -0,0 +1,56 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 30th April, 2015
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Search\Interfaces;
/**
* Search Interface
*
* @since 3.2.0
*/
interface SearchInterface
{
/**
* Get found values
*
* @param string $table The table being searched
*
* @return array|null
* @since 3.2.0
*/
public function get(string $table): ?array;
/**
* 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;
/**
* Empty the found values
*
* @param string $table The table being searched
*
* @return void
* @since 3.2.0
*/
public function reset(string $table);
}

View File

@ -0,0 +1,43 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 30th April, 2015
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Search\Interfaces;
/**
* Search Type Interface
*
* @since 3.2.0
*/
interface SearchTypeInterface
{
/**
* Search inside a string
*
* @param string $value The string value
*
* @return string|null The marked string if found, else null
* @since 3.2.0
*/
public function string(string $value): ?string;
/**
* Replace found instances inside string value
*
* @param string $value The string value to update
*
* @return string The updated string
* @since 3.2.0
*/
public function replace(string $value): string;
}

View File

@ -12,10 +12,11 @@
namespace VDM\Joomla\Componentbuilder\Search; namespace VDM\Joomla\Componentbuilder\Search;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Componentbuilder\Search\Factory; use VDM\Joomla\Componentbuilder\Search\Factory;
use VDM\Joomla\Componentbuilder\Search\Config; use VDM\Joomla\Componentbuilder\Search\Config;
use VDM\Joomla\Componentbuilder\Search\Table; use VDM\Joomla\Componentbuilder\Search\Table;
use VDM\Joomla\Utilities\ArrayHelper;
/** /**
@ -65,15 +66,15 @@ abstract class Model
/** /**
* Model the values of an item * Model the values of an item
* Example: $this->item(Object, 'table_name'); * Example: $this->item('table_name', Object);
* *
* @param object $item The item object * @param object $item The item object
* @param string|null $table The table * @param string|null $table The table
* *
* @return object * @return object|null
* @since 3.2.0 * @since 3.2.0
*/ */
public function item(object $item, ?string $table = null): object public function item(object $item, ?string $table = null): ?object
{ {
// set the table name // set the table name
if (empty($table)) if (empty($table))
@ -81,19 +82,39 @@ abstract class Model
$table = $this->config->table_name; $table = $this->config->table_name;
} }
// field counter
$field_number = 0;
// check if this is a valid table // check if this is a valid table
if (($fields = $this->table->fields($table)) !== null) if (($fields = $this->table->fields($table)) !== null)
{ {
foreach ($fields as $field) foreach ($fields as $field)
{ {
// model a value if it exists
if(isset($item->{$field})) if(isset($item->{$field}))
{ {
$item->{$field} = $this->value($item->{$field}, $field, $table); $item->{$field} = $this->value($item->{$field}, $field, $table);
// remove empty values
if (!StringHelper::check($item->{$field}) && !ArrayHelper::check($item->{$field}, true))
{
unset($item->{$field});
}
else
{
$field_number++;
}
} }
} }
} }
return $item; // all items must have more than one field or its empty (1 = id)
if ($field_number > 1)
{
return $item;
}
return null;
} }
/** /**
@ -120,14 +141,24 @@ abstract class Model
foreach ($items as $id => &$item) foreach ($items as $id => &$item)
{ {
// model the item // model the item
$item = $this->item($item, $table); if (($item = $this->item($item, $table)) !== null)
{
// add the last ID
$this->last[$table] = $item->id;
}
else
{
unset($items[$id]);
}
}
// add the last ID if (ArrayHelper::check($items))
$this->last[$table] = $item->id; {
return $items;
} }
} }
return $items; return null;
} }
/** /**

View File

@ -12,6 +12,8 @@
namespace VDM\Joomla\Componentbuilder\Search\Model; namespace VDM\Joomla\Componentbuilder\Search\Model;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Search\Interfaces\ModelInterface; use VDM\Joomla\Componentbuilder\Search\Interfaces\ModelInterface;
use VDM\Joomla\Componentbuilder\Search\Model; use VDM\Joomla\Componentbuilder\Search\Model;
@ -43,7 +45,7 @@ class Get extends Model implements ModelInterface
} }
// check if this is a valid table // check if this is a valid table
if (($store = $this->table->get($table, $field, 'store')) !== null) if (StringHelper::check($value) && ($store = $this->table->get($table, $field, 'store')) !== null)
{ {
// open the value based on the store method // open the value based on the store method
switch($store) switch($store)
@ -52,7 +54,11 @@ class Get extends Model implements ModelInterface
$value = \base64_decode($value); $value = \base64_decode($value);
break; break;
case 'json': case 'json':
$value = \json_decode($value, true); // check if there is a json string
if (JsonHelper::check($value))
{
$value = \json_decode($value, true);
}
break; break;
} }
} }

View File

@ -117,8 +117,7 @@ class Agent implements ServiceProviderInterface
public function getSearch(Container $container): Search public function getSearch(Container $container): Search
{ {
return new Search( return new Search(
$container->get('Config'), $container->get('Search')
$container->get('Table')
); );
} }
@ -133,8 +132,7 @@ class Agent implements ServiceProviderInterface
public function getUpdate(Container $container): Update public function getUpdate(Container $container): Update
{ {
return new Update( return new Update(
$container->get('Config'), $container->get('Search')
$container->get('Table')
); );
} }

View File

@ -16,6 +16,9 @@ use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface; use Joomla\DI\ServiceProviderInterface;
use VDM\Joomla\Componentbuilder\Search\Config; use VDM\Joomla\Componentbuilder\Search\Config;
use VDM\Joomla\Componentbuilder\Search\Table; use VDM\Joomla\Componentbuilder\Search\Table;
use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface as SearchEngine;
use VDM\Joomla\Componentbuilder\Search\Type\Regex;
use VDM\Joomla\Componentbuilder\Search\Type\Basic;
/** /**
@ -25,6 +28,14 @@ use VDM\Joomla\Componentbuilder\Search\Table;
*/ */
class Search implements ServiceProviderInterface class Search implements ServiceProviderInterface
{ {
/**
* Selected search engine
*
* @var int
* @since 3.2.0
**/
protected $searchEngine = 101;
/** /**
* Registers the service provider with a DI container. * Registers the service provider with a DI container.
* *
@ -40,6 +51,15 @@ class Search implements ServiceProviderInterface
$container->alias(Table::class, 'Table') $container->alias(Table::class, 'Table')
->share('Table', [$this, 'getTable'], true); ->share('Table', [$this, 'getTable'], true);
$container->alias(Regex::class, 'Search.Regex')
->share('Search.Regex', [$this, 'getRegex'], true);
$container->alias(Basic::class, 'Search.Basic')
->share('Search.Basic', [$this, 'getBasic'], true);
$container->alias(SearchEngine::class, 'Search')
->share('Search', [$this, 'getSearch'], true);
} }
/** /**
@ -69,6 +89,63 @@ class Search implements ServiceProviderInterface
$container->get('Config') $container->get('Config')
); );
} }
/**
* Get the Regex Type Search Engine
*
* @param Container $container The DI container.
*
* @return Regex
* @since 3.2.0
*/
public function getRegex(Container $container): Regex
{
return new Regex(
$container->get('Config')
);
}
/**
* Get the Basic Type Search Engine
*
* @param Container $container The DI container.
*
* @return Basic
* @since 3.2.0
*/
public function getBasic(Container $container): Basic
{
return new Basic(
$container->get('Config')
);
}
/**
* Get the Search Engine
*
* @param Container $container The DI container.
*
* @return SearchEngine
* @since 3.2.0
*/
public function getSearch(Container $container): SearchEngine
{
// set the search engine to use for this container
if ($this->searchEngine == 101)
{
$this->searchEngine = (int) $container->get('Config')->regex_search;
}
// get the correct type of search engine
if ($this->searchEngine == 1)
{
return $container->get('Search.Regex');
}
// the default is the basic
return $container->get('Search.Basic');
}
} }

View File

@ -0,0 +1,127 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 30th April, 2015
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Search\Type;
use VDM\Joomla\Componentbuilder\Search\Factory;
use VDM\Joomla\Componentbuilder\Search\Config;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface;
/**
* Search Type String
*
* @since 3.2.0
*/
class Basic implements SearchTypeInterface
{
/**
* Search Config
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* Search Value
*
* @var string|null
* @since 3.2.0
*/
protected ?string $searchValue;
/**
* Replace Value
*
* @var string|null
* @since 3.2.0
*/
protected ?string $replaceValue;
/**
* Search Should Match Case
*
* @var int
* @since 3.2.0
*/
protected int $matchCase = 0;
/**
* Search Should Match Whole Word
*
* @var int
* @since 3.2.0
*/
protected int $wholeWord = 0;
/**
* Constructor
*
* @param Config|null $config The search config object.
*
* @since 3.2.0
*/
public function __construct(?Config $config = null)
{
$this->config = $config ?: Factory::_('Config');
// set some class values
$this->searchValue = $this->config->search_value;
$this->replaceValue = $this->config->replace_value; // TODO
$this->matchCase = $this->config->match_case;
$this->wholeWord = $this->config->whole_word; // TODO
}
/**
* Search inside a string
*
* @param string $value The string value
*
* @return string|null The marked string if found, else null
* @since 3.2.0
*/
public function string(string $value): ?string
{
if (StringHelper::check($this->searchValue))
{
if ($this->matchCase == 1)
{
if (strpos($value, $this->searchValue) !== false)
{
return trim(str_replace($this->searchValue, '{+' . '|' . '=[' . $this->searchValue . ']=' . '|' . '+}', $value));
}
}
elseif (stripos($value, $this->searchValue) !== false)
{
return trim(str_ireplace($this->searchValue, '{+' . '|' . '=[' . $this->searchValue . ']=' . '|' . '+}', $value));
}
}
return null;
}
/**
* Replace found instances inside string value
*
* @param string $value The string value to update
*
* @return string The updated string
* @since 3.2.0
*/
public function replace(string $value): string
{
return $value;
}
}

View File

@ -0,0 +1,112 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 30th April, 2015
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Search\Type;
use VDM\Joomla\Componentbuilder\Search\Factory;
use VDM\Joomla\Componentbuilder\Search\Config;
use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface;
/**
* Search Type Regex
*
* @since 3.2.0
*/
class Regex implements SearchTypeInterface
{
/**
* Search Config
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* Search Value
*
* @var string
* @since 3.2.0
*/
protected string $searchValue;
/**
* Replace Value
*
* @var string
* @since 3.2.0
*/
protected string $replaceValue;
/**
* Search Should Match Case
*
* @var int
* @since 3.2.0
*/
protected int $matchCase = 0;
/**
* Search Should Match Whole Word
*
* @var int
* @since 3.2.0
*/
protected int $wholeWord = 0;
/**
* Constructor
*
* @param Config|null $config The search config object.
*
* @since 3.2.0
*/
public function __construct(?Config $config = null)
{
$this->config = $config ?: Factory::_('Config');
// set some class values
$this->searchValue = $this->config->search_value;
$this->replaceValue = $this->config->replace_value; // TODO
$this->matchCase = $this->config->match_case;
$this->wholeWord = $this->config->whole_word; // TODO
}
/**
* Search inside a string
*
* @param string $value The string value
*
* @return string|null The marked string if found, else null
* @since 3.2.0
*/
public function string(string $value): ?string
{
return null;
}
/**
* Replace found instances inside string value
*
* @param string $value The string value to update
*
* @return string The updated string
* @since 3.2.0
*/
public function replace(string $value): string
{
return $value;
}
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>