Release of v4.1.4

This commit is contained in:
Robot committed 2026-03-24 13:37:04 +00:00
1 parent 7b22e3c441
commit e89cc27510
104 files changed
+5527 -1316

No files matched your search

@@ -345,7 +345,7 @@ final class Contents implements ContentsInterface
* @return string|null
* @since 5.1.1
**/
public function editor(string $owner, string $repo, string $filepath, string $ref = null): ?string
public function editor(string $owner, string $repo, string $filepath, ?string $ref = null): ?string
{
$target = $this->getTarget();
return $this->{$target}->editor($owner, $repo, $filepath, $ref);
@@ -187,10 +187,10 @@ class Milestones extends Api
string $owner,
string $repo,
string $milestoneId,
string $title = null,
string $description = null,
string $dueOn = null,
string $state = null
?string $title = null,
?string $description = null,
?string $dueOn = null,
?string $state = null
): ?object
{
// Set the lines data
@@ -41,11 +41,11 @@ class Times extends Api
string $owner,
string $repo,
int $index,
string $user = null,
string $since = null,
string $before = null,
int $page = null,
int $limit = null
?string $user = null,
?string $since = null,
?string $before = null,
?int $page = null,
?int $limit = null
): ?array
{
// Build the request path.
@@ -98,8 +98,8 @@ class Times extends Api
string $repo,
int $index,
int $time,
string $created = null,
string $userName = null
?string $created = null,
?string $userName = null
): ?object
{
// Set the lines data
@@ -99,8 +99,8 @@ class Teams extends Api
string $permission = 'read',
array $units = [],
array $unitsMap = [],
bool $canCreateOrgRepo = null,
bool $includesAllRepositories = null
?bool $canCreateOrgRepo = null,
?bool $includesAllRepositories = null
): ?object
{
// Build the request path.
@@ -94,7 +94,7 @@ class Collaborator extends Api
string $owner,
string $repo,
string $collaborator,
string $permission = null
?string $permission = null
): string
{
// Build the request path.
@@ -158,8 +158,8 @@ class Commits extends Api
string $owner,
string $repo,
string $ref,
string $sort = null,
string $state = null,
?string $sort = null,
?string $state = null,
int $page = 1,
int $limit = 10
): ?array
@@ -467,7 +467,7 @@ class Contents extends Api implements ContentsInterface
* @return string|null
* @since 3.2.0
**/
public function editor(string $owner, string $repo, string $filepath, string $ref = null): ?string
public function editor(string $owner, string $repo, string $filepath, ?string $ref = null): ?string
{
// Build the request path.
$path = "/repos/{$owner}/{$repo}/editorconfig/{$filepath}";
@@ -73,8 +73,6 @@ class Hooks extends Api
string $repo,
string $type,
array $config,
string $type,
array $config,
bool $active = false,
?array $events = null,
string $branchFilter = ''
@@ -517,7 +517,7 @@ class Pulls extends Api
* @return string
* @since 3.2.0
*/
public function update(
public function mergeUpdate(
string $owner,
string $repo,
int $index,
@@ -39,9 +39,9 @@ class Times extends Api
public function list(
string $ownerName,
string $repoName,
string $user = null,
string $since = null,
string $before = null,
?string $user = null,
?string $since = null,
?string $before = null,
int $page = 1,
int $limit = 10
): ?array
@@ -172,7 +172,7 @@ class Wiki extends Api implements WikiInterface
string $pageName,
string $title,
string $content,
string $message = null
?string $message = null
): ?object
{
// Build the request path.
@@ -88,7 +88,7 @@ class User extends Api
* @return object|null
* @since 3.2.0
**/
public function get(string $username): o?bject
public function get(string $username): ?object
{
// Build the request path.
$path = "/users/{$username}";
@@ -450,7 +450,7 @@ final class Contents extends Api implements ContentsInterface
* @return string|null
* @since 5.1.1
**/
public function editor(string $owner, string $repo, string $filepath, string $ref = null): ?string
public function editor(string $owner, string $repo, string $filepath, ?string $ref = null): ?string
{
// Not supported in GitHub
return null;
@@ -136,7 +136,7 @@ class Wiki extends Api implements WikiInterface
string $pageName,
string $title,
string $content,
string $message = null
?string $message = null
): ?object
{
return null; // github does not support wiki over API
@@ -0,0 +1,261 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem\ItemCode;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem\Link;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem\LinkAuthority;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem\LinkLogic;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
/**
* List Item Class
*
* @since 5.1.5
*/
final class ListItem
{
/**
* The ItemCode Class.
*
* @var ItemCode
* @since 5.1.5
*/
protected ItemCode $itemcode;
/**
* The Link Class.
*
* @var Link
* @since 5.1.5
*/
protected Link $link;
/**
* The LinkAuthority Class.
*
* @var LinkAuthority
* @since 5.1.5
*/
protected LinkAuthority $linkauthority;
/**
* The LinkLogic Class.
*
* @var LinkLogic
* @since 5.1.5
*/
protected LinkLogic $linklogic;
/**
* Constructor.
*
* @param ItemCode $itemcode The ItemCode Class.
* @param Link $link The Link Class.
* @param LinkAuthority $linkauthority The LinkAuthority Class.
* @param LinkLogic $linklogic The LinkLogic Class.
*
* @since 5.1.5
*/
public function __construct(
ItemCode $itemcode,
Link $link,
LinkAuthority $linkauthority,
LinkLogic $linklogic
) {
$this->itemcode = $itemcode;
$this->link = $link;
$this->linkauthority = $linkauthority;
$this->linklogic = $linklogic;
}
/**
* Get the list item row value.
*
* @param array $item The item array.
* @param string $nameSingleCode The single view code name.
* @param string $nameListCode The list view code name.
* @param string &$itemClass The table row default class.
* @param bool $doNotEscape The do not escape global switch.
* @param bool $class The div class adding switch.
* @param string|null $ref The link referral string.
* @param string $classPointer The class pointer.
* @param string $user The user code name.
* @param string|null $refview The override of the referral view code name.
*
* @return string The single item value for the table row.
* @since 5.1.5
*/
public function get(
array $item,
string $nameSingleCode,
string $nameListCode,
string &$itemClass,
bool $doNotEscape,
bool $class = true,
?string $ref = null,
string $classPointer = '$this->',
string $user = '$this->user',
?string $refview = null
): string {
$itemCode = $this->itemcode->get(
$item,
$nameListCode,
$doNotEscape,
$classPointer
);
if (!$this->shouldRenderLinkedItem($item, $refview))
{
return $this->getPlainListItemOutput($itemCode);
}
return $this->getLinkedListItemOutput(
$item,
$itemCode,
$nameSingleCode,
$nameListCode,
$itemClass,
$class,
$ref,
$classPointer,
$user
);
}
/**
* Check whether the item should be rendered as a linked item.
*
* @param array $item The item array.
* @param string|null $refview The override of the referral view code name.
*
* @return bool True if the item should be rendered as a link.
* @since 5.1.5
*/
protected function shouldRenderLinkedItem(array $item, ?string $refview = null): bool
{
if ($this->shouldNotUseDefaultLink($item, $refview))
{
return false;
}
$extendsField = $this->getCustomExtendsField($item);
return (!empty($item['link']) || $extendsField === 'user');
}
/**
* Check whether the default link should not be used.
*
* @param array $item The item array.
* @param string|null $refview The override of the referral view code name.
*
* @return bool True if the default link should not be used.
* @since 5.1.5
*/
protected function shouldNotUseDefaultLink(array $item, ?string $refview = null): bool
{
return StringHelper::check($refview)
&& isset($item['custom'])
&& isset($item['custom']['view'])
&& $refview === $item['custom']['view'];
}
/**
* Get the custom extends field value.
*
* @param array $item The item array.
*
* @return string The custom extends field value.
* @since 5.1.5
*/
protected function getCustomExtendsField(array $item): string
{
return $item['custom']['extends'] ?? '';
}
/**
* Build the linked list item output.
*
* @param array $item The item array.
* @param string $itemCode The item code string.
* @param string $nameSingleCode The single view code name.
* @param string $nameListCode The list view code name.
* @param string &$itemClass The table row default class.
* @param bool $class The div class adding switch.
* @param string|null $ref The link referral string.
* @param string $classPointer The class pointer.
* @param string $user The user code name.
*
* @return string The linked list item output.
* @since 5.1.5
*/
protected function getLinkedListItemOutput(
array $item,
string $itemCode,
string $nameSingleCode,
string $nameListCode,
string &$itemClass,
bool $class = true,
?string $ref = null,
string $classPointer = '$this->',
string $user = '$this->user'
): string {
$checkoutTriger = false;
$itemClass = 'nowrap';
$itemLink = $this->link->get(
$item,
$checkoutTriger,
$nameSingleCode,
$nameListCode,
$ref
);
$itemLinkAuthority = $this->linkauthority->get(
$item,
$nameSingleCode,
$nameListCode,
$classPointer,
$user
);
return $this->linklogic->get(
$item,
$itemCode,
$itemLink,
$itemLinkAuthority,
$nameSingleCode,
$nameListCode,
$classPointer,
$checkoutTriger,
$class
);
}
/**
* Build the plain list item output.
*
* @param string $itemCode The item code string.
*
* @return string The plain list item output.
* @since 5.1.5
*/
protected function getPlainListItemOutput(string $itemCode): string
{
return PHP_EOL . Indent::_(3) . "<?php echo " . $itemCode . "; ?>";
}
}
@@ -0,0 +1,324 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Builder\SelectionTranslation;
use VDM\Joomla\Componentbuilder\Compiler\Builder\DoNotEscape;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\ArrayHelper;
/**
* List Item Item Code Class
*
* @since 5.1.5
*/
final class ItemCode
{
/**
* The Config Class.
*
* @var Config
* @since 5.1.5
*/
protected Config $config;
/**
* The SelectionTranslation Class.
*
* @var SelectionTranslation
* @since 5.1.5
*/
protected SelectionTranslation $selectiontranslation;
/**
* The DoNotEscape Class.
*
* @var DoNotEscape
* @since 5.1.5
*/
protected DoNotEscape $donotescape;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param SelectionTranslation $selectiontranslation The SelectionTranslation Class.
* @param DoNotEscape $donotescape The DoNotEscape Class.
*
* @since 5.1.5
*/
public function __construct(
Config $config,
SelectionTranslation $selectiontranslation,
DoNotEscape $donotescape
) {
$this->config = $config;
$this->selectiontranslation = $selectiontranslation;
$this->donotescape = $donotescape;
}
/**
* Get the list item code value.
*
* @param array $item The item array.
* @param string $nameListCode The list view code name.
* @param bool $doNotEscape The do not escape global switch.
* @param string $classPointer The class pointer.
*
* @return string The single item code string.
* @since 5.1.5
*/
public function get(
array &$item,
string $nameListCode,
bool $doNotEscape,
string $classPointer = '$this->'
): string {
$this->prepareCustomItemCode($item);
$extendsField = $item['custom']['extends'] ?? '';
$extendsText = $item['custom']['text'] ?? '';
if ($this->isCategoryWithoutTitle($item))
{
return $this->getCategoryTitleCode($classPointer);
}
if ($this->isDirectUserType($item))
{
return $this->getUserNameCode($item['code']);
}
if ($this->isCustomUserById($item, $extendsField))
{
return $this->getUserNameCode($item['id_code']);
}
if ($this->hasTranslatedSelection($nameListCode, $item['code']))
{
return $this->getTranslatedSelectionCode($item['code']);
}
if ($this->isCustomUserField($item, $extendsField, $extendsText))
{
return $this->getUserNameCode($item['code']);
}
if (
$doNotEscape
&& $this->shouldNotEscapeField($nameListCode, $item['code'])
) {
return $this->getRawItemCode($item['code']);
}
return $this->getEscapedItemCode($item['code'], $classPointer);
}
/**
* Prepare the item code for custom table values.
*
* @param array $item The item array.
*
* @return void
* @since 5.1.5
*/
protected function prepareCustomItemCode(array &$item): void
{
if (
isset($item['custom'])
&& ArrayHelper::check($item['custom'])
&& isset($item['custom']['table'])
&& StringHelper::check($item['custom']['table'])
) {
$item['id_code'] = $item['code'];
if (!(bool) $item['multiple'])
{
$item['code'] = $item['code'] . '_' . $item['custom']['text'];
}
}
}
/**
* Check if the item is a category without a title field.
*
* @param array $item The item array.
*
* @return bool
* @since 5.1.5
*/
protected function isCategoryWithoutTitle(array $item): bool
{
return $item['type'] === 'category' && !$item['title'];
}
/**
* Check if the item is a direct user field type.
*
* @param array $item The item array.
*
* @return bool
* @since 5.1.5
*/
protected function isDirectUserType(array $item): bool
{
return $item['type'] === 'user';
}
/**
* Check if the item is a custom user relation resolved by ID code.
*
* @param array $item The item array.
* @param string $extendsField The custom extends field value.
*
* @return bool
* @since 5.1.5
*/
protected function isCustomUserById(array $item, string $extendsField): bool
{
return isset($item['custom'])
&& ArrayHelper::check($item['custom'])
&& $extendsField === 'user'
&& isset($item['id_code']);
}
/**
* Check if the item uses a translated selection value.
*
* @param string $nameListCode The list view code name.
* @param string $code The field code.
*
* @return bool
* @since 5.1.5
*/
protected function hasTranslatedSelection(string $nameListCode, string $code): bool
{
return $this->selectiontranslation->exists($nameListCode . '.' . $code);
}
/**
* Check if the item resolves to a custom user field.
*
* @param array $item The item array.
* @param string $extendsField The custom extends field value.
* @param string $extendsText The custom text value.
*
* @return bool
* @since 5.1.5
*/
protected function isCustomUserField(
array $item,
string $extendsField,
string $extendsText
): bool {
return isset($item['custom'])
&& ArrayHelper::check($item['custom'])
&& ($extendsText === 'user' || $extendsField === 'user');
}
/**
* Check if the field should not be escaped.
*
* @param string $nameListCode The list view code name.
* @param string $code The field code.
*
* @return bool
* @since 5.1.5
*/
protected function shouldNotEscapeField(string $nameListCode, string $code): bool
{
return $this->donotescape->exists($nameListCode . '.' . $code);
}
/**
* Get the category title code string.
*
* @param string $classPointer The class pointer.
*
* @return string
* @since 5.1.5
*/
protected function getCategoryTitleCode(string $classPointer): string
{
return $classPointer . 'escape($item->category_title)';
}
/**
* Get the translated selection code string.
*
* @param string $code The field code.
*
* @return string
* @since 5.1.5
*/
protected function getTranslatedSelectionCode(string $code): string
{
return 'Joomla__'
. '_ba6326ef_cb79_4348_80f4_ab086082e3c5___Power::_($item->'
. $code . ')';
}
/**
* Get the raw item code string.
*
* @param string $code The field code.
*
* @return string
* @since 5.1.5
*/
protected function getRawItemCode(string $code): string
{
return '$item->' . $code;
}
/**
* Get the escaped item code string.
*
* @param string $code The field code.
* @param string $classPointer The class pointer.
*
* @return string
* @since 5.1.5
*/
protected function getEscapedItemCode(string $code, string $classPointer): string
{
return $classPointer . 'escape($item->' . $code . ')';
}
/**
* Get the user name lookup code string.
*
* @param string $code The field code.
*
* @return string
* @since 5.1.5
*/
protected function getUserNameCode(string $code): string
{
if ((int) $this->config->get('joomla_version', 3) === 3)
{
return 'Joomla__'
. '_39403062_84fb_46e0_bac4_0023f766e827___Power::getUser((int)$item->'
. $code . ')->name';
}
return 'Joomla__'
. '_39403062_84fb_46e0_bac4_0023f766e827___Power::getContainer()->'
. 'get(Joomla__'
. '_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power::class)->'
. 'loadUserById((int) ($item->' . $code . ' ?? 0))->name';
}
}
@@ -0,0 +1,259 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Category;
use VDM\Joomla\Utilities\ArrayHelper;
/**
* List Item Link Class
*
* @since 5.1.5
*/
final class Link
{
/**
* The Category Class.
*
* @var Category
* @since 5.1.5
*/
protected Category $category;
/**
* Constructor.
*
* @param Category $category The Category Class.
*
* @since 5.1.5
*/
public function __construct(Category $category)
{
$this->category = $category;
}
/**
* Get the list item link.
*
* @param array $item The item array.
* @param bool &$checkoutTriger The checkout trigger switch.
* @param string $nameSingleCode The single view code name.
* @param string $nameListCode The list view code name.
* @param string|null $ref The link referral string.
*
* @return string The single item link.
* @since 5.1.5
*/
public function get(
array $item,
bool &$checkoutTriger,
string $nameSingleCode,
string $nameListCode,
?string $ref = null
): string
{
[$ref, $referal] = $this->resolveReferral($ref);
if ($this->isCategoryLink($item))
{
return $this->buildCategoryLink($item, $nameListCode);
}
if ($this->isDirectUserLink($item))
{
return $this->buildUserLink($item['code']);
}
if ($this->isCustomNonUserLink($item))
{
return $this->buildCustomLink($item, $ref);
}
if ($this->isCustomUserLink($item))
{
return $this->buildUserLink($item['id_code']);
}
$checkoutTriger = true;
return $this->buildDefaultItemLink($referal);
}
/**
* Resolve the referral values.
*
* @param string|null $ref The incoming referral string.
*
* @return array{0:string,1:string} The resolved ref and referal values.
* @since 5.1.5
*/
protected function resolveReferral(?string $ref): array
{
$referal = '';
if (!$ref)
{
$ref = '&return=<?php echo $this->return_here; ?>';
}
else
{
$referal = $ref;
}
return [$ref, $referal];
}
/**
* Check if the item should link to a category edit page.
*
* @param array $item The item array.
*
* @return bool
* @since 5.1.5
*/
protected function isCategoryLink(array $item): bool
{
return isset($item['type'], $item['title'], $item['code'])
&& $item['type'] === 'category'
&& !$item['title'];
}
/**
* Build the category edit link.
*
* @param array $item The item array.
* @param string $nameListCode The list view code name.
*
* @return string
* @since 5.1.5
*/
protected function buildCategoryLink(array $item, string $nameListCode): string
{
return 'index.php?option=com_categories&task=category.edit&id=<?php echo (int)$item->'
. $item['code'] . '; ?>&extension='
. $this->category->get("{$nameListCode}.extension", 'error');
}
/**
* Check if the item should link directly to a user edit page.
*
* @param array $item The item array.
*
* @return bool
* @since 5.1.5
*/
protected function isDirectUserLink(array $item): bool
{
return isset($item['type'], $item['title'], $item['code'])
&& $item['type'] === 'user'
&& !$item['title'];
}
/**
* Check if the item should link to a custom non-user target.
*
* @param array $item The item array.
*
* @return bool
* @since 5.1.5
*/
protected function isCustomNonUserLink(array $item): bool
{
return isset($item['custom'], $item['title'], $item['id_code'])
&& ArrayHelper::check($item['custom'])
&& $item['custom']['extends'] != 'user'
&& !$item['title'];
}
/**
* Check if the item should link to a custom user target.
*
* @param array $item The item array.
*
* @return bool
* @since 5.1.5
*/
protected function isCustomUserLink(array $item): bool
{
return isset($item['custom'], $item['title'], $item['id_code'])
&& ArrayHelper::check($item['custom'])
&& $item['custom']['extends'] === 'user'
&& !$item['title'];
}
/**
* Build the user edit link.
*
* @param string $code The item code field.
*
* @return string
* @since 5.1.5
*/
protected function buildUserLink(string $code): string
{
return 'index.php?option=com_users&task=user.edit&id=<?php echo (int) $item->'
. $code . ' ?>';
}
/**
* Build the custom item edit link.
*
* @param array $item The item array.
* @param string $ref The resolved referral string.
*
* @return string
* @since 5.1.5
*/
protected function buildCustomLink(array $item, string $ref): string
{
$idField = $this->getCustomLinkIdField($item);
return 'index.php?option=' . $item['custom']['component'] . '&view='
. $item['custom']['views'] . '&task=' . $item['custom']['view']
. '.edit&id=<?php echo $item->' . $idField . '; ?>'
. $ref;
}
/**
* Get the ID field to use for a custom link.
*
* @param array $item The item array.
*
* @return string
* @since 5.1.5
*/
protected function getCustomLinkIdField(array $item): string
{
if (isset($item['custom']['id']) && $item['custom']['id'] !== 'id')
{
return $item['id_code'] . '_id';
}
return $item['id_code'];
}
/**
* Build the default item edit link.
*
* @param string $referal The referral string for linked tab/view handling.
*
* @return string
* @since 5.1.5
*/
protected function buildDefaultItemLink(string $referal): string
{
return '<?php echo $edit; ?>&id=<?php echo $item->id; ?>' . $referal;
}
}
@@ -0,0 +1,313 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Builder\CategoryCode;
use VDM\Joomla\Componentbuilder\Compiler\Creator\Permission;
use VDM\Joomla\Utilities\ArrayHelper;
/**
* List Item Link Authority Class
*
* @since 5.1.5
*/
final class LinkAuthority
{
/**
* The Config Class.
*
* @var Config
* @since 5.1.5
*/
protected Config $config;
/**
* The CategoryCode Class.
*
* @var CategoryCode
* @since 5.1.5
*/
protected CategoryCode $categorycode;
/**
* The Permission Class.
*
* @var Permission
* @since 5.1.5
*/
protected Permission $permission;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param CategoryCode $categorycode The CategoryCode Class.
* @param Permission $permission The Permission Class.
*
* @since 5.1.5
*/
public function __construct(
Config $config,
CategoryCode $categorycode,
Permission $permission
) {
$this->config = $config;
$this->categorycode = $categorycode;
$this->permission = $permission;
}
/**
* Get the list item link authority.
*
* @param array $item The item array.
* @param string $nameSingleCode The single view code name.
* @param string $nameListCode The list view code name.
* @param string $classPointer The class pointer.
* @param string $user The user code name.
*
* @return string The single item link authority string.
* @since 5.1.5
*/
public function get(
array $item,
string $nameSingleCode,
string $nameListCode,
string $classPointer = '$this->',
string $user = '$this->user'
): string {
$isModal = $this->getModalAuthorityPrefix($classPointer);
if ($this->isCategoryItemWithoutTitle($item))
{
return $this->getCategoryItemAuthority(
$item,
$nameSingleCode,
$isModal,
$user
);
}
if ($this->isUserItemWithoutTitle($item))
{
return $this->getUserItemAuthority($isModal, $user);
}
if ($this->isCustomNonUserItemWithoutTitle($item))
{
return $this->getCustomItemAuthority($item, $isModal, $user);
}
if ($this->isCustomUserItemWithoutTitle($item))
{
return $this->getUserItemAuthority($isModal, $user);
}
return $this->getDefaultItemAuthority($nameSingleCode, $isModal);
}
/**
* Get the modal authority prefix.
*
* @param string $classPointer The class pointer.
*
* @return string The modal authority prefix or an empty string.
* @since 5.1.5
*/
protected function getModalAuthorityPrefix(string $classPointer): string
{
if ($this->config->get('joomla_version', 3) === 3)
{
return '';
}
return "!{$classPointer}isModal && ";
}
/**
* Check if the item is a category item without a title.
*
* @param array $item The item array.
*
* @return bool True if the item is a category item without a title.
* @since 5.1.5
*/
protected function isCategoryItemWithoutTitle(array $item): bool
{
return isset($item['type'], $item['title'])
&& $item['type'] === 'category'
&& !$item['title'];
}
/**
* Check if the item is a user item without a title.
*
* @param array $item The item array.
*
* @return bool True if the item is a user item without a title.
* @since 5.1.5
*/
protected function isUserItemWithoutTitle(array $item): bool
{
return isset($item['type'], $item['title'])
&& $item['type'] === 'user'
&& !$item['title'];
}
/**
* Check if the item is a custom non-user item without a title.
*
* @param array $item The item array.
*
* @return bool True if the item is a custom non-user item without a title.
* @since 5.1.5
*/
protected function isCustomNonUserItemWithoutTitle(array $item): bool
{
return $this->hasValidCustomItem($item)
&& $item['custom']['extends'] !== 'user';
}
/**
* Check if the item is a custom user item without a title.
*
* @param array $item The item array.
*
* @return bool True if the item is a custom user item without a title.
* @since 5.1.5
*/
protected function isCustomUserItemWithoutTitle(array $item): bool
{
return $this->hasValidCustomItem($item)
&& $item['custom']['extends'] === 'user';
}
/**
* Check if the item contains a valid custom definition.
*
* @param array $item The item array.
*
* @return bool True if the item contains a valid custom definition.
* @since 5.1.5
*/
protected function hasValidCustomItem(array $item): bool
{
return isset($item['custom'], $item['title'], $item['id_code'])
&& ArrayHelper::check($item['custom'])
&& !$item['title'];
}
/**
* Get the category item authority string.
*
* @param array $item The item array.
* @param string $nameSingleCode The single view code name.
* @param string $isModal The modal authority prefix.
* @param string $user The user code name.
*
* @return string The category item authority string.
* @since 5.1.5
*/
protected function getCategoryItemAuthority(
array $item,
string $nameSingleCode,
string $isModal,
string $user
): string {
$otherView = $this->categorycode->getString(
"{$nameSingleCode}.view",
'error'
);
return $isModal . $user . "->authorise('core.edit', 'com_"
. $this->config->component_code_name . "."
. $otherView
. ".category.' . (int) (\$item->" . $item['code'] . " ?? 0))";
}
/**
* Get the user item authority string.
*
* @param string $isModal The modal authority prefix.
* @param string $user The user code name.
*
* @return string The user item authority string.
* @since 5.1.5
*/
protected function getUserItemAuthority(string $isModal, string $user): string
{
return $isModal . $user . "->authorise('core.edit', 'com_users')";
}
/**
* Get the custom item authority string.
*
* @param array $item The item array.
* @param string $isModal The modal authority prefix.
* @param string $user The user code name.
*
* @return string The custom item authority string.
* @since 5.1.5
*/
protected function getCustomItemAuthority(
array $item,
string $isModal,
string $user
): string {
$view = $item['custom']['view'];
$action = $this->permission->getAction($view, 'core.edit');
$idCode = $this->getCustomItemIdCode($item);
return $isModal . $user . "->authorise('"
. $action . "', 'com_" . $this->config->component_code_name . "."
. $view . ".' . (int) (\$item->" . $idCode . " ?? 0))";
}
/**
* Get the custom item ID code.
*
* @param array $item The item array.
*
* @return string The custom item ID code.
* @since 5.1.5
*/
protected function getCustomItemIdCode(array $item): string
{
if (isset($item['custom']['id']) && $item['custom']['id'] !== 'id')
{
return $item['id_code'] . '_id';
}
return $item['id_code'];
}
/**
* Get the default item authority string.
*
* @param string $nameSingleCode The single view code name.
* @param string $isModal The modal authority prefix.
*
* @return string The default item authority string.
* @since 5.1.5
*/
protected function getDefaultItemAuthority(
string $nameSingleCode,
string $isModal
): string {
return $isModal . "\$canDo->get('"
. $this->permission->getGlobal($nameSingleCode, 'core.edit')
. "')";
}
}
@@ -0,0 +1,345 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
/**
* List Item Link Logic Class
*
* @since 5.1.5
*/
final class LinkLogic
{
/**
* The Config Class.
*
* @var Config
* @since 5.1.5
*/
protected Config $config;
/**
* Constructor.
*
* @param Config $config The Config Class.
*
* @since 5.1.5
*/
public function __construct(Config $config)
{
$this->config = $config;
}
/**
* Get the list item link logic.
*
* @param array $item The item.
* @param string $itemCode The item code string.
* @param string $itemLink The item link string.
* @param string $itemLinkAuthority The link authority string.
* @param string $nameSingleCode The single view code name.
* @param string $nameListCode The list view code name.
* @param string $classPointer The class pointer.
* @param bool $checkoutTriger The check out trigger.
* @param bool $class The div class adding switch.
*
* @return string The complete link logic of row item.
* @since 5.1.5
*/
public function get(
array $item,
string $itemCode,
string $itemLink,
string $itemLinkAuthority,
string $nameSingleCode,
string $nameListCode,
string $classPointer,
bool $checkoutTriger,
bool $class = true
): string
{
$code = (string) ($item['code'] ?? '');
$tab = $this->getWrapperTab($class);
$link = $this->openNameWrapper($class);
$link .= $this->buildAuthorizedLinkBlock(
$itemCode,
$itemLink,
$itemLinkAuthority,
$nameSingleCode,
$nameListCode,
$classPointer,
$checkoutTriger,
$code,
$tab
);
$link .= $this->closeNameWrapper($class);
return $link;
}
/**
* Open the name wrapper when enabled.
*
* @param bool $class The div class adding switch.
*
* @return string The opening wrapper markup or empty string.
* @since 5.1.5
*/
protected function openNameWrapper(bool $class): string
{
if (!$class)
{
return '';
}
return PHP_EOL . Indent::_(3) . '<div class="name">';
}
/**
* Close the name wrapper when enabled.
*
* @param bool $class The div class adding switch.
*
* @return string The closing wrapper markup or empty string.
* @since 5.1.5
*/
protected function closeNameWrapper(bool $class): string
{
if (!$class)
{
return '';
}
return PHP_EOL . Indent::_(3) . '</div>';
}
/**
* Get the wrapper indentation prefix.
*
* @param bool $class The div class adding switch.
*
* @return string The indentation prefix.
* @since 5.1.5
*/
protected function getWrapperTab(bool $class): string
{
return $class ? Indent::_(1) : '';
}
/**
* Build the main authorized link block.
*
* @param string $itemCode The item code string.
* @param string $itemLink The item link string.
* @param string $itemLinkAuthority The link authority string.
* @param string $nameSingleCode The single view code name.
* @param string $nameListCode The list view code name.
* @param string $classPointer The class pointer.
* @param bool $checkoutTriger The check out trigger.
* @param string $code The item field code.
* @param string $tab The indentation prefix.
*
* @return string The built authorized link block.
* @since 5.1.5
*/
protected function buildAuthorizedLinkBlock(
string $itemCode,
string $itemLink,
string $itemLinkAuthority,
string $nameSingleCode,
string $nameListCode,
string $classPointer,
bool $checkoutTriger,
string $code,
string $tab
): string
{
$link = '';
$link .= PHP_EOL . $tab . Indent::_(3) . "<?php if (" . $itemLinkAuthority . "): ?>";
$link .= PHP_EOL . $tab . Indent::_(4) . '<a href="' . $itemLink . '"><?php echo ' . $itemCode . '; ?></a>';
if ($checkoutTriger)
{
$link .= $this->buildCheckedOutBlock($nameListCode, $tab);
}
$link .= PHP_EOL . $tab . Indent::_(3) . "<?php else: ?>";
$link .= $this->buildUnauthorizedOutput(
$itemCode,
$nameSingleCode,
$classPointer,
$code,
$tab,
$checkoutTriger
);
$link .= PHP_EOL . $tab . Indent::_(3) . "<?php endif; ?>";
return $link;
}
/**
* Build the checked out block.
*
* @param string $nameListCode The list view code name.
* @param string $tab The indentation prefix.
*
* @return string The checked out block.
* @since 5.1.5
*/
protected function buildCheckedOutBlock(string $nameListCode, string $tab): string
{
$link = '';
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php if (\$item->checked_out): ?>";
$link .= PHP_EOL . $tab . Indent::_(5)
. "<?php echo Joomla__"
. "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('jgrid.checkedout', \$i, \$userChkOut->name, \$item->checked_out_time, '"
. $nameListCode
. ".', \$canCheckin); ?>";
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php endif; ?>";
return $link;
}
/**
* Build the unauthorized output block.
*
* @param string $itemCode The item code string.
* @param string $nameSingleCode The single view code name.
* @param string $classPointer The class pointer.
* @param string $code The item field code.
* @param string $tab The indentation prefix.
* @param bool $checkoutTriger The check out trigger.
*
* @return string The unauthorized output block.
* @since 5.1.5
*/
protected function buildUnauthorizedOutput(
string $itemCode,
string $nameSingleCode,
string $classPointer,
string $code,
string $tab,
bool $checkoutTriger
): string
{
if ($this->shouldApplyModalFix($checkoutTriger))
{
return $this->buildModalAwareOutput(
$itemCode,
$nameSingleCode,
$classPointer,
$code,
$tab
);
}
return PHP_EOL . $tab . Indent::_(4) . "<?php echo " . $itemCode . "; ?>";
}
/**
* Determine whether the modal fix should be applied.
*
* @param bool $checkoutTriger The check out trigger.
*
* @return bool True if the modal fix should be applied.
* @since 5.1.5
*/
protected function shouldApplyModalFix(bool $checkoutTriger): bool
{
return $checkoutTriger
&& $this->config->get('joomla_version', 3) !== 3;
}
/**
* Build the modal aware unauthorized output.
*
* @param string $itemCode The item code string.
* @param string $nameSingleCode The single view code name.
* @param string $classPointer The class pointer.
* @param string $code The item field code.
* @param string $tab The indentation prefix.
*
* @return string The modal aware output block.
* @since 5.1.5
*/
protected function buildModalAwareOutput(
string $itemCode,
string $nameSingleCode,
string $classPointer,
string $code,
string $tab
): string
{
$link = '';
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php if (!{$classPointer}isModal): ?>";
$link .= PHP_EOL . $tab . Indent::_(5) . "<?php echo " . $itemCode . "; ?>";
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php else: ?>";
$link .= $this->buildModalSelectionBlock($nameSingleCode, $classPointer, $code, $tab, $itemCode);
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php endif; ?>";
return $link;
}
/**
* Build the modal selection block.
*
* @param string $nameSingleCode The single view code name.
* @param string $classPointer The class pointer.
* @param string $code The item field code.
* @param string $tab The indentation prefix.
* @param string $itemCode The item code string.
*
* @return string The modal selection block.
* @since 5.1.5
*/
protected function buildModalSelectionBlock(
string $nameSingleCode,
string $classPointer,
string $code,
string $tab,
string $itemCode
): string
{
$link = '';
$link .= PHP_EOL . $tab . Indent::_(5) . "<?php";
$link .= PHP_EOL . $tab . Indent::_(6) . "\$link = \"{\$edit}&id={\$item->id}\";";
$link .= PHP_EOL . $tab . Indent::_(6) . "\$dataId = \$item->{{$classPointer}getModalTitleKey()} ?? 0;";
$link .= PHP_EOL . $tab . Indent::_(6)
. "\$itemHtml = '<a href=\"' . {$classPointer}escape(\$link, false) . '\">' . {$classPointer}escape(\$item->{$code}, false) . '</a>';";
$link .= PHP_EOL . $tab . Indent::_(6)
. "\$attribs = 'data-content-select data-content-type=\"com_"
. $this->config->component_code_name
. "."
. $nameSingleCode
. "\"'";
$link .= PHP_EOL . $tab . Indent::_(7) . ". ' data-id=\"' . \$dataId . '\"'";
$link .= PHP_EOL . $tab . Indent::_(7) . ". ' data-title=\"' . {$classPointer}escape(\$item->{$code}, false) . '\"'";
$link .= PHP_EOL . $tab . Indent::_(7) . ". ' data-uri=\"' . {$classPointer}escape(\$link, false) . '\"'";
$link .= PHP_EOL . $tab . Indent::_(7) . ". ' data-html=\"' . {$classPointer}escape(\$itemHtml, false) . '\"';";
$link .= PHP_EOL . $tab . Indent::_(5) . "?>";
$link .= PHP_EOL . $tab . Indent::_(5) . "<a class=\"select-link\" href=\"javascript:void(0)\" <?php echo \$attribs; ?>>";
$link .= PHP_EOL . $tab . Indent::_(6) . "<?php echo " . $itemCode . "; ?>";
$link .= PHP_EOL . $tab . Indent::_(5) . "</a>";
return $link;
}
}
@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>
@@ -0,0 +1,413 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem;
use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldRelations;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ListJoin;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
/**
* List Item Builder Class
*
* @since 5.1.5
*/
final class ListItemBuilder
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.1.5
*/
protected Placeholder $placeholder;
/**
* The ListItem Class.
*
* @var ListItem
* @since 5.1.5
*/
protected ListItem $listitem;
/**
* The FieldRelations Class.
*
* @var FieldRelations
* @since 5.1.5
*/
protected FieldRelations $fieldrelations;
/**
* The ListJoin Class.
*
* @var ListJoin
* @since 5.1.5
*/
protected ListJoin $listjoin;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param ListItem $listitem The ListItem Class.
* @param FieldRelations $fieldrelations The FieldRelations Class.
* @param ListJoin $listjoin The ListJoin Class.
*
* @since 5.1.5
*/
public function __construct(Placeholder $placeholder, ListItem $listitem,
FieldRelations $fieldrelations, ListJoin $listjoin)
{
$this->placeholder = $placeholder;
$this->listitem = $listitem;
$this->fieldrelations = $fieldrelations;
$this->listjoin = $listjoin;
}
/**
* Get the list item dynamic row.
*
* @param array $item The item array.
* @param string $nameSingleCode The single view code name.
* @param string $nameListCode The list view code name.
* @param string $itemClass The table row default class.
* @param bool $doNotEscape The do not escape global switch.
* @param bool $class The div class adding switch.
* @param ?string $ref The link referral string.
* @param string $classPointer The class pointer (this or displaydata).
* @param string $user The user code name.
* @param ?string $refview The override of the referral view code name.
*
* @return string The completed item value for the table row.
* @since 5.1.2
*/
public function get(
array $item,
string $nameSingleCode,
string $nameListCode,
string &$itemClass,
bool $doNotEscape,
bool $class = true,
?string $ref = null,
string $classPointer = '$this->',
string $user = '$this->user',
?string $refview = null
): string
{
$fieldRelations = $this->getListItemFieldRelations($nameListCode, $item);
if ($fieldRelations === null)
{
return $this->listitem->get(
$item,
$nameSingleCode,
$nameListCode,
$itemClass,
$doNotEscape,
$class,
$ref,
$classPointer,
$user,
$refview
);
}
$fieldListItem = $this->listitem->get(
$item,
$nameSingleCode,
$nameListCode,
$itemClass,
$doNotEscape,
false,
$ref,
$classPointer,
$user,
$refview
);
$fieldPlaceholders = [];
$fieldArray = [];
$id = (int) ($item['id'] ?? 0);
$guid = (string) ($item['guid'] ?? 'error');
$this->addFieldOutputPlaceholders(
$fieldPlaceholders,
$fieldArray,
$fieldListItem,
$id,
$guid
);
$this->addItemCodePlaceholders(
$item,
$id,
$guid,
$fieldPlaceholders
);
$this->addJoinListItemFieldData(
$fieldRelations,
$nameSingleCode,
$nameListCode,
$doNotEscape,
$ref,
$classPointer,
$user,
$refview,
$fieldPlaceholders,
$fieldArray
);
return $this->renderListItemBuilderOutput(
$fieldRelations,
$fieldPlaceholders,
$fieldArray
);
}
/**
* Get the field relation settings for a list item.
*
* @param string $nameListCode The list view code name.
* @param array $item The field item array.
*
* @return array|null The field relation settings or null.
* @since 5.1.2
*/
protected function getListItemFieldRelations(string $nameListCode, array $item): ?array
{
$fieldRelations = $this->fieldrelations->get(
$nameListCode . '.' . (string) $item['guid'] . '.2'
);
return is_array($fieldRelations) ? $fieldRelations : null;
}
/**
* Add rendered field output placeholders.
*
* @param array $fieldPlaceholders The field placeholders.
* @param array $fieldArray The rendered field array.
* @param string $fieldOutput The rendered field output.
* @param int $fieldId The field ID.
* @param string $fieldGuid The field GUID.
*
* @return void
* @since 5.1.2
*/
protected function addFieldOutputPlaceholders(
array &$fieldPlaceholders,
array &$fieldArray,
string $fieldOutput,
int $fieldId,
string $fieldGuid
): void
{
$fieldPlaceholders['[field=' . $fieldId . ']'] = $fieldOutput;
$fieldPlaceholders['[field=' . $fieldGuid . ']'] = $fieldOutput;
$fieldArray[] = trim($fieldOutput);
}
/**
* Add code name placeholders for an item.
*
* @param array $item The field item array.
* @param int $fieldId The field ID.
* @param string $fieldGuid The field GUID.
* @param array $fieldPlaceholders The field placeholders.
*
* @return void
* @since 5.1.2
*/
protected function addItemCodePlaceholders(
array $item,
int $fieldId,
string $fieldGuid,
array &$fieldPlaceholders
): void
{
if (
!isset($item['code'])
|| !StringHelper::check((string) $item['code'])
)
{
return;
}
$codeReference = '$item->' . $item['code'];
$fieldPlaceholders['$item->{' . $fieldId . '}'] = $codeReference;
$fieldPlaceholders['$item->{' . $fieldGuid . '}'] = $codeReference;
}
/**
* Add joined list item field data.
*
* @param array $fieldRelations The field relation settings.
* @param string $nameSingleCode The single view code name.
* @param string $nameListCode The list view code name.
* @param bool $doNotEscape The do not escape global switch.
* @param ?string $ref The link referral string.
* @param string $classPointer The class pointer.
* @param string $user The user code name.
* @param ?string $refview The referral view code name override.
* @param array $fieldPlaceholders The field placeholders.
* @param array $fieldArray The rendered field array.
*
* @return void
* @since 5.1.2
*/
protected function addJoinListItemFieldData(
array $fieldRelations,
string $nameSingleCode,
string $nameListCode,
bool $doNotEscape,
?string $ref,
string $classPointer,
string $user,
?string $refview,
array &$fieldPlaceholders,
array &$fieldArray
): void
{
if (
!isset($fieldRelations['joinfields'])
|| !ArrayHelper::check($fieldRelations['joinfields'])
)
{
return;
}
foreach ($fieldRelations['joinfields'] as $join)
{
$joinKey = $nameListCode . '.' . (string) $join;
$joinItem = $this->listjoin->get($joinKey);
if (!is_array($joinItem))
{
continue;
}
$blankClass = '';
$joinId = (int) $this->listjoin->get($joinKey . '.id', 0);
$joinFieldListItem = $this->listitem->get(
$joinItem,
$nameSingleCode,
$nameListCode,
$blankClass,
$doNotEscape,
false,
$ref,
$classPointer,
$user,
$refview
);
$this->addFieldOutputPlaceholders(
$fieldPlaceholders,
$fieldArray,
$joinFieldListItem,
$joinId,
(string) $join
);
$this->addItemCodePlaceholders(
$joinItem,
$joinId,
(string) $join,
$fieldPlaceholders
);
}
}
/**
* Render the final list item builder output.
*
* @param array $fieldRelations The field relation settings.
* @param array $fieldPlaceholders The field placeholders.
* @param array $fieldArray The rendered field array.
*
* @return string The rendered output.
* @since 5.1.2
*/
protected function renderListItemBuilderOutput(
array $fieldRelations,
array $fieldPlaceholders,
array $fieldArray
): string
{
if ($this->shouldUseCustomRelationCode($fieldRelations))
{
$output = str_replace(
array_keys($fieldPlaceholders),
array_values($fieldPlaceholders),
(string) $fieldRelations['set']
);
return $this->wrapListItemBuilderOutput(
$this->placeholder->update_($output)
);
}
if (
isset($fieldRelations['set'])
&& StringHelper::check((string) $fieldRelations['set'])
)
{
return $this->wrapListItemBuilderOutput(
implode((string) $fieldRelations['set'], $fieldArray)
);
}
return $this->wrapListItemBuilderOutput(
implode('', $fieldArray)
);
}
/**
* Check if the relation should use custom code.
*
* @param array $fieldRelations The field relation settings.
*
* @return bool True if custom relation code should be used.
* @since 5.1.2
*/
protected function shouldUseCustomRelationCode(array $fieldRelations): bool
{
return isset($fieldRelations['join_type'], $fieldRelations['set'])
&& (int) $fieldRelations['join_type'] === 2
&& StringHelper::check((string) $fieldRelations['set']);
}
/**
* Wrap the output in the standard list item builder div.
*
* @param string $output The output string.
*
* @return string The wrapped output.
* @since 5.1.2
*/
protected function wrapListItemBuilderOutput(string $output): string
{
return PHP_EOL . Indent::_(3) . '<div>'
. $output . PHP_EOL . Indent::_(3) . '</div>';
}
}
@@ -0,0 +1,626 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Dashboard;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Structure;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Dashboard\ViewInterface;
/**
* Dashboard View Class
*
* @since 5.1.5
*/
final class View implements ViewInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.1.5
*/
protected Config $config;
/**
* The Component Class.
*
* @var Component
* @since 5.1.5
*/
protected Component $component;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.1.5
*/
protected Placeholder $placeholder;
/**
* The ContentMulti Class.
*
* @var ContentMulti
* @since 5.1.5
*/
protected ContentMulti $contentmulti;
/**
* The Structure Class.
*
* @var Structure
* @since 5.1.5
*/
protected Structure $structure;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Component $component The Component Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param ContentMulti $contentmulti The ContentMulti Class.
* @param Structure $structure The Structure Class.
*
* @since 5.1.5
*/
public function __construct(
Config $config,
Component $component,
Placeholder $placeholder,
ContentMulti $contentmulti,
Structure $structure
) {
$this->config = $config;
$this->component = $component;
$this->placeholder = $placeholder;
$this->contentmulti = $contentmulti;
$this->structure = $structure;
}
/**
* Build the admin dashboard display markup for Joomla 5.
*
* @return string The compiled dashboard display markup.
* @since 5.1.5
*/
public function get(): string
{
$state = $this->getDashboardDisplayState();
$this->initializeDashboardDisplay($state);
$this->appendMainDashboardColumns($state);
if ($state['loadTabs'])
{
$this->appendCustomTabs($state);
$this->appendTabSetEnd($state);
}
else
{
$this->appendMainRowEnd($state);
}
$this->appendDashboardContainerEnd($state);
return PHP_EOL . implode(PHP_EOL, $state['display']);
}
/**
* Get the initial dashboard display state.
*
* @return array The dashboard display state.
* @since 5.1.5
*/
protected function getDashboardDisplayState(): array
{
return [
'display' => [],
'builder' => [],
'tab' => Indent::_(3),
'loadTabs' => false,
'containerId' => 'j-main-container',
'wrapperTabsClass' => 'main-card',
'wrapperClass' => 'main-card p-3 p-lg-4',
'rowClass' => 'row g-4',
'mainColumnClass' => 'col-12 col-xl-9',
'sideColumnClass' => 'col-12 col-xl-3',
'fullColumnClass' => 'col-12',
'uiTab' => 'uitab',
'tabSet' => 'cpanel_tab',
'mainTabAlias' => 'cpanel',
];
}
/**
* Initialize the dashboard display structure.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function initializeDashboardDisplay(array &$state): void
{
if ($this->hasCustomDashboardTabs())
{
$this->buildCustomDashboardTabTemplates($state['builder']);
$this->appendDashboardWithTabsStart($state);
$state['loadTabs'] = true;
return;
}
$this->appendStandardDashboardStart($state);
}
/**
* Check whether custom dashboard tabs exist.
*
* @return bool True if custom dashboard tabs exist.
* @since 5.1.5
*/
protected function hasCustomDashboardTabs(): bool
{
return $this->component->isArray('dashboard_tab');
}
/**
* Build the custom dashboard tab template map.
*
* @param array &$builder The custom tab builder map.
*
* @return void
* @since 5.1.5
*/
protected function buildCustomDashboardTabTemplates(array &$builder): void
{
foreach ($this->component->get('dashboard_tab') as $data)
{
$builder[$data['name']][$data['header']]
= $this->placeholder->update_($data['html']);
}
}
/**
* Append the dashboard start markup when custom tabs are enabled.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendDashboardWithTabsStart(array &$state): void
{
$state['display'][] = $this->getOpenContainer($state['containerId']);
$state['display'][] = Indent::_(1) . $this->getOpenDiv($state['wrapperTabsClass']);
$state['display'][] = Indent::_(1)
. $this->getUiTabStartSetCode($state['tabSet'], $state['mainTabAlias']);
$state['display'][] = PHP_EOL . Indent::_(2)
. $this->getUiTabAddTabCode(
$state['tabSet'],
$state['mainTabAlias'],
"Text:" . ":_('cPanel', true)"
);
$state['display'][] = Indent::_(2) . $this->getOpenDiv($state['rowClass']);
}
/**
* Append the standard dashboard start markup.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendStandardDashboardStart(array &$state): void
{
$state['display'][] = $this->getOpenContainer($state['containerId']);
$state['display'][] = Indent::_(1) . $this->getOpenDiv($state['wrapperClass']);
$state['display'][] = Indent::_(2) . $this->getOpenDiv($state['rowClass']);
}
/**
* Append the main dashboard columns.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendMainDashboardColumns(array &$state): void
{
$this->appendLeftDashboardColumn($state);
$this->appendRightDashboardColumn($state);
}
/**
* Append the left dashboard column.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendLeftDashboardColumn(array &$state): void
{
$state['display'][] = $state['tab'] . $this->getOpenDiv($state['mainColumnClass']);
$state['display'][] = $state['tab'] . Indent::_(1)
. $this->getLoadTemplateCode('main');
$state['display'][] = $state['tab'] . '</div>';
}
/**
* Append the right dashboard column.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendRightDashboardColumn(array &$state): void
{
$state['display'][] = $state['tab'] . $this->getOpenDiv($state['sideColumnClass']);
$state['display'][] = $state['tab'] . Indent::_(1)
. $this->getLoadTemplateCode('vdm');
$state['display'][] = $state['tab'] . '</div>';
}
/**
* Append all custom dashboard tabs.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendCustomTabs(array &$state): void
{
$state['display'][] = Indent::_(2) . '</div>';
$state['display'][] = Indent::_(2) . $this->getUiTabEndTabCode();
foreach ($state['builder'] as $tabName => $templates)
{
$this->appendCustomTab($state, $tabName, $templates);
}
}
/**
* Append a single custom dashboard tab.
*
* @param array &$state The dashboard display state.
* @param string $tabName The tab name.
* @param array $templates The template content definitions.
*
* @return void
* @since 5.1.5
*/
protected function appendCustomTab(array &$state, string $tabName, array $templates): void
{
$alias = StringHelper::safe($tabName);
$state['display'][] = PHP_EOL . Indent::_(2)
. $this->getUiTabAddTabCode(
$state['tabSet'],
$alias,
"Joomla__" . "_ba6326ef_cb79_4348_80f4_ab086082e3c5___Power::_('"
. $tabName . "', true)"
);
$state['display'][] = Indent::_(2) . $this->getOpenDiv($state['rowClass']);
$state['display'][] = $state['tab'] . $this->getOpenDiv($state['fullColumnClass']);
$this->appendCustomTabTemplates($state, $alias, $templates);
$state['display'][] = $state['tab'] . '</div>';
$state['display'][] = Indent::_(2) . '</div>';
$state['display'][] = Indent::_(2) . $this->getUiTabEndTabCode();
}
/**
* Append all template loads for a custom dashboard tab.
*
* @param array &$state The dashboard display state.
* @param string $alias The safe tab alias.
* @param array $templates The template content definitions.
*
* @return void
* @since 5.1.5
*/
protected function appendCustomTabTemplates(array &$state, string $alias, array $templates): void
{
foreach ($templates as $templateName => $html)
{
$this->appendCustomTabTemplate($state, $alias, $templateName, $html);
}
}
/**
* Append a single custom dashboard template load and register its content.
*
* @param array &$state The dashboard display state.
* @param string $alias The safe tab alias.
* @param string $templateName The template name.
* @param string $html The HTML content.
*
* @return void
* @since 5.1.5
*/
protected function appendCustomTabTemplate(
array &$state,
string $alias,
string $templateName,
string $html
): void
{
$safeTemplateName = $alias . '_' . StringHelper::safe($templateName);
$state['display'][] = $state['tab'] . Indent::_(1)
. $this->getLoadTemplateCode($safeTemplateName);
$this->buildCustomDashboardTemplate($safeTemplateName, $html);
}
/**
* Build a custom dashboard template file and register its content.
*
* @param string $templateName The template name.
* @param string $html The template body HTML.
*
* @return void
* @since 5.1.5
*/
protected function buildCustomDashboardTemplate(string $templateName, string $html): void
{
$this->buildCustomDashboardTemplateStructure($templateName);
$this->storeCustomDashboardTemplateBody($templateName, $html);
$this->storeCustomDashboardTemplateCodeBody($templateName);
}
/**
* Build the custom dashboard template structure.
*
* @param string $templateName The template name.
*
* @return void
* @since 5.1.5
*/
protected function buildCustomDashboardTemplateStructure(string $templateName): void
{
$this->structure->build(
['custom_admin' => $this->config->component_code_name],
'template',
$templateName
);
}
/**
* Store the custom dashboard template body.
*
* @param string $templateName The template name.
* @param string $html The template body HTML.
*
* @return void
* @since 5.1.5
*/
protected function storeCustomDashboardTemplateBody(string $templateName, string $html): void
{
$this->contentmulti->set(
$this->getCustomDashboardTemplateKey(
$templateName,
'CUSTOM_ADMIN_TEMPLATE_BODY'
),
PHP_EOL . $html
);
}
/**
* Store the custom dashboard template code body.
*
* @param string $templateName The template name.
*
* @return void
* @since 5.1.5
*/
protected function storeCustomDashboardTemplateCodeBody(string $templateName): void
{
$this->contentmulti->set(
$this->getCustomDashboardTemplateKey(
$templateName,
'CUSTOM_ADMIN_TEMPLATE_CODE_BODY'
),
''
);
}
/**
* Get the custom dashboard template storage key.
*
* @param string $templateName The template name.
* @param string $suffix The key suffix.
*
* @return string The storage key.
* @since 5.1.5
*/
protected function getCustomDashboardTemplateKey(
string $templateName,
string $suffix
): string
{
return $this->config->component_code_name . '_'
. $templateName . '|' . $suffix;
}
/**
* Append the end of the tab set.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendTabSetEnd(array &$state): void
{
$state['display'][] = PHP_EOL . Indent::_(1)
. $this->getUiTabEndTabSetCode();
}
/**
* Append the end of the main row layout.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendMainRowEnd(array &$state): void
{
$state['display'][] = Indent::_(2) . '</div>';
}
/**
* Append the closing dashboard container markup.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendDashboardContainerEnd(array &$state): void
{
$state['display'][] = Indent::_(1) . '</div>';
$state['display'][] = '</div>';
}
/**
* Get the PHP code for starting a UI tab set.
*
* @param string $tabSet The tab set name.
* @param string $activeTab The active tab alias.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getUiTabStartSetCode(
string $tabSet,
string $activeTab
): string
{
return "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('"
. $this->getUiTabHelperName('startTabSet') . "', '" . $tabSet
. "', array('active' => '" . $activeTab . "')); ?>";
}
/**
* Get the PHP code for adding a UI tab.
*
* @param string $tabSet The tab set name.
* @param string $alias The tab alias.
* @param string $title The tab title PHP expression.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getUiTabAddTabCode(
string $tabSet,
string $alias,
string $title
): string
{
return "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('"
. $this->getUiTabHelperName('addTab') . "', '" . $tabSet
. "', '" . $alias . "', " . $title . "); ?>";
}
/**
* Get the PHP code for ending a UI tab.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getUiTabEndTabCode(): string
{
return "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('"
. $this->getUiTabHelperName('endTab') . "'); ?>";
}
/**
* Get the PHP code for ending a UI tab set.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getUiTabEndTabSetCode(): string
{
return "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('"
. $this->getUiTabHelperName('endTabSet') . "'); ?>";
}
/**
* Get the UI tab helper name.
*
* @param string $method The helper method name.
*
* @return string The full helper name.
* @since 5.1.5
*/
protected function getUiTabHelperName(string $method): string
{
return 'uitab.' . $method;
}
/**
* Get the PHP code for loading a layout template.
*
* @param string $templateName The template name.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getLoadTemplateCode(string $templateName): string
{
return "<?php echo \$this->loadTemplate('" . $templateName . "');?>";
}
/**
* Get the opening container markup.
*
* @param string $id The container ID.
*
* @return string The container opening markup.
* @since 5.1.5
*/
protected function getOpenContainer(string $id): string
{
return '<div id="' . $id . '">';
}
/**
* Get the opening div markup.
*
* @param string $class The div class.
*
* @return string The div opening markup.
* @since 5.1.5
*/
protected function getOpenDiv(string $class): string
{
return '<div class="' . $class . '">';
}
}
@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>
@@ -0,0 +1,454 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Dashboard;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Structure;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Dashboard\ViewInterface;
/**
* Dashboard View Class
*
* @since 5.1.5
*/
final class View implements ViewInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.1.5
*/
protected Config $config;
/**
* The Component Class.
*
* @var Component
* @since 5.1.5
*/
protected Component $component;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.1.5
*/
protected Placeholder $placeholder;
/**
* The ContentMulti Class.
*
* @var ContentMulti
* @since 5.1.5
*/
protected ContentMulti $contentmulti;
/**
* The Structure Class.
*
* @var Structure
* @since 5.1.5
*/
protected Structure $structure;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Component $component The Component Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param ContentMulti $contentmulti The ContentMulti Class.
* @param Structure $structure The Structure Class.
*
* @since 5.1.5
*/
public function __construct(Config $config, Component $component,
Placeholder $placeholder, ContentMulti $contentmulti, Structure $structure)
{
$this->config = $config;
$this->component = $component;
$this->placeholder = $placeholder;
$this->contentmulti = $contentmulti;
$this->structure = $structure;
}
/**
* Build the admin dashboard display markup for Joomla 4 and above.
*
* @return string The compiled dashboard display markup.
*
* @since 5.1.5
*/
public function get(): string
{
$state = $this->getDashboardDisplayState();
$this->initializeDashboardDisplay($state);
$this->appendMainDashboardColumns($state);
if ($state['loadTabs'])
{
$this->appendCustomTabs($state);
$this->appendTabSetEnd($state);
}
else
{
$this->appendStandardRowEnd($state);
}
$this->appendDashboardContainerEnd($state);
return PHP_EOL . implode(PHP_EOL, $state['display']);
}
/**
* Get the initial dashboard display state.
*
* @return array The dashboard display state.
*
* @since 5.1.5
*/
protected function getDashboardDisplayState(): array
{
return [
'display' => [],
'mainAccordionName' => 'cPanel',
'builder' => [],
'tab' => Indent::_(3),
'loadTabs' => false,
'widthClass' => 'col-md-',
'rowClass' => 'row',
'formClass' => 'main-card',
'uiTab' => 'uitab',
];
}
/**
* Initialize the dashboard display structure.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function initializeDashboardDisplay(array &$state): void
{
if ($this->hasCustomDashboardTabs())
{
$this->buildCustomDashboardTabTemplates($state['builder']);
$this->appendDashboardWithTabsStart($state);
$state['mainAccordionName'] = 'Control Panel';
$state['loadTabs'] = true;
return;
}
$this->appendStandardDashboardStart($state);
}
/**
* Check whether custom dashboard tabs exist.
*
* @return bool True if custom dashboard tabs exist.
*
* @since 5.1.5
*/
protected function hasCustomDashboardTabs(): bool
{
return $this->component->isArray('dashboard_tab');
}
/**
* Build the custom dashboard tab template map.
*
* @param array &$builder The custom tab builder map.
*
* @return void
*
* @since 5.1.5
*/
protected function buildCustomDashboardTabTemplates(array &$builder): void
{
foreach ($this->component->get('dashboard_tab') as $data)
{
$builder[$data['name']][$data['header']]
= $this->placeholder->update_($data['html']);
}
}
/**
* Append the dashboard start markup when custom tabs are enabled.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendDashboardWithTabsStart(array &$state): void
{
$state['display'][] = '<div id="j-main-container">';
$state['display'][] = Indent::_(1) . '<div class="' . $state['formClass'] . '">';
$state['display'][] = Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.startTabSet', 'cpanel_tab', array('active' => 'cpanel')); ?>";
$state['display'][] = PHP_EOL . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.addTab', 'cpanel_tab', 'cpanel', Text:" . ":_('cPanel', true)); ?>";
$state['display'][] = Indent::_(2) . '<div class="' . $state['rowClass'] . '">';
}
/**
* Append the standard dashboard start markup.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendStandardDashboardStart(array &$state): void
{
$state['display'][] = '<div id="j-main-container">';
$state['display'][] = Indent::_(1) . '<div class="' . $state['formClass'] . '" style="padding: 20px;">';
$state['display'][] = Indent::_(2) . '<div class="' . $state['rowClass'] . '">';
}
/**
* Append the main dashboard columns.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendMainDashboardColumns(array &$state): void
{
$this->appendLeftDashboardColumn($state);
$this->appendRightDashboardColumn($state);
}
/**
* Append the left dashboard column.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendLeftDashboardColumn(array &$state): void
{
$state['display'][] = $state['tab'] . '<div class="' . $state['widthClass'] . '9">';
$state['display'][] = $state['tab'] . Indent::_(1)
. "<?php echo \$this->loadTemplate('main');?>";
$state['display'][] = $state['tab'] . '</div>';
}
/**
* Append the right dashboard column.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendRightDashboardColumn(array &$state): void
{
$state['display'][] = $state['tab'] . '<div class="' . $state['widthClass'] . '3">';
$state['display'][] = $state['tab'] . Indent::_(1)
. "<?php echo \$this->loadTemplate('vdm');?>";
$state['display'][] = $state['tab'] . '</div>';
}
/**
* Append all custom dashboard tabs.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendCustomTabs(array &$state): void
{
$state['display'][] = Indent::_(2) . '</div>';
$state['display'][] = Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.endTab'); ?>";
foreach ($state['builder'] as $tabName => $accordions)
{
$this->appendCustomTab($state, $tabName, $accordions);
}
}
/**
* Append a single custom dashboard tab.
*
* @param array &$state The dashboard display state.
* @param string $tabName The tab name.
* @param array $accordions The accordion content definitions.
*
* @return void
*
* @since 5.1.5
*/
protected function appendCustomTab(array &$state, string $tabName, array $accordions): void
{
$alias = StringHelper::safe($tabName);
$state['display'][] = PHP_EOL . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.addTab', 'cpanel_tab', '"
. $alias . "', Joomla__" . "_ba6326ef_cb79_4348_80f4_ab086082e3c5___Power::_('"
. $tabName . "', true)); ?>";
$state['display'][] = Indent::_(2) . '<div class="' . $state['rowClass'] . '">';
$state['display'][] = $state['tab'] . '<div class="' . $state['widthClass'] . '12">';
$this->appendCustomTabTemplates($state, $alias, $accordions);
$state['display'][] = $state['tab'] . '</div>';
$state['display'][] = Indent::_(2) . '</div>';
$state['display'][] = Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.endTab'); ?>";
}
/**
* Append all template loads for a custom dashboard tab.
*
* @param array &$state The dashboard display state.
* @param string $alias The safe tab alias.
* @param array $accordions The accordion content definitions.
*
* @return void
*
* @since 5.1.5
*/
protected function appendCustomTabTemplates(array &$state, string $alias, array $accordions): void
{
foreach ($accordions as $accordionName => $html)
{
$this->appendCustomTabTemplate($state, $alias, $accordionName, $html);
}
}
/**
* Append a single custom dashboard template load and register its content.
*
* @param array &$state The dashboard display state.
* @param string $alias The safe tab alias.
* @param string $accordionName The accordion name.
* @param string $html The HTML content.
*
* @return void
*
* @since 5.1.5
*/
protected function appendCustomTabTemplate(
array &$state,
string $alias,
string $accordionName,
string $html
): void
{
$accordionAlias = StringHelper::safe($accordionName);
$templateName = $alias . '_' . $accordionAlias;
$state['display'][] = $state['tab'] . Indent::_(1)
. "<?php echo \$this->loadTemplate('" . $templateName . "');?>";
$this->buildCustomDashboardTemplate($templateName, $html);
}
/**
* Build a custom dashboard template file and register its content.
*
* @param string $templateName The template name.
* @param string $html The template body HTML.
*
* @return void
*
* @since 5.1.5
*/
protected function buildCustomDashboardTemplate(string $templateName, string $html): void
{
$componentCodeName = $this->config->component_code_name;
$target = ['custom_admin' => $componentCodeName];
$this->structure->build($target, 'template', $templateName);
$this->contentmulti->set(
$componentCodeName . '_' . $templateName . '|CUSTOM_ADMIN_TEMPLATE_BODY',
PHP_EOL . $html
);
$this->contentmulti->set(
$componentCodeName . '_' . $templateName . '|CUSTOM_ADMIN_TEMPLATE_CODE_BODY',
''
);
}
/**
* Append the end of the tab set.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendTabSetEnd(array &$state): void
{
$state['display'][] = PHP_EOL . Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.endTabSet'); ?>";
}
/**
* Append the end of the standard row layout.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendStandardRowEnd(array &$state): void
{
$state['display'][] = Indent::_(2) . '</div>';
}
/**
* Append the closing dashboard container markup.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendDashboardContainerEnd(array &$state): void
{
$state['display'][] = Indent::_(1) . '</div>';
$state['display'][] = '</div>';
}
}
@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>
@@ -0,0 +1,657 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaSix\Dashboard;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Structure;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Dashboard\ViewInterface;
/**
* Dashboard View Class
*
* @since 5.1.5
*/
final class View implements ViewInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.1.5
*/
protected Config $config;
/**
* The Component Class.
*
* @var Component
* @since 5.1.5
*/
protected Component $component;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.1.5
*/
protected Placeholder $placeholder;
/**
* The ContentMulti Class.
*
* @var ContentMulti
* @since 5.1.5
*/
protected ContentMulti $contentmulti;
/**
* The Structure Class.
*
* @var Structure
* @since 5.1.5
*/
protected Structure $structure;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Component $component The Component Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param ContentMulti $contentmulti The ContentMulti Class.
* @param Structure $structure The Structure Class.
*
* @since 5.1.5
*/
public function __construct(
Config $config,
Component $component,
Placeholder $placeholder,
ContentMulti $contentmulti,
Structure $structure
) {
$this->config = $config;
$this->component = $component;
$this->placeholder = $placeholder;
$this->contentmulti = $contentmulti;
$this->structure = $structure;
}
/**
* Build the admin dashboard display markup for Joomla 6 style layouts.
*
* @return string The compiled dashboard display markup.
* @since 5.1.5
*/
public function get(): string
{
$state = $this->getDashboardDisplayState();
$this->initializeDashboardDisplay($state);
$this->appendMainDashboardColumns($state);
if ($state['loadTabs'])
{
$this->appendCustomTabs($state);
$this->appendTabSetEnd($state);
}
else
{
$this->appendMainRowEnd($state);
}
$this->appendDashboardContainerEnd($state);
return PHP_EOL . implode(PHP_EOL, $state['display']);
}
/**
* Get the initial dashboard display state.
*
* @return array The dashboard display state.
* @since 5.1.5
*/
protected function getDashboardDisplayState(): array
{
return [
'display' => [],
'builder' => [],
'tab' => Indent::_(3),
'loadTabs' => false,
'containerId' => 'j-main-container',
'containerClass' => 'container-fluid',
'wrapperTabsClass' => 'main-card jcb-dashboard',
'wrapperClass' => 'main-card jcb-dashboard p-3 p-lg-4',
'contentClass' => 'jcb-dashboard__content',
'rowClass' => 'row g-4 align-items-start',
'mainColumnClass' => 'col-12 col-xxl-9',
'sideColumnClass' => 'col-12 col-xxl-3',
'fullColumnClass' => 'col-12',
'mainInnerClass' => 'jcb-dashboard__main d-flex flex-column gap-4',
'sideInnerClass' => 'jcb-dashboard__sidebar d-flex flex-column gap-4',
'fullInnerClass' => 'jcb-dashboard__tab d-flex flex-column gap-4',
'uiTab' => 'uitab',
'tabSet' => 'cpanel_tab',
'mainTabAlias' => 'cpanel',
];
}
/**
* Initialize the dashboard display structure.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function initializeDashboardDisplay(array &$state): void
{
if ($this->hasCustomDashboardTabs())
{
$this->buildCustomDashboardTabTemplates($state['builder']);
$this->appendDashboardWithTabsStart($state);
$state['loadTabs'] = true;
return;
}
$this->appendStandardDashboardStart($state);
}
/**
* Check whether custom dashboard tabs exist.
*
* @return bool True if custom dashboard tabs exist.
* @since 5.1.5
*/
protected function hasCustomDashboardTabs(): bool
{
return $this->component->isArray('dashboard_tab');
}
/**
* Build the custom dashboard tab template map.
*
* @param array &$builder The custom tab builder map.
*
* @return void
* @since 5.1.5
*/
protected function buildCustomDashboardTabTemplates(array &$builder): void
{
foreach ($this->component->get('dashboard_tab') as $data)
{
$builder[$data['name']][$data['header']]
= $this->placeholder->update_($data['html']);
}
}
/**
* Append the dashboard start markup when custom tabs are enabled.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendDashboardWithTabsStart(array &$state): void
{
$state['display'][] = $this->getOpenContainer(
$state['containerId'],
$state['containerClass']
);
$state['display'][] = Indent::_(1) . $this->getOpenDiv($state['wrapperTabsClass']);
$state['display'][] = Indent::_(2) . $this->getOpenDiv($state['contentClass']);
$state['display'][] = Indent::_(2)
. $this->getUiTabStartSetCode($state['tabSet'], $state['mainTabAlias']);
$state['display'][] = PHP_EOL . Indent::_(3)
. $this->getUiTabAddTabCode(
$state['tabSet'],
$state['mainTabAlias'],
"Text:" . ":_('cPanel', true)"
);
$state['display'][] = Indent::_(3) . $this->getOpenDiv($state['rowClass']);
}
/**
* Append the standard dashboard start markup.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendStandardDashboardStart(array &$state): void
{
$state['display'][] = $this->getOpenContainer(
$state['containerId'],
$state['containerClass']
);
$state['display'][] = Indent::_(1) . $this->getOpenDiv($state['wrapperClass']);
$state['display'][] = Indent::_(2) . $this->getOpenDiv($state['contentClass']);
$state['display'][] = Indent::_(3) . $this->getOpenDiv($state['rowClass']);
}
/**
* Append the main dashboard columns.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendMainDashboardColumns(array &$state): void
{
$this->appendLeftDashboardColumn($state);
$this->appendRightDashboardColumn($state);
}
/**
* Append the left dashboard column.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendLeftDashboardColumn(array &$state): void
{
$state['display'][] = $state['tab']
. $this->getOpenDiv($state['mainColumnClass']);
$state['display'][] = $state['tab'] . Indent::_(1)
. $this->getOpenDiv($state['mainInnerClass']);
$state['display'][] = $state['tab'] . Indent::_(2)
. $this->getLoadTemplateCode('main');
$state['display'][] = $state['tab'] . Indent::_(1) . '</div>';
$state['display'][] = $state['tab'] . '</div>';
}
/**
* Append the right dashboard column.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendRightDashboardColumn(array &$state): void
{
$state['display'][] = $state['tab']
. $this->getOpenDiv($state['sideColumnClass']);
$state['display'][] = $state['tab'] . Indent::_(1)
. $this->getOpenDiv($state['sideInnerClass']);
$state['display'][] = $state['tab'] . Indent::_(2)
. $this->getLoadTemplateCode('vdm');
$state['display'][] = $state['tab'] . Indent::_(1) . '</div>';
$state['display'][] = $state['tab'] . '</div>';
}
/**
* Append all custom dashboard tabs.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendCustomTabs(array &$state): void
{
$state['display'][] = Indent::_(3) . '</div>';
$state['display'][] = Indent::_(3) . $this->getUiTabEndTabCode();
foreach ($state['builder'] as $tabName => $templates)
{
$this->appendCustomTab($state, $tabName, $templates);
}
}
/**
* Append a single custom dashboard tab.
*
* @param array &$state The dashboard display state.
* @param string $tabName The tab name.
* @param array $templates The template content definitions.
*
* @return void
* @since 5.1.5
*/
protected function appendCustomTab(array &$state, string $tabName, array $templates): void
{
$alias = StringHelper::safe($tabName);
$state['display'][] = PHP_EOL . Indent::_(3)
. $this->getUiTabAddTabCode(
$state['tabSet'],
$alias,
"Joomla__" . "_ba6326ef_cb79_4348_80f4_ab086082e3c5___Power::_('"
. $tabName . "', true)"
);
$state['display'][] = Indent::_(3) . $this->getOpenDiv($state['rowClass']);
$state['display'][] = $state['tab'] . $this->getOpenDiv($state['fullColumnClass']);
$state['display'][] = $state['tab'] . Indent::_(1)
. $this->getOpenDiv($state['fullInnerClass']);
$this->appendCustomTabTemplates($state, $alias, $templates);
$state['display'][] = $state['tab'] . Indent::_(1) . '</div>';
$state['display'][] = $state['tab'] . '</div>';
$state['display'][] = Indent::_(3) . '</div>';
$state['display'][] = Indent::_(3) . $this->getUiTabEndTabCode();
}
/**
* Append all template loads for a custom dashboard tab.
*
* @param array &$state The dashboard display state.
* @param string $alias The safe tab alias.
* @param array $templates The template content definitions.
*
* @return void
* @since 5.1.5
*/
protected function appendCustomTabTemplates(array &$state, string $alias, array $templates): void
{
foreach ($templates as $templateName => $html)
{
$this->appendCustomTabTemplate($state, $alias, $templateName, $html);
}
}
/**
* Append a single custom dashboard template load and register its content.
*
* @param array &$state The dashboard display state.
* @param string $alias The safe tab alias.
* @param string $templateName The template name.
* @param string $html The HTML content.
*
* @return void
* @since 5.1.5
*/
protected function appendCustomTabTemplate(
array &$state,
string $alias,
string $templateName,
string $html
): void
{
$safeTemplateName = $alias . '_' . StringHelper::safe($templateName);
$state['display'][] = $state['tab'] . Indent::_(2)
. $this->getLoadTemplateCode($safeTemplateName);
$this->buildCustomDashboardTemplate($safeTemplateName, $html);
}
/**
* Build a custom dashboard template file and register its content.
*
* @param string $templateName The template name.
* @param string $html The template body HTML.
*
* @return void
* @since 5.1.5
*/
protected function buildCustomDashboardTemplate(string $templateName, string $html): void
{
$this->buildCustomDashboardTemplateStructure($templateName);
$this->storeCustomDashboardTemplateBody($templateName, $html);
$this->storeCustomDashboardTemplateCodeBody($templateName);
}
/**
* Build the custom dashboard template structure.
*
* @param string $templateName The template name.
*
* @return void
* @since 5.1.5
*/
protected function buildCustomDashboardTemplateStructure(string $templateName): void
{
$this->structure->build(
['custom_admin' => $this->config->component_code_name],
'template',
$templateName
);
}
/**
* Store the custom dashboard template body.
*
* @param string $templateName The template name.
* @param string $html The template body HTML.
*
* @return void
* @since 5.1.5
*/
protected function storeCustomDashboardTemplateBody(string $templateName, string $html): void
{
$this->contentmulti->set(
$this->getCustomDashboardTemplateKey(
$templateName,
'CUSTOM_ADMIN_TEMPLATE_BODY'
),
PHP_EOL . $html
);
}
/**
* Store the custom dashboard template code body.
*
* @param string $templateName The template name.
*
* @return void
* @since 5.1.5
*/
protected function storeCustomDashboardTemplateCodeBody(string $templateName): void
{
$this->contentmulti->set(
$this->getCustomDashboardTemplateKey(
$templateName,
'CUSTOM_ADMIN_TEMPLATE_CODE_BODY'
),
''
);
}
/**
* Get the custom dashboard template storage key.
*
* @param string $templateName The template name.
* @param string $suffix The key suffix.
*
* @return string The storage key.
* @since 5.1.5
*/
protected function getCustomDashboardTemplateKey(
string $templateName,
string $suffix
): string
{
return $this->config->component_code_name . '_'
. $templateName . '|' . $suffix;
}
/**
* Append the end of the tab set.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendTabSetEnd(array &$state): void
{
$state['display'][] = PHP_EOL . Indent::_(2)
. $this->getUiTabEndTabSetCode();
}
/**
* Append the end of the main row layout.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendMainRowEnd(array &$state): void
{
$state['display'][] = Indent::_(3) . '</div>';
}
/**
* Append the closing dashboard container markup.
*
* @param array &$state The dashboard display state.
*
* @return void
* @since 5.1.5
*/
protected function appendDashboardContainerEnd(array &$state): void
{
$state['display'][] = Indent::_(2) . '</div>';
$state['display'][] = Indent::_(1) . '</div>';
$state['display'][] = '</div>';
}
/**
* Get the PHP code for starting a UI tab set.
*
* @param string $tabSet The tab set name.
* @param string $activeTab The active tab alias.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getUiTabStartSetCode(
string $tabSet,
string $activeTab
): string
{
return "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('"
. $this->getUiTabHelperName('startTabSet') . "', '" . $tabSet
. "', array('active' => '" . $activeTab . "')); ?>";
}
/**
* Get the PHP code for adding a UI tab.
*
* @param string $tabSet The tab set name.
* @param string $alias The tab alias.
* @param string $title The tab title PHP expression.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getUiTabAddTabCode(
string $tabSet,
string $alias,
string $title
): string
{
return "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('"
. $this->getUiTabHelperName('addTab') . "', '" . $tabSet
. "', '" . $alias . "', " . $title . "); ?>";
}
/**
* Get the PHP code for ending a UI tab.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getUiTabEndTabCode(): string
{
return "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('"
. $this->getUiTabHelperName('endTab') . "'); ?>";
}
/**
* Get the PHP code for ending a UI tab set.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getUiTabEndTabSetCode(): string
{
return "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('"
. $this->getUiTabHelperName('endTabSet') . "'); ?>";
}
/**
* Get the UI tab helper name.
*
* @param string $method The helper method name.
*
* @return string The full helper name.
* @since 5.1.5
*/
protected function getUiTabHelperName(string $method): string
{
return 'uitab.' . $method;
}
/**
* Get the PHP code for loading a layout template.
*
* @param string $templateName The template name.
*
* @return string The generated PHP code.
* @since 5.1.5
*/
protected function getLoadTemplateCode(string $templateName): string
{
return "<?php echo \$this->loadTemplate('" . $templateName . "');?>";
}
/**
* Get the opening container markup.
*
* @param string $id The container ID.
* @param string|null $class The container class.
*
* @return string The container opening markup.
* @since 5.1.5
*/
protected function getOpenContainer(string $id, ?string $class = null): string
{
if ($class !== null && $class !== '')
{
return '<div id="' . $id . '" class="' . $class . '">';
}
return '<div id="' . $id . '">';
}
/**
* Get the opening div markup.
*
* @param string $class The div class.
*
* @return string The div opening markup.
* @since 5.1.5
*/
protected function getOpenDiv(string $class): string
{
return '<div class="' . $class . '">';
}
}
@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>
@@ -0,0 +1,514 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Dashboard;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Structure;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Dashboard\ViewInterface;
/**
* Dashboard View Class
*
* @since 5.1.5
*/
final class View implements ViewInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.1.5
*/
protected Config $config;
/**
* The Component Class.
*
* @var Component
* @since 5.1.5
*/
protected Component $component;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.1.5
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var ContentOne
* @since 5.1.5
*/
protected ContentOne $contentone;
/**
* The ContentMulti Class.
*
* @var ContentMulti
* @since 5.1.5
*/
protected ContentMulti $contentmulti;
/**
* The Structure Class.
*
* @var Structure
* @since 5.1.5
*/
protected Structure $structure;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Component $component The Component Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param ContentOne $contentone The ContentOne Class.
* @param ContentMulti $contentmulti The ContentMulti Class.
* @param Structure $structure The Structure Class.
*
* @since 5.1.5
*/
public function __construct(Config $config, Component $component,
Placeholder $placeholder, ContentOne $contentone,
ContentMulti $contentmulti, Structure $structure)
{
$this->config = $config;
$this->component = $component;
$this->placeholder = $placeholder;
$this->contentone = $contentone;
$this->contentmulti = $contentmulti;
$this->structure = $structure;
}
/**
* Build the admin dashboard display markup.
*
* @return string The compiled dashboard display markup.
*
* @since 5.1.5
*/
public function get(): string
{
$state = $this->getDashboardDisplayState();
$this->initializeDashboardDisplay($state);
$this->appendMainDashboardColumns($state);
if ($state['loadTabs'])
{
$this->appendCustomTabs($state);
$this->appendTabSetEnd($state);
}
else
{
$this->appendStandardRowEnd($state);
}
$this->appendDashboardContainerEnd($state);
return PHP_EOL . implode(PHP_EOL, $state['display']);
}
/**
* Get the initial dashboard display state.
*
* @return array The dashboard display state.
*
* @since 5.1.5
*/
protected function getDashboardDisplayState(): array
{
return [
'display' => [],
'mainAccordianName' => 'cPanel',
'builder' => [],
'tab' => Indent::_(3),
'loadTabs' => false,
'widthClass' => 'span',
'rowClass' => 'row-fluid',
'formClass' => 'form-horizontal',
'uiTab' => 'bootstrap',
];
}
/**
* Initialize the dashboard display structure.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function initializeDashboardDisplay(array &$state): void
{
if ($this->hasCustomDashboardTabs())
{
$this->buildCustomDashboardTabTemplates($state['builder']);
$this->appendDashboardWithTabsStart($state);
$state['mainAccordionName'] = 'Control Panel';
$state['loadTabs'] = true;
return;
}
$this->appendStandardDashboardStart($state);
}
/**
* Check whether custom dashboard tabs exist.
*
* @return bool True if custom dashboard tabs exist.
*
* @since 5.1.5
*/
protected function hasCustomDashboardTabs(): bool
{
return $this->component->isArray('dashboard_tab');
}
/**
* Build the custom dashboard tab template map.
*
* @param array &$builder The builder map.
*
* @return void
*
* @since 5.1.5
*/
protected function buildCustomDashboardTabTemplates(array &$builder): void
{
foreach ($this->component->get('dashboard_tab') as $data)
{
$builder[$data['name']][$data['header']]
= $this->placeholder->update_($data['html']);
}
}
/**
* Append the dashboard start markup when custom tabs are enabled.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendDashboardWithTabsStart(array &$state): void
{
$state['display'][] = '<div id="j-main-container">';
$state['display'][] = Indent::_(1) . '<div class="' . $state['formClass'] . '">';
$state['display'][] = Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.startTabSet', 'cpanel_tab', array('active' => 'cpanel')); ?>";
$state['display'][] = PHP_EOL . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.addTab', 'cpanel_tab', 'cpanel', Text:" . ":_('cPanel', true)); ?>";
$state['display'][] = Indent::_(2) . '<div class="' . $state['rowClass'] . '">';
}
/**
* Append the standard dashboard start markup.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendStandardDashboardStart(array &$state): void
{
$state['display'][] = '<div id="j-main-container">';
$state['display'][] = Indent::_(1) . '<div class="' . $state['formClass'] . '" style="padding: 20px;">';
$state['display'][] = Indent::_(2) . '<div class="' . $state['rowClass'] . '">';
}
/**
* Append the main dashboard columns.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendMainDashboardColumns(array &$state): void
{
$this->appendLeftDashboardColumn($state);
$this->appendRightDashboardColumn($state);
}
/**
* Append the left dashboard column.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendLeftDashboardColumn(array &$state): void
{
$state['display'][] = $state['tab'] . '<div class="' . $state['widthClass'] . '9">';
$state['display'][] = $state['tab'] . Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.startAccordion', 'dashboard_left', array('active' => 'main')); ?>";
$state['display'][] = $state['tab'] . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.addSlide', 'dashboard_left', '"
. $state['mainAccordionName'] . "', 'main'); ?>";
$state['display'][] = $state['tab'] . Indent::_(3)
. "<?php echo \$this->loadTemplate('main');?>";
$state['display'][] = $state['tab'] . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.endSlide'); ?>";
$state['display'][] = $state['tab'] . Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.endAccordion'); ?>";
$state['display'][] = $state['tab'] . '</div>';
}
/**
* Append the right dashboard column.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendRightDashboardColumn(array &$state): void
{
$companyName = $this->contentone->get('COMPANYNAME');
$state['display'][] = $state['tab'] . '<div class="' . $state['widthClass'] . '3">';
$state['display'][] = $state['tab'] . Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.startAccordion', 'dashboard_right', array('active' => 'vdm')); ?>";
$state['display'][] = $state['tab'] . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.addSlide', 'dashboard_right', '"
. $companyName . "', 'vdm'); ?>";
$state['display'][] = $state['tab'] . Indent::_(3)
. "<?php echo \$this->loadTemplate('vdm');?>";
$state['display'][] = $state['tab'] . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.endSlide'); ?>";
$state['display'][] = $state['tab'] . Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.endAccordion'); ?>";
$state['display'][] = $state['tab'] . '</div>';
}
/**
* Append all custom dashboard tabs.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendCustomTabs(array &$state): void
{
$state['display'][] = Indent::_(2) . '</div>';
$state['display'][] = Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.endTab'); ?>";
foreach ($state['builder'] as $tabName => $accordions)
{
$this->appendCustomTab($state, $tabName, $accordions);
}
}
/**
* Append a single custom dashboard tab.
*
* @param array &$state The dashboard display state.
* @param string $tabName The tab name.
* @param array $accordions The accordion definitions.
*
* @return void
*
* @since 5.1.5
*/
protected function appendCustomTab(array &$state, string $tabName, array $accordions): void
{
$alias = StringHelper::safe($tabName);
$state['display'][] = PHP_EOL . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.addTab', 'cpanel_tab', '"
. $alias . "', Joomla__" . "_ba6326ef_cb79_4348_80f4_ab086082e3c5___Power::_('"
. $tabName . "', true)); ?>";
$state['display'][] = Indent::_(2) . '<div class="' . $state['rowClass'] . '">';
$state['display'][] = $state['tab'] . '<div class="' . $state['widthClass'] . '12">';
$state['display'][] = $state['tab'] . Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.startAccordion', '"
. $alias . "_accordian', array('active' => '" . $alias . "_one')); ?>";
$this->appendCustomTabSlides($state, $tabName, $alias, $accordions);
$state['display'][] = $state['tab'] . Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.endAccordion'); ?>";
$state['display'][] = $state['tab'] . '</div>';
$state['display'][] = Indent::_(2) . '</div>';
$state['display'][] = Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.endTab'); ?>";
}
/**
* Append all slides for a custom dashboard tab.
*
* @param array &$state The dashboard display state.
* @param string $tabName The tab name.
* @param string $alias The tab alias.
* @param array $accordions The accordion definitions.
*
* @return void
*
* @since 5.1.5
*/
protected function appendCustomTabSlides(array &$state, string $tabName, string $alias, array $accordions): void
{
$slideCounter = 1;
foreach ($accordions as $accordionName => $html)
{
$this->appendCustomTabSlide(
$state,
$tabName,
$alias,
$accordionName,
$html,
$slideCounter
);
$slideCounter++;
}
}
/**
* Append a single custom dashboard tab slide.
*
* @param array &$state The dashboard display state.
* @param string $tabName The tab name.
* @param string $alias The tab alias.
* @param string $accordionName The accordion name.
* @param string $html The slide HTML.
* @param int $slideCounter The slide counter.
*
* @return void
*
* @since 5.1.5
*/
protected function appendCustomTabSlide(
array &$state,
string $tabName,
string $alias,
string $accordionName,
string $html,
int $slideCounter
): void
{
$accordionAlias = StringHelper::safe($accordionName);
$counterName = StringHelper::safe($slideCounter);
$templateName = $alias . '_' . $accordionAlias;
$state['display'][] = $state['tab'] . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.addSlide', '"
. $alias . "_accordian', '" . $accordionName . "', '"
. $alias . "_" . $counterName . "'); ?>";
$state['display'][] = $state['tab'] . Indent::_(3)
. "<?php echo \$this->loadTemplate('" . $templateName . "');?>";
$state['display'][] = $state['tab'] . Indent::_(2)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('bootstrap.endSlide'); ?>";
$this->buildCustomDashboardTemplate($templateName, $html);
}
/**
* Build a custom dashboard template file and register its content.
*
* @param string $templateName The template name.
* @param string $html The template body HTML.
*
* @return void
*
* @since 5.1.5
*/
protected function buildCustomDashboardTemplate(string $templateName, string $html): void
{
$componentCodeName = $this->config->component_code_name;
$target = ['custom_admin' => $componentCodeName];
$this->structure->build($target, 'template', $templateName);
$this->contentmulti->set(
$componentCodeName . '_' . $templateName . '|CUSTOM_ADMIN_TEMPLATE_BODY',
PHP_EOL . $html
);
$this->contentmulti->set(
$componentCodeName . '_' . $templateName . '|CUSTOM_ADMIN_TEMPLATE_CODE_BODY',
''
);
}
/**
* Append the end of the tab set.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendTabSetEnd(array &$state): void
{
$state['display'][] = PHP_EOL . Indent::_(1)
. "<?php echo Joomla__" . "_34690c75_1090_47eb_8c06_7228dc7eedd6___Power::_('{$state['uiTab']}.endTabSet'); ?>";
}
/**
* Append the end of the standard row layout.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendStandardRowEnd(array &$state): void
{
$state['display'][] = Indent::_(2) . '</div>';
}
/**
* Append the closing dashboard container markup.
*
* @param array &$state The dashboard display state.
*
* @return void
*
* @since 5.1.5
*/
protected function appendDashboardContainerEnd(array &$state): void
{
$state['display'][] = Indent::_(1) . '</div>';
$state['display'][] = '</div>';
}
}
@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>
@@ -49,6 +49,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitectureComponent;
use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitectureModel;
use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitectureView;
use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitectureController;
use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitectureDashboard;
use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitectureModule;
use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitecturePlugin;
use VDM\Joomla\Componentbuilder\Power\Service\Git;
@@ -180,6 +181,7 @@ abstract class Factory extends ExtendingFactory implements FactoryInterface
->registerServiceProvider(new ArchitectureModel())
->registerServiceProvider(new ArchitectureView())
->registerServiceProvider(new ArchitectureController())
->registerServiceProvider(new ArchitectureDashboard())
->registerServiceProvider(new ArchitectureModule())
->registerServiceProvider(new ArchitecturePlugin())
->registerServiceProvider(new Git())
@@ -1661,7 +1661,7 @@ class Infusion extends Interpretation
// DASH_DISPLAY_DATA
CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASH_DISPLAY_DATA',
$this->setDashboardDisplayData()
CFactory::_('Architecture.Dashboard.View')->get()
);
// DASH_VIEW_HEADER
@@ -2551,20 +2551,31 @@ class Interpretation extends Fields
$view['settings']->css_document
))
{
$script = PHP_EOL . Indent::_(2) . "//" . Line::_(
if (CFactory::_('Config')->get('joomla_version', 3) == 3)
{
$script = PHP_EOL . Indent::_(2) . "//" . Line::_(
__LINE__,__CLASS__
) . " Set the Custom CSS script to view" . PHP_EOL
. Indent::_(2) . '$this->document->addStyleDeclaration("';
) . " Set the Custom CSS script to view" . PHP_EOL
. Indent::_(2) . '$this->document->addStyleDeclaration("';
}
else
{
$script = PHP_EOL . Indent::_(2) . "//" . Line::_(
__LINE__,__CLASS__
) . " Set the Custom JS script to view" . PHP_EOL
. Indent::_(2) . '$this->getDocument()->getWebAssetManager()->addInlineStyle("';
}
$cssDocument = PHP_EOL . Indent::_(3) . str_replace(
'"', '\"', implode(
PHP_EOL . Indent::_(3),
$view['settings']->css_document
)
);
'"', '\"', implode(
PHP_EOL . Indent::_(3),
$view['settings']->css_document
)
);
return $script . CFactory::_('Placeholder')->update_(
$cssDocument
) . PHP_EOL . Indent::_(2) . '");';
$cssDocument
) . PHP_EOL . Indent::_(2) . '");';
}
}
@@ -3507,10 +3518,19 @@ class Interpretation extends Fields
// top
if ('site' === CFactory::_('Config')->build_target)
{
return '<form action="<?php echo Joomla__'.'_d4c76099_4c32_408a_8701_d0a724484dfd___Power::_(\'index.php?option=com_'
. CFactory::_('Config')->component_code_name
. '\'); ?>" method="post" name="adminForm" id="adminForm">'
. PHP_EOL;
if (CFactory::_('Config')->get('joomla_version', 3) >= 6)
{
return '<form action="<?php echo Joomla__'.'_d4c76099_4c32_408a_8701_d0a724484dfd___Power::_(\'index.php'
. '\'); ?>" method="post" name="adminForm" id="adminForm">'
. PHP_EOL; // yes we only need index.php
}
else
{
return '<form action="<?php echo Joomla__'.'_d4c76099_4c32_408a_8701_d0a724484dfd___Power::_(\'index.php?option=com_'
. CFactory::_('Config')->component_code_name
. '\'); ?>" method="post" name="adminForm" id="adminForm">'
. PHP_EOL;
}
}
else
{
@@ -8121,7 +8141,7 @@ class Interpretation extends Fields
// set the item default class
$itemClass = 'hidden-phone';
// set the item row
$itemRow = $this->getListItemBuilder(
$itemRow = CFactory::_('Architecture.AdminViews.ListItemBuilder')->get(
$item, $nameSingleCode, $nameListCode, $itemClass, $doNotEscape
);
// check if buttons was already added
@@ -8194,263 +8214,18 @@ class Interpretation extends Fields
}
/**
* Get the list item dynamic row
* Get the list field class
*
* @param array $item The item array
* @param string $nameSingleCode The single view code name
* @param string $nameListCode The list view code name
* @param string $itemClass The table row default class
* @param bool $doNotEscape The do not escape global switch
* @param bool $class The dive class adding switch
* @param string $ref The link referral string
* @param string $classPointer The class pointer (this or displaydata)
* @param string $user The user code name
* @param string $refview The override of the referral view code name
* @param string $name The field code name
* @param string $nameListCode The list view code name
* @param string $default The default
*
* @return string of the completer item value for the table row
* @return string The list field class
*
*/
protected function getListItemBuilder($item, $nameSingleCode,
$nameListCode, &$itemClass, $doNotEscape,
$class = true, $ref = null, $classPointer = '$this->',
$user = '$this->user', $refview = null
)
protected function getListFieldClass($name, $nameListCode, $default = '')
{
// check if we have relation fields
if (($field_relations =
CFactory::_('Compiler.Builder.Field.Relations')->get($nameListCode . '.' . (string) $item['guid'] . '.2')) !== null)
{
// set the fields array
$field = [];
// use custom code
$useCustomCode
= (isset($field_relations['join_type'])
&& $field_relations['join_type']
== 2
&& isset($field_relations['set'])
&& StringHelper::check(
$field_relations['set']
));
// load the main list view field
$field_list_item = $this->getListItem(
$item, $nameSingleCode, $nameListCode, $itemClass,
$doNotEscape, false, $ref, $classPointer, $user,
$refview
);
$field['[field=' . (int) $item['id'] . ']'] = $field_list_item;
$field['[field=' . (string) $item['guid'] . ']'] = $field_list_item;
// code name
if (isset($item['code']))
{
$field['$item->{' . (int) $item['id'] . '}'] = '$item->' . $item['code'];
$field['$item->{' . (string) $item['guid'] . '}'] = '$item->' . $item['code'];
}
// now load the relations
if (isset($field_relations['joinfields'])
&& ArrayHelper::check($field_relations['joinfields']))
{
foreach ($field_relations['joinfields'] as $join)
{
$blankClass = '';
if (($join_item =
CFactory::_('Compiler.Builder.List.Join')->get($nameListCode . '.' . (string) $join)) !== null && is_array($join_item))
{
$join_id = CFactory::_('Compiler.Builder.List.Join')->get($nameListCode . '.' . (string) $join . '.id', 0);
// code block
$join_field_list_item = $this->getListItem(
$join_item, $nameSingleCode, $nameListCode, $blankClass,
$doNotEscape, false, $ref,
$classPointer, $user, $refview
);
$field['[field=' . (int) $join_id . ']'] = $join_field_list_item;
$field['[field=' . (string) $join . ']'] = $join_field_list_item;
// code name
if (isset($join_item['code']))
{
$field['$item->{' . (int) $join_id . '}'] = '$item->' . $join_item['code'];
$field['$item->{' . (string) $join . '}'] = '$item->' . $join_item['code'];
}
}
}
}
// join based on join type
if ($useCustomCode)
{
// custom code
return PHP_EOL . Indent::_(3) . "<div>"
. CFactory::_('Placeholder')->update_(
str_replace(
array_keys($field), array_values($field),
(string) $field_relations['set']
)
) . PHP_EOL . Indent::_(3) . "</div>";
}
elseif (isset($field_relations['set'])
&& StringHelper::check(
$field_relations['set']
))
{
// concatenate
return PHP_EOL . Indent::_(3) . "<div>" . implode(
$field_relations['set'],
$field
) . PHP_EOL . Indent::_(3) . "</div>";
}
// default
return PHP_EOL . Indent::_(3) . "<div>" . implode('', $field)
. PHP_EOL . Indent::_(3) . "</div>";
}
return $this->getListItem(
$item, $nameSingleCode, $nameListCode, $itemClass, $doNotEscape,
$class, $ref, $classPointer, $user, $refview
);
}
/**
* Get the list item row value
*
* @param array $item The item array
* @param string $nameSingleCode The single view code name
* @param string $nameListCode The list view code name
* @param string $itemClass The table row default class
* @param bool $doNotEscape The do not escape global switch
* @param bool $class The dive class adding switch
* @param string $ref The link referral string
* @param string $classPointer The class pointer
* @param string $user The user code name
* @param string $refview The override of the referral view code name
*
* @return string of the single item value for the table row
*
*/
protected function getListItem($item, $nameSingleCode, $nameListCode,
&$itemClass, $doNotEscape, $class = true, $ref = null,
$classPointer = '$this->', $user = '$this->user', $refview = null)
{
// get list item code
$itemCode = $this->getListItemCode(
$item, $nameListCode, $doNotEscape, $classPointer
);
// add default links
$defaultLink = true;
if (StringHelper::check($refview) && isset($item['custom'])
&& isset($item['custom']['view']) && $refview === $item['custom']['view'])
{
$defaultLink = false;
}
// is this a linked item
$extends_field = $item['custom']['extends'] ?? '';
if (($item['link'] || $extends_field === 'user') && $defaultLink)
{
// set some defaults
$checkoutTriger = false;
// set the item default class
$itemClass = 'nowrap';
// get list item link
$itemLink = $this->getListItemLink(
$item, $checkoutTriger, $nameSingleCode, $nameListCode, $ref
);
// get list item link authority
$itemLinkAuthority = $this->getListItemLinkAuthority(
$item, $nameSingleCode, $nameListCode, $classPointer, $user
);
// set item row
return $this->getListItemLinkLogic(
$item, $itemCode, $itemLink, $itemLinkAuthority, $nameSingleCode,
$nameListCode, $classPointer, $checkoutTriger, $class
);
}
// return the default (no link)
return PHP_EOL . Indent::_(3) . "<?php echo " . $itemCode . "; ?>";
}
/**
* Get the list item link logic
*
* @param array $item The item
* @param string $itemCode The item code string
* @param string $itemLink The item link string
* @param string $itemLinkAuthority The link authority string
* @param string $nameSingleCode The single view code name
* @param string $nameListCode The list view code name
* @param bool $checkoutTriger The check out trigger
* @param string $classPointer The class pointer
* @param bool $class The dive class adding switch
*
* @return string of the complete link logic of row item
*
*/
protected function getListItemLinkLogic($item, $itemCode, $itemLink,
$itemLinkAuthority, $nameSingleCode, $nameListCode, $classPointer, $checkoutTriger, $class = true)
{
// set some local values
$code = $item['code'];
// build link
$link = '';
// add class
$tab = '';
if ($class)
{
$link .= PHP_EOL . Indent::_(3) . '<div class="name">';
$tab = Indent::_(1);
}
// the link logic
$link .= PHP_EOL . $tab . Indent::_(3) . "<?php if ("
. $itemLinkAuthority . "): ?>";
$link .= PHP_EOL . $tab . Indent::_(4) . '<a href="' . $itemLink
. '"><?php echo ' . $itemCode . '; ?></a>';
$addModalFix = false;
if ($checkoutTriger)
{
$link .= PHP_EOL . $tab . Indent::_(4)
. "<?php if (\$item->checked_out): ?>";
$link .= PHP_EOL . $tab . Indent::_(5)
. "<?php echo Html::_('jgrid.checkedout', \$i, \$userChkOut->name, \$item->checked_out_time, '"
. $nameListCode . ".', \$canCheckin); ?>";
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php endif; ?>";
if (CFactory::_('Config')->get('joomla_version', 3) !== 3)
{
$addModalFix = true;
}
}
$link .= PHP_EOL . $tab . Indent::_(3) . "<?php else: ?>";
if ($addModalFix)
{
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php if (!{$classPointer}isModal): ?>";
$link .= PHP_EOL . $tab . Indent::_(5) . "<?php echo " . $itemCode . "; ?>";
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php else: ?>";
$link .= PHP_EOL . $tab . Indent::_(5) . "<?php";
$link .= PHP_EOL . $tab . Indent::_(6) . "\$link = \"{\$edit}&id={\$item->id}\";";
$link .= PHP_EOL . $tab . Indent::_(6) . "\$dataId = \$item->{{$classPointer}getModalTitleKey()} ?? 0;";
$link .= PHP_EOL . $tab . Indent::_(6) . "\$itemHtml = '<a href=\"' . {$classPointer}escape(\$link, false) . '\">' . {$classPointer}escape(\$item->{$code}, false) . '</a>';";
$link .= PHP_EOL . $tab . Indent::_(6) . "\$attribs = 'data-content-select data-content-type=\"com_" . CFactory::_('Config')->component_code_name . ".". $nameSingleCode . "\"'";
$link .= PHP_EOL . $tab . Indent::_(7) . ". ' data-id=\"' . \$dataId . '\"'";
$link .= PHP_EOL . $tab . Indent::_(7) . ". ' data-title=\"' . {$classPointer}escape(\$item->{$code}, false) . '\"'";
$link .= PHP_EOL . $tab . Indent::_(7) . ". ' data-uri=\"' . {$classPointer}escape(\$link, false) . '\"'";
$link .= PHP_EOL . $tab . Indent::_(7) . ". ' data-html=\"' . {$classPointer}escape(\$itemHtml, false) . '\"';";
$link .= PHP_EOL . $tab . Indent::_(5) . "?>";
$link .= PHP_EOL . $tab . Indent::_(5) . "<a class=\"select-link\" href=\"javascript:void(0)\" <?php echo \$attribs; ?>>";
$link .= PHP_EOL . $tab . Indent::_(6) . "<?php echo " . $itemCode . "; ?>";
$link .= PHP_EOL . $tab . Indent::_(5) . "</a>";
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php endif; ?>";
}
else
{
$link .= PHP_EOL . $tab . Indent::_(4) . "<?php echo " . $itemCode . "; ?>";
}
$link .= PHP_EOL . $tab . Indent::_(3) . "<?php endif; ?>";
// add class
if ($class)
{
$link .= PHP_EOL . Indent::_(3) . "</div>";
}
// return the link logic
return $link;
return CFactory::_('Compiler.Builder.List.Field.Class')->get($nameListCode . '.' . $name, $default);
}
/**
@@ -8506,276 +8281,6 @@ class Interpretation extends Fields
return $customAdminViewButton;
}
/**
* Get the list item code value
*
* @param array $item The item array
* @param string $nameListCode The list view code name
* @param bool $doNotEscape The do not escape global switch
* @param string $classPointer The class pointer
*
* @return string of the single item code
*
*/
protected function getListItemCode(&$item, $nameListCode, $doNotEscape, $classPointer = '$this->')
{
// first update the code id needed
if (isset($item['custom'])
&& ArrayHelper::check(
$item['custom']
)
&& isset($item['custom']['table'])
&& StringHelper::check($item['custom']['table']))
{
$item['id_code'] = $item['code'];
if (!$item['multiple'])
{
$item['code'] = $item['code'] . '_' . $item['custom']['text'];
}
}
// set the extends value
$extends_field = $item['custom']['extends'] ?? '';
$extends_text = $item['custom']['text'] ?? '';
// check if category
if ($item['type'] === 'category' && !$item['title'])
{
return $classPointer . 'escape($item->category_title)';
}
// check if user
elseif ($item['type'] === 'user')
{
if (CFactory::_('Config')->get('joomla_version', 3) == 3)
{
return 'Joomla__'.'_39403062_84fb_46e0_bac4_0023f766e827___Power::getUser((int)$item->' . $item['code'] . ')->name';
}
else
{
return 'Joomla__'.'_39403062_84fb_46e0_bac4_0023f766e827___Power::getContainer()->'
. 'get(Joomla__'.'_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power::class)->'
. 'loadUserById((int) ($item->' . $item['code'] . ' ?? 0))->name';
}
}
// check if custom user
elseif (isset($item['custom'])
&& ArrayHelper::check($item['custom'])
&& $extends_field === 'user'
&& isset($item['id_code']))
{
if (CFactory::_('Config')->get('joomla_version', 3) == 3)
{
return 'Joomla__'.'_39403062_84fb_46e0_bac4_0023f766e827___Power::getUser((int)$item->' . $item['id_code'] . ')->name';
}
else
{
return 'Joomla__'.'_39403062_84fb_46e0_bac4_0023f766e827___Power::getContainer()->'
. 'get(Joomla__'.'_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power::class)->'
. 'loadUserById((int) ($item->' . $item['id_code'] . ' ?? 0))->name';
}
}
// check if translated value is used
elseif (CFactory::_('Compiler.Builder.Selection.Translation')->
exists($nameListCode . '.' . $item['code']))
{
return 'Joomla__'.'_ba6326ef_cb79_4348_80f4_ab086082e3c5___Power::_($item->' . $item['code'] . ')';
}
elseif (isset($item['custom'])
&& ArrayHelper::check($item['custom'])
&& ($extends_text === 'user' || $extends_field === 'user'))
{
if (CFactory::_('Config')->get('joomla_version', 3) == 3)
{
return 'Joomla__'.'_39403062_84fb_46e0_bac4_0023f766e827___Power::getUser((int)$item->' . $item['code'] . ')->name';
}
else
{
return 'Joomla__'.'_39403062_84fb_46e0_bac4_0023f766e827___Power::getContainer()->'
. 'get(Joomla__'.'_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power::class)->'
. 'loadUserById((int) ($item->' . $item['code'] . ' ?? 0))->name';
}
}
elseif ($doNotEscape)
{
if (CFactory::_('Compiler.Builder.Do.Not.Escape')->exists($nameListCode . '.' . $item['code']))
{
return '$item->' . $item['code'];
}
}
// default
return $classPointer . 'escape($item->' . $item['code'] . ')';
}
/**
* Get the list item link
*
* @param array $item The item array
* @param bool $checkoutTriger The checkout trigger switch
* @param string $nameSingleCode The single view code name
* @param string $nameListCode The list view code name
* @param string $ref The link referral string
*
* @return string of the single item link
*
*/
protected function getListItemLink($item, &$checkoutTriger,
$nameSingleCode, $nameListCode, $ref = null)
{
// set referal if not set
$referal = '';
if (!$ref)
{
$ref = '&return=<?php echo $this->return_here; ?>';
}
// in linked tab/view so must add ref to default
else
{
$referal = $ref;
}
// if to be linked
if ($item['type'] === 'category' && !$item['title'])
{
// return the link to category
return 'index.php?option=com_categories&task=category.edit&id=<?php echo (int)$item->'
. $item['code'] . '; ?>&extension='
. CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.extension", 'error');
}
elseif ($item['type'] === 'user' && !$item['title'])
{
// return user link
return 'index.php?option=com_users&task=user.edit&id=<?php echo (int) $item->'
. $item['code'] . ' ?>';
}
elseif (isset($item['custom'])
&& ArrayHelper::check(
$item['custom']
)
&& $item['custom']['extends'] != 'user'
&& !$item['title']
&& isset($item['id_code']))
{
// build GUID link
if (isset($item['custom']['id']) && $item['custom']['id'] !== 'id')
{
// link to that linked item
return 'index.php?option=' . $item['custom']['component'] . '&view='
. $item['custom']['views'] . '&task=' . $item['custom']['view']
. '.edit&id=<?php echo $item->' . $item['id_code'] . '_id; ?>'
. $ref;
}
// link to that linked item
return 'index.php?option=' . $item['custom']['component'] . '&view='
. $item['custom']['views'] . '&task=' . $item['custom']['view']
. '.edit&id=<?php echo $item->' . $item['id_code'] . '; ?>'
. $ref;
}
elseif (isset($item['custom'])
&& ArrayHelper::check(
$item['custom']
)
&& $item['custom']['extends'] === 'user'
&& !$item['title']
&& isset($item['id_code']))
{
// return user link
return 'index.php?option=com_users&task=user.edit&id=<?php echo (int) $item->'
. $item['id_code'] . ' ?>';
}
// make sure to triger the checkout
$checkoutTriger = true;
// basic default item link
return '<?php echo $edit; ?>&id=<?php echo $item->id; ?>' . $referal;
}
/**
* Get the list item authority
*
* @param array $item The item array
* @param string $nameSingleCode The single view code name
* @param string $nameListCode The list view code name
* @param string $classPointer The class pointer
* @param string $user The user code name
*
* @return string of the single item link authority
*
*/
protected function getListItemLinkAuthority($item, $nameSingleCode, $nameListCode, $classPointer= '$this->', $user = '$this->user')
{
// add modal fix
$isModal = '';
if (CFactory::_('Config')->get('joomla_version', 3) !== 3)
{
$isModal = "!{$classPointer}isModal && ";
}
// if to be linked
if ($item['type'] === 'category' && !$item['title'])
{
// get the other view
$otherView = CFactory::_('Compiler.Builder.Category.Code')->getString("{$nameSingleCode}.view", 'error');
// return the authority to category
return $isModal . $user . "->authorise('core.edit', 'com_"
. CFactory::_('Config')->component_code_name . "." . $otherView
. ".category.' . (int) (\$item->" . $item['code'] . " ?? 0))";
}
elseif ($item['type'] === 'user' && !$item['title'])
{
// return user authority
return $isModal . $user . "->authorise('core.edit', 'com_users')";
}
elseif (isset($item['custom'])
&& ArrayHelper::check(
$item['custom']
)
&& $item['custom']['extends'] != 'user'
&& !$item['title']
&& isset($item['id_code']))
{
// do this with GUID
if (isset($item['custom']['id']) && $item['custom']['id'] !== 'id')
{
return $isModal . $user . "->authorise('" . CFactory::_('Compiler.Creator.Permission')->getAction($item['custom']['view'], 'core.edit')
. "', 'com_" . CFactory::_('Config')->component_code_name . "."
. $item['custom']['view'] . ".' . (int) (\$item->" . $item['id_code'] . "_id ?? 0))";
}
else
{
return $isModal . $user . "->authorise('" . CFactory::_('Compiler.Creator.Permission')->getAction($item['custom']['view'], 'core.edit')
. "', 'com_" . CFactory::_('Config')->component_code_name . "."
. $item['custom']['view'] . ".' . (int) (\$item->" . $item['id_code'] . " ?? 0))";
}
}
elseif (isset($item['custom'])
&& ArrayHelper::check(
$item['custom']
)
&& $item['custom']['extends'] === 'user'
&& !$item['title']
&& isset($item['id_code']))
{
// return user link
return $isModal . $user . "->authorise('core.edit', 'com_users')";
}
// set core permissions.
return $isModal . "\$canDo->get('" . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.edit') . "')";
}
/**
* Get the list field class
*
* @param string $name The field code name
* @param string $nameListCode The list view code name
* @param string $default The default
*
* @return string The list field class
*
*/
protected function getListFieldClass($name, $nameListCode, $default = '')
{
return CFactory::_('Compiler.Builder.List.Field.Class')->get($nameListCode . '.' . $name, $default);
}
/**
* set the default views body
*
@@ -9346,7 +8851,7 @@ class Interpretation extends Fields
foreach ($tabBucket as $tabCodeName => $positions)
{
// get lang string
$tabLangName = $positions['lang'];
$tabLangName = $positions['lang'] ?? 'error_missing_lang';
// build main center position
$main = '';
$mainbottom = '';
@@ -10831,6 +10336,7 @@ class Interpretation extends Fields
// make sure the custom links are only added once
$firstTimeBeingAdded = true;
$counter = 0;
$itemClass = '';
// add the default
$body = PHP_EOL . "<tbody>";
$body .= PHP_EOL . "<?php foreach (\$items as \$i => \$item): ?>";
@@ -10871,7 +10377,7 @@ class Interpretation extends Fields
// set some defaults
$customAdminViewButtons = '';
// set the item row
$itemRow = $this->getListItemBuilder(
$itemRow = CFactory::_('Architecture.AdminViews.ListItemBuilder')->get(
$item, $nameSingleCode, $nameListCode, $itemClass,
$doNotEscape, false, $ref,
'$displayData->', '$user', $refview
@@ -16871,7 +16377,7 @@ class Interpretation extends Fields
{
foreach ($fields as $area => $field)
{
if ($area == 1 && isset($field['code']))
if ((int) $area === 1 && !empty($field['code']))
{
$fix .= $this->setModelFieldRelation(
$field, $nameListCode, $tab
@@ -17226,7 +16732,7 @@ class Interpretation extends Fields
{
foreach ($fields as $area => $field)
{
if ($area == 3 && isset($field['code']))
if ((int) $area === 3 && !empty($field['code']))
{
$fix .= $this->setModelFieldRelation(
$field, $nameListCode, $tab
@@ -17453,11 +16959,12 @@ class Interpretation extends Fields
{
$fix = '';
// set fields
$field = [];
$field_placeholders = [];
// set list field name
$field['$item->{' . (int) $item['id'] . '}'] = '$item->' . $item['code'];
$field['$item->{' . (string) $item['guid'] . '}'] = '$item->' . $item['code'];
$field_placeholders['$item->{' . (int) $item['id'] . '}'] = '$item->' . $item['code'];
$field_placeholders['$item->{' . (string) $item['guid'] . '}'] = '$item->' . $item['code'];
$field_array[] = '$item->' . $item['code'];
// load joint field names
if (isset($item['joinfields'])
@@ -17470,18 +16977,19 @@ class Interpretation extends Fields
$join_id = CFactory::_('Compiler.Builder.List.Join')->get($nameListCode . '.' . (string) $join . '.id', 0);
$join_string = '$item->' . CFactory::_('Compiler.Builder.List.Join')->get($nameListCode . '.' . (string) $join . '.code', 'error');
$field['$item->{' . (int) $join_id . '}'] = $join_string;
$field['$item->{' . $join . '}'] = $join_string;
$field_placeholders['$item->{' . (int) $join_id . '}'] = $join_string;
$field_placeholders['$item->{' . $join . '}'] = $join_string;
$field_array[] = $join_string;
}
}
// set based on join_type
if ($item['join_type'] == 2)
if ((int) $item['join_type'] === 2)
{
// code
$code = (array) explode(
PHP_EOL, str_replace(
array_keys($field), array_values($field), (string) $item['set']
array_keys($field_placeholders), array_values($field_placeholders), (string) $item['set']
)
);
$fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . implode(
@@ -17496,7 +17004,7 @@ class Interpretation extends Fields
$fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$item->"
. $item['code'] . ' = ' . implode(
" . '" . str_replace("'", '&apos;', (string) $item['set']) . "' . ",
$field
$field_array
) . ';';
}
@@ -17905,274 +17413,6 @@ class Interpretation extends Fields
return '';
}
public function setDashboardDisplayData()
{
if (CFactory::_('Config')->get('joomla_version', 3) == 3)
{
return $this->setDashboardDisplayDataJ3();
}
return $this->setDashboardDisplayDataJ4();
}
public function setDashboardDisplayDataJ3()
{
// display array reset
$display = [];
$mainAccordianName = 'cPanel';
$builder = [];
$tab = Indent::_(3);
$loadTabs = false;
$width_class = 'span';
$row_class = 'row-fluid';
$form_class = 'form-horizontal';
$uitab = 'bootstrap';
// check if we have custom tabs
if (CFactory::_('Component')->isArray('dashboard_tab'))
{
// build the tabs and accordians
foreach (CFactory::_('Component')->get('dashboard_tab') as $data)
{
$builder[$data['name']][$data['header']]
= CFactory::_('Placeholder')->update_(
$data['html']
);
}
// since we have custom tabs we must load the tab structure around the cpanel
$display[] = '<div id="j-main-container">';
$display[] = Indent::_(1) . '<div class="' . $form_class . '">';
$display[] = Indent::_(1)
. "<?php echo Html::_('{$uitab}.startTabSet', 'cpanel_tab', array('active' => 'cpanel')); ?>";
$display[] = PHP_EOL . Indent::_(2)
. "<?php echo Html::_('{$uitab}.addTab', 'cpanel_tab', 'cpanel', Text:"
. ":_('cPanel', true)); ?>";
$display[] = Indent::_(2) . '<div class="' . $row_class . '">';
// change the name of the main tab
$mainAccordianName = 'Control Panel';
$loadTabs = true;
}
else
{
$display[] = '<div id="j-main-container">';
$display[] = Indent::_(1) . '<div class="' . $form_class . '" style="padding: 20px;">';
$display[] = Indent::_(2) . '<div class="' . $row_class . '">';
}
// set dashboard display
$display[] = $tab . '<div class="' . $width_class . '9">';
$display[] = $tab . Indent::_(1)
. "<?php echo Html::_('bootstrap.startAccordion', 'dashboard_left', array('active' => 'main')); ?>";
$display[] = $tab . Indent::_(2)
. "<?php echo Html::_('bootstrap.addSlide', 'dashboard_left', '"
. $mainAccordianName . "', 'main'); ?>";
$display[] = $tab . Indent::_(3)
. "<?php echo \$this->loadTemplate('main');?>";
$display[] = $tab . Indent::_(2)
. "<?php echo Html::_('bootstrap.endSlide'); ?>";
$display[] = $tab . Indent::_(1)
. "<?php echo Html::_('bootstrap.endAccordion'); ?>";
$display[] = $tab . "</div>";
$display[] = $tab . '<div class="' . $width_class . '3">';
$display[] = $tab . Indent::_(1)
. "<?php echo Html::_('bootstrap.startAccordion', 'dashboard_right', array('active' => 'vdm')); ?>";
$display[] = $tab . Indent::_(2)
. "<?php echo Html::_('bootstrap.addSlide', 'dashboard_right', '"
. CFactory::_('Compiler.Builder.Content.One')->get('COMPANYNAME')
. "', 'vdm'); ?>";
$display[] = $tab . Indent::_(3)
. "<?php echo \$this->loadTemplate('vdm');?>";
$display[] = $tab . Indent::_(2)
. "<?php echo Html::_('bootstrap.endSlide'); ?>";
$display[] = $tab . Indent::_(1)
. "<?php echo Html::_('bootstrap.endAccordion'); ?>";
$display[] = $tab . "</div>";
if ($loadTabs)
{
$display[] = Indent::_(2) . "</div>";
$display[] = Indent::_(2)
. "<?php echo Html::_('{$uitab}.endTab'); ?>";
// load the new tabs
foreach ($builder as $tabname => $accordians)
{
$alias = StringHelper::safe($tabname);
$display[] = PHP_EOL . Indent::_(2)
. "<?php echo Html::_('{$uitab}.addTab', 'cpanel_tab', '"
. $alias . "', Joomla__"."_ba6326ef_cb79_4348_80f4_ab086082e3c5___Power::_('" . $tabname
. "', true)); ?>";
$display[] = Indent::_(2) . '<div class="' . $row_class . '">';
$display[] = $tab . '<div class="' . $width_class . '12">';
$display[] = $tab . Indent::_(1)
. "<?php echo Html::_('bootstrap.startAccordion', '"
. $alias . "_accordian', array('active' => '" . $alias
. "_one')); ?>";
$slidecounter = 1;
foreach ($accordians as $accordianname => $html)
{
$ac_alias = StringHelper::safe(
$accordianname
);
$counterName = StringHelper::safe(
$slidecounter
);
$tempName = $alias . '_' . $ac_alias;
$display[] = $tab . Indent::_(2)
. "<?php echo Html::_('bootstrap.addSlide', '"
. $alias . "_accordian', '" . $accordianname . "', '"
. $alias . "_" . $counterName . "'); ?>";
$display[] = $tab . Indent::_(3)
. "<?php echo \$this->loadTemplate('" . $tempName
. "');?>";
$display[] = $tab . Indent::_(2)
. "<?php echo Html::_('bootstrap.endSlide'); ?>";
$slidecounter++;
// build the template file
$target = array('custom_admin' => CFactory::_('Config')->component_code_name);
CFactory::_('Utilities.Structure')->build($target, 'template', $tempName);
// set the file data
$TARGET = StringHelper::safe(
CFactory::_('Config')->build_target, 'U'
);
// CUSTOM_ADMIN_TEMPLATE_BODY <<<DYNAMIC>>>
CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '_' . $tempName . '|CUSTOM_ADMIN_TEMPLATE_BODY', PHP_EOL . $html);
// CUSTOM_ADMIN_TEMPLATE_CODE_BODY <<<DYNAMIC>>>
CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '_' . $tempName . '|CUSTOM_ADMIN_TEMPLATE_CODE_BODY', '');
}
$display[] = $tab . Indent::_(1)
. "<?php echo Html::_('bootstrap.endAccordion'); ?>";
$display[] = $tab . "</div>";
$display[] = Indent::_(2) . "</div>";
$display[] = Indent::_(2)
. "<?php echo Html::_('{$uitab}.endTab'); ?>";
}
$display[] = PHP_EOL . Indent::_(1)
. "<?php echo Html::_('{$uitab}.endTabSet'); ?>";
}
else
{
$display[] = Indent::_(2) . "</div>";
}
$display[] = Indent::_(1) . "</div>";
$display[] = "</div>";
// return the display
return PHP_EOL . implode(PHP_EOL, $display);
}
public function setDashboardDisplayDataJ4()
{
// display array reset
$display = [];
$mainAccordianName = 'cPanel';
$builder = [];
$tab = Indent::_(3);
$loadTabs = false;
$width_class = 'col-md-';
$row_class = 'row';
$form_class = 'main-card';
$uitab = 'uitab';
// check if we have custom tabs
if (CFactory::_('Component')->isArray('dashboard_tab'))
{
// build the tabs and accordians
foreach (CFactory::_('Component')->get('dashboard_tab') as $data)
{
$builder[$data['name']][$data['header']]
= CFactory::_('Placeholder')->update_(
$data['html']
);
}
// since we have custom tabs we must load the tab structure around the cpanel
$display[] = '<div id="j-main-container">';
$display[] = Indent::_(1) . '<div class="' . $form_class . '">';
$display[] = Indent::_(1)
. "<?php echo Html::_('{$uitab}.startTabSet', 'cpanel_tab', array('active' => 'cpanel')); ?>";
$display[] = PHP_EOL . Indent::_(2)
. "<?php echo Html::_('{$uitab}.addTab', 'cpanel_tab', 'cpanel', Text:"
. ":_('cPanel', true)); ?>";
$display[] = Indent::_(2) . '<div class="' . $row_class . '">';
// change the name of the main tab
$mainAccordianName = 'Control Panel';
$loadTabs = true;
}
else
{
$display[] = '<div id="j-main-container">';
$display[] = Indent::_(1) . '<div class="' . $form_class . '" style="padding: 20px;">';
$display[] = Indent::_(2) . '<div class="' . $row_class . '">';
}
// set dashboard display
$display[] = $tab . '<div class="' . $width_class . '9">';
$display[] = $tab . Indent::_(1)
. "<?php echo \$this->loadTemplate('main');?>";
$display[] = $tab . "</div>";
$display[] = $tab . '<div class="' . $width_class . '3">';
$display[] = $tab . Indent::_(1)
. "<?php echo \$this->loadTemplate('vdm');?>";
$display[] = $tab . "</div>";
if ($loadTabs)
{
$display[] = Indent::_(2) . "</div>";
$display[] = Indent::_(2)
. "<?php echo Html::_('{$uitab}.endTab'); ?>";
// load the new tabs
foreach ($builder as $tabname => $accordians)
{
$alias = StringHelper::safe($tabname);
$display[] = PHP_EOL . Indent::_(2)
. "<?php echo Html::_('{$uitab}.addTab', 'cpanel_tab', '"
. $alias . "', Joomla__"."_ba6326ef_cb79_4348_80f4_ab086082e3c5___Power::_('" . $tabname
. "', true)); ?>";
$display[] = Indent::_(2) . '<div class="' . $row_class . '">';
$display[] = $tab . '<div class="' . $width_class . '12">';
$slidecounter = 1;
foreach ($accordians as $accordianname => $html)
{
$ac_alias = StringHelper::safe(
$accordianname
);
$counterName = StringHelper::safe(
$slidecounter
);
$tempName = $alias . '_' . $ac_alias;
$display[] = $tab . Indent::_(1)
. "<?php echo \$this->loadTemplate('" . $tempName
. "');?>";
$slidecounter++;
// build the template file
$target = array('custom_admin' => CFactory::_('Config')->component_code_name);
CFactory::_('Utilities.Structure')->build($target, 'template', $tempName);
// set the file data
$TARGET = StringHelper::safe(
CFactory::_('Config')->build_target, 'U'
);
// SITE_TEMPLATE_BODY <<<DYNAMIC>>>
CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '_' . $tempName . '|CUSTOM_ADMIN_TEMPLATE_BODY', PHP_EOL . $html);
// SITE_TEMPLATE_CODE_BODY <<<DYNAMIC>>>
CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '_' . $tempName . '|CUSTOM_ADMIN_TEMPLATE_CODE_BODY', '');
}
$display[] = $tab . "</div>";
$display[] = Indent::_(2) . "</div>";
$display[] = Indent::_(2)
. "<?php echo Html::_('{$uitab}.endTab'); ?>";
}
$display[] = PHP_EOL . Indent::_(1)
. "<?php echo Html::_('{$uitab}.endTabSet'); ?>";
}
else
{
$display[] = Indent::_(2) . "</div>";
}
$display[] = Indent::_(1) . "</div>";
$display[] = "</div>";
// return the display
return PHP_EOL . implode(PHP_EOL, $display);
}
public function addCustomDashboardIcons(&$view, &$counter)
{
$icon = '';
@@ -0,0 +1,30 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Dashboard;
/**
* Dashboard View Interface
*
* @since 5.1.5
*/
interface ViewInterface
{
/**
* Build the admin dashboard display markup.
*
* @return string The compiled dashboard display markup.
* @since 5.1.5
*/
public function get(): string;
}
@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>
@@ -120,7 +120,7 @@ class Data
* @since 3.2.0
*/
public function __construct(Config $config, Registry $registry,
Customcode $customcode = null, Gui $gui,
Customcode $customcode, Gui $gui,
FieldData $field, Filesfolders $filesFolders,
DatabaseInterface $db, Superpower $superpower)
{
@@ -78,7 +78,7 @@ class Libraries
* @return void
* @since 3.2.0
*/
public function set(string $key, object &$item, string $target = null)
public function set(string $key, object &$item, ?string $target = null)
{
// set the target
$target = $target ?: $this->config->build_target;
@@ -101,15 +101,15 @@ class Injector implements InjectorInterface
/**
* Constructor.
*
* @param Power|null $power The power object.
* @param Extractor|null $extractor The powers extractor object.
* @param Parser|null $parser The powers parser object.
* @param Placeholder|null $placeholder The compiler placeholder object.
* @param Power $power The power object.
* @param Extractor $extractor The powers extractor object.
* @param Parser $parser The powers parser object.
* @param Placeholder $placeholder The compiler placeholder object.
*
* @since 3.2.0
*/
public function __construct(Power $power = null, Extractor $extractor = null,
Parser $parser = null, Placeholder $placeholder = null)
public function __construct(Power $power, Extractor $extractor,
Parser $parser, Placeholder $placeholder)
{
$this->power = $power;
$this->extractor = $extractor;
@@ -0,0 +1,160 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Dashboard\ViewInterface;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaSix\Dashboard\View as J6View;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Dashboard\View as J5View;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Dashboard\View as J4View;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Dashboard\View as J3View;
/**
* Architecture Dashboard Service Provider
*
* @since 5.1.5
*/
class ArchitectureDashboard implements ServiceProviderInterface
{
/**
* Current Joomla Version Being Build
*
* @var int
* @since 5.1.5
**/
protected $targetVersion;
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
* @since 5.1.5
*/
public function register(Container $container)
{
$container->alias(ViewInterface::class, 'Architecture.Dashboard.View')
->share('Architecture.Dashboard.View', [$this, 'getViewInterface'], true);
$container->alias(J6View::class, 'Architecture.Dashboard.J6.View')
->share('Architecture.Dashboard.J6.View', [$this, 'getJ6View'], true);
$container->alias(J5View::class, 'Architecture.Dashboard.J5.View')
->share('Architecture.Dashboard.J5.View', [$this, 'getJ5View'], true);
$container->alias(J4View::class, 'Architecture.Dashboard.J4.View')
->share('Architecture.Dashboard.J4.View', [$this, 'getJ4View'], true);
$container->alias(J3View::class, 'Architecture.Dashboard.J3.View')
->share('Architecture.Dashboard.J3.View', [$this, 'getJ3View'], true);
}
/**
* Get The ViewInterface Class.
*
* @param Container $container The DI container.
*
* @return ViewInterface
* @since 5.1.5
*/
public function getViewInterface(Container $container): ViewInterface
{
if (empty($this->targetVersion))
{
$this->targetVersion = $container->get('Config')->joomla_version;
}
return $container->get('Architecture.Dashboard.J' . $this->targetVersion . '.View');
}
/**
* Get The View Class.
*
* @param Container $container The DI container.
*
* @return J6View
* @since 5.1.5
*/
public function getJ6View(Container $container): J6View
{
return new J6View(
$container->get('Config'),
$container->get('Component'),
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.Multi'),
$container->get('Utilities.Structure')
);
}
/**
* Get The View Class.
*
* @param Container $container The DI container.
*
* @return J5View
* @since 5.1.5
*/
public function getJ5View(Container $container): J5View
{
return new J5View(
$container->get('Config'),
$container->get('Component'),
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.Multi'),
$container->get('Utilities.Structure')
);
}
/**
* Get The View Class.
*
* @param Container $container The DI container.
*
* @return J4View
* @since 5.1.5
*/
public function getJ4View(Container $container): J4View
{
return new J4View(
$container->get('Config'),
$container->get('Component'),
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.Multi'),
$container->get('Utilities.Structure')
);
}
/**
* Get The View Class.
*
* @param Container $container The DI container.
*
* @return J3View
* @since 5.1.5
*/
public function getJ3View(Container $container): J3View
{
return new J3View(
$container->get('Config'),
$container->get('Component'),
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.One'),
$container->get('Compiler.Builder.Content.Multi'),
$container->get('Utilities.Structure')
);
}
}
@@ -46,6 +46,12 @@ use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaSix\CustomAdminViews
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\CustomAdminViews\AddToolBar as J5CustomAdminViewsAddToolBar;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\CustomAdminViews\AddToolBar as J4CustomAdminViewsAddToolBar;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\CustomAdminViews\AddToolBar as J3CustomAdminViewsAddToolBar;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItemBuilder;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem\ItemCode;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem\Link;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem\LinkAuthority;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\AdminViews\ListItem\LinkLogic;
/**
@@ -130,7 +136,6 @@ class ArchitectureView implements ServiceProviderInterface
$container->alias(J3AdminViewsAddToolBar::class, 'Architecture.AdminViews.J3.AddToolBar')
->share('Architecture.AdminViews.J3.AddToolBar', [$this, 'getJ3AdminViewsAddToolBar'], true);
$container->alias(SiteViewAddToolBar::class, 'Architecture.SiteView.AddToolBar')
->share('Architecture.SiteView.AddToolBar', [$this, 'getSiteViewAddToolBar'], true);
@@ -177,6 +182,25 @@ class ArchitectureView implements ServiceProviderInterface
$container->alias(J3CustomAdminViewsAddToolBar::class, 'Architecture.CustomAdminViews.J3.AddToolBar')
->share('Architecture.CustomAdminViews.J3.AddToolBar', [$this, 'getJ3CustomAdminViewsAddToolBar'], true);
$container->alias(ListItemBuilder::class, 'Architecture.AdminViews.ListItemBuilder')
->share('Architecture.AdminViews.ListItemBuilder', [$this, 'getAdminViewsListItemBuilder'], true);
$container->alias(ListItem::class, 'Architecture.AdminViews.ListItem')
->share('Architecture.AdminViews.ListItem', [$this, 'getAdminViewsListItem'], true);
$container->alias(ItemCode::class, 'Architecture.AdminViews.ListItem.ItemCode')
->share('Architecture.AdminViews.ListItem.ItemCode', [$this, 'getAdminViewsListItemItemCode'], true);
$container->alias(Link::class, 'Architecture.AdminViews.ListItem.Link')
->share('Architecture.AdminViews.ListItem.Link', [$this, 'getAdminViewsListItemLink'], true);
$container->alias(LinkAuthority::class, 'Architecture.AdminViews.ListItem.LinkAuthority')
->share('Architecture.AdminViews.ListItem.LinkAuthority', [$this, 'getAdminViewsListItemLinkAuthority'], true);
$container->alias(LinkLogic::class, 'Architecture.AdminViews.ListItem.LinkLogic')
->share('Architecture.AdminViews.ListItem.LinkLogic', [$this, 'getAdminViewsListItemLinkLogic'], true);
}
/**
@@ -782,6 +806,106 @@ class ArchitectureView implements ServiceProviderInterface
$container->get('Compiler.Builder.Content.One'),
$container->get('Architecture.CustomButtons')
);
}
/**
* Get The ListItemBuilder Class.
*
* @param Container $container The DI container.
*
* @return ListItemBuilder
* @since 5.1.5
*/
public function getAdminViewsListItemBuilder(Container $container): ListItemBuilder
{
return new ListItemBuilder(
$container->get('Placeholder'),
$container->get('Architecture.AdminViews.ListItem'),
$container->get('Compiler.Builder.Field.Relations'),
$container->get('Compiler.Builder.List.Join')
);
}
/**
* Get The ListItem Class.
*
* @param Container $container The DI container.
*
* @return ListItem
* @since 5.1.5
*/
public function getAdminViewsListItem(Container $container): ListItem
{
return new ListItem(
$container->get('Architecture.AdminViews.ListItem.ItemCode'),
$container->get('Architecture.AdminViews.ListItem.Link'),
$container->get('Architecture.AdminViews.ListItem.LinkAuthority'),
$container->get('Architecture.AdminViews.ListItem.LinkLogic')
);
}
/**
* Get The ItemCode Class.
*
* @param Container $container The DI container.
*
* @return ItemCode
* @since 5.1.5
*/
public function getAdminViewsListItemItemCode(Container $container): ItemCode
{
return new ItemCode(
$container->get('Config'),
$container->get('Compiler.Builder.Selection.Translation'),
$container->get('Compiler.Builder.Do.Not.Escape')
);
}
/**
* Get The Link Class.
*
* @param Container $container The DI container.
*
* @return Link
* @since 5.1.5
*/
public function getAdminViewsListItemLink(Container $container): Link
{
return new Link(
$container->get('Compiler.Builder.Category')
);
}
/**
* Get The LinkAuthority Class.
*
* @param Container $container The DI container.
*
* @return LinkAuthority
* @since 5.1.5
*/
public function getAdminViewsListItemLinkAuthority(Container $container): LinkAuthority
{
return new LinkAuthority(
$container->get('Config'),
$container->get('Compiler.Builder.Category.Code'),
$container->get('Compiler.Creator.Permission')
);
}
/**
* Get The LinkLogic Class.
*
* @param Container $container The DI container.
*
* @return LinkLogic
* @since 5.1.5
*/
public function getAdminViewsListItemLinkLogic(Container $container): LinkLogic
{
return new LinkLogic(
$container->get('Config')
);
}
}
@@ -48,7 +48,7 @@ class Paths extends Registry
*
* @since 3.2.0
*/
public function __construct(Config $config = null, Component $component = null)
public function __construct(Config $config, Component $component)
{
$this->config = $config;
$this->component = $component;
@@ -69,7 +69,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -106,7 +106,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -73,7 +73,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -95,7 +95,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -61,22 +61,22 @@ final class Resolve
*
* @param string $target The target network.
* @param string &$domain The API base domain (passed by reference).
* @param string &$organisation The repository organisation (passed by reference).
* @param string &$organization The repository organization (passed by reference).
* @param string &$repository The repository name (passed by reference).
*
* @return void
* @since 5.0.4
*/
public function api(string $target, string &$domain, string &$organisation, string &$repository): void
public function api(string $target, string &$domain, string &$organization, string &$repository): void
{
try {
// Check the status of the current API
$status = $this->status->get($target, $domain, $repository, $organisation);
$status = $this->status->get($target, $domain, $repository, $organization);
// If the API is inactive, attempt to find another active URL
if ($status == 0)
{
$this->resolve($target, $domain, $organisation, $repository);
$this->resolve($target, $domain, $organization, $repository);
}
} catch (\Exception $e) {
// ignore any none [in]active urls
@@ -87,18 +87,18 @@ final class Resolve
/**
* Resolves an active API URL if the current API is inactive.
*
* Updates the `$domain`, `$organisation`, and `$repository` parameters to point to an active API URL.
* Updates the `$domain`, `$organization`, and `$repository` parameters to point to an active API URL.
*
* @param string $target The target network.
* @param string &$domain The API base domain (passed by reference).
* @param string &$organisation The repository organisation (passed by reference).
* @param string &$organization The repository organization (passed by reference).
* @param string &$repository The repository name (passed by reference).
*
* @return void
* @throws \Exception
* @since 5.0.4
*/
private function resolve(string $target, string &$domain, string &$organisation, string &$repository): void
private function resolve(string $target, string &$domain, string &$organization, string &$repository): void
{
$activeRepo = $this->active($target);
@@ -111,12 +111,12 @@ final class Resolve
// Parse the active repository's URL and update the references
$parsedUrl = $this->url->parse($activeRepo->url);
$noneActiveDomain = "{$domain}/{$organisation}/{$repository}";
$activeDomain = "{$parsedUrl->scheme}://{$parsedUrl->domain}/{$parsedUrl->organisation}/{$parsedUrl->repository}";
$noneActiveDomain = "{$domain}/{$organization}/{$repository}";
$activeDomain = "{$parsedUrl->scheme}://{$parsedUrl->domain}/{$parsedUrl->organization}/{$parsedUrl->repository}";
// update the values passed by reference
$domain = $parsedUrl->scheme . '://' . $parsedUrl->domain;
$organisation = $parsedUrl->organisation ?? $organisation;
$organization = $parsedUrl->organization ?? $organization;
$repository = $parsedUrl->repository ?? $repository;
// add info
@@ -71,7 +71,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -108,7 +108,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -147,7 +147,7 @@ MD;
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -119,7 +119,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -71,7 +71,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -117,7 +117,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -88,7 +88,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -173,7 +173,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -125,7 +125,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -122,7 +122,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -106,7 +106,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -128,7 +128,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -148,7 +148,7 @@ MD;
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -110,7 +110,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -116,7 +116,7 @@ MD;
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -111,7 +111,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -79,7 +79,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -110,7 +110,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -56,7 +56,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -127,7 +127,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -71,7 +71,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -119,7 +119,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -79,7 +79,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -106,7 +106,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -66,7 +66,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -160,7 +160,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -119,7 +119,7 @@ MD;
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -110,7 +110,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -91,7 +91,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -130,7 +130,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -157,7 +157,7 @@ class Insert implements InsertInterface
* @return bool
* @since 3.2.0
*/
public function items(?array $items, string $table = null): bool
public function items(?array $items, ?string $table = null): bool
{
// load the table
if (empty($table))
@@ -98,7 +98,7 @@ class Load implements LoadInterface
* @return mixed
* @since 3.2.0
*/
public function value(int $id, string $field, string $table = null)
public function value(int $id, string $field, ?string $table = null)
{
// load the table
if (empty($table))
@@ -132,7 +132,7 @@ class Load implements LoadInterface
* @return object|null
* @since 3.2.0
*/
public function item(int $id, string $table = null): ?object
public function item(int $id, ?string $table = null): ?object
{
// load the table
if (empty($table))
@@ -165,7 +165,7 @@ class Load implements LoadInterface
* @return array|null
* @since 3.2.0
*/
public function items(string $table = null, int $bundle = 0): ?array
public function items(?string $table = null, int $bundle = 0): ?array
{
// load the table
if (empty($table))
@@ -55,6 +55,6 @@ interface InsertInterface
* @return bool
* @since 3.2.0
*/
public function items(array $items, string $table = null): bool;
public function items(array $items, ?string $table = null): bool;
}
@@ -30,7 +30,7 @@ interface LoadInterface
* @return mixed
* @since 3.2.0
*/
public function value(int $id, string $field, string $table = null);
public function value(int $id, string $field, ?string $table = null);
/**
* Get values from a given table
@@ -42,7 +42,7 @@ interface LoadInterface
* @return object|null
* @since 3.2.0
*/
public function item(int $id, string $table = null): ?object;
public function item(int $id, ?string $table = null): ?object;
/**
* Get values from a given table
@@ -54,7 +54,7 @@ interface LoadInterface
* @return array|null
* @since 3.2.0
*/
public function items(string $table = null, int $bundle = 0): ?array;
public function items(?string $table = null, int $bundle = 0): ?array;
}
@@ -117,7 +117,7 @@ final class Item implements ItemInterface
### Used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -107,7 +107,7 @@ MD;
### All used in [Joomla Component Builder](https://www.joomlacomponentbuilder.com) - [Source](https://git.vdm.dev/joomla/Component-Builder) - [Mirror](https://github.com/vdm-io/Joomla-Component-Builder) - [Download](https://git.vdm.dev/joomla/pkg-component-builder/releases)
---
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/u/llewellyn "Llewellyn on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
[![Joomla Volunteer Portal](https://img.shields.io/badge/-Joomla-gold?logo=joomla)](https://volunteers.joomla.org/joomlers/1396-llewellyn-van-der-merwe "Join Llewellyn on the Joomla Volunteer Portal: Shaping the Future Together!") [![GitHub](https://img.shields.io/badge/-Git-181717?logo=git)](https://github.com/joomengine "Build premium Joomla extensions with JoomEngine on GitHub: Help us raise Joomla extension standards!") [![Octoleo](https://img.shields.io/badge/-Octoleo-black?logo=linux)](https://git.vdm.dev/octoleo "--quiet") [![Llewellyn](https://img.shields.io/badge/-Llewellyn-ffffff?logo=gitea)](https://git.vdm.dev/Llewellyn "Collaborate and Innovate with Llewellyn on Git: Building a Better Code Future!") [![Telegram](https://img.shields.io/badge/-Telegram-blue?logo=telegram)](https://t.me/Joomla_component_builder "Join Llewellyn and the Community on Telegram: Building Joomla Components Together!") [![Mastodon](https://img.shields.io/badge/-Mastodon-9e9eec?logo=mastodon)](https://joomla.social/@llewellyn "Connect and Engage with Llewellyn on Joomla Social: Empowering Communities, One Post at a Time!") [![X (Twitter)](https://img.shields.io/badge/-X-black?logo=x)](https://x.com/llewellynvdm "Join the Conversation with Llewellyn on X: Where Ideas Take Flight!") [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/Llewellynvdm "Build, Innovate, and Thrive with Llewellyn on GitHub: Turning Ideas into Impact!") [![YouTube](https://img.shields.io/badge/-YouTube-ff0000?logo=youtube)](https://www.youtube.com/@OctoYou "Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!") [![n8n](https://img.shields.io/badge/-n8n-black?logo=n8n)](https://n8n.io/creators/octoleo "Effortless Automation and Impactful Workflows with Llewellyn on n8n!") [![Docker Hub](https://img.shields.io/badge/-Docker-grey?logo=docker)](https://hub.docker.com/r/octoleo/joomengine "JoomEngine on Docker: Containerize Your Creativity!") [![Open Collective](https://img.shields.io/badge/-Donate-green?logo=opencollective)](https://opencollective.com/joomla-component-builder "Donate towards JCB: Help Llewellyn financially so he can continue developing this great tool!") [![GPG Key](https://img.shields.io/badge/-GPG-blue?logo=gnupg)](https://git.vdm.dev/Llewellyn/gpg "Unlock Trust and Security with Llewellyn's GPG Key: Your Gateway to Verified Connections!")
MD;
return implode("\n", $readme);
@@ -80,7 +80,7 @@ interface HandlerInterface
* @return array|null File details or false on failure.
* @since 3.0.11
*/
public function getFile(string $field, string $type, string $filter = null, string $path = null): ?array;
public function getFile(string $field, string $type, ?string $filter = null, ?string $path = null): ?array;
/**
* Remove a previously uploaded file.
@@ -192,7 +192,7 @@ interface ContentsInterface extends ApiInterface
* @return string|null
* @since 3.2.0
**/
public function editor(string $owner, string $repo, string $filepath, string $ref = null): ?string;
public function editor(string $owner, string $repo, string $filepath, ?string $ref = null): ?string;
/**
* Get the blob of a repository.
@@ -111,7 +111,7 @@ interface WikiInterface extends ApiInterface
string $pageName,
string $title,
string $content,
string $message = null
?string $message = null
): ?object;
/**