update 2024-04-22 16:43:32
This commit is contained in:
parent
2125425324
commit
321d89954a
@ -31,6 +31,7 @@ This repository contains an index (see below) of all the approved powers within
|
||||
- **abstract class Database** | [Details](src/6cbef8f8-4813-48e3-b05a-65e1aea95171) | [Code](src/6cbef8f8-4813-48e3-b05a-65e1aea95171/code.php) | [Settings](src/6cbef8f8-4813-48e3-b05a-65e1aea95171/settings.json) | Super__6cbef8f8_4813_48e3_b05a_65e1aea95171__Power
|
||||
- **abstract class Model** | [Details](src/584747d1-3a86-453d-b7a3-a2219de8d777) | [Code](src/584747d1-3a86-453d-b7a3-a2219de8d777/code.php) | [Settings](src/584747d1-3a86-453d-b7a3-a2219de8d777/settings.json) | Super__584747d1_3a86_453d_b7a3_a2219de8d777__Power
|
||||
- **abstract class Registry** | [Details](src/7e822c03-1b20-41d1-9427-f5b8d5836af7) | [Code](src/7e822c03-1b20-41d1-9427-f5b8d5836af7/code.php) | [Settings](src/7e822c03-1b20-41d1-9427-f5b8d5836af7/settings.json) | Super__7e822c03_1b20_41d1_9427_f5b8d5836af7__Power
|
||||
- **abstract class Schema** | [Details](src/f3c04c28-bce4-422e-be93-7d163e4e342b) | [Code](src/f3c04c28-bce4-422e-be93-7d163e4e342b/code.php) | [Settings](src/f3c04c28-bce4-422e-be93-7d163e4e342b/settings.json) | Super__f3c04c28_bce4_422e_be93_7d163e4e342b__Power
|
||||
- **Namespace**: [VDM\Joomla\Componentbuilder](#vdm-joomla-componentbuilder)
|
||||
|
||||
- **class Table** | [Details](src/bfd1d6d5-56c1-4fe9-9fee-1c5910e1f5d8) | [Code](src/bfd1d6d5-56c1-4fe9-9fee-1c5910e1f5d8/code.php) | [Settings](src/bfd1d6d5-56c1-4fe9-9fee-1c5910e1f5d8/settings.json) | Super__bfd1d6d5_56c1_4fe9_9fee_1c5910e1f5d8__Power
|
||||
@ -47,6 +48,7 @@ This repository contains an index (see below) of all the approved powers within
|
||||
- **interface LoadInterface** | [Details](src/2ad31f74-f579-499d-b98b-c4f54fd615dd) | [Code](src/2ad31f74-f579-499d-b98b-c4f54fd615dd/code.php) | [Settings](src/2ad31f74-f579-499d-b98b-c4f54fd615dd/settings.json) | Super__2ad31f74_f579_499d_b98b_c4f54fd615dd__Power
|
||||
- **interface ModelInterface** | [Details](src/8aef58c1-3f70-4bd4-b9e4-3f29fcd41cff) | [Code](src/8aef58c1-3f70-4bd4-b9e4-3f29fcd41cff/code.php) | [Settings](src/8aef58c1-3f70-4bd4-b9e4-3f29fcd41cff/settings.json) | Super__8aef58c1_3f70_4bd4_b9e4_3f29fcd41cff__Power
|
||||
- **interface Registryinterface** | [Details](src/64e291c2-11f1-423d-a44d-837cc12cc017) | [Code](src/64e291c2-11f1-423d-a44d-837cc12cc017/code.php) | [Settings](src/64e291c2-11f1-423d-a44d-837cc12cc017/settings.json) | Super__64e291c2_11f1_423d_a44d_837cc12cc017__Power
|
||||
- **interface SchemaInterface** | [Details](src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa) | [Code](src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/code.php) | [Settings](src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/settings.json) | Super__4dd11b9b_3c64_460b_aaa6_62ba467db7aa__Power
|
||||
- **interface Tableinterface** | [Details](src/2da6d6c4-eb29-4d69-8bc2-36d96e916adf) | [Code](src/2da6d6c4-eb29-4d69-8bc2-36d96e916adf/code.php) | [Settings](src/2da6d6c4-eb29-4d69-8bc2-36d96e916adf/settings.json) | Super__2da6d6c4_eb29_4d69_8bc2_36d96e916adf__Power
|
||||
- **interface UpdateInterface** | [Details](src/7179fde6-1e51-4b51-8545-7ca18f74a0f4) | [Code](src/7179fde6-1e51-4b51-8545-7ca18f74a0f4/code.php) | [Settings](src/7179fde6-1e51-4b51-8545-7ca18f74a0f4/settings.json) | Super__7179fde6_1e51_4b51_8545_7ca18f74a0f4__Power
|
||||
- **Namespace**: [VDM\Joomla\Utilities](#vdm-joomla-utilities)
|
||||
@ -68,6 +70,9 @@ This repository contains an index (see below) of all the approved powers within
|
||||
- **Namespace**: [VDM\Joomla\Componentbuilder\Service](#vdm-joomla-componentbuilder-service)
|
||||
|
||||
- **class Database** | [Details](src/4815e1c7-a433-443d-a112-d1e03d7df84b) | [Code](src/4815e1c7-a433-443d-a112-d1e03d7df84b/code.php) | [Settings](src/4815e1c7-a433-443d-a112-d1e03d7df84b/settings.json) | Super__4815e1c7_a433_443d_a112_d1e03d7df84b__Power
|
||||
- **Namespace**: [VDM\Joomla\Componentbuilder\Table](#vdm-joomla-componentbuilder-table)
|
||||
|
||||
- **final class Schema** | [Details](src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce) | [Code](src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/code.php) | [Settings](src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/settings.json) | Super__b3d2ec33_76d4_4c3b_bb2c_86ac14a221ce__Power
|
||||
- **Namespace**: [VDM\Joomla\Componentbuilder\Utilities](#vdm-joomla-componentbuilder-utilities)
|
||||
|
||||
- **abstract class FilterHelper** | [Details](src/cddcac51-9a46-47c4-ba59-105c70453bd6) | [Code](src/cddcac51-9a46-47c4-ba59-105c70453bd6/code.php) | [Settings](src/cddcac51-9a46-47c4-ba59-105c70453bd6/settings.json) | Super__cddcac51_9a46_47c4_ba59_105c70453bd6__Power
|
||||
@ -77,6 +82,7 @@ This repository contains an index (see below) of all the approved powers within
|
||||
- **Namespace**: [VDM\Joomla\Utilities\String](#vdm-joomla-utilities-string)
|
||||
|
||||
- **abstract class ClassfunctionHelper** | [Details](src/30c5b4c2-f75f-4d15-869a-f8bfedd87358) | [Code](src/30c5b4c2-f75f-4d15-869a-f8bfedd87358/code.php) | [Settings](src/30c5b4c2-f75f-4d15-869a-f8bfedd87358/settings.json) | Super__30c5b4c2_f75f_4d15_869a_f8bfedd87358__Power
|
||||
- **abstract class ComponentCodeNameHelper** | [Details](src/491dbe41-f26c-4de9-8a95-fcf87b35b56f) | [Code](src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/code.php) | [Settings](src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/settings.json) | Super__491dbe41_f26c_4de9_8a95_fcf87b35b56f__Power
|
||||
- **abstract class FieldHelper** | [Details](src/9ef0eb24-aae4-4f5a-99af-d724db44808f) | [Code](src/9ef0eb24-aae4-4f5a-99af-d724db44808f/code.php) | [Settings](src/9ef0eb24-aae4-4f5a-99af-d724db44808f/settings.json) | Super__9ef0eb24_aae4_4f5a_99af_d724db44808f__Power
|
||||
- **abstract class NamespaceHelper** | [Details](src/ce8cf834-6bac-44fb-941c-861f7e046cc0) | [Code](src/ce8cf834-6bac-44fb-941c-861f7e046cc0/code.php) | [Settings](src/ce8cf834-6bac-44fb-941c-861f7e046cc0/settings.json) | Super__ce8cf834_6bac_44fb_941c_861f7e046cc0__Power
|
||||
- **abstract class PluginHelper** | [Details](src/3cf76fbf-fd95-4a33-878e-7aff6d36b7f6) | [Code](src/3cf76fbf-fd95-4a33-878e-7aff6d36b7f6/code.php) | [Settings](src/3cf76fbf-fd95-4a33-878e-7aff6d36b7f6/settings.json) | Super__3cf76fbf_fd95_4a33_878e_7aff6d36b7f6__Power
|
||||
|
@ -11,12 +11,12 @@
|
||||
```uml
|
||||
@startuml
|
||||
interface Tableinterface #Lavender {
|
||||
+ get(string $table, ?string $field = null, ...) : mixed
|
||||
+ get(?string $table = null, ?string $field = null, ...) : mixed
|
||||
+ title(string $table) : ?array
|
||||
+ titleName(string $table) : string
|
||||
+ tables() : array
|
||||
+ exist(string $table, ?string $field = null) : bool
|
||||
+ fields(string $table, bool $default = false) : ?array
|
||||
+ fields(string $table, bool $default = false, ...) : ?array
|
||||
}
|
||||
|
||||
note right of Tableinterface::get
|
||||
@ -28,12 +28,13 @@ 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();
|
||||
|
||||
since: 3.2.0
|
||||
return: mixed
|
||||
|
||||
arguments:
|
||||
string $table
|
||||
?string $table = null
|
||||
?string $field = null
|
||||
?string $key = null
|
||||
end note
|
||||
@ -71,6 +72,11 @@ note right of Tableinterface::fields
|
||||
|
||||
since: 3.2.0
|
||||
return: ?array
|
||||
|
||||
arguments:
|
||||
string $table
|
||||
bool $default = false
|
||||
bool $details = false
|
||||
end note
|
||||
|
||||
@enduml
|
||||
|
@ -26,15 +26,16 @@ interface Tableinterface
|
||||
* 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 $table The table
|
||||
* @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, ?string $field = null, ?string $key = null);
|
||||
public function get(?string $table = null, ?string $field = null, ?string $key = null);
|
||||
|
||||
/**
|
||||
* Get title field from an area/view/table
|
||||
@ -80,10 +81,11 @@ interface Tableinterface
|
||||
*
|
||||
* @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): ?array;
|
||||
public function fields(string $table, bool $default = false, bool $details = false): ?array;
|
||||
}
|
||||
|
||||
|
@ -7,15 +7,16 @@
|
||||
* 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 $table The table
|
||||
* @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, ?string $field = null, ?string $key = null);
|
||||
public function get(?string $table = null, ?string $field = null, ?string $key = null);
|
||||
|
||||
/**
|
||||
* Get title field from an area/view/table
|
||||
@ -61,8 +62,9 @@
|
||||
*
|
||||
* @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): ?array;
|
||||
public function fields(string $table, bool $default = false, bool $details = false): ?array;
|
39
src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/README.md
Normal file
39
src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/README.md
Normal file
@ -0,0 +1,39 @@
|
||||
```
|
||||
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
|
||||
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
|
||||
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
|
||||
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
|
||||
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
|
||||
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
|
||||
```
|
||||
# abstract class ComponentCodeNameHelper (Details)
|
||||
> namespace: **VDM\Joomla\Utilities\String**
|
||||
```uml
|
||||
@startuml
|
||||
abstract ComponentCodeNameHelper #Orange {
|
||||
+ {static} safe(string $string) : string
|
||||
}
|
||||
|
||||
note right of ComponentCodeNameHelper::safe
|
||||
Making component code name safe for namespacing.
|
||||
This function processes a given string to format it according to PHP namespace naming conventions.
|
||||
ensures no spaces or underscores are present.
|
||||
|
||||
since: 3.2.1
|
||||
return: string
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
---
|
||||
```
|
||||
██╗ ██████╗██████╗
|
||||
██║██╔════╝██╔══██╗
|
||||
██║██║ ██████╔╝
|
||||
██ ██║██║ ██╔══██╗
|
||||
╚█████╔╝╚██████╗██████╔╝
|
||||
╚════╝ ╚═════╝╚═════╝
|
||||
```
|
||||
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
|
48
src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/code.php
Normal file
48
src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/code.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Component.Builder
|
||||
*
|
||||
* @created 3rd September, 2020
|
||||
* @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\Utilities\String;
|
||||
|
||||
|
||||
/**
|
||||
* Control the naming of a component code name
|
||||
*
|
||||
* @since 3.2.1
|
||||
*/
|
||||
abstract class ComponentCodeNameHelper
|
||||
{
|
||||
/**
|
||||
* Making component code name safe for namespacing.
|
||||
*
|
||||
* This function processes a given string to format it according to PHP namespace naming conventions.
|
||||
* ensures no spaces or underscores are present.
|
||||
*
|
||||
* @param string $string The component code name string to make safe
|
||||
*
|
||||
* @return string A namespace-safe string on success
|
||||
* @since 3.2.1
|
||||
*/
|
||||
public static function safe(string $string): string
|
||||
{
|
||||
// Trim whitespace from both ends of the string
|
||||
$string = trim($string);
|
||||
|
||||
// Replace any sequence of non-alphanumeric characters or underscores with a single underscore
|
||||
$string = preg_replace('/[^\p{L}\p{N}]+/u', '', $string);
|
||||
|
||||
// Ensure the first character is uppercase (useful if the input string started with an invalid character)
|
||||
$string = ucfirst($string);
|
||||
|
||||
// Return the namespace-safe component code name
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
25
src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/code.power
Normal file
25
src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/code.power
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Making component code name safe for namespacing.
|
||||
*
|
||||
* This function processes a given string to format it according to PHP namespace naming conventions.
|
||||
* ensures no spaces or underscores are present.
|
||||
*
|
||||
* @param string $string The component code name string to make safe
|
||||
*
|
||||
* @return string A namespace-safe string on success
|
||||
* @since 3.2.1
|
||||
*/
|
||||
public static function safe(string $string): string
|
||||
{
|
||||
// Trim whitespace from both ends of the string
|
||||
$string = trim($string);
|
||||
|
||||
// Replace any sequence of non-alphanumeric characters or underscores with a single underscore
|
||||
$string = preg_replace('/[^\p{L}\p{N}]+/u', '', $string);
|
||||
|
||||
// Ensure the first character is uppercase (useful if the input string started with an invalid character)
|
||||
$string = ucfirst($string);
|
||||
|
||||
// Return the namespace-safe component code name
|
||||
return $string;
|
||||
}
|
18
src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/settings.json
Normal file
18
src/491dbe41-f26c-4de9-8a95-fcf87b35b56f/settings.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"add_head": "0",
|
||||
"add_licensing_template": "2",
|
||||
"extends": "0",
|
||||
"guid": "491dbe41-f26c-4de9-8a95-fcf87b35b56f",
|
||||
"implements": null,
|
||||
"load_selection": null,
|
||||
"name": "ComponentCodeNameHelper",
|
||||
"power_version": "1.0.0",
|
||||
"system_name": "String ComponentCodeName Helper",
|
||||
"type": "abstract class",
|
||||
"use_selection": null,
|
||||
"namespace": "[[[NamespacePrefix]]]\\Joomla\\Utilities.String.ComponentCodeNameHelper",
|
||||
"description": "Control the naming of a component code name\r\n\r\n@since 3.2.1",
|
||||
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 3rd September, 2020\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
|
||||
"head": "",
|
||||
"composer": ""
|
||||
}
|
53
src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/README.md
Normal file
53
src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/README.md
Normal file
@ -0,0 +1,53 @@
|
||||
```
|
||||
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
|
||||
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
|
||||
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
|
||||
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
|
||||
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
|
||||
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
|
||||
```
|
||||
# interface SchemaInterface (Details)
|
||||
> namespace: **VDM\Joomla\Interfaces**
|
||||
```uml
|
||||
@startuml
|
||||
interface SchemaInterface #Lavender {
|
||||
+ update() : array
|
||||
+ createTable(string $table) : void
|
||||
+ updateSchema(string $table) : void
|
||||
}
|
||||
|
||||
note right of SchemaInterface::update
|
||||
Check and update database schema for missing fields or tables.
|
||||
|
||||
since: 3.2.1
|
||||
return: array
|
||||
end note
|
||||
|
||||
note right of SchemaInterface::createTable
|
||||
Create a table with all necessary fields.
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
note right of SchemaInterface::updateSchema
|
||||
Update the schema of an existing table.
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
---
|
||||
```
|
||||
██╗ ██████╗██████╗
|
||||
██║██╔════╝██╔══██╗
|
||||
██║██║ ██████╔╝
|
||||
██ ██║██║ ██╔══██╗
|
||||
╚█████╔╝╚██████╗██████╔╝
|
||||
╚════╝ ╚═════╝╚═════╝
|
||||
```
|
||||
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
|
53
src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/code.php
Normal file
53
src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/code.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?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\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;
|
||||
}
|
||||
|
30
src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/code.power
Normal file
30
src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/code.power
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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;
|
18
src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/settings.json
Normal file
18
src/4dd11b9b-3c64-460b-aaa6-62ba467db7aa/settings.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"add_head": "0",
|
||||
"add_licensing_template": "2",
|
||||
"extends": "0",
|
||||
"guid": "4dd11b9b-3c64-460b-aaa6-62ba467db7aa",
|
||||
"implements": null,
|
||||
"load_selection": null,
|
||||
"name": "SchemaInterface",
|
||||
"power_version": "1.0.0",
|
||||
"system_name": "VDM.SchemaInterface",
|
||||
"type": "interface",
|
||||
"use_selection": null,
|
||||
"namespace": "[[[NamespacePrefix]]]\\Joomla\\Interfaces.SchemaInterface",
|
||||
"description": "Schema Checking Interface\r\n\r\n@since 3.2.1",
|
||||
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
|
||||
"head": "",
|
||||
"composer": ""
|
||||
}
|
@ -11,19 +11,19 @@
|
||||
```uml
|
||||
@startuml
|
||||
interface Registryinterface #Lavender {
|
||||
+ set(string $path, mixed $value) : void
|
||||
+ add(string $path, mixed $value, ...) : void
|
||||
+ set(string $path, mixed $value) : static
|
||||
+ add(string $path, mixed $value, ...) : static
|
||||
+ get(string $path, mixed $default = null) : mixed
|
||||
+ remove(string $path) : void
|
||||
+ remove(string $path) : static
|
||||
+ exists(string $path) : bool
|
||||
+ setSeparator(?string $value) : void
|
||||
+ setSeparator(?string $value) : static
|
||||
}
|
||||
|
||||
note right of Registryinterface::set
|
||||
Sets a value into the registry using multiple keys.
|
||||
|
||||
since: 3.2.0
|
||||
return: void
|
||||
return: static
|
||||
end note
|
||||
|
||||
note right of Registryinterface::add
|
||||
@ -33,7 +33,7 @@ Default is $addAsArray = false (if null) in base class.
|
||||
Override in child class allowed set class property $addAsArray = true.
|
||||
|
||||
since: 3.2.0
|
||||
return: void
|
||||
return: static
|
||||
|
||||
arguments:
|
||||
string $path
|
||||
@ -52,7 +52,7 @@ note right of Registryinterface::remove
|
||||
Removes a value (or sub-array) from the registry using multiple keys.
|
||||
|
||||
since: 3.2.0
|
||||
return: void
|
||||
return: static
|
||||
end note
|
||||
|
||||
note right of Registryinterface::exists
|
||||
@ -66,7 +66,7 @@ note right of Registryinterface::setSeparator
|
||||
Sets a separator value
|
||||
|
||||
since: 3.2.0
|
||||
return: void
|
||||
return: static
|
||||
end note
|
||||
|
||||
@enduml
|
||||
|
@ -26,10 +26,10 @@ interface Registryinterface
|
||||
* @param mixed $value Value of entry
|
||||
*
|
||||
* @throws \InvalidArgumentException If any of the path values are not a number or string.
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function set(string $path, $value): void;
|
||||
public function set(string $path, $value): static;
|
||||
|
||||
/**
|
||||
* Adds content into the registry. If a key exists,
|
||||
@ -42,10 +42,10 @@ interface Registryinterface
|
||||
* Override in child class allowed set class property $addAsArray = true.
|
||||
*
|
||||
* @throws \InvalidArgumentException If any of the path values are not a number or string.
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function add(string $path, $value, ?bool $asArray = null): void;
|
||||
public function add(string $path, $value, ?bool $asArray = null): static;
|
||||
|
||||
/**
|
||||
* Retrieves a value (or sub-array) from the registry using multiple keys.
|
||||
@ -65,10 +65,10 @@ interface Registryinterface
|
||||
* @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
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function remove(string $path): void;
|
||||
public function remove(string $path): static;
|
||||
|
||||
/**
|
||||
* Checks the existence of a particular location in the registry using multiple keys.
|
||||
@ -86,9 +86,9 @@ interface Registryinterface
|
||||
*
|
||||
* @param string|null $value The value to set.
|
||||
*
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function setSeparator(?string $value): void;
|
||||
public function setSeparator(?string $value): static;
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,10 @@
|
||||
* @param mixed $value Value of entry
|
||||
*
|
||||
* @throws \InvalidArgumentException If any of the path values are not a number or string.
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function set(string $path, $value): void;
|
||||
public function set(string $path, $value): static;
|
||||
|
||||
/**
|
||||
* Adds content into the registry. If a key exists,
|
||||
@ -21,10 +21,10 @@
|
||||
* Override in child class allowed set class property $addAsArray = true.
|
||||
*
|
||||
* @throws \InvalidArgumentException If any of the path values are not a number or string.
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function add(string $path, $value, ?bool $asArray = null): void;
|
||||
public function add(string $path, $value, ?bool $asArray = null): static;
|
||||
|
||||
/**
|
||||
* Retrieves a value (or sub-array) from the registry using multiple keys.
|
||||
@ -44,10 +44,10 @@
|
||||
* @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
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function remove(string $path): void;
|
||||
public function remove(string $path): static;
|
||||
|
||||
/**
|
||||
* Checks the existence of a particular location in the registry using multiple keys.
|
||||
@ -65,7 +65,7 @@
|
||||
*
|
||||
* @param string|null $value The value to set.
|
||||
*
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function setSeparator(?string $value): void;
|
||||
public function setSeparator(?string $value): static;
|
@ -13,12 +13,12 @@
|
||||
@startuml
|
||||
abstract Registry #Orange {
|
||||
# ?string $separator
|
||||
+ set(string $path, mixed $value) : void
|
||||
+ add(string $path, mixed $value, ...) : void
|
||||
+ set(string $path, mixed $value) : static
|
||||
+ add(string $path, mixed $value, ...) : static
|
||||
+ get(string $path, mixed $default = null) : mixed
|
||||
+ remove(string $path) : void
|
||||
+ remove(string $path) : static
|
||||
+ exists(string $path) : bool
|
||||
+ setSeparator(?string $value) : void
|
||||
+ setSeparator(?string $value) : static
|
||||
# getActiveKeys(string $path) : ?array
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ note right of Registry::set
|
||||
Sets a value into the registry using multiple keys.
|
||||
|
||||
since: 3.2.0
|
||||
return: void
|
||||
return: static
|
||||
end note
|
||||
|
||||
note right of Registry::add
|
||||
@ -36,7 +36,7 @@ Default is $addAsArray = false (if null) in base class.
|
||||
Override in child class allowed set class property $addAsArray = true.
|
||||
|
||||
since: 3.2.0
|
||||
return: void
|
||||
return: static
|
||||
|
||||
arguments:
|
||||
string $path
|
||||
@ -55,7 +55,7 @@ note right of Registry::remove
|
||||
Removes a value (or sub-array) from the registry using multiple keys.
|
||||
|
||||
since: 3.2.0
|
||||
return: void
|
||||
return: static
|
||||
end note
|
||||
|
||||
note right of Registry::exists
|
||||
@ -69,7 +69,7 @@ note right of Registry::setSeparator
|
||||
Sets a separator value
|
||||
|
||||
since: 3.2.0
|
||||
return: void
|
||||
return: static
|
||||
end note
|
||||
|
||||
note right of Registry::getActiveKeys
|
||||
|
@ -41,10 +41,10 @@ abstract class Registry extends ActiveRegistry implements Activeregistryinterfac
|
||||
* @param mixed $value Value of entry
|
||||
*
|
||||
* @throws \InvalidArgumentException If any of the path values are not a number or string.
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function set(string $path, $value): void
|
||||
public function set(string $path, $value): static
|
||||
{
|
||||
if (($keys = $this->getActiveKeys($path)) === null)
|
||||
{
|
||||
@ -52,6 +52,8 @@ abstract class Registry extends ActiveRegistry implements Activeregistryinterfac
|
||||
}
|
||||
|
||||
$this->setActive($value, ...$keys);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,10 +67,10 @@ abstract class Registry extends ActiveRegistry implements Activeregistryinterfac
|
||||
* Override in child class allowed set class property $addAsArray = true.
|
||||
*
|
||||
* @throws \InvalidArgumentException If any of the path values are not a number or string.
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function add(string $path, $value, ?bool $asArray = null): void
|
||||
public function add(string $path, $value, ?bool $asArray = null): static
|
||||
{
|
||||
if (($keys = $this->getActiveKeys($path)) === null)
|
||||
{
|
||||
@ -76,6 +78,8 @@ abstract class Registry extends ActiveRegistry implements Activeregistryinterfac
|
||||
}
|
||||
|
||||
$this->addActive($value, $asArray, ...$keys);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -104,10 +108,10 @@ abstract class Registry extends ActiveRegistry implements Activeregistryinterfac
|
||||
* @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
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function remove(string $path): void
|
||||
public function remove(string $path): static
|
||||
{
|
||||
if (($keys = $this->getActiveKeys($path)) === null)
|
||||
{
|
||||
@ -115,6 +119,8 @@ abstract class Registry extends ActiveRegistry implements Activeregistryinterfac
|
||||
}
|
||||
|
||||
$this->removeActive(...$keys);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -141,12 +147,14 @@ abstract class Registry extends ActiveRegistry implements Activeregistryinterfac
|
||||
*
|
||||
* @param string|null $value The value to set.
|
||||
*
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function setSeparator(?string $value): void
|
||||
public function setSeparator(?string $value): static
|
||||
{
|
||||
$this->separator = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,10 +13,10 @@
|
||||
* @param mixed $value Value of entry
|
||||
*
|
||||
* @throws \InvalidArgumentException If any of the path values are not a number or string.
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function set(string $path, $value): void
|
||||
public function set(string $path, $value): static
|
||||
{
|
||||
if (($keys = $this->getActiveKeys($path)) === null)
|
||||
{
|
||||
@ -24,6 +24,8 @@
|
||||
}
|
||||
|
||||
$this->setActive($value, ...$keys);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,10 +39,10 @@
|
||||
* Override in child class allowed set class property $addAsArray = true.
|
||||
*
|
||||
* @throws \InvalidArgumentException If any of the path values are not a number or string.
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function add(string $path, $value, ?bool $asArray = null): void
|
||||
public function add(string $path, $value, ?bool $asArray = null): static
|
||||
{
|
||||
if (($keys = $this->getActiveKeys($path)) === null)
|
||||
{
|
||||
@ -48,6 +50,8 @@
|
||||
}
|
||||
|
||||
$this->addActive($value, $asArray, ...$keys);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,10 +80,10 @@
|
||||
* @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
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function remove(string $path): void
|
||||
public function remove(string $path): static
|
||||
{
|
||||
if (($keys = $this->getActiveKeys($path)) === null)
|
||||
{
|
||||
@ -87,6 +91,8 @@
|
||||
}
|
||||
|
||||
$this->removeActive(...$keys);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,12 +119,14 @@
|
||||
*
|
||||
* @param string|null $value The value to set.
|
||||
*
|
||||
* @return void
|
||||
* @return $this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function setSeparator(?string $value): void
|
||||
public function setSeparator(?string $value): static
|
||||
{
|
||||
$this->separator = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
45
src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/README.md
Normal file
45
src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/README.md
Normal file
@ -0,0 +1,45 @@
|
||||
```
|
||||
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
|
||||
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
|
||||
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
|
||||
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
|
||||
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
|
||||
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
|
||||
```
|
||||
# final class Schema (Details)
|
||||
> namespace: **VDM\Joomla\Componentbuilder\Table**
|
||||
> extends: **ExtendingSchema**
|
||||
```uml
|
||||
@startuml
|
||||
class Schema << (F,LightGreen) >> #RoyalBlue {
|
||||
+ __construct(?Table $table = null)
|
||||
# getCode() : string
|
||||
}
|
||||
|
||||
note right of Schema::__construct
|
||||
Constructor.
|
||||
|
||||
since: 3.2.1
|
||||
end note
|
||||
|
||||
note right of Schema::getCode
|
||||
Get the targeted component code
|
||||
|
||||
since: 3.2.1
|
||||
return: string
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
---
|
||||
```
|
||||
██╗ ██████╗██████╗
|
||||
██║██╔════╝██╔══██╗
|
||||
██║██║ ██████╔╝
|
||||
██ ██║██║ ██╔══██╗
|
||||
╚█████╔╝╚██████╗██████╔╝
|
||||
╚════╝ ╚═════╝╚═════╝
|
||||
```
|
||||
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
|
52
src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/code.php
Normal file
52
src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/code.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?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\Componentbuilder\Table;
|
||||
|
||||
|
||||
use VDM\Joomla\Componentbuilder\Table;
|
||||
use VDM\Joomla\Interfaces\SchemaInterface;
|
||||
use VDM\Joomla\Abstraction\Schema as ExtendingSchema;
|
||||
|
||||
|
||||
/**
|
||||
* JCB 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';
|
||||
}
|
||||
}
|
||||
|
24
src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/code.power
Normal file
24
src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/code.power
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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 '[[[component]]]';
|
||||
}
|
25
src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/settings.json
Normal file
25
src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/settings.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"add_head": "0",
|
||||
"add_licensing_template": "2",
|
||||
"extends": "f3c04c28-bce4-422e-be93-7d163e4e342b",
|
||||
"guid": "b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce",
|
||||
"implements": [
|
||||
"4dd11b9b-3c64-460b-aaa6-62ba467db7aa"
|
||||
],
|
||||
"load_selection": null,
|
||||
"name": "Schema",
|
||||
"power_version": "2.0.0",
|
||||
"system_name": "JCB.Table.Schema",
|
||||
"type": "final class",
|
||||
"use_selection": {
|
||||
"use_selection0": {
|
||||
"use": "bfd1d6d5-56c1-4fe9-9fee-1c5910e1f5d8",
|
||||
"as": "default"
|
||||
}
|
||||
},
|
||||
"namespace": "[[[NamespacePrefix]]]\\Joomla\\Componentbuilder.Table.Schema",
|
||||
"description": "JCB Tables Schema\r\n\r\n@since 3.2.1",
|
||||
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
|
||||
"head": "",
|
||||
"composer": ""
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -12,16 +12,17 @@
|
||||
@startuml
|
||||
abstract BaseTable #Orange {
|
||||
# array $tables
|
||||
+ get(string $table, ?string $field = null, ...) : mixed
|
||||
+ get(?string $table = null, ?string $field = null, ...) : mixed
|
||||
+ title(string $table) : ?array
|
||||
+ titleName(string $table) : string
|
||||
+ tables() : array
|
||||
+ exist(string $table, ?string $field = null) : bool
|
||||
+ fields(string $table, bool $default = false) : ?array
|
||||
+ fields(string $table, bool $default = false, ...) : ?array
|
||||
# addDefault(array $fields) : array
|
||||
# addDefaultDetails(array $fields) : array
|
||||
# isDefault(string $field) : bool
|
||||
# getDefault(string $field) : ?array
|
||||
# getDefaultKey(string $field, string $key) : ?string
|
||||
# getDefaultKey(string $field, string $key) : mixed
|
||||
}
|
||||
|
||||
note right of BaseTable::get
|
||||
@ -33,12 +34,13 @@ 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();
|
||||
|
||||
since: 3.2.0
|
||||
since: 3.2.1
|
||||
return: mixed
|
||||
|
||||
arguments:
|
||||
string $table
|
||||
?string $table = null
|
||||
?string $field = null
|
||||
?string $key = null
|
||||
end note
|
||||
@ -76,6 +78,11 @@ note left of BaseTable::fields
|
||||
|
||||
since: 3.2.0
|
||||
return: ?array
|
||||
|
||||
arguments:
|
||||
string $table
|
||||
bool $default = false
|
||||
bool $details = false
|
||||
end note
|
||||
|
||||
note right of BaseTable::addDefault
|
||||
@ -85,25 +92,32 @@ note right of BaseTable::addDefault
|
||||
return: array
|
||||
end note
|
||||
|
||||
note left of BaseTable::isDefault
|
||||
note left of BaseTable::addDefaultDetails
|
||||
Add the default fields
|
||||
|
||||
since: 3.2.0
|
||||
return: array
|
||||
end note
|
||||
|
||||
note right of BaseTable::isDefault
|
||||
Check if the field is a default field
|
||||
|
||||
since: 3.2.0
|
||||
return: bool
|
||||
end note
|
||||
|
||||
note right of BaseTable::getDefault
|
||||
note left of BaseTable::getDefault
|
||||
Get a default field
|
||||
|
||||
since: 3.2.0
|
||||
return: ?array
|
||||
end note
|
||||
|
||||
note left of BaseTable::getDefaultKey
|
||||
note right of BaseTable::getDefaultKey
|
||||
Get a default field property
|
||||
|
||||
since: 3.2.0
|
||||
return: ?string
|
||||
return: mixed
|
||||
end note
|
||||
|
||||
@enduml
|
||||
|
@ -34,7 +34,7 @@ abstract class BaseTable implements Tableinterface
|
||||
* All default fields
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
* @since 3.2.1
|
||||
**/
|
||||
protected array $defaults = [
|
||||
'id' => [
|
||||
@ -45,7 +45,29 @@ abstract class BaseTable implements Tableinterface
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(11)',
|
||||
'default' => '',
|
||||
'auto_increment' => true,
|
||||
'primary_key' => true,
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'asset_id' => [
|
||||
'name' => 'asset_id',
|
||||
'label' => NULL,
|
||||
'type' => NULL,
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'comment' => 'FK to the #__assets table.'
|
||||
]
|
||||
],
|
||||
'ordering' => [
|
||||
'name' => 'ordering',
|
||||
@ -54,7 +76,12 @@ abstract class BaseTable implements Tableinterface
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(11)',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'published' => [
|
||||
'name' => 'published',
|
||||
@ -63,7 +90,14 @@ abstract class BaseTable implements Tableinterface
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'TINYINT(3)',
|
||||
'default' => '1',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'key' => true,
|
||||
'key_name' => 'state'
|
||||
]
|
||||
],
|
||||
'modified_by' => [
|
||||
'name' => 'modified_by',
|
||||
@ -72,7 +106,14 @@ abstract class BaseTable implements Tableinterface
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'key' => true,
|
||||
'key_name' => 'modifiedby'
|
||||
]
|
||||
],
|
||||
'modified' => [
|
||||
'name' => 'modified',
|
||||
@ -81,7 +122,12 @@ abstract class BaseTable implements Tableinterface
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'DATETIME',
|
||||
'default' => '0000-00-00 00:00:00',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'created_by' => [
|
||||
'name' => 'created_by',
|
||||
@ -90,7 +136,14 @@ abstract class BaseTable implements Tableinterface
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'key' => true,
|
||||
'key_name' => 'createdby'
|
||||
]
|
||||
],
|
||||
'created' => [
|
||||
'name' => 'created',
|
||||
@ -99,7 +152,42 @@ abstract class BaseTable implements Tableinterface
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'DATETIME',
|
||||
'default' => '0000-00-00 00:00:00',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'checked_out' => [
|
||||
'name' => 'checked_out',
|
||||
'label' => NULL,
|
||||
'type' => NULL,
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'key' => true,
|
||||
'key_name' => 'checkout'
|
||||
]
|
||||
],
|
||||
'checked_out_time' => [
|
||||
'name' => 'checked_out_time',
|
||||
'label' => NULL,
|
||||
'type' => NULL,
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'DATETIME',
|
||||
'default' => '0000-00-00 00:00:00',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'hits' => [
|
||||
'name' => 'hits',
|
||||
@ -108,7 +196,12 @@ abstract class BaseTable implements Tableinterface
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'version' => [
|
||||
'name' => 'version',
|
||||
@ -117,7 +210,26 @@ abstract class BaseTable implements Tableinterface
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '1',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'params' => [
|
||||
'name' => 'params',
|
||||
'label' => NULL,
|
||||
'type' => NULL,
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => 'json',
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'TEXT',
|
||||
'default' => '',
|
||||
'null_switch' => 'NULL'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
@ -130,48 +242,41 @@ abstract class BaseTable implements Tableinterface
|
||||
* 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 $table The table
|
||||
* @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
|
||||
* @since 3.2.1
|
||||
*/
|
||||
public function get(string $table, ?string $field = null, ?string $key = null)
|
||||
public function get(?string $table = null, ?string $field = null, ?string $key = null)
|
||||
{
|
||||
// return the item/field/column of an area/view/table
|
||||
if (is_string($field) && is_string($key))
|
||||
// Return specific value
|
||||
if ($table && $field && $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->tables[$table][$field][$key] ?? $this->getDefaultKey($field, $key);
|
||||
}
|
||||
|
||||
return $this->getDefaultKey($field, $key);
|
||||
}
|
||||
// return the item/field/column of an area/view/table
|
||||
elseif (is_string($field))
|
||||
// Return field within table
|
||||
if ($table && $field)
|
||||
{
|
||||
if (isset($this->tables[$table][$field]))
|
||||
{
|
||||
return $this->tables[$table][$field];
|
||||
return $this->tables[$table][$field] ?? $this->getDefault($field);
|
||||
}
|
||||
|
||||
return $this->getDefault($field);
|
||||
}
|
||||
// return an area/view/table
|
||||
elseif ($table !== 'All')
|
||||
// Return all fields in a table or all tables if 'All' is passed
|
||||
if ($table)
|
||||
{
|
||||
if (isset($this->tables[$table]))
|
||||
if (strtoupper($table) === 'ALL')
|
||||
{
|
||||
return $this->tables[$table];
|
||||
}
|
||||
return null;
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
// return all
|
||||
return $this->tables[$table] ?? null;
|
||||
}
|
||||
|
||||
// Return all tables
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
@ -268,27 +373,30 @@ abstract class BaseTable implements Tableinterface
|
||||
*
|
||||
* @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): ?array
|
||||
public function fields(string $table, bool $default = false, bool $details = false): ?array
|
||||
{
|
||||
// return all fields of an area/view/table
|
||||
if (($table = $this->get($table)) !== null)
|
||||
// Retrieve fields from the specified table
|
||||
$fields = $this->get($table);
|
||||
|
||||
if ($fields === null)
|
||||
{
|
||||
if ($default)
|
||||
{
|
||||
return $this->addDefault(array_keys($table));
|
||||
}
|
||||
else
|
||||
{
|
||||
return array_keys($table);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// none found
|
||||
return null;
|
||||
// Determine the fields output based on the $default and $details flags
|
||||
if ($details)
|
||||
{
|
||||
return $default ? $this->addDefaultDetails($fields) : $fields;
|
||||
}
|
||||
|
||||
$fieldKeys = array_keys($fields);
|
||||
|
||||
return $default ? $this->addDefault($fieldKeys) : $fieldKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -304,6 +412,11 @@ abstract class BaseTable implements Tableinterface
|
||||
// add default fields
|
||||
foreach ($this->defaults as $default)
|
||||
{
|
||||
if (in_array($default['name'], $fields))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// used just for loading the fields
|
||||
$order = $default['order'] ?? 1;
|
||||
unset($default['order']);
|
||||
@ -321,6 +434,31 @@ abstract class BaseTable implements Tableinterface
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the default fields
|
||||
*
|
||||
* @param array $fields The table dynamic fields
|
||||
*
|
||||
* @return array Fields (with defaults details added)
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function addDefaultDetails(array $fields): array
|
||||
{
|
||||
// add default fields
|
||||
foreach ($this->defaults as $default)
|
||||
{
|
||||
// remove ordering for now
|
||||
unset($default['order']);
|
||||
|
||||
if (!isset($fields[$default['name']]))
|
||||
{
|
||||
$fields[$default['name']] = $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the field is a default field
|
||||
*
|
||||
@ -353,10 +491,10 @@ abstract class BaseTable implements Tableinterface
|
||||
* @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
|
||||
* @return mixed String value if a default field property exist
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function getDefaultKey(string $field, string $key): ?string
|
||||
protected function getDefaultKey(string $field, string $key)
|
||||
{
|
||||
return $this->defaults[$field][$key] ?? null;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* All default fields
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
* @since 3.2.1
|
||||
**/
|
||||
protected array $defaults = [
|
||||
'id' => [
|
||||
@ -21,7 +21,29 @@
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(11)',
|
||||
'default' => '',
|
||||
'auto_increment' => true,
|
||||
'primary_key' => true,
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'asset_id' => [
|
||||
'name' => 'asset_id',
|
||||
'label' => NULL,
|
||||
'type' => NULL,
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'comment' => 'FK to the #__assets table.'
|
||||
]
|
||||
],
|
||||
'ordering' => [
|
||||
'name' => 'ordering',
|
||||
@ -30,7 +52,12 @@
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(11)',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'published' => [
|
||||
'name' => 'published',
|
||||
@ -39,7 +66,14 @@
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'TINYINT(3)',
|
||||
'default' => '1',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'key' => true,
|
||||
'key_name' => 'state'
|
||||
]
|
||||
],
|
||||
'modified_by' => [
|
||||
'name' => 'modified_by',
|
||||
@ -48,7 +82,14 @@
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'key' => true,
|
||||
'key_name' => 'modifiedby'
|
||||
]
|
||||
],
|
||||
'modified' => [
|
||||
'name' => 'modified',
|
||||
@ -57,7 +98,12 @@
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'DATETIME',
|
||||
'default' => '0000-00-00 00:00:00',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'created_by' => [
|
||||
'name' => 'created_by',
|
||||
@ -66,7 +112,14 @@
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'key' => true,
|
||||
'key_name' => 'createdby'
|
||||
]
|
||||
],
|
||||
'created' => [
|
||||
'name' => 'created',
|
||||
@ -75,7 +128,42 @@
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'DATETIME',
|
||||
'default' => '0000-00-00 00:00:00',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'checked_out' => [
|
||||
'name' => 'checked_out',
|
||||
'label' => NULL,
|
||||
'type' => NULL,
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'key' => true,
|
||||
'key_name' => 'checkout'
|
||||
]
|
||||
],
|
||||
'checked_out_time' => [
|
||||
'name' => 'checked_out_time',
|
||||
'label' => NULL,
|
||||
'type' => NULL,
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'DATETIME',
|
||||
'default' => '0000-00-00 00:00:00',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'hits' => [
|
||||
'name' => 'hits',
|
||||
@ -84,7 +172,12 @@
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'version' => [
|
||||
'name' => 'version',
|
||||
@ -93,7 +186,26 @@
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => NULL,
|
||||
'tab_name' => NULL
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'INT(10) unsigned',
|
||||
'default' => '1',
|
||||
'null_switch' => 'NOT NULL'
|
||||
]
|
||||
],
|
||||
'params' => [
|
||||
'name' => 'params',
|
||||
'label' => NULL,
|
||||
'type' => NULL,
|
||||
'title' => false,
|
||||
'list' => NULL,
|
||||
'store' => 'json',
|
||||
'tab_name' => NULL,
|
||||
'db' => [
|
||||
'type' => 'TEXT',
|
||||
'default' => '',
|
||||
'null_switch' => 'NULL'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
@ -106,48 +218,41 @@
|
||||
* 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 $table The table
|
||||
* @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
|
||||
* @since 3.2.1
|
||||
*/
|
||||
public function get(string $table, ?string $field = null, ?string $key = null)
|
||||
public function get(?string $table = null, ?string $field = null, ?string $key = null)
|
||||
{
|
||||
// return the item/field/column of an area/view/table
|
||||
if (is_string($field) && is_string($key))
|
||||
// Return specific value
|
||||
if ($table && $field && $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->tables[$table][$field][$key] ?? $this->getDefaultKey($field, $key);
|
||||
}
|
||||
|
||||
return $this->getDefaultKey($field, $key);
|
||||
}
|
||||
// return the item/field/column of an area/view/table
|
||||
elseif (is_string($field))
|
||||
// Return field within table
|
||||
if ($table && $field)
|
||||
{
|
||||
if (isset($this->tables[$table][$field]))
|
||||
{
|
||||
return $this->tables[$table][$field];
|
||||
return $this->tables[$table][$field] ?? $this->getDefault($field);
|
||||
}
|
||||
|
||||
return $this->getDefault($field);
|
||||
}
|
||||
// return an area/view/table
|
||||
elseif ($table !== 'All')
|
||||
// Return all fields in a table or all tables if 'All' is passed
|
||||
if ($table)
|
||||
{
|
||||
if (isset($this->tables[$table]))
|
||||
if (strtoupper($table) === 'ALL')
|
||||
{
|
||||
return $this->tables[$table];
|
||||
}
|
||||
return null;
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
// return all
|
||||
return $this->tables[$table] ?? null;
|
||||
}
|
||||
|
||||
// Return all tables
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
@ -244,27 +349,30 @@
|
||||
*
|
||||
* @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): ?array
|
||||
public function fields(string $table, bool $default = false, bool $details = false): ?array
|
||||
{
|
||||
// return all fields of an area/view/table
|
||||
if (($table = $this->get($table)) !== null)
|
||||
// Retrieve fields from the specified table
|
||||
$fields = $this->get($table);
|
||||
|
||||
if ($fields === null)
|
||||
{
|
||||
if ($default)
|
||||
{
|
||||
return $this->addDefault(array_keys($table));
|
||||
}
|
||||
else
|
||||
{
|
||||
return array_keys($table);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// none found
|
||||
return null;
|
||||
// Determine the fields output based on the $default and $details flags
|
||||
if ($details)
|
||||
{
|
||||
return $default ? $this->addDefaultDetails($fields) : $fields;
|
||||
}
|
||||
|
||||
$fieldKeys = array_keys($fields);
|
||||
|
||||
return $default ? $this->addDefault($fieldKeys) : $fieldKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -280,6 +388,11 @@
|
||||
// add default fields
|
||||
foreach ($this->defaults as $default)
|
||||
{
|
||||
if (in_array($default['name'], $fields))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// used just for loading the fields
|
||||
$order = $default['order'] ?? 1;
|
||||
unset($default['order']);
|
||||
@ -297,6 +410,31 @@
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the default fields
|
||||
*
|
||||
* @param array $fields The table dynamic fields
|
||||
*
|
||||
* @return array Fields (with defaults details added)
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function addDefaultDetails(array $fields): array
|
||||
{
|
||||
// add default fields
|
||||
foreach ($this->defaults as $default)
|
||||
{
|
||||
// remove ordering for now
|
||||
unset($default['order']);
|
||||
|
||||
if (!isset($fields[$default['name']]))
|
||||
{
|
||||
$fields[$default['name']] = $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the field is a default field
|
||||
*
|
||||
@ -329,10 +467,10 @@
|
||||
* @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
|
||||
* @return mixed String value if a default field property exist
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function getDefaultKey(string $field, string $key): ?string
|
||||
protected function getDefaultKey(string $field, string $key)
|
||||
{
|
||||
return $this->defaults[$field][$key] ?? null;
|
||||
}
|
178
src/f3c04c28-bce4-422e-be93-7d163e4e342b/README.md
Normal file
178
src/f3c04c28-bce4-422e-be93-7d163e4e342b/README.md
Normal file
@ -0,0 +1,178 @@
|
||||
```
|
||||
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
|
||||
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
|
||||
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
|
||||
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
|
||||
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
|
||||
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
|
||||
```
|
||||
# abstract class Schema (Details)
|
||||
> namespace: **VDM\Joomla\Abstraction**
|
||||
```uml
|
||||
@startuml
|
||||
abstract Schema #Orange {
|
||||
# Table $table
|
||||
# $db
|
||||
- array $tables
|
||||
- string $prefix
|
||||
- array $uniqueKeys
|
||||
- array $keys
|
||||
- array $columns
|
||||
- array $success
|
||||
+ __construct(Table $table)
|
||||
+ update() : array
|
||||
+ createTable(string $table) : void
|
||||
+ updateSchema(string $table) : void
|
||||
# {abstract} getCode() : string
|
||||
# addMissingColumns(string $table, array $columns) : void
|
||||
# checkColumnsDataType(string $table, array $columns) : void
|
||||
# updateColumnsDataType(string $table, array $columns) : void
|
||||
# updateColumnDataType(string $updateString, string $table, ...) : bool
|
||||
# getTableKeys() : string
|
||||
# setUniqueKey(array $column) : void
|
||||
# setKey(array $column) : void
|
||||
# getTable(string $table) : string
|
||||
- tableExists(string $table) : bool
|
||||
- getExistingColumns(string $table) : array
|
||||
- getColumnDefinition(string $table, string $field) : ?string
|
||||
- setKeys(array $column) : void
|
||||
}
|
||||
|
||||
note right of Schema::__construct
|
||||
Constructor.
|
||||
|
||||
since: 3.2.1
|
||||
end note
|
||||
|
||||
note left of Schema::update
|
||||
Check and update database schema for missing fields or tables.
|
||||
|
||||
since: 3.2.1
|
||||
return: array
|
||||
end note
|
||||
|
||||
note right of Schema::createTable
|
||||
Create a table with all necessary fields.
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
note left of Schema::updateSchema
|
||||
Update the schema of an existing table.
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
note right of Schema::getCode
|
||||
Get the targeted component code
|
||||
|
||||
since: 3.2.1
|
||||
return: string
|
||||
end note
|
||||
|
||||
note left of Schema::addMissingColumns
|
||||
Add missing columns to a table.
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
note right of Schema::checkColumnsDataType
|
||||
Validate and update the data type of existing fields/columns
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
note left of Schema::updateColumnsDataType
|
||||
Update the data type of the given fields.
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
note right of Schema::updateColumnDataType
|
||||
Update the data type of the given field.
|
||||
|
||||
since: 3.2.1
|
||||
return: bool
|
||||
|
||||
arguments:
|
||||
string $updateString
|
||||
string $table
|
||||
string $field
|
||||
end note
|
||||
|
||||
note left of Schema::getTableKeys
|
||||
Key all needed keys for this table
|
||||
|
||||
since: 3.2.1
|
||||
return: string
|
||||
end note
|
||||
|
||||
note right of Schema::setUniqueKey
|
||||
Function to set the unique key
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
note left of Schema::setKey
|
||||
Function to set the key
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
note right of Schema::getTable
|
||||
Add the component name to get the full table name.
|
||||
|
||||
since: 3.2.1
|
||||
return: string
|
||||
end note
|
||||
|
||||
note left of Schema::tableExists
|
||||
Check if a table exists in the database.
|
||||
|
||||
since: 3.2.1
|
||||
return: bool
|
||||
end note
|
||||
|
||||
note right of Schema::getExistingColumns
|
||||
Fetch existing columns from a database table.
|
||||
|
||||
since: 3.2.1
|
||||
return: array
|
||||
end note
|
||||
|
||||
note left of Schema::getColumnDefinition
|
||||
Generates a SQL snippet for defining a table column, incorporating column type,
|
||||
default value, nullability, and auto-increment properties.
|
||||
|
||||
since: 3.2.1
|
||||
return: ?string
|
||||
end note
|
||||
|
||||
note right of Schema::setKeys
|
||||
Function to set the view keys
|
||||
|
||||
since: 3.2.1
|
||||
return: void
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
---
|
||||
```
|
||||
██╗ ██████╗██████╗
|
||||
██║██╔════╝██╔══██╗
|
||||
██║██║ ██████╔╝
|
||||
██ ██║██║ ██╔══██╗
|
||||
╚█████╔╝╚██████╗██████╔╝
|
||||
╚════╝ ╚═════╝╚═════╝
|
||||
```
|
||||
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
|
519
src/f3c04c28-bce4-422e-be93-7d163e4e342b/code.php
Normal file
519
src/f3c04c28-bce4-422e-be93-7d163e4e342b/code.php
Normal file
@ -0,0 +1,519 @@
|
||||
<?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;
|
||||
use VDM\Joomla\Interfaces\Tableinterface as Table;
|
||||
use VDM\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;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("Error: failed to initialize schema class due to a database error.", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
|
||||
$this->success[] = "Success: created missing $table table.";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
|
||||
if (!empty($missingColumns))
|
||||
{
|
||||
$column_s = (count($missingColumns) == 1) ? 'column' : 'columns';
|
||||
$missingColumns = implode(', ', $missingColumns);
|
||||
$this->success[] = "Success: added missing ($missingColumns) $column_s to $table table.";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the targeted component code
|
||||
*
|
||||
* @return string
|
||||
* @since 3.2.1
|
||||
*/
|
||||
abstract protected function getCode(): string;
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
// this field is no longer part of the component and can be ignored
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if the data type and size match
|
||||
if (strcasecmp($current->Type, $expected['type']) != 0)
|
||||
{
|
||||
$requireUpdate[$column] = [
|
||||
'column' => $column,
|
||||
'current' => $current->Type,
|
||||
'expected' => $expected['type']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($requireUpdate))
|
||||
{
|
||||
$this->updateColumnsDataType($table, $requireUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = (string) $types['current'] ?? 'error';
|
||||
$expected = (string) $types['expected'] ?? 'error';
|
||||
$this->success[] = "Success: updated ($column) column datatype $current to $expected in $table table.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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'] . "`)";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private function tableExists(string $table): bool
|
||||
{
|
||||
return in_array($this->getTable($table), $this->tables);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private function getExistingColumns(string $table): array
|
||||
{
|
||||
$this->columns = $this->db->getTableColumns($this->getTable($table), false);
|
||||
|
||||
return array_keys($this->columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private 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 default value SQL, null switch, and auto increment statement
|
||||
$default = !empty($db['default']) ? " DEFAULT " . $this->db->quote($db['default']) : '';
|
||||
$null_switch = !empty($db['null_switch']) ? " " . $db['null_switch'] : '';
|
||||
$auto_increment = !empty($db['auto_increment']) ? " AUTO_INCREMENT" : '';
|
||||
$type = !empty($db['type']) ? $db['type'] : 'TEXT';
|
||||
|
||||
$this->setKeys($db);
|
||||
|
||||
// Assemble the SQL snippet for the column definition
|
||||
return "{$column_name} {$type}{$default}{$null_switch}{$auto_increment}";
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("Error: failed to generate column definition for $table.$field", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set the view keys
|
||||
*
|
||||
* @param string $column The field column database array values
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.1
|
||||
*/
|
||||
private function setKeys(array $column): void
|
||||
{
|
||||
$this->setUniqueKey($column);
|
||||
$this->setKey($column);
|
||||
}
|
||||
}
|
||||
|
491
src/f3c04c28-bce4-422e-be93-7d163e4e342b/code.power
Normal file
491
src/f3c04c28-bce4-422e-be93-7d163e4e342b/code.power
Normal file
@ -0,0 +1,491 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("Error: failed to initialize schema class due to a database error.", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
|
||||
$this->success[] = "Success: created missing $table table.";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
|
||||
if (!empty($missingColumns))
|
||||
{
|
||||
$column_s = (count($missingColumns) == 1) ? 'column' : 'columns';
|
||||
$missingColumns = implode(', ', $missingColumns);
|
||||
$this->success[] = "Success: added missing ($missingColumns) $column_s to $table table.";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the targeted component code
|
||||
*
|
||||
* @return string
|
||||
* @since 3.2.1
|
||||
*/
|
||||
abstract protected function getCode(): string;
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
// this field is no longer part of the component and can be ignored
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if the data type and size match
|
||||
if (strcasecmp($current->Type, $expected['type']) != 0)
|
||||
{
|
||||
$requireUpdate[$column] = [
|
||||
'column' => $column,
|
||||
'current' => $current->Type,
|
||||
'expected' => $expected['type']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($requireUpdate))
|
||||
{
|
||||
$this->updateColumnsDataType($table, $requireUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = (string) $types['current'] ?? 'error';
|
||||
$expected = (string) $types['expected'] ?? 'error';
|
||||
$this->success[] = "Success: updated ($column) column datatype $current to $expected in $table table.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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'] . "`)";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private function tableExists(string $table): bool
|
||||
{
|
||||
return in_array($this->getTable($table), $this->tables);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private function getExistingColumns(string $table): array
|
||||
{
|
||||
$this->columns = $this->db->getTableColumns($this->getTable($table), false);
|
||||
|
||||
return array_keys($this->columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private 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 default value SQL, null switch, and auto increment statement
|
||||
$default = !empty($db['default']) ? " DEFAULT " . $this->db->quote($db['default']) : '';
|
||||
$null_switch = !empty($db['null_switch']) ? " " . $db['null_switch'] : '';
|
||||
$auto_increment = !empty($db['auto_increment']) ? " AUTO_INCREMENT" : '';
|
||||
$type = !empty($db['type']) ? $db['type'] : 'TEXT';
|
||||
|
||||
$this->setKeys($db);
|
||||
|
||||
// Assemble the SQL snippet for the column definition
|
||||
return "{$column_name} {$type}{$default}{$null_switch}{$auto_increment}";
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("Error: failed to generate column definition for $table.$field", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set the view keys
|
||||
*
|
||||
* @param string $column The field column database array values
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.1
|
||||
*/
|
||||
private function setKeys(array $column): void
|
||||
{
|
||||
$this->setUniqueKey($column);
|
||||
$this->setKey($column);
|
||||
}
|
25
src/f3c04c28-bce4-422e-be93-7d163e4e342b/settings.json
Normal file
25
src/f3c04c28-bce4-422e-be93-7d163e4e342b/settings.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"add_head": "1",
|
||||
"add_licensing_template": "2",
|
||||
"extends": "0",
|
||||
"guid": "f3c04c28-bce4-422e-be93-7d163e4e342b",
|
||||
"implements": [
|
||||
"4dd11b9b-3c64-460b-aaa6-62ba467db7aa"
|
||||
],
|
||||
"load_selection": null,
|
||||
"name": "Schema",
|
||||
"power_version": "1.0.0",
|
||||
"system_name": "VDM.Schema",
|
||||
"type": "abstract class",
|
||||
"use_selection": {
|
||||
"use_selection0": {
|
||||
"use": "2da6d6c4-eb29-4d69-8bc2-36d96e916adf",
|
||||
"as": "Table"
|
||||
}
|
||||
},
|
||||
"namespace": "[[[NamespacePrefix]]]\\Joomla\\Abstraction.Schema",
|
||||
"description": "Schema Checking\r\n\r\n@since 3.2.1",
|
||||
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
|
||||
"head": "use Joomla\\CMS\\Factory;",
|
||||
"composer": ""
|
||||
}
|
@ -142,6 +142,17 @@
|
||||
"spk": "Super__4815e1c7_a433_443d_a112_d1e03d7df84b__Power",
|
||||
"guid": "4815e1c7-a433-443d-a112-d1e03d7df84b"
|
||||
},
|
||||
"491dbe41-f26c-4de9-8a95-fcf87b35b56f": {
|
||||
"name": "ComponentCodeNameHelper",
|
||||
"type": "abstract class",
|
||||
"namespace": "VDM\\Joomla\\Utilities\\String",
|
||||
"code": "src\/491dbe41-f26c-4de9-8a95-fcf87b35b56f\/code.php",
|
||||
"power": "src\/491dbe41-f26c-4de9-8a95-fcf87b35b56f\/code.power",
|
||||
"settings": "src\/491dbe41-f26c-4de9-8a95-fcf87b35b56f\/settings.json",
|
||||
"path": "src\/491dbe41-f26c-4de9-8a95-fcf87b35b56f",
|
||||
"spk": "Super__491dbe41_f26c_4de9_8a95_fcf87b35b56f__Power",
|
||||
"guid": "491dbe41-f26c-4de9-8a95-fcf87b35b56f"
|
||||
},
|
||||
"4b225c51-d293-48e4-b3f6-5136cf5c3f18": {
|
||||
"name": "JsonHelper",
|
||||
"type": "abstract class",
|
||||
@ -153,6 +164,17 @@
|
||||
"spk": "Super__4b225c51_d293_48e4_b3f6_5136cf5c3f18__Power",
|
||||
"guid": "4b225c51-d293-48e4-b3f6-5136cf5c3f18"
|
||||
},
|
||||
"4dd11b9b-3c64-460b-aaa6-62ba467db7aa": {
|
||||
"name": "SchemaInterface",
|
||||
"type": "interface",
|
||||
"namespace": "VDM\\Joomla\\Interfaces",
|
||||
"code": "src\/4dd11b9b-3c64-460b-aaa6-62ba467db7aa\/code.php",
|
||||
"power": "src\/4dd11b9b-3c64-460b-aaa6-62ba467db7aa\/code.power",
|
||||
"settings": "src\/4dd11b9b-3c64-460b-aaa6-62ba467db7aa\/settings.json",
|
||||
"path": "src\/4dd11b9b-3c64-460b-aaa6-62ba467db7aa",
|
||||
"spk": "Super__4dd11b9b_3c64_460b_aaa6_62ba467db7aa__Power",
|
||||
"guid": "4dd11b9b-3c64-460b-aaa6-62ba467db7aa"
|
||||
},
|
||||
"524eb8f6-38d4-47dc-92ad-98b94e099ac0": {
|
||||
"name": "Insert",
|
||||
"type": "final class",
|
||||
@ -362,6 +384,17 @@
|
||||
"spk": "Super__af0eedbe_603b_4671_8e5a_28165d88254b__Power",
|
||||
"guid": "af0eedbe-603b-4671-8e5a-28165d88254b"
|
||||
},
|
||||
"b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce": {
|
||||
"name": "Schema",
|
||||
"type": "final class",
|
||||
"namespace": "VDM\\Joomla\\Componentbuilder\\Table",
|
||||
"code": "src\/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce\/code.php",
|
||||
"power": "src\/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce\/code.power",
|
||||
"settings": "src\/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce\/settings.json",
|
||||
"path": "src\/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce",
|
||||
"spk": "Super__b3d2ec33_76d4_4c3b_bb2c_86ac14a221ce__Power",
|
||||
"guid": "b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce"
|
||||
},
|
||||
"b84e947d-2a13-44f7-ac0f-3902ae55ae0c": {
|
||||
"name": "BaseRegistry",
|
||||
"type": "abstract class",
|
||||
@ -472,6 +505,17 @@
|
||||
"spk": "Super__e0f6ddbe_2a35_4537_942c_faff2ebd04f6__Power",
|
||||
"guid": "e0f6ddbe-2a35-4537-942c-faff2ebd04f6"
|
||||
},
|
||||
"f3c04c28-bce4-422e-be93-7d163e4e342b": {
|
||||
"name": "Schema",
|
||||
"type": "abstract class",
|
||||
"namespace": "VDM\\Joomla\\Abstraction",
|
||||
"code": "src\/f3c04c28-bce4-422e-be93-7d163e4e342b\/code.php",
|
||||
"power": "src\/f3c04c28-bce4-422e-be93-7d163e4e342b\/code.power",
|
||||
"settings": "src\/f3c04c28-bce4-422e-be93-7d163e4e342b\/settings.json",
|
||||
"path": "src\/f3c04c28-bce4-422e-be93-7d163e4e342b",
|
||||
"spk": "Super__f3c04c28_bce4_422e_be93_7d163e4e342b__Power",
|
||||
"guid": "f3c04c28-bce4-422e-be93-7d163e4e342b"
|
||||
},
|
||||
"ff7d0111-8f79-42aa-ac14-b53ba2c49369": {
|
||||
"name": "IsString",
|
||||
"type": "trait",
|
||||
|
Loading…
Reference in New Issue
Block a user