First release
This commit is contained in:
commit
3ab7279214
77
README.md
Normal file
77
README.md
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# Vdm Data (1.0.0)
|
||||||
|
|
||||||
|
VDM Data Library
|
||||||
|
|
||||||
|
## Details
|
||||||
|
|
||||||
|
- Packager: [OctoPower v2.0](https://git.vdm.dev/octoleo/octopower)
|
||||||
|
- Author: [Llewellyn van der Merwe](https://io.vdm.dev)
|
||||||
|
- Creation Date: June 2024
|
||||||
|
|
||||||
|
### Installation via Composer
|
||||||
|
|
||||||
|
Setup this registry in your `~/.composer/config.json` file:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"repositories": [{
|
||||||
|
"type": "composer",
|
||||||
|
"url": "https://git.vdm.dev/api/packages/joomla/composer"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To install the package using Composer, run the following command:
|
||||||
|
```
|
||||||
|
composer require vdm/data:1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Joomla Framework Dependencies
|
||||||
|
|
||||||
|
>We have added the following framework classes to the required list of this Composer package.
|
||||||
|
|
||||||
|
- Joomla/DI "^3.0"
|
||||||
|
- [VastDevelopmentMethod\Joomla\Data\Factory](src/VastDevelopmentMethod/Joomla/Data/Factory.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Abstraction\Factory](src/VastDevelopmentMethod/Joomla/Abstraction/Factory.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Interfaces\FactoryInterface](src/VastDevelopmentMethod/Joomla/Interfaces/FactoryInterface.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Service\Table](src/VastDevelopmentMethod/Joomla/Service/Table.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Componentbuilder\Table\Schema](src/VastDevelopmentMethod/Joomla/Componentbuilder/Table/Schema.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Service\Database](src/VastDevelopmentMethod/Joomla/Service/Database.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Database\Load](src/VastDevelopmentMethod/Joomla/Database/Load.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Service\Model](src/VastDevelopmentMethod/Joomla/Service/Model.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Model\Load](src/VastDevelopmentMethod/Joomla/Model/Load.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Abstraction\Model](src/VastDevelopmentMethod/Joomla/Abstraction/Model.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Service\Data](src/VastDevelopmentMethod/Joomla/Service/Data.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Data\Action\Load](src/VastDevelopmentMethod/Joomla/Data/Action/Load.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Interfaces\Data\LoadInterface](src/VastDevelopmentMethod/Joomla/Interfaces/Data/LoadInterface.php)
|
||||||
|
- Joomla/Filter "^3.0"
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\StringHelper](src/VastDevelopmentMethod/Joomla/Utilities/StringHelper.php)
|
||||||
|
- Joomla/Input "^3.0"
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\Component\Helper](src/VastDevelopmentMethod/Joomla/Utilities/Component/Helper.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\String\NamespaceHelper](src/VastDevelopmentMethod/Joomla/Utilities/String/NamespaceHelper.php)
|
||||||
|
- Joomla/Registry "^3.0"
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\Component\Helper](src/VastDevelopmentMethod/Joomla/Utilities/Component/Helper.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\String\NamespaceHelper](src/VastDevelopmentMethod/Joomla/Utilities/String/NamespaceHelper.php)
|
||||||
|
|
||||||
|
|
||||||
|
## Joomla CMS Dependencies
|
||||||
|
|
||||||
|
- Joomla\CMS\Component\ComponentHelper
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\Component\Helper](src/VastDevelopmentMethod/Joomla/Utilities/Component/Helper.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\String\NamespaceHelper](src/VastDevelopmentMethod/Joomla/Utilities/String/NamespaceHelper.php)
|
||||||
|
- Joomla\CMS\Date\Date
|
||||||
|
- [VastDevelopmentMethod\Joomla\Database\Insert](src/VastDevelopmentMethod/Joomla/Database/Insert.php)
|
||||||
|
- Joomla\CMS\Factory
|
||||||
|
- [VastDevelopmentMethod\Joomla\Abstraction\Schema](src/VastDevelopmentMethod/Joomla/Abstraction/Schema.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Abstraction\Database](src/VastDevelopmentMethod/Joomla/Abstraction/Database.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\Component\Helper](src/VastDevelopmentMethod/Joomla/Utilities/Component/Helper.php)
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\String\NamespaceHelper](src/VastDevelopmentMethod/Joomla/Utilities/String/NamespaceHelper.php)
|
||||||
|
- Joomla\CMS\Language\Language
|
||||||
|
- [VastDevelopmentMethod\Joomla\Utilities\StringHelper](src/VastDevelopmentMethod/Joomla/Utilities/StringHelper.php)
|
||||||
|
- Joomla\CMS\Version
|
||||||
|
- [VastDevelopmentMethod\Joomla\Abstraction\Schema](src/VastDevelopmentMethod/Joomla/Abstraction/Schema.php)
|
||||||
|
|
||||||
|
|
||||||
|
### License
|
||||||
|
> GNU General Public License version 2 or later
|
||||||
|
|
31
composer.json
Normal file
31
composer.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "vdm/data",
|
||||||
|
"type": "library",
|
||||||
|
"description": "VDM Data Library",
|
||||||
|
"homepage": "https://git.vdm.dev/joomla/vdm-data",
|
||||||
|
"license": "GNU General Public License version 2 or later",
|
||||||
|
"require": {
|
||||||
|
"php": "^8.1.0",
|
||||||
|
"Joomla/DI": "^3.0",
|
||||||
|
"Joomla/Filter": "^3.0",
|
||||||
|
"Joomla/Input": "^3.0",
|
||||||
|
"Joomla/Registry": "^3.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"VastDevelopmentMethod\\Joomla\\": "src/VastDevelopmentMethod/Joomla"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"VDM",
|
||||||
|
"Data",
|
||||||
|
"SuperPower"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Llewellyn van der Merwe",
|
||||||
|
"email": "joomla@vdm.io",
|
||||||
|
"homepage": "https://io.vdm.dev"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
115
src/VastDevelopmentMethod/Joomla/Abstraction/Database.php
Normal file
115
src/VastDevelopmentMethod/Joomla/Abstraction/Database.php
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Abstraction;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\CMS\Factory as JoomlaFactory;
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\Component\Helper;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
abstract class Database
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Database object to query local DB
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected $db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core Component Table Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected string $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->db = JoomlaFactory::getDbo();
|
||||||
|
|
||||||
|
// set the component table
|
||||||
|
$this->table = '#__' . Helper::getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a value based on data type
|
||||||
|
*
|
||||||
|
* @param mixed $value The value to set
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
protected function quote($value)
|
||||||
|
{
|
||||||
|
if ($value === null) // hmm the null does pose an issue (will keep an eye on this)
|
||||||
|
{
|
||||||
|
return 'NULL';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_numeric($value))
|
||||||
|
{
|
||||||
|
if (filter_var($value, FILTER_VALIDATE_INT))
|
||||||
|
{
|
||||||
|
return (int) $value;
|
||||||
|
}
|
||||||
|
elseif (filter_var($value, FILTER_VALIDATE_FLOAT))
|
||||||
|
{
|
||||||
|
return (float) $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (is_bool($value)) // not sure if this will work well (but its correct)
|
||||||
|
{
|
||||||
|
return $value ? 'TRUE' : 'FALSE';
|
||||||
|
}
|
||||||
|
|
||||||
|
// For date and datetime values
|
||||||
|
if ($value instanceof \DateTime)
|
||||||
|
{
|
||||||
|
return $this->db->quote($value->format('Y-m-d H:i:s'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// For other data types, just escape it
|
||||||
|
return $this->db->quote($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a table name, adding the
|
||||||
|
* core component as needed
|
||||||
|
*
|
||||||
|
* @param string $table The table string
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
protected function getTable(string $table): string
|
||||||
|
{
|
||||||
|
if (strpos($table, '#__') === false)
|
||||||
|
{
|
||||||
|
return $this->table . '_' . $table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
83
src/VastDevelopmentMethod/Joomla/Abstraction/Factory.php
Normal file
83
src/VastDevelopmentMethod/Joomla/Abstraction/Factory.php
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Abstraction;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\DI\Container;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\FactoryInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
|
||||||
|
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
|
||||||
|
**
|
||||||
|
** In realms of code where purists frown, the anti-pattern wears a crown,
|
||||||
|
** A paradox of chaos bright, where complex paths lose all its slight.
|
||||||
|
** For in its tangled, wild embrace, lies raw creativity's face,
|
||||||
|
** No rigid forms, no strict decree, just boundless, daring artistry.
|
||||||
|
** In flaws, we find the freedom's key, where messy code and brilliance spree,
|
||||||
|
** A dance of thought, unchained, unbound, in anti-pattern, beauty's found.
|
||||||
|
**
|
||||||
|
** Perfect Paradox and True Nature of the Anti-Pattern by ChatGPT
|
||||||
|
**
|
||||||
|
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
|
||||||
|
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
|
||||||
|
**
|
||||||
|
** @since 0.0.0
|
||||||
|
**/
|
||||||
|
abstract class Factory implements FactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Global Package Container
|
||||||
|
*
|
||||||
|
* @var Container|null
|
||||||
|
* @since 0.0.0
|
||||||
|
**/
|
||||||
|
protected static ?Container $container = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get any class from the package container
|
||||||
|
*
|
||||||
|
* @param string $key The container class key
|
||||||
|
*
|
||||||
|
* @return Mixed
|
||||||
|
* @since 0.0.0
|
||||||
|
*/
|
||||||
|
public static function _($key)
|
||||||
|
{
|
||||||
|
return static::getContainer()->get($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the global package container
|
||||||
|
*
|
||||||
|
* @return Container
|
||||||
|
* @since 0.0.0
|
||||||
|
*/
|
||||||
|
public static function getContainer(): Container
|
||||||
|
{
|
||||||
|
if (!static::$container)
|
||||||
|
{
|
||||||
|
static::$container = static::createContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a container object
|
||||||
|
*
|
||||||
|
* @return Container
|
||||||
|
* @since 0.0.0
|
||||||
|
*/
|
||||||
|
abstract protected static function createContainer(): Container;
|
||||||
|
}
|
||||||
|
|
503
src/VastDevelopmentMethod/Joomla/Abstraction/Model.php
Normal file
503
src/VastDevelopmentMethod/Joomla/Abstraction/Model.php
Normal file
@ -0,0 +1,503 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Abstraction;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\StringHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\ArrayHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Tableinterface as Table;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\ModelInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Model
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
abstract class Model implements ModelInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Last ID
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected array $last;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search Table
|
||||||
|
*
|
||||||
|
* @var Table
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected Table $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected string $tableName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The switch to control the behaviour of empty values
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected bool $allowEmpty = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param Table $table The search table object.
|
||||||
|
* @param string|null $tableName The table
|
||||||
|
* @param bool|null $allowEmpty The switch to control the behaviour of empty values (default true)
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function __construct(Table $table, ?string $tableName = null, bool $allowEmpty = null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
if ($tableName !== null)
|
||||||
|
{
|
||||||
|
$this->setTable($tableName);
|
||||||
|
}
|
||||||
|
if ($allowEmpty !== null)
|
||||||
|
{
|
||||||
|
$this->setAllowEmpty($allowEmpty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(string $table): self
|
||||||
|
{
|
||||||
|
$this->setTable($table);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the value
|
||||||
|
* Example: $this->value(value, 'value_key', 'table_name');
|
||||||
|
*
|
||||||
|
* @param mixed $value The value to model
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
abstract public function value($value, string $field, ?string $table = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model a value of multiple items
|
||||||
|
* Example: $this->items(Array, 'value_key', 'table_name');
|
||||||
|
*
|
||||||
|
* @param array|null $items The array of values
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function values(?array $items = null, string $field, ?string $table = null): ?array
|
||||||
|
{
|
||||||
|
// check if this is a valid table
|
||||||
|
if (ArrayHelper::check($items))
|
||||||
|
{
|
||||||
|
// set the table name
|
||||||
|
if (empty($table))
|
||||||
|
{
|
||||||
|
$table = $this->getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate if field exist in table
|
||||||
|
if (!$this->table->exist($table, $field))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// value counter
|
||||||
|
$value_number = 0;
|
||||||
|
|
||||||
|
// check if this is a valid table
|
||||||
|
$item_bucket = [];
|
||||||
|
|
||||||
|
foreach ($items as $value)
|
||||||
|
{
|
||||||
|
if (!$this->validateBefore($value, $field, $table))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $this->value($value, $field, $table);
|
||||||
|
|
||||||
|
if (!$this->validateAfter($value, $field, $table))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$item_bucket[] = $value;
|
||||||
|
|
||||||
|
$value_number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have any values left
|
||||||
|
if ($value_number > 0)
|
||||||
|
{
|
||||||
|
return $item_bucket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the values of an item
|
||||||
|
* Example: $this->item(Object, 'table_name');
|
||||||
|
*
|
||||||
|
* @param object|null $item The item object
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return object|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function item(?object $item, ?string $table = null): ?object
|
||||||
|
{
|
||||||
|
// we must have an object
|
||||||
|
if (empty($item))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the table name
|
||||||
|
if (empty($table))
|
||||||
|
{
|
||||||
|
$table = $this->getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($fields = $this->getTableFields($table, true)) !== null)
|
||||||
|
{
|
||||||
|
// field counter
|
||||||
|
$field_number = 0;
|
||||||
|
|
||||||
|
// check if this is a valid table
|
||||||
|
$item_bucket = new \stdClass();
|
||||||
|
|
||||||
|
foreach ($fields as $field)
|
||||||
|
{
|
||||||
|
// model a value if it exists
|
||||||
|
if(isset($item->{$field}))
|
||||||
|
{
|
||||||
|
if (!$this->validateBefore($item->{$field}, $field, $table))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$item->{$field} = $this->value($item->{$field}, $field, $table);
|
||||||
|
|
||||||
|
if (!$this->validateAfter($item->{$field}, $field, $table))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$item_bucket->{$field} = $item->{$field};
|
||||||
|
|
||||||
|
$field_number++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// all items must have more than one field or its empty (1 = key)
|
||||||
|
if ($field_number > 1)
|
||||||
|
{
|
||||||
|
return $item_bucket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the values of multiple items
|
||||||
|
* Example: $this->items(Array, 'table_name');
|
||||||
|
*
|
||||||
|
* @param array|null $items The array of item objects
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function items(?array $items = null, ?string $table = null): ?array
|
||||||
|
{
|
||||||
|
// check if this is a valid table
|
||||||
|
if (ArrayHelper::check($items))
|
||||||
|
{
|
||||||
|
// set the table name
|
||||||
|
if (empty($table))
|
||||||
|
{
|
||||||
|
$table = $this->getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($items as $id => &$item)
|
||||||
|
{
|
||||||
|
// model the item
|
||||||
|
if (($item = $this->item($item, $table)) !== null)
|
||||||
|
{
|
||||||
|
// add the last ID
|
||||||
|
$this->last[$table] = $item->id ?? $this->last[$table] ?? null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($items[$id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ArrayHelper::check($items))
|
||||||
|
{
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the values of an row
|
||||||
|
* Example: $this->item(Array, 'table_name');
|
||||||
|
*
|
||||||
|
* @param array|null $item The item array
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function row(?array $item, ?string $table = null): ?array
|
||||||
|
{
|
||||||
|
// we must have an array
|
||||||
|
if (empty($item))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the table name
|
||||||
|
if (empty($table))
|
||||||
|
{
|
||||||
|
$table = $this->getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($fields = $this->getTableFields($table, true)) !== null)
|
||||||
|
{
|
||||||
|
// field counter
|
||||||
|
$field_number = 0;
|
||||||
|
|
||||||
|
// check if this is a valid table
|
||||||
|
$item_bucket = [];
|
||||||
|
|
||||||
|
foreach ($fields as $field)
|
||||||
|
{
|
||||||
|
// model a value if it exists
|
||||||
|
if(isset($item[$field]))
|
||||||
|
{
|
||||||
|
if (!$this->validateBefore($item[$field], $field, $table))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$item[$field] = $this->value($item[$field], $field, $table);
|
||||||
|
|
||||||
|
if (!$this->validateAfter($item[$field], $field, $table))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$item_bucket[$field] = $item[$field];
|
||||||
|
|
||||||
|
$field_number++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// all items must have more than one field or its empty (1 = id or guid)
|
||||||
|
if ($field_number > 1)
|
||||||
|
{
|
||||||
|
return $item_bucket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the values of multiple rows
|
||||||
|
* Example: $this->items(Array, 'table_name');
|
||||||
|
*
|
||||||
|
* @param array|null $items The array of item array
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function rows(?array $items = null, ?string $table = null): ?array
|
||||||
|
{
|
||||||
|
// check if this is a valid table
|
||||||
|
if (ArrayHelper::check($items))
|
||||||
|
{
|
||||||
|
// set the table name
|
||||||
|
if (empty($table))
|
||||||
|
{
|
||||||
|
$table = $this->getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($items as $id => &$item)
|
||||||
|
{
|
||||||
|
// model the item
|
||||||
|
if (($item = $this->row($item, $table)) !== null)
|
||||||
|
{
|
||||||
|
// add the last ID
|
||||||
|
$this->last[$table] = $item['id'] ?? $this->last[$table] ?? null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($items[$id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ArrayHelper::check($items))
|
||||||
|
{
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get last modeled ID
|
||||||
|
* Example: $this->last('table_name');
|
||||||
|
*
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function last(?string $table = null): ?int
|
||||||
|
{
|
||||||
|
// set the table name
|
||||||
|
if (empty($table))
|
||||||
|
{
|
||||||
|
$table = $this->getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if this is a valid table
|
||||||
|
if ($table && isset($this->last[$table]))
|
||||||
|
{
|
||||||
|
return $this->last[$table];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $tableName The table name
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function setTable(string $tableName): void
|
||||||
|
{
|
||||||
|
$this->tableName = $tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the switch to control the behaviour of empty values
|
||||||
|
*
|
||||||
|
* @param bool $allowEmpty The switch
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function setAllowEmpty(bool $allowEmpty): void
|
||||||
|
{
|
||||||
|
$this->allowEmpty = $allowEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected function getTable(): string
|
||||||
|
{
|
||||||
|
return $this->tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the switch to control the behaviour of empty values
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected function getAllowEmpty(): bool
|
||||||
|
{
|
||||||
|
return $this->allowEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table's fields (including defaults)
|
||||||
|
*
|
||||||
|
* @param string $table The area
|
||||||
|
* @param bool $default Add the default fields
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected function getTableFields(string $table, bool $default = false): ?array
|
||||||
|
{
|
||||||
|
return $this->table->fields($table, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate before the value is modelled (basic, override in child class)
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string|null $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
abstract protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate after the value is modelled (basic, override in child class)
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string|null $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
abstract protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool;
|
||||||
|
}
|
||||||
|
|
821
src/VastDevelopmentMethod/Joomla/Abstraction/Schema.php
Normal file
821
src/VastDevelopmentMethod/Joomla/Abstraction/Schema.php
Normal file
@ -0,0 +1,821 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Abstraction;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\CMS\Factory;
|
||||||
|
use Joomla\CMS\Version;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Tableinterface as Table;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\SchemaInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema Checking
|
||||||
|
*
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
abstract class Schema implements SchemaInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Table Class.
|
||||||
|
*
|
||||||
|
* @var Table
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected Table $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Database Class
|
||||||
|
*
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected $db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The local tables
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
private array $tables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The component table prefix
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
private string $prefix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The field unique keys
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
private array $uniqueKeys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The field keys
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
private array $keys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current table columns
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
private array $columns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The success messages of the action
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
private array $success;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current Joomla Version We are IN
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @since 3.2.1
|
||||||
|
**/
|
||||||
|
protected $currentVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param Table $table The Table Class.
|
||||||
|
*
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If the database fails
|
||||||
|
*/
|
||||||
|
public function __construct(Table $table)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// set the database object
|
||||||
|
$this->db = Factory::getDbo();
|
||||||
|
|
||||||
|
// get current component tables
|
||||||
|
$this->tables = $this->db->getTableList();
|
||||||
|
|
||||||
|
// set the component table
|
||||||
|
$this->prefix = $this->db->getPrefix() . $this->getCode();
|
||||||
|
|
||||||
|
// set the current version
|
||||||
|
$this->currentVersion = Version::MAJOR_VERSION;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \Exception("Error: failed to initialize schema class due to a database error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check and update database schema for missing fields or tables.
|
||||||
|
*
|
||||||
|
* @return array The array of successful updates/actions, if empty no update/action was taken.
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If there is an error during the update process.
|
||||||
|
*/
|
||||||
|
public function update(): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->success = [
|
||||||
|
"Success: scan of the component tables started."
|
||||||
|
];
|
||||||
|
foreach ($this->table->tables() as $table)
|
||||||
|
{
|
||||||
|
$this->uniqueKeys = [];
|
||||||
|
$this->keys = [];
|
||||||
|
|
||||||
|
if ($this->tableExists($table))
|
||||||
|
{
|
||||||
|
$this->updateSchema($table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->createTable($table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \Exception("Error: updating database schema. " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->success) == 1)
|
||||||
|
{
|
||||||
|
$this->success[] = "Success: scan of the component tables completed with no update needed.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->success[] = "Success: scan of the component tables completed.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the targeted component code
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
abstract protected function getCode(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a table exists in the database.
|
||||||
|
*
|
||||||
|
* @param string $table The name of the table to check.
|
||||||
|
*
|
||||||
|
* @return bool True if table exists, False otherwise.
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function tableExists(string $table): bool
|
||||||
|
{
|
||||||
|
return in_array($this->getTable($table), $this->tables);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the schema of an existing table.
|
||||||
|
*
|
||||||
|
* @param string $table The table to update.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If there is an error while updating the schema.
|
||||||
|
*/
|
||||||
|
public function updateSchema(string $table): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$existingColumns = $this->getExistingColumns($table);
|
||||||
|
$expectedColumns = $this->table->fields($table, true);
|
||||||
|
|
||||||
|
$missingColumns = array_diff($expectedColumns, $existingColumns);
|
||||||
|
|
||||||
|
if (!empty($missingColumns))
|
||||||
|
{
|
||||||
|
$this->addMissingColumns($table, $missingColumns);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->checkColumnsDataType($table, $expectedColumns);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \Exception("Error: updating schema for $table table. " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($missingColumns))
|
||||||
|
{
|
||||||
|
$column_s = (count($missingColumns) == 1) ? 'column' : 'columns';
|
||||||
|
$missingColumns = implode(', ', $missingColumns);
|
||||||
|
$this->success[] = "Success: added missing ($missingColumns) $column_s to $table table.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a table with all necessary fields.
|
||||||
|
*
|
||||||
|
* @param string $table The name of the table to create.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If there is an error creating the table.
|
||||||
|
*/
|
||||||
|
public function createTable(string $table): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$columns = [];
|
||||||
|
$fields = $this->table->fields($table, true);
|
||||||
|
$createTable = 'CREATE TABLE IF NOT EXISTS ' . $this->db->quoteName($this->getTable($table));
|
||||||
|
|
||||||
|
foreach ($fields as $field)
|
||||||
|
{
|
||||||
|
if (($def = $this->getColumnDefinition($table, $field)) !== null)
|
||||||
|
{
|
||||||
|
$columns[] = $def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$columnDefinitions = implode(', ', $columns);
|
||||||
|
|
||||||
|
$keys = $this->getTableKeys();
|
||||||
|
|
||||||
|
$createTableSql = "$createTable ($columnDefinitions, $keys)";
|
||||||
|
|
||||||
|
$this->db->setQuery($createTableSql);
|
||||||
|
$this->db->execute();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \Exception("Error: failed to create missing $table table. " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->success[] = "Success: created missing $table table.";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch existing columns from a database table.
|
||||||
|
*
|
||||||
|
* @param string $table The name of the table.
|
||||||
|
*
|
||||||
|
* @return array An array of column names.
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function getExistingColumns(string $table): array
|
||||||
|
{
|
||||||
|
$this->columns = $this->db->getTableColumns($this->getTable($table), false);
|
||||||
|
|
||||||
|
return array_keys($this->columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add missing columns to a table.
|
||||||
|
*
|
||||||
|
* @param string $table The table to update.
|
||||||
|
* @param array $columns List of missing columns/fields.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If there is an error adding columns.
|
||||||
|
*/
|
||||||
|
protected function addMissingColumns(string $table, array $columns): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$query = $this->db->getQuery(true);
|
||||||
|
$alterTable = 'ALTER TABLE ' . $this->db->quoteName($this->getTable($table)) . ' ';
|
||||||
|
|
||||||
|
// Start an ALTER TABLE query
|
||||||
|
$alterQueries = [];
|
||||||
|
foreach ($columns as $column)
|
||||||
|
{
|
||||||
|
if (($def = $this->getColumnDefinition($table, $column)) !== null)
|
||||||
|
{
|
||||||
|
$alterQueries[] = " ADD " . $def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->setQuery($alterTable . implode(', ', $alterQueries));
|
||||||
|
$this->db->execute();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$column_s = (count($columns) == 1) ? 'column' : 'columns';
|
||||||
|
$columns = implode(', ', $columns);
|
||||||
|
throw new \Exception("Error: failed to add ($columns) $column_s to $table table. " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate and update the data type of existing fields/columns
|
||||||
|
*
|
||||||
|
* @param string $table The table to update.
|
||||||
|
* @param array $columns List of columns/fields to check.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function checkColumnsDataType(string $table, array $columns): void
|
||||||
|
{
|
||||||
|
$requireUpdate = [];
|
||||||
|
foreach ($columns as $column)
|
||||||
|
{
|
||||||
|
$current = $this->columns[$column] ?? null;
|
||||||
|
if ($current === null || ($expected = $this->table->get($table, $column, 'db')) === null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the data type and size match
|
||||||
|
if ($this->isDataTypeChangeSignificant($current->Type, $expected['type']))
|
||||||
|
{
|
||||||
|
$requireUpdate[$column] = [
|
||||||
|
'column' => $column,
|
||||||
|
'current' => $current->Type,
|
||||||
|
'expected' => $expected['type']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// check if update of default values is needed
|
||||||
|
elseif ($this->checkDefault($table, $column))
|
||||||
|
{
|
||||||
|
$requireUpdate[$column] = [
|
||||||
|
'column' => $column,
|
||||||
|
'current' => $current->Type,
|
||||||
|
'expected' => $expected['type']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// check if update of null is needed
|
||||||
|
elseif ($this->checkNull($table, $column))
|
||||||
|
{
|
||||||
|
$requireUpdate[$column] = [
|
||||||
|
'column' => $column,
|
||||||
|
'current' => $current->Type,
|
||||||
|
'expected' => $expected['type']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($requireUpdate))
|
||||||
|
{
|
||||||
|
$this->updateColumnsDataType($table, $requireUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a SQL snippet for defining a table column, incorporating column type,
|
||||||
|
* default value, nullability, and auto-increment properties.
|
||||||
|
*
|
||||||
|
* @param string $table The table name to be used.
|
||||||
|
* @param string $field The field name in the table to generate SQL for.
|
||||||
|
*
|
||||||
|
* @return string|null The SQL snippet for the column definition.
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If the schema details cannot be retrieved or the SQL statement cannot be constructed properly.
|
||||||
|
*/
|
||||||
|
protected function getColumnDefinition(string $table, string $field): ?string
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Retrieve the database schema details for the specified table and field
|
||||||
|
if (($db = $this->table->get($table, $field, 'db')) === null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the column name
|
||||||
|
$column_name = $this->db->quoteName($field);
|
||||||
|
$db['name'] = $field;
|
||||||
|
|
||||||
|
// Prepare the type and default value SQL statement
|
||||||
|
$type = $db['type'] ?? 'TEXT';
|
||||||
|
$db_default = isset($db['default']) ? $db['default'] : null;
|
||||||
|
$default = $this->getDefaultValue($type, $db_default);
|
||||||
|
|
||||||
|
// Prepare the null switch, and auto increment statement
|
||||||
|
$null_switch = !empty($db['null_switch']) ? ' ' . $db['null_switch'] : '';
|
||||||
|
|
||||||
|
// Prepare the auto increment statement
|
||||||
|
$auto_increment = !empty($db['auto_increment']) ? " AUTO_INCREMENT" : '';
|
||||||
|
|
||||||
|
// If there's a default value, the column should not be nullable
|
||||||
|
if ($default !== '')
|
||||||
|
{
|
||||||
|
$null_switch = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setKeys($db);
|
||||||
|
|
||||||
|
// Assemble the SQL snippet for the column definition
|
||||||
|
return "{$column_name} {$type}{$null_switch}{$auto_increment}{$default}";
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \Exception("Error: failed to generate column definition for ($table.$field). " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check and Update the default values if needed, including existing data adjustments
|
||||||
|
*
|
||||||
|
* @param string $table The table to update.
|
||||||
|
* @param string $column The column/field to check.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function checkDefault(string $table, string $column): bool
|
||||||
|
{
|
||||||
|
// Retrieve the expected column configuration
|
||||||
|
$expected = $this->table->get($table, $column, 'db');
|
||||||
|
|
||||||
|
// Skip updates if the column is auto_increment
|
||||||
|
if (isset($expected['auto_increment']) && $expected['auto_increment'] === true)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the current column configuration
|
||||||
|
$current = $this->columns[$column];
|
||||||
|
|
||||||
|
// Determine the new default value based on the expected settings
|
||||||
|
$type = $expected['type'] ?? 'TEXT';
|
||||||
|
$db_default = isset($expected['default']) ? $expected['default'] : null;
|
||||||
|
$newDefault = $this->getDefaultValue($type, $db_default, true);
|
||||||
|
|
||||||
|
// First, adjust existing rows to conform to the new default if necessary
|
||||||
|
if (is_numeric($newDefault) && $this->adjustExistingDefaults($table, $column, $current->Default, $newDefault))
|
||||||
|
{
|
||||||
|
$this->success[] = "Success: updated the ($column) defaults in $table table.";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($expected['default']) && strtoupper($expected['default']) === 'EMPTY' &&
|
||||||
|
is_string($current->Default) && strpos($current->Default, 'EMPTY') !== false)
|
||||||
|
{
|
||||||
|
return true; // little fix
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check and Update the null value if needed, including existing data adjustments
|
||||||
|
*
|
||||||
|
* @param string $table The table to update.
|
||||||
|
* @param string $column The column/field to check.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected function checkNull(string $table, string $column): bool
|
||||||
|
{
|
||||||
|
// Retrieve the expected column configuration
|
||||||
|
$expected = $this->table->get($table, $column, 'db');
|
||||||
|
|
||||||
|
// Skip updates if the null_switch is not set
|
||||||
|
if (!isset($expected['null_switch']))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the current column configuration
|
||||||
|
$current = $this->columns[$column];
|
||||||
|
|
||||||
|
// Skip updates if the Null is not set
|
||||||
|
if (!isset($current->Null))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the expected NULL
|
||||||
|
$expected_null = 'NO';
|
||||||
|
if ($expected['null_switch'] === "NULL")
|
||||||
|
{
|
||||||
|
$expected_null = 'YES';
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the current NULL
|
||||||
|
$current_null = $current->Null;
|
||||||
|
|
||||||
|
// Prepare the type and default value SQL statement
|
||||||
|
$type = $expected['type'] ?? 'TEXT';
|
||||||
|
$db_default = isset($expected['default']) ? $expected['default'] : null;
|
||||||
|
$default = $this->getDefaultValue($type, $db_default, true);
|
||||||
|
|
||||||
|
// check the null values if they match
|
||||||
|
if ($current_null !== $expected_null && $current_null === 'NO' && empty($default))
|
||||||
|
{
|
||||||
|
$this->success[] = "Success: updated the ($column) null state in $table table.";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the data type of the given fields.
|
||||||
|
*
|
||||||
|
* @param string $table The table to update.
|
||||||
|
* @param array $columns List of columns/fields that must be updated.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function updateColumnsDataType(string $table, array $columns): void
|
||||||
|
{
|
||||||
|
$alterTable = 'ALTER TABLE ' . $this->db->quoteName($this->getTable($table));
|
||||||
|
foreach ($columns as $column => $types)
|
||||||
|
{
|
||||||
|
if (($def = $this->getColumnDefinition($table, $column)) === null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbField = $this->db->quoteName($column);
|
||||||
|
$alterQuery = "$alterTable CHANGE $dbField ". $def;
|
||||||
|
|
||||||
|
if ($this->updateColumnDataType($alterQuery, $table, $column))
|
||||||
|
{
|
||||||
|
$current = $types['current'] ?? 'error';
|
||||||
|
$expected = $types['expected'] ?? 'error';
|
||||||
|
$this->success[] = "Success: updated ($column) column datatype $current to $expected in $table table.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the component name to get the full table name.
|
||||||
|
*
|
||||||
|
* @param string $table The table name.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function getTable(string $table): string
|
||||||
|
{
|
||||||
|
return $this->prefix . '_' . $table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the change in data type between two definitions is significant.
|
||||||
|
*
|
||||||
|
* This function checks if there's a significant difference between the current
|
||||||
|
* data type and the expected data type that would require updating the database schema.
|
||||||
|
* It ignores display width for numeric types where MySQL considers these attributes
|
||||||
|
* irrelevant for storage but considers size and other modifiers for types like VARCHAR.
|
||||||
|
*
|
||||||
|
* @param string $currentType The current data type from the database schema.
|
||||||
|
* @param string $expectedType The expected data type to validate against.
|
||||||
|
*
|
||||||
|
* @return bool Returns true if the data type change is significant, otherwise false.
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function isDataTypeChangeSignificant(string $currentType, string $expectedType): bool
|
||||||
|
{
|
||||||
|
// Normalize both input types to lowercase for case-insensitive comparison
|
||||||
|
$currentType = strtolower($currentType);
|
||||||
|
$expectedType = strtolower($expectedType);
|
||||||
|
|
||||||
|
// Regex to extract the base data type and numeric parameters with named groups
|
||||||
|
$typePattern = '/^(?<datatype>\w+)(\((?<params>\d+(,\d+)?)\))?/';
|
||||||
|
|
||||||
|
// Match types and parameters
|
||||||
|
preg_match($typePattern, $currentType, $currentMatches);
|
||||||
|
preg_match($typePattern, $expectedType, $expectedMatches);
|
||||||
|
|
||||||
|
// Compare base types
|
||||||
|
if ($currentMatches['datatype'] !== $expectedMatches['datatype'])
|
||||||
|
{
|
||||||
|
return true; // Base types differ
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define types where size and other modifiers are irrelevant
|
||||||
|
$sizeIrrelevantTypes = [
|
||||||
|
'int', 'tinyint', 'smallint', 'mediumint', 'bigint',
|
||||||
|
'float', 'double', 'decimal', 'numeric' // Numeric types where display width is irrelevant
|
||||||
|
];
|
||||||
|
|
||||||
|
// If the type is not in the size irrelevant list, compare full definitions
|
||||||
|
if (!in_array($currentMatches['datatype'], $sizeIrrelevantTypes))
|
||||||
|
{
|
||||||
|
return $currentType !== $expectedType; // Use full definition for types where size matters
|
||||||
|
}
|
||||||
|
|
||||||
|
// For size irrelevant types, only compare base type, ignoring size and unsigned
|
||||||
|
$currentBaseType = preg_replace('/\(\d+(,\d+)?\)|unsigned/', '', $currentType);
|
||||||
|
$expectedBaseType = preg_replace('/\(\d+(,\d+)?\)|unsigned/', '', $expectedType);
|
||||||
|
|
||||||
|
// Perform a final comparison for numeric types ignoring size
|
||||||
|
return $currentBaseType !== $expectedBaseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates existing rows in a column to a new default value
|
||||||
|
*
|
||||||
|
* @param string $table The table to update.
|
||||||
|
* @param string $column The column to update.
|
||||||
|
* @param mixed $currentDefault Current default value.
|
||||||
|
* @param mixed $newDefault The new default value to be set.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If there is an error updating column defaults.
|
||||||
|
*/
|
||||||
|
protected function adjustExistingDefaults(string $table, string $column, $currentDefault, $newDefault): bool
|
||||||
|
{
|
||||||
|
// Determine if adjustment is needed based on new and current defaults
|
||||||
|
if ($newDefault !== $currentDefault)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Format the new default for SQL use
|
||||||
|
$sqlDefault = $this->db->quote($newDefault);
|
||||||
|
|
||||||
|
$updateTable = 'UPDATE ' . $this->db->quoteName($this->getTable($table));
|
||||||
|
$dbField = $this->db->quoteName($column);
|
||||||
|
|
||||||
|
// Update SQL to set new default on existing rows where the default is currently the old default
|
||||||
|
$sql = $updateTable . " SET $dbField = $sqlDefault WHERE $dbField IS NULL OR $dbField = ''";
|
||||||
|
|
||||||
|
// Execute the update
|
||||||
|
$this->db->setQuery($sql);
|
||||||
|
return $this->db->execute();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \Exception("Error: failed to update ($column) column defaults in $table table. " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the data type of the given field.
|
||||||
|
*
|
||||||
|
* @param string $updateString The SQL command to update the column data type
|
||||||
|
* @param string $table The table to update.
|
||||||
|
* @param string $field Column/field that must be updated.
|
||||||
|
*
|
||||||
|
* @return bool true on succes
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If there is an error adding columns.
|
||||||
|
*/
|
||||||
|
protected function updateColumnDataType(string $updateString, string $table, string $field): bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->db->setQuery($updateString);
|
||||||
|
return $this->db->execute();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \Exception("Error: failed to update the datatype of ($field) column in $table table. " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key all needed keys for this table
|
||||||
|
*
|
||||||
|
* @return string of keys
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function getTableKeys(): string
|
||||||
|
{
|
||||||
|
$keys = [];
|
||||||
|
$keys[] = 'PRIMARY KEY (`id`)'; // TODO (we may want this to be dynamicly set)
|
||||||
|
|
||||||
|
if (!empty($this->uniqueKeys))
|
||||||
|
{
|
||||||
|
$keys[] = implode(', ', $this->uniqueKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->keys))
|
||||||
|
{
|
||||||
|
$keys[] = implode(', ', $this->keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(', ', $keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to set the view keys
|
||||||
|
*
|
||||||
|
* @param string $column The field column database array values
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function setKeys(array $column): void
|
||||||
|
{
|
||||||
|
$this->setUniqueKey($column);
|
||||||
|
$this->setKey($column);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to set the unique key
|
||||||
|
*
|
||||||
|
* @param string $column The field column database array values
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function setUniqueKey(array $column): void
|
||||||
|
{
|
||||||
|
if (isset($column['unique_key']) && $column['unique_key'])
|
||||||
|
{
|
||||||
|
$key = $column['unique_key_name'] ?? $column['name'];
|
||||||
|
$this->uniqueKeys[] = "UNIQUE KEY `idx_" . $key . "` (`" . $column['name'] . "`)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to set the key
|
||||||
|
*
|
||||||
|
* @param string $column The field column database array values
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function setKey(array $column): void
|
||||||
|
{
|
||||||
|
if (isset($column['key']) && $column['key'])
|
||||||
|
{
|
||||||
|
$key = $column['key_name'] ?? $column['name'];
|
||||||
|
$this->keys[] = "KEY `idx_" . $key . "` (`" . $column['name'] . "`)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the default value SQL fragment for a database field based on its type and specific rules.
|
||||||
|
*
|
||||||
|
* If the field is of type DATETIME and the Joomla version is not 3, it sets the default to CURRENT_TIMESTAMP
|
||||||
|
* if not explicitly specified otherwise. For all other types it handles defaults by either leaving them unset or applying
|
||||||
|
* the provided default, properly quoted for SQL safety. When a 'EMPTY' default is specified, it returns no default at all. (:)
|
||||||
|
*
|
||||||
|
* @param string $type The type of the database field (e.g., 'DATETIME').
|
||||||
|
* @param string|null $defaultValue Optional default value for the field, null if not provided.
|
||||||
|
* @param bool $pure Optional to add the 'DEFAULT' string or not.
|
||||||
|
*
|
||||||
|
* @return string The SQL fragment to set the default value for a field.
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function getDefaultValue(string $type, ?string $defaultValue, bool $pure = false): string
|
||||||
|
{
|
||||||
|
if ($defaultValue === null || strtoupper($defaultValue) === 'EMPTY')
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default for DATETIME fields in Joomla versions above 3
|
||||||
|
if (strtoupper($type) === 'DATETIME' && $this->currentVersion != 3)
|
||||||
|
{
|
||||||
|
return $pure ? "CURRENT_TIMESTAMP" : " DEFAULT CURRENT_TIMESTAMP";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply and quote the default value
|
||||||
|
$sql_default = $this->quote($defaultValue);
|
||||||
|
return $pure ? $defaultValue : " DEFAULT $sql_default";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a value based on data type
|
||||||
|
*
|
||||||
|
* @param mixed $value The value to set
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
protected function quote($value)
|
||||||
|
{
|
||||||
|
if ($value === null) // hmm the null does pose an issue (will keep an eye on this)
|
||||||
|
{
|
||||||
|
return 'NULL';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_numeric($value))
|
||||||
|
{
|
||||||
|
if (filter_var($value, FILTER_VALIDATE_INT))
|
||||||
|
{
|
||||||
|
return (int) $value;
|
||||||
|
}
|
||||||
|
elseif (filter_var($value, FILTER_VALIDATE_FLOAT))
|
||||||
|
{
|
||||||
|
return (float) $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (is_bool($value)) // not sure if this will work well (but its correct)
|
||||||
|
{
|
||||||
|
return $value ? 'TRUE' : 'FALSE';
|
||||||
|
}
|
||||||
|
// For date and datetime values
|
||||||
|
elseif ($value instanceof \DateTime)
|
||||||
|
{
|
||||||
|
return $this->db->quote($value->format('Y-m-d H:i:s'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// For other data types, just escape it
|
||||||
|
return $this->db->quote($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Componentbuilder\Table;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Componentbuilder\Table;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\SchemaInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Abstraction\Schema as ExtendingSchema;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Componentbuilder Tables Schema
|
||||||
|
*
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
final class Schema extends ExtendingSchema implements SchemaInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param Table $table The Table Class.
|
||||||
|
*
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
public function __construct(?Table $table = null)
|
||||||
|
{
|
||||||
|
$table ??= new Table;
|
||||||
|
|
||||||
|
parent::__construct($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the targeted component code
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected function getCode(): string
|
||||||
|
{
|
||||||
|
return 'componentbuilder';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
112
src/VastDevelopmentMethod/Joomla/Data/Action/Delete.php
Normal file
112
src/VastDevelopmentMethod/Joomla/Data/Action/Delete.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Data\Action;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\DeleteInterface as Database;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\DeleteInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Delete
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
class Delete implements DeleteInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Delete Class.
|
||||||
|
*
|
||||||
|
* @var Database
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Database $database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected string $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param Database $database The Delete Class.
|
||||||
|
* @param string|null $table The table name.
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function __construct(Database $database, ?string $table = null)
|
||||||
|
{
|
||||||
|
$this->database = $database;
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string|null $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(?string $table): self
|
||||||
|
{
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all items in the database that match these conditions
|
||||||
|
*
|
||||||
|
* @param array $conditions Conditions by which to delete the data in database [array of arrays (key => value)]
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
public function items(array $conditions): bool
|
||||||
|
{
|
||||||
|
return $this->database->items($conditions, $this->getTable());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncate a table
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
public function truncate(): void
|
||||||
|
{
|
||||||
|
$this->database->truncate($this->getTable());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string
|
||||||
|
{
|
||||||
|
return $this->table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
202
src/VastDevelopmentMethod/Joomla/Data/Action/Insert.php
Normal file
202
src/VastDevelopmentMethod/Joomla/Data/Action/Insert.php
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Data\Action;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\ModelInterface as Model;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\InsertInterface as Database;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\InsertInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Insert (GUID)
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
class Insert implements InsertInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Model
|
||||||
|
*
|
||||||
|
* @var Model
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected Model $model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database
|
||||||
|
*
|
||||||
|
* @var Database
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected Database $database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected string $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param Model $model The set model object.
|
||||||
|
* @param Database $database The insert database object.
|
||||||
|
* @param string|null $table The table name.
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function __construct(Model $model, Database $database, ?string $table = null)
|
||||||
|
{
|
||||||
|
$this->model = $model;
|
||||||
|
$this->database = $database;
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string|null $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(?string $table): self
|
||||||
|
{
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a value to a given table
|
||||||
|
* Example: $this->value(Value, 'value_key', 'GUID');
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string $keyValue The key value
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function value($value, string $field, string $keyValue, string $key = 'guid'): bool
|
||||||
|
{
|
||||||
|
// build the array
|
||||||
|
$item = [];
|
||||||
|
$item[$key] = $keyValue;
|
||||||
|
$item[$field] = $value;
|
||||||
|
|
||||||
|
// Insert the column of this table
|
||||||
|
return $this->row($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert single row with multiple values to a given table
|
||||||
|
* Example: $this->item(Array);
|
||||||
|
*
|
||||||
|
* @param array $item The item to save
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function row(array $item): bool
|
||||||
|
{
|
||||||
|
// check if object could be modelled
|
||||||
|
if (($item = $this->model->row($item, $this->getTable())) !== null)
|
||||||
|
{
|
||||||
|
// Insert the column of this table
|
||||||
|
return $this->database->row($item, $this->getTable());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert multiple rows to a given table
|
||||||
|
* Example: $this->items(Array);
|
||||||
|
*
|
||||||
|
* @param array|null $items The items updated in database (array of arrays)
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function rows(?array $items): bool
|
||||||
|
{
|
||||||
|
// check if object could be modelled
|
||||||
|
if (($items = $this->model->rows($items, $this->getTable())) !== null)
|
||||||
|
{
|
||||||
|
// Insert the column of this table
|
||||||
|
return $this->database->rows($items, $this->getTable());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert single item with multiple values to a given table
|
||||||
|
* Example: $this->item(Object);
|
||||||
|
*
|
||||||
|
* @param object $item The item to save
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function item(object $item): bool
|
||||||
|
{
|
||||||
|
// check if object could be modelled
|
||||||
|
if (($item = $this->model->item($item, $this->getTable())) !== null)
|
||||||
|
{
|
||||||
|
// Insert the column of this table
|
||||||
|
return $this->database->item($item, $this->getTable());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert multiple items to a given table
|
||||||
|
* Example: $this->items(Array);
|
||||||
|
*
|
||||||
|
* @param array|null $items The items updated in database (array of objects)
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function items(?array $items): bool
|
||||||
|
{
|
||||||
|
// check if object could be modelled
|
||||||
|
if (($items = $this->model->items($items, $this->getTable())) !== null)
|
||||||
|
{
|
||||||
|
// Update the column of this table using guid as the primary key.
|
||||||
|
return $this->database->items($items, $this->getTable());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string
|
||||||
|
{
|
||||||
|
return $this->table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
224
src/VastDevelopmentMethod/Joomla/Data/Action/Load.php
Normal file
224
src/VastDevelopmentMethod/Joomla/Data/Action/Load.php
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Data\Action;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\ModelInterface as Model;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\LoadInterface as Database;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\LoadInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Load (GUID)
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
class Load implements LoadInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Model Load
|
||||||
|
*
|
||||||
|
* @var Model
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
protected Model $model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Load
|
||||||
|
*
|
||||||
|
* @var Database
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
protected Database $load;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected string $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param Model $model The model object.
|
||||||
|
* @param Database $load The database object.
|
||||||
|
* @param string|null $table The table name.
|
||||||
|
*
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
public function __construct(Model $model, Database $load, ?string $table = null)
|
||||||
|
{
|
||||||
|
$this->model = $model;
|
||||||
|
$this->load = $load;
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string|null $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(?string $table): self
|
||||||
|
{
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value from a given table
|
||||||
|
* Example: $this->value(
|
||||||
|
* [
|
||||||
|
* 'guid' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
||||||
|
* ], 'value_key'
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @param array $keys The item keys
|
||||||
|
* @param string $field The field key
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
public function value(array $keys, string $field)
|
||||||
|
{
|
||||||
|
return $this->model->value(
|
||||||
|
$this->load->value(
|
||||||
|
["a.{$field}" => $field],
|
||||||
|
['a' => $this->getTable()],
|
||||||
|
$this->prefix($keys)
|
||||||
|
),
|
||||||
|
$field,
|
||||||
|
$this->getTable()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value from multiple rows from a given table
|
||||||
|
* Example: $this->values(
|
||||||
|
* [
|
||||||
|
* 'guid' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
||||||
|
* ], 'value_key'
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @param array $keys The item keys
|
||||||
|
* @param string $field The field key
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function values(array $keys, string $field): ?array
|
||||||
|
{
|
||||||
|
return $this->model->values(
|
||||||
|
$this->load->values(
|
||||||
|
["a.{$field}" => $field],
|
||||||
|
['a' => $this->getTable()],
|
||||||
|
$this->prefix($keys)
|
||||||
|
),
|
||||||
|
$field,
|
||||||
|
$this->getTable()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get values from a given table
|
||||||
|
* Example: $this->item(
|
||||||
|
* [
|
||||||
|
* 'guid' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
||||||
|
* ]
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @param array $keys The item keys
|
||||||
|
*
|
||||||
|
* @return object|null
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
public function item(array $keys): ?object
|
||||||
|
{
|
||||||
|
return $this->model->item(
|
||||||
|
$this->load->item(
|
||||||
|
['all' => 'a.*'],
|
||||||
|
['a' => $this->getTable()],
|
||||||
|
$this->prefix($keys)
|
||||||
|
),
|
||||||
|
$this->getTable()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get values from a given table
|
||||||
|
* Example: $this->items(
|
||||||
|
* [
|
||||||
|
* 'guid' => [
|
||||||
|
* 'operator' => 'IN',
|
||||||
|
* 'value' => [''xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'', ''xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'']
|
||||||
|
* ]
|
||||||
|
* ]
|
||||||
|
* );
|
||||||
|
* Example: $this->items($ids);
|
||||||
|
*
|
||||||
|
* @param array $keys The item keys
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
public function items(array $keys): ?array
|
||||||
|
{
|
||||||
|
return $this->model->items(
|
||||||
|
$this->load->items(
|
||||||
|
['all' => 'a.*'], ['a' => $this->getTable()], $this->prefix($keys)
|
||||||
|
),
|
||||||
|
$this->getTable()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string
|
||||||
|
{
|
||||||
|
return $this->table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add prefix to the keys
|
||||||
|
*
|
||||||
|
* @param array $keys The query keys
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
private function prefix(array &$keys): array
|
||||||
|
{
|
||||||
|
// update the key values
|
||||||
|
$bucket = [];
|
||||||
|
foreach ($keys as $k => $v)
|
||||||
|
{
|
||||||
|
$bucket['a.' . $k] = $v;
|
||||||
|
}
|
||||||
|
return $bucket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
206
src/VastDevelopmentMethod/Joomla/Data/Action/Update.php
Normal file
206
src/VastDevelopmentMethod/Joomla/Data/Action/Update.php
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Data\Action;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\ModelInterface as Model;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\UpdateInterface as Database;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\UpdateInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Update
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
class Update implements UpdateInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Model
|
||||||
|
*
|
||||||
|
* @var Model
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected Model $model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database
|
||||||
|
*
|
||||||
|
* @var Database
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected Database $database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected string $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param Model $model The set model object.
|
||||||
|
* @param Database $database The update database object.
|
||||||
|
* @param string|null $table The table name.
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function __construct(Model $model, Database $database, ?string $table = null)
|
||||||
|
{
|
||||||
|
$this->model = $model;
|
||||||
|
$this->database = $database;
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string|null $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(?string $table): self
|
||||||
|
{
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a value to a given table
|
||||||
|
* Example: $this->value(Value, 'value_key', 'GUID');
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string $keyValue The key value
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function value($value, string $field, string $keyValue, string $key = 'guid'): bool
|
||||||
|
{
|
||||||
|
// build the array
|
||||||
|
$item = [];
|
||||||
|
$item[$key] = $keyValue;
|
||||||
|
$item[$field] = $value;
|
||||||
|
|
||||||
|
// Update the column of this table using $key as the primary key.
|
||||||
|
return $this->row($item, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update single row with multiple values to a given table
|
||||||
|
* Example: $this->item(Array);
|
||||||
|
*
|
||||||
|
* @param array $item The item to save
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function row(array $item, string $key = 'guid'): bool
|
||||||
|
{
|
||||||
|
// check if object could be modelled
|
||||||
|
if (($item = $this->model->row($item, $this->getTable())) !== null)
|
||||||
|
{
|
||||||
|
// Update the column of this table using $key as the primary key.
|
||||||
|
return $this->database->row($item, $key, $this->getTable());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update multiple rows to a given table
|
||||||
|
* Example: $this->items(Array);
|
||||||
|
*
|
||||||
|
* @param array|null $items The items updated in database (array of arrays)
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function rows(?array $items, string $key = 'guid'): bool
|
||||||
|
{
|
||||||
|
// check if object could be modelled
|
||||||
|
if (($items = $this->model->rows($items, $this->getTable())) !== null)
|
||||||
|
{
|
||||||
|
// Update the column of this table using $key as the primary key.
|
||||||
|
return $this->database->rows($items, $key, $this->getTable());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update single item with multiple values to a given table
|
||||||
|
* Example: $this->item(Object);
|
||||||
|
*
|
||||||
|
* @param object $item The item to save
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function item(object $item, string $key = 'guid'): bool
|
||||||
|
{
|
||||||
|
// check if object could be modelled
|
||||||
|
if (($item = $this->model->item($item, $this->getTable())) !== null)
|
||||||
|
{
|
||||||
|
// Update the column of this table using $key as the primary key.
|
||||||
|
return $this->database->item($item, $key, $this->getTable());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update multiple items to a given table
|
||||||
|
* Example: $this->items(Array);
|
||||||
|
*
|
||||||
|
* @param array|null $items The items updated in database (array of objects)
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function items(?array $items, string $key = 'guid'): bool
|
||||||
|
{
|
||||||
|
// check if object could be modelled
|
||||||
|
if (($items = $this->model->items($items, $this->getTable())) !== null)
|
||||||
|
{
|
||||||
|
// Update the column of this table using $key as the primary key.
|
||||||
|
return $this->database->items($items, $key, $this->getTable());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string
|
||||||
|
{
|
||||||
|
return $this->table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
46
src/VastDevelopmentMethod/Joomla/Data/Factory.php
Normal file
46
src/VastDevelopmentMethod/Joomla/Data/Factory.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Data;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\DI\Container;
|
||||||
|
use VastDevelopmentMethod\Joomla\Service\Table;
|
||||||
|
use VastDevelopmentMethod\Joomla\Service\Database;
|
||||||
|
use VastDevelopmentMethod\Joomla\Service\Model;
|
||||||
|
use VastDevelopmentMethod\Joomla\Service\Data;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\FactoryInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Abstraction\Factory as ExtendingFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Factory
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
abstract class Factory extends ExtendingFactory implements FactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a container object
|
||||||
|
*
|
||||||
|
* @return Container
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected static function createContainer(): Container
|
||||||
|
{
|
||||||
|
return (new Container())
|
||||||
|
->registerServiceProvider(new Table())
|
||||||
|
->registerServiceProvider(new Database())
|
||||||
|
->registerServiceProvider(new Model())
|
||||||
|
->registerServiceProvider(new Data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
245
src/VastDevelopmentMethod/Joomla/Data/Item.php
Normal file
245
src/VastDevelopmentMethod/Joomla/Data/Item.php
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Data;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\LoadInterface as Load;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\InsertInterface as Insert;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\UpdateInterface as Update;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\DeleteInterface as Delete;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\LoadInterface as Database;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\ItemInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Item
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
final class Item implements ItemInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Load Class.
|
||||||
|
*
|
||||||
|
* @var Load
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Load $load;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Insert Class.
|
||||||
|
*
|
||||||
|
* @var Insert
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Insert $insert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Update Class.
|
||||||
|
*
|
||||||
|
* @var Update
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Update $update;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Delete Class.
|
||||||
|
*
|
||||||
|
* @var Delete
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Delete $delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Load Class.
|
||||||
|
*
|
||||||
|
* @var Database
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Database $database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected string $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param Load $load The LoadInterface Class.
|
||||||
|
* @param Insert $insert The InsertInterface Class.
|
||||||
|
* @param Update $update The UpdateInterface Class.
|
||||||
|
* @param Delete $delete The UpdateInterface Class.
|
||||||
|
* @param Database $database The Database Load Class.
|
||||||
|
* @param string|null $table The table name.
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function __construct(Load $load, Insert $insert, Update $update,
|
||||||
|
Delete $delete, Database $database, ?string $table = null)
|
||||||
|
{
|
||||||
|
$this->load = $load;
|
||||||
|
$this->insert = $insert;
|
||||||
|
$this->update = $update;
|
||||||
|
$this->delete = $delete;
|
||||||
|
$this->database = $database;
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(string $table): self
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an item
|
||||||
|
*
|
||||||
|
* @param string $value The item key value
|
||||||
|
* @param string $key The item key
|
||||||
|
*
|
||||||
|
* @return object|null The item object or null
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function get(string $value, string $key = 'guid'): ?object
|
||||||
|
{
|
||||||
|
return $this->load->table($this->getTable())->item([$key => $value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value
|
||||||
|
*
|
||||||
|
* @param string $value The item key value
|
||||||
|
* @param string $key The item key
|
||||||
|
* @param string $get The key of the values we want back
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function value(string $value, string $key = 'guid', string $get = 'id')
|
||||||
|
{
|
||||||
|
return $this->load->table($this->getTable())->value([$key => $value], $get);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an item
|
||||||
|
*
|
||||||
|
* @param object $item The item
|
||||||
|
* @param string $key The item key
|
||||||
|
* @param string|null $action The action to load power
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function set(object $item, string $key = 'guid', ?string $action = null): bool
|
||||||
|
{
|
||||||
|
if ($action !== null || (isset($item->{$key}) && ($action = $this->action($item->{$key}, $key)) !== null))
|
||||||
|
{
|
||||||
|
return method_exists($this, $action) ? $this->{$action}($item, $key) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an item
|
||||||
|
*
|
||||||
|
* @param string $value The item key value
|
||||||
|
* @param string $key The item key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function delete(string $value, string $key = 'guid'): bool
|
||||||
|
{
|
||||||
|
return $this->delete->table($this->getTable())->items([$key => $value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string
|
||||||
|
{
|
||||||
|
return $this->table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a item
|
||||||
|
*
|
||||||
|
* @param object $item The item
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function insert(object $item): bool
|
||||||
|
{
|
||||||
|
return $this->insert->table($this->getTable())->item($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a item
|
||||||
|
*
|
||||||
|
* @param object $item The item
|
||||||
|
* @param string $key The item key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function update(object $item, string $key): bool
|
||||||
|
{
|
||||||
|
return $this->update->table($this->getTable())->item($item, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get loading action
|
||||||
|
*
|
||||||
|
* @param string $value The key value the item
|
||||||
|
* @param string $key The item key
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function action(string $value, string $key): string
|
||||||
|
{
|
||||||
|
$id = $this->database->value(
|
||||||
|
["a.id" => 'id'],
|
||||||
|
["a" => $this->getTable()],
|
||||||
|
["a.$key" => $value]
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($id !== null && $id > 0)
|
||||||
|
{
|
||||||
|
return 'update';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'insert';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
342
src/VastDevelopmentMethod/Joomla/Data/Items.php
Normal file
342
src/VastDevelopmentMethod/Joomla/Data/Items.php
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Data;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\LoadInterface as Load;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\InsertInterface as Insert;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\UpdateInterface as Update;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\DeleteInterface as Delete;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\LoadInterface as Database;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\ItemsInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Items
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
final class Items implements ItemsInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The LoadInterface Class.
|
||||||
|
*
|
||||||
|
* @var Load
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Load $load;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The InsertInterface Class.
|
||||||
|
*
|
||||||
|
* @var Insert
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Insert $insert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The UpdateInterface Class.
|
||||||
|
*
|
||||||
|
* @var Update
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Update $update;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DeleteInterface Class.
|
||||||
|
*
|
||||||
|
* @var Delete
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Delete $delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Load Class.
|
||||||
|
*
|
||||||
|
* @var Database
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Database $database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected string $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param Load $load The LoadInterface Class.
|
||||||
|
* @param Insert $insert The InsertInterface Class.
|
||||||
|
* @param Update $update The UpdateInterface Class.
|
||||||
|
* @param Delete $delete The DeleteInterface Class.
|
||||||
|
* @param Database $database The Database Load Class.
|
||||||
|
* @param string|null $table The table name.
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function __construct(Load $load, Insert $insert, Update $update, Delete $delete,
|
||||||
|
Database $database, ?string $table = null)
|
||||||
|
{
|
||||||
|
$this->load = $load;
|
||||||
|
$this->insert = $insert;
|
||||||
|
$this->update = $update;
|
||||||
|
$this->delete = $delete;
|
||||||
|
$this->database = $database;
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(string $table): self
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of items
|
||||||
|
*
|
||||||
|
* @param array $values The ids of the items
|
||||||
|
* @param string $key The key of the values
|
||||||
|
*
|
||||||
|
* @return array|null The item object or null
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function get(array $values, string $key = 'guid'): ?array
|
||||||
|
{
|
||||||
|
return $this->load->table($this->getTable())->items([
|
||||||
|
$key => [
|
||||||
|
'operator' => 'IN',
|
||||||
|
'value' => array_values($values)
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the values
|
||||||
|
*
|
||||||
|
* @param array $values The list of values (to search by).
|
||||||
|
* @param string $key The key on which the values being searched.
|
||||||
|
* @param string $get The key of the values we want back
|
||||||
|
*
|
||||||
|
* @return array|null The array of found values.
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function values(array $values, string $key = 'guid', string $get = 'id'): ?array
|
||||||
|
{
|
||||||
|
// Perform the database query
|
||||||
|
return $this->load->table($this->getTable())->values([
|
||||||
|
$key => [
|
||||||
|
'operator' => 'IN',
|
||||||
|
'value' => array_values($values)
|
||||||
|
]
|
||||||
|
], $get);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set items
|
||||||
|
*
|
||||||
|
* @param array $items The list of items
|
||||||
|
* @param string $key The key on which the items should be set
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function set(array $items, string $key = 'guid'): bool
|
||||||
|
{
|
||||||
|
if (($sets = $this->sort($items, $key)) !== null)
|
||||||
|
{
|
||||||
|
foreach ($sets as $action => $items)
|
||||||
|
{
|
||||||
|
$this->{$action}($items, $key);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete items
|
||||||
|
*
|
||||||
|
* @param array $values The item key value
|
||||||
|
* @param string $key The item key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function delete(array $values, string $key = 'guid'): bool
|
||||||
|
{
|
||||||
|
return $this->delete->table($this->getTable())->items([$key => ['operator' => 'IN', 'value' => $values]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string
|
||||||
|
{
|
||||||
|
return $this->table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a item
|
||||||
|
*
|
||||||
|
* @param array $items The item
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function insert(array $items): bool
|
||||||
|
{
|
||||||
|
return $this->insert->table($this->getTable())->rows($items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a item
|
||||||
|
*
|
||||||
|
* @param object $item The item
|
||||||
|
* @param string $key The item key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function update(array $items, string $key): bool
|
||||||
|
{
|
||||||
|
return $this->update->table($this->getTable())->rows($items, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort items between insert and update.
|
||||||
|
*
|
||||||
|
* @param array $items The list of items.
|
||||||
|
* @param string $key The key on which the items should be sorted.
|
||||||
|
*
|
||||||
|
* @return array|null The sorted sets.
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function sort(array $items, string $key): ?array
|
||||||
|
{
|
||||||
|
// Extract relevant items based on the key.
|
||||||
|
$values = $this->extractValues($items, $key);
|
||||||
|
if ($values === null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sets = [
|
||||||
|
'insert' => [],
|
||||||
|
'update' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
// Check for existing items.
|
||||||
|
$existingItems = $this->database->values(
|
||||||
|
["a.$key" => $key],
|
||||||
|
["a" => $this->getTable()],
|
||||||
|
["a.$key" => ['operator' => 'IN', 'value' => $values]]
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($existingItems !== null)
|
||||||
|
{
|
||||||
|
$sets['update'] = $this->extractSet($items, $existingItems, $key) ?? [];
|
||||||
|
$sets['insert'] = $this->extractSet($items, $existingItems, $key, true) ?? [];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sets['insert'] = $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If either set is empty, remove it from the result.
|
||||||
|
$sets = array_filter($sets);
|
||||||
|
|
||||||
|
return !empty($sets) ? $sets : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts values for a given key from an array of items.
|
||||||
|
* Items can be either arrays or objects.
|
||||||
|
*
|
||||||
|
* @param array $items Array of items (arrays or objects)
|
||||||
|
* @param string $key The key to extract values for
|
||||||
|
*
|
||||||
|
* @return array|null Extracted values
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function extractValues(array $items, string $key): ?array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($items as $item)
|
||||||
|
{
|
||||||
|
if (is_array($item) && !empty($item[$key]))
|
||||||
|
{
|
||||||
|
$result[] = $item[$key];
|
||||||
|
}
|
||||||
|
elseif (is_object($item) && !empty($item->{$key}))
|
||||||
|
{
|
||||||
|
$result[] = $item->{$key};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($result === []) ? null : $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts items from an array of items based on a set.
|
||||||
|
* Items can be either arrays or objects.
|
||||||
|
*
|
||||||
|
* @param array $items Array of items (arrays or objects)
|
||||||
|
* @param array $set The set to match values against
|
||||||
|
* @param string $key The key of the set values
|
||||||
|
* @param bool $inverse Whether to extract items not in the set
|
||||||
|
*
|
||||||
|
* @return array|null Extracted values
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function extractSet(array $items, array $set, string $key, bool $inverse = false): ?array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($items as $item)
|
||||||
|
{
|
||||||
|
$value = is_array($item) ? ($item[$key] ?? null) : ($item->{$key} ?? null);
|
||||||
|
|
||||||
|
if ($value !== null)
|
||||||
|
{
|
||||||
|
$inSet = in_array($value, $set);
|
||||||
|
if (($inSet && !$inverse) || (!$inSet && $inverse))
|
||||||
|
{
|
||||||
|
$result[] = is_array($item) ? $item : (array) $item; // convert all to arrays
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return empty($result) ? null : $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
511
src/VastDevelopmentMethod/Joomla/Data/MultiSubform.php
Normal file
511
src/VastDevelopmentMethod/Joomla/Data/MultiSubform.php
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 3rd September, 2020
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Data;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\SubformInterface as Subform;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\MultiSubformInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRUD the data of multi subform to another views (tables)
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
final class MultiSubform implements MultiSubformInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Subform Class.
|
||||||
|
*
|
||||||
|
* @var Subform
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Subform $subform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param Subform $subform The Subform Class.
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function __construct(Subform $subform)
|
||||||
|
{
|
||||||
|
$this->subform = $subform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a subform items
|
||||||
|
*
|
||||||
|
* @param array $getMap The the map to get the subfrom data
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* $getMap = [
|
||||||
|
* '_core' => [
|
||||||
|
* 'table' =>'data',
|
||||||
|
* 'linkValue' => $item->guid ?? '',
|
||||||
|
* 'linkKey' => 'look',
|
||||||
|
* 'field' => 'data',
|
||||||
|
* 'get' => ['guid','email','image','mobile_phone','website','dateofbirth']
|
||||||
|
* ],
|
||||||
|
* 'countries' => [
|
||||||
|
* 'table' =>'data_country',
|
||||||
|
* 'linkValue' => 'data:guid', // coretable:fieldname
|
||||||
|
* 'linkKey' => 'data',
|
||||||
|
* 'get' => ['guid','country','currency']
|
||||||
|
* ]
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* @return array|null The subform
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function get(array $getMap): ?array
|
||||||
|
{
|
||||||
|
// Validate the core map presence and structure
|
||||||
|
if (!isset($getMap['_core']) || !is_array($getMap['_core']) || !$this->validGetMap($getMap['_core']))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the core data
|
||||||
|
$coreData = $this->getSubformData($getMap['_core']);
|
||||||
|
|
||||||
|
// Return null if fetching core data fails
|
||||||
|
if (null === $coreData)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$table = $getMap['_core']['table'];
|
||||||
|
unset($getMap['_core']);
|
||||||
|
|
||||||
|
// Recursively get data for all nested subforms
|
||||||
|
return $this->getNestedSubforms($getMap, $coreData, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a subform items
|
||||||
|
*
|
||||||
|
* @param array $items The list of items from the subform to set
|
||||||
|
* @param array $setMap The the map to set the subfrom data
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* $items,
|
||||||
|
* $setMap = [
|
||||||
|
* '_core' => [
|
||||||
|
* 'table' =>'data',
|
||||||
|
* 'indexKey' => 'guid',
|
||||||
|
* 'linkKey' => 'look',
|
||||||
|
* 'linkValue' => $data['guid'] ?? ''
|
||||||
|
* ],
|
||||||
|
* 'countries' => [
|
||||||
|
* 'table' =>'data_country',
|
||||||
|
* 'indexKey' => 'guid',
|
||||||
|
* 'linkKey' => 'data',
|
||||||
|
* 'linkValue' => 'data:guid' // coretable:fieldname
|
||||||
|
* ]
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function set(array $items, array $setMap): bool
|
||||||
|
{
|
||||||
|
// Validate the core map presence and structure
|
||||||
|
if (!isset($setMap['_core']) || !is_array($setMap['_core']) || !$this->validSetMap($setMap['_core']))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the core data
|
||||||
|
if (!$this->setSubformData($items, $setMap['_core']))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$table = $setMap['_core']['table'];
|
||||||
|
unset($setMap['_core']);
|
||||||
|
|
||||||
|
// Recursively set data for all nested subforms
|
||||||
|
return $this->setNestedSubforms($setMap, $items, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch data based on provided map configuration.
|
||||||
|
*
|
||||||
|
* @param array $map Map configuration
|
||||||
|
* @param array|null $coreData The core data to be appended with subform data
|
||||||
|
*
|
||||||
|
* @return array|null Fetched data or null on failure
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function getSubformData(array $map, ?array $coreData = null): ?array
|
||||||
|
{
|
||||||
|
$map['linkValue'] = $this->setLinkValue($map['linkValue'], $coreData);
|
||||||
|
|
||||||
|
if (empty($map['linkValue']) || strpos($map['linkValue'], ':') !== false)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->subform->table($map['table'])->get(
|
||||||
|
$map['linkValue'],
|
||||||
|
$map['linkKey'],
|
||||||
|
$map['field'],
|
||||||
|
$map['get']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set data based on provided map configuration.
|
||||||
|
*
|
||||||
|
* @param array $items The list of items from the subform to set
|
||||||
|
* @param array $map The the map to set the subfrom data
|
||||||
|
* @param array|null $coreData The core data to be appended with subform data
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function setSubformData(array $items, array $map, ?array $coreData = null): bool
|
||||||
|
{
|
||||||
|
$map['linkValue'] = $this->setLinkValue($map['linkValue'], $coreData);
|
||||||
|
|
||||||
|
if (empty($map['linkValue']) || strpos($map['linkValue'], ':') !== false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->subform->table($map['table'])->set(
|
||||||
|
$items,
|
||||||
|
$map['indexKey'],
|
||||||
|
$map['linkKey'],
|
||||||
|
$map['linkValue']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the linked value if needed, and posible.
|
||||||
|
*
|
||||||
|
* @param string $linkValue The current linkValue
|
||||||
|
* @param array|null $data The already found data as table => dataSet[field] => value
|
||||||
|
*
|
||||||
|
* @return string|null The actual linkValue
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function setLinkValue(string $linkValue, ?array $data = null): ?string
|
||||||
|
{
|
||||||
|
if ($data !== null && strpos($linkValue, ':') !== false)
|
||||||
|
{
|
||||||
|
[$table, $field] = explode(':', $linkValue);
|
||||||
|
$linkValue = $data[$table][$field] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $linkValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively process additional subform data.
|
||||||
|
*
|
||||||
|
* @param array $getMap The nested map of data to process
|
||||||
|
* @param array $subformData The core subform data
|
||||||
|
* @param string $table The core table
|
||||||
|
*
|
||||||
|
* @return array The core data with nested subforms included
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function getNestedSubforms(array $getMap, array $subformData, string $table): array
|
||||||
|
{
|
||||||
|
foreach ($subformData as &$subform)
|
||||||
|
{
|
||||||
|
$subform = $this->processGetSubform($getMap, $subform, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $subformData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively process additional subform data.
|
||||||
|
*
|
||||||
|
* @param array $setMap The nested map of data to process
|
||||||
|
* @param array $subformData The core subform data
|
||||||
|
* @param string $table The core table
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function setNestedSubforms(array $setMap, array $subformData, string $table): bool
|
||||||
|
{
|
||||||
|
$status = true;
|
||||||
|
foreach ($subformData as $subform)
|
||||||
|
{
|
||||||
|
if (!$this->processSetSubform($setMap, $subform, $table))
|
||||||
|
{
|
||||||
|
$status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process each subform entry based on the map.
|
||||||
|
*
|
||||||
|
* @param array $getMap Mapping data for processing subforms
|
||||||
|
* @param array $subform A single subform entry
|
||||||
|
* @param string $table The table name used for linking values
|
||||||
|
*
|
||||||
|
* @return array Updated subform
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function processGetSubform(array $getMap, array $subform, string $table): array
|
||||||
|
{
|
||||||
|
foreach ($getMap as $key => $map)
|
||||||
|
{
|
||||||
|
if (!is_array($map) || isset($subform[$key]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->processGetMap($subform, $map, $key, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $subform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process each subform entry based on the map.
|
||||||
|
*
|
||||||
|
* @param array $setMap Mapping data for processing subforms
|
||||||
|
* @param array $subform A single subform entry
|
||||||
|
* @param string $table The table name used for linking values
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function processSetSubform(array $setMap, array $subform, string $table): bool
|
||||||
|
{
|
||||||
|
$status = true;
|
||||||
|
foreach ($setMap as $key => $map)
|
||||||
|
{
|
||||||
|
if (!is_array($map) || !isset($subform[$key]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->processSetMap($subform, $map, $key, $table))
|
||||||
|
{
|
||||||
|
$status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a given map by either fetching nested subforms or handling them directly.
|
||||||
|
*
|
||||||
|
* @param array &$subform Reference to subform data
|
||||||
|
* @param array $map Map configuration for subform processing
|
||||||
|
* @param string $key Key associated with the map
|
||||||
|
* @param string $table Core table name for linking values
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function processGetMap(array &$subform, array $map, string $key, string $table): void
|
||||||
|
{
|
||||||
|
if (isset($map['_core']))
|
||||||
|
{
|
||||||
|
$this->handleCoreGetMap($subform, $map, $key, $table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->handleRegularGetMap($subform, $map, $key, $table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a given map by either setting nested subforms or handling them directly.
|
||||||
|
*
|
||||||
|
* @param array $subform Subform data
|
||||||
|
* @param array $map Map configuration for subform processing
|
||||||
|
* @param string $key Key associated with the map
|
||||||
|
* @param string $table Core table name for linking values
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function processSetMap(array $subform, array $map, string $key, string $table): bool
|
||||||
|
{
|
||||||
|
if (isset($map['_core']))
|
||||||
|
{
|
||||||
|
return $this->handleCoreSetMap($subform, $map, $key, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->handleRegularSetMap($subform, $map, $key, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the processing of '_core' maps in a subform.
|
||||||
|
*
|
||||||
|
* @param array &$subform Reference to subform data
|
||||||
|
* @param array $map Map configuration for core subform processing
|
||||||
|
* @param string $key Key associated with the map
|
||||||
|
* @param string $table Core table name for linking values
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function handleCoreGetMap(array &$subform, array $map, string $key, string $table): void
|
||||||
|
{
|
||||||
|
if (is_array($map['_core']) && $this->validGetMap($map['_core']))
|
||||||
|
{
|
||||||
|
$map['_core']['linkValue'] = $this->setLinkValue($map['_core']['linkValue'], [$table => $subform]);
|
||||||
|
|
||||||
|
$subCoreData = $this->get($map);
|
||||||
|
if ($subCoreData !== null)
|
||||||
|
{
|
||||||
|
$subform[$key] = $subCoreData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the processing of '_core' maps in a subform.
|
||||||
|
*
|
||||||
|
* @param array $subform Subform data
|
||||||
|
* @param array $map Map configuration for core subform processing
|
||||||
|
* @param string $key Key associated with the map
|
||||||
|
* @param string $table Core table name for linking values
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function handleCoreSetMap(array $subform, array $map, string $key, string $table): bool
|
||||||
|
{
|
||||||
|
if (is_array($map['_core']) && $this->validGetMap($map['_core']))
|
||||||
|
{
|
||||||
|
$map['_core']['linkValue'] = $this->setLinkValue($map['_core']['linkValue'], [$table => $subform]);
|
||||||
|
|
||||||
|
return $this->set($subform[$key], $map);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the processing of regular maps in a subform.
|
||||||
|
*
|
||||||
|
* @param array &$subform Reference to subform data
|
||||||
|
* @param array $map Map configuration for regular subform processing
|
||||||
|
* @param string $key Key associated with the map
|
||||||
|
* @param string $table Core table name for linking values
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function handleRegularGetMap(array &$subform, array $map, string $key, string $table): void
|
||||||
|
{
|
||||||
|
$map['field'] = $key;
|
||||||
|
if ($this->validGetMap($map))
|
||||||
|
{
|
||||||
|
$subformData = $this->getSubformData($map, [$table => $subform]);
|
||||||
|
if ($subformData !== null)
|
||||||
|
{
|
||||||
|
$subform[$key] = $subformData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the processing of regular maps in a subform.
|
||||||
|
*
|
||||||
|
* @param array $subform Subform data
|
||||||
|
* @param array $map Map configuration for regular subform processing
|
||||||
|
* @param string $key Key associated with the map
|
||||||
|
* @param string $table Core table name for linking values
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function handleRegularSetMap(array $subform, array $map, string $key, string $table): bool
|
||||||
|
{
|
||||||
|
if ($this->validSetMap($map))
|
||||||
|
{
|
||||||
|
return $this->setSubformData($subform[$key], $map, [$table => $subform]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the get map configuration for fetching subform data.
|
||||||
|
* Ensures all required keys are present and have valid values.
|
||||||
|
*
|
||||||
|
* @param array $map The map configuration to validate.
|
||||||
|
*
|
||||||
|
* @return bool Returns true if the map is valid, false otherwise.
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function validGetMap(array $map): bool
|
||||||
|
{
|
||||||
|
// List of required keys with their expected types or validation functions
|
||||||
|
$requiredKeys = [
|
||||||
|
'table' => 'is_string',
|
||||||
|
'linkValue' => 'is_string',
|
||||||
|
'linkKey' => 'is_string',
|
||||||
|
'field' => 'is_string',
|
||||||
|
'get' => 'is_array'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Iterate through each required key and validate
|
||||||
|
foreach ($requiredKeys as $key => $validator)
|
||||||
|
{
|
||||||
|
if (empty($map[$key]) || !$validator($map[$key]))
|
||||||
|
{
|
||||||
|
return false; // Key missing or validation failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // All checks passed
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the set map configuration for fetching subform data.
|
||||||
|
* Ensures all required keys are present and have valid values.
|
||||||
|
*
|
||||||
|
* @param array $map The map configuration to validate.
|
||||||
|
*
|
||||||
|
* @return bool Returns true if the map is valid, false otherwise.
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function validSetMap(array $map): bool
|
||||||
|
{
|
||||||
|
// List of required keys with their expected types or validation functions
|
||||||
|
$requiredKeys = [
|
||||||
|
'table' => 'is_string',
|
||||||
|
'indexKey' => 'is_string',
|
||||||
|
'linkKey' => 'is_string',
|
||||||
|
'linkValue' => 'is_string'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Iterate through each required key and validate
|
||||||
|
foreach ($requiredKeys as $key => $validator)
|
||||||
|
{
|
||||||
|
if (empty($map[$key]) || !$validator($map[$key]))
|
||||||
|
{
|
||||||
|
return false; // Key missing or validation failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // All checks passed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
310
src/VastDevelopmentMethod/Joomla/Data/Subform.php
Normal file
310
src/VastDevelopmentMethod/Joomla/Data/Subform.php
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 3rd September, 2020
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Data;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\ItemsInterface as Items;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\Data\SubformInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRUD the data of any sub-form to another view (table)
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
final class Subform implements SubformInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The ItemsInterface Class.
|
||||||
|
*
|
||||||
|
* @var Items
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
protected Items $items;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table Name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
protected string $table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param Items $items The ItemsInterface Class.
|
||||||
|
* @param string|null $table The table name.
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function __construct(Items $items, ?string $table = null)
|
||||||
|
{
|
||||||
|
$this->items = $items;
|
||||||
|
if ($table !== null)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(string $table): self
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a subform items
|
||||||
|
*
|
||||||
|
* @param string $linkValue The value of the link key in child table.
|
||||||
|
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||||
|
* @param string $field The parent field name of the subform in the parent view.
|
||||||
|
* @param array $get The array get:set of the keys of each row in the subform.
|
||||||
|
*
|
||||||
|
* @return array|null The subform
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function get(string $linkValue, string $linkKey, string $field, array $get): ?array
|
||||||
|
{
|
||||||
|
if (($items = $this->items->table($this->getTable())->get([$linkValue], $linkKey)) !== null)
|
||||||
|
{
|
||||||
|
return $this->converter($items, $get, $field);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a subform items
|
||||||
|
*
|
||||||
|
* @param array $items The list of items from the subform to set
|
||||||
|
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete.
|
||||||
|
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||||
|
* @param string $linkValue The value of the link key in child table.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function set(array $items, string $indexKey, string $linkKey, string $linkValue): bool
|
||||||
|
{
|
||||||
|
$items = $this->process($items, $indexKey, $linkKey, $linkValue);
|
||||||
|
|
||||||
|
$this->purge($items, $indexKey, $linkKey, $linkValue);
|
||||||
|
|
||||||
|
return $this->items->table($this->getTable())->set(
|
||||||
|
$items, $indexKey
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string
|
||||||
|
{
|
||||||
|
return $this->table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purge all items no longer in subform
|
||||||
|
*
|
||||||
|
* @param array $items The list of items to set.
|
||||||
|
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete
|
||||||
|
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||||
|
* @param string $linkValue The value of the link key in child table.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function purge(array $items, string $indexKey, string $linkKey, string $linkValue): void
|
||||||
|
{
|
||||||
|
// Get the current index values from the database
|
||||||
|
$currentIndexValues = $this->items->table($this->getTable())->values([$linkValue], $linkKey, $indexKey);
|
||||||
|
|
||||||
|
if ($currentIndexValues !== null)
|
||||||
|
{
|
||||||
|
// Extract the index values from the items array
|
||||||
|
$activeIndexValues = array_values(array_map(function($item) use ($indexKey) {
|
||||||
|
return $item[$indexKey] ?? null;
|
||||||
|
}, $items));
|
||||||
|
|
||||||
|
// Find the index values that are no longer in the items array
|
||||||
|
$inactiveIndexValues = array_diff($currentIndexValues, $activeIndexValues);
|
||||||
|
|
||||||
|
// Delete the inactive index values
|
||||||
|
if (!empty($inactiveIndexValues))
|
||||||
|
{
|
||||||
|
$this->items->table($this->getTable())->delete($inactiveIndexValues, $indexKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the specified keys from an array of objects or arrays, converts them to arrays,
|
||||||
|
* and sets them by association with a specified key and an incrementing integer.
|
||||||
|
*
|
||||||
|
* @param array $items Array of objects or arrays to be filtered.
|
||||||
|
* @param array $keySet Array of keys to retain in each item.
|
||||||
|
* @param string $field The field prefix for the resulting associative array.
|
||||||
|
*
|
||||||
|
* @return array Array of filtered arrays set by association.
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function converter(array $items, array $keySet, string $field): array
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Filters keys for a single item and converts it to an array.
|
||||||
|
*
|
||||||
|
* @param object|array $item The item to filter.
|
||||||
|
* @param array $keySet The keys to retain.
|
||||||
|
*
|
||||||
|
* @return array The filtered array.
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
$filterKeys = function ($item, array $keySet) {
|
||||||
|
$filteredArray = [];
|
||||||
|
foreach ($keySet as $key) {
|
||||||
|
if (is_object($item) && property_exists($item, $key)) {
|
||||||
|
$filteredArray[$key] = $item->{$key};
|
||||||
|
} elseif (is_array($item) && array_key_exists($key, $item)) {
|
||||||
|
$filteredArray[$key] = $item[$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $filteredArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
foreach ($items as $index => $item)
|
||||||
|
{
|
||||||
|
$filteredArray = $filterKeys($item, $keySet);
|
||||||
|
$result[$field . $index] = $filteredArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes an array of arrays based on the specified key.
|
||||||
|
*
|
||||||
|
* @param array $items Array of arrays to be processed.
|
||||||
|
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete
|
||||||
|
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||||
|
* @param string $linkValue The value of the link key in child table.
|
||||||
|
*
|
||||||
|
* @return array The processed array of arrays.
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
private function process(array $items, string $indexKey, string $linkKey, string $linkValue): array
|
||||||
|
{
|
||||||
|
foreach ($items as &$item)
|
||||||
|
{
|
||||||
|
$value = $item[$indexKey] ?? '';
|
||||||
|
switch ($indexKey) {
|
||||||
|
case 'guid':
|
||||||
|
if (empty($value))
|
||||||
|
{
|
||||||
|
// set INDEX
|
||||||
|
$item[$indexKey] = $this->setGuid($indexKey);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'id':
|
||||||
|
if (empty($value))
|
||||||
|
{
|
||||||
|
$item[$indexKey] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// No action for other keys if empty
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// set LINK
|
||||||
|
$item[$linkKey] = $linkValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values($items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a GUIDv4 string
|
||||||
|
*
|
||||||
|
* Thanks to Dave Pearson (and other)
|
||||||
|
* https://www.php.net/manual/en/function.com-create-guid.php#119168
|
||||||
|
*
|
||||||
|
* Uses the best cryptographically secure method
|
||||||
|
* for all supported platforms with fallback to an older,
|
||||||
|
* less secure version.
|
||||||
|
*
|
||||||
|
* @param string $key The key to check and modify values.
|
||||||
|
* @param bool $trim
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
private function setGuid(string $key, bool $trim = true): string
|
||||||
|
{
|
||||||
|
// Windows
|
||||||
|
if (function_exists('com_create_guid'))
|
||||||
|
{
|
||||||
|
if ($trim)
|
||||||
|
{
|
||||||
|
return trim(\com_create_guid(), '{}');
|
||||||
|
}
|
||||||
|
return \com_create_guid();
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the braces if needed
|
||||||
|
$lbrace = $trim ? "" : chr(123); // "{"
|
||||||
|
$rbrace = $trim ? "" : chr(125); // "}"
|
||||||
|
|
||||||
|
// OSX/Linux
|
||||||
|
if (function_exists('openssl_random_pseudo_bytes'))
|
||||||
|
{
|
||||||
|
$data = \openssl_random_pseudo_bytes(16);
|
||||||
|
$data[6] = chr( ord($data[6]) & 0x0f | 0x40); // set version to 0100
|
||||||
|
$data[8] = chr( ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
|
||||||
|
return $lbrace . vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)) . $lbrace;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback (PHP 4.2+)
|
||||||
|
mt_srand((double) microtime() * 10000);
|
||||||
|
$charid = strtolower( md5( uniqid( rand(), true)));
|
||||||
|
$hyphen = chr(45); // "-"
|
||||||
|
$guidv4 = $lbrace.
|
||||||
|
substr($charid, 0, 8). $hyphen.
|
||||||
|
substr($charid, 8, 4). $hyphen.
|
||||||
|
substr($charid, 12, 4). $hyphen.
|
||||||
|
substr($charid, 16, 4). $hyphen.
|
||||||
|
substr($charid, 20, 12).
|
||||||
|
$rbrace;
|
||||||
|
|
||||||
|
// check that it does not already exist (one in a billion chance ;)
|
||||||
|
// but we do it any way...
|
||||||
|
if ($this->items->table($this->getTable())->values([$guidv4], $key))
|
||||||
|
{
|
||||||
|
return $this->setGuid($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $guidv4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
132
src/VastDevelopmentMethod/Joomla/Database/Delete.php
Normal file
132
src/VastDevelopmentMethod/Joomla/Database/Delete.php
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Database;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\ArrayHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\DeleteInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Abstraction\Database;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Delete Class
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
final class Delete extends Database implements DeleteInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Delete all items in the database that match these conditions
|
||||||
|
*
|
||||||
|
* @param array $conditions Conditions by which to delete the data in database [array of arrays (key => value)]
|
||||||
|
* @param string $table The table where the data is being deleted
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
public function items(array $conditions, string $table): bool
|
||||||
|
{
|
||||||
|
// set the update columns
|
||||||
|
if ($conditions === [])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a query object
|
||||||
|
$query = $this->db->getQuery(true);
|
||||||
|
|
||||||
|
// start the conditions bucket
|
||||||
|
$_conditions = [];
|
||||||
|
foreach ($conditions as $key => $value)
|
||||||
|
{
|
||||||
|
if (ArrayHelper::check($value))
|
||||||
|
{
|
||||||
|
if (isset($value['value']) && isset($value['operator']))
|
||||||
|
{
|
||||||
|
// check if value needs to be quoted
|
||||||
|
$quote = $value['quote'] ?? true;
|
||||||
|
if (!$quote)
|
||||||
|
{
|
||||||
|
if (ArrayHelper::check($value['value']))
|
||||||
|
{
|
||||||
|
// add the where by array
|
||||||
|
$_conditions[] = $this->db->quoteName($key)
|
||||||
|
. ' ' . $value['operator']
|
||||||
|
. ' ' . ' (' .
|
||||||
|
implode(',', $value['value'])
|
||||||
|
. ')';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add the conditions
|
||||||
|
$_conditions[] = $this->db->quoteName($key)
|
||||||
|
. ' ' . $value['operator']
|
||||||
|
. ' ' . $value['value'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ArrayHelper::check($value['value']))
|
||||||
|
{
|
||||||
|
// add the where by array
|
||||||
|
$_conditions[] = $this->db->quoteName($key)
|
||||||
|
. ' ' . $value['operator']
|
||||||
|
. ' ' . ' (' .
|
||||||
|
implode(',', array_map(fn($val) => $this->quote($val), $value['value']))
|
||||||
|
. ')';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add the conditions
|
||||||
|
$_conditions[] = $this->db->quoteName($key)
|
||||||
|
. ' ' . $value['operator']
|
||||||
|
. ' ' . $this->quote($value['value']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we should through an exception
|
||||||
|
// for security we just return false for now
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add default condition
|
||||||
|
$_conditions[] = $this->db->quoteName($key) . ' = ' . $this->quote($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the query targets
|
||||||
|
$query->delete($this->db->quoteName($this->getTable($table)));
|
||||||
|
$query->where($_conditions);
|
||||||
|
|
||||||
|
$this->db->setQuery($query);
|
||||||
|
|
||||||
|
return $this->db->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncate a table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be truncated
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
public function truncate(string $table): void
|
||||||
|
{
|
||||||
|
$this->db->truncateTable($this->getTable($table));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
290
src/VastDevelopmentMethod/Joomla/Database/Insert.php
Normal file
290
src/VastDevelopmentMethod/Joomla/Database/Insert.php
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Database;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\CMS\Date\Date;
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\ArrayHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\InsertInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Abstraction\Database;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Insert Class
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
final class Insert extends Database implements InsertInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Switch to set the defaults
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
* @since 1.2.0
|
||||||
|
**/
|
||||||
|
protected bool $defaults = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch to prevent/allow defaults from being added.
|
||||||
|
*
|
||||||
|
* @param bool $trigger toggle the defaults
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function defaults(bool $trigger = true)
|
||||||
|
{
|
||||||
|
$this->defaults = $trigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert rows to the database (with remapping and filtering columns option)
|
||||||
|
*
|
||||||
|
* @param array $data Dataset to store in database [array of arrays (key => value)]
|
||||||
|
* @param string $table The table where the data is being added
|
||||||
|
* @param array $columns Data columns for remapping and filtering
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function rows(array $data, string $table, array $columns = []): bool
|
||||||
|
{
|
||||||
|
if (!ArrayHelper::check($data))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($columns === [])
|
||||||
|
{
|
||||||
|
$columns = $this->getArrayColumns($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($columns === []) ? false : $this->insert($data, $table, $columns, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert items to the database (with remapping and filtering columns option)
|
||||||
|
*
|
||||||
|
* @param array $data Data to store in database (array of objects)
|
||||||
|
* @param string $table The table where the data is being added
|
||||||
|
* @param array $columns Data columns for remapping and filtering
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function items(array $data, string $table, array $columns = []): bool
|
||||||
|
{
|
||||||
|
if (!ArrayHelper::check($data))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($columns === [])
|
||||||
|
{
|
||||||
|
$columns = $this->getObjectsColumns($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($columns === []) ? false : $this->insert($data, $table, $columns, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert row to the database
|
||||||
|
*
|
||||||
|
* @param array $data Dataset to store in database (key => value)
|
||||||
|
* @param string $table The table where the data is being added
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function row(array $data, string $table): bool
|
||||||
|
{
|
||||||
|
return $this->rows([$data], $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert item to the database
|
||||||
|
*
|
||||||
|
* @param object $data Dataset to store in database (key => value)
|
||||||
|
* @param string $table The table where the data is being added
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function item(object $data, string $table): bool
|
||||||
|
{
|
||||||
|
return $this->items([$data], $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get columns from data array
|
||||||
|
*
|
||||||
|
* @param array $data Data array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
protected function getArrayColumns(array &$data): array
|
||||||
|
{
|
||||||
|
$row = array_values($data)[0];
|
||||||
|
|
||||||
|
if (!ArrayHelper::check($row))
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = array_keys($row);
|
||||||
|
|
||||||
|
return array_combine($columns, $columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get columns from data objects
|
||||||
|
*
|
||||||
|
* @param array $data Data objects
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
protected function getObjectsColumns(array &$data): array
|
||||||
|
{
|
||||||
|
$row = array_values($data)[0];
|
||||||
|
|
||||||
|
if (!is_object($row))
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = get_object_vars($row);
|
||||||
|
|
||||||
|
return array_combine(array_keys($columns), array_keys($columns));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert data into the database
|
||||||
|
*
|
||||||
|
* @param array $data Data to store in database
|
||||||
|
* @param string $table The table where the data is being added
|
||||||
|
* @param array $columns Data columns for remapping and filtering
|
||||||
|
* @param bool $isArray Whether the data is an array of arrays or an array of objects
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
protected function insert(array &$data, string $table, array $columns, bool $isArray): bool
|
||||||
|
{
|
||||||
|
// set joomla default columns
|
||||||
|
$add_created = false;
|
||||||
|
$add_version = false;
|
||||||
|
$add_published = false;
|
||||||
|
|
||||||
|
// check if we should load the defaults
|
||||||
|
if ($this->defaults)
|
||||||
|
{
|
||||||
|
// get the date
|
||||||
|
$date = (new Date())->toSql();
|
||||||
|
|
||||||
|
if (!isset($columns['created']))
|
||||||
|
{
|
||||||
|
$columns['created'] = ' (o_O) ';
|
||||||
|
$add_created = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($columns['version']))
|
||||||
|
{
|
||||||
|
$columns['version'] = ' (o_O) ';
|
||||||
|
$add_version = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($columns['published']))
|
||||||
|
{
|
||||||
|
$columns['published'] = ' (o_O) ';
|
||||||
|
$add_published = true;
|
||||||
|
}
|
||||||
|
// the (o_O) prevents an empty value from being loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a query object
|
||||||
|
$query = $this->db->getQuery(true);
|
||||||
|
|
||||||
|
// set the query targets
|
||||||
|
$query->insert($this->db->quoteName($this->getTable($table)))->columns($this->db->quoteName(array_keys($columns)));
|
||||||
|
|
||||||
|
// limiting factor on the amount of rows to insert before we reset the query
|
||||||
|
$limit = 300;
|
||||||
|
|
||||||
|
// set the insert values
|
||||||
|
foreach ($data as $nr => $value)
|
||||||
|
{
|
||||||
|
// check the limit
|
||||||
|
if ($limit <= 1)
|
||||||
|
{
|
||||||
|
// execute and reset the query
|
||||||
|
$this->db->setQuery($query);
|
||||||
|
$this->db->execute();
|
||||||
|
|
||||||
|
// reset limit
|
||||||
|
$limit = 300;
|
||||||
|
|
||||||
|
// get a query object
|
||||||
|
$query = $this->db->getQuery(true);
|
||||||
|
|
||||||
|
// set the query targets
|
||||||
|
$query->insert($this->db->quoteName($this->getTable($table)))->columns($this->db->quoteName(array_keys($columns)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = [];
|
||||||
|
foreach ($columns as $column => $key)
|
||||||
|
{
|
||||||
|
if (' (o_O) ' !== $key)
|
||||||
|
{
|
||||||
|
$row[] = ($isArray && isset($value[$key])) ? $this->quote($value[$key])
|
||||||
|
: ((!$isArray && isset($value->{$key})) ? $this->quote($value->{$key}) : '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set joomla default columns
|
||||||
|
if ($add_created)
|
||||||
|
{
|
||||||
|
$row[] = $this->db->quote($date);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($add_version)
|
||||||
|
{
|
||||||
|
$row[] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($add_published)
|
||||||
|
{
|
||||||
|
$row[] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to query
|
||||||
|
$query->values(implode(',', $row));
|
||||||
|
|
||||||
|
// decrement the limiter
|
||||||
|
$limit--;
|
||||||
|
|
||||||
|
// clear the data from memory
|
||||||
|
unset($data[$nr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the final query
|
||||||
|
$this->db->setQuery($query);
|
||||||
|
$this->db->execute();
|
||||||
|
|
||||||
|
// always reset the default switch
|
||||||
|
$this->defaults();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
502
src/VastDevelopmentMethod/Joomla/Database/Load.php
Normal file
502
src/VastDevelopmentMethod/Joomla/Database/Load.php
Normal file
@ -0,0 +1,502 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Database;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\ArrayHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\LoadInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Abstraction\Database;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Load
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
final class Load extends Database implements LoadInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Load data rows as an array of associated arrays
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
* @param int|null $limit Limit the number of values returned
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function rows(array $select, array $tables, ?array $where = null,
|
||||||
|
?array $order = null, ?int $limit = null): ?array
|
||||||
|
{
|
||||||
|
// set key if found
|
||||||
|
$key = $this->getKey($select);
|
||||||
|
|
||||||
|
// check if we can get many rows
|
||||||
|
if ($this->many($select, $tables, $where, $order, $limit))
|
||||||
|
{
|
||||||
|
// return associated arrays from the table records
|
||||||
|
return $this->db->loadAssocList($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load data rows as an array of objects
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
* @param int|null $limit Limit the number of values returned
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function items(array $select, array $tables, ?array $where = null,
|
||||||
|
?array $order = null, ?int $limit = null): ?array
|
||||||
|
{
|
||||||
|
// set key if found
|
||||||
|
$key = $this->getKey($select);
|
||||||
|
|
||||||
|
// check if we can get many rows
|
||||||
|
if ($this->many($select, $tables, $where, $order, $limit))
|
||||||
|
{
|
||||||
|
// return associated arrays from the table records
|
||||||
|
return $this->db->loadObjectList($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load data row as an associated array
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function row(array $select, array $tables, ?array $where = null, ?array $order = null): ?array
|
||||||
|
{
|
||||||
|
// check if we can get one row
|
||||||
|
if ($this->one($select, $tables, $where, $order))
|
||||||
|
{
|
||||||
|
return $this->db->loadAssoc();
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load data row as an object
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
*
|
||||||
|
* @return object|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function item(array $select, array $tables, ?array $where = null, ?array $order = null): ?object
|
||||||
|
{
|
||||||
|
// check if we can get one row
|
||||||
|
if ($this->one($select, $tables, $where, $order))
|
||||||
|
{
|
||||||
|
return $this->db->loadObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the max value based on a filtered result from a given table
|
||||||
|
*
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string $tables The tables
|
||||||
|
* @param array $filter The filter keys
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function max($field, array $tables, array $filter): ?int
|
||||||
|
{
|
||||||
|
// only do check if we have the table set
|
||||||
|
if (isset($tables['a']))
|
||||||
|
{
|
||||||
|
// get the query
|
||||||
|
$query = $this->query(["all" => "MAX(`$field`)"], $tables, $filter);
|
||||||
|
|
||||||
|
// Load the max number
|
||||||
|
$this->db->setQuery($query);
|
||||||
|
$this->db->execute();
|
||||||
|
|
||||||
|
// check if we have values
|
||||||
|
if ($this->db->getNumRows())
|
||||||
|
{
|
||||||
|
return (int) $this->db->loadResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the number of items based on filter result from a given table
|
||||||
|
*
|
||||||
|
* @param string $tables The table
|
||||||
|
* @param array $filter The filter keys
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function count(array $tables, array $filter): ?int
|
||||||
|
{
|
||||||
|
// only do check if we have the table set
|
||||||
|
if (isset($tables['a']))
|
||||||
|
{
|
||||||
|
// get the query
|
||||||
|
$query = $this->query(["all" => 'COUNT(*)'], $tables, $filter);
|
||||||
|
|
||||||
|
// Load the max number
|
||||||
|
$this->db->setQuery($query);
|
||||||
|
$this->db->execute();
|
||||||
|
|
||||||
|
// check if we have values
|
||||||
|
if ($this->db->getNumRows())
|
||||||
|
{
|
||||||
|
return (int) $this->db->loadResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load one value from a row
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function value(array $select, array $tables, ?array $where = null, ?array $order = null)
|
||||||
|
{
|
||||||
|
// check if we can get one value
|
||||||
|
if ($this->one($select, $tables, $where, $order))
|
||||||
|
{
|
||||||
|
return $this->db->loadResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load values from multiple rows
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
* @param int|null $limit Limit the number of values returned
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
public function values(array $select, array $tables, ?array $where = null,
|
||||||
|
?array $order = null, ?int $limit = null): ?array
|
||||||
|
{
|
||||||
|
// check if we can get many rows
|
||||||
|
if ($this->many($select, $tables, $where, $order, $limit))
|
||||||
|
{
|
||||||
|
return $this->db->loadColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load many
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
* @param int|null $limit Limit the number of values returned
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
protected function many(array $select, array $tables, ?array $where = null,
|
||||||
|
?array $order = null, ?int $limit = null): bool
|
||||||
|
{
|
||||||
|
// only do check if we have the table set
|
||||||
|
if (isset($tables['a']))
|
||||||
|
{
|
||||||
|
// get the query
|
||||||
|
$query = $this->query($select, $tables, $where, $order, $limit);
|
||||||
|
|
||||||
|
// Load the items
|
||||||
|
$this->db->setQuery($query);
|
||||||
|
$this->db->execute();
|
||||||
|
|
||||||
|
// check if we have values
|
||||||
|
if ($this->db->getNumRows())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load one
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
protected function one(array $select, array $tables, ?array $where = null, ?array $order = null): bool
|
||||||
|
{
|
||||||
|
// only do check if we have the table set
|
||||||
|
if (isset($tables['a']))
|
||||||
|
{
|
||||||
|
// get the query
|
||||||
|
$query = $this->query($select, $tables, $where, $order);
|
||||||
|
|
||||||
|
// Load the item
|
||||||
|
$this->db->setQuery($query, 0, 1);
|
||||||
|
$this->db->execute();
|
||||||
|
|
||||||
|
// check if we have values
|
||||||
|
if ($this->db->getNumRows())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// data does not exist
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the query object
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
* @param int|null $limit Limit the number of values returned
|
||||||
|
*
|
||||||
|
* @return object|null The query object (DatabaseQuery)
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
protected function query(array $select, array $tables, ?array $where = null,
|
||||||
|
?array $order = null, ?int $limit = null): ?object
|
||||||
|
{
|
||||||
|
$query = $this->db->getQuery(true);
|
||||||
|
|
||||||
|
// check if we have an all selection set
|
||||||
|
if (isset($select['all']))
|
||||||
|
{
|
||||||
|
// all selection example array: ['all' => ['a.*', 'b.*']]
|
||||||
|
if (ArrayHelper::check($select['all']))
|
||||||
|
{
|
||||||
|
foreach ($select['all'] as $select_all)
|
||||||
|
{
|
||||||
|
// set target selection
|
||||||
|
$query->select(
|
||||||
|
$select_all
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// all selection example string: ['all' =>'a.*']
|
||||||
|
elseif (is_string($select['all']))
|
||||||
|
{
|
||||||
|
// set target selection
|
||||||
|
$query->select(
|
||||||
|
$select['all']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
unset($select['all']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the table where join
|
||||||
|
if (ArrayHelper::check($select))
|
||||||
|
{
|
||||||
|
// set target selection
|
||||||
|
$query->select(
|
||||||
|
$this->db->quoteName(
|
||||||
|
array_keys($select),
|
||||||
|
array_values($select)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set main table
|
||||||
|
$query->from($this->db->quoteName($this->getTable($tables['a']), 'a'));
|
||||||
|
|
||||||
|
// remove main table
|
||||||
|
unset($tables['a']);
|
||||||
|
|
||||||
|
// load the table where join
|
||||||
|
if (ArrayHelper::check($tables))
|
||||||
|
{
|
||||||
|
foreach ($tables as $as => $table)
|
||||||
|
{
|
||||||
|
$query->join(
|
||||||
|
'LEFT', $this->db->quoteName(
|
||||||
|
$this->getTable($table['name']), $as
|
||||||
|
) . ' ON (' . $this->db->quoteName($table['join_on'])
|
||||||
|
. ' = ' . $this->db->quoteName($table['as_on']) . ')'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the table where getters
|
||||||
|
if (ArrayHelper::check($where))
|
||||||
|
{
|
||||||
|
foreach ($where as $key => $value)
|
||||||
|
{
|
||||||
|
if (ArrayHelper::check($value))
|
||||||
|
{
|
||||||
|
if (isset($value['value']) && isset($value['operator']))
|
||||||
|
{
|
||||||
|
// check if value needs to be quoted
|
||||||
|
$quote = $value['quote'] ?? true;
|
||||||
|
if (!$quote)
|
||||||
|
{
|
||||||
|
if (ArrayHelper::check($value['value']))
|
||||||
|
{
|
||||||
|
// add the where by array
|
||||||
|
$query->where($this->db->quoteName($key) . ' ' .
|
||||||
|
$value['operator'] . ' (' .
|
||||||
|
implode(',', $value['value'])
|
||||||
|
. ')'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add the where
|
||||||
|
$query->where($this->db->quoteName($key) . ' ' .
|
||||||
|
$value['operator'] . ' ' . $value['value']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ArrayHelper::check($value['value']))
|
||||||
|
{
|
||||||
|
// add the where by array
|
||||||
|
$query->where($this->db->quoteName($key) . ' ' .
|
||||||
|
$value['operator'] . ' (' .
|
||||||
|
implode(',',
|
||||||
|
array_map(
|
||||||
|
fn($val) => $this->quote($val),
|
||||||
|
$value['value']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
. ')'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add the where
|
||||||
|
$query->where($this->db->quoteName($key) . ' ' .
|
||||||
|
$value['operator'] . ' ' . $this->quote($value['value']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we should through an exception
|
||||||
|
// for security we just return nothing for now
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add the where
|
||||||
|
$query->where($this->db->quoteName($key) .
|
||||||
|
' = ' . $this->quote($value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the row ordering
|
||||||
|
if (ArrayHelper::check($order))
|
||||||
|
{
|
||||||
|
foreach ($order as $key => $direction)
|
||||||
|
{
|
||||||
|
// add the ordering
|
||||||
|
$query->order($this->db->quoteName($key) .
|
||||||
|
' ' . $direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only return a limited number
|
||||||
|
if (is_numeric($limit))
|
||||||
|
{
|
||||||
|
$query->setLimit($limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the key from the selection array.
|
||||||
|
*
|
||||||
|
* This function retrieves a key from the provided selection array.
|
||||||
|
* The key is removed from the array after being retrieved.
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys.
|
||||||
|
*
|
||||||
|
* @return string|null The key, or null if no key is found.
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
protected function getKey(array &$select): ?string
|
||||||
|
{
|
||||||
|
$key = null;
|
||||||
|
|
||||||
|
// Check for 'key' first and ensure it's a string.
|
||||||
|
if (isset($select['key']) && is_string($select['key']))
|
||||||
|
{
|
||||||
|
$key = $select['key'];
|
||||||
|
unset($select['key']); // Remove 'key' from the array.
|
||||||
|
}
|
||||||
|
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
188
src/VastDevelopmentMethod/Joomla/Database/Update.php
Normal file
188
src/VastDevelopmentMethod/Joomla/Database/Update.php
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Database;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\UpdateInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Abstraction\Database;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Update Class
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
final class Update extends Database implements UpdateInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Update rows in the database (with remapping and filtering columns option)
|
||||||
|
*
|
||||||
|
* @param array $data Dataset to update in database [array of arrays (key => value)]
|
||||||
|
* @param string $key Dataset key column to use in updating the values in the Database
|
||||||
|
* @param string $table The table where the data is being updated
|
||||||
|
* @param array $columns Data columns for remapping and filtering
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function rows(array $data, string $key, string $table, array $columns = []): bool
|
||||||
|
{
|
||||||
|
// set the update columns
|
||||||
|
if ($data === [] || strlen($key) == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the update values
|
||||||
|
foreach ($data as $values)
|
||||||
|
{
|
||||||
|
if ($columns !== [])
|
||||||
|
{
|
||||||
|
// load only what is part of the columns set
|
||||||
|
$row = [];
|
||||||
|
foreach ($columns as $column => $key_)
|
||||||
|
{
|
||||||
|
if (isset($values[$key_]))
|
||||||
|
{
|
||||||
|
$row[$column] = $values[$key_];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the row
|
||||||
|
$this->row($row, $key, $table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// update the row
|
||||||
|
$this->row((array) $values, $key, $table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update items in the database (with remapping and filtering columns option)
|
||||||
|
*
|
||||||
|
* @param array $data Data to updated in database (array of objects)
|
||||||
|
* @param string $key Dataset key column to use in updating the values in the Database
|
||||||
|
* @param string $table The table where the data is being update
|
||||||
|
* @param array $columns Data columns for remapping and filtering
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function items(array $data, string $key, string $table, array $columns = []): bool
|
||||||
|
{
|
||||||
|
// set the update columns
|
||||||
|
if ($data === [] || strlen($key) == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the update values
|
||||||
|
foreach ($data as $nr => $values)
|
||||||
|
{
|
||||||
|
if ($columns !== [])
|
||||||
|
{
|
||||||
|
// load only what is part of the columns set
|
||||||
|
$row = [];
|
||||||
|
foreach ($columns as $column => $key_)
|
||||||
|
{
|
||||||
|
if (isset($values->{$key_}))
|
||||||
|
{
|
||||||
|
$row[$column] = $values->{$key_};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the row
|
||||||
|
$this->row($row, $key, $table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// update the row
|
||||||
|
$this->row((array) $values, $key, $table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update row in the database
|
||||||
|
*
|
||||||
|
* @param array $data Dataset to update in database (key => value)
|
||||||
|
* @param string $key Dataset key column to use in updating the values in the Database
|
||||||
|
* @param string $table The table where the data is being updated
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function row(array $data, string $key, string $table): bool
|
||||||
|
{
|
||||||
|
// set the update columns
|
||||||
|
if ($data === [] || strlen($key) == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a query object
|
||||||
|
$query = $this->db->getQuery(true);
|
||||||
|
|
||||||
|
// set the query targets
|
||||||
|
$query->update($this->db->quoteName($this->getTable($table)));
|
||||||
|
|
||||||
|
// set the update values
|
||||||
|
$key_ = null;
|
||||||
|
foreach ($data as $column => $value)
|
||||||
|
{
|
||||||
|
if ($column === $key)
|
||||||
|
{
|
||||||
|
$key_ = $value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$query->set($this->db->quoteName($column) . ' = ' . $this->quote($value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the key condition
|
||||||
|
if ($key_ !== null)
|
||||||
|
{
|
||||||
|
$query->where($this->db->quoteName($key) . ' = ' . $this->quote($key_));
|
||||||
|
|
||||||
|
// execute the final query
|
||||||
|
$this->db->setQuery($query);
|
||||||
|
|
||||||
|
return $this->db->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update item in the database
|
||||||
|
*
|
||||||
|
* @param object $data Dataset to update in database (key => value)
|
||||||
|
* @param string $key Dataset key column to use in updating the values in the Database
|
||||||
|
* @param string $table The table where the data is being updated
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function item(object $data, string $key, string $table): bool
|
||||||
|
{
|
||||||
|
// convert to an array
|
||||||
|
return $this->row((array) get_object_vars($data), $key, $table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces\Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Delete
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
interface DeleteInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string|null $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(?string $table): self;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all items in the database that match these conditions
|
||||||
|
*
|
||||||
|
* @param array $conditions Conditions by which to delete the data in database [array of arrays (key => value)]
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
public function items(array $conditions): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncate a table
|
||||||
|
*
|
||||||
|
* @param string|null $table The table that should be truncated
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
public function truncate(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces\Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Insert
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
interface InsertInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string|null $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(?string $table): self;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a value to a given table
|
||||||
|
* Example: $this->value(Value, 'value_key', 'GUID');
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string $keyValue The key value
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function value($value, string $field, string $keyValue, string $key = 'guid'): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert single row with multiple values to a given table
|
||||||
|
* Example: $this->item(Array);
|
||||||
|
*
|
||||||
|
* @param array $item The item to save
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function row(array $item): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert multiple rows to a given table
|
||||||
|
* Example: $this->items(Array);
|
||||||
|
*
|
||||||
|
* @param array|null $items The items updated in database (array of arrays)
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function rows(?array $items): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert single item with multiple values to a given table
|
||||||
|
* Example: $this->item(Object);
|
||||||
|
*
|
||||||
|
* @param object $item The item to save
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function item(object $item): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert multiple items to a given table
|
||||||
|
* Example: $this->items(Array);
|
||||||
|
*
|
||||||
|
* @param array|null $items The items updated in database (array of objects)
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function items(?array $items): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces\Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Item Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
interface ItemInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(string $table): self;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an item
|
||||||
|
*
|
||||||
|
* @param string $value The item key value
|
||||||
|
* @param string $key The item key
|
||||||
|
*
|
||||||
|
* @return object|null The item object or null
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function get(string $value, string $key = 'guid'): ?object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value
|
||||||
|
*
|
||||||
|
* @param string $value The item key value
|
||||||
|
* @param string $key The item key
|
||||||
|
* @param string $get The key of the values we want back
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function value(string $value, string $key = 'guid', string $get = 'id');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an item
|
||||||
|
*
|
||||||
|
* @param object $item The item
|
||||||
|
* @param string $key The item key
|
||||||
|
* @param string|null $action The action to load power
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function set(object $item, string $key = 'guid', ?string $action = null): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an item
|
||||||
|
*
|
||||||
|
* @param string $value The item key value
|
||||||
|
* @param string $key The item key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function delete(string $value, string $key = 'guid'): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces\Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Items Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
interface ItemsInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(string $table): self;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of items
|
||||||
|
*
|
||||||
|
* @param array $values The ids of the items
|
||||||
|
* @param string $key The key of the values
|
||||||
|
*
|
||||||
|
* @return array|null The item object or null
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function get(array $values, string $key = 'guid'): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the values
|
||||||
|
*
|
||||||
|
* @param array $values The list of values (to search by).
|
||||||
|
* @param string $key The key on which the values being searched.
|
||||||
|
* @param string $get The key of the values we want back
|
||||||
|
*
|
||||||
|
* @return array|null The array of found values.
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function values(array $values, string $key = 'guid', string $get = 'id'): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set items
|
||||||
|
*
|
||||||
|
* @param array $items The list of items
|
||||||
|
* @param string $key The key on which the items should be set
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function set(array $items, string $key = 'guid'): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete items
|
||||||
|
*
|
||||||
|
* @param array $values The item key value
|
||||||
|
* @param string $key The item key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function delete(array $values, string $key = 'guid'): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,106 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces\Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Load Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
interface LoadInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string|null $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(?string $table): self;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value from a given table
|
||||||
|
* Example: $this->value(
|
||||||
|
* [
|
||||||
|
* 'guid' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
||||||
|
* ], 'value_key'
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @param array $keys The item keys
|
||||||
|
* @param string $field The field key
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
public function value(array $keys, string $field);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value from multiple rows from a given table
|
||||||
|
* Example: $this->values(
|
||||||
|
* [
|
||||||
|
* 'guid' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
||||||
|
* ], 'value_key'
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @param array $keys The item keys
|
||||||
|
* @param string $field The field key
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function values(array $keys, string $field): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get values from a given table
|
||||||
|
* Example: $this->item(
|
||||||
|
* [
|
||||||
|
* 'guid' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
||||||
|
* ]
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @param array $keys The item keys
|
||||||
|
*
|
||||||
|
* @return object|null
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
public function item(array $keys): ?object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get values from a given table
|
||||||
|
* Example: $this->items(
|
||||||
|
* [
|
||||||
|
* 'guid' => [
|
||||||
|
* 'operator' => 'IN',
|
||||||
|
* 'value' => [''xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'', ''xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'']
|
||||||
|
* ]
|
||||||
|
* ]
|
||||||
|
* );
|
||||||
|
* Example: $this->items($keys);
|
||||||
|
*
|
||||||
|
* @param array $keys The item keys
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
public function items(array $keys): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces\Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Multi Subform Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
interface MultiSubformInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get a subform items
|
||||||
|
*
|
||||||
|
* @param array $getMap The the map to get the subfrom data
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* $getMap = [
|
||||||
|
* '_core' => [
|
||||||
|
* 'table' =>'data',
|
||||||
|
* 'linkValue' => $item->guid ?? '',
|
||||||
|
* 'linkKey' => 'look',
|
||||||
|
* 'field' => 'data',
|
||||||
|
* 'get' => ['guid','email','image','mobile_phone','website','dateofbirth']
|
||||||
|
* ],
|
||||||
|
* 'countries' => [
|
||||||
|
* 'table' =>'data_country',
|
||||||
|
* 'linkValue' => 'data:guid', // coretable:fieldname
|
||||||
|
* 'linkKey' => 'data',
|
||||||
|
* 'get' => ['guid','country','currency']
|
||||||
|
* ]
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* @return array|null The subform
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function get(array $getMap): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a subform items
|
||||||
|
*
|
||||||
|
* @param array $items The list of items from the subform to set
|
||||||
|
* @param array $setMap The the map to set the subfrom data
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* $items,
|
||||||
|
* $setMap = [
|
||||||
|
* '_core' => [
|
||||||
|
* 'table' =>'data',
|
||||||
|
* 'indexKey' => 'guid',
|
||||||
|
* 'linkKey' => 'look',
|
||||||
|
* 'linkValue' => $data['guid'] ?? ''
|
||||||
|
* ],
|
||||||
|
* 'countries' => [
|
||||||
|
* 'table' =>'data_country',
|
||||||
|
* 'indexKey' => 'guid',
|
||||||
|
* 'linkKey' => 'data',
|
||||||
|
* 'linkValue' => 'data:guid' // coretable:fieldname
|
||||||
|
* ]
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function set(array $items, array $setMap): bool;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces\Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Subform Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
interface SubformInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(string $table): self;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a subform items
|
||||||
|
*
|
||||||
|
* @param string $linkValue The value of the link key in child table.
|
||||||
|
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||||
|
* @param string $field The parent field name of the subform in the parent view.
|
||||||
|
* @param array $set The array SET of the keys of each row in the subform.
|
||||||
|
*
|
||||||
|
* @return array|null The subform
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function get(string $linkValue, string $linkKey, string $field, array $set): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a subform items
|
||||||
|
*
|
||||||
|
* @param array $items The list of items from the subform to set
|
||||||
|
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete.
|
||||||
|
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||||
|
* @param string $linkValue The value of the link key in child table.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function set(array $items, string $indexKey, string $linkKey, string $linkValue): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces\Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Update
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
interface UpdateInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string|null $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(?string $table): self;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a value to a given table
|
||||||
|
* Example: $this->value(Value, 'value_key', 'GUID');
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string $keyValue The key value
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function value($value, string $field, string $keyValue, string $key = 'guid'): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update single row with multiple values to a given table
|
||||||
|
* Example: $this->item(Array);
|
||||||
|
*
|
||||||
|
* @param array $item The item to save
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function row(array $item, string $key = 'guid'): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update multiple rows to a given table
|
||||||
|
* Example: $this->items(Array);
|
||||||
|
*
|
||||||
|
* @param array|null $items The items updated in database (array of arrays)
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function rows(?array $items, string $key = 'guid'): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update single item with multiple values to a given table
|
||||||
|
* Example: $this->item(Object);
|
||||||
|
*
|
||||||
|
* @param object $item The item to save
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function item(object $item, string $key = 'guid'): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update multiple items to a given table
|
||||||
|
* Example: $this->items(Array);
|
||||||
|
*
|
||||||
|
* @param array|null $items The items updated in database (array of objects)
|
||||||
|
* @param string $key The key name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function items(?array $items, string $key = 'guid'): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(): string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Delete Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
interface DeleteInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Delete all rows in the database that match these conditions
|
||||||
|
*
|
||||||
|
* @param array $conditions Conditions by which to delete the data in database [array of arrays (key => value)]
|
||||||
|
* @param string $table The table where the data is being deleted
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function items(array $conditions, string $table): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncate a table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be truncated
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
public function truncate(string $table): void;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\DI\Container;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Container Factory Interface
|
||||||
|
*
|
||||||
|
* @since 0.0.0
|
||||||
|
*/
|
||||||
|
interface FactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get any class from the container
|
||||||
|
*
|
||||||
|
* @param string $key The container class key
|
||||||
|
*
|
||||||
|
* @return Mixed
|
||||||
|
* @since 0.0.0
|
||||||
|
*/
|
||||||
|
public static function _(string $key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the global container
|
||||||
|
*
|
||||||
|
* @return Container
|
||||||
|
* @since 0.0.0
|
||||||
|
*/
|
||||||
|
public static function getContainer(): Container;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Insert Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
interface InsertInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Switch to prevent/allow defaults from being added.
|
||||||
|
*
|
||||||
|
* @param bool $trigger toggle the defaults
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function defaults(bool $trigger = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert rows to the database (with remapping and filtering columns option)
|
||||||
|
*
|
||||||
|
* @param array $data Dataset to store in database [array of arrays (key => value)]
|
||||||
|
* @param string $table The table where the data is being added
|
||||||
|
* @param array $columns Data columns for remapping and filtering
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function rows(array $data, string $table, array $columns = []): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert items to the database (with remapping and filtering columns option)
|
||||||
|
*
|
||||||
|
* @param array $data Data to store in database (array of objects)
|
||||||
|
* @param string $table The table where the data is being added
|
||||||
|
* @param array $columns Data columns for remapping and filtering
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function items(array $data, string $table, array $columns = []): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert row to the database
|
||||||
|
*
|
||||||
|
* @param array $data Dataset to store in database (key => value)
|
||||||
|
* @param string $table The table where the data is being added
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function row(array $data, string $table): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert item to the database
|
||||||
|
*
|
||||||
|
* @param object $data Dataset to store in database (key => value)
|
||||||
|
* @param string $table The table where the data is being added
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function item(object $data, string $table): bool;
|
||||||
|
}
|
||||||
|
|
129
src/VastDevelopmentMethod/Joomla/Interfaces/LoadInterface.php
Normal file
129
src/VastDevelopmentMethod/Joomla/Interfaces/LoadInterface.php
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Load Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
interface LoadInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Load data rows as an array of associated arrays
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
* @param int|null $limit Limit the number of values returned
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function rows(array $select, array $tables, ?array $where = null,
|
||||||
|
?array $order = null, ?int $limit = null): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load data rows as an array of objects
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
* @param int|null $limit Limit the number of values returned
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function items(array $select, array $tables, ?array $where = null,
|
||||||
|
?array $order = null, ?int $limit = null): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load data row as an associated array
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function row(array $select, array $tables, ?array $where = null, ?array $order = null): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load data row as an object
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
*
|
||||||
|
* @return object|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function item(array $select, array $tables, ?array $where = null, ?array $order = null): ?object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the max value based on a filtered result from a given table
|
||||||
|
*
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string $tables The table
|
||||||
|
* @param array $filter The filter keys
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function max($field, array $tables, array $filter): ?int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the number of items based on filter result from a given table
|
||||||
|
*
|
||||||
|
* @param string $tables The table
|
||||||
|
* @param array $filter The filter keys
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function count(array $tables, array $filter): ?int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load one value from a row
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function value(array $select, array $tables, ?array $where = null, ?array $order = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load values from multiple rows
|
||||||
|
*
|
||||||
|
* @param array $select Array of selection keys
|
||||||
|
* @param array $tables Array of tables to search
|
||||||
|
* @param array|null $where Array of where key=>value match exist
|
||||||
|
* @param array|null $order Array of how to order the data
|
||||||
|
* @param int|null $limit Limit the number of values returned
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.2
|
||||||
|
**/
|
||||||
|
public function values(array $select, array $tables, ?array $where = null,
|
||||||
|
?array $order = null, ?int $limit = null): ?array;
|
||||||
|
}
|
||||||
|
|
137
src/VastDevelopmentMethod/Joomla/Interfaces/ModelInterface.php
Normal file
137
src/VastDevelopmentMethod/Joomla/Interfaces/ModelInterface.php
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
interface ModelInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $table The table that should be active
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function table(string $table): self;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the value
|
||||||
|
* Example: $this->value(value, 'value_key', 'table_name');
|
||||||
|
*
|
||||||
|
* @param mixed $value The value to model
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function value($value, string $field, ?string $table = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model a value of multiple items
|
||||||
|
* Example: $this->items(Array, 'value_key', 'table_name');
|
||||||
|
*
|
||||||
|
* @param array|null $items The array of values
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function values(?array $items = null, string $field, ?string $table = null): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the values of an item
|
||||||
|
* Example: $this->item(Object, 'table_name');
|
||||||
|
*
|
||||||
|
* @param object|null $item The item object
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return object|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function item(?object $item, ?string $table = null): ?object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the values of multiple items
|
||||||
|
* Example: $this->items(Array, 'table_name');
|
||||||
|
*
|
||||||
|
* @param array|null $items The array of item objects
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function items(?array $items = null, ?string $table = null): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the values of an row
|
||||||
|
* Example: $this->item(Array, 'table_name');
|
||||||
|
*
|
||||||
|
* @param array|null $item The item array
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function row(?array $item, ?string $table = null): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model the values of multiple rows
|
||||||
|
* Example: $this->items(Array, 'table_name');
|
||||||
|
*
|
||||||
|
* @param array|null $items The array of item array
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function rows(?array $items = null, ?string $table = null): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get last modeled ID
|
||||||
|
* Example: $this->last('table_name');
|
||||||
|
*
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function last(?string $table = null): ?int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current active table
|
||||||
|
*
|
||||||
|
* @param string $tableName The table name
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function setTable(string $tableName): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the switch to control the behaviour of empty values
|
||||||
|
*
|
||||||
|
* @param bool $allowEmpty The switch
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function setAllowEmpty(bool $allowEmpty): void;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema Checking Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.1
|
||||||
|
*/
|
||||||
|
interface SchemaInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check and update database schema for missing fields or tables.
|
||||||
|
*
|
||||||
|
* @return array The array of successful updates/actions, if empty no update/action was taken.
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If there is an error during the update process.
|
||||||
|
*/
|
||||||
|
public function update(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a table with all necessary fields.
|
||||||
|
*
|
||||||
|
* @param string $table The name of the table to create.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If there is an error creating the table.
|
||||||
|
*/
|
||||||
|
public function createTable(string $table): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the schema of an existing table.
|
||||||
|
*
|
||||||
|
* @param string $table The table to update.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.1
|
||||||
|
* @throws \Exception If there is an error while updating the schema.
|
||||||
|
*/
|
||||||
|
public function updateSchema(string $table): void;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The VDM Core Table Interface
|
||||||
|
*/
|
||||||
|
interface Tableinterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get any value from a item/field/column of an area/view/table
|
||||||
|
* Example: $this->get('table_name', 'field_name', 'value_key');
|
||||||
|
* Get an item/field/column of an area/view/table
|
||||||
|
* Example: $this->get('table_name', 'field_name');
|
||||||
|
* Get all items/fields/columns of an area/view/table
|
||||||
|
* Example: $this->get('table_name');
|
||||||
|
* Get all areas/views/tables with all their item/field/column details
|
||||||
|
* Example: $this->get('All');
|
||||||
|
* Example: $this->get();
|
||||||
|
*
|
||||||
|
* @param string|null $table The table
|
||||||
|
* @param string|null $field The field
|
||||||
|
* @param string|null $key The value key
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function get(?string $table = null, ?string $field = null, ?string $key = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get title field from an area/view/table
|
||||||
|
*
|
||||||
|
* @param string $table The area
|
||||||
|
*
|
||||||
|
* @return ?array
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function title(string $table): ?array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get title field name
|
||||||
|
*
|
||||||
|
* @param string $table The area
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function titleName(string $table): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all tables
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function tables(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a table (and field) exist
|
||||||
|
*
|
||||||
|
* @param string $table The area
|
||||||
|
* @param string|null $field The area
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function exist(string $table, ?string $field = null): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all fields of an area/view/table
|
||||||
|
*
|
||||||
|
* @param string $table The area
|
||||||
|
* @param bool $default Add the default fields
|
||||||
|
* @param bool $details Add/Leave fields the details
|
||||||
|
*
|
||||||
|
* @return array|null On success an array of fields
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function fields(string $table, bool $default = false, bool $details = false): ?array;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Update Interface
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
interface UpdateInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Update rows in the database (with remapping and filtering columns option)
|
||||||
|
*
|
||||||
|
* @param array $data Dataset to update in database [array of arrays (key => value)]
|
||||||
|
* @param string $key Dataset key column to use in updating the values in the Database
|
||||||
|
* @param string $table The table where the data is being updated
|
||||||
|
* @param array $columns Data columns for remapping and filtering
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function rows(array $data, string $key, string $table, array $columns = []): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update items in the database (with remapping and filtering columns option)
|
||||||
|
*
|
||||||
|
* @param array $data Data to updated in database (array of objects)
|
||||||
|
* @param string $key Dataset key column to use in updating the values in the Database
|
||||||
|
* @param string $table The table where the data is being update
|
||||||
|
* @param array $columns Data columns for remapping and filtering
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function items(array $data, string $key, string $table, array $columns = []): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update row in the database
|
||||||
|
*
|
||||||
|
* @param array $data Dataset to update in database (key => value)
|
||||||
|
* @param string $key Dataset key column to use in updating the values in the Database
|
||||||
|
* @param string $table The table where the data is being updated
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function row(array $data, string $key, string $table): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update item in the database
|
||||||
|
*
|
||||||
|
* @param object $data Dataset to update in database (key => value)
|
||||||
|
* @param string $key Dataset key column to use in updating the values in the Database
|
||||||
|
* @param string $table The table where the data is being updated
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
**/
|
||||||
|
public function item(object $data, string $key, string $table): bool;
|
||||||
|
}
|
||||||
|
|
118
src/VastDevelopmentMethod/Joomla/Model/Load.php
Normal file
118
src/VastDevelopmentMethod/Joomla/Model/Load.php
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Model;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\StringHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\ArrayHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\ObjectHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\ModelInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Abstraction\Model;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Power Model Load
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
final class Load extends Model implements ModelInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Model the value
|
||||||
|
* Example: $this->value(value, 'field_key', 'table_name');
|
||||||
|
*
|
||||||
|
* @param mixed $value The value to model
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function value($value, string $field, ?string $table = null)
|
||||||
|
{
|
||||||
|
// set the table name
|
||||||
|
if (empty($table))
|
||||||
|
{
|
||||||
|
$table = $this->getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if this is a valid table
|
||||||
|
if (($store = $this->table->get($table, $field, 'store')) !== null)
|
||||||
|
{
|
||||||
|
// open the value based on the store method
|
||||||
|
switch($store)
|
||||||
|
{
|
||||||
|
case 'base64':
|
||||||
|
$value = base64_decode((string) $value);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$value = json_decode($value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate before the value is modelled
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string|null $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool
|
||||||
|
{
|
||||||
|
// only strings or numbers allowed
|
||||||
|
if (StringHelper::check($value) || is_numeric($value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// check if we allow empty
|
||||||
|
elseif ($this->getAllowEmpty() && empty($value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// remove empty values
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate after the value is modelled
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string|null $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool
|
||||||
|
{
|
||||||
|
// only strings or numbers allowed
|
||||||
|
if (StringHelper::check($value) || ArrayHelper::check($value, true) || ObjectHelper::check($value) || is_numeric($value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// check if we allow empty
|
||||||
|
elseif ($this->getAllowEmpty() && empty($value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// remove empty values
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
118
src/VastDevelopmentMethod/Joomla/Model/Upsert.php
Normal file
118
src/VastDevelopmentMethod/Joomla/Model/Upsert.php
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Model;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\StringHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\ArrayHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\ObjectHelper;
|
||||||
|
use VastDevelopmentMethod\Joomla\Interfaces\ModelInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Abstraction\Model;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Power Model Update or Insert
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
final class Upsert extends Model implements ModelInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Model the value
|
||||||
|
* Example: $this->value(value, 'field_key', 'table_name');
|
||||||
|
*
|
||||||
|
* @param mixed $value The value to model
|
||||||
|
* @param string $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function value($value, string $field, ?string $table = null)
|
||||||
|
{
|
||||||
|
// set the table name
|
||||||
|
if (empty($table))
|
||||||
|
{
|
||||||
|
$table = $this->getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if this is a valid table
|
||||||
|
if (($store = $this->table->get($table, $field, 'store')) !== null)
|
||||||
|
{
|
||||||
|
// open the value based on the store method
|
||||||
|
switch($store)
|
||||||
|
{
|
||||||
|
case 'base64':
|
||||||
|
$value = base64_encode((string) $value);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$value = json_encode($value, JSON_FORCE_OBJECT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate before the value is modelled
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string|null $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool
|
||||||
|
{
|
||||||
|
// check values
|
||||||
|
if (StringHelper::check($value) || ArrayHelper::check($value, true) || ObjectHelper::check($value) || is_numeric($value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// check if we allow empty
|
||||||
|
elseif ($this->getAllowEmpty() && empty($value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// remove empty values
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate after the value is modelled
|
||||||
|
*
|
||||||
|
* @param mixed $value The field value
|
||||||
|
* @param string|null $field The field key
|
||||||
|
* @param string|null $table The table
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool
|
||||||
|
{
|
||||||
|
// only strings or numbers allowed
|
||||||
|
if (StringHelper::check($value) || is_numeric($value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// check if we allow empty
|
||||||
|
elseif ($this->getAllowEmpty() && empty($value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// remove empty values
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
200
src/VastDevelopmentMethod/Joomla/Service/Data.php
Normal file
200
src/VastDevelopmentMethod/Joomla/Service/Data.php
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Service;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\DI\Container;
|
||||||
|
use Joomla\DI\ServiceProviderInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Data\Action\Load;
|
||||||
|
use VastDevelopmentMethod\Joomla\Data\Action\Insert;
|
||||||
|
use VastDevelopmentMethod\Joomla\Data\Action\Update;
|
||||||
|
use VastDevelopmentMethod\Joomla\Data\Action\Delete;
|
||||||
|
use VastDevelopmentMethod\Joomla\Data\Item;
|
||||||
|
use VastDevelopmentMethod\Joomla\Data\Items;
|
||||||
|
use VastDevelopmentMethod\Joomla\Data\Subform;
|
||||||
|
use VastDevelopmentMethod\Joomla\Data\MultiSubform;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Service Provider
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
class Data implements ServiceProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Registers the service provider with a DI container.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function register(Container $container)
|
||||||
|
{
|
||||||
|
$container->alias(Load::class, 'Data.Load')
|
||||||
|
->share('Data.Load', [$this, 'getLoad'], true);
|
||||||
|
|
||||||
|
$container->alias(Insert::class, 'Data.Insert')
|
||||||
|
->share('Data.Insert', [$this, 'getInsert'], true);
|
||||||
|
|
||||||
|
$container->alias(Update::class, 'Data.Update')
|
||||||
|
->share('Data.Update', [$this, 'getUpdate'], true);
|
||||||
|
|
||||||
|
$container->alias(Delete::class, 'Data.Delete')
|
||||||
|
->share('Data.Delete', [$this, 'getDelete'], true);
|
||||||
|
|
||||||
|
$container->alias(Item::class, 'Data.Item')
|
||||||
|
->share('Data.Item', [$this, 'getItem'], true);
|
||||||
|
|
||||||
|
$container->alias(Items::class, 'Data.Items')
|
||||||
|
->share('Data.Items', [$this, 'getItems'], true);
|
||||||
|
|
||||||
|
$container->alias(Subform::class, 'Data.Subform')
|
||||||
|
->share('Data.Subform', [$this, 'getSubform'], true);
|
||||||
|
|
||||||
|
$container->alias(MultiSubform::class, 'Data.MultiSubform')
|
||||||
|
->share('Data.MultiSubform', [$this, 'getMultiSubform'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Load Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Load
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getLoad(Container $container): Load
|
||||||
|
{
|
||||||
|
return new Load(
|
||||||
|
$container->get('Model.Load'),
|
||||||
|
$container->get('Load')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Insert Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Insert
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getInsert(Container $container): Insert
|
||||||
|
{
|
||||||
|
return new Insert(
|
||||||
|
$container->get('Model.Upsert'),
|
||||||
|
$container->get('Insert')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Update Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Update
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getUpdate(Container $container): Update
|
||||||
|
{
|
||||||
|
return new Update(
|
||||||
|
$container->get('Model.Upsert'),
|
||||||
|
$container->get('Update')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Delete Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Delete
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getDelete(Container $container): Delete
|
||||||
|
{
|
||||||
|
return new Delete(
|
||||||
|
$container->get('Delete')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Item Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Item
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getItem(Container $container): Item
|
||||||
|
{
|
||||||
|
return new Item(
|
||||||
|
$container->get('Data.Load'),
|
||||||
|
$container->get('Data.Insert'),
|
||||||
|
$container->get('Data.Update'),
|
||||||
|
$container->get('Data.Delete'),
|
||||||
|
$container->get('Load')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Items Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Items
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getItems(Container $container): Items
|
||||||
|
{
|
||||||
|
return new Items(
|
||||||
|
$container->get('Data.Load'),
|
||||||
|
$container->get('Data.Insert'),
|
||||||
|
$container->get('Data.Update'),
|
||||||
|
$container->get('Data.Delete'),
|
||||||
|
$container->get('Load')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Subform Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Subform
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getSubform(Container $container): Subform
|
||||||
|
{
|
||||||
|
return new Subform(
|
||||||
|
$container->get('Data.Items')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The MultiSubform Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return MultiSubform
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getMultiSubform(Container $container): MultiSubform
|
||||||
|
{
|
||||||
|
return new MultiSubform(
|
||||||
|
$container->get('Data.Subform')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
105
src/VastDevelopmentMethod/Joomla/Service/Database.php
Normal file
105
src/VastDevelopmentMethod/Joomla/Service/Database.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Service;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\DI\Container;
|
||||||
|
use Joomla\DI\ServiceProviderInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Database\Load;
|
||||||
|
use VastDevelopmentMethod\Joomla\Database\Insert;
|
||||||
|
use VastDevelopmentMethod\Joomla\Database\Update;
|
||||||
|
use VastDevelopmentMethod\Joomla\Database\Delete;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Service Provider
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
class Database implements ServiceProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Registers the service provider with a DI container.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function register(Container $container)
|
||||||
|
{
|
||||||
|
$container->alias(Load::class, 'Load')
|
||||||
|
->share('Load', [$this, 'getLoad'], true);
|
||||||
|
|
||||||
|
$container->alias(Insert::class, 'Insert')
|
||||||
|
->share('Insert', [$this, 'getInsert'], true);
|
||||||
|
|
||||||
|
$container->alias(Update::class, 'Update')
|
||||||
|
->share('Update', [$this, 'getUpdate'], true);
|
||||||
|
|
||||||
|
$container->alias(Delete::class, 'Delete')
|
||||||
|
->share('Delete', [$this, 'getDelete'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Core Load Database
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Load
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getLoad(Container $container): Load
|
||||||
|
{
|
||||||
|
return new Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Core Insert Database
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Insert
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getInsert(Container $container): Insert
|
||||||
|
{
|
||||||
|
return new Insert();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Core Update Database
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Update
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getUpdate(Container $container): Update
|
||||||
|
{
|
||||||
|
return new Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Core Delete Database
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Delete
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getDelete(Container $container): Delete
|
||||||
|
{
|
||||||
|
return new Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
75
src/VastDevelopmentMethod/Joomla/Service/Model.php
Normal file
75
src/VastDevelopmentMethod/Joomla/Service/Model.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Service;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\DI\Container;
|
||||||
|
use Joomla\DI\ServiceProviderInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Model\Load;
|
||||||
|
use VastDevelopmentMethod\Joomla\Model\Upsert;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Service Provider
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
class Model implements ServiceProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Registers the service provider with a DI container.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function register(Container $container)
|
||||||
|
{
|
||||||
|
$container->alias(Load::class, 'Model.Load')
|
||||||
|
->share('Model.Load', [$this, 'getLoad'], true);
|
||||||
|
|
||||||
|
$container->alias(Upsert::class, 'Model.Upsert')
|
||||||
|
->share('Model.Upsert', [$this, 'getUpsert'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Load Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Load
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getLoad(Container $container): Load
|
||||||
|
{
|
||||||
|
return new Load(
|
||||||
|
$container->get('Table')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Upsert Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Upsert
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public function getUpsert(Container $container): Upsert
|
||||||
|
{
|
||||||
|
return new Upsert(
|
||||||
|
$container->get('Table')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
73
src/VastDevelopmentMethod/Joomla/Service/Table.php
Normal file
73
src/VastDevelopmentMethod/Joomla/Service/Table.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 4th September, 2022
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Service;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\DI\Container;
|
||||||
|
use Joomla\DI\ServiceProviderInterface;
|
||||||
|
use VastDevelopmentMethod\Joomla\Componentbuilder\Table as DataTable;
|
||||||
|
use VastDevelopmentMethod\Joomla\Componentbuilder\Table\Schema;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table Service Provider
|
||||||
|
*
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
class Table implements ServiceProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Registers the service provider with a DI container.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function register(Container $container)
|
||||||
|
{
|
||||||
|
$container->alias(DataTable::class, 'Table')
|
||||||
|
->share('Table', [$this, 'getTable'], true);
|
||||||
|
|
||||||
|
$container->alias(Schema::class, 'Table.Schema')
|
||||||
|
->share('Table.Schema', [$this, 'getSchema'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Componentbuilder Data Table Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return DataTable
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getTable(Container $container): DataTable
|
||||||
|
{
|
||||||
|
return new DataTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get The Schema Class.
|
||||||
|
*
|
||||||
|
* @param Container $container The DI container.
|
||||||
|
*
|
||||||
|
* @return Schema
|
||||||
|
* @since 3.2.2
|
||||||
|
*/
|
||||||
|
public function getSchema(Container $container): Schema
|
||||||
|
{
|
||||||
|
return new Schema(
|
||||||
|
$container->get('Table')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
107
src/VastDevelopmentMethod/Joomla/Utilities/ArrayHelper.php
Normal file
107
src/VastDevelopmentMethod/Joomla/Utilities/ArrayHelper.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 3rd September, 2020
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Utilities;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some array tricks helper
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
abstract class ArrayHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check if have an array with a length
|
||||||
|
*
|
||||||
|
* @input array The array to check
|
||||||
|
*
|
||||||
|
* @returns int|false number of items in array on success
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public static function check($array, $removeEmptyString = false)
|
||||||
|
{
|
||||||
|
if (is_array($array) && ($nr = count((array) $array)) > 0)
|
||||||
|
{
|
||||||
|
// also make sure the empty strings are removed
|
||||||
|
if ($removeEmptyString)
|
||||||
|
{
|
||||||
|
$array = array_filter($array);
|
||||||
|
|
||||||
|
if ($array === [])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count($array);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge an array of array's
|
||||||
|
*
|
||||||
|
* @input array The arrays you would like to merge
|
||||||
|
*
|
||||||
|
* @returns array|null merged array on success
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function merge($arrays): ?array
|
||||||
|
{
|
||||||
|
if(self::check($arrays))
|
||||||
|
{
|
||||||
|
$merged = [];
|
||||||
|
foreach ($arrays as $array)
|
||||||
|
{
|
||||||
|
if (self::check($array))
|
||||||
|
{
|
||||||
|
$merged = array_merge($merged, $array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $merged;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if arrays intersect
|
||||||
|
*
|
||||||
|
* @input array The first array
|
||||||
|
* @input array The second array
|
||||||
|
*
|
||||||
|
* @returns bool true if intersect else false
|
||||||
|
*
|
||||||
|
* @since 3.1.1
|
||||||
|
*/
|
||||||
|
public static function intersect($a_array, $b_array): bool
|
||||||
|
{
|
||||||
|
// flip the second array
|
||||||
|
$b_array = array_flip($b_array);
|
||||||
|
|
||||||
|
// loop the first array
|
||||||
|
foreach ($a_array as $v)
|
||||||
|
{
|
||||||
|
if (isset($b_array[$v]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
296
src/VastDevelopmentMethod/Joomla/Utilities/Component/Helper.php
Normal file
296
src/VastDevelopmentMethod/Joomla/Utilities/Component/Helper.php
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 3rd September, 2020
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Utilities\Component;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\CMS\Factory;
|
||||||
|
use Joomla\CMS\Component\ComponentHelper;
|
||||||
|
use Joomla\Input\Input;
|
||||||
|
use Joomla\Registry\Registry;
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\String\NamespaceHelper;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some component helper
|
||||||
|
*
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
abstract class Helper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The current option
|
||||||
|
*
|
||||||
|
* @var string|null
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
public static ?string $option = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The component manifest list cache
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public static array $manifest = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The component params list cache
|
||||||
|
*
|
||||||
|
* @var Registry[]
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
protected static array $params = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the parameter object for the component
|
||||||
|
*
|
||||||
|
* @param string|null $option The option for the component.
|
||||||
|
*
|
||||||
|
* @return Registry A Registry object.
|
||||||
|
* @see Registry
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
public static function getParams(?string $option = null): Registry
|
||||||
|
{
|
||||||
|
// check that we have an option
|
||||||
|
if (empty($option))
|
||||||
|
{
|
||||||
|
$option = self::getOption();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get global value
|
||||||
|
if (!isset(self::$params[$option]) || !self::$params[$option] instanceof Registry)
|
||||||
|
{
|
||||||
|
self::$params[$option] = ComponentHelper::getParams($option);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$params[$option];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the component option
|
||||||
|
*
|
||||||
|
* @param string|null $option The option
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public static function setOption(?string $option): void
|
||||||
|
{
|
||||||
|
self::$option = $option;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the component option
|
||||||
|
*
|
||||||
|
* @param string|null $default The default return value if none is found
|
||||||
|
*
|
||||||
|
* @return string|null A component option
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
public static function getOption(?string $default = 'empty'): ?string
|
||||||
|
{
|
||||||
|
if (empty(self::$option))
|
||||||
|
{
|
||||||
|
// get the option from the url input
|
||||||
|
self::$option = (new Input)->getString('option', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty(self::$option))
|
||||||
|
{
|
||||||
|
$app = Factory::getApplication();
|
||||||
|
|
||||||
|
// Check if the getInput method exists in the application object
|
||||||
|
if (method_exists($app, 'getInput'))
|
||||||
|
{
|
||||||
|
// get the option from the application
|
||||||
|
self::$option = $app->getInput()->getCmd('option', $default);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use the default value if getInput method does not exist
|
||||||
|
self::$option = $default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$option;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the component code name
|
||||||
|
*
|
||||||
|
* @param string|null $option The option for the component.
|
||||||
|
* @param string|null $default The default return value if none is found
|
||||||
|
*
|
||||||
|
* @return string|null A component code name
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
public static function getCode(?string $option = null, ?string $default = null): ?string
|
||||||
|
{
|
||||||
|
// check that we have an option
|
||||||
|
if (empty($option))
|
||||||
|
{
|
||||||
|
$option = self::getOption();
|
||||||
|
}
|
||||||
|
// option with com_
|
||||||
|
if (is_string($option) && strpos($option, 'com_') === 0)
|
||||||
|
{
|
||||||
|
return strtolower(trim(substr($option, 4)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the component abstract helper class
|
||||||
|
*
|
||||||
|
* @param string|null $option The option for the component.
|
||||||
|
* @param string|null $default The default return value if none is found
|
||||||
|
*
|
||||||
|
* @return string|null A component helper name
|
||||||
|
*
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
public static function get(?string $option = null, ?string $default = null): ?string
|
||||||
|
{
|
||||||
|
// check that we have an option
|
||||||
|
// and get the code name from it
|
||||||
|
if (($code_name = self::getCode($option, null)) !== null)
|
||||||
|
{
|
||||||
|
// we build the helper class name
|
||||||
|
$helper_name = '\\' . \ucfirst($code_name) . 'Helper';
|
||||||
|
|
||||||
|
// check if class exist
|
||||||
|
if (class_exists($helper_name))
|
||||||
|
{
|
||||||
|
return $helper_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try loading namespace
|
||||||
|
if (($namespace = self::getNamespace($option)) !== null)
|
||||||
|
{
|
||||||
|
$name = \ucfirst($code_name) . 'Helper';
|
||||||
|
$namespace_helper = '\\' . $namespace . '\Administrator\Helper\\' . NamespaceHelper::safeSegment($name); // TODO target site or admin locations not just admin...
|
||||||
|
if (class_exists($namespace_helper))
|
||||||
|
{
|
||||||
|
return $namespace_helper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the component namespace if set
|
||||||
|
*
|
||||||
|
* @param string|null $option The option for the component.
|
||||||
|
* @param string|null $default The default return value if none is found
|
||||||
|
*
|
||||||
|
* @return string|null A component namespace
|
||||||
|
*
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
public static function getNamespace(?string $option = null): ?string
|
||||||
|
{
|
||||||
|
$manifest = self::getManifest($option);
|
||||||
|
|
||||||
|
return $manifest->namespace ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the component abstract helper class
|
||||||
|
*
|
||||||
|
* @param string|null $option The option for the component.
|
||||||
|
* @param string|null $default The default return value if none is found
|
||||||
|
*
|
||||||
|
* @return object|null A component helper name
|
||||||
|
*
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
public static function getManifest(?string $option = null): ?object
|
||||||
|
{
|
||||||
|
if ($option === null
|
||||||
|
&& ($option = self::getOption($option)) === null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get global manifest_cache values
|
||||||
|
if (!isset(self::$manifest[$option]))
|
||||||
|
{
|
||||||
|
$db = Factory::getDbo();
|
||||||
|
$query = $db->getQuery(true);
|
||||||
|
|
||||||
|
$query->select($db->quoteName('manifest_cache'))
|
||||||
|
->from($db->quoteName('#__extensions'))
|
||||||
|
->where($db->quoteName('type') . ' = ' . $db->quote('component'))
|
||||||
|
->where($db->quoteName('element') . ' LIKE ' . $db->quote($option));
|
||||||
|
|
||||||
|
$db->setQuery($query);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$manifest = $db->loadResult();
|
||||||
|
self::$manifest[$option] = json_decode($manifest);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// Handle the database error appropriately.
|
||||||
|
self::$manifest[$option] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$manifest[$option];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the helper class of this component has a method
|
||||||
|
*
|
||||||
|
* @param string $method The method name to search for
|
||||||
|
* @param string|null $option The option for the component.
|
||||||
|
*
|
||||||
|
* @return bool true if method exist
|
||||||
|
*
|
||||||
|
* @since 3.0.11
|
||||||
|
*/
|
||||||
|
public static function methodExists(string $method, ?string $option = null): bool
|
||||||
|
{
|
||||||
|
// get the helper class
|
||||||
|
return ($helper = self::get($option, null)) !== null &&
|
||||||
|
method_exists($helper, $method);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the helper class of this component has a method, and call it with the arguments
|
||||||
|
*
|
||||||
|
* @param string $method The method name to search for
|
||||||
|
* @param array $arguments The arguments for function.
|
||||||
|
* @param string|null $option The option for the component.
|
||||||
|
*
|
||||||
|
* @return mixed return whatever the method returns or null
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public static function _(string $method, array $arguments = [], ?string $option = null)
|
||||||
|
{
|
||||||
|
// get the helper class
|
||||||
|
if (($helper = self::get($option, null)) !== null &&
|
||||||
|
method_exists($helper, $method))
|
||||||
|
{
|
||||||
|
// we know this is not ideal...
|
||||||
|
// so we need to move these
|
||||||
|
// functions to their own classes
|
||||||
|
return call_user_func_array([$helper, $method], $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
78
src/VastDevelopmentMethod/Joomla/Utilities/ObjectHelper.php
Normal file
78
src/VastDevelopmentMethod/Joomla/Utilities/ObjectHelper.php
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 3rd September, 2020
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Utilities;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some object tricks
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
abstract class ObjectHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check if have an object with a length
|
||||||
|
*
|
||||||
|
* @input object The object to check
|
||||||
|
*
|
||||||
|
* @returns bool true on success
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function check($object)
|
||||||
|
{
|
||||||
|
if (is_object($object))
|
||||||
|
{
|
||||||
|
return count((array) $object) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two objects for equality based on their property values.
|
||||||
|
*
|
||||||
|
* Note that this method works only for simple objects that don't
|
||||||
|
* contain any nested objects or resource references. If you need
|
||||||
|
* to compare more complex objects, you may need to use a
|
||||||
|
* more advanced method such as serialization or reflection.
|
||||||
|
*
|
||||||
|
* @param object|null $obj1 The first object to compare.
|
||||||
|
* @param object|null $obj2 The second object to compare.
|
||||||
|
*
|
||||||
|
* @return bool True if the objects have the same key-value pairs and false otherwise.
|
||||||
|
*/
|
||||||
|
public static function equal(?object $obj1, ?object $obj2): bool
|
||||||
|
{
|
||||||
|
// if any is null we return false as that means there is a none object
|
||||||
|
// we are not comparing null but objects
|
||||||
|
// but we allow null as some objects while
|
||||||
|
// not instantiate are still null
|
||||||
|
if (is_null($obj1) || is_null($obj2))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the objects to arrays of their property values using get_object_vars.
|
||||||
|
$array1 = get_object_vars($obj1);
|
||||||
|
$array2 = get_object_vars($obj2);
|
||||||
|
|
||||||
|
// Compare the arrays using array_diff_assoc to detect any differences.
|
||||||
|
$diff1 = array_diff_assoc($array1, $array2);
|
||||||
|
$diff2 = array_diff_assoc($array2, $array1);
|
||||||
|
|
||||||
|
// If the arrays have the same key-value pairs, they will have no differences, so return true.
|
||||||
|
return empty($diff1) && empty($diff2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 3rd September, 2020
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Utilities\String;
|
||||||
|
|
||||||
|
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\StringHelper;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control the naming of a namespace helper
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
abstract class NamespaceHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Making namespace safe
|
||||||
|
*
|
||||||
|
* @param string $string The namespace string you would like to make safe
|
||||||
|
*
|
||||||
|
* @return string on success
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function safe(string $string): string
|
||||||
|
{
|
||||||
|
// Remove leading and trailing backslashes
|
||||||
|
$string = trim($string, '\\');
|
||||||
|
|
||||||
|
// Split the string into namespace segments
|
||||||
|
$segments = explode('\\', $string);
|
||||||
|
|
||||||
|
// make each segment safe
|
||||||
|
$segments = array_map([self::class, 'safeSegment'], $segments);
|
||||||
|
|
||||||
|
// Join the namespace segments back together
|
||||||
|
return implode('\\', $segments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Making one namespace segment safe
|
||||||
|
*
|
||||||
|
* @param string $string The namespace segment string you would like to make safe
|
||||||
|
*
|
||||||
|
* @return string on success
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function safeSegment(string $string): string
|
||||||
|
{
|
||||||
|
// Check if segment starts with a number
|
||||||
|
if (preg_match("/^\d/", $string))
|
||||||
|
{
|
||||||
|
// Extract the starting number(s)
|
||||||
|
preg_match("/^\d+/", $string, $matches);
|
||||||
|
|
||||||
|
if (isset($matches[0]))
|
||||||
|
{
|
||||||
|
$numberWord = StringHelper::numbers($matches[0]);
|
||||||
|
$string = str_replace($matches[0], $numberWord, $string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transliterate string TODO: look again as this makes it lowercase
|
||||||
|
// $segment = StringHelper::transliterate($segment);
|
||||||
|
|
||||||
|
// Make sure segment only contains valid characters
|
||||||
|
return preg_replace("/[^A-Za-z0-9]/", '', $string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
416
src/VastDevelopmentMethod/Joomla/Utilities/StringHelper.php
Normal file
416
src/VastDevelopmentMethod/Joomla/Utilities/StringHelper.php
Normal file
@ -0,0 +1,416 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package vdm/data
|
||||||
|
*
|
||||||
|
* @created 3rd September, 2020
|
||||||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||||||
|
* @git VDM Data Library <https://git.vdm.dev/joomla/vdm-data>
|
||||||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace VastDevelopmentMethod\Joomla\Utilities;
|
||||||
|
|
||||||
|
|
||||||
|
use Joomla\Filter\InputFilter;
|
||||||
|
use Joomla\CMS\Language\Language;
|
||||||
|
use VastDevelopmentMethod\Joomla\Utilities\Component\Helper;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some string tricks
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
abstract class StringHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Main Active Language
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static $langTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we have a string with a length
|
||||||
|
*
|
||||||
|
* @input string $string The string to check
|
||||||
|
*
|
||||||
|
* @returns bool true on success
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function check($string): bool
|
||||||
|
{
|
||||||
|
return is_string($string) && strlen($string) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorten a string
|
||||||
|
*
|
||||||
|
* @input string The sting that you would like to shorten
|
||||||
|
*
|
||||||
|
* @returns string on success
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public static function shorten($string, $length = 40, $addTip = true)
|
||||||
|
{
|
||||||
|
if (self::check($string))
|
||||||
|
{
|
||||||
|
$initial = strlen((string) $string);
|
||||||
|
$words = preg_split('/([\s\n\r]+)/', (string) $string, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||||
|
$words_count = count((array)$words);
|
||||||
|
|
||||||
|
$word_length = 0;
|
||||||
|
$last_word = 0;
|
||||||
|
for (; $last_word < $words_count; ++$last_word)
|
||||||
|
{
|
||||||
|
$word_length += strlen($words[$last_word]);
|
||||||
|
if ($word_length > $length)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$newString = implode(array_slice($words, 0, $last_word));
|
||||||
|
$final = strlen($newString);
|
||||||
|
if ($initial !== $final && $addTip)
|
||||||
|
{
|
||||||
|
$title = self::shorten($string, 400 , false);
|
||||||
|
return '<span class="hasTip" title="' . $title . '" style="cursor:help">' . trim($newString) . '...</span>';
|
||||||
|
}
|
||||||
|
elseif ($initial !== $final && !$addTip)
|
||||||
|
{
|
||||||
|
return trim($newString) . '...';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Making strings safe (various ways)
|
||||||
|
*
|
||||||
|
* @input string The you would like to make safe
|
||||||
|
*
|
||||||
|
* @returns string on success
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function safe($string, $type = 'L', $spacer = '_', $replaceNumbers = true, $keepOnlyCharacters = true)
|
||||||
|
{
|
||||||
|
if ($replaceNumbers === true)
|
||||||
|
{
|
||||||
|
// remove all numbers and replace with English text version (works well only up to millions)
|
||||||
|
$string = self::numbers($string);
|
||||||
|
}
|
||||||
|
// 0nly continue if we have a string
|
||||||
|
if (self::check($string))
|
||||||
|
{
|
||||||
|
// create file name without the extension that is safe
|
||||||
|
if ($type === 'filename')
|
||||||
|
{
|
||||||
|
// make sure VDM is not in the string
|
||||||
|
$string = str_replace('VDM', 'vDm', (string) $string);
|
||||||
|
// Remove anything which isn't a word, whitespace, number
|
||||||
|
// or any of the following caracters -_()
|
||||||
|
// If you don't need to handle multi-byte characters
|
||||||
|
// you can use preg_replace rather than mb_ereg_replace
|
||||||
|
// Thanks @Łukasz Rysiak!
|
||||||
|
// $string = mb_ereg_replace("([^\w\s\d\-_\(\)])", '', $string);
|
||||||
|
$string = preg_replace("([^\w\s\d\-_\(\)])", '', $string);
|
||||||
|
|
||||||
|
// http://stackoverflow.com/a/2021729/1429677
|
||||||
|
return preg_replace('/\s+/', ' ', (string) $string);
|
||||||
|
}
|
||||||
|
// remove all other characters
|
||||||
|
$string = trim((string) $string);
|
||||||
|
$string = preg_replace('/'.$spacer.'+/', ' ', $string);
|
||||||
|
$string = preg_replace('/\s+/', ' ', $string);
|
||||||
|
// Transliterate string
|
||||||
|
$string = self::transliterate($string);
|
||||||
|
// remove all and keep only characters
|
||||||
|
if ($keepOnlyCharacters)
|
||||||
|
{
|
||||||
|
$string = preg_replace("/[^A-Za-z ]/", '', (string) $string);
|
||||||
|
}
|
||||||
|
// keep both numbers and characters
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$string = preg_replace("/[^A-Za-z0-9 ]/", '', (string) $string);
|
||||||
|
}
|
||||||
|
// select final adaptations
|
||||||
|
if ($type === 'L' || $type === 'strtolower')
|
||||||
|
{
|
||||||
|
// replace white space with underscore
|
||||||
|
$string = preg_replace('/\s+/', (string) $spacer, (string) $string);
|
||||||
|
// default is to return lower
|
||||||
|
return strtolower($string);
|
||||||
|
}
|
||||||
|
elseif ($type === 'W')
|
||||||
|
{
|
||||||
|
// return a string with all first letter of each word uppercase(no underscore)
|
||||||
|
return ucwords(strtolower($string));
|
||||||
|
}
|
||||||
|
elseif ($type === 'w' || $type === 'word')
|
||||||
|
{
|
||||||
|
// return a string with all lowercase(no underscore)
|
||||||
|
return strtolower($string);
|
||||||
|
}
|
||||||
|
elseif ($type === 'Ww' || $type === 'Word')
|
||||||
|
{
|
||||||
|
// return a string with first letter of the first word uppercase and all the rest lowercase(no underscore)
|
||||||
|
return ucfirst(strtolower($string));
|
||||||
|
}
|
||||||
|
elseif ($type === 'WW' || $type === 'WORD')
|
||||||
|
{
|
||||||
|
// return a string with all the uppercase(no underscore)
|
||||||
|
return strtoupper($string);
|
||||||
|
}
|
||||||
|
elseif ($type === 'U' || $type === 'strtoupper')
|
||||||
|
{
|
||||||
|
// replace white space with underscore
|
||||||
|
$string = preg_replace('/\s+/', (string) $spacer, $string);
|
||||||
|
// return all upper
|
||||||
|
return strtoupper($string);
|
||||||
|
}
|
||||||
|
elseif ($type === 'F' || $type === 'ucfirst')
|
||||||
|
{
|
||||||
|
// replace white space with underscore
|
||||||
|
$string = preg_replace('/\s+/', (string) $spacer, $string);
|
||||||
|
// return with first character to upper
|
||||||
|
return ucfirst(strtolower($string));
|
||||||
|
}
|
||||||
|
elseif ($type === 'cA' || $type === 'cAmel' || $type === 'camelcase')
|
||||||
|
{
|
||||||
|
// convert all words to first letter uppercase
|
||||||
|
$string = ucwords(strtolower($string));
|
||||||
|
// remove white space
|
||||||
|
$string = preg_replace('/\s+/', '', $string);
|
||||||
|
// now return first letter lowercase
|
||||||
|
return lcfirst($string);
|
||||||
|
}
|
||||||
|
// return string
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
// not a string
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert none English strings to code usable string
|
||||||
|
*
|
||||||
|
* @input an string
|
||||||
|
*
|
||||||
|
* @returns a string
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function transliterate($string)
|
||||||
|
{
|
||||||
|
// set tag only once
|
||||||
|
if (!self::check(self::$langTag))
|
||||||
|
{
|
||||||
|
// get global value
|
||||||
|
self::$langTag = Helper::getParams()->get('language', 'en-GB');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transliterate on the language requested
|
||||||
|
$lang = Language::getInstance(self::$langTag);
|
||||||
|
|
||||||
|
return $lang->transliterate($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* make sure a string is HTML save
|
||||||
|
*
|
||||||
|
* @input an html string
|
||||||
|
*
|
||||||
|
* @returns a string
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function html($var, $charset = 'UTF-8', $shorten = false, $length = 40, $addTip = true)
|
||||||
|
{
|
||||||
|
if (self::check($var))
|
||||||
|
{
|
||||||
|
$filter = new InputFilter();
|
||||||
|
$string = $filter->clean(
|
||||||
|
html_entity_decode(
|
||||||
|
htmlentities(
|
||||||
|
(string) $var,
|
||||||
|
ENT_COMPAT,
|
||||||
|
$charset
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'HTML'
|
||||||
|
);
|
||||||
|
if ($shorten)
|
||||||
|
{
|
||||||
|
return self::shorten($string, $length, $addTip);
|
||||||
|
}
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert all int in a string to an English word string
|
||||||
|
*
|
||||||
|
* @input an string with numbers
|
||||||
|
*
|
||||||
|
* @returns a string
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function numbers($string)
|
||||||
|
{
|
||||||
|
// set numbers array
|
||||||
|
$numbers = [];
|
||||||
|
$search_replace= [];
|
||||||
|
|
||||||
|
// first get all numbers
|
||||||
|
preg_match_all('!\d+!', (string) $string, $numbers);
|
||||||
|
|
||||||
|
// check if we have any numbers
|
||||||
|
if (isset($numbers[0]) && ArrayHelper::check($numbers[0]))
|
||||||
|
{
|
||||||
|
foreach ($numbers[0] as $number)
|
||||||
|
{
|
||||||
|
$search_replace[$number] = self::number((int)$number);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now replace numbers in string
|
||||||
|
$string = str_replace(array_keys($search_replace), array_values($search_replace), (string) $string);
|
||||||
|
|
||||||
|
// check if we missed any, strange if we did.
|
||||||
|
return self::numbers($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the string with no numbers remaining.
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an integer into an English word string
|
||||||
|
* Thanks to Tom Nicholson <http://php.net/manual/en/function.strval.php#41988>
|
||||||
|
*
|
||||||
|
* @input an int
|
||||||
|
* @returns a string
|
||||||
|
*
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function number($x)
|
||||||
|
{
|
||||||
|
$nwords = array( "zero", "one", "two", "three", "four", "five", "six", "seven",
|
||||||
|
"eight", "nine", "ten", "eleven", "twelve", "thirteen",
|
||||||
|
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
|
||||||
|
"nineteen", "twenty", 30 => "thirty", 40 => "forty",
|
||||||
|
50 => "fifty", 60 => "sixty", 70 => "seventy", 80 => "eighty",
|
||||||
|
90 => "ninety" );
|
||||||
|
|
||||||
|
if(!is_numeric($x))
|
||||||
|
{
|
||||||
|
$w = $x;
|
||||||
|
}
|
||||||
|
elseif(fmod($x, 1) != 0)
|
||||||
|
{
|
||||||
|
$w = $x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if($x < 0)
|
||||||
|
{
|
||||||
|
$w = 'minus ';
|
||||||
|
$x = -$x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$w = '';
|
||||||
|
// ... now $x is a non-negative integer.
|
||||||
|
}
|
||||||
|
|
||||||
|
if($x < 21) // 0 to 20
|
||||||
|
{
|
||||||
|
$w .= $nwords[$x];
|
||||||
|
}
|
||||||
|
elseif($x < 100) // 21 to 99
|
||||||
|
{
|
||||||
|
$w .= $nwords[10 * floor($x/10)];
|
||||||
|
$r = fmod($x, 10);
|
||||||
|
if($r > 0)
|
||||||
|
{
|
||||||
|
$w .= ' ' . $nwords[$r];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif($x < 1000) // 100 to 999
|
||||||
|
{
|
||||||
|
$w .= $nwords[floor($x/100)] .' hundred';
|
||||||
|
$r = fmod($x, 100);
|
||||||
|
if($r > 0)
|
||||||
|
{
|
||||||
|
$w .= ' and '. self::number($r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif($x < 1000000) // 1000 to 999999
|
||||||
|
{
|
||||||
|
$w .= self::number(floor($x/1000)) .' thousand';
|
||||||
|
$r = fmod($x, 1000);
|
||||||
|
if($r > 0)
|
||||||
|
{
|
||||||
|
$w .= ' ';
|
||||||
|
if($r < 100)
|
||||||
|
{
|
||||||
|
$w .= 'and ';
|
||||||
|
}
|
||||||
|
$w .= self::number($r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // millions
|
||||||
|
{
|
||||||
|
$w .= self::number(floor($x/1000000)) .' million';
|
||||||
|
$r = fmod($x, 1000000);
|
||||||
|
if($r > 0)
|
||||||
|
{
|
||||||
|
$w .= ' ';
|
||||||
|
if($r < 100)
|
||||||
|
{
|
||||||
|
$w .= 'and ';
|
||||||
|
}
|
||||||
|
$w .= self::number($r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $w;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Random Key
|
||||||
|
*
|
||||||
|
* @input int $size The size of the random string
|
||||||
|
*
|
||||||
|
* @returns a string
|
||||||
|
* @since 3.0.9
|
||||||
|
*/
|
||||||
|
public static function random(int $size): string
|
||||||
|
{
|
||||||
|
$bag = "abcefghijknopqrstuwxyzABCDDEFGHIJKLLMMNOPQRSTUVVWXYZabcddefghijkllmmnopqrstuvvwxyzABCEFGHIJKNOPQRSTUWXYZ";
|
||||||
|
$key = [];
|
||||||
|
$bagsize = strlen($bag) - 1;
|
||||||
|
|
||||||
|
for ($i = 0; $i < $size; $i++)
|
||||||
|
{
|
||||||
|
$get = rand(0, $bagsize);
|
||||||
|
$key[] = $bag[$get];
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user