forked from joomla/super-powers
Update 2024-09-02 22:44:12
This commit is contained in:
parent
4a12bd8374
commit
9ca083305b
@ -47,6 +47,8 @@ This repository contains an index (see below) of all the approved powers within
|
||||
- **final class Items** | [Details](src/21bca8a4-5b28-41c4-843e-8097f0ba7cca) | [Code](src/21bca8a4-5b28-41c4-843e-8097f0ba7cca/code.php) | [Settings](src/21bca8a4-5b28-41c4-843e-8097f0ba7cca/settings.json) | SPK: `Super---21bca8a4_5b28_41c4_843e_8097f0ba7cca---Power`
|
||||
- **final class MultiSubform** | [Details](src/e0198c3f-777a-4a0b-87b7-e6a198afc8f9) | [Code](src/e0198c3f-777a-4a0b-87b7-e6a198afc8f9/code.php) | [Settings](src/e0198c3f-777a-4a0b-87b7-e6a198afc8f9/settings.json) | SPK: `Super---e0198c3f_777a_4a0b_87b7_e6a198afc8f9---Power`
|
||||
- **final class Subform** | [Details](src/85785701-07b2-4f81-bc1e-0f423700c254) | [Code](src/85785701-07b2-4f81-bc1e-0f423700c254/code.php) | [Settings](src/85785701-07b2-4f81-bc1e-0f423700c254/settings.json) | SPK: `Super---85785701_07b2_4f81_bc1e_0f423700c254---Power`
|
||||
- **final class UsersSubform** | [Details](src/46b98346-ec98-42b3-a393-96c7d1282b1c) | [Code](src/46b98346-ec98-42b3-a393-96c7d1282b1c/code.php) | [Settings](src/46b98346-ec98-42b3-a393-96c7d1282b1c/settings.json) | SPK: `Super---46b98346_ec98_42b3_a393_96c7d1282b1c---Power`
|
||||
- **trait Guid** | [Details](src/5acded67-0e3d-4c6b-a6ea-b533b076de0c) | [Code](src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/code.php) | [Settings](src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/settings.json) | SPK: `Super---5acded67_0e3d_4c6b_a6ea_b533b076de0c---Power`
|
||||
- **Namespace**: [VDM\Joomla\Database](#vdm-joomla-database)
|
||||
|
||||
- **final class Delete** | [Details](src/92291f1f-f248-4ec0-9f2a-3d47c49eeac1) | [Code](src/92291f1f-f248-4ec0-9f2a-3d47c49eeac1/code.php) | [Settings](src/92291f1f-f248-4ec0-9f2a-3d47c49eeac1/settings.json) | SPK: `Super---92291f1f_f248_4ec0_9f2a_3d47c49eeac1---Power`
|
||||
@ -103,6 +105,9 @@ This repository contains an index (see below) of all the approved powers within
|
||||
|
||||
- **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) | SPK: `Super---b3d2ec33_76d4_4c3b_bb2c_86ac14a221ce---Power`
|
||||
- **final class SchemaChecker** | [Details](src/709d7294-9a43-46e2-b64e-d16a16f0eab1) | [Code](src/709d7294-9a43-46e2-b64e-d16a16f0eab1/code.php) | [Settings](src/709d7294-9a43-46e2-b64e-d16a16f0eab1/settings.json) | SPK: `Super---709d7294_9a43_46e2_b64e_d16a16f0eab1---Power`
|
||||
- **Namespace**: [VDM\Joomla\Componentbuilder\Utilities](#vdm-joomla-componentbuilder-utilities)
|
||||
|
||||
- **abstract class UserHelper** | [Details](src/7832a726-87b6-4e95-887e-7b725d3fab8f) | [Code](src/7832a726-87b6-4e95-887e-7b725d3fab8f/code.php) | [Settings](src/7832a726-87b6-4e95-887e-7b725d3fab8f/settings.json) | SPK: `Super---7832a726_87b6_4e95_887e_7b725d3fab8f---Power`
|
||||
- **Namespace**: [VDM\Joomla\Data\Action](#vdm-joomla-data-action)
|
||||
|
||||
- **class Delete** | [Details](src/3fc72954-a303-4cac-b53c-554be38b85e7) | [Code](src/3fc72954-a303-4cac-b53c-554be38b85e7/code.php) | [Settings](src/3fc72954-a303-4cac-b53c-554be38b85e7/settings.json) | SPK: `Super---3fc72954_a303_4cac_b53c_554be38b85e7---Power`
|
||||
@ -112,6 +117,7 @@ This repository contains an index (see below) of all the approved powers within
|
||||
- **Namespace**: [VDM\Joomla\Interfaces\Data](#vdm-joomla-interfaces-data)
|
||||
|
||||
- **interface DeleteInterface** | [Details](src/d8f9ba53-c490-4e8b-8e9f-6757224e069c) | [Code](src/d8f9ba53-c490-4e8b-8e9f-6757224e069c/code.php) | [Settings](src/d8f9ba53-c490-4e8b-8e9f-6757224e069c/settings.json) | SPK: `Super---d8f9ba53_c490_4e8b_8e9f_6757224e069c---Power`
|
||||
- **interface GuidInterface** | [Details](src/576685fd-263c-46bb-9fdc-1f5eb234cbb6) | [Code](src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/code.php) | [Settings](src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/settings.json) | SPK: `Super---576685fd_263c_46bb_9fdc_1f5eb234cbb6---Power`
|
||||
- **interface InsertInterface** | [Details](src/03bbc8d5-86e8-4d2f-ae5f-0d44a4f7af13) | [Code](src/03bbc8d5-86e8-4d2f-ae5f-0d44a4f7af13/code.php) | [Settings](src/03bbc8d5-86e8-4d2f-ae5f-0d44a4f7af13/settings.json) | SPK: `Super---03bbc8d5_86e8_4d2f_ae5f_0d44a4f7af13---Power`
|
||||
- **interface ItemInterface** | [Details](src/05744dd3-4030-4cf8-8dda-a93ab809b473) | [Code](src/05744dd3-4030-4cf8-8dda-a93ab809b473/code.php) | [Settings](src/05744dd3-4030-4cf8-8dda-a93ab809b473/settings.json) | SPK: `Super---05744dd3_4030_4cf8_8dda_a93ab809b473---Power`
|
||||
- **interface ItemsInterface** | [Details](src/7212e4db-371f-4cfd-8122-32e9bb100d83) | [Code](src/7212e4db-371f-4cfd-8122-32e9bb100d83/code.php) | [Settings](src/7212e4db-371f-4cfd-8122-32e9bb100d83/settings.json) | SPK: `Super---7212e4db_371f_4cfd_8122_32e9bb100d83---Power`
|
||||
|
172
src/46b98346-ec98-42b3-a393-96c7d1282b1c/README.md
Normal file
172
src/46b98346-ec98-42b3-a393-96c7d1282b1c/README.md
Normal file
@ -0,0 +1,172 @@
|
||||
```
|
||||
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
|
||||
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
|
||||
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
|
||||
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
|
||||
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
|
||||
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
|
||||
```
|
||||
# final class UsersSubform (Details)
|
||||
> namespace: **VDM\Joomla\Data**
|
||||
|
||||
```uml
|
||||
@startuml
|
||||
class UsersSubform << (F,LightGreen) >> #RoyalBlue {
|
||||
# Items $items
|
||||
# string $table
|
||||
# array $user
|
||||
+ __construct(Items $items, ?string $table = null)
|
||||
+ table(string $table) : self
|
||||
+ get(string $linkValue, string $linkKey, ...) : ?array
|
||||
+ set(mixed $items, string $indexKey, ...) : bool
|
||||
+ getTable() : string
|
||||
# initializeUserProperties() : void
|
||||
- purge(array $items, string $indexKey, ...) : void
|
||||
- getUsersDetails(array $items) : array
|
||||
- getUserDetails(array $item) : void
|
||||
- converter(array $items, array $keySet, ...) : array
|
||||
- process(mixed $items, string $indexKey, ...) : array
|
||||
- setUserDetails(array $item) : int
|
||||
}
|
||||
|
||||
note right of UsersSubform::__construct
|
||||
Constructor.
|
||||
|
||||
since: 3.2.2
|
||||
end note
|
||||
|
||||
note left of UsersSubform::table
|
||||
Set the current active table
|
||||
|
||||
since: 3.2.2
|
||||
return: self
|
||||
end note
|
||||
|
||||
note right of UsersSubform::get
|
||||
Get a subform items
|
||||
|
||||
since: 3.2.2
|
||||
return: ?array
|
||||
|
||||
arguments:
|
||||
string $linkValue
|
||||
string $linkKey
|
||||
string $field
|
||||
array $get
|
||||
end note
|
||||
|
||||
note left of UsersSubform::set
|
||||
Set a subform items
|
||||
|
||||
since: 3.2.2
|
||||
return: bool
|
||||
|
||||
arguments:
|
||||
mixed $items
|
||||
string $indexKey
|
||||
string $linkKey
|
||||
string $linkValue
|
||||
end note
|
||||
|
||||
note right of UsersSubform::getTable
|
||||
Get the current active table
|
||||
|
||||
since: 3.2.2
|
||||
return: string
|
||||
end note
|
||||
|
||||
note left of UsersSubform::initializeUserProperties
|
||||
Initializes the user properties.
|
||||
|
||||
since: 5.0.2
|
||||
return: void
|
||||
end note
|
||||
|
||||
note right of UsersSubform::purge
|
||||
Purge all items no longer in subform
|
||||
|
||||
since: 3.2.2
|
||||
return: void
|
||||
|
||||
arguments:
|
||||
array $items
|
||||
string $indexKey
|
||||
string $linkKey
|
||||
string $linkValue
|
||||
end note
|
||||
|
||||
note left of UsersSubform::getUsersDetails
|
||||
Get the users details found in the user table.
|
||||
|
||||
since: 5.0.2
|
||||
return: array
|
||||
end note
|
||||
|
||||
note right of UsersSubform::getUserDetails
|
||||
Get the user details found in the user table.
|
||||
|
||||
since: 5.0.2
|
||||
return: void
|
||||
end note
|
||||
|
||||
note left of UsersSubform::converter
|
||||
Filters the specified keys from an array of objects or arrays, converts them to arrays,
|
||||
and sets them by association with a specified key and an incrementing integer.
|
||||
|
||||
since: 3.2.2
|
||||
return: array
|
||||
|
||||
arguments:
|
||||
array $items
|
||||
array $keySet
|
||||
string $field
|
||||
end note
|
||||
|
||||
note right of UsersSubform::process
|
||||
Processes an array of arrays based on the specified key.
|
||||
|
||||
since: 3.2.2
|
||||
return: array
|
||||
|
||||
arguments:
|
||||
mixed $items
|
||||
string $indexKey
|
||||
string $linkKey
|
||||
string $linkValue
|
||||
end note
|
||||
|
||||
note left of UsersSubform::setUserDetails
|
||||
Set the user details.
|
||||
|
||||
since: 5.0.2
|
||||
return: int
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
|
||||
|
||||
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
|
||||
|
||||
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
|
||||
|
||||
To add this specific Power to your project in JCB:
|
||||
|
||||
> simply use this SPK
|
||||
```
|
||||
Super---46b98346_ec98_42b3_a393_96c7d1282b1c---Power
|
||||
```
|
||||
> remember to replace the `---` with `___` to activate this Power in your code
|
||||
|
||||
---
|
||||
```
|
||||
██╗ ██████╗██████╗
|
||||
██║██╔════╝██╔══██╗
|
||||
██║██║ ██████╔╝
|
||||
██ ██║██║ ██╔══██╗
|
||||
╚█████╔╝╚██████╗██████╔╝
|
||||
╚════╝ ╚═════╝╚═════╝
|
||||
```
|
||||
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
|
403
src/46b98346-ec98-42b3-a393-96c7d1282b1c/code.php
Normal file
403
src/46b98346-ec98-42b3-a393-96c7d1282b1c/code.php
Normal file
@ -0,0 +1,403 @@
|
||||
<?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\Data;
|
||||
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use VDM\Joomla\Interfaces\Data\ItemsInterface as Items;
|
||||
use VDM\Joomla\Data\Guid;
|
||||
use VDM\Joomla\Componentbuilder\Utilities\UserHelper;
|
||||
use VDM\Joomla\Interfaces\Data\GuidInterface;
|
||||
use VDM\Joomla\Interfaces\Data\SubformInterface;
|
||||
|
||||
|
||||
/**
|
||||
* CRUD the user data of any sub-form to another view (table)
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
final class UsersSubform implements GuidInterface, SubformInterface
|
||||
{
|
||||
/**
|
||||
* The Globally Unique Identifier.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
use Guid;
|
||||
|
||||
/**
|
||||
* The Items Class.
|
||||
*
|
||||
* @var Items
|
||||
* @since 3.2.2
|
||||
*/
|
||||
protected Items $items;
|
||||
|
||||
/**
|
||||
* Table Name
|
||||
*
|
||||
* @var string
|
||||
* @since 3.2.1
|
||||
*/
|
||||
protected string $table;
|
||||
|
||||
/**
|
||||
* The user properties
|
||||
*
|
||||
* @var array
|
||||
* @since 5.0.2
|
||||
*/
|
||||
protected array $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Items $items The items Class.
|
||||
* @param string|null $table The table name.
|
||||
*
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function __construct(Items $items, ?string $table = null)
|
||||
{
|
||||
$this->items = $items;
|
||||
if ($table !== null)
|
||||
{
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
// Retrieve the user properties
|
||||
$this->initializeUserProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current active table
|
||||
*
|
||||
* @param string $table The table that should be active
|
||||
*
|
||||
* @return self
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function table(string $table): self
|
||||
{
|
||||
$this->table = $table;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subform items
|
||||
*
|
||||
* @param string $linkValue The value of the link key in child table.
|
||||
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||
* @param string $field The parent field name of the subform in the parent view.
|
||||
* @param array $get The array get:set of the keys of each row in the subform.
|
||||
*
|
||||
* @return array|null The subform
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function get(string $linkValue, string $linkKey, string $field, array $get): ?array
|
||||
{
|
||||
if (($items = $this->items->table($this->getTable())->get([$linkValue], $linkKey)) !== null)
|
||||
{
|
||||
return $this->converter(
|
||||
$this->getUsersDetails($items),
|
||||
$get,
|
||||
$field
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a subform items
|
||||
*
|
||||
* @param mixed $items The list of items from the subform to set
|
||||
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete.
|
||||
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||
* @param string $linkValue The value of the link key in child table.
|
||||
*
|
||||
* @return bool
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function set(mixed $items, string $indexKey, string $linkKey, string $linkValue): bool
|
||||
{
|
||||
$items = $this->process($items, $indexKey, $linkKey, $linkValue);
|
||||
|
||||
$this->purge($items, $indexKey, $linkKey, $linkValue);
|
||||
|
||||
if (empty($items))
|
||||
{
|
||||
return true; // nothing to set (already purged)
|
||||
}
|
||||
|
||||
return $this->items->table($this->getTable())->set(
|
||||
$items, $indexKey
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current active table
|
||||
*
|
||||
* @return string
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function getTable(): string
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the user properties.
|
||||
*
|
||||
* @return void
|
||||
* @since 5.0.2
|
||||
*/
|
||||
protected function initializeUserProperties(): void
|
||||
{
|
||||
$user = UserHelper::getUserById(0);
|
||||
|
||||
// Populate user properties array excluding the 'id'
|
||||
foreach (get_object_vars($user) as $property => $value)
|
||||
{
|
||||
if ($property !== 'id')
|
||||
{
|
||||
$this->user[$property] = $property;
|
||||
}
|
||||
}
|
||||
$this->user['password2'] = 'password2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge all items no longer in subform
|
||||
*
|
||||
* @param array $items The list of items to set.
|
||||
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete
|
||||
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||
* @param string $linkValue The value of the link key in child table.
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.2
|
||||
*/
|
||||
private function purge(array $items, string $indexKey, string $linkKey, string $linkValue): void
|
||||
{
|
||||
// Get the current index values from the database
|
||||
$currentIndexValues = $this->items->table($this->getTable())->values([$linkValue], $linkKey, $indexKey);
|
||||
|
||||
if ($currentIndexValues !== null)
|
||||
{
|
||||
// Check if the items array is empty
|
||||
if (empty($items))
|
||||
{
|
||||
// Set activeIndexValues to an empty array if items is empty
|
||||
$activeIndexValues = [];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Extract the index values from the items array
|
||||
$activeIndexValues = array_values(array_map(function($item) use ($indexKey) {
|
||||
return $item[$indexKey] ?? null;
|
||||
}, $items));
|
||||
}
|
||||
|
||||
// Find the index values that are no longer in the items array
|
||||
$inactiveIndexValues = array_diff($currentIndexValues, $activeIndexValues);
|
||||
|
||||
// Delete the inactive index values
|
||||
if (!empty($inactiveIndexValues))
|
||||
{
|
||||
$this->items->table($this->getTable())->delete($inactiveIndexValues, $indexKey);
|
||||
|
||||
// $this->deleteUsers($inactiveIndexValues); (soon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the users details found in the user table.
|
||||
*
|
||||
* @param array $items Array of objects or arrays to be filtered.
|
||||
*
|
||||
* @return array
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function getUsersDetails(array $items): array
|
||||
{
|
||||
foreach ($items as $index => &$item)
|
||||
{
|
||||
$item = (array) $item;
|
||||
$this->getUserDetails($item);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user details found in the user table.
|
||||
*
|
||||
* @param array $item The user map array
|
||||
*
|
||||
* @return void
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function getUserDetails(array &$item): void
|
||||
{
|
||||
// Validate the user_id and ensure it is numeric and greater than 0
|
||||
if (empty($item['user_id']) || !is_numeric($item['user_id']) || $item['user_id'] <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve the user by ID
|
||||
$user = UserHelper::getUserById((int)$item['user_id']);
|
||||
|
||||
// Verify if the user exists and the ID matches
|
||||
if ($user && $user->id === (int) $item['user_id'])
|
||||
{
|
||||
// Iterate over public properties of the user object
|
||||
foreach (get_object_vars($user) as $property => $value)
|
||||
{
|
||||
// Avoid overwriting the id in the item
|
||||
if ($property !== 'id')
|
||||
{
|
||||
$item[$property] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the specified keys from an array of objects or arrays, converts them to arrays,
|
||||
* and sets them by association with a specified key and an incrementing integer.
|
||||
*
|
||||
* @param array $items Array of objects or arrays to be filtered.
|
||||
* @param array $keySet Array of keys to retain in each item.
|
||||
* @param string $field The field prefix for the resulting associative array.
|
||||
*
|
||||
* @return array Array of filtered arrays set by association.
|
||||
* @since 3.2.2
|
||||
*/
|
||||
private function converter(array $items, array $keySet, string $field): array
|
||||
{
|
||||
/**
|
||||
* Filters keys for a single item and converts it to an array.
|
||||
*
|
||||
* @param object|array $item The item to filter.
|
||||
* @param array $keySet The keys to retain.
|
||||
*
|
||||
* @return array The filtered array.
|
||||
* @since 3.2.2
|
||||
*/
|
||||
$filterKeys = function ($item, array $keySet) {
|
||||
$filteredArray = [];
|
||||
foreach ($keySet as $key) {
|
||||
if (is_object($item) && property_exists($item, $key)) {
|
||||
$filteredArray[$key] = $item->{$key};
|
||||
} elseif (is_array($item) && array_key_exists($key, $item)) {
|
||||
$filteredArray[$key] = $item[$key];
|
||||
}
|
||||
}
|
||||
return $filteredArray;
|
||||
};
|
||||
|
||||
$result = [];
|
||||
foreach ($items as $index => $item)
|
||||
{
|
||||
$filteredArray = $filterKeys($item, $keySet);
|
||||
$result[$field . $index] = $filteredArray;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes an array of arrays based on the specified key.
|
||||
*
|
||||
* @param mixed $items Array of arrays to be processed.
|
||||
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete
|
||||
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||
* @param string $linkValue The value of the link key in child table.
|
||||
*
|
||||
* @return array The processed array of arrays.
|
||||
* @since 3.2.2
|
||||
*/
|
||||
private function process($items, string $indexKey, string $linkKey, string $linkValue): array
|
||||
{
|
||||
$items = is_array($items) ? $items : [];
|
||||
foreach ($items as &$item)
|
||||
{
|
||||
$value = $item[$indexKey] ?? '';
|
||||
switch ($indexKey) {
|
||||
case 'guid':
|
||||
if (empty($value))
|
||||
{
|
||||
// set INDEX
|
||||
$item[$indexKey] = $this->getGuid($indexKey);
|
||||
}
|
||||
break;
|
||||
case 'id':
|
||||
if (empty($value))
|
||||
{
|
||||
$item[$indexKey] = 0;
|
||||
}
|
||||
break;
|
||||
case 'user_id':
|
||||
$item[$indexKey] = $this->setUserDetails($item);
|
||||
break;
|
||||
default:
|
||||
// No action for other keys if empty
|
||||
break;
|
||||
}
|
||||
// set LINK
|
||||
$item[$linkKey] = $linkValue;
|
||||
}
|
||||
|
||||
return array_values($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user details.
|
||||
*
|
||||
* @param array $item The user details
|
||||
*
|
||||
* @return int
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function setUserDetails(array &$item): int
|
||||
{
|
||||
$user = [];
|
||||
|
||||
// now load the user ID
|
||||
if (isset($item['user_id']) && is_numeric($item['user_id']) && $item['user_id'] > 0)
|
||||
{
|
||||
$user['id'] = (int) $item['user_id'];
|
||||
}
|
||||
|
||||
foreach ($this->user as $property)
|
||||
{
|
||||
if (isset($item[$property]))
|
||||
{
|
||||
$user[$property] = $item[$property];
|
||||
unset($item[$property]);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return UserHelper::save($user);
|
||||
} catch(\Exception $e) {
|
||||
Factory::getApplication()->enqueueMessage($e->getMessage(), 'warning');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
372
src/46b98346-ec98-42b3-a393-96c7d1282b1c/code.power
Normal file
372
src/46b98346-ec98-42b3-a393-96c7d1282b1c/code.power
Normal file
@ -0,0 +1,372 @@
|
||||
/**
|
||||
* The Globally Unique Identifier.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
use Guid;
|
||||
|
||||
/**
|
||||
* The Items Class.
|
||||
*
|
||||
* @var Items
|
||||
* @since 3.2.2
|
||||
*/
|
||||
protected Items $items;
|
||||
|
||||
/**
|
||||
* Table Name
|
||||
*
|
||||
* @var string
|
||||
* @since 3.2.1
|
||||
*/
|
||||
protected string $table;
|
||||
|
||||
/**
|
||||
* The user properties
|
||||
*
|
||||
* @var array
|
||||
* @since 5.0.2
|
||||
*/
|
||||
protected array $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Items $items The items Class.
|
||||
* @param string|null $table The table name.
|
||||
*
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function __construct(Items $items, ?string $table = null)
|
||||
{
|
||||
$this->items = $items;
|
||||
if ($table !== null)
|
||||
{
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
// Retrieve the user properties
|
||||
$this->initializeUserProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current active table
|
||||
*
|
||||
* @param string $table The table that should be active
|
||||
*
|
||||
* @return self
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function table(string $table): self
|
||||
{
|
||||
$this->table = $table;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subform items
|
||||
*
|
||||
* @param string $linkValue The value of the link key in child table.
|
||||
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||
* @param string $field The parent field name of the subform in the parent view.
|
||||
* @param array $get The array get:set of the keys of each row in the subform.
|
||||
*
|
||||
* @return array|null The subform
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function get(string $linkValue, string $linkKey, string $field, array $get): ?array
|
||||
{
|
||||
if (($items = $this->items->table($this->getTable())->get([$linkValue], $linkKey)) !== null)
|
||||
{
|
||||
return $this->converter(
|
||||
$this->getUsersDetails($items),
|
||||
$get,
|
||||
$field
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a subform items
|
||||
*
|
||||
* @param mixed $items The list of items from the subform to set
|
||||
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete.
|
||||
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||
* @param string $linkValue The value of the link key in child table.
|
||||
*
|
||||
* @return bool
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function set(mixed $items, string $indexKey, string $linkKey, string $linkValue): bool
|
||||
{
|
||||
$items = $this->process($items, $indexKey, $linkKey, $linkValue);
|
||||
|
||||
$this->purge($items, $indexKey, $linkKey, $linkValue);
|
||||
|
||||
if (empty($items))
|
||||
{
|
||||
return true; // nothing to set (already purged)
|
||||
}
|
||||
|
||||
return $this->items->table($this->getTable())->set(
|
||||
$items, $indexKey
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current active table
|
||||
*
|
||||
* @return string
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public function getTable(): string
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the user properties.
|
||||
*
|
||||
* @return void
|
||||
* @since 5.0.2
|
||||
*/
|
||||
protected function initializeUserProperties(): void
|
||||
{
|
||||
$user = UserHelper::getUserById(0);
|
||||
|
||||
// Populate user properties array excluding the 'id'
|
||||
foreach (get_object_vars($user) as $property => $value)
|
||||
{
|
||||
if ($property !== 'id')
|
||||
{
|
||||
$this->user[$property] = $property;
|
||||
}
|
||||
}
|
||||
$this->user['password2'] = 'password2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge all items no longer in subform
|
||||
*
|
||||
* @param array $items The list of items to set.
|
||||
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete
|
||||
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||
* @param string $linkValue The value of the link key in child table.
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.2
|
||||
*/
|
||||
private function purge(array $items, string $indexKey, string $linkKey, string $linkValue): void
|
||||
{
|
||||
// Get the current index values from the database
|
||||
$currentIndexValues = $this->items->table($this->getTable())->values([$linkValue], $linkKey, $indexKey);
|
||||
|
||||
if ($currentIndexValues !== null)
|
||||
{
|
||||
// Check if the items array is empty
|
||||
if (empty($items))
|
||||
{
|
||||
// Set activeIndexValues to an empty array if items is empty
|
||||
$activeIndexValues = [];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Extract the index values from the items array
|
||||
$activeIndexValues = array_values(array_map(function($item) use ($indexKey) {
|
||||
return $item[$indexKey] ?? null;
|
||||
}, $items));
|
||||
}
|
||||
|
||||
// Find the index values that are no longer in the items array
|
||||
$inactiveIndexValues = array_diff($currentIndexValues, $activeIndexValues);
|
||||
|
||||
// Delete the inactive index values
|
||||
if (!empty($inactiveIndexValues))
|
||||
{
|
||||
$this->items->table($this->getTable())->delete($inactiveIndexValues, $indexKey);
|
||||
|
||||
// $this->deleteUsers($inactiveIndexValues); (soon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the users details found in the user table.
|
||||
*
|
||||
* @param array $items Array of objects or arrays to be filtered.
|
||||
*
|
||||
* @return array
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function getUsersDetails(array $items): array
|
||||
{
|
||||
foreach ($items as $index => &$item)
|
||||
{
|
||||
$item = (array) $item;
|
||||
$this->getUserDetails($item);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user details found in the user table.
|
||||
*
|
||||
* @param array $item The user map array
|
||||
*
|
||||
* @return void
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function getUserDetails(array &$item): void
|
||||
{
|
||||
// Validate the user_id and ensure it is numeric and greater than 0
|
||||
if (empty($item['user_id']) || !is_numeric($item['user_id']) || $item['user_id'] <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve the user by ID
|
||||
$user = UserHelper::getUserById((int)$item['user_id']);
|
||||
|
||||
// Verify if the user exists and the ID matches
|
||||
if ($user && $user->id === (int) $item['user_id'])
|
||||
{
|
||||
// Iterate over public properties of the user object
|
||||
foreach (get_object_vars($user) as $property => $value)
|
||||
{
|
||||
// Avoid overwriting the id in the item
|
||||
if ($property !== 'id')
|
||||
{
|
||||
$item[$property] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the specified keys from an array of objects or arrays, converts them to arrays,
|
||||
* and sets them by association with a specified key and an incrementing integer.
|
||||
*
|
||||
* @param array $items Array of objects or arrays to be filtered.
|
||||
* @param array $keySet Array of keys to retain in each item.
|
||||
* @param string $field The field prefix for the resulting associative array.
|
||||
*
|
||||
* @return array Array of filtered arrays set by association.
|
||||
* @since 3.2.2
|
||||
*/
|
||||
private function converter(array $items, array $keySet, string $field): array
|
||||
{
|
||||
/**
|
||||
* Filters keys for a single item and converts it to an array.
|
||||
*
|
||||
* @param object|array $item The item to filter.
|
||||
* @param array $keySet The keys to retain.
|
||||
*
|
||||
* @return array The filtered array.
|
||||
* @since 3.2.2
|
||||
*/
|
||||
$filterKeys = function ($item, array $keySet) {
|
||||
$filteredArray = [];
|
||||
foreach ($keySet as $key) {
|
||||
if (is_object($item) && property_exists($item, $key)) {
|
||||
$filteredArray[$key] = $item->{$key};
|
||||
} elseif (is_array($item) && array_key_exists($key, $item)) {
|
||||
$filteredArray[$key] = $item[$key];
|
||||
}
|
||||
}
|
||||
return $filteredArray;
|
||||
};
|
||||
|
||||
$result = [];
|
||||
foreach ($items as $index => $item)
|
||||
{
|
||||
$filteredArray = $filterKeys($item, $keySet);
|
||||
$result[$field . $index] = $filteredArray;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes an array of arrays based on the specified key.
|
||||
*
|
||||
* @param mixed $items Array of arrays to be processed.
|
||||
* @param string $indexKey The index key on which the items should be observed as it relates to insert/update/delete
|
||||
* @param string $linkKey The link key on which the items where linked in the child table.
|
||||
* @param string $linkValue The value of the link key in child table.
|
||||
*
|
||||
* @return array The processed array of arrays.
|
||||
* @since 3.2.2
|
||||
*/
|
||||
private function process($items, string $indexKey, string $linkKey, string $linkValue): array
|
||||
{
|
||||
$items = is_array($items) ? $items : [];
|
||||
foreach ($items as &$item)
|
||||
{
|
||||
$value = $item[$indexKey] ?? '';
|
||||
switch ($indexKey) {
|
||||
case 'guid':
|
||||
if (empty($value))
|
||||
{
|
||||
// set INDEX
|
||||
$item[$indexKey] = $this->getGuid($indexKey);
|
||||
}
|
||||
break;
|
||||
case 'id':
|
||||
if (empty($value))
|
||||
{
|
||||
$item[$indexKey] = 0;
|
||||
}
|
||||
break;
|
||||
case 'user_id':
|
||||
$item[$indexKey] = $this->setUserDetails($item);
|
||||
break;
|
||||
default:
|
||||
// No action for other keys if empty
|
||||
break;
|
||||
}
|
||||
// set LINK
|
||||
$item[$linkKey] = $linkValue;
|
||||
}
|
||||
|
||||
return array_values($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user details.
|
||||
*
|
||||
* @param array $item The user details
|
||||
*
|
||||
* @return int
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function setUserDetails(array &$item): int
|
||||
{
|
||||
$user = [];
|
||||
|
||||
// now load the user ID
|
||||
if (isset($item['user_id']) && is_numeric($item['user_id']) && $item['user_id'] > 0)
|
||||
{
|
||||
$user['id'] = (int) $item['user_id'];
|
||||
}
|
||||
|
||||
foreach ($this->user as $property)
|
||||
{
|
||||
if (isset($item[$property]))
|
||||
{
|
||||
$user[$property] = $item[$property];
|
||||
unset($item[$property]);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return UserHelper::save($user);
|
||||
} catch(\Exception $e) {
|
||||
Factory::getApplication()->enqueueMessage($e->getMessage(), 'warning');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
35
src/46b98346-ec98-42b3-a393-96c7d1282b1c/settings.json
Normal file
35
src/46b98346-ec98-42b3-a393-96c7d1282b1c/settings.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"add_head": "1",
|
||||
"add_licensing_template": "2",
|
||||
"extends": "",
|
||||
"guid": "46b98346-ec98-42b3-a393-96c7d1282b1c",
|
||||
"implements": [
|
||||
"576685fd-263c-46bb-9fdc-1f5eb234cbb6",
|
||||
"34959721-415b-4b5e-8002-3d1fc84b3b2b"
|
||||
],
|
||||
"load_selection": null,
|
||||
"name": "UsersSubform",
|
||||
"power_version": "1.0.0",
|
||||
"system_name": "VDM.Data.UsersSubform",
|
||||
"type": "final class",
|
||||
"use_selection": {
|
||||
"use_selection0": {
|
||||
"use": "7212e4db-371f-4cfd-8122-32e9bb100d83",
|
||||
"as": "Items"
|
||||
},
|
||||
"use_selection1": {
|
||||
"use": "5acded67-0e3d-4c6b-a6ea-b533b076de0c",
|
||||
"as": "default"
|
||||
},
|
||||
"use_selection2": {
|
||||
"use": "7832a726-87b6-4e95-887e-7b725d3fab8f",
|
||||
"as": "default"
|
||||
}
|
||||
},
|
||||
"extendsinterfaces": null,
|
||||
"namespace": "[[[NamespacePrefix]]]\\Joomla\\Data.UsersSubform",
|
||||
"description": "CRUD the user data of any sub-form to another view (table)\r\n\r\n@since 5.0.2",
|
||||
"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": "use Joomla\\CMS\\Factory;",
|
||||
"composer": ""
|
||||
}
|
54
src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/README.md
Normal file
54
src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/README.md
Normal file
@ -0,0 +1,54 @@
|
||||
```
|
||||
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
|
||||
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
|
||||
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
|
||||
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
|
||||
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
|
||||
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
|
||||
```
|
||||
# interface GuidInterface (Details)
|
||||
> namespace: **VDM\Joomla\Interfaces\Data**
|
||||
|
||||
```uml
|
||||
@startuml
|
||||
interface GuidInterface #Lavender {
|
||||
+ getGuid(string $key) : string
|
||||
}
|
||||
|
||||
note right of GuidInterface::getGuid
|
||||
Returns a GUIDv4 string.
|
||||
This function uses the best cryptographically secure method
|
||||
available on the platform with a fallback to an older, less secure version.
|
||||
|
||||
since: 5.0.2
|
||||
return: string
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
|
||||
|
||||
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
|
||||
|
||||
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
|
||||
|
||||
To add this specific Power to your project in JCB:
|
||||
|
||||
> simply use this SPK
|
||||
```
|
||||
Super---576685fd_263c_46bb_9fdc_1f5eb234cbb6---Power
|
||||
```
|
||||
> remember to replace the `---` with `___` to activate this Power in your code
|
||||
|
||||
---
|
||||
```
|
||||
██╗ ██████╗██████╗
|
||||
██║██╔════╝██╔══██╗
|
||||
██║██║ ██████╔╝
|
||||
██ ██║██║ ██╔══██╗
|
||||
╚█████╔╝╚██████╗██████╔╝
|
||||
╚════╝ ╚═════╝╚═════╝
|
||||
```
|
||||
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
|
36
src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/code.php
Normal file
36
src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/code.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?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\Data;
|
||||
|
||||
|
||||
/**
|
||||
* Globally Unique Identifier Interface
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
interface GuidInterface
|
||||
{
|
||||
/**
|
||||
* Returns a GUIDv4 string.
|
||||
*
|
||||
* This function uses the best cryptographically secure method
|
||||
* available on the platform with a fallback to an older, less secure version.
|
||||
*
|
||||
* @param string $key The key to check and modify values.
|
||||
*
|
||||
* @return string A GUIDv4 string.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public function getGuid(string $key): string;
|
||||
}
|
||||
|
13
src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/code.power
Normal file
13
src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/code.power
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Returns a GUIDv4 string.
|
||||
*
|
||||
* This function uses the best cryptographically secure method
|
||||
* available on the platform with a fallback to an older, less secure version.
|
||||
*
|
||||
* @param string $key The key to check and modify values.
|
||||
*
|
||||
* @return string A GUIDv4 string.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public function getGuid(string $key): string;
|
19
src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/settings.json
Normal file
19
src/576685fd-263c-46bb-9fdc-1f5eb234cbb6/settings.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"add_head": "0",
|
||||
"add_licensing_template": "2",
|
||||
"extends": "",
|
||||
"guid": "576685fd-263c-46bb-9fdc-1f5eb234cbb6",
|
||||
"implements": null,
|
||||
"load_selection": null,
|
||||
"name": "GuidInterface",
|
||||
"power_version": "1.0.0",
|
||||
"system_name": "VDM.Interfaces.Data.GuidInterface",
|
||||
"type": "interface",
|
||||
"use_selection": null,
|
||||
"extendsinterfaces": null,
|
||||
"namespace": "[[[NamespacePrefix]]]\\Joomla\\Interfaces.Data.GuidInterface",
|
||||
"description": "Globally Unique Identifier Interface\r\n\r\n@since 5.0.2",
|
||||
"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": ""
|
||||
}
|
70
src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/README.md
Normal file
70
src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/README.md
Normal file
@ -0,0 +1,70 @@
|
||||
```
|
||||
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
|
||||
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
|
||||
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
|
||||
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
|
||||
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
|
||||
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
|
||||
```
|
||||
# trait Guid (Details)
|
||||
> namespace: **VDM\Joomla\Data**
|
||||
|
||||
```uml
|
||||
@startuml
|
||||
class Guid << (T,Orange) >> #Turquoise {
|
||||
+ getGuid(string $key) : string
|
||||
- fallbackGuid(string $key) : string
|
||||
- checkGuid(string $guid, string $key) : string
|
||||
}
|
||||
|
||||
note right of Guid::getGuid
|
||||
Returns a GUIDv4 string.
|
||||
This function uses the best cryptographically secure method
|
||||
available on the platform with a fallback to an older, less secure version.
|
||||
|
||||
since: 5.0.2
|
||||
return: string
|
||||
end note
|
||||
|
||||
note right of Guid::fallbackGuid
|
||||
Generates a fallback GUIDv4 using less secure methods.
|
||||
|
||||
since: 5.0.2
|
||||
return: string
|
||||
end note
|
||||
|
||||
note right of Guid::checkGuid
|
||||
Checks if the GUID value is unique and does not already exist.
|
||||
|
||||
since: 5.0.2
|
||||
return: string
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
|
||||
|
||||
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
|
||||
|
||||
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
|
||||
|
||||
To add this specific Power to your project in JCB:
|
||||
|
||||
> simply use this SPK
|
||||
```
|
||||
Super---5acded67_0e3d_4c6b_a6ea_b533b076de0c---Power
|
||||
```
|
||||
> remember to replace the `---` with `___` to activate this Power in your code
|
||||
|
||||
---
|
||||
```
|
||||
██╗ ██████╗██████╗
|
||||
██║██╔════╝██╔══██╗
|
||||
██║██║ ██████╔╝
|
||||
██ ██║██║ ██╔══██╗
|
||||
╚█████╔╝╚██████╗██████╔╝
|
||||
╚════╝ ╚═════╝╚═════╝
|
||||
```
|
||||
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
|
110
src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/code.php
Normal file
110
src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/code.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?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\Data;
|
||||
|
||||
|
||||
/**
|
||||
* Globally Unique Identifier
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
trait Guid
|
||||
{
|
||||
/**
|
||||
* Returns a GUIDv4 string.
|
||||
*
|
||||
* This function uses the best cryptographically secure method
|
||||
* available on the platform with a fallback to an older, less secure version.
|
||||
*
|
||||
* @param string $key The key to check and modify values.
|
||||
*
|
||||
* @return string A GUIDv4 string.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public function getGuid(string $key): string
|
||||
{
|
||||
// Windows: Use com_create_guid if available
|
||||
if (function_exists('com_create_guid'))
|
||||
{
|
||||
$guid = trim(\com_create_guid(), '{}');
|
||||
return $this->checkGuid($guid, $key);
|
||||
}
|
||||
|
||||
// Unix-based systems: Use openssl_random_pseudo_bytes if available
|
||||
if (function_exists('random_bytes'))
|
||||
{
|
||||
try {
|
||||
$data = random_bytes(16);
|
||||
} catch (Exception $e) {
|
||||
// Handle the error appropriately (logging, throwing, etc.)
|
||||
return $this->fallbackGuid($key);
|
||||
}
|
||||
|
||||
// Set the version to 0100 and the bits 6-7 to 10 as per RFC 4122
|
||||
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
|
||||
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
|
||||
|
||||
$guid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
|
||||
return $this->checkGuid($guid, $key);
|
||||
}
|
||||
|
||||
// Fallback to older methods if secure methods are not available
|
||||
return $this->fallbackGuid($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a fallback GUIDv4 using less secure methods.
|
||||
*
|
||||
* @param string $key The key to check and modify values.
|
||||
*
|
||||
* @return string A GUIDv4 string.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function fallbackGuid(string $key): string
|
||||
{
|
||||
$charid = strtolower(md5(uniqid(random_int(0, PHP_INT_MAX), true)));
|
||||
$guidv4 = sprintf(
|
||||
'%s-%s-%s-%s-%s',
|
||||
substr($charid, 0, 8),
|
||||
substr($charid, 8, 4),
|
||||
substr($charid, 12, 4),
|
||||
substr($charid, 16, 4),
|
||||
substr($charid, 20, 12)
|
||||
);
|
||||
|
||||
return $this->checkGuid($guidv4, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the GUID value is unique and does not already exist.
|
||||
*
|
||||
* @param string $guid The GUID value to check.
|
||||
* @param string $key The key to check and modify values.
|
||||
*
|
||||
* @return string The unique GUID value.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function checkGuid(string $guid, string $key): string
|
||||
{
|
||||
// Check that the GUID does not already exist
|
||||
if ($this->items->table($this->getTable())->values([$guid], $key))
|
||||
{
|
||||
return $this->getGuid($key);
|
||||
}
|
||||
|
||||
return $guid;
|
||||
}
|
||||
}
|
||||
|
87
src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/code.power
Normal file
87
src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/code.power
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Returns a GUIDv4 string.
|
||||
*
|
||||
* This function uses the best cryptographically secure method
|
||||
* available on the platform with a fallback to an older, less secure version.
|
||||
*
|
||||
* @param string $key The key to check and modify values.
|
||||
*
|
||||
* @return string A GUIDv4 string.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public function getGuid(string $key): string
|
||||
{
|
||||
// Windows: Use com_create_guid if available
|
||||
if (function_exists('com_create_guid'))
|
||||
{
|
||||
$guid = trim(\com_create_guid(), '{}');
|
||||
return $this->checkGuid($guid, $key);
|
||||
}
|
||||
|
||||
// Unix-based systems: Use openssl_random_pseudo_bytes if available
|
||||
if (function_exists('random_bytes'))
|
||||
{
|
||||
try {
|
||||
$data = random_bytes(16);
|
||||
} catch (Exception $e) {
|
||||
// Handle the error appropriately (logging, throwing, etc.)
|
||||
return $this->fallbackGuid($key);
|
||||
}
|
||||
|
||||
// Set the version to 0100 and the bits 6-7 to 10 as per RFC 4122
|
||||
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
|
||||
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
|
||||
|
||||
$guid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
|
||||
return $this->checkGuid($guid, $key);
|
||||
}
|
||||
|
||||
// Fallback to older methods if secure methods are not available
|
||||
return $this->fallbackGuid($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a fallback GUIDv4 using less secure methods.
|
||||
*
|
||||
* @param string $key The key to check and modify values.
|
||||
*
|
||||
* @return string A GUIDv4 string.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function fallbackGuid(string $key): string
|
||||
{
|
||||
$charid = strtolower(md5(uniqid(random_int(0, PHP_INT_MAX), true)));
|
||||
$guidv4 = sprintf(
|
||||
'%s-%s-%s-%s-%s',
|
||||
substr($charid, 0, 8),
|
||||
substr($charid, 8, 4),
|
||||
substr($charid, 12, 4),
|
||||
substr($charid, 16, 4),
|
||||
substr($charid, 20, 12)
|
||||
);
|
||||
|
||||
return $this->checkGuid($guidv4, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the GUID value is unique and does not already exist.
|
||||
*
|
||||
* @param string $guid The GUID value to check.
|
||||
* @param string $key The key to check and modify values.
|
||||
*
|
||||
* @return string The unique GUID value.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
private function checkGuid(string $guid, string $key): string
|
||||
{
|
||||
// Check that the GUID does not already exist
|
||||
if ($this->items->table($this->getTable())->values([$guid], $key))
|
||||
{
|
||||
return $this->getGuid($key);
|
||||
}
|
||||
|
||||
return $guid;
|
||||
}
|
19
src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/settings.json
Normal file
19
src/5acded67-0e3d-4c6b-a6ea-b533b076de0c/settings.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"add_head": "0",
|
||||
"add_licensing_template": "2",
|
||||
"extends": "",
|
||||
"guid": "5acded67-0e3d-4c6b-a6ea-b533b076de0c",
|
||||
"implements": null,
|
||||
"load_selection": null,
|
||||
"name": "Guid",
|
||||
"power_version": "1.0.0",
|
||||
"system_name": "VDM.Data.Guid",
|
||||
"type": "trait",
|
||||
"use_selection": null,
|
||||
"extendsinterfaces": null,
|
||||
"namespace": "[[[NamespacePrefix]]]\\Joomla\\Data.Guid",
|
||||
"description": "Globally Unique Identifier\r\n\r\n@since 5.0.2",
|
||||
"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": ""
|
||||
}
|
@ -12,6 +12,7 @@
|
||||
```uml
|
||||
@startuml
|
||||
abstract Helper #Orange {
|
||||
+ {static} setParams(string $target, mixed $value, ...) : mixed
|
||||
+ {static} getParams(?string $option = null) : Registry
|
||||
+ {static} setOption(?string $option) : void
|
||||
+ {static} getOption(?string $default = 'empty') : ?string
|
||||
@ -21,65 +22,82 @@ abstract Helper #Orange {
|
||||
+ {static} getManifest(?string $option = null) : ?object
|
||||
+ {static} methodExists(string $method, ?string $option = null) : bool
|
||||
+ {static} _(string $method, array $arguments = [], ...) : mixed
|
||||
+ {static} getModel(string $type, string $prefix = 'Administrator', ...) : BaseDatabaseModel
|
||||
- {static} getPrefixFromModelPath(string $path) : string
|
||||
}
|
||||
|
||||
note right of Helper::getParams
|
||||
note right of Helper::setParams
|
||||
Sets a parameter value for the given target in the specified option's params.
|
||||
If no option is provided, it falls back to the default option.
|
||||
This method updates the parameters for a given extension in the database,
|
||||
only if the new value differs from the existing one.
|
||||
|
||||
since: 5.0.3
|
||||
return: mixed
|
||||
|
||||
arguments:
|
||||
string $target
|
||||
mixed $value
|
||||
?string $option = null
|
||||
end note
|
||||
|
||||
note left of Helper::getParams
|
||||
Gets the parameter object for the component
|
||||
|
||||
since: 3.0.11
|
||||
return: Registry
|
||||
end note
|
||||
|
||||
note left of Helper::setOption
|
||||
note right of Helper::setOption
|
||||
Set the component option
|
||||
|
||||
since: 3.2.0
|
||||
return: void
|
||||
end note
|
||||
|
||||
note right of Helper::getOption
|
||||
note left of Helper::getOption
|
||||
Get the component option
|
||||
|
||||
since: 3.0.11
|
||||
return: ?string
|
||||
end note
|
||||
|
||||
note left of Helper::getCode
|
||||
note right of Helper::getCode
|
||||
Gets the component code name
|
||||
|
||||
since: 3.0.11
|
||||
return: ?string
|
||||
end note
|
||||
|
||||
note right of Helper::get
|
||||
note left of Helper::get
|
||||
Gets the component abstract helper class
|
||||
|
||||
since: 3.0.11
|
||||
return: ?string
|
||||
end note
|
||||
|
||||
note left of Helper::getNamespace
|
||||
note right of Helper::getNamespace
|
||||
Gets the component namespace if set
|
||||
|
||||
since: 3.0.11
|
||||
return: ?string
|
||||
end note
|
||||
|
||||
note right of Helper::getManifest
|
||||
note left of Helper::getManifest
|
||||
Gets the component abstract helper class
|
||||
|
||||
since: 3.0.11
|
||||
return: ?object
|
||||
end note
|
||||
|
||||
note left of Helper::methodExists
|
||||
note right of Helper::methodExists
|
||||
Check if the helper class of this component has a method
|
||||
|
||||
since: 3.0.11
|
||||
return: bool
|
||||
end note
|
||||
|
||||
note right of Helper::_
|
||||
note left of Helper::_
|
||||
Check if the helper class of this component has a method, and call it with the arguments
|
||||
|
||||
since: 3.2.0
|
||||
@ -90,6 +108,26 @@ note right of Helper::_
|
||||
array $arguments = []
|
||||
?string $option = null
|
||||
end note
|
||||
|
||||
note right of Helper::getModel
|
||||
Returns a Model object based on the specified type, prefix, and configuration.
|
||||
|
||||
since: 5.0.3
|
||||
return: BaseDatabaseModel
|
||||
|
||||
arguments:
|
||||
string $type
|
||||
string $prefix = 'Administrator'
|
||||
?string $option = null
|
||||
array $config = []
|
||||
end note
|
||||
|
||||
note left of Helper::getPrefixFromModelPath
|
||||
Get the prefix from the model path
|
||||
|
||||
since: 5.0.3
|
||||
return: string
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
@ -14,9 +14,11 @@ namespace VDM\Joomla\Utilities\Component;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Registry\Registry;
|
||||
use VDM\Joomla\Utilities\String\NamespaceHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
|
||||
|
||||
/**
|
||||
@ -50,6 +52,57 @@ abstract class Helper
|
||||
*/
|
||||
protected static array $params = [];
|
||||
|
||||
/**
|
||||
* Sets a parameter value for the given target in the specified option's params.
|
||||
* If no option is provided, it falls back to the default option.
|
||||
*
|
||||
* This method updates the parameters for a given extension in the database,
|
||||
* only if the new value differs from the existing one.
|
||||
*
|
||||
* @param string $target The parameter name to be updated.
|
||||
* @param mixed $value The value to set for the parameter.
|
||||
* @param string|null $option The optional extension element name. Defaults to null, which will use the default option.
|
||||
*
|
||||
* @return mixed The previous value of the parameter before it was updated.
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function setParams(string $target, $value, ?string $option = null)
|
||||
{
|
||||
// Ensure that an option is specified, defaulting to the system's option if not provided.
|
||||
if (empty($option))
|
||||
{
|
||||
$option = static::getOption();
|
||||
}
|
||||
|
||||
// Retrieve current parameters for the specified option.
|
||||
$params = static::getParams($option);
|
||||
|
||||
// Get the current value of the target parameter.
|
||||
$was = $params->get($target, null);
|
||||
|
||||
// Only proceed if the new value differs from the current value.
|
||||
if ($was !== $value)
|
||||
{
|
||||
// Update the parameter value.
|
||||
$params->set($target, $value);
|
||||
|
||||
// Obtain a database connection instance.
|
||||
$db = Factory::getDBO();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Build and execute the query to update the parameters in the database.
|
||||
$query->update('#__extensions AS a')
|
||||
->set('a.params = ' . $db->quote((string) $params))
|
||||
->where('a.element = ' . $db->quote((string) $option));
|
||||
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
}
|
||||
|
||||
// Return the previous value of the parameter.
|
||||
return $was;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parameter object for the component
|
||||
*
|
||||
@ -64,16 +117,16 @@ abstract class Helper
|
||||
// check that we have an option
|
||||
if (empty($option))
|
||||
{
|
||||
$option = self::getOption();
|
||||
$option = static::getOption();
|
||||
}
|
||||
|
||||
// get global value
|
||||
if (!isset(self::$params[$option]) || !self::$params[$option] instanceof Registry)
|
||||
if (!isset(static::$params[$option]) || !static::$params[$option] instanceof Registry)
|
||||
{
|
||||
self::$params[$option] = ComponentHelper::getParams($option);
|
||||
static::$params[$option] = ComponentHelper::getParams($option);
|
||||
}
|
||||
|
||||
return self::$params[$option];
|
||||
return static::$params[$option];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,7 +139,7 @@ abstract class Helper
|
||||
*/
|
||||
public static function setOption(?string $option): void
|
||||
{
|
||||
self::$option = $option;
|
||||
static::$option = $option;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,13 +152,13 @@ abstract class Helper
|
||||
*/
|
||||
public static function getOption(?string $default = 'empty'): ?string
|
||||
{
|
||||
if (empty(self::$option))
|
||||
if (empty(static::$option))
|
||||
{
|
||||
// get the option from the url input
|
||||
self::$option = (new Input)->getString('option', null);
|
||||
static::$option = (new Input)->getString('option', null);
|
||||
}
|
||||
|
||||
if (empty(self::$option))
|
||||
if (empty(static::$option))
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
@ -113,16 +166,16 @@ abstract class Helper
|
||||
if (method_exists($app, 'getInput'))
|
||||
{
|
||||
// get the option from the application
|
||||
self::$option = $app->getInput()->getCmd('option', $default);
|
||||
static::$option = $app->getInput()->getCmd('option', $default);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the default value if getInput method does not exist
|
||||
self::$option = $default;
|
||||
static::$option = $default;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$option;
|
||||
return static::$option;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +192,7 @@ abstract class Helper
|
||||
// check that we have an option
|
||||
if (empty($option))
|
||||
{
|
||||
$option = self::getOption();
|
||||
$option = static::getOption();
|
||||
}
|
||||
// option with com_
|
||||
if (is_string($option) && strpos($option, 'com_') === 0)
|
||||
@ -164,7 +217,7 @@ abstract class Helper
|
||||
{
|
||||
// check that we have an option
|
||||
// and get the code name from it
|
||||
if (($code_name = self::getCode($option, null)) !== null)
|
||||
if (($code_name = static::getCode($option, null)) !== null)
|
||||
{
|
||||
// we build the helper class name
|
||||
$helper_name = '\\' . \ucfirst($code_name) . 'Helper';
|
||||
@ -176,7 +229,7 @@ abstract class Helper
|
||||
}
|
||||
|
||||
// try loading namespace
|
||||
if (($namespace = self::getNamespace($option)) !== null)
|
||||
if (($namespace = static::getNamespace($option)) !== null)
|
||||
{
|
||||
$name = \ucfirst($code_name) . 'Helper';
|
||||
$namespace_helper = '\\' . $namespace . '\Administrator\Helper\\' . NamespaceHelper::safeSegment($name); // TODO target site or admin locations not just admin...
|
||||
@ -202,7 +255,7 @@ abstract class Helper
|
||||
*/
|
||||
public static function getNamespace(?string $option = null): ?string
|
||||
{
|
||||
$manifest = self::getManifest($option);
|
||||
$manifest = static::getManifest($option);
|
||||
|
||||
return $manifest->namespace ?? null;
|
||||
}
|
||||
@ -220,13 +273,13 @@ abstract class Helper
|
||||
public static function getManifest(?string $option = null): ?object
|
||||
{
|
||||
if ($option === null
|
||||
&& ($option = self::getOption($option)) === null)
|
||||
&& ($option = static::getOption($option)) === null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// get global manifest_cache values
|
||||
if (!isset(self::$manifest[$option]))
|
||||
if (!isset(static::$manifest[$option]))
|
||||
{
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
@ -240,14 +293,14 @@ abstract class Helper
|
||||
|
||||
try {
|
||||
$manifest = $db->loadResult();
|
||||
self::$manifest[$option] = json_decode($manifest);
|
||||
static::$manifest[$option] = json_decode($manifest);
|
||||
} catch (\Exception $e) {
|
||||
// Handle the database error appropriately.
|
||||
self::$manifest[$option] = null;
|
||||
static::$manifest[$option] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$manifest[$option];
|
||||
return static::$manifest[$option];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -263,7 +316,7 @@ abstract class Helper
|
||||
public static function methodExists(string $method, ?string $option = null): bool
|
||||
{
|
||||
// get the helper class
|
||||
return ($helper = self::get($option, null)) !== null &&
|
||||
return ($helper = static::get($option, null)) !== null &&
|
||||
method_exists($helper, $method);
|
||||
}
|
||||
|
||||
@ -280,7 +333,7 @@ abstract class Helper
|
||||
public static function _(string $method, array $arguments = [], ?string $option = null)
|
||||
{
|
||||
// get the helper class
|
||||
if (($helper = self::get($option, null)) !== null &&
|
||||
if (($helper = static::get($option, null)) !== null &&
|
||||
method_exists($helper, $method))
|
||||
{
|
||||
// we know this is not ideal...
|
||||
@ -291,6 +344,77 @@ abstract class Helper
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Model object based on the specified type, prefix, and configuration.
|
||||
*
|
||||
* @param string $type The model type to instantiate. Must not be empty.
|
||||
* @param string $prefix Prefix for the model class name. Optional, defaults to 'Administrator'.
|
||||
* @param string|null $option The component option. Optional, defaults to the component's option.
|
||||
* @param array $config Configuration array for the model. Optional, defaults to an empty array.
|
||||
*
|
||||
* @return BaseDatabaseModel The instantiated model object.
|
||||
*
|
||||
* @throws \InvalidArgumentException If the $type parameter is empty.
|
||||
* @throws \Exception For other errors that may occur during model creation.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function getModel(string $type, string $prefix = 'Administrator',
|
||||
?string $option = null, array $config = []): BaseDatabaseModel
|
||||
{
|
||||
// Ensure the $type parameter is not empty
|
||||
if (empty($type))
|
||||
{
|
||||
throw new \InvalidArgumentException('The $type parameter cannot be empty when calling Component Helper getModel method.');
|
||||
}
|
||||
|
||||
// Ensure the $option parameter is set, defaulting to the component's option if not provided
|
||||
if (empty($option))
|
||||
{
|
||||
$option = static::getOption();
|
||||
}
|
||||
|
||||
// Normalize the model type name if the first character is not uppercase
|
||||
if (!ctype_upper($type[0]))
|
||||
{
|
||||
$type = StringHelper::safe($type, 'F');
|
||||
}
|
||||
|
||||
// Normalize the prefix if it's not 'Site' or 'Administrator'
|
||||
if ($prefix !== 'Site' && $prefix !== 'Administrator')
|
||||
{
|
||||
$prefix = static::getPrefixFromModelPath($prefix);
|
||||
}
|
||||
|
||||
// Instantiate and return the model using the MVCFactory
|
||||
return Factory::getApplication()
|
||||
->bootComponent($option)
|
||||
->getMVCFactory()
|
||||
->createModel($type, $prefix, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prefix from the model path
|
||||
*
|
||||
* @param string $path The model path
|
||||
*
|
||||
* @return string The prefix value
|
||||
* @since 5.0.3
|
||||
*/
|
||||
private static function getPrefixFromModelPath(string $path): string
|
||||
{
|
||||
// Check if $path starts with JPATH_ADMINISTRATOR path
|
||||
if (str_starts_with($path, JPATH_ADMINISTRATOR . '/components/'))
|
||||
{
|
||||
return 'Administrator';
|
||||
}
|
||||
// Check if $path starts with JPATH_SITE path
|
||||
elseif (str_starts_with($path, JPATH_SITE . '/components/'))
|
||||
{
|
||||
return 'Site';
|
||||
}
|
||||
return 'Administrator';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,57 @@
|
||||
*/
|
||||
protected static array $params = [];
|
||||
|
||||
/**
|
||||
* Sets a parameter value for the given target in the specified option's params.
|
||||
* If no option is provided, it falls back to the default option.
|
||||
*
|
||||
* This method updates the parameters for a given extension in the database,
|
||||
* only if the new value differs from the existing one.
|
||||
*
|
||||
* @param string $target The parameter name to be updated.
|
||||
* @param mixed $value The value to set for the parameter.
|
||||
* @param string|null $option The optional extension element name. Defaults to null, which will use the default option.
|
||||
*
|
||||
* @return mixed The previous value of the parameter before it was updated.
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function setParams(string $target, $value, ?string $option = null)
|
||||
{
|
||||
// Ensure that an option is specified, defaulting to the system's option if not provided.
|
||||
if (empty($option))
|
||||
{
|
||||
$option = static::getOption();
|
||||
}
|
||||
|
||||
// Retrieve current parameters for the specified option.
|
||||
$params = static::getParams($option);
|
||||
|
||||
// Get the current value of the target parameter.
|
||||
$was = $params->get($target, null);
|
||||
|
||||
// Only proceed if the new value differs from the current value.
|
||||
if ($was !== $value)
|
||||
{
|
||||
// Update the parameter value.
|
||||
$params->set($target, $value);
|
||||
|
||||
// Obtain a database connection instance.
|
||||
$db = Factory::getDBO();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Build and execute the query to update the parameters in the database.
|
||||
$query->update('#__extensions AS a')
|
||||
->set('a.params = ' . $db->quote((string) $params))
|
||||
->where('a.element = ' . $db->quote((string) $option));
|
||||
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
}
|
||||
|
||||
// Return the previous value of the parameter.
|
||||
return $was;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parameter object for the component
|
||||
*
|
||||
@ -36,16 +87,16 @@
|
||||
// check that we have an option
|
||||
if (empty($option))
|
||||
{
|
||||
$option = self::getOption();
|
||||
$option = static::getOption();
|
||||
}
|
||||
|
||||
// get global value
|
||||
if (!isset(self::$params[$option]) || !self::$params[$option] instanceof Registry)
|
||||
if (!isset(static::$params[$option]) || !static::$params[$option] instanceof Registry)
|
||||
{
|
||||
self::$params[$option] = ComponentHelper::getParams($option);
|
||||
static::$params[$option] = ComponentHelper::getParams($option);
|
||||
}
|
||||
|
||||
return self::$params[$option];
|
||||
return static::$params[$option];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,7 +109,7 @@
|
||||
*/
|
||||
public static function setOption(?string $option): void
|
||||
{
|
||||
self::$option = $option;
|
||||
static::$option = $option;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,13 +122,13 @@
|
||||
*/
|
||||
public static function getOption(?string $default = 'empty'): ?string
|
||||
{
|
||||
if (empty(self::$option))
|
||||
if (empty(static::$option))
|
||||
{
|
||||
// get the option from the url input
|
||||
self::$option = (new Input)->getString('option', null);
|
||||
static::$option = (new Input)->getString('option', null);
|
||||
}
|
||||
|
||||
if (empty(self::$option))
|
||||
if (empty(static::$option))
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
@ -85,16 +136,16 @@
|
||||
if (method_exists($app, 'getInput'))
|
||||
{
|
||||
// get the option from the application
|
||||
self::$option = $app->getInput()->getCmd('option', $default);
|
||||
static::$option = $app->getInput()->getCmd('option', $default);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the default value if getInput method does not exist
|
||||
self::$option = $default;
|
||||
static::$option = $default;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$option;
|
||||
return static::$option;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +162,7 @@
|
||||
// check that we have an option
|
||||
if (empty($option))
|
||||
{
|
||||
$option = self::getOption();
|
||||
$option = static::getOption();
|
||||
}
|
||||
// option with com_
|
||||
if (is_string($option) && strpos($option, 'com_') === 0)
|
||||
@ -136,7 +187,7 @@
|
||||
{
|
||||
// check that we have an option
|
||||
// and get the code name from it
|
||||
if (($code_name = self::getCode($option, null)) !== null)
|
||||
if (($code_name = static::getCode($option, null)) !== null)
|
||||
{
|
||||
// we build the helper class name
|
||||
$helper_name = '\\' . \ucfirst($code_name) . 'Helper';
|
||||
@ -148,7 +199,7 @@
|
||||
}
|
||||
|
||||
// try loading namespace
|
||||
if (($namespace = self::getNamespace($option)) !== null)
|
||||
if (($namespace = static::getNamespace($option)) !== null)
|
||||
{
|
||||
$name = \ucfirst($code_name) . 'Helper';
|
||||
$namespace_helper = '\\' . $namespace . '\Administrator\Helper\\' . NamespaceHelper::safeSegment($name); // TODO target site or admin locations not just admin...
|
||||
@ -174,7 +225,7 @@
|
||||
*/
|
||||
public static function getNamespace(?string $option = null): ?string
|
||||
{
|
||||
$manifest = self::getManifest($option);
|
||||
$manifest = static::getManifest($option);
|
||||
|
||||
return $manifest->namespace ?? null;
|
||||
}
|
||||
@ -192,13 +243,13 @@
|
||||
public static function getManifest(?string $option = null): ?object
|
||||
{
|
||||
if ($option === null
|
||||
&& ($option = self::getOption($option)) === null)
|
||||
&& ($option = static::getOption($option)) === null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// get global manifest_cache values
|
||||
if (!isset(self::$manifest[$option]))
|
||||
if (!isset(static::$manifest[$option]))
|
||||
{
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
@ -212,14 +263,14 @@
|
||||
|
||||
try {
|
||||
$manifest = $db->loadResult();
|
||||
self::$manifest[$option] = json_decode($manifest);
|
||||
static::$manifest[$option] = json_decode($manifest);
|
||||
} catch (\Exception $e) {
|
||||
// Handle the database error appropriately.
|
||||
self::$manifest[$option] = null;
|
||||
static::$manifest[$option] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$manifest[$option];
|
||||
return static::$manifest[$option];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,7 +286,7 @@
|
||||
public static function methodExists(string $method, ?string $option = null): bool
|
||||
{
|
||||
// get the helper class
|
||||
return ($helper = self::get($option, null)) !== null &&
|
||||
return ($helper = static::get($option, null)) !== null &&
|
||||
method_exists($helper, $method);
|
||||
}
|
||||
|
||||
@ -252,7 +303,7 @@
|
||||
public static function _(string $method, array $arguments = [], ?string $option = null)
|
||||
{
|
||||
// get the helper class
|
||||
if (($helper = self::get($option, null)) !== null &&
|
||||
if (($helper = static::get($option, null)) !== null &&
|
||||
method_exists($helper, $method))
|
||||
{
|
||||
// we know this is not ideal...
|
||||
@ -263,3 +314,75 @@
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Model object based on the specified type, prefix, and configuration.
|
||||
*
|
||||
* @param string $type The model type to instantiate. Must not be empty.
|
||||
* @param string $prefix Prefix for the model class name. Optional, defaults to 'Administrator'.
|
||||
* @param string|null $option The component option. Optional, defaults to the component's option.
|
||||
* @param array $config Configuration array for the model. Optional, defaults to an empty array.
|
||||
*
|
||||
* @return BaseDatabaseModel The instantiated model object.
|
||||
*
|
||||
* @throws \InvalidArgumentException If the $type parameter is empty.
|
||||
* @throws \Exception For other errors that may occur during model creation.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function getModel(string $type, string $prefix = 'Administrator',
|
||||
?string $option = null, array $config = []): BaseDatabaseModel
|
||||
{
|
||||
// Ensure the $type parameter is not empty
|
||||
if (empty($type))
|
||||
{
|
||||
throw new \InvalidArgumentException('The $type parameter cannot be empty when calling Component Helper getModel method.');
|
||||
}
|
||||
|
||||
// Ensure the $option parameter is set, defaulting to the component's option if not provided
|
||||
if (empty($option))
|
||||
{
|
||||
$option = static::getOption();
|
||||
}
|
||||
|
||||
// Normalize the model type name if the first character is not uppercase
|
||||
if (!ctype_upper($type[0]))
|
||||
{
|
||||
$type = StringHelper::safe($type, 'F');
|
||||
}
|
||||
|
||||
// Normalize the prefix if it's not 'Site' or 'Administrator'
|
||||
if ($prefix !== 'Site' && $prefix !== 'Administrator')
|
||||
{
|
||||
$prefix = static::getPrefixFromModelPath($prefix);
|
||||
}
|
||||
|
||||
// Instantiate and return the model using the MVCFactory
|
||||
return Factory::getApplication()
|
||||
->bootComponent($option)
|
||||
->getMVCFactory()
|
||||
->createModel($type, $prefix, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prefix from the model path
|
||||
*
|
||||
* @param string $path The model path
|
||||
*
|
||||
* @return string The prefix value
|
||||
* @since 5.0.3
|
||||
*/
|
||||
private static function getPrefixFromModelPath(string $path): string
|
||||
{
|
||||
// Check if $path starts with JPATH_ADMINISTRATOR path
|
||||
if (str_starts_with($path, JPATH_ADMINISTRATOR . '/components/'))
|
||||
{
|
||||
return 'Administrator';
|
||||
}
|
||||
// Check if $path starts with JPATH_SITE path
|
||||
elseif (str_starts_with($path, JPATH_SITE . '/components/'))
|
||||
{
|
||||
return 'Site';
|
||||
}
|
||||
return 'Administrator';
|
||||
}
|
@ -13,12 +13,16 @@
|
||||
"use_selection0": {
|
||||
"use": "ce8cf834-6bac-44fb-941c-861f7e046cc0",
|
||||
"as": "default"
|
||||
},
|
||||
"use_selection1": {
|
||||
"use": "1f28cb53-60d9-4db1-b517-3c7dc6b429ef",
|
||||
"as": "default"
|
||||
}
|
||||
},
|
||||
"extendsinterfaces": null,
|
||||
"namespace": "[[[NamespacePrefix]]]\\Joomla\\Utilities.Component.Helper",
|
||||
"description": "Some component helper\r\n\r\n@since 3.0.11",
|
||||
"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": "use Joomla\\CMS\\Factory;\r\nuse Joomla\\CMS\\Component\\ComponentHelper;\r\nuse Joomla\\Input\\Input;\r\nuse Joomla\\Registry\\Registry;",
|
||||
"head": "use Joomla\\CMS\\Factory;\r\nuse Joomla\\CMS\\Component\\ComponentHelper;\r\nuse Joomla\\CMS\\MVC\\Model\\BaseDatabaseModel;\r\nuse Joomla\\Input\\Input;\r\nuse Joomla\\Registry\\Registry;",
|
||||
"composer": ""
|
||||
}
|
141
src/7832a726-87b6-4e95-887e-7b725d3fab8f/README.md
Normal file
141
src/7832a726-87b6-4e95-887e-7b725d3fab8f/README.md
Normal file
@ -0,0 +1,141 @@
|
||||
```
|
||||
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
|
||||
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
|
||||
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
|
||||
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
|
||||
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
|
||||
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
|
||||
```
|
||||
# abstract class UserHelper (Details)
|
||||
> namespace: **VDM\Joomla\Componentbuilder\Utilities**
|
||||
|
||||
```uml
|
||||
@startuml
|
||||
abstract UserHelper #Orange {
|
||||
+ {static} save(array $credentials, int $autologin, ...) : int
|
||||
+ {static} create(array $credentials, int $autologin, ...) : int
|
||||
+ {static} update(array $userDetails) : int
|
||||
+ {static} getUserById(int $id) : User
|
||||
+ {static} getUserIdByUsername(string $username) : ?int
|
||||
+ {static} getUserIdByEmail(string $email) : ?int
|
||||
# {static} getModelByMode(int $mode) : BaseDatabaseModel
|
||||
# {static} prepareUserData(array $credentials, int $mode) : array
|
||||
- {static} adminRegister(BaseDatabaseModel $model, array $data) : int
|
||||
- {static} handlePostRegistration(int $userId, int $autologin, ...) : int
|
||||
}
|
||||
|
||||
note right of UserHelper::save
|
||||
Save user details by either creating a new user or updating an existing user.
|
||||
|
||||
since: 5.0.3
|
||||
return: int
|
||||
|
||||
arguments:
|
||||
array $credentials
|
||||
int $autologin
|
||||
array $params = ['useractivation' => 0, 'sendpassword' => 1]
|
||||
int $mode = 1
|
||||
end note
|
||||
|
||||
note left of UserHelper::create
|
||||
Create a user and update the given table.
|
||||
|
||||
since: 5.0.3
|
||||
return: int
|
||||
|
||||
arguments:
|
||||
array $credentials
|
||||
int $autologin
|
||||
array $params = ['useractivation' => 0, 'sendpassword' => 1]
|
||||
int $mode = 1
|
||||
end note
|
||||
|
||||
note right of UserHelper::update
|
||||
Update user details.
|
||||
|
||||
since: 5.0.3
|
||||
return: int
|
||||
end note
|
||||
|
||||
note left of UserHelper::getUserById
|
||||
Method to get an instance of a user for the given id.
|
||||
|
||||
since: 5.0.3
|
||||
return: User
|
||||
end note
|
||||
|
||||
note right of UserHelper::getUserIdByUsername
|
||||
Retrieve the user ID by username.
|
||||
|
||||
since: 5.0.3
|
||||
return: ?int
|
||||
end note
|
||||
|
||||
note left of UserHelper::getUserIdByEmail
|
||||
Retrieve the user ID by email.
|
||||
|
||||
since: 5.0.3
|
||||
return: ?int
|
||||
end note
|
||||
|
||||
note right of UserHelper::getModelByMode
|
||||
Load the correct user model based on the registration mode.
|
||||
|
||||
since: 5.0.3
|
||||
return: BaseDatabaseModel
|
||||
end note
|
||||
|
||||
note left of UserHelper::prepareUserData
|
||||
Prepare user data array for registration or update.
|
||||
|
||||
since: 5.0.3
|
||||
return: array
|
||||
end note
|
||||
|
||||
note right of UserHelper::adminRegister
|
||||
Handle the registration process for admin mode.
|
||||
|
||||
since: 5.0.3
|
||||
return: int
|
||||
end note
|
||||
|
||||
note left of UserHelper::handlePostRegistration
|
||||
Handle post-registration processes like auto-login.
|
||||
|
||||
since: 5.0.3
|
||||
return: int
|
||||
|
||||
arguments:
|
||||
int $userId
|
||||
int $autologin
|
||||
array $credentials
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
|
||||
|
||||
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
|
||||
|
||||
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
|
||||
|
||||
To add this specific Power to your project in JCB:
|
||||
|
||||
> simply use this SPK
|
||||
```
|
||||
Super---7832a726_87b6_4e95_887e_7b725d3fab8f---Power
|
||||
```
|
||||
> remember to replace the `---` with `___` to activate this Power in your code
|
||||
|
||||
---
|
||||
```
|
||||
██╗ ██████╗██████╗
|
||||
██║██╔════╝██╔══██╗
|
||||
██║██║ ██████╔╝
|
||||
██ ██║██║ ██╔══██╗
|
||||
╚█████╔╝╚██████╗██████╔╝
|
||||
╚════╝ ╚═════╝╚═════╝
|
||||
```
|
||||
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
|
413
src/7832a726-87b6-4e95-887e-7b725d3fab8f/code.php
Normal file
413
src/7832a726-87b6-4e95-887e-7b725d3fab8f/code.php
Normal file
@ -0,0 +1,413 @@
|
||||
<?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\Componentbuilder\Utilities;
|
||||
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\User\User;
|
||||
use Joomla\CMS\User\UserHelper as JoomlaUserHelper;
|
||||
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
||||
use VDM\Joomla\Utilities\Component\Helper as Component;
|
||||
use VDM\Component\Componentbuilder\Administrator\Helper\ComponentbuilderHelper;
|
||||
|
||||
|
||||
/**
|
||||
* Create & Update User [Save]
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
abstract class UserHelper
|
||||
{
|
||||
/**
|
||||
* Save user details by either creating a new user or updating an existing user.
|
||||
*
|
||||
* @param array $credentials User credentials including 'name', 'username', 'email', 'password', and 'password2'.
|
||||
* @param int $autologin Flag to determine whether to auto-login the user after registration.
|
||||
* @param array $params Parameters for user activation, password sending, and user registration allowance.
|
||||
* @param int $mode Mode of registration: 1 = Site Registration, 0 = Admin Registration, 2 = Custom Helper Method.
|
||||
*
|
||||
* @return int User ID on success.
|
||||
*
|
||||
* @throws \InvalidArgumentException If required credentials are missing.
|
||||
* @throws \RuntimeException If the user update or creation fails.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function save(array $credentials, int $autologin = 0,
|
||||
array $params = ['useractivation' => 0, 'sendpassword' => 1], int $mode = 1): int
|
||||
{
|
||||
// can not continue without an email
|
||||
if (empty($credentials['email']))
|
||||
{
|
||||
throw new \InvalidArgumentException(Text::_('COM_COMPONENTBUILDER_CAN_NOT_SAVE_USER_WITHOUT_EMAIL_VALUE'));
|
||||
}
|
||||
|
||||
// Ensure the 'username' key exists in the credentials array, set to an empty string if not provided.
|
||||
$username = $credentials['username'] ?? $credentials['email'];
|
||||
|
||||
// Check for an existing user by email or username.
|
||||
$existingEmailUserId = static::getUserIdByEmail($credentials['email']);
|
||||
$existingUserId = static::getUserIdByUsername($username);
|
||||
|
||||
// If either the email or username already exists, handle the update logic.
|
||||
if ($existingEmailUserId !== null || $existingUserId !== null || (isset($credentials['id']) && $credentials['id'] > 0))
|
||||
{
|
||||
// Prevent updating other users or reusing an email by different users.
|
||||
if (
|
||||
(
|
||||
isset($credentials['id']) &&
|
||||
(
|
||||
($existingEmailUserId !== null && $existingEmailUserId != $credentials['id']) ||
|
||||
($existingUserId !== null && $existingUserId != $credentials['id'])
|
||||
)
|
||||
) || ($existingUserId !== null && $existingEmailUserId !== null && $existingEmailUserId != $existingUserId)
|
||||
)
|
||||
{
|
||||
throw new \RuntimeException(Text::sprintf('COM_COMPONENTBUILDER_USER_ID_MISMATCH_DETECTED_WHEN_TRYING_TO_SAVE_S_S_CREDENTIALS', $username, $credentials['email']));
|
||||
}
|
||||
|
||||
// Update the existing user.
|
||||
$credentials['id'] = $credentials['id'] ?? $existingEmailUserId ?? $existingUserId;
|
||||
return static::update($credentials);
|
||||
}
|
||||
|
||||
// Create a new user if no existing user is found.
|
||||
return static::create($credentials, $autologin, $params, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a user and update the given table.
|
||||
*
|
||||
* @param array $credentials User credentials including 'name', 'username', 'email', 'password', and 'password2'.
|
||||
* @param int $autologin Flag to determine whether to auto-login the user after registration.
|
||||
* @param array $params Parameters for user activation, password sending, and user registration allowance.
|
||||
* @param int $mode Mode of registration: 1 = Site Registration, 0 = Admin Registration, 2 = Custom Helper Method.
|
||||
*
|
||||
* @return int User ID on success.
|
||||
*
|
||||
* @throws \RuntimeException If user creation fails.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function create(array $credentials, int $autologin = 0,
|
||||
array $params = ['useractivation' => 0, 'sendpassword' => 1], int $mode = 1): int
|
||||
{
|
||||
$lang = Factory::getLanguage();
|
||||
$lang->load('com_users', JPATH_SITE, 'en-GB', true);
|
||||
|
||||
// Handle custom registration mode
|
||||
if ($mode === 2 && method_exists(ComponentbuilderHelper::class, 'registerUser'))
|
||||
{
|
||||
$params['autologin'] = $autologin;
|
||||
$userId = ComponentbuilderHelper::registerUser($credentials, $params);
|
||||
|
||||
if (is_numeric($userId))
|
||||
{
|
||||
return $userId;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(Text::_('COM_COMPONENTBUILDER_USER_CREATION_FAILED'));
|
||||
}
|
||||
|
||||
// Check if we have params/config
|
||||
if (ArrayHelper::check($params))
|
||||
{
|
||||
// Make changes to user config
|
||||
foreach ($params as $param => $set)
|
||||
{
|
||||
// If you know of a better path, let me know
|
||||
$params[$param] = Component::setParams($param, $set, 'com_users');
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to Site Registrations if mode is set to 2 but the method doesn't exist
|
||||
$mode = $mode === 2 ? 1 : $mode;
|
||||
|
||||
// Load the appropriate user model
|
||||
$model = static::getModelByMode($mode);
|
||||
|
||||
// Set default values for missing credentials
|
||||
$credentials['username'] = $credentials['username'] ?? $credentials['email'];
|
||||
|
||||
// Prepare user data
|
||||
$data = static::prepareUserData($credentials, $mode);
|
||||
|
||||
// Handle user creation
|
||||
$userId = $mode === 1 ? $model->register($data) : static::adminRegister($model, $data);
|
||||
|
||||
// Check if we have params
|
||||
if (ArrayHelper::check($params))
|
||||
{
|
||||
// Change user params/config back
|
||||
foreach ($params as $param => $set)
|
||||
{
|
||||
// If you know of a better path, let me know
|
||||
Component::setParams($param, $set, 'com_users');
|
||||
}
|
||||
}
|
||||
|
||||
if (is_numeric($userId) && $userId > 0)
|
||||
{
|
||||
// Handle post-registration processes
|
||||
return static::handlePostRegistration($userId, $autologin, $credentials);
|
||||
}
|
||||
|
||||
$error_messages = '';
|
||||
if (method_exists($model, 'getError'))
|
||||
{
|
||||
$errors = $model->getError();
|
||||
if (!empty($errors))
|
||||
{
|
||||
$error_messages = '<br>' . implode('<br>', $errors);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \RuntimeException(
|
||||
Text::sprintf('COM_COMPONENTBUILDER_USER_S_S_CREATION_FAILEDS',
|
||||
(string) $credentials['username'],
|
||||
(string) $credentials['email'],
|
||||
$error_messages
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user details.
|
||||
*
|
||||
* @param array $userDetails Array containing user details to be updated.
|
||||
*
|
||||
* @return int Updated user ID on success.
|
||||
*
|
||||
* @throws \RuntimeException If user update fails.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function update(array $userDetails): int
|
||||
{
|
||||
$lang = Factory::getLanguage();
|
||||
$lang->load('com_users', JPATH_ADMINISTRATOR, 'en-GB', true);
|
||||
|
||||
$model = Component::getModel('User', 'Administrator', 'com_users');
|
||||
|
||||
// Set default values for missing credentials
|
||||
$userDetails['username'] = $userDetails['username'] ?? $userDetails['email'];
|
||||
|
||||
// Prepare user data for update
|
||||
$data = [
|
||||
'id' => $userDetails['id'],
|
||||
'username' => $userDetails['username'],
|
||||
'name' => $userDetails['name'],
|
||||
'email' => $userDetails['email'],
|
||||
'password' => $userDetails['password'] ?? null,
|
||||
'password2' => $userDetails['password2'] ?? null,
|
||||
'block' => 0
|
||||
];
|
||||
|
||||
// set groups if found
|
||||
if (isset($userDetails['groups']) && ArrayHelper::check($userDetails['groups']))
|
||||
{
|
||||
$data['groups'] = $userDetails['groups'];
|
||||
}
|
||||
|
||||
// Update the user
|
||||
if ($model->save($data))
|
||||
{
|
||||
return $userDetails['id'];
|
||||
}
|
||||
|
||||
$error_messages = '';
|
||||
if (method_exists($model, 'getError'))
|
||||
{
|
||||
$errors = $model->getError();
|
||||
if (!empty($errors))
|
||||
{
|
||||
$error_messages = '<br>' . implode('<br>', $errors);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \RuntimeException(
|
||||
Text::sprintf('COM_COMPONENTBUILDER_UPDATE_OF_USER_S_S_FAILEDS',
|
||||
(string) $userDetails['username'],
|
||||
(string) $userDetails['email'],
|
||||
(string) $error_messages
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an instance of a user for the given id.
|
||||
*
|
||||
* @param int $id The id
|
||||
*
|
||||
* @return User
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function getUserById(int $id): User
|
||||
{
|
||||
return new User($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the user ID by username.
|
||||
*
|
||||
* @param string $username The username to check.
|
||||
*
|
||||
* @return int|null The user ID if the user exists, null otherwise.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function getUserIdByUsername(string $username): ?int
|
||||
{
|
||||
$userId = JoomlaUserHelper::getUserId($username);
|
||||
return $userId ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the user ID by email.
|
||||
*
|
||||
* @param string $email The email address to check.
|
||||
*
|
||||
* @return int|null The user ID if the user exists, null otherwise.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function getUserIdByEmail(string $email): ?int
|
||||
{
|
||||
// Initialise some variables
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__users'))
|
||||
->where($db->quoteName('email') . ' = :email')
|
||||
->bind(':email', $email)
|
||||
->setLimit(1);
|
||||
$db->setQuery($query);
|
||||
|
||||
$userId = $db->loadResult();
|
||||
return $userId ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the correct user model based on the registration mode.
|
||||
*
|
||||
* @param int $mode The registration mode.
|
||||
*
|
||||
* @return BaseDatabaseModel The appropriate user model.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
protected static function getModelByMode(int $mode): BaseDatabaseModel
|
||||
{
|
||||
if ($mode === 1)
|
||||
{
|
||||
return Component::getModel('Registration', 'Site', 'com_users');
|
||||
}
|
||||
|
||||
return Component::getModel('User', 'Administrator', 'com_users');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare user data array for registration or update.
|
||||
*
|
||||
* @param array $credentials User credentials.
|
||||
* @param int $mode The registration mode.
|
||||
*
|
||||
* @return array The prepared user data array.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
protected static function prepareUserData(array $credentials, int $mode)
|
||||
{
|
||||
$data = [
|
||||
'username' => $credentials['username'],
|
||||
'name' => $credentials['name'],
|
||||
'block' => 0
|
||||
];
|
||||
|
||||
if ($mode === 1)
|
||||
{
|
||||
$data['email1'] = $credentials['email'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['email'] = $credentials['email'];
|
||||
$data['registerDate'] = Factory::getDate()->toSql();
|
||||
}
|
||||
|
||||
if ($mode === 1 && empty($credentials['password']))
|
||||
{
|
||||
$credentials['password'] = StringHelper::random(10);
|
||||
$credentials['password2'] = $credentials['password'];
|
||||
}
|
||||
|
||||
if (!empty($credentials['password']) && !empty($credentials['password2']))
|
||||
{
|
||||
$data['password1'] = $credentials['password'];
|
||||
$data['password2'] = $credentials['password2'];
|
||||
}
|
||||
|
||||
if ($mode === 0 && isset($credentials['groups']) && ArrayHelper::check($credentials['groups']))
|
||||
{
|
||||
$data['groups'] = $credentials['groups'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the registration process for admin mode.
|
||||
*
|
||||
* @param BaseDatabaseModel $model The user model.
|
||||
* @param array $data The user data.
|
||||
*
|
||||
* @return int The ID of the created user.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
private static function adminRegister(BaseDatabaseModel $model, array $data): int
|
||||
{
|
||||
$model->save($data);
|
||||
|
||||
return $model->getState('user.id', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle post-registration processes like auto-login.
|
||||
*
|
||||
* @param int $userId The ID of the created user.
|
||||
* @param int $autologin Flag to determine whether to auto-login the user.
|
||||
* @param array $credentials The user credentials.
|
||||
*
|
||||
* @return int The user ID on success.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
private static function handlePostRegistration(int $userId, int $autologin, array $credentials): int
|
||||
{
|
||||
if ($autologin && isset($credentials['password']))
|
||||
{
|
||||
try
|
||||
{
|
||||
Factory::getApplication()->login($credentials);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
// we might need to redirect here?
|
||||
}
|
||||
}
|
||||
|
||||
return $userId;
|
||||
}
|
||||
}
|
||||
|
381
src/7832a726-87b6-4e95-887e-7b725d3fab8f/code.power
Normal file
381
src/7832a726-87b6-4e95-887e-7b725d3fab8f/code.power
Normal file
@ -0,0 +1,381 @@
|
||||
/**
|
||||
* Save user details by either creating a new user or updating an existing user.
|
||||
*
|
||||
* @param array $credentials User credentials including 'name', 'username', 'email', 'password', and 'password2'.
|
||||
* @param int $autologin Flag to determine whether to auto-login the user after registration.
|
||||
* @param array $params Parameters for user activation, password sending, and user registration allowance.
|
||||
* @param int $mode Mode of registration: 1 = Site Registration, 0 = Admin Registration, 2 = Custom Helper Method.
|
||||
*
|
||||
* @return int User ID on success.
|
||||
*
|
||||
* @throws \InvalidArgumentException If required credentials are missing.
|
||||
* @throws \RuntimeException If the user update or creation fails.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function save(array $credentials, int $autologin = 0,
|
||||
array $params = ['useractivation' => 0, 'sendpassword' => 1], int $mode = 1): int
|
||||
{
|
||||
// can not continue without an email
|
||||
if (empty($credentials['email']))
|
||||
{
|
||||
throw new \InvalidArgumentException(Text::_('Can not save user without email value.'));
|
||||
}
|
||||
|
||||
// Ensure the 'username' key exists in the credentials array, set to an empty string if not provided.
|
||||
$username = $credentials['username'] ?? $credentials['email'];
|
||||
|
||||
// Check for an existing user by email or username.
|
||||
$existingEmailUserId = static::getUserIdByEmail($credentials['email']);
|
||||
$existingUserId = static::getUserIdByUsername($username);
|
||||
|
||||
// If either the email or username already exists, handle the update logic.
|
||||
if ($existingEmailUserId !== null || $existingUserId !== null || (isset($credentials['id']) && $credentials['id'] > 0))
|
||||
{
|
||||
// Prevent updating other users or reusing an email by different users.
|
||||
if (
|
||||
(
|
||||
isset($credentials['id']) &&
|
||||
(
|
||||
($existingEmailUserId !== null && $existingEmailUserId != $credentials['id']) ||
|
||||
($existingUserId !== null && $existingUserId != $credentials['id'])
|
||||
)
|
||||
) || ($existingUserId !== null && $existingEmailUserId !== null && $existingEmailUserId != $existingUserId)
|
||||
)
|
||||
{
|
||||
throw new \RuntimeException(Text::sprintf('User ID mismatch detected when trying to save %s (%s) credentials.', $username, $credentials['email']));
|
||||
}
|
||||
|
||||
// Update the existing user.
|
||||
$credentials['id'] = $credentials['id'] ?? $existingEmailUserId ?? $existingUserId;
|
||||
return static::update($credentials);
|
||||
}
|
||||
|
||||
// Create a new user if no existing user is found.
|
||||
return static::create($credentials, $autologin, $params, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a user and update the given table.
|
||||
*
|
||||
* @param array $credentials User credentials including 'name', 'username', 'email', 'password', and 'password2'.
|
||||
* @param int $autologin Flag to determine whether to auto-login the user after registration.
|
||||
* @param array $params Parameters for user activation, password sending, and user registration allowance.
|
||||
* @param int $mode Mode of registration: 1 = Site Registration, 0 = Admin Registration, 2 = Custom Helper Method.
|
||||
*
|
||||
* @return int User ID on success.
|
||||
*
|
||||
* @throws \RuntimeException If user creation fails.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function create(array $credentials, int $autologin = 0,
|
||||
array $params = ['useractivation' => 0, 'sendpassword' => 1], int $mode = 1): int
|
||||
{
|
||||
$lang = Factory::getLanguage();
|
||||
$lang->load('com_users', JPATH_SITE, 'en-GB', true);
|
||||
|
||||
// Handle custom registration mode
|
||||
if ($mode === 2 && method_exists(ComponentbuilderHelper::class, 'registerUser'))
|
||||
{
|
||||
$params['autologin'] = $autologin;
|
||||
$userId = ComponentbuilderHelper::registerUser($credentials, $params);
|
||||
|
||||
if (is_numeric($userId))
|
||||
{
|
||||
return $userId;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(Text::_('User creation failed!'));
|
||||
}
|
||||
|
||||
// Check if we have params/config
|
||||
if (ArrayHelper::check($params))
|
||||
{
|
||||
// Make changes to user config
|
||||
foreach ($params as $param => $set)
|
||||
{
|
||||
// If you know of a better path, let me know
|
||||
$params[$param] = Component::setParams($param, $set, 'com_users');
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to Site Registrations if mode is set to 2 but the method doesn't exist
|
||||
$mode = $mode === 2 ? 1 : $mode;
|
||||
|
||||
// Load the appropriate user model
|
||||
$model = static::getModelByMode($mode);
|
||||
|
||||
// Set default values for missing credentials
|
||||
$credentials['username'] = $credentials['username'] ?? $credentials['email'];
|
||||
|
||||
// Prepare user data
|
||||
$data = static::prepareUserData($credentials, $mode);
|
||||
|
||||
// Handle user creation
|
||||
$userId = $mode === 1 ? $model->register($data) : static::adminRegister($model, $data);
|
||||
|
||||
// Check if we have params
|
||||
if (ArrayHelper::check($params))
|
||||
{
|
||||
// Change user params/config back
|
||||
foreach ($params as $param => $set)
|
||||
{
|
||||
// If you know of a better path, let me know
|
||||
Component::setParams($param, $set, 'com_users');
|
||||
}
|
||||
}
|
||||
|
||||
if (is_numeric($userId) && $userId > 0)
|
||||
{
|
||||
// Handle post-registration processes
|
||||
return static::handlePostRegistration($userId, $autologin, $credentials);
|
||||
}
|
||||
|
||||
$error_messages = '';
|
||||
if (method_exists($model, 'getError'))
|
||||
{
|
||||
$errors = $model->getError();
|
||||
if (!empty($errors))
|
||||
{
|
||||
$error_messages = '<br>' . implode('<br>', $errors);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \RuntimeException(
|
||||
Text::sprintf('User %s (%s) creation failed!%s',
|
||||
(string) $credentials['username'],
|
||||
(string) $credentials['email'],
|
||||
$error_messages
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user details.
|
||||
*
|
||||
* @param array $userDetails Array containing user details to be updated.
|
||||
*
|
||||
* @return int Updated user ID on success.
|
||||
*
|
||||
* @throws \RuntimeException If user update fails.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function update(array $userDetails): int
|
||||
{
|
||||
$lang = Factory::getLanguage();
|
||||
$lang->load('com_users', JPATH_ADMINISTRATOR, 'en-GB', true);
|
||||
|
||||
$model = Component::getModel('User', 'Administrator', 'com_users');
|
||||
|
||||
// Set default values for missing credentials
|
||||
$userDetails['username'] = $userDetails['username'] ?? $userDetails['email'];
|
||||
|
||||
// Prepare user data for update
|
||||
$data = [
|
||||
'id' => $userDetails['id'],
|
||||
'username' => $userDetails['username'],
|
||||
'name' => $userDetails['name'],
|
||||
'email' => $userDetails['email'],
|
||||
'password' => $userDetails['password'] ?? null,
|
||||
'password2' => $userDetails['password2'] ?? null,
|
||||
'block' => 0
|
||||
];
|
||||
|
||||
// set groups if found
|
||||
if (isset($userDetails['groups']) && ArrayHelper::check($userDetails['groups']))
|
||||
{
|
||||
$data['groups'] = $userDetails['groups'];
|
||||
}
|
||||
|
||||
// Update the user
|
||||
if ($model->save($data))
|
||||
{
|
||||
return $userDetails['id'];
|
||||
}
|
||||
|
||||
$error_messages = '';
|
||||
if (method_exists($model, 'getError'))
|
||||
{
|
||||
$errors = $model->getError();
|
||||
if (!empty($errors))
|
||||
{
|
||||
$error_messages = '<br>' . implode('<br>', $errors);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \RuntimeException(
|
||||
Text::sprintf('Update of user %s (%s) failed!%s',
|
||||
(string) $userDetails['username'],
|
||||
(string) $userDetails['email'],
|
||||
(string) $error_messages
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an instance of a user for the given id.
|
||||
*
|
||||
* @param int $id The id
|
||||
*
|
||||
* @return User
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function getUserById(int $id): User
|
||||
{
|
||||
return new User($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the user ID by username.
|
||||
*
|
||||
* @param string $username The username to check.
|
||||
*
|
||||
* @return int|null The user ID if the user exists, null otherwise.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function getUserIdByUsername(string $username): ?int
|
||||
{
|
||||
$userId = JoomlaUserHelper::getUserId($username);
|
||||
return $userId ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the user ID by email.
|
||||
*
|
||||
* @param string $email The email address to check.
|
||||
*
|
||||
* @return int|null The user ID if the user exists, null otherwise.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
public static function getUserIdByEmail(string $email): ?int
|
||||
{
|
||||
// Initialise some variables
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__users'))
|
||||
->where($db->quoteName('email') . ' = :email')
|
||||
->bind(':email', $email)
|
||||
->setLimit(1);
|
||||
$db->setQuery($query);
|
||||
|
||||
$userId = $db->loadResult();
|
||||
return $userId ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the correct user model based on the registration mode.
|
||||
*
|
||||
* @param int $mode The registration mode.
|
||||
*
|
||||
* @return BaseDatabaseModel The appropriate user model.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
protected static function getModelByMode(int $mode): BaseDatabaseModel
|
||||
{
|
||||
if ($mode === 1)
|
||||
{
|
||||
return Component::getModel('Registration', 'Site', 'com_users');
|
||||
}
|
||||
|
||||
return Component::getModel('User', 'Administrator', 'com_users');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare user data array for registration or update.
|
||||
*
|
||||
* @param array $credentials User credentials.
|
||||
* @param int $mode The registration mode.
|
||||
*
|
||||
* @return array The prepared user data array.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
protected static function prepareUserData(array $credentials, int $mode)
|
||||
{
|
||||
$data = [
|
||||
'username' => $credentials['username'],
|
||||
'name' => $credentials['name'],
|
||||
'block' => 0
|
||||
];
|
||||
|
||||
if ($mode === 1)
|
||||
{
|
||||
$data['email1'] = $credentials['email'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['email'] = $credentials['email'];
|
||||
$data['registerDate'] = Factory::getDate()->toSql();
|
||||
}
|
||||
|
||||
if ($mode === 1 && empty($credentials['password']))
|
||||
{
|
||||
$credentials['password'] = StringHelper::random(10);
|
||||
$credentials['password2'] = $credentials['password'];
|
||||
}
|
||||
|
||||
if (!empty($credentials['password']) && !empty($credentials['password2']))
|
||||
{
|
||||
$data['password1'] = $credentials['password'];
|
||||
$data['password2'] = $credentials['password2'];
|
||||
}
|
||||
|
||||
if ($mode === 0 && isset($credentials['groups']) && ArrayHelper::check($credentials['groups']))
|
||||
{
|
||||
$data['groups'] = $credentials['groups'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the registration process for admin mode.
|
||||
*
|
||||
* @param BaseDatabaseModel $model The user model.
|
||||
* @param array $data The user data.
|
||||
*
|
||||
* @return int The ID of the created user.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
private static function adminRegister(BaseDatabaseModel $model, array $data): int
|
||||
{
|
||||
$model->save($data);
|
||||
|
||||
return $model->getState('user.id', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle post-registration processes like auto-login.
|
||||
*
|
||||
* @param int $userId The ID of the created user.
|
||||
* @param int $autologin Flag to determine whether to auto-login the user.
|
||||
* @param array $credentials The user credentials.
|
||||
*
|
||||
* @return int The user ID on success.
|
||||
*
|
||||
* @since 5.0.3
|
||||
*/
|
||||
private static function handlePostRegistration(int $userId, int $autologin, array $credentials): int
|
||||
{
|
||||
if ($autologin && isset($credentials['password']))
|
||||
{
|
||||
try
|
||||
{
|
||||
Factory::getApplication()->login($credentials);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
// we might need to redirect here?
|
||||
}
|
||||
}
|
||||
|
||||
return $userId;
|
||||
}
|
31
src/7832a726-87b6-4e95-887e-7b725d3fab8f/settings.json
Normal file
31
src/7832a726-87b6-4e95-887e-7b725d3fab8f/settings.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"add_head": "1",
|
||||
"add_licensing_template": "2",
|
||||
"extends": "",
|
||||
"guid": "7832a726-87b6-4e95-887e-7b725d3fab8f",
|
||||
"implements": null,
|
||||
"load_selection": {
|
||||
"load_selection0": {
|
||||
"load": "0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a"
|
||||
},
|
||||
"load_selection1": {
|
||||
"load": "1f28cb53-60d9-4db1-b517-3c7dc6b429ef"
|
||||
}
|
||||
},
|
||||
"name": "UserHelper",
|
||||
"power_version": "1.0.0",
|
||||
"system_name": "Joomla.Utilities.UserHelper",
|
||||
"type": "abstract class",
|
||||
"use_selection": {
|
||||
"use_selection0": {
|
||||
"use": "640b5352-fb09-425f-a26e-cd44eda03f15",
|
||||
"as": "Component"
|
||||
}
|
||||
},
|
||||
"extendsinterfaces": null,
|
||||
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Utilities.UserHelper",
|
||||
"description": "Create & Update User [Save]\r\n\r\n@since 5.0.2",
|
||||
"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": "use Joomla\\CMS\\Factory;\r\nuse Joomla\\CMS\\Language\\Text;\r\nuse Joomla\\CMS\\User\\User;\r\nuse Joomla\\CMS\\User\\UserHelper as JoomlaUserHelper;\r\nuse Joomla\\CMS\\MVC\\Model\\BaseDatabaseModel;",
|
||||
"composer": ""
|
||||
}
|
@ -22,7 +22,6 @@ class Subform << (F,LightGreen) >> #RoyalBlue {
|
||||
- purge(array $items, string $indexKey, ...) : void
|
||||
- converter(array $items, array $keySet, ...) : array
|
||||
- process(mixed $items, string $indexKey, ...) : array
|
||||
- setGuid(string $key, bool $trim = true) : string
|
||||
}
|
||||
|
||||
note right of Subform::__construct
|
||||
@ -109,18 +108,6 @@ note left of Subform::process
|
||||
string $linkKey
|
||||
string $linkValue
|
||||
end note
|
||||
|
||||
note right of Subform::setGuid
|
||||
Returns a GUIDv4 string
|
||||
Thanks to Dave Pearson (and other)
|
||||
https://www.php.net/manual/en/function.com-create-guid.php#119168
|
||||
Uses the best cryptographically secure method
|
||||
for all supported platforms with fallback to an older,
|
||||
less secure version.
|
||||
|
||||
since: 3.0.9
|
||||
return: string
|
||||
end note
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
@ -13,6 +13,8 @@ namespace VDM\Joomla\Data;
|
||||
|
||||
|
||||
use VDM\Joomla\Interfaces\Data\ItemsInterface as Items;
|
||||
use VDM\Joomla\Data\Guid;
|
||||
use VDM\Joomla\Interfaces\Data\GuidInterface;
|
||||
use VDM\Joomla\Interfaces\Data\SubformInterface;
|
||||
|
||||
|
||||
@ -21,10 +23,17 @@ use VDM\Joomla\Interfaces\Data\SubformInterface;
|
||||
*
|
||||
* @since 3.2.2
|
||||
*/
|
||||
final class Subform implements SubformInterface
|
||||
final class Subform implements GuidInterface, SubformInterface
|
||||
{
|
||||
/**
|
||||
* The ItemsInterface Class.
|
||||
* The Globally Unique Identifier.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
use Guid;
|
||||
|
||||
/**
|
||||
* The Items Class.
|
||||
*
|
||||
* @var Items
|
||||
* @since 3.2.2
|
||||
@ -42,7 +51,7 @@ final class Subform implements SubformInterface
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Items $items The ItemsInterface Class.
|
||||
* @param Items $items The Items Class.
|
||||
* @param string|null $table The table name.
|
||||
*
|
||||
* @since 3.2.2
|
||||
@ -238,7 +247,7 @@ final class Subform implements SubformInterface
|
||||
if (empty($value))
|
||||
{
|
||||
// set INDEX
|
||||
$item[$indexKey] = $this->setGuid($indexKey);
|
||||
$item[$indexKey] = $this->getGuid($indexKey);
|
||||
}
|
||||
break;
|
||||
case 'id':
|
||||
@ -256,70 +265,6 @@ final class Subform implements SubformInterface
|
||||
}
|
||||
|
||||
return array_values($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a GUIDv4 string
|
||||
*
|
||||
* Thanks to Dave Pearson (and other)
|
||||
* https://www.php.net/manual/en/function.com-create-guid.php#119168
|
||||
*
|
||||
* Uses the best cryptographically secure method
|
||||
* for all supported platforms with fallback to an older,
|
||||
* less secure version.
|
||||
*
|
||||
* @param string $key The key to check and modify values.
|
||||
* @param bool $trim
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
private function setGuid(string $key, bool $trim = true): string
|
||||
{
|
||||
// Windows
|
||||
if (function_exists('com_create_guid'))
|
||||
{
|
||||
if ($trim)
|
||||
{
|
||||
return trim(\com_create_guid(), '{}');
|
||||
}
|
||||
return \com_create_guid();
|
||||
}
|
||||
|
||||
// set the braces if needed
|
||||
$lbrace = $trim ? "" : chr(123); // "{"
|
||||
$rbrace = $trim ? "" : chr(125); // "}"
|
||||
|
||||
// OSX/Linux
|
||||
if (function_exists('openssl_random_pseudo_bytes'))
|
||||
{
|
||||
$data = \openssl_random_pseudo_bytes(16);
|
||||
$data[6] = chr( ord($data[6]) & 0x0f | 0x40); // set version to 0100
|
||||
$data[8] = chr( ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
|
||||
return $lbrace . vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)) . $lbrace;
|
||||
}
|
||||
|
||||
// Fallback (PHP 4.2+)
|
||||
mt_srand((double) microtime() * 10000);
|
||||
$charid = strtolower( md5( uniqid( rand(), true)));
|
||||
$hyphen = chr(45); // "-"
|
||||
$guidv4 = $lbrace.
|
||||
substr($charid, 0, 8). $hyphen.
|
||||
substr($charid, 8, 4). $hyphen.
|
||||
substr($charid, 12, 4). $hyphen.
|
||||
substr($charid, 16, 4). $hyphen.
|
||||
substr($charid, 20, 12).
|
||||
$rbrace;
|
||||
|
||||
// check that it does not already exist (one in a billion chance ;)
|
||||
// but we do it any way...
|
||||
if ($this->items->table($this->getTable())->values([$guidv4], $key))
|
||||
{
|
||||
return $this->setGuid($key);
|
||||
}
|
||||
|
||||
return $guidv4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,12 @@
|
||||
/**
|
||||
* The ItemsInterface Class.
|
||||
* The Globally Unique Identifier.
|
||||
*
|
||||
* @since 5.0.2
|
||||
*/
|
||||
use Guid;
|
||||
|
||||
/**
|
||||
* The Items Class.
|
||||
*
|
||||
* @var Items
|
||||
* @since 3.2.2
|
||||
@ -17,7 +24,7 @@
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Items $items The ItemsInterface Class.
|
||||
* @param Items $items The Items Class.
|
||||
* @param string|null $table The table name.
|
||||
*
|
||||
* @since 3.2.2
|
||||
@ -213,7 +220,7 @@
|
||||
if (empty($value))
|
||||
{
|
||||
// set INDEX
|
||||
$item[$indexKey] = $this->setGuid($indexKey);
|
||||
$item[$indexKey] = $this->getGuid($indexKey);
|
||||
}
|
||||
break;
|
||||
case 'id':
|
||||
@ -231,68 +238,4 @@
|
||||
}
|
||||
|
||||
return array_values($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a GUIDv4 string
|
||||
*
|
||||
* Thanks to Dave Pearson (and other)
|
||||
* https://www.php.net/manual/en/function.com-create-guid.php#119168
|
||||
*
|
||||
* Uses the best cryptographically secure method
|
||||
* for all supported platforms with fallback to an older,
|
||||
* less secure version.
|
||||
*
|
||||
* @param string $key The key to check and modify values.
|
||||
* @param bool $trim
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
private function setGuid(string $key, bool $trim = true): string
|
||||
{
|
||||
// Windows
|
||||
if (function_exists('com_create_guid'))
|
||||
{
|
||||
if ($trim)
|
||||
{
|
||||
return trim(\com_create_guid(), '{}');
|
||||
}
|
||||
return \com_create_guid();
|
||||
}
|
||||
|
||||
// set the braces if needed
|
||||
$lbrace = $trim ? "" : chr(123); // "{"
|
||||
$rbrace = $trim ? "" : chr(125); // "}"
|
||||
|
||||
// OSX/Linux
|
||||
if (function_exists('openssl_random_pseudo_bytes'))
|
||||
{
|
||||
$data = \openssl_random_pseudo_bytes(16);
|
||||
$data[6] = chr( ord($data[6]) & 0x0f | 0x40); // set version to 0100
|
||||
$data[8] = chr( ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
|
||||
return $lbrace . vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)) . $lbrace;
|
||||
}
|
||||
|
||||
// Fallback (PHP 4.2+)
|
||||
mt_srand((double) microtime() * 10000);
|
||||
$charid = strtolower( md5( uniqid( rand(), true)));
|
||||
$hyphen = chr(45); // "-"
|
||||
$guidv4 = $lbrace.
|
||||
substr($charid, 0, 8). $hyphen.
|
||||
substr($charid, 8, 4). $hyphen.
|
||||
substr($charid, 12, 4). $hyphen.
|
||||
substr($charid, 16, 4). $hyphen.
|
||||
substr($charid, 20, 12).
|
||||
$rbrace;
|
||||
|
||||
// check that it does not already exist (one in a billion chance ;)
|
||||
// but we do it any way...
|
||||
if ($this->items->table($this->getTable())->values([$guidv4], $key))
|
||||
{
|
||||
return $this->setGuid($key);
|
||||
}
|
||||
|
||||
return $guidv4;
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
"extends": "",
|
||||
"guid": "85785701-07b2-4f81-bc1e-0f423700c254",
|
||||
"implements": [
|
||||
"576685fd-263c-46bb-9fdc-1f5eb234cbb6",
|
||||
"34959721-415b-4b5e-8002-3d1fc84b3b2b"
|
||||
],
|
||||
"load_selection": null,
|
||||
@ -15,6 +16,10 @@
|
||||
"use_selection0": {
|
||||
"use": "7212e4db-371f-4cfd-8122-32e9bb100d83",
|
||||
"as": "Items"
|
||||
},
|
||||
"use_selection1": {
|
||||
"use": "5acded67-0e3d-4c6b-a6ea-b533b076de0c",
|
||||
"as": "default"
|
||||
}
|
||||
},
|
||||
"extendsinterfaces": null,
|
||||
|
@ -20,6 +20,7 @@ class Data #Gold {
|
||||
+ getItem(Container $container) : Item
|
||||
+ getItems(Container $container) : Items
|
||||
+ getSubform(Container $container) : Subform
|
||||
+ getUsersSubform(Container $container) : UsersSubform
|
||||
+ getMultiSubform(Container $container) : MultiSubform
|
||||
}
|
||||
|
||||
@ -79,7 +80,14 @@ note left of Data::getSubform
|
||||
return: Subform
|
||||
end note
|
||||
|
||||
note right of Data::getMultiSubform
|
||||
note right of Data::getUsersSubform
|
||||
Get The Users Subform Class.
|
||||
|
||||
since: 5.0.2
|
||||
return: UsersSubform
|
||||
end note
|
||||
|
||||
note left of Data::getMultiSubform
|
||||
Get The MultiSubform Class.
|
||||
|
||||
since: 3.2.0
|
||||
|
@ -21,6 +21,7 @@ use VDM\Joomla\Data\Action\Delete;
|
||||
use VDM\Joomla\Data\Item;
|
||||
use VDM\Joomla\Data\Items;
|
||||
use VDM\Joomla\Data\Subform;
|
||||
use VDM\Joomla\Data\UsersSubform;
|
||||
use VDM\Joomla\Data\MultiSubform;
|
||||
|
||||
|
||||
@ -62,6 +63,9 @@ class Data implements ServiceProviderInterface
|
||||
$container->alias(Subform::class, 'Data.Subform')
|
||||
->share('Data.Subform', [$this, 'getSubform'], true);
|
||||
|
||||
$container->alias(UsersSubform::class, 'Data.UsersSubform')
|
||||
->share('Data.UsersSubform', [$this, 'getUsersSubform'], true);
|
||||
|
||||
$container->alias(MultiSubform::class, 'Data.MultiSubform')
|
||||
->share('Data.MultiSubform', [$this, 'getMultiSubform'], true);
|
||||
}
|
||||
@ -182,6 +186,21 @@ class Data implements ServiceProviderInterface
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get The Users Subform Class.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsersSubform
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public function getUsersSubform(Container $container): UsersSubform
|
||||
{
|
||||
return new UsersSubform(
|
||||
$container->get('Data.Items')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get The MultiSubform Class.
|
||||
*
|
||||
|
@ -29,6 +29,9 @@
|
||||
$container->alias(Subform::class, 'Data.Subform')
|
||||
->share('Data.Subform', [$this, 'getSubform'], true);
|
||||
|
||||
$container->alias(UsersSubform::class, 'Data.UsersSubform')
|
||||
->share('Data.UsersSubform', [$this, 'getUsersSubform'], true);
|
||||
|
||||
$container->alias(MultiSubform::class, 'Data.MultiSubform')
|
||||
->share('Data.MultiSubform', [$this, 'getMultiSubform'], true);
|
||||
}
|
||||
@ -149,6 +152,21 @@
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get The Users Subform Class.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsersSubform
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public function getUsersSubform(Container $container): UsersSubform
|
||||
{
|
||||
return new UsersSubform(
|
||||
$container->get('Data.Items')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get The MultiSubform Class.
|
||||
*
|
||||
|
@ -40,6 +40,10 @@
|
||||
"use": "85785701-07b2-4f81-bc1e-0f423700c254",
|
||||
"as": "default"
|
||||
},
|
||||
"use_selection8": {
|
||||
"use": "46b98346-ec98-42b3-a393-96c7d1282b1c",
|
||||
"as": "default"
|
||||
},
|
||||
"use_selection7": {
|
||||
"use": "e0198c3f-777a-4a0b-87b7-e6a198afc8f9",
|
||||
"as": "default"
|
||||
|
@ -7019,7 +7019,7 @@ final class Table extends BaseTable implements Tableinterface
|
||||
'db' => [
|
||||
'type' => 'TINYINT(1)',
|
||||
'default' => '0',
|
||||
'null_switch' => 'NOT NULL',
|
||||
'null_switch' => 'NULL',
|
||||
'unique_key' => false,
|
||||
'key' => true,
|
||||
],
|
||||
|
@ -445,7 +445,10 @@ final class MultiSubform implements MultiSubformInterface
|
||||
{
|
||||
if ($this->validSetMap($map))
|
||||
{
|
||||
return $this->setSubformData($subform[$key], $map, [$table => $subform]);
|
||||
// will delete all existing linked items [IF EMPTY] :( not ideal, but real
|
||||
$data = (empty($subform[$key]) || !is_array($subform[$key])) ? [] : $subform[$key];
|
||||
|
||||
return $this->setSubformData($data, $map, [$table => $subform]);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -420,7 +420,10 @@
|
||||
{
|
||||
if ($this->validSetMap($map))
|
||||
{
|
||||
return $this->setSubformData($subform[$key], $map, [$table => $subform]);
|
||||
// will delete all existing linked items [IF EMPTY] :( not ideal, but real
|
||||
$data = (empty($subform[$key]) || !is_array($subform[$key])) ? [] : $subform[$key];
|
||||
|
||||
return $this->setSubformData($data, $map, [$table => $subform]);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -274,6 +274,17 @@
|
||||
"spk": "Super---43134867_5cb8_4280_9be8_309fd2fd135f---Power",
|
||||
"guid": "43134867-5cb8-4280-9be8-309fd2fd135f"
|
||||
},
|
||||
"46b98346-ec98-42b3-a393-96c7d1282b1c": {
|
||||
"name": "UsersSubform",
|
||||
"type": "final class",
|
||||
"namespace": "VDM\\Joomla\\Data",
|
||||
"code": "src\/46b98346-ec98-42b3-a393-96c7d1282b1c\/code.php",
|
||||
"power": "src\/46b98346-ec98-42b3-a393-96c7d1282b1c\/code.power",
|
||||
"settings": "src\/46b98346-ec98-42b3-a393-96c7d1282b1c\/settings.json",
|
||||
"path": "src\/46b98346-ec98-42b3-a393-96c7d1282b1c",
|
||||
"spk": "Super---46b98346_ec98_42b3_a393_96c7d1282b1c---Power",
|
||||
"guid": "46b98346-ec98-42b3-a393-96c7d1282b1c"
|
||||
},
|
||||
"4815e1c7-a433-443d-a112-d1e03d7df84b": {
|
||||
"name": "Database",
|
||||
"type": "class",
|
||||
@ -362,6 +373,17 @@
|
||||
"spk": "Super---52a1d14f_304a_431c_8fa4_411179942db5---Power",
|
||||
"guid": "52a1d14f-304a-431c-8fa4-411179942db5"
|
||||
},
|
||||
"576685fd-263c-46bb-9fdc-1f5eb234cbb6": {
|
||||
"name": "GuidInterface",
|
||||
"type": "interface",
|
||||
"namespace": "VDM\\Joomla\\Interfaces\\Data",
|
||||
"code": "src\/576685fd-263c-46bb-9fdc-1f5eb234cbb6\/code.php",
|
||||
"power": "src\/576685fd-263c-46bb-9fdc-1f5eb234cbb6\/code.power",
|
||||
"settings": "src\/576685fd-263c-46bb-9fdc-1f5eb234cbb6\/settings.json",
|
||||
"path": "src\/576685fd-263c-46bb-9fdc-1f5eb234cbb6",
|
||||
"spk": "Super---576685fd_263c_46bb_9fdc_1f5eb234cbb6---Power",
|
||||
"guid": "576685fd-263c-46bb-9fdc-1f5eb234cbb6"
|
||||
},
|
||||
"584747d1-3a86-453d-b7a3-a2219de8d777": {
|
||||
"name": "Model",
|
||||
"type": "abstract class",
|
||||
@ -384,6 +406,17 @@
|
||||
"spk": "Super---59b1a2ea_d77e_4040_ac8c_e65cd8743e9b---Power",
|
||||
"guid": "59b1a2ea-d77e-4040-ac8c-e65cd8743e9b"
|
||||
},
|
||||
"5acded67-0e3d-4c6b-a6ea-b533b076de0c": {
|
||||
"name": "Guid",
|
||||
"type": "trait",
|
||||
"namespace": "VDM\\Joomla\\Data",
|
||||
"code": "src\/5acded67-0e3d-4c6b-a6ea-b533b076de0c\/code.php",
|
||||
"power": "src\/5acded67-0e3d-4c6b-a6ea-b533b076de0c\/code.power",
|
||||
"settings": "src\/5acded67-0e3d-4c6b-a6ea-b533b076de0c\/settings.json",
|
||||
"path": "src\/5acded67-0e3d-4c6b-a6ea-b533b076de0c",
|
||||
"spk": "Super---5acded67_0e3d_4c6b_a6ea_b533b076de0c---Power",
|
||||
"guid": "5acded67-0e3d-4c6b-a6ea-b533b076de0c"
|
||||
},
|
||||
"5f0205fa-5c43-424a-af7d-abc943c17c8c": {
|
||||
"name": "SchemaChecker",
|
||||
"type": "abstract class",
|
||||
@ -505,6 +538,17 @@
|
||||
"spk": "Super---728ee726_3f0f_4762_899d_f8c9430cee58---Power",
|
||||
"guid": "728ee726-3f0f-4762-899d-f8c9430cee58"
|
||||
},
|
||||
"7832a726-87b6-4e95-887e-7b725d3fab8f": {
|
||||
"name": "UserHelper",
|
||||
"type": "abstract class",
|
||||
"namespace": "VDM\\Joomla\\Componentbuilder\\Utilities",
|
||||
"code": "src\/7832a726-87b6-4e95-887e-7b725d3fab8f\/code.php",
|
||||
"power": "src\/7832a726-87b6-4e95-887e-7b725d3fab8f\/code.power",
|
||||
"settings": "src\/7832a726-87b6-4e95-887e-7b725d3fab8f\/settings.json",
|
||||
"path": "src\/7832a726-87b6-4e95-887e-7b725d3fab8f",
|
||||
"spk": "Super---7832a726_87b6_4e95_887e_7b725d3fab8f---Power",
|
||||
"guid": "7832a726-87b6-4e95-887e-7b725d3fab8f"
|
||||
},
|
||||
"7c1fb50f-8fb1-4627-8705-6fedf7182ca5": {
|
||||
"name": "Upsert",
|
||||
"type": "final class",
|
||||
|
Loading…
Reference in New Issue
Block a user