Fixed changelog direction so newest changes is listed at top of the file. Finished the init function of super powers. Adds rest function inside super power. Adds super powers to all templates. Updates many helper class methods to now use the utility classes. Adds the method to the component entry file (as-well). Moved most methods from the compiler fields class to powers. #955 Refactored many new builder classes from the registry class. Converted the Content class to two builder classes. Adds option to add additional templates to a module. Resolves #1002 by adding STRING instead of WORD. Ported the FOF encryption class into Powers. https://git.vdm.dev/joomla/fof Changed all CSS and JS to use instead of in compiler code. Adds option to turn jQuery off if UIKIT 3 is added. Adds option to auto write injection boilerplate code in Powers area. Adds option to auto write service provider boilerplate code in the Powers area. Improved the method and all banner locations to fetch from https://git.vdm.dev/joomla/jcb-external/ instead. Major stability improvements all over the new powers complier classes. New [base Registry class](https://git.vdm.dev/joomla/super-powers/src/branch/master/src/7e822c03-1b20-41d1-9427-f5b8d5836af7) has been created specially for JCB. Remember to update all plug-ins with this version update (use the package).

This commit is contained in:
2023-10-18 09:26:30 +02:00
parent a77eac9adf
commit e99899f6f1
632 changed files with 30604 additions and 16888 deletions

View File

@@ -0,0 +1,272 @@
<?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 = [];
/**
* 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.
*
* @param mixed $value The value to set.
* @param bool $asArray Determines if the new value should be treated as an array.
* @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 addActive($value, bool $asArray, string ...$keys): void
{
if (!$this->validActiveKeys($keys))
{
throw new \InvalidArgumentException("Keys must only be strings or numbers to add 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];
}
// 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;
}
}

View File

@@ -0,0 +1,122 @@
<?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 Joomla\Registry\Registry as JoomlaRegistry;
use VDM\Joomla\Utilities\String\ClassfunctionHelper;
/**
* Config
*
* @since 3.2.0
*/
abstract class BaseConfig extends JoomlaRegistry
{
/**
* Constructor
*
* @since 3.2.0
*/
public function __construct()
{
// Instantiate the internal data object.
$this->data = new \stdClass();
}
/**
* setting any config value
*
* @param string $key The value's key/path name
* @param mixed $value Optional default value, returned if the internal value is null.
*
* @since 3.2.0
*/
public function __set(string $key, $value)
{
$this->set($key, $value);
}
/**
* getting any valid value
*
* @param string $key The value's key/path name
*
* @since 3.2.0
* @throws \InvalidArgumentException If $key is not a valid function name.
*/
public function __get(string $key)
{
// check if it has been set
if (($value = $this->get($key, '__N0T_S3T_Y3T_')) !== '__N0T_S3T_Y3T_')
{
return $value;
}
throw new \InvalidArgumentException(sprintf('Argument %s could not be found as function or path.', $key));
}
/**
* Get a config value.
*
* @param string $path Registry path (e.g. joomla_content_showauthor)
* @param mixed $default Optional default value, returned if the internal value is null.
*
* @return mixed Value of entry or null
*
* @since 3.2.0
*/
public function get($path, $default = null)
{
// function name with no underscores
$method = 'get' . ucfirst((string) ClassfunctionHelper::safe(str_replace('_', '', $path)));
// check if it has been set
if (($value = parent::get($path, '__N0T_S3T_Y3T_')) !== '__N0T_S3T_Y3T_')
{
return $value;
}
elseif (method_exists($this, $method))
{
$value = $this->{$method}($default);
$this->set($path, $value);
return $value;
}
return $default;
}
/**
* Append value to a path in registry of an array
*
* @param string $path Parent registry Path (e.g. joomla.content.showauthor)
* @param mixed $value Value of entry
*
* @return mixed The value of the that has been set.
*
* @since 3.2.0
*/
public function appendArray(string $path, $value)
{
// check if it does not exist
if (!$this->exists($path))
{
$this->set($path, []);
}
return $this->append($path, $value);
}
}

View File

@@ -0,0 +1,364 @@
<?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\Tableinterface;
/**
* Base Table
*
* @since 3.2.0
*/
abstract class BaseTable implements Tableinterface
{
/**
* All areas/views/tables with their field details
*
* @var array
* @since 3.2.0
**/
protected array $tables;
/**
* All default fields
*
* @var array
* @since 3.2.0
**/
protected array $defaults = [
'id' => [
'order' => -1,
'name' => 'id',
'label' => 'ID',
'type' => 'text',
'title' => false,
'list' => NULL,
'store' => NULL,
'tab_name' => NULL
],
'ordering' => [
'name' => 'ordering',
'label' => 'Ordering',
'type' => 'number',
'title' => false,
'list' => NULL,
'store' => NULL,
'tab_name' => NULL
],
'published' => [
'name' => 'published',
'label' => 'Status',
'type' => 'list',
'title' => false,
'list' => NULL,
'store' => NULL,
'tab_name' => NULL
],
'modified_by' => [
'name' => 'modified_by',
'label' => 'Modified by',
'type' => 'user',
'title' => false,
'list' => NULL,
'store' => NULL,
'tab_name' => NULL
],
'modified' => [
'name' => 'modified',
'label' => 'Modified',
'type' => 'calendar',
'title' => false,
'list' => NULL,
'store' => NULL,
'tab_name' => NULL
],
'created_by' => [
'name' => 'created_by',
'label' => 'Created by',
'type' => 'user',
'title' => false,
'list' => NULL,
'store' => NULL,
'tab_name' => NULL
],
'created' => [
'name' => 'created',
'label' => 'Created',
'type' => 'calendar',
'title' => false,
'list' => NULL,
'store' => NULL,
'tab_name' => NULL
],
'hits' => [
'name' => 'hits',
'label' => 'Hits',
'type' => 'number',
'title' => false,
'list' => NULL,
'store' => NULL,
'tab_name' => NULL
],
'version' => [
'name' => 'version',
'label' => 'Version',
'type' => 'text',
'title' => false,
'list' => NULL,
'store' => NULL,
'tab_name' => NULL
]
];
/**
* 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');
*
* @param string $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, ?string $field = null, ?string $key = null)
{
// return the item/field/column of an area/view/table
if (is_string($field) && is_string($key))
{
// return the value of a item/field/column of an area/view/table
if (isset($this->tables[$table][$field][$key]))
{
return $this->tables[$table][$field][$key];
}
return $this->getDefaultKey($field, $key);
}
// return the item/field/column of an area/view/table
elseif (is_string($field))
{
if (isset($this->tables[$table][$field]))
{
return $this->tables[$table][$field];
}
return $this->getDefault($field);
}
// return an area/view/table
elseif ($table !== 'All')
{
if (isset($this->tables[$table]))
{
return $this->tables[$table];
}
return null;
}
// return all
return $this->tables;
}
/**
* 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
{
// return the title item/field/column of an area/view/table
if (($table = $this->get($table)) !== null)
{
foreach ($table as $item)
{
if ($item['title'])
{
return $item;
}
}
}
// none found
return null;
}
/**
* Get title field name
*
* @param string $table The area
*
* @return string
* @since 3.2.0
*/
public function titleName(string $table): string
{
// return the title name of an area/view/table
if (($field = $this->title($table)) !== null)
{
return $field['name'];
}
// none found default to ID
return 'id';
}
/**
* Get all tables
*
* @return array
* @since 3.2.0
*/
public function tables(): array
{
// return all areas/views/tables
return array_keys($this->tables);
}
/**
* 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
{
if (isset($this->tables[$table]))
{
// if we have a field
if (is_string($field))
{
if (isset($this->tables[$table][$field]))
{
return true;
}
}
else
{
return true;
}
}
return $this->isDefault($field);
}
/**
* Get all fields of an area/view/table
*
* @param string $table The area
* @param bool $default Add the default fields
*
* @return array|null On success an array of fields
* @since 3.2.0
*/
public function fields(string $table, bool $default = false): ?array
{
// return all fields of an area/view/table
if (($table = $this->get($table)) !== null)
{
if ($default)
{
return $this->addDefault(array_keys($table));
}
else
{
return array_keys($table);
}
}
// none found
return null;
}
/**
* Add the default fields
*
* @param array $fields The table dynamic fields
*
* @return array Fields (with defaults added)
* @since 3.2.0
*/
protected function addDefault(array $fields): array
{
// add default fields
foreach ($this->defaults as $default)
{
// used just for loading the fields
$order = $default['order'] ?? 1;
unset($default['order']);
if ($order < 0)
{
array_unshift($fields, $default['name']);
}
else
{
$fields[] = $default['name'];
}
}
return $fields;
}
/**
* Check if the field is a default field
*
* @param string $field The field to check
*
* @return bool True if a default field
* @since 3.2.0
*/
protected function isDefault(string $field): bool
{
return isset($this->defaults[$field]);
}
/**
* Get a default field
*
* @param string $field The field to check
*
* @return array|null True if a default field
* @since 3.2.0
*/
protected function getDefault(string $field): ?array
{
return $this->defaults[$field] ?? null;
}
/**
* Get a default field property
*
* @param string $field The field to check
* @param string $key The field key/property to check
*
* @return string|null String value if a default field property exist
* @since 3.2.0
*/
protected function getDefaultKey(string $field, string $key): ?string
{
return $this->defaults[$field][$key] ?? null;
}
}

View File

@@ -0,0 +1,118 @@
<?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 Joomla\CMS\Factory as JoomlaFactory;
use VDM\Joomla\Utilities\Component\Helper;
/**
* Database
*
* @since 3.2.0
*/
abstract class Database
{
/**
* Database object to query local DB
*
* @var \JDatabaseDriver
* @since 3.2.0
*/
protected \JDatabaseDriver $db;
/**
* Core Component Table Name
*
* @var string
* @since 3.2.0
*/
protected string $table;
/**
* Constructor
*
* @param \JDatabaseDriver|null $db The database driver
*
* @throws \Exception
* @since 3.2.0
*/
public function __construct(?\JDatabaseDriver $db = null)
{
$this->db = $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;
}
}

View File

@@ -0,0 +1,358 @@
<?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\Utilities\StringHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Interfaces\Tableinterface as Table;
/**
* Base Model
*
* @since 3.2.0
*/
abstract class Model
{
/**
* Last ID
*
* @var array
* @since 3.2.0
*/
protected array $last;
/**
* Search Table
*
* @var Table
* @since 3.2.0
*/
protected Table $table;
/**
* Constructor
*
* @param Table $table The search table object.
*
* @since 3.2.0
*/
public function __construct(Table $table)
{
$this->table = $table;
}
/**
* 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 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;
}
/**
* 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;
/**
* Get the current active table
*
* @return string
* @since 3.2.0
*/
abstract protected function getTable(): string;
}

View File

@@ -0,0 +1,182 @@
<?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;
use VDM\Joomla\Interfaces\Registryinterface;
use VDM\Joomla\Abstraction\ActiveRegistry;
/**
* VDM Basic Registry.
*
* Don't use this beyond 10 dimensional depth for best performance.
*
* @since 3.2.0
*/
abstract class Registry extends ActiveRegistry implements Activeregistryinterface, Registryinterface
{
/**
* Path separator
*
* @var string|null
* @since 3.2.0
*/
protected ?string $separator = '.';
/**
* Sets a value into the registry using multiple keys.
*
* @param string $path Registry path (e.g. vdm.content.builder)
* @param mixed $value Value of entry
*
* @throws \InvalidArgumentException If any of the path values are not a number or string.
* @return void
* @since 3.2.0
*/
public function set(string $path, $value): void
{
if (($keys = $this->getActiveKeys($path)) === null)
{
throw new \InvalidArgumentException("Path must only be strings or numbers to set any value.");
}
$this->setActive($value, ...$keys);
}
/**
* Adds content into the registry. If a key exists,
* it either appends or concatenates based on $asArray switch.
*
* @param string $path Registry path (e.g. vdm.content.builder)
* @param mixed $value Value of entry
* @param bool $asArray Determines if the new value should be treated as an array. Default is false.
*
* @throws \InvalidArgumentException If any of the path values are not a number or string.
* @return void
* @since 3.2.0
*/
public function add(string $path, $value, bool $asArray = false): void
{
if (($keys = $this->getActiveKeys($path)) === null)
{
throw new \InvalidArgumentException("Path must only be strings or numbers to add any value.");
}
$this->addActive($value, $asArray, ...$keys);
}
/**
* Retrieves a value (or sub-array) from the registry using multiple keys.
*
* @param string $path Registry path (e.g. vdm.content.builder)
* @param mixed $default Optional default value, returned if the internal doesn't exist.
*
* @throws \InvalidArgumentException If any of the path values 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 get(string $path, $default = null)
{
if (($keys = $this->getActiveKeys($path)) === null)
{
throw new \InvalidArgumentException("Path must only be strings or numbers to get any value.");
}
return $this->getActive($default, ...$keys);
}
/**
* Removes a value (or sub-array) from the registry using multiple keys.
*
* @param string $path Registry path (e.g. vdm.content.builder)
*
* @throws \InvalidArgumentException If any of the path values are not a number or string.
* @return void
* @since 3.2.0
*/
public function remove(string $path): void
{
if (($keys = $this->getActiveKeys($path)) === null)
{
throw new \InvalidArgumentException("Path must only be strings or numbers to remove any value.");
}
$this->removeActive(...$keys);
}
/**
* Checks the existence of a particular location in the registry using multiple keys.
*
* @param string $path Registry path (e.g. vdm.content.builder)
*
* @throws \InvalidArgumentException If any of the path values are not a number or string.
* @return bool True if the location exists, false otherwise.
* @since 3.2.0
*/
public function exists(string $path): bool
{
if (($keys = $this->getActiveKeys($path)) === null)
{
throw new \InvalidArgumentException("Path must only be strings or numbers to check if any value exist.");
}
return $this->existsActive(...$keys);
}
/**
* Sets a separator value
*
* @param string|null $value The value to set.
*
* @return void
* @since 3.2.0
*/
public function setSeparator(?string $value): void
{
$this->separator = $value;
}
/**
* Get that the active keys from a path
*
* @param string $path The path to determine the location registry.
*
* @return array|null The valid array of keys
* @since 3.2.0
*/
protected function getActiveKeys(string $path): ?array
{
// empty path no allowed
if ($path === '')
{
return null;
}
// Flatten the path
if ($this->separator === null || $this->separator === '')
{
return [$path];
}
$keys = array_values(array_filter(explode($this->separator, $path), 'strlen'));
if (empty($keys))
{
return null;
}
return $keys;
}
}

View File

@@ -0,0 +1,51 @@
<?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\Registry\Traits;
/**
* Count Values
*
* @since 3.2.0
*/
trait Count
{
/**
* Retrieves number of values (or sub-array) from the storage using multiple keys.
*
* @param string $path Storage path (e.g. vdm.content.builder)
*
* @throws \InvalidArgumentException If any of the path values are not a number or string.
* @return int The number of values
* @since 3.2.0
*/
public function count(string $path): int
{
if (($values = $this->get($path)) === null)
{
return 0;
}
if (is_array($values))
{
return count($values);
}
if (is_object($values))
{
return count((array) $values);
}
return 1;
}
}

View File

@@ -0,0 +1,50 @@
<?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\Registry\Traits;
/**
* Get String Values
*
* @since 3.2.0
*/
trait GetString
{
/**
* Get a registry path if the return value is a string
*
* @param string $path Registry path (e.g. joomla.content.showauthor)
* @param string|null $default A default value
*
* @return string|null
* @since 3.2.0
*/
public function getString(string $path, ?string $default = null): ?string
{
// Return default value if path is empty
if (empty($path))
{
return $default;
}
// get the value
if (($node = $this->get($path)) !== null
&& is_string($node)
&& strlen((string) $node) > 0)
{
return $node;
}
return $default;
}
}

View File

@@ -0,0 +1,50 @@
<?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\Registry\Traits;
/**
* Check if a value is in an array
*
* @since 3.2.0
*/
trait InArray
{
/**
* Check if a value is found in an array
*
* @param mixed $value The value to check for
* @param string|null $path Registry path (e.g. joomla.content.showauthor)
*
* @return bool
* @since 3.2.0
*/
public function inArray($value, ?string $path = null): bool
{
// Check base array if no path is given
if (empty($path))
{
return in_array($value, $this->active);
}
// get the value
if (($node = $this->get($path)) !== null
&& is_array($node)
&& in_array($value, $node))
{
return true;
}
return false;
}
}

View File

@@ -0,0 +1,48 @@
<?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\Registry\Traits;
/**
* Check if a value is in an array
*
* @since 3.2.0
*/
trait IsArray
{
/**
* Check if a path is an array
*
* @param string $path Registry path (e.g. joomla.content.showauthor)
*
* @return bool
* @since 3.2.0
*/
public function isArray(string $path): bool
{
// Check base array if no path is given
if (empty($path))
{
return false;
}
// get the value
if (($node = $this->get($path)) !== null
&& is_array($node))
{
return true;
}
return false;
}
}

View File

@@ -0,0 +1,48 @@
<?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\Registry\Traits;
/**
* Is String Values
*
* @since 3.2.0
*/
trait IsString
{
/**
* Check if a registry path exists and is a string
*
* @param string $path Registry path (e.g. joomla.content.showauthor)
*
* @return boolean
* @since 3.2.0
*/
public function isString(string $path): bool
{
// Return default value if path is empty
if (empty($path)) {
return false;
}
// get the value
if (($node = $this->get($path)) !== null
&& is_string($node)
&& strlen((string) $node) > 0)
{
return true;
}
return false;
}
}

View File

@@ -0,0 +1,55 @@
<?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\Registry\Traits;
/**
* To String Values
*
* @since 3.2.0
*/
trait ToString
{
/**
* Convert an array of values to a string (or return string)
*
* @param string $path Registry path (e.g. joomla.content.showauthor)
* @param string $seperator Return string separator
*
* @return string
* @since 3.2.0
*/
public function toString(string $path, string $separator = ''): string
{
// Return default value if path is empty
if (empty($path))
{
return '';
}
// get the value
if (($node = $this->get($path)) !== null)
{
if (is_array($node) && $node !== [])
{
return implode($separator, $node);
}
elseif (is_string($node) && strlen((string) $node) > 0)
{
return $node;
}
}
return '';
}
}

View File

@@ -0,0 +1,105 @@
<?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\Registry\Traits;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
/**
* Var Export Values
*
* @since 3.2.0
*/
trait VarExport
{
/**
* Default indentation value
*
* @var int
* @since 3.4.0
*/
protected int $indent = 2;
/**
* Method to export a set of values to a PHP array
*
* @param string|null $path Registry path (e.g. joomla.content.showauthor)
* @param int $indentation The default indentation
*
* @return ?string The var set being exported as a PHP array
* @since 3.4.0
*/
public function varExport(?string $path = null, int $indentation = 2): ?string
{
// Load the data array
if ($path === null && $this->isActive())
{
$data = $this->allActive();
}
else
{
$data = $this->get($path);
}
// check if we have data
if ($data === null)
{
return null;
}
// set the default indentation value
$this->indent = $indentation;
// convert to string
$data = var_export($data, true);
// replace all space with system indentation
$data = preg_replace_callback("/^(\s{2})(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(.*)/m", [$this, 'convertIndent'], $data);
// convert all array to []
$array = preg_split("/\r\n|\n|\r/", $data);
$array = preg_replace(["/\s*array\s\($/", "/\)(,)?$/", "/\s=>\s$/"], [NULL, ']$1', ' => ['], $array);
$data = implode(PHP_EOL, array_filter(["["] + $array));
// add needed indentation to the last ]
$data = preg_replace("/^(\])/m", Indent::_($indentation) . '$1', $data);
return $data;
}
/**
* Method to convert found of grouped spaces to system indentation
*
* @param array $matches The regex array of matching values
*
* @return string The resulting string.
* @since 3.4.0
*/
protected function convertIndent(array $matches): string
{
// set number to indent by default
$indent = Indent::_($this->indent);
// update each found space (group) with one indentation
foreach (range(1, 11) as $space)
{
if (strlen((string) $matches[$space]) > 0)
{
$indent .= Indent::_(1);
}
}
return $indent . $matches[12];
}
}

View File

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

View File

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