diff --git a/README.md b/README.md index b21d7c8..28d92aa 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ This repository contains an index (see below) of all the approved powers within - **final class MultiSubform** | [Details](src/e0198c3f-777a-4a0b-87b7-e6a198afc8f9) | [Code](src/e0198c3f-777a-4a0b-87b7-e6a198afc8f9/code.php) | [Settings](src/e0198c3f-777a-4a0b-87b7-e6a198afc8f9/settings.json) | Super__e0198c3f_777a_4a0b_87b7_e6a198afc8f9__Power - **final class Subform** | [Details](src/85785701-07b2-4f81-bc1e-0f423700c254) | [Code](src/85785701-07b2-4f81-bc1e-0f423700c254/code.php) | [Settings](src/85785701-07b2-4f81-bc1e-0f423700c254/settings.json) | Super__85785701_07b2_4f81_bc1e_0f423700c254__Power - **class Remote** | [Details](src/728ee726-3f0f-4762-899d-f8c9430cee58) | [Code](src/728ee726-3f0f-4762-899d-f8c9430cee58/code.php) | [Settings](src/728ee726-3f0f-4762-899d-f8c9430cee58/settings.json) | Super__728ee726_3f0f_4762_899d_f8c9430cee58__Power + - **class Repository** | [Details](src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895) | [Code](src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/code.php) | [Settings](src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/settings.json) | Super__eb7d69c2_4ee9_4bd0_aacc_ab51a12be895__Power - **Namespace**: [VDM\Joomla\Database](#vdm-joomla-database) - **final class Delete** | [Details](src/92291f1f-f248-4ec0-9f2a-3d47c49eeac1) | [Code](src/92291f1f-f248-4ec0-9f2a-3d47c49eeac1/code.php) | [Settings](src/92291f1f-f248-4ec0-9f2a-3d47c49eeac1/settings.json) | Super__92291f1f_f248_4ec0_9f2a_3d47c49eeac1__Power @@ -93,9 +94,6 @@ This repository contains an index (see below) of all the approved powers within - **Namespace**: [VDM\Joomla\Componentbuilder\Table](#vdm-joomla-componentbuilder-table) - **final class Schema** | [Details](src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce) | [Code](src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/code.php) | [Settings](src/b3d2ec33-76d4-4c3b-bb2c-86ac14a221ce/settings.json) | Super__b3d2ec33_76d4_4c3b_bb2c_86ac14a221ce__Power -- **Namespace**: [VDM\Joomla\Componentbuilder\Utilities](#vdm-joomla-componentbuilder-utilities) - - - **abstract class FilterHelper** | [Details](src/cddcac51-9a46-47c4-ba59-105c70453bd6) | [Code](src/cddcac51-9a46-47c4-ba59-105c70453bd6/code.php) | [Settings](src/cddcac51-9a46-47c4-ba59-105c70453bd6/settings.json) | Super__cddcac51_9a46_47c4_ba59_105c70453bd6__Power - **Namespace**: [VDM\Joomla\Data\Action](#vdm-joomla-data-action) - **class Delete** | [Details](src/3fc72954-a303-4cac-b53c-554be38b85e7) | [Code](src/3fc72954-a303-4cac-b53c-554be38b85e7/code.php) | [Settings](src/3fc72954-a303-4cac-b53c-554be38b85e7/settings.json) | Super__3fc72954_a303_4cac_b53c_554be38b85e7__Power diff --git a/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/README.md b/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/README.md index befbb57..96017bf 100644 --- a/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/README.md +++ b/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/README.md @@ -19,10 +19,12 @@ abstract Grep #Orange { # CMSApplication $app + __construct(Contents $contents, array $paths, ...) + getRemotePowersGuid() : ?array + + setBranchField(string $field) : void + get(string $guid, ?array $order = null) : ?object # {abstract} remoteIndex(object $path) : void # getFunctionName(string $name) : ?string # init() : void + + getBranchField() : string } note right of Grep::__construct @@ -37,14 +39,21 @@ note right of Grep::__construct ?CMSApplication $app = null end note -note right of Grep::getRemotePowersGuid +note left of Grep::getRemotePowersGuid Get all remote powers GUID's since: 3.2.0 return: ?array end note -note right of Grep::get +note right of Grep::setBranchField + Set the branch field + + since: 3.2.2 + return: void +end note + +note left of Grep::get Get a power since: 3.2.0 @@ -58,7 +67,7 @@ note right of Grep::remoteIndex return: void end note -note right of Grep::getFunctionName +note left of Grep::getFunctionName Get function name since: 3.2.0 @@ -71,6 +80,13 @@ note right of Grep::init since: 3.2.0 return: void end note + +note left of Grep::getBranchField + Get the branch field + + since: 3.2.2 + return: string +end note @enduml ``` diff --git a/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/code.php b/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/code.php index f4c306f..9a8bdba 100644 --- a/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/code.php +++ b/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/code.php @@ -55,6 +55,14 @@ abstract class Grep implements GrepInterface **/ protected array $order = ['local', 'remote']; + /** + * The target branch field name ['read_branch', 'write_branch'] + * + * @var string + * @since 3.2.2 + **/ + protected string $branch_field = 'read_branch'; + /** * Gitea Repository Contents * @@ -120,6 +128,19 @@ abstract class Grep implements GrepInterface return empty($powers) ? null : array_unique($powers); } + /** + * Set the branch field + * + * @param string $field The global unique id of the power + * + * @return void + * @since 3.2.2 + */ + public function setBranchField(string $field): void + { + $this->branch_field = $field; + } + /** * Get a power * @@ -196,15 +217,12 @@ abstract class Grep implements GrepInterface $path->path = trim($path->organisation) . '/' . trim($path->repository); // update the branch - if ($path->read_branch === 'default' || empty($path->read_branch)) - { - $path->read_branch = null; - } + $branch_field = $this->getBranchField(); + $branch = $path->{$branch_field} ?? null; - // only update the write branch if set - if (isset($path->write_branch) && ($path->write_branch === 'default' || empty($path->write_branch))) + if ($branch === 'default' || empty($branch)) { - $path->write_branch = null; + $path->{$branch_field} = null; } // set local path @@ -219,6 +237,17 @@ abstract class Grep implements GrepInterface } } } + } + + /** + * Get the branch field + * + * @return string + * @since 3.2.2 + */ + public function getBranchField(): string + { + return $this->branch_field; } } diff --git a/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/code.power b/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/code.power index 7837fa6..62f034b 100644 --- a/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/code.power +++ b/src/1401a167-0ce4-4f4a-afee-2d8b02ed339b/code.power @@ -22,6 +22,14 @@ **/ protected array $order = ['local', 'remote']; + /** + * The target branch field name ['read_branch', 'write_branch'] + * + * @var string + * @since 3.2.2 + **/ + protected string $branch_field = 'read_branch'; + /** * Gitea Repository Contents * @@ -87,6 +95,19 @@ return empty($powers) ? null : array_unique($powers); } + /** + * Set the branch field + * + * @param string $field The global unique id of the power + * + * @return void + * @since 3.2.2 + */ + public function setBranchField(string $field): void + { + $this->branch_field = $field; + } + /** * Get a power * @@ -163,15 +184,12 @@ $path->path = trim($path->organisation) . '/' . trim($path->repository); // update the branch - if ($path->read_branch === 'default' || empty($path->read_branch)) - { - $path->read_branch = null; - } + $branch_field = $this->getBranchField(); + $branch = $path->{$branch_field} ?? null; - // only update the write branch if set - if (isset($path->write_branch) && ($path->write_branch === 'default' || empty($path->write_branch))) + if ($branch === 'default' || empty($branch)) { - $path->write_branch = null; + $path->{$branch_field} = null; } // set local path @@ -186,4 +204,15 @@ } } } + } + + /** + * Get the branch field + * + * @return string + * @since 3.2.2 + */ + public function getBranchField(): string + { + return $this->branch_field; } \ No newline at end of file diff --git a/src/c182506a-ab84-439c-b962-1e606b58d545/README.md b/src/c182506a-ab84-439c-b962-1e606b58d545/README.md index 243cabd..eeddece 100644 --- a/src/c182506a-ab84-439c-b962-1e606b58d545/README.md +++ b/src/c182506a-ab84-439c-b962-1e606b58d545/README.md @@ -13,6 +13,7 @@ @startuml interface GrepInterface #Lavender { + getRemotePowersGuid() : ?array + + setBranchField(string $field) : void + get(string $guid, array $order = ['local', 'remote']) : ?object } @@ -23,6 +24,13 @@ note right of GrepInterface::getRemotePowersGuid return: ?array end note +note right of GrepInterface::setBranchField + Set the branch field + + since: 3.2.2 + return: void +end note + note right of GrepInterface::get Get a power diff --git a/src/c182506a-ab84-439c-b962-1e606b58d545/code.php b/src/c182506a-ab84-439c-b962-1e606b58d545/code.php index 5b1badb..574b2db 100644 --- a/src/c182506a-ab84-439c-b962-1e606b58d545/code.php +++ b/src/c182506a-ab84-439c-b962-1e606b58d545/code.php @@ -27,6 +27,16 @@ interface GrepInterface */ public function getRemotePowersGuid(): ?array; + /** + * Set the branch field + * + * @param string $field The global unique id of the power + * + * @return void + * @since 3.2.2 + */ + public function setBranchField(string $field): void; + /** * Get a power * diff --git a/src/c182506a-ab84-439c-b962-1e606b58d545/code.power b/src/c182506a-ab84-439c-b962-1e606b58d545/code.power index 9d0b4aa..21eb71f 100644 --- a/src/c182506a-ab84-439c-b962-1e606b58d545/code.power +++ b/src/c182506a-ab84-439c-b962-1e606b58d545/code.power @@ -6,6 +6,16 @@ */ public function getRemotePowersGuid(): ?array; + /** + * Set the branch field + * + * @param string $field The global unique id of the power + * + * @return void + * @since 3.2.2 + */ + public function setBranchField(string $field): void; + /** * Get a power * diff --git a/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/README.md b/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/README.md new file mode 100644 index 0000000..d89618a --- /dev/null +++ b/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/README.md @@ -0,0 +1,148 @@ +``` +██████╗ ██████╗ ██╗ ██╗███████╗██████╗ +██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗ +██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝ +██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗ +██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║ +╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝ +``` +# class Repository (Details) +> namespace: **VDM\Joomla\Data** +> extends: **** +```uml +@startuml +class Repository #Gold { + # Grep $grep + # Items $items + # Git $git + + array $repos + # string $table + # array $map + + __construct(array $repos, Grep $grep, ...) + + table(string $table) : self + + set(array $guids) : bool + + getTable() : string + + getLocalItems(array $guids) : ?array + # fetchLocalItems(array $guids) : ?array + # mapItems(array $items) : array + # mapItem(object $item) : object + # getRepoItems(array $guids) : ?array + # canWrite() : bool + # areObjectsEqual(object $obj1, object $obj2) : bool + # updateItem(object $item, object $existing) : void + # createItem(object $item) : void +} + +note right of Repository::__construct + Constructor. + + since: 3.2.2 + + arguments: + array $repos + Grep $grep + Items $items + Git $git + ?string $table = null +end note + +note left of Repository::table + Set the current active table + + since: 3.2.2 + return: self +end note + +note right of Repository::set + Set items + + since: 3.2.0 + return: bool +end note + +note left of Repository::getTable + Get the current active table + + since: 3.2.2 + return: string +end note + +note right of Repository::getLocalItems + Get items + + since: 3.2.2 + return: ?array +end note + +note left of Repository::fetchLocalItems + Fetch items from the database + + since: 3.2.2 + return: ?array +end note + +note right of Repository::mapItems + Map items to their properties + + since: 3.2.2 + return: array +end note + +note left of Repository::mapItem + Map a single item to its properties + + since: 3.2.2 + return: object +end note + +note right of Repository::getRepoItems + get existing items + + since: 3.2.2 + return: ?array +end note + +note left of Repository::canWrite + check that we have an active repo towards which we can write data + + since: 3.2.2 + return: bool +end note + +note right of Repository::areObjectsEqual + Checks if two objects are equal by comparing their JSON representations. +This method converts both input objects to JSON strings and compares these strings. +If the JSON strings are identical, the objects are considered equal. + + since: 3.2.2 + return: bool +end note + +note left of Repository::updateItem + update an existing item (if changed) + + since: 3.2.2 + return: void +end note + +note right of Repository::createItem + create a new item + + since: 3.2.2 + return: void +end note + +@enduml +``` + +--- +``` + ██╗ ██████╗██████╗ + ██║██╔════╝██╔══██╗ + ██║██║ ██████╔╝ +██ ██║██║ ██╔══██╗ +╚█████╔╝╚██████╗██████╔╝ + ╚════╝ ╚═════╝╚═════╝ +``` +> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder) + diff --git a/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/code.php b/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/code.php new file mode 100644 index 0000000..44e6bf6 --- /dev/null +++ b/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/code.php @@ -0,0 +1,386 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Data; + + +use VDM\Joomla\Interfaces\GrepInterface as Grep; +use VDM\Joomla\Interfaces\Data\ItemsInterface as Items; +use VDM\Joomla\Gitea\Repository\Contents as Git; + + +/** + * Set data based on global unique ids to remote repository + * + * @since 3.2.2 + */ +class Repository +{ + /** + * The GrepInterface Class. + * + * @var Grep + * @since 3.2.2 + */ + protected Grep $grep; + + /** + * The ItemsInterface Class. + * + * @var Items + * @since 3.2.2 + */ + protected Items $items; + + /** + * The Contents Class. + * + * @var Git + * @since 3.2.2 + */ + protected Git $git; + + /** + * All active repos + * + * @var array + * @since 3.2.0 + **/ + public array $repos; + + /** + * Table Name + * + * @var string + * @since 3.2.1 + */ + protected string $table; + + /** + * The item map + * + * @var array + * @since 3.2.2 + */ + protected array $map; + + /** + * Constructor. + * + * @param array $repos The active repos + * @param Grep $grep The GrepInterface Class. + * @param Items $items The ItemsInterface Class. + * @param Git $git The Contents Class. + * @param string|null $table The table name. + * + * @since 3.2.2 + */ + public function __construct(array $repos, Grep $grep, Items $items, Git $git, ?string $table = null) + { + $this->repos = $repos; + $this->grep = $grep; + $this->items = $items; + $this->git = $git; + if ($table !== null) + { + $this->table = $table; + } + // set the branch to writing + $this->grep->setBranchField('write_branch'); + } + + /** + * Set the current active table + * + * @param string $table The table that should be active + * + * @return self + * @since 3.2.2 + */ + public function table(string $table): self + { + $this->table = $table; + + return $this; + } + + /** + * Set items + * + * @param array $guids The global unique id of the item + * + * @return bool + * @throws \Exception + * @since 3.2.0 + */ + public function set(array $guids): bool + { + if (($items = $this->getLocalItems($guids)) === null) + { + throw new \Exception("At least one valid local [Joomla Power] must exist for the push function to operate correctly."); + } + + if (!$this->canWrite()) + { + throw new \Exception("At least one [Joomla Power] content repository must be configured with a [Write Branch] value in the repositories area for the push function to operate correctly."); + } + + // update the existing found + if (($existing_items = $this->getRepoItems($guids)) !== []) + { + foreach ($existing_items as $e_guid => $item) + { + if (isset($items[$e_guid])) + { + $this->updateItem($items[$e_guid], $item); + unset($items[$e_guid]); + } + } + } + + // create the new items + foreach ($items as $item) + { + $this->createItem($item); + } + + return true; + } + + /** + * Get the current active table + * + * @return string + * @since 3.2.2 + */ + public function getTable(): string + { + return $this->table; + } + + /** + * Get items + * + * @param array $guids The global unique id of the item + * + * @return array|null + * @since 3.2.2 + */ + public function getLocalItems(array $guids): ?array + { + $items = $this->fetchLocalItems($guids); + + if ($items === null) + { + return null; + } + + return $this->mapItems($items); + } + + /** + * Fetch items from the database + * + * @param array $guids The global unique id of the item + * + * @return array|null + * @since 3.2.2 + */ + protected function fetchLocalItems(array $guids): ?array + { + return $this->items->table($this->table)->get($guids); + } + + /** + * Map items to their properties + * + * @param array $items The items fetched from the database + * + * @return array + * @since 3.2.2 + */ + protected function mapItems(array $items): array + { + $bucket = []; + + foreach ($items as $item) + { + if (!isset($item->guid)) + { + continue; + } + + $bucket[$item->guid] = $this->mapItem($item); + } + + return $bucket; + } + + /** + * Map a single item to its properties + * + * @param object $item The item to be mapped + * + * @return object + * @since 3.2.2 + */ + protected function mapItem(object $item): object + { + $power = []; + + foreach ($this->map as $key => $map) + { + $power[$key] = $item->{$map} ?? null; + } + + return (object) $power; + } + + /** + * get existing items + * + * @param array $guids The global unique id of the item + * + * @return array|null + * @since 3.2.2 + */ + protected function getRepoItems(array $guids): ?array + { + $bucket = []; + foreach ($guids as $guid) + { + if (($item = $this->grep->get($guid)) !== null) + { + $bucket[$guid] = (object) $item; + } + } + + return $bucket ?? null; + } + + /** + * check that we have an active repo towards which we can write data + * + * @return bool + * @since 3.2.2 + */ + protected function canWrite(): bool + { + foreach ($this->repos as $repo) + { + if (!empty($repo->write_branch) && $repo->write_branch !== 'default') + { + return true; + } + } + + return false; + } + + /** + * Checks if two objects are equal by comparing their JSON representations. + * + * This method converts both input objects to JSON strings and compares these strings. + * If the JSON strings are identical, the objects are considered equal. + * + * @param object $obj1 The first object to compare. + * @param object $obj2 The second object to compare. + * + * @return bool True if the objects are equal, false otherwise. + * @since 3.2.2 + */ + protected function areObjectsEqual(object $obj1, object $obj2): bool + { + // Convert both objects to JSON strings + $json1 = json_encode($obj1); + $json2 = json_encode($obj2); + + // Compare the JSON strings + return $json1 === $json2; + } + + /** + * update an existing item (if changed) + * + * @param object $item + * @param object $existing + * + * @return void + * @since 3.2.2 + */ + protected function updateItem(object $item, object $existing): void + { + if (isset($existing->params->source) && is_array($existing->params->source)) + { + // get the source values + $source = $existing->params->source; + + // make sure there was a change + $existing = $this->mapItem($existing); + if ($this->areObjectsEqual($item, $existing)) + { + return; + } + + foreach ($this->repos as $repo) + { + if (isset($source[$repo->guid])) + { + $this->git->load_($repo->base ?? null, $repo->token ?? null); + $this->git->update( + $repo->organisation, // The owner name. + $repo->repository, // The repository name. + 'src/' . $item->guid . '/item.json', // The file path. + json_encode($item, JSON_PRETTY_PRINT), // The file content. + 'Update ' . $item->system_name, // The commit message. + $source[$repo->guid], // The blob SHA of the old file. + $repo->write_branch // The branch name. + ); + $this->git->reset_(); + + // only update in the first found repo + return; + } + } + } + } + + /** + * create a new item + * + * @param object $item + * + * @return void + * @since 3.2.2 + */ + protected function createItem(object $item): void + { + foreach ($this->repos as $repo) + { + if (!empty($repo->write_branch) && $repo->write_branch !== 'default') + { + $this->git->load_($repo->base ?? null, $repo->token ?? null); + $this->git->create( + $repo->organisation, // The owner name. + $repo->repository, // The repository name. + 'src/' . $item->guid . '/item.json', // The file path. + json_encode($item, JSON_PRETTY_PRINT), // The file content. + 'Create ' . $item->system_name, // The commit message. + $repo->write_branch // The branch name. + ); + $this->git->reset_(); + // only create in the first found repo + return; + } + } + } +} + diff --git a/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/code.power b/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/code.power new file mode 100644 index 0000000..90219be --- /dev/null +++ b/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/code.power @@ -0,0 +1,358 @@ + /** + * The GrepInterface Class. + * + * @var Grep + * @since 3.2.2 + */ + protected Grep $grep; + + /** + * The ItemsInterface Class. + * + * @var Items + * @since 3.2.2 + */ + protected Items $items; + + /** + * The Contents Class. + * + * @var Git + * @since 3.2.2 + */ + protected Git $git; + + /** + * All active repos + * + * @var array + * @since 3.2.0 + **/ + public array $repos; + + /** + * Table Name + * + * @var string + * @since 3.2.1 + */ + protected string $table; + + /** + * The item map + * + * @var array + * @since 3.2.2 + */ + protected array $map; + + /** + * Constructor. + * + * @param array $repos The active repos + * @param Grep $grep The GrepInterface Class. + * @param Items $items The ItemsInterface Class. + * @param Git $git The Contents Class. + * @param string|null $table The table name. + * + * @since 3.2.2 + */ + public function __construct(array $repos, Grep $grep, Items $items, Git $git, ?string $table = null) + { + $this->repos = $repos; + $this->grep = $grep; + $this->items = $items; + $this->git = $git; + if ($table !== null) + { + $this->table = $table; + } + // set the branch to writing + $this->grep->setBranchField('write_branch'); + } + + /** + * Set the current active table + * + * @param string $table The table that should be active + * + * @return self + * @since 3.2.2 + */ + public function table(string $table): self + { + $this->table = $table; + + return $this; + } + + /** + * Set items + * + * @param array $guids The global unique id of the item + * + * @return bool + * @throws \Exception + * @since 3.2.0 + */ + public function set(array $guids): bool + { + if (($items = $this->getLocalItems($guids)) === null) + { + throw new \Exception("At least one valid local [Joomla Power] must exist for the push function to operate correctly."); + } + + if (!$this->canWrite()) + { + throw new \Exception("At least one [Joomla Power] content repository must be configured with a [Write Branch] value in the repositories area for the push function to operate correctly."); + } + + // update the existing found + if (($existing_items = $this->getRepoItems($guids)) !== []) + { + foreach ($existing_items as $e_guid => $item) + { + if (isset($items[$e_guid])) + { + $this->updateItem($items[$e_guid], $item); + unset($items[$e_guid]); + } + } + } + + // create the new items + foreach ($items as $item) + { + $this->createItem($item); + } + + return true; + } + + /** + * Get the current active table + * + * @return string + * @since 3.2.2 + */ + public function getTable(): string + { + return $this->table; + } + + /** + * Get items + * + * @param array $guids The global unique id of the item + * + * @return array|null + * @since 3.2.2 + */ + public function getLocalItems(array $guids): ?array + { + $items = $this->fetchLocalItems($guids); + + if ($items === null) + { + return null; + } + + return $this->mapItems($items); + } + + /** + * Fetch items from the database + * + * @param array $guids The global unique id of the item + * + * @return array|null + * @since 3.2.2 + */ + protected function fetchLocalItems(array $guids): ?array + { + return $this->items->table($this->table)->get($guids); + } + + /** + * Map items to their properties + * + * @param array $items The items fetched from the database + * + * @return array + * @since 3.2.2 + */ + protected function mapItems(array $items): array + { + $bucket = []; + + foreach ($items as $item) + { + if (!isset($item->guid)) + { + continue; + } + + $bucket[$item->guid] = $this->mapItem($item); + } + + return $bucket; + } + + /** + * Map a single item to its properties + * + * @param object $item The item to be mapped + * + * @return object + * @since 3.2.2 + */ + protected function mapItem(object $item): object + { + $power = []; + + foreach ($this->map as $key => $map) + { + $power[$key] = $item->{$map} ?? null; + } + + return (object) $power; + } + + /** + * get existing items + * + * @param array $guids The global unique id of the item + * + * @return array|null + * @since 3.2.2 + */ + protected function getRepoItems(array $guids): ?array + { + $bucket = []; + foreach ($guids as $guid) + { + if (($item = $this->grep->get($guid)) !== null) + { + $bucket[$guid] = (object) $item; + } + } + + return $bucket ?? null; + } + + /** + * check that we have an active repo towards which we can write data + * + * @return bool + * @since 3.2.2 + */ + protected function canWrite(): bool + { + foreach ($this->repos as $repo) + { + if (!empty($repo->write_branch) && $repo->write_branch !== 'default') + { + return true; + } + } + + return false; + } + + /** + * Checks if two objects are equal by comparing their JSON representations. + * + * This method converts both input objects to JSON strings and compares these strings. + * If the JSON strings are identical, the objects are considered equal. + * + * @param object $obj1 The first object to compare. + * @param object $obj2 The second object to compare. + * + * @return bool True if the objects are equal, false otherwise. + * @since 3.2.2 + */ + protected function areObjectsEqual(object $obj1, object $obj2): bool + { + // Convert both objects to JSON strings + $json1 = json_encode($obj1); + $json2 = json_encode($obj2); + + // Compare the JSON strings + return $json1 === $json2; + } + + /** + * update an existing item (if changed) + * + * @param object $item + * @param object $existing + * + * @return void + * @since 3.2.2 + */ + protected function updateItem(object $item, object $existing): void + { + if (isset($existing->params->source) && is_array($existing->params->source)) + { + // get the source values + $source = $existing->params->source; + + // make sure there was a change + $existing = $this->mapItem($existing); + if ($this->areObjectsEqual($item, $existing)) + { + return; + } + + foreach ($this->repos as $repo) + { + if (isset($source[$repo->guid])) + { + $this->git->load_($repo->base ?? null, $repo->token ?? null); + $this->git->update( + $repo->organisation, // The owner name. + $repo->repository, // The repository name. + 'src/' . $item->guid . '/item.json', // The file path. + json_encode($item, JSON_PRETTY_PRINT), // The file content. + 'Update ' . $item->system_name, // The commit message. + $source[$repo->guid], // The blob SHA of the old file. + $repo->write_branch // The branch name. + ); + $this->git->reset_(); + + // only update in the first found repo + return; + } + } + } + } + + /** + * create a new item + * + * @param object $item + * + * @return void + * @since 3.2.2 + */ + protected function createItem(object $item): void + { + foreach ($this->repos as $repo) + { + if (!empty($repo->write_branch) && $repo->write_branch !== 'default') + { + $this->git->load_($repo->base ?? null, $repo->token ?? null); + $this->git->create( + $repo->organisation, // The owner name. + $repo->repository, // The repository name. + 'src/' . $item->guid . '/item.json', // The file path. + json_encode($item, JSON_PRETTY_PRINT), // The file content. + 'Create ' . $item->system_name, // The commit message. + $repo->write_branch // The branch name. + ); + $this->git->reset_(); + // only create in the first found repo + return; + } + } + } \ No newline at end of file diff --git a/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/settings.json b/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/settings.json new file mode 100644 index 0000000..c7530a0 --- /dev/null +++ b/src/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895/settings.json @@ -0,0 +1,32 @@ +{ + "add_head": "0", + "add_licensing_template": "2", + "extends": "", + "guid": "eb7d69c2-4ee9-4bd0-aacc-ab51a12be895", + "implements": null, + "load_selection": null, + "name": "Repository", + "power_version": "1.0.0", + "system_name": "VDM.Data.Repository", + "type": "class", + "use_selection": { + "use_selection0": { + "use": "c182506a-ab84-439c-b962-1e606b58d545", + "as": "Grep" + }, + "use_selection1": { + "use": "7212e4db-371f-4cfd-8122-32e9bb100d83", + "as": "Items" + }, + "use_selection2": { + "use": "8d1baef6-fcad-49a9-848f-428009cdb989", + "as": "Git" + } + }, + "extendsinterfaces": null, + "namespace": "[[[NamespacePrefix]]]\\Joomla\\Data.Repository", + "description": "Set data based on global unique ids to remote repository\r\n\r\n@since 3.2.2", + "licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe \r\n * @git Joomla Component Builder \r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n", + "head": "", + "composer": "" +} \ No newline at end of file diff --git a/super-powers.json b/super-powers.json index e5d03ce..0cfbc35 100644 --- a/super-powers.json +++ b/super-powers.json @@ -747,17 +747,6 @@ "spk": "Super__cce56585_58b0_4f72_a92c_e2635ea52d83__Power", "guid": "cce56585-58b0-4f72-a92c-e2635ea52d83" }, - "cddcac51-9a46-47c4-ba59-105c70453bd6": { - "name": "FilterHelper", - "type": "abstract class", - "namespace": "VDM\\Joomla\\Componentbuilder\\Utilities", - "code": "src\/cddcac51-9a46-47c4-ba59-105c70453bd6\/code.php", - "power": "src\/cddcac51-9a46-47c4-ba59-105c70453bd6\/code.power", - "settings": "src\/cddcac51-9a46-47c4-ba59-105c70453bd6\/settings.json", - "path": "src\/cddcac51-9a46-47c4-ba59-105c70453bd6", - "spk": "Super__cddcac51_9a46_47c4_ba59_105c70453bd6__Power", - "guid": "cddcac51-9a46-47c4-ba59-105c70453bd6" - }, "ce8cf834-6bac-44fb-941c-861f7e046cc0": { "name": "NamespaceHelper", "type": "abstract class", @@ -824,6 +813,17 @@ "spk": "Super__e0f6ddbe_2a35_4537_942c_faff2ebd04f6__Power", "guid": "e0f6ddbe-2a35-4537-942c-faff2ebd04f6" }, + "eb7d69c2-4ee9-4bd0-aacc-ab51a12be895": { + "name": "Repository", + "type": "class", + "namespace": "VDM\\Joomla\\Data", + "code": "src\/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895\/code.php", + "power": "src\/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895\/code.power", + "settings": "src\/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895\/settings.json", + "path": "src\/eb7d69c2-4ee9-4bd0-aacc-ab51a12be895", + "spk": "Super__eb7d69c2_4ee9_4bd0_aacc_ab51a12be895__Power", + "guid": "eb7d69c2-4ee9-4bd0-aacc-ab51a12be895" + }, "f3c04c28-bce4-422e-be93-7d163e4e342b": { "name": "Schema", "type": "abstract class",