Component Builder (v.5.1.1-beta2)
+ Component Builder (v.5.1.1-beta3)
The Component Builder for [Joomla](https://extensions.joomla.org/extension/component-builder/) is highly advanced tool that is truly able to build extremely complex components in a fraction of the time.
diff --git a/componentbuilder_update_server.xml b/componentbuilder_update_server.xml
index 1d8afd621..9f2e3a088 100644
--- a/componentbuilder_update_server.xml
+++ b/componentbuilder_update_server.xml
@@ -134,14 +134,14 @@
5.1.1-beta
https://dev.vdm.io
- https://github.com/vdm-io/pkg-component-builder/archive/refs/tags/v5.1.1-beta2.zip
+ https://github.com/vdm-io/pkg-component-builder/archive/refs/tags/v5.1.1-beta3.zip
beta
Llewellyn van der Merwe
https://dev.vdm.io
-
+
Component Builder
@@ -149,16 +149,16 @@
pkg_component_builder
package
site
- 5.1.1-beta2
+ 5.1.1-beta3
https://dev.vdm.io
- https://github.com/vdm-io/pkg-component-builder/archive/refs/tags/v5.1.1-beta2.zip
+ https://github.com/vdm-io/pkg-component-builder/archive/refs/tags/v5.1.1-beta3.zip
beta
Llewellyn van der Merwe
https://dev.vdm.io
-
+
\ No newline at end of file
diff --git a/libraries/vendor_jcb/VDM.Joomla.Gitea/src/Repository/Tags.php b/libraries/vendor_jcb/VDM.Joomla.Gitea/src/Repository/Tags.php
index 600bfc2b0..f2967178c 100644
--- a/libraries/vendor_jcb/VDM.Joomla.Gitea/src/Repository/Tags.php
+++ b/libraries/vendor_jcb/VDM.Joomla.Gitea/src/Repository/Tags.php
@@ -12,6 +12,7 @@
namespace VDM\Joomla\Gitea\Repository;
+use VDM\Joomla\Interfaces\Git\Repository\TagsInterface;
use VDM\Joomla\Gitea\Abstraction\Api;
@@ -20,7 +21,7 @@ use VDM\Joomla\Gitea\Abstraction\Api;
*
* @since 3.2.0
*/
-class Tags extends Api
+class Tags extends Api implements TagsInterface
{
/**
* List a repository's tags
diff --git a/libraries/vendor_jcb/VDM.Joomla.Gitea/src/Repository/Wiki.php b/libraries/vendor_jcb/VDM.Joomla.Gitea/src/Repository/Wiki.php
index 748860817..1a80320a4 100644
--- a/libraries/vendor_jcb/VDM.Joomla.Gitea/src/Repository/Wiki.php
+++ b/libraries/vendor_jcb/VDM.Joomla.Gitea/src/Repository/Wiki.php
@@ -12,6 +12,7 @@
namespace VDM\Joomla\Gitea\Repository;
+use VDM\Joomla\Interfaces\Git\Repository\WikiInterface;
use VDM\Joomla\Gitea\Abstraction\Api;
@@ -20,16 +21,16 @@ use VDM\Joomla\Gitea\Abstraction\Api;
*
* @since 3.2.0
*/
-class Wiki extends Api
+class Wiki extends Api implements WikiInterface
{
/**
* Create a wiki page.
*
- * @param string $owner The owner name.
- * @param string $repo The repository name.
- * @param string $title The title of the wiki page.
- * @param string $contentBase64 The base64 encoded content of the wiki page.
- * @param string|null $message Optional commit message summarizing the change.
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $title The title of the wiki page.
+ * @param string $contentBase64 The base64 encoded content of the wiki page.
+ * @param string|null $message Optional commit message summarizing the change.
*
* @return object|null
* @since 3.2.0
@@ -67,9 +68,9 @@ class Wiki extends Api
/**
* Get a wiki page.
*
- * @param string $owner The owner name.
- * @param string $repo The repository name.
- * @param string $pageName The name of the wiki page.
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $pageName The name of the wiki page.
*
* @return object|null
* @since 3.2.0
@@ -95,10 +96,10 @@ class Wiki extends Api
/**
* Get all wiki pages.
*
- * @param string $owner The owner name.
- * @param string $repo The repository name.
- * @param int $page Page number of results to return (1-based).
- * @param int $limit Page size of results.
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param int $page Page number of results to return (1-based).
+ * @param int $limit Page size of results.
*
* @return array|null
* @since 3.2.0
@@ -127,9 +128,9 @@ class Wiki extends Api
/**
* Delete a wiki page.
*
- * @param string $owner The owner name.
- * @param string $repo The repository name.
- * @param string $pageName The name of the wiki page.
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $pageName The name of the wiki page.
*
* @return string
* @since 3.2.0
@@ -155,12 +156,12 @@ class Wiki extends Api
/**
* Edit a wiki page.
*
- * @param string $owner The owner name.
- * @param string $repo The repository name.
- * @param string $pageName The name of the wiki page.
- * @param string $title The new title of the wiki page.
- * @param string $content The new content of the wiki page.
- * @param string $message The optional commit message summarizing the change.
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $pageName The name of the wiki page.
+ * @param string $title The new title of the wiki page.
+ * @param string $content The new content of the wiki page.
+ * @param string $message The optional commit message summarizing the change.
*
* @return object|null
* @since 3.2.0
@@ -199,10 +200,10 @@ class Wiki extends Api
/**
* Get revisions of a wiki page.
*
- * @param string $owner The owner name.
- * @param string $repo The repository name.
- * @param string $pageName The name of the wiki page.
- * @param int $page The page number of results to return (1-based).
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $pageName The name of the wiki page.
+ * @param int $page The page number of results to return (1-based).
*
* @return object|null
* @since 3.2.0
@@ -226,7 +227,6 @@ class Wiki extends Api
$this->uri->get($path)
)
);
- }
-
+ }
}
diff --git a/libraries/vendor_jcb/VDM.Joomla.Github/src/Abstraction/Api.php b/libraries/vendor_jcb/VDM.Joomla.Github/src/Abstraction/Api.php
index 9a5455deb..7598eb98b 100644
--- a/libraries/vendor_jcb/VDM.Joomla.Github/src/Abstraction/Api.php
+++ b/libraries/vendor_jcb/VDM.Joomla.Github/src/Abstraction/Api.php
@@ -19,7 +19,7 @@ use VDM\Joomla\Interfaces\Git\ApiInterface;
/**
- * The Gitea Api
+ * The Github Api
*
* @since 5.1.1
*/
@@ -98,10 +98,11 @@ abstract class Api implements ApiInterface
// for the rest of the container
if ($backup)
{
- if ($url !== null)
- {
- $this->url = $this->uri->getUrl();
- }
+ // Github has only one URL
+ // if ($url !== null)
+ // {
+ // $this->url = $this->uri->getUrl();
+ // }
if ($token !== null)
{
@@ -109,10 +110,11 @@ abstract class Api implements ApiInterface
}
}
- if ($url !== null)
- {
- $this->uri->setUrl($url);
- }
+ // Github has only one URL
+ // if ($url !== null)
+ // {
+ // $this->uri->setUrl($url);
+ // }
if ($token !== null)
{
@@ -128,11 +130,12 @@ abstract class Api implements ApiInterface
**/
public function reset_(): void
{
- if ($this->url !== null)
- {
- $this->uri->setUrl($this->url);
- $this->url = null;
- }
+ // Github has only one URL
+ // if ($this->url !== null)
+ // {
+ // $this->uri->setUrl($this->url);
+ // $this->url = null;
+ // }
if ($this->token !== null)
{
diff --git a/libraries/vendor_jcb/VDM.Joomla.Github/src/Factory.php b/libraries/vendor_jcb/VDM.Joomla.Github/src/Factory.php
new file mode 100644
index 000000000..591819da6
--- /dev/null
+++ b/libraries/vendor_jcb/VDM.Joomla.Github/src/Factory.php
@@ -0,0 +1,51 @@
+
+ * @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\Github;
+
+
+use Joomla\DI\Container;
+use VDM\Joomla\Github\Service\Utilities;
+use VDM\Joomla\Componentbuilder\Power\Service\Github;
+use VDM\Joomla\Interfaces\FactoryInterface;
+use VDM\Joomla\Abstraction\Factory as ExtendingFactory;
+
+
+/**
+ * Github Factory
+ *
+ * @since 5.1.1
+ */
+abstract class Factory extends ExtendingFactory implements FactoryInterface
+{
+ /**
+ * Package Container
+ *
+ * @var Container|null
+ * @since 5.0.3
+ **/
+ protected static ?Container $container = null;
+
+ /**
+ * Create a container object
+ *
+ * @return Container
+ * @since 3.2.0
+ */
+ protected static function createContainer(): Container
+ {
+ return (new Container())
+ ->registerServiceProvider(new Utilities())
+ ->registerServiceProvider(new Github());
+ }
+
+}
+
diff --git a/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Contents.php b/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Contents.php
index 9969c1327..ec86007a9 100644
--- a/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Contents.php
+++ b/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Contents.php
@@ -21,7 +21,7 @@ use VDM\Joomla\Github\Abstraction\Api;
*
* @since 5.1.1
*/
-class Contents extends Api implements ContentsInterface
+final class Contents extends Api implements ContentsInterface
{
/**
* Get a file from a repository.
diff --git a/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Tags.php b/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Tags.php
new file mode 100644
index 000000000..e05d16349
--- /dev/null
+++ b/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Tags.php
@@ -0,0 +1,186 @@
+
+ * @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\Github\Repository;
+
+
+use VDM\Joomla\Interfaces\Git\Repository\TagsInterface;
+use VDM\Joomla\Github\Abstraction\Api;
+
+
+/**
+ * The Github Repository Tags
+ *
+ * @since 5.1.1
+ */
+final class Tags extends Api implements TagsInterface
+{
+ /**
+ * List a repository's tags
+ *
+ * @param string $owner The owner of the repo.
+ * @param string $repo The name of the repo.
+ * @param int|null $page The page number of results to return (1-based).
+ * @param int|null $limit The page size of results. GitHub default is 30, max 100. Here we fix it to 10.
+ *
+ * @return array|null
+ * @since 3.2.0
+ */
+ public function list(
+ string $owner,
+ string $repo,
+ ?int $page = 1,
+ ?int $limit = 10
+ ): ?array {
+ $path = "/repos/{$owner}/{$repo}/tags";
+ $uri = $this->uri->get($path);
+
+ $uri->setVar('page', $page ?? 1);
+ $uri->setVar('per_page', $limit ?? 10);
+
+ return $this->response->get(
+ $this->http->get($uri)
+ );
+ }
+
+ /**
+ * Get the tag object by tag name (loop until found or exhausted).
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $tag The tag name to find.
+ *
+ * @return object|null
+ * @since 3.2.0
+ */
+ public function get(string $owner, string $repo, string $tag): ?object
+ {
+ $page = 1;
+ $limit = 10;
+
+ do {
+ $tags = $this->list($owner, $repo, $page, $limit);
+
+ if (empty($tags))
+ {
+ return null;
+ }
+
+ foreach ($tags as $entry)
+ {
+ if (isset($entry->name) && $entry->name === $tag)
+ {
+ return $entry;
+ }
+ }
+
+ $page++;
+ } while (count($tags) === $limit);
+
+ return null;
+ }
+
+ /**
+ * Get the annotated tag object by SHA.
+ *
+ * @param string $owner The owner of the repo.
+ * @param string $repo The repository name.
+ * @param string $sha The tag object SHA.
+ *
+ * @return object|null
+ * @since 3.2.0
+ */
+ public function sha(string $owner, string $repo, string $sha): ?object
+ {
+ $path = "/repos/{$owner}/{$repo}/git/tags/{$sha}";
+ return $this->response->get(
+ $this->http->get($this->uri->get($path))
+ );
+ }
+
+ /**
+ * Create a new annotated tag and attach it to the repository.
+ *
+ * GitHub requires two steps to create a tag:
+ * 1. Create an annotated tag object.
+ * 2. Create a reference to the tag under `refs/tags/*`.
+ *
+ * @param string $owner The owner of the repo.
+ * @param string $repo The repository name.
+ * @param string $tagName The name of the tag.
+ * @param string $target The SHA the tag points to (usually a commit SHA).
+ * @param string $message The tag message.
+ *
+ * @return object|null
+ * @since 3.2.0
+ */
+ public function create(string $owner, string $repo, string $tagName, string $target, string $message): ?object
+ {
+ // Step 1: Create the tag object
+ $tagObject = (object) [
+ 'tag' => $tagName,
+ 'message' => $message,
+ 'object' => $target,
+ 'type' => 'commit'
+ ];
+
+ $tagResponse = $this->response->get(
+ $this->http->post(
+ $this->uri->get("/repos/{$owner}/{$repo}/git/tags"),
+ json_encode($tagObject)
+ )
+ );
+
+ if (!isset($tagResponse->sha))
+ {
+ return null;
+ }
+
+ // Step 2: Create the ref pointing to the tag object
+ $refData = (object) [
+ 'ref' => "refs/tags/{$tagName}",
+ 'sha' => $tagResponse->sha
+ ];
+
+ return $this->response->get(
+ $this->http->post(
+ $this->uri->get("/repos/{$owner}/{$repo}/git/refs"),
+ json_encode($refData)
+ )
+ );
+ }
+
+ /**
+ * Delete a tag reference by tag name.
+ *
+ * GitHub deletes tags via refs.
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $tag The tag name to delete.
+ *
+ * @return string Returns 'success' on successful deletion.
+ * @since 3.2.0
+ */
+ public function delete(string $owner, string $repo, string $tag): string
+ {
+ $path = "/repos/{$owner}/{$repo}/git/refs/tags/{$tag}";
+
+ return $this->response->get(
+ $this->http->delete(
+ $this->uri->get($path)
+ ),
+ 204,
+ 'success'
+ );
+ }
+}
+
diff --git a/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Wiki.php b/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Wiki.php
new file mode 100644
index 000000000..ba6e9c345
--- /dev/null
+++ b/libraries/vendor_jcb/VDM.Joomla.Github/src/Repository/Wiki.php
@@ -0,0 +1,166 @@
+
+ * @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\Github\Repository;
+
+
+use VDM\Joomla\Interfaces\Git\Repository\WikiInterface;
+use VDM\Joomla\Github\Abstraction\Api;
+use Joomla\CMS\Uri\Uri;
+
+
+/**
+ * The Github Repository Wiki
+ *
+ * @since 5.1.1
+ */
+class Wiki extends Api implements WikiInterface
+{
+ /**
+ * Create a new wiki page or update it if it already exists.
+ *
+ * @param string $owner Repository owner (user or organization).
+ * @param string $repo Repository name (without `.wiki`).
+ * @param string $title Title of the wiki page.
+ * @param string $contentBase64 Base64-encoded Markdown content.
+ * @param string|null $message Optional commit message.
+ *
+ * @return object|null API response object or null on failure.
+ * @since 5.1.1
+ */
+ public function create(
+ string $owner,
+ string $repo,
+ string $title,
+ string $contentBase64,
+ ?string $message = null
+ ): ?object
+ {
+ return null; // github does not support wiki over API
+ }
+
+ /**
+ * Retrieve the content of a specific wiki page.
+ *
+ * @param string $owner Repository owner (user or organization).
+ * @param string $repo Repository name (without `.wiki`).
+ * @param string $pageName Name of the page (excluding `.md`).
+ *
+ * @return object|null Page details including content and metadata, or null on failure.
+ * @since 5.1.1
+ */
+ public function get(
+ string $owner,
+ string $repo,
+ string $pageName
+ ): ?object
+ {
+ // Build the raw wiki URL
+ $url = "https://raw.githubusercontent.com/wiki/{$owner}/{$repo}/{$pageName}.md";
+
+ // Use a direct HTTP GET request (bypasses GitHub API)
+ $body = $this->response->get(
+ $this->http->get(new Uri($url), [])
+ );
+
+ return (object) [
+ 'name' => "{$pageName}.md",
+ 'content' => base64_encode($body),
+ ];
+ }
+
+ /**
+ * List all wiki pages in the repository.
+ *
+ * @param string $owner Repository owner (user or organization).
+ * @param string $repo Repository name (without `.wiki`).
+ * @param int $page Pagination index (1-based).
+ * @param int $limit Number of results per page.
+ *
+ * @return array|null List of page metadata or null on failure.
+ * @since 5.1.1
+ */
+ public function pages(
+ string $owner,
+ string $repo,
+ int $page = 1,
+ int $limit = 10
+ ): ?array
+ {
+ return null; // github does not support wiki over API
+ }
+
+ /**
+ * Delete a wiki page from the repository.
+ *
+ * @param string $owner Repository owner (user or organization).
+ * @param string $repo Repository name (without `.wiki`).
+ * @param string $pageName Name of the page to delete (excluding `.md`).
+ *
+ * @return string 'success' on deletion, or error message if the page was not found.
+ * @since 5.1.1
+ */
+ public function delete(
+ string $owner,
+ string $repo,
+ string $pageName
+ ): string
+ {
+ return 'error'; // github does not support wiki over API
+ }
+
+ /**
+ * Edit an existing wiki page.
+ *
+ * @param string $owner Repository owner (user or organization).
+ * @param string $repo Repository name (without `.wiki`).
+ * @param string $pageName Name of the page to edit (excluding `.md`).
+ * @param string $title New title of the page (used to rename if applicable).
+ * @param string $content Updated Markdown content.
+ * @param string|null $message Optional commit message.
+ *
+ * @return object|null API response object or null if the page doesn't exist.
+ * @since 5.1.1
+ */
+ public function edit(
+ string $owner,
+ string $repo,
+ string $pageName,
+ string $title,
+ string $content,
+ string $message = null
+ ): ?object
+ {
+ return null; // github does not support wiki over API
+ }
+
+ /**
+ * Get the commit history (revisions) for a specific wiki page.
+ *
+ * @param string $owner Repository owner (user or organization).
+ * @param string $repo Repository name (without `.wiki`).
+ * @param string $pageName Name of the page to retrieve revisions for (excluding `.md`).
+ * @param int $page Pagination index (1-based).
+ *
+ * @return object|null API response object with commit history or null on failure.
+ * @since 5.1.1
+ */
+ public function revisions(
+ string $owner,
+ string $repo,
+ string $pageName,
+ int $page = 1
+ ): ?object
+ {
+ return null; // github does not support wiki over API
+ }
+}
+
diff --git a/libraries/vendor_jcb/VDM.Joomla.Github/src/Service/Utilities.php b/libraries/vendor_jcb/VDM.Joomla.Github/src/Service/Utilities.php
index 2dabe2d5d..ed19f0fc2 100644
--- a/libraries/vendor_jcb/VDM.Joomla.Github/src/Service/Utilities.php
+++ b/libraries/vendor_jcb/VDM.Joomla.Github/src/Service/Utilities.php
@@ -14,6 +14,7 @@ namespace VDM\Joomla\Github\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
+use VDM\Joomla\Utilities\Component\Helper;
use VDM\Joomla\Github\Utilities\Http;
use VDM\Joomla\Github\Utilities\Uri;
use VDM\Joomla\Github\Utilities\Response;
@@ -56,7 +57,9 @@ class Utilities implements ServiceProviderInterface
*/
public function getHttp(Container $container): Http
{
- return new Http();
+ return new Http(
+ Helper::getParams('com_componentbuilder')->get('github_access_token') ?? null
+ );
}
/**
diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionDashboard.php b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionDashboard.php
index ac3c8c43d..578a75d29 100644
--- a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionDashboard.php
+++ b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionDashboard.php
@@ -44,21 +44,25 @@ final class PermissionDashboard extends Registry implements Registryinterface
use VarExport;
/**
- * Get the build permission dashboard code
+ * Get the build permission dashboard code.
*
- * @return string
- * @since 3.2.0
+ * @return string
+ * @since 3.2.0
+ * @since 5.1.1 Changed to class property.
*/
public function build(): string
{
- if ($this->isActive())
- {
- return PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__)
- . " view access array" . PHP_EOL . Indent::_(2)
- . "\$viewAccess = " . $this->varExport() . ';';
- }
+ $indent = Indent::_(1);
+ $docBlock = PHP_EOL . $indent . '/**'
+ . PHP_EOL . $indent . ' *' . Line::_(__LINE__, __CLASS__) . ' View access array.'
+ . PHP_EOL . $indent . ' *'
+ . PHP_EOL . $indent . ' * @var array'
+ . PHP_EOL . $indent . ' * @since 5.1.1'
+ . PHP_EOL . $indent . ' */';
- return '';
+ $value = $this->isActive() ? $this->varExport(null, 1) : '[]';
+
+ return $docBlock . PHP_EOL . $indent . 'protected array $viewAccess = ' . $value . ';' . PHP_EOL;
}
}
diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Power/Service/Github.php b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Power/Service/Github.php
index 5034af963..5277309a3 100644
--- a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Power/Service/Github.php
+++ b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Power/Service/Github.php
@@ -15,6 +15,8 @@ namespace VDM\Joomla\Componentbuilder\Power\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use VDM\Joomla\Github\Repository\Contents;
+use VDM\Joomla\Github\Repository\Tags;
+use VDM\Joomla\Github\Repository\Wiki;
/**
@@ -36,6 +38,12 @@ class Github implements ServiceProviderInterface
{
$container->alias(Contents::class, 'Github.Repository.Contents')
->share('Github.Repository.Contents', [$this, 'getContents'], true);
+
+ $container->alias(Tags::class, 'Github.Repository.Tags')
+ ->share('Github.Repository.Tags', [$this, 'getTags'], true);
+
+ $container->alias(Wiki::class, 'Github.Repository.Wiki')
+ ->share('Github.Repository.Wiki', [$this, 'getWiki'], true);
}
/**
@@ -53,6 +61,40 @@ class Github implements ServiceProviderInterface
$container->get('Github.Utilities.Uri'),
$container->get('Github.Utilities.Response')
);
+ }
+
+ /**
+ * Get the Tags class
+ *
+ * @param Container $container The DI container.
+ *
+ * @return Tags
+ * @since 5.1.1
+ */
+ public function getTags(Container $container): Tags
+ {
+ return new Tags(
+ $container->get('Github.Utilities.Http'),
+ $container->get('Github.Utilities.Uri'),
+ $container->get('Github.Utilities.Response')
+ );
+ }
+
+ /**
+ * Get the Wiki class
+ *
+ * @param Container $container The DI container.
+ *
+ * @return Wiki
+ * @since 5.1.1
+ */
+ public function getWiki(Container $container): Wiki
+ {
+ return new Wiki(
+ $container->get('Github.Utilities.Http'),
+ $container->get('Github.Utilities.Uri'),
+ $container->get('Github.Utilities.Response')
+ );
}
}
diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Remote/Version.php b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Remote/Version.php
new file mode 100644
index 000000000..71fe04cf2
--- /dev/null
+++ b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Remote/Version.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\Componentbuilder\Remote;
+
+
+use Joomla\CMS\Language\Text;
+use VDM\Joomla\Github\Factory as Github;
+use VDM\Joomla\Gitea\Factory as Gitea;
+use VDM\Component\Componentbuilder\Administrator\Helper\ComponentbuilderHelper;
+
+
+/**
+ * Get Remote Version
+ *
+ * @since 5.1.1
+ */
+final class Version
+{
+ /**
+ * GitHub organization name.
+ *
+ * @var string
+ * @since 5.1.1
+ */
+ protected string $githubOrg;
+
+ /**
+ * GitHub repository name.
+ *
+ * @var string
+ * @since 5.1.1
+ */
+ protected string $githubRepo;
+
+ /**
+ * Gitea organization name.
+ *
+ * @var string
+ * @since 5.1.1
+ */
+ protected string $giteaOrg;
+
+ /**
+ * Gitea repository name.
+ *
+ * @var string
+ * @since 5.1.1
+ */
+ protected string $giteaRepo;
+
+ /**
+ * Constructor to set repository organization and name for both GitHub and Gitea.
+ *
+ * @param string $githubOrg GitHub organization name.
+ * @param string $githubRepo GitHub repository name.
+ * @param string $giteaOrg Gitea organization name.
+ * @param string $giteaRepo Gitea repository name.
+ *
+ * @since 5.1.1
+ */
+ public function __construct(string $githubOrg, string $githubRepo, string $giteaOrg, string $giteaRepo)
+ {
+ $this->githubOrg = $githubOrg;
+ $this->githubRepo = $githubRepo;
+ $this->giteaOrg = $giteaOrg;
+ $this->giteaRepo = $giteaRepo;
+ }
+
+ /**
+ * Get the current version notice.
+ *
+ * Compares the installed version of the component with the latest available
+ * version from the repository tags and returns an appropriate message.
+ *
+ * @param string|null $version Optional version to compare if manifest version not found.
+ *
+ * @return array The array with 'notice' or 'error' and optional 'github-error' / 'gitea-error'.
+ * @since 5.1.1
+ */
+ public function get(?string $version = null): array
+ {
+ $defaultDownloadLink = 'https://git.vdm.dev/joomla/pkg-component-builder/releases';
+
+ $manifest = ComponentbuilderHelper::manifest();
+ $localVersion = (string) ($manifest->version ?? $version ?? '1.0.0');
+ $major = explode('.', $localVersion)[0] ?? '1';
+
+ $errors = [
+ 'error' => Text::sprintf(
+ 'There was an error getting the %sVersion details.',
+ ''
+ )
+ ];
+
+ $tags = $this->getRepositoryTags($errors);
+
+ if (empty($tags) || !isset($tags[0]->name))
+ {
+ return $this->mergeErrors($errors);
+ }
+
+ $grouped = $this->groupTagsByType($tags, $major);
+
+ $latestStableTag = $grouped['stable'][0] ?? null;
+ $latestStableVer = $latestStableTag ? ltrim($latestStableTag->name, 'vV') : '1.0.0';
+ $latestStableLink = $latestStableTag->zipball_url ?? $defaultDownloadLink;
+
+ $versionType = $this->getVersionType($localVersion);
+ $versionCompare = version_compare($localVersion, $latestStableVer);
+
+ // Handle pre-release versions
+ if ($versionType !== 'stable')
+ {
+ $isLatestPre = $this->isLatestPreRelease($localVersion, $grouped['pre']);
+
+ $state = $isLatestPre ? Text::_('COM_COMPONENTBUILDER_PRE_RELEASE') : Text::_('COM_COMPONENTBUILDER_OUT_OF_DATE');
+ $statement = sprintf(
+ ' %s',
+ $state
+ );
+
+ $color = $isLatestPre ? '#F7B033' : 'red';
+ $state = $isLatestPre
+ ? Text::sprintf("COM_COMPONENTBUILDER_THANK_YOU_FOR_TESTING_THE_S_RELEASE_YOURE_A_JCB_HERO", strtoupper($versionType))
+ : Text::sprintf("COM_COMPONENTBUILDER_GRAB_THE_LATEST_S_TESTING_RELEASE", strtoupper($versionType));
+
+ $notice = sprintf(
+ ' %s',
+ $color, $grouped['pre'][0]->zipball_url ?? $defaultDownloadLink, $state, $statement
+ );
+
+ return ['notice' => $notice];
+ }
+
+ // Stable and up-to-date
+ if ($versionCompare === 0)
+ {
+ $notice = sprintf(
+ ' %s',
+ Text::_('COM_COMPONENTBUILDER_UP_TO_DATE')
+ );
+
+ if (!empty($grouped['pre']))
+ {
+ $notice = sprintf(
+ ' %s',
+ $grouped['pre'][0]->zipball_url ?? $defaultDownloadLink,
+ Text::_('COM_COMPONENTBUILDER_HELP_US_TEST_THE_UPCOMING_RELEASE'),
+ $notice
+ );
+ }
+
+ return ['notice' => $notice];
+ }
+
+ // Stable but outdated
+ return ['notice' => sprintf(
+ ' %s ' .
+ '%s',
+ Text::_('COM_COMPONENTBUILDER_OUT_OF_DATE') . '!',
+ $latestStableLink,
+ Text::_('COM_COMPONENTBUILDER_YOU_CAN_DIRECTLY_DOWNLOAD_THE_LATEST_UPDATE_OR_USE_THE_JOOMLA_UPDATE_AREA'),
+ Text::_('COM_COMPONENTBUILDER_DOWNLOAD_UPDATE') . '!'
+ )];
+ }
+
+ /**
+ * Check if the local pre-release version is the latest.
+ *
+ * @param string $localVersion The current local version.
+ * @param array $preTags All matching pre-release tags.
+ *
+ * @return bool
+ * @since 5.1.1
+ */
+ protected function isLatestPreRelease(string $localVersion, array $preTags): bool
+ {
+ if (empty($preTags))
+ {
+ return false;
+ }
+
+ usort($preTags, static fn($a, $b) => version_compare($b->name, $a->name));
+
+ $latestPre = ltrim($preTags[0]->name, 'vV');
+
+ return version_compare($localVersion, $latestPre) === 0;
+ }
+
+ /**
+ * Fetch tags from GitHub or fallback to various Gitea instances.
+ *
+ * Appends source keys to the return array on failure.
+ *
+ * @param array &$errors The response array to populate error messages into.
+ *
+ * @return array List of tags or an empty array.
+ * @since 5.1.1
+ */
+ protected function getRepositoryTags(array &$errors): array
+ {
+ // Attempt GitHub fetch
+ if ($tags = $this->tryFetchTags('github', $errors))
+ {
+ return $tags;
+ }
+
+ // Try default VDM Gitea instance
+ if ($tags = $this->tryFetchTags('gitea', $errors))
+ {
+ return $tags;
+ }
+
+ // Try alternative Gitea hosts
+ $alternatives = [
+ 'codeberg' => 'https://codeberg.org',
+ 'tildegit' => 'https://tildegit.org',
+ 'disroot' => 'https://git.disroot.org',
+ ];
+
+ foreach ($alternatives as $key => $url)
+ {
+ Gitea::_('Gitea.Repository.Tags')->load_($url, '');
+ if ($tags = $this->tryFetchTags($key, $errors))
+ {
+ return $tags;
+ }
+ }
+
+ // Final reset to default host
+ return [];
+ }
+
+ /**
+ * Attempt to fetch tags from a given source and record any error.
+ *
+ * @param string $source One of: 'github', 'gitea', 'codeberg', 'tildegit', 'disroot'.
+ * @param array &$errors Reference to return array for error recording.
+ *
+ * @return array|null List of tags or null on failure.
+ * @since 5.1.1
+ */
+ protected function tryFetchTags(string $source, array &$errors): ?array
+ {
+ try {
+ return match ($source) {
+ 'github' => Github::_('Github.Repository.Tags')->list($this->githubOrg, $this->githubRepo),
+ default => Gitea::_('Gitea.Repository.Tags')->list($this->giteaOrg, $this->giteaRepo),
+ };
+ } catch (\Throwable $e) {
+ $errors["{$source}-error"] = $e->getMessage();
+ } finally {
+ if ($source !== 'github' && $source !== 'gitea') {
+ Gitea::_('Gitea.Repository.Tags')->reset_();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Groups and sorts tags into stable and pre-release arrays.
+ *
+ * @param array $tags List of repository tags.
+ * @param string $major Major version prefix to match.
+ *
+ * @return array{stable: array, pre: array}
+ * @since 5.1.1
+ */
+ protected function groupTagsByType(array $tags, string $major): array
+ {
+ $stable = [];
+ $pre = [];
+
+ foreach ($tags as $tag)
+ {
+ if (!isset($tag->name) || strpos($tag->name, 'v' . $major) !== 0)
+ {
+ continue;
+ }
+
+ $version = strtolower($tag->name);
+
+ if (preg_match('/-(alpha|beta|rc)\d*/', $version)) {
+ $pre[] = $tag;
+ } else {
+ $stable[] = $tag;
+ }
+ }
+
+ usort($stable, static fn($a, $b) => version_compare($b->name, $a->name));
+ usort($pre, static fn($a, $b) => version_compare($b->name, $a->name));
+
+ return ['stable' => $stable, 'pre' => $pre];
+ }
+
+ /**
+ * Determine the version type from the string.
+ *
+ * @param string $version The version string to analyze.
+ *
+ * @return string 'stable', 'alpha', 'beta' or 'rc'.
+ * @since 5.1.1
+ */
+ protected function getVersionType(string $version): string
+ {
+ $version = strtolower($version);
+
+ if (str_contains($version, '-alpha'))
+ {
+ return 'alpha';
+ }
+
+ if (str_contains($version, '-beta'))
+ {
+ return 'beta';
+ }
+
+ if (str_contains($version, '-rc'))
+ {
+ return 'rc';
+ }
+
+ return 'stable';
+ }
+
+ /**
+ * Merge repository fetch errors into the error message as a toggleable Bootstrap block.
+ *
+ * This enhances the 'error' message by appending a red icon and a collapsible
+ * section with the actual GitHub/Gitea error messages.
+ *
+ * @param array $errors The array containing at least 'error' and optionally error details.
+ *
+ * @return array The modified array with a richer 'error' message.
+ * @since 5.1.1
+ */
+ protected function mergeErrors(array $errors): array
+ {
+ $bucket = [];
+
+ foreach ($errors as $key => $value)
+ {
+ if ($key !== 'error')
+ {
+ $source = ucfirst(explode('-', $key)[0]);
+ $bucket[] = '' . $source . ': ' . htmlspecialchars($value) . '';
+ }
+ }
+
+ if (empty($bucket))
+ {
+ return $errors;
+ }
+
+ $uid = uniqid('version-error-');
+
+ $toggle = sprintf(
+ ' ' .
+ ' %s',
+ $uid,
+ $uid,
+ Text::_('COM_COMPONENTBUILDER_DETAILS')
+ );
+
+ $details = sprintf(
+ '',
+ $uid,
+ implode('', $bucket)
+ );
+
+ $errors['error'] .= $toggle . $details;
+
+ return $errors;
+ }
+}
+
diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Remote/index.html b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Remote/index.html
new file mode 100644
index 000000000..fa6d84e80
--- /dev/null
+++ b/libraries/vendor_jcb/VDM.Joomla/src/Componentbuilder/Remote/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Interfaces/Git/Repository/TagsInterface.php b/libraries/vendor_jcb/VDM.Joomla/src/Interfaces/Git/Repository/TagsInterface.php
new file mode 100644
index 000000000..edd8eb983
--- /dev/null
+++ b/libraries/vendor_jcb/VDM.Joomla/src/Interfaces/Git/Repository/TagsInterface.php
@@ -0,0 +1,107 @@
+
+ * @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\Interfaces\Git\Repository;
+
+
+use VDM\Joomla\Interfaces\Git\ApiInterface;
+
+
+/**
+ * The Git Repository Tags Interface
+ *
+ * @since 5.1.1
+ */
+interface TagsInterface extends ApiInterface
+{
+ /**
+ * List a repository's tags
+ *
+ * @param string $owner The owner of the repo.
+ * @param string $repo The name of the repo.
+ * @param int|null $page The page number of results to return (1-based).
+ * @param int|null $limit The page size of results, default maximum page size is 10.
+ *
+ * @return array|null
+ * @since 3.2.0
+ **/
+ public function list(
+ string $owner,
+ string $repo,
+ ?int $page = 1,
+ ?int $limit = 10
+ ): ?array;
+
+ /**
+ * Get the tag of a repository by tag name.
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $tag The tag name.
+ *
+ * @return object|null
+ * @since 3.2.0
+ **/
+ public function get(string $owner, string $repo, string $tag): ?object;
+
+ /**
+ * Get the tag object of an annotated tag (not lightweight tags).
+ *
+ * @param string $owner The owner of the repo.
+ * @param string $repo The name of the repo.
+ * @param string $sha The sha of the tag. The Git tags API only supports annotated tag objects, not lightweight tags.
+ *
+ * @return object|null
+ * @since 3.2.0
+ **/
+ public function sha(
+ string $owner,
+ string $repo,
+ string $sha
+ ): ?object;
+
+ /**
+ * Create a new git tag in a repository.
+ *
+ * @param string $owner The owner of the repo.
+ * @param string $repo The name of the repo.
+ * @param string $tagName The name of the tag.
+ * @param string $target The SHA of the git object this is tagging.
+ * @param string $message The tag message.
+ *
+ * @return object|null
+ * @since 3.2.0
+ **/
+ public function create(
+ string $owner,
+ string $repo,
+ string $tagName,
+ string $target,
+ string $message
+ ): ?object;
+
+ /**
+ * Delete a repository's tag by name.
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $tag The tag name.
+ *
+ * @return string
+ * @since 3.2.0
+ **/
+ public function delete(
+ string $owner,
+ string $repo,
+ string $tag
+ ): string;
+}
+
diff --git a/libraries/vendor_jcb/VDM.Joomla/src/Interfaces/Git/Repository/WikiInterface.php b/libraries/vendor_jcb/VDM.Joomla/src/Interfaces/Git/Repository/WikiInterface.php
new file mode 100644
index 000000000..bf169569f
--- /dev/null
+++ b/libraries/vendor_jcb/VDM.Joomla/src/Interfaces/Git/Repository/WikiInterface.php
@@ -0,0 +1,135 @@
+
+ * @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\Interfaces\Git\Repository;
+
+
+use VDM\Joomla\Interfaces\Git\ApiInterface;
+
+
+/**
+ * The Git Repository Wiki Interface
+ *
+ * @since 5.1.1
+ */
+interface WikiInterface extends ApiInterface
+{
+ /**
+ * Create a wiki page.
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $title The title of the wiki page.
+ * @param string $contentBase64 The base64 encoded content of the wiki page.
+ * @param string|null $message Optional commit message summarizing the change.
+ *
+ * @return object|null
+ * @since 3.2.0
+ **/
+ public function create(
+ string $owner,
+ string $repo,
+ string $title,
+ string $contentBase64,
+ ?string $message = null
+ ): ?object;
+
+ /**
+ * Get a wiki page.
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $pageName The name of the wiki page.
+ *
+ * @return object|null
+ * @since 3.2.0
+ **/
+ public function get(
+ string $owner,
+ string $repo,
+ string $pageName
+ ): ?object;
+
+ /**
+ * Get all wiki pages.
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param int $page Page number of results to return (1-based).
+ * @param int $limit Page size of results.
+ *
+ * @return array|null
+ * @since 3.2.0
+ **/
+ public function pages(
+ string $owner,
+ string $repo,
+ int $page = 1,
+ int $limit = 10
+ ): ?array;
+
+ /**
+ * Delete a wiki page.
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $pageName The name of the wiki page.
+ *
+ * @return string
+ * @since 3.2.0
+ **/
+ public function delete(
+ string $owner,
+ string $repo,
+ string $pageName
+ ): string;
+
+ /**
+ * Edit a wiki page.
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $pageName The name of the wiki page.
+ * @param string $title The new title of the wiki page.
+ * @param string $content The new content of the wiki page.
+ * @param string $message The optional commit message summarizing the change.
+ *
+ * @return object|null
+ * @since 3.2.0
+ **/
+ public function edit(
+ string $owner,
+ string $repo,
+ string $pageName,
+ string $title,
+ string $content,
+ string $message = null
+ ): ?object;
+
+ /**
+ * Get revisions of a wiki page.
+ *
+ * @param string $owner The owner name.
+ * @param string $repo The repository name.
+ * @param string $pageName The name of the wiki page.
+ * @param int $page The page number of results to return (1-based).
+ *
+ * @return object|null
+ * @since 3.2.0
+ **/
+ public function revisions(
+ string $owner,
+ string $repo,
+ string $pageName,
+ int $page = 1
+ ): ?object;
+}
+