2023-10-18 07:26:30 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @package Joomla.Component.Builder
|
|
|
|
*
|
|
|
|
* @created 4th September, 2022
|
|
|
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
|
|
|
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
|
|
|
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
|
|
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace VDM\Joomla\Abstraction;
|
|
|
|
|
|
|
|
|
|
|
|
use VDM\Joomla\Interfaces\Activeregistryinterface;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Active Storage Registry.
|
|
|
|
*
|
|
|
|
* Don't use this beyond 10 dimensional depth for best performance.
|
|
|
|
*
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
abstract class ActiveRegistry implements Activeregistryinterface
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* The registry array.
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
* @since 3.2.0
|
|
|
|
**/
|
|
|
|
protected array $active = [];
|
|
|
|
|
2024-03-02 20:10:30 +00:00
|
|
|
/**
|
|
|
|
* Base switch to add values as string or array
|
|
|
|
*
|
|
|
|
* @var boolean
|
|
|
|
* @since 3.2.0
|
|
|
|
**/
|
|
|
|
protected bool $addAsArray = false;
|
|
|
|
|
2023-10-18 07:26:30 +00:00
|
|
|
/**
|
|
|
|
* Check if the registry has any content.
|
|
|
|
*
|
|
|
|
* @return bool Returns true if the active array is not empty, false otherwise.
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
public function isActive(): bool
|
|
|
|
{
|
|
|
|
return !empty($this->active);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get all value from the active registry.
|
|
|
|
*
|
|
|
|
* @return array The values or empty array.
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
public function allActive(): array
|
|
|
|
{
|
|
|
|
return $this->active;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets a value into the registry using multiple keys.
|
|
|
|
*
|
|
|
|
* @param mixed $value The value to set.
|
|
|
|
* @param string ...$keys The keys to determine the location.
|
|
|
|
*
|
|
|
|
* @throws \InvalidArgumentException If any of the keys are not a number or string.
|
|
|
|
* @return void
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
public function setActive($value, string ...$keys): void
|
|
|
|
{
|
|
|
|
if (!$this->validActiveKeys($keys))
|
|
|
|
{
|
|
|
|
throw new \InvalidArgumentException("Keys must only be strings or numbers to set any value.");
|
|
|
|
}
|
|
|
|
|
|
|
|
$array = &$this->active;
|
|
|
|
|
|
|
|
foreach ($keys as $key)
|
|
|
|
{
|
|
|
|
if (!isset($array[$key]))
|
|
|
|
{
|
|
|
|
if (!is_array($array))
|
|
|
|
{
|
|
|
|
$path = '[' . implode('][', $keys) . ']';
|
|
|
|
throw new \InvalidArgumentException("Attempted to use key '{$key}' on a non-array value: {$array}. Path: {$path} Value: {$value}");
|
|
|
|
}
|
|
|
|
|
|
|
|
$array[$key] = [];
|
|
|
|
}
|
|
|
|
$array = &$array[$key];
|
|
|
|
}
|
|
|
|
|
|
|
|
$array = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds content into the registry. If a key exists,
|
|
|
|
* it either appends or concatenates based on the value's type.
|
|
|
|
*
|
2024-03-02 20:10:30 +00:00
|
|
|
* @param mixed $value The value to set.
|
|
|
|
* @param bool|null $asArray Determines if the new value should be treated as an array.
|
|
|
|
* Default is $addAsArray = false (if null) in base class.
|
|
|
|
* Override in child class allowed set class property $addAsArray = true.
|
|
|
|
* @param string ...$keys The keys to determine the location.
|
2023-10-18 07:26:30 +00:00
|
|
|
*
|
|
|
|
* @throws \InvalidArgumentException If any of the keys are not a number or string.
|
|
|
|
* @return void
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
2024-03-02 20:10:30 +00:00
|
|
|
public function addActive($value, ?bool $asArray, string ...$keys): void
|
2023-10-18 07:26:30 +00:00
|
|
|
{
|
|
|
|
if (!$this->validActiveKeys($keys))
|
|
|
|
{
|
|
|
|
throw new \InvalidArgumentException("Keys must only be strings or numbers to add any value.");
|
|
|
|
}
|
|
|
|
|
2024-03-02 20:10:30 +00:00
|
|
|
// null fallback to class value
|
|
|
|
if ($asArray === null)
|
|
|
|
{
|
|
|
|
$asArray = $this->addAsArray;
|
|
|
|
}
|
|
|
|
|
2023-10-18 07:26:30 +00:00
|
|
|
$array = &$this->active;
|
|
|
|
|
|
|
|
foreach ($keys as $key)
|
|
|
|
{
|
|
|
|
if (!isset($array[$key]))
|
|
|
|
{
|
|
|
|
if (!is_array($array))
|
|
|
|
{
|
|
|
|
$path = '[' . implode('][', $keys) . ']';
|
|
|
|
throw new \InvalidArgumentException("Attempted to use key '{$key}' on a non-array value: {$array}. Path: {$path} Value: {$value}");
|
|
|
|
}
|
|
|
|
|
|
|
|
$array[$key] = [];
|
|
|
|
}
|
|
|
|
$array = &$array[$key];
|
|
|
|
}
|
|
|
|
|
|
|
|
// add string
|
|
|
|
if (!$asArray && $array === [])
|
|
|
|
{
|
|
|
|
$array = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle the adding logic at the tip of the array
|
|
|
|
if (is_array($array) || $asArray)
|
|
|
|
{
|
|
|
|
if (!is_array($array))
|
|
|
|
{
|
|
|
|
// Convert to array if it's not already an array
|
|
|
|
$array = [$array];
|
|
|
|
}
|
|
|
|
$array[] = $value;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (is_string($value) || is_numeric($value))
|
|
|
|
{
|
|
|
|
$array .= (string) $value;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$array = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves a value (or sub-array) from the registry using multiple keys.
|
|
|
|
*
|
|
|
|
* @param mixed $default The default value if not set.
|
|
|
|
* @param string ...$keys The keys to determine the location.
|
|
|
|
*
|
|
|
|
* @throws \InvalidArgumentException If any of the keys are not a number or string.
|
|
|
|
* @return mixed The value or sub-array from the storage. Null if the location doesn't exist.
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
public function getActive($default, string ...$keys)
|
|
|
|
{
|
|
|
|
if (!$this->validActiveKeys($keys))
|
|
|
|
{
|
|
|
|
throw new \InvalidArgumentException("Keys must only be strings or numbers to get any value.");
|
|
|
|
}
|
|
|
|
|
|
|
|
$array = $this->active;
|
|
|
|
|
|
|
|
foreach ($keys as $key)
|
|
|
|
{
|
|
|
|
if (!isset($array[$key]))
|
|
|
|
{
|
|
|
|
return $default;
|
|
|
|
}
|
|
|
|
$array = $array[$key];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $array;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes a value (or sub-array) from the registry using multiple keys.
|
|
|
|
*
|
|
|
|
* @param string ...$keys The keys to determine the location.
|
|
|
|
*
|
|
|
|
* @throws \InvalidArgumentException If any of the keys are not a number or string.
|
|
|
|
* @return void
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
public function removeActive(string ...$keys): void
|
|
|
|
{
|
|
|
|
if (!$this->validActiveKeys($keys))
|
|
|
|
{
|
|
|
|
throw new \InvalidArgumentException("Keys must only be strings or numbers to remove any value.");
|
|
|
|
}
|
|
|
|
|
|
|
|
$array = &$this->active;
|
|
|
|
$lastKey = array_pop($keys);
|
|
|
|
|
|
|
|
foreach ($keys as $key)
|
|
|
|
{
|
|
|
|
if (!isset($array[$key]))
|
|
|
|
{
|
|
|
|
return; // Exit early if the key doesn't exist
|
|
|
|
}
|
|
|
|
$array = &$array[$key];
|
|
|
|
}
|
|
|
|
|
|
|
|
unset($array[$lastKey]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks the existence of a particular location in the registry using multiple keys.
|
|
|
|
*
|
|
|
|
* @param string ...$keys The keys to determine the location.
|
|
|
|
*
|
|
|
|
* @throws \InvalidArgumentException If any of the keys are not a number or string.
|
|
|
|
* @return bool True if the location exists, false otherwise.
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
public function existsActive(string ...$keys): bool
|
|
|
|
{
|
|
|
|
if (!$this->validActiveKeys($keys))
|
|
|
|
{
|
|
|
|
throw new \InvalidArgumentException("Keys must only be strings or numbers to check if any value exist.");
|
|
|
|
}
|
|
|
|
|
|
|
|
$array = $this->active;
|
|
|
|
|
|
|
|
foreach ($keys as $key)
|
|
|
|
{
|
|
|
|
if (!isset($array[$key]))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$array = $array[$key];
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks that the keys are valid
|
|
|
|
*
|
|
|
|
* @param array $keys The keys to determine the location.
|
|
|
|
*
|
|
|
|
* @return bool False if any of the keys are not a number or string.
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
protected function validActiveKeys(array $keys): bool
|
|
|
|
{
|
|
|
|
foreach ($keys as $key)
|
|
|
|
{
|
|
|
|
if ($key === '' || (!is_string($key) && !is_numeric($key)))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|