From b6b101be3a0472b3dbd6bb2a148f2037c12ba822 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:06:36 +0000 Subject: [PATCH 01/28] chore: sync auto-release.yml from Template-Generic [skip ci] --- .mokogitea/workflows/auto-release.yml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.mokogitea/workflows/auto-release.yml b/.mokogitea/workflows/auto-release.yml index 4489ae0..8337c71 100644 --- a/.mokogitea/workflows/auto-release.yml +++ b/.mokogitea/workflows/auto-release.yml @@ -64,10 +64,14 @@ jobs: promote-rc: name: Promote to RC runs-on: release + # Skip on template repos (Template-*) — they scaffold other repos and do not release. if: >- - (github.event.action == 'opened' && github.event.pull_request.merged != true) || - (github.event.action == 'synchronize' && github.event.pull_request.merged != true) || - (github.event_name == 'workflow_dispatch' && inputs.action == 'promote-rc') + !startsWith(github.event.repository.name, 'Template-') && + ( + (github.event.action == 'opened' && github.event.pull_request.merged != true) || + (github.event.action == 'synchronize' && github.event.pull_request.merged != true) || + (github.event_name == 'workflow_dispatch' && inputs.action == 'promote-rc') + ) steps: - name: Checkout repository @@ -164,9 +168,13 @@ jobs: release: name: Build & Release Pipeline runs-on: release + # Skip on template repos (Template-*) — they scaffold other repos and do not release. if: >- - github.event.pull_request.merged == true || - (github.event_name == 'workflow_dispatch' && inputs.action != 'promote-rc') + !startsWith(github.event.repository.name, 'Template-') && + ( + github.event.pull_request.merged == true || + (github.event_name == 'workflow_dispatch' && inputs.action != 'promote-rc') + ) steps: - name: Checkout repository From 318b1469e33dcb1a129f1509056dab523b7a55a6 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:06:37 +0000 Subject: [PATCH 02/28] chore: sync ci-generic.yml from Template-Generic [skip ci] --- .mokogitea/workflows/ci-generic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mokogitea/workflows/ci-generic.yml b/.mokogitea/workflows/ci-generic.yml index 92d2685..3a942ad 100644 --- a/.mokogitea/workflows/ci-generic.yml +++ b/.mokogitea/workflows/ci-generic.yml @@ -6,7 +6,7 @@ # DEFGROUP: Gitea.Workflow # INGROUP: MokoStandards.CI # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic -# PATH: /.gitea/workflows/ci-generic.yml +# PATH: /.mokogitea/workflows/ci-generic.yml # VERSION: 01.00.00 # BRIEF: CI pipeline — lint, validate, and test for generic projects (PHP + Node.js) From 679268874035eaa06a86f7f8d8962e7eda87c1a2 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:06:38 +0000 Subject: [PATCH 03/28] chore: sync cleanup.yml from Template-Generic [skip ci] --- .mokogitea/workflows/cleanup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mokogitea/workflows/cleanup.yml b/.mokogitea/workflows/cleanup.yml index 0023862..2e6b6a2 100644 --- a/.mokogitea/workflows/cleanup.yml +++ b/.mokogitea/workflows/cleanup.yml @@ -6,7 +6,7 @@ # DEFGROUP: Gitea.Workflow # INGROUP: MokoStandards.Maintenance # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards -# PATH: /.gitea/workflows/cleanup.yml +# PATH: /.mokogitea/workflows/cleanup.yml # VERSION: 01.00.00 # BRIEF: Scheduled cleanup — delete merged branches and old workflow runs From caaedfdff5fbddde7dc11f77a833bfc84e70f7ef Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:06:39 +0000 Subject: [PATCH 04/28] chore: sync notify.yml from Template-Generic [skip ci] --- .mokogitea/workflows/notify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mokogitea/workflows/notify.yml b/.mokogitea/workflows/notify.yml index 51dfcb5..9dfa047 100644 --- a/.mokogitea/workflows/notify.yml +++ b/.mokogitea/workflows/notify.yml @@ -6,7 +6,7 @@ # DEFGROUP: Gitea.Workflow # INGROUP: MokoStandards.Notifications # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards -# PATH: /.gitea/workflows/notify.yml +# PATH: /.mokogitea/workflows/notify.yml # VERSION: 01.00.00 # BRIEF: Push notifications via ntfy on release success or workflow failure From c5f4daa2e64e83013c8957126d0282c91d86bca8 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:06:40 +0000 Subject: [PATCH 05/28] chore: sync pr-check.yml from Template-Generic [skip ci] --- .mokogitea/workflows/pr-check.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.mokogitea/workflows/pr-check.yml b/.mokogitea/workflows/pr-check.yml index c834bf5..1652713 100644 --- a/.mokogitea/workflows/pr-check.yml +++ b/.mokogitea/workflows/pr-check.yml @@ -4,8 +4,8 @@ # # FILE INFORMATION # DEFGROUP: Gitea.Workflow -# INGROUP: moko-platform.CI -# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/moko-platform +# INGROUP: mokocli.CI +# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/universal/pr-check.yml.template # VERSION: 09.23.00 # BRIEF: PR gate — branch policy + code validation before merge From 77d93602d62e6831c6d02e783c37e412577954e2 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:06:41 +0000 Subject: [PATCH 06/28] chore: sync pre-release.yml from Template-Generic [skip ci] --- .mokogitea/workflows/pre-release.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.mokogitea/workflows/pre-release.yml b/.mokogitea/workflows/pre-release.yml index efb3d1b..cc40025 100644 --- a/.mokogitea/workflows/pre-release.yml +++ b/.mokogitea/workflows/pre-release.yml @@ -48,9 +48,13 @@ jobs: build: name: "Build Pre-Release (${{ inputs.stability || github.ref_name }})" runs-on: release + # Skip on template repos (Template-*) — they scaffold other repos and do not release. if: >- - github.event_name == 'workflow_dispatch' || - github.event_name == 'push' + !startsWith(github.event.repository.name, 'Template-') && + ( + github.event_name == 'workflow_dispatch' || + github.event_name == 'push' + ) steps: - name: Checkout From 406b666486bf73c65cfdd52bc429956e6baae1e1 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:06:42 +0000 Subject: [PATCH 07/28] chore: sync sync-on-merge.yml from Template-Generic [skip ci] --- .mokogitea/workflows/sync-on-merge.yml | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .mokogitea/workflows/sync-on-merge.yml diff --git a/.mokogitea/workflows/sync-on-merge.yml b/.mokogitea/workflows/sync-on-merge.yml new file mode 100644 index 0000000..1b882bc --- /dev/null +++ b/.mokogitea/workflows/sync-on-merge.yml @@ -0,0 +1,31 @@ +name: Sync Workflows to Repos + +on: + push: + branches: + - main + paths: + - '.mokogitea/workflows/**' + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Checkout mokocli + uses: actions/checkout@v4 + with: + repository: MokoConsulting/mokocli + token: ${{ secrets.MOKOGITEA_TOKEN }} + + - name: Setup PHP + uses: https://git.mokoconsulting.tech/MokoConsulting/.mokogitea/raw/branch/main/actions/setup-php@v1 + with: + php-version: '8.1' + + - name: Install dependencies + run: composer install --no-dev --no-interaction + + - name: Sync workflows to generic repos + run: php automation/bulk_sync.php --platform generic --org MokoConsulting --workflows-only --auto-merge --token "${{ secrets.MOKOGITEA_TOKEN }}" + env: + MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} From a808789acb71472cb6835ba5b83bbc8232a64fdf Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 4 Jul 2026 14:20:54 -0500 Subject: [PATCH 08/28] feat: add COM_MOKOJOOMBACKUP_SHORT and apply short name to views and admin menu - Add COM_MOKOJOOMBACKUP_SHORT="Backup" to the component .ini and .sys.ini (en-GB + en-US) so both view titles and the admin sidebar menu resolve it. - Prefix every admin view's toolbar title with the short brand via the constant (e.g. "Backup: Dashboard", "Backup: Records"), and tighten the view title strings that redundantly led with "Backup"/"MokoSuiteBackup". - Admin sidebar top-level menu now shows the short name. Hardcoded as "Backup" in the manifest per the package-xml convention (no language strings in package XML). --- .../language/en-GB/com_mokosuitebackup.ini | 9 +++++---- .../language/en-GB/com_mokosuitebackup.sys.ini | 1 + .../language/en-US/com_mokosuitebackup.ini | 7 ++++--- .../language/en-US/com_mokosuitebackup.sys.ini | 1 + source/packages/com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../com_mokosuitebackup/src/View/Backup/HtmlView.php | 2 +- .../com_mokosuitebackup/src/View/Backups/HtmlView.php | 2 +- .../com_mokosuitebackup/src/View/Dashboard/HtmlView.php | 2 +- .../com_mokosuitebackup/src/View/Profile/HtmlView.php | 2 +- .../com_mokosuitebackup/src/View/Profiles/HtmlView.php | 2 +- .../com_mokosuitebackup/src/View/Snapshots/HtmlView.php | 2 +- 11 files changed, 18 insertions(+), 14 deletions(-) diff --git a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini index c21b6d1..46c7903 100644 --- a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini +++ b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini @@ -5,6 +5,7 @@ ; @license GPL-3.0-or-later COM_MOKOJOOMBACKUP="MokoSuiteBackup" +COM_MOKOJOOMBACKUP_SHORT="Backup" COM_MOKOJOOMBACKUP_CONFIGURATION="MokoSuiteBackup Options" COM_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla" @@ -22,7 +23,7 @@ COM_MOKOSUITEBACKUP_ACTION_BACKUP_RESTORE="Restore Backup" COM_MOKOSUITEBACKUP_ACTION_BACKUP_RESTORE_DESC="Allows users in this group to restore the site from a backup archive. This is a destructive operation that overwrites the current site." ; Dashboard view -COM_MOKOJOOMBACKUP_DASHBOARD_TITLE="MokoSuiteBackup Dashboard" +COM_MOKOJOOMBACKUP_DASHBOARD_TITLE="Dashboard" COM_MOKOJOOMBACKUP_DASHBOARD_LAST_BACKUP="Last Backup" COM_MOKOJOOMBACKUP_DASHBOARD_NO_BACKUPS="No backups yet" COM_MOKOJOOMBACKUP_DASHBOARD_NEXT_SCHEDULED="Next Scheduled" @@ -44,14 +45,14 @@ COM_MOKOJOOMBACKUP_DASHBOARD_BACKUP_TREND="Backup Trend (30 days)" ; Backups view COM_MOKOJOOMBACKUP_BACKUPS_N_ITEMS_DELETED="%d backup records deleted." COM_MOKOJOOMBACKUP_BACKUPS_N_ITEMS_DELETED_1="%d backup record deleted." -COM_MOKOJOOMBACKUP_BACKUPS_TITLE="Backup Records" +COM_MOKOJOOMBACKUP_BACKUPS_TITLE="Records" COM_MOKOJOOMBACKUP_BACKUPS_TABLE_CAPTION="Table of backup records" COM_MOKOJOOMBACKUP_NO_BACKUPS="No backups found. Click 'Backup Now' to create your first backup." COM_MOKOJOOMBACKUP_TOOLBAR_BACKUP_NOW="Backup Now" COM_MOKOJOOMBACKUP_DOWNLOAD="Download" ; Backup detail view -COM_MOKOJOOMBACKUP_BACKUP_DETAIL="Backup Detail" +COM_MOKOJOOMBACKUP_BACKUP_DETAIL="Detail" COM_MOKOJOOMBACKUP_VIEW_LOG="Backup Log" COM_MOKOJOOMBACKUP_BROWSE_ARCHIVE="Browse Archive Contents" COM_MOKOJOOMBACKUP_BROWSE_COL_NAME="Name" @@ -75,7 +76,7 @@ COM_MOKOJOOMBACKUP_FIELD_DB_SIZE="DB Size" COM_MOKOJOOMBACKUP_FIELD_REMOTE="Remote Path" ; Profiles view -COM_MOKOJOOMBACKUP_PROFILES_TITLE="Backup Profiles" +COM_MOKOJOOMBACKUP_PROFILES_TITLE="Profiles" COM_MOKOJOOMBACKUP_PROFILES_TABLE_CAPTION="Table of backup profiles" COM_MOKOJOOMBACKUP_NO_PROFILES="No backup profiles found." COM_MOKOJOOMBACKUP_PROFILE_NEW="New Profile" diff --git a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.sys.ini b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.sys.ini index d9887da..b7c62b0 100644 --- a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.sys.ini +++ b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.sys.ini @@ -5,6 +5,7 @@ ; @license GPL-3.0-or-later COM_MOKOJOOMBACKUP="MokoSuiteBackup" +COM_MOKOJOOMBACKUP_SHORT="Backup" COM_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla — database, files, and configuration." COM_MOKOJOOMBACKUP_SUBMENU_DASHBOARD="Dashboard" COM_MOKOJOOMBACKUP_SUBMENU_BACKUPS="Backup Records" diff --git a/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini b/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini index db5e85b..6a8d625 100644 --- a/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini +++ b/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini @@ -5,6 +5,7 @@ ; @license GPL-3.0-or-later COM_MOKOJOOMBACKUP="MokoSuiteBackup" +COM_MOKOJOOMBACKUP_SHORT="Backup" COM_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla" COM_MOKOJOOMBACKUP_SUBMENU_DASHBOARD="Dashboard" COM_MOKOJOOMBACKUP_SUBMENU_BACKUPS="Backup Records" @@ -18,7 +19,7 @@ COM_MOKOSUITEBACKUP_ACTION_BACKUP_DOWNLOAD_DESC="Allows users in this group to d COM_MOKOSUITEBACKUP_ACTION_BACKUP_RESTORE="Restore Backup" COM_MOKOSUITEBACKUP_ACTION_BACKUP_RESTORE_DESC="Allows users in this group to restore the site from a backup archive. This is a destructive operation that overwrites the current site." -COM_MOKOJOOMBACKUP_DASHBOARD_TITLE="MokoSuiteBackup Dashboard" +COM_MOKOJOOMBACKUP_DASHBOARD_TITLE="Dashboard" COM_MOKOJOOMBACKUP_DASHBOARD_LAST_BACKUP="Last Backup" COM_MOKOJOOMBACKUP_DASHBOARD_NO_BACKUPS="No backups yet" COM_MOKOJOOMBACKUP_DASHBOARD_NEXT_SCHEDULED="Next Scheduled" @@ -30,8 +31,8 @@ COM_MOKOJOOMBACKUP_DASHBOARD_QUICK_ACTIONS="Quick Actions" COM_MOKOJOOMBACKUP_DASHBOARD_SCHEDULED_TASKS="Scheduled Tasks" COM_MOKOJOOMBACKUP_DASHBOARD_UPDATE_SITE="Update Site" COM_MOKOJOOMBACKUP_DASHBOARD_SYSTEM_HEALTH="System Health" -COM_MOKOJOOMBACKUP_BACKUPS_TITLE="Backup Records" -COM_MOKOJOOMBACKUP_PROFILES_TITLE="Backup Profiles" +COM_MOKOJOOMBACKUP_BACKUPS_TITLE="Records" +COM_MOKOJOOMBACKUP_PROFILES_TITLE="Profiles" COM_MOKOJOOMBACKUP_TOOLBAR_BACKUP_NOW="Backup Now" COM_MOKOJOOMBACKUP_NO_BACKUPS="No backups found. Click 'Backup Now' to create your first backup." COM_MOKOJOOMBACKUP_NO_PROFILES="No backup profiles found." diff --git a/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.sys.ini b/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.sys.ini index 23f1d10..53dd3f7 100644 --- a/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.sys.ini +++ b/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.sys.ini @@ -5,6 +5,7 @@ ; @license GPL-3.0-or-later COM_MOKOJOOMBACKUP="MokoSuiteBackup" +COM_MOKOJOOMBACKUP_SHORT="Backup" COM_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla — database, files, and configuration." COM_MOKOJOOMBACKUP_SUBMENU_DASHBOARD="Dashboard" COM_MOKOJOOMBACKUP_SUBMENU_BACKUPS="Backup Records" diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index f099e1a..e14a776 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -37,7 +37,7 @@ - COM_MOKOJOOMBACKUP + Backup getIdentity(); diff --git a/source/packages/com_mokosuitebackup/src/View/Backups/HtmlView.php b/source/packages/com_mokosuitebackup/src/View/Backups/HtmlView.php index 3b45d0f..ba43de3 100644 --- a/source/packages/com_mokosuitebackup/src/View/Backups/HtmlView.php +++ b/source/packages/com_mokosuitebackup/src/View/Backups/HtmlView.php @@ -99,7 +99,7 @@ class HtmlView extends BaseHtmlView { $user = Factory::getApplication()->getIdentity(); - ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_BACKUPS_TITLE'), 'database'); + ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_SHORT') . ': ' . Text::_('COM_MOKOJOOMBACKUP_BACKUPS_TITLE'), 'database'); if ($user->authorise('mokosuitebackup.backup.restore', 'com_mokosuitebackup')) { ToolbarHelper::custom('backups.restore', 'upload', '', 'COM_MOKOJOOMBACKUP_TOOLBAR_RESTORE', true); diff --git a/source/packages/com_mokosuitebackup/src/View/Dashboard/HtmlView.php b/source/packages/com_mokosuitebackup/src/View/Dashboard/HtmlView.php index f5c9b88..454a6ae 100644 --- a/source/packages/com_mokosuitebackup/src/View/Dashboard/HtmlView.php +++ b/source/packages/com_mokosuitebackup/src/View/Dashboard/HtmlView.php @@ -52,7 +52,7 @@ class HtmlView extends BaseHtmlView protected function addToolbar(): void { - ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_DASHBOARD_TITLE'), 'archive'); + ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_SHORT') . ': ' . Text::_('COM_MOKOJOOMBACKUP_DASHBOARD_TITLE'), 'archive'); ToolbarHelper::preferences('com_mokosuitebackup'); } } diff --git a/source/packages/com_mokosuitebackup/src/View/Profile/HtmlView.php b/source/packages/com_mokosuitebackup/src/View/Profile/HtmlView.php index 315c942..0db045b 100644 --- a/source/packages/com_mokosuitebackup/src/View/Profile/HtmlView.php +++ b/source/packages/com_mokosuitebackup/src/View/Profile/HtmlView.php @@ -44,7 +44,7 @@ class HtmlView extends BaseHtmlView ? $user->authorise('core.create', 'com_mokosuitebackup') : $user->authorise('core.edit', 'com_mokosuitebackup'); - ToolbarHelper::title(Text::_($title), 'cog'); + ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_SHORT') . ': ' . Text::_($title), 'cog'); if ($canSave) { ToolbarHelper::apply('profile.apply'); diff --git a/source/packages/com_mokosuitebackup/src/View/Profiles/HtmlView.php b/source/packages/com_mokosuitebackup/src/View/Profiles/HtmlView.php index ce3563e..34f350c 100644 --- a/source/packages/com_mokosuitebackup/src/View/Profiles/HtmlView.php +++ b/source/packages/com_mokosuitebackup/src/View/Profiles/HtmlView.php @@ -49,7 +49,7 @@ class HtmlView extends BaseHtmlView { $user = Factory::getApplication()->getIdentity(); - ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_PROFILES_TITLE'), 'cog'); + ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_SHORT') . ': ' . Text::_('COM_MOKOJOOMBACKUP_PROFILES_TITLE'), 'cog'); if ($user->authorise('core.create', 'com_mokosuitebackup')) { ToolbarHelper::addNew('profile.add'); diff --git a/source/packages/com_mokosuitebackup/src/View/Snapshots/HtmlView.php b/source/packages/com_mokosuitebackup/src/View/Snapshots/HtmlView.php index 089e7e4..308afbe 100644 --- a/source/packages/com_mokosuitebackup/src/View/Snapshots/HtmlView.php +++ b/source/packages/com_mokosuitebackup/src/View/Snapshots/HtmlView.php @@ -38,7 +38,7 @@ class HtmlView extends BaseHtmlView { $user = Factory::getApplication()->getIdentity(); - ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_SNAPSHOTS_TITLE'), 'camera'); + ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_SHORT') . ': ' . Text::_('COM_MOKOJOOMBACKUP_SNAPSHOTS_TITLE'), 'camera'); if ($user->authorise('mokosuitebackup.snapshot.manage', 'com_mokosuitebackup')) { ToolbarHelper::custom('snapshots.create', 'plus', '', 'COM_MOKOJOOMBACKUP_SNAPSHOT_CREATE', false); From 1be16af5a4881d6cfc6176246672bd29d40e87bd Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Sat, 4 Jul 2026 19:21:24 +0000 Subject: [PATCH 09/28] chore(version): pre-release bump to 02.52.27-dev [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- SECURITY.md | 2 +- source/packages/MokoSuiteClient | 2 +- source/packages/com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/com_mokosuitebackup/sql/updates/mysql/02.52.27.sql | 1 + .../mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml | 2 +- .../packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml | 2 +- .../plg_webservices_mokosuitebackup/mokosuitebackup.xml | 2 +- source/pkg_mokosuitebackup.xml | 2 +- 14 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 source/packages/com_mokosuitebackup/sql/updates/mysql/02.52.27.sql diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 11958bd..1357926 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.00.00 +# VERSION: 02.52.27 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/SECURITY.md b/SECURITY.md index c72f18e..4a23ad4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla INGROUP: Template-Joomla.Documentation REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla PATH: /SECURITY.md -VERSION: 02.52.24 +VERSION: 02.52.27 BRIEF: Security vulnerability reporting and handling policy --> diff --git a/source/packages/MokoSuiteClient b/source/packages/MokoSuiteClient index c7e6670..7879ecb 160000 --- a/source/packages/MokoSuiteClient +++ b/source/packages/MokoSuiteClient @@ -1 +1 @@ -Subproject commit c7e66705443f74e3ee2ffdfecc08224cc40240aa +Subproject commit 7879ecbf1f91ddf3b474465a93252f6ddc2f0a3a diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index e14a776..a63a72b 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> MokoSuiteBackup - 02.52.24 + 02.52.27 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.52.27.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.52.27.sql new file mode 100644 index 0000000..1adde24 --- /dev/null +++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.52.27.sql @@ -0,0 +1 @@ +/* 02.52.27 — no schema changes */ diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml index 099fe46..b36e632 100644 --- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml +++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml @@ -8,7 +8,7 @@ --> mod_mokosuitebackup_cpanel - 02.52.24 + 02.52.27 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml index ced288a..2a28a92 100644 --- a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Action Log - MokoSuiteBackup - 02.52.24 + 02.52.27 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml index 1e8f1a8..7247bc6 100644 --- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Console - MokoSuiteBackup - 02.52.24 + 02.52.27 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml index 7d17290..6ec6bad 100644 --- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Content - MokoSuiteBackup - 02.52.24 + 02.52.27 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml index e9fa579..81725cf 100644 --- a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml @@ -1,7 +1,7 @@ Quick Icon - MokoSuiteBackup - 02.52.24 + 02.52.27 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml index 4cefd2c..83044c8 100644 --- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> System - MokoSuiteBackup - 02.52.24 + 02.52.27 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml index 4381063..5bda339 100644 --- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Task - MokoSuiteBackup - 02.52.24 + 02.52.27 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml index bc268fc..eb6df9b 100644 --- a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Web Services - MokoSuiteBackup - 02.52.24 + 02.52.27 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index 15b18fd..56f0ac3 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -8,7 +8,7 @@ Package - MokoSuiteBackup mokosuitebackup - 02.52.24 + 02.52.27 2026-06-02 Moko Consulting hello@mokoconsulting.tech From 1ee5e6ba9b5f900a68d61a56c7925af15fe423d1 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:39:05 +0000 Subject: [PATCH 10/28] chore: sync branch-cleanup.yml from Template-Generic [skip ci] --- .mokogitea/workflows/branch-cleanup.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.mokogitea/workflows/branch-cleanup.yml b/.mokogitea/workflows/branch-cleanup.yml index 9d884e7..dd5ff56 100644 --- a/.mokogitea/workflows/branch-cleanup.yml +++ b/.mokogitea/workflows/branch-cleanup.yml @@ -33,7 +33,8 @@ jobs: run: | BRANCH="${{ github.event.pull_request.head.ref }}" API="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}/api/v1/repos/${{ github.repository }}/branches" - ENCODED=$(php -r "echo rawurlencode('${BRANCH}');") + # URL-encode the branch name's slashes (no PHP dependency on the runner) + ENCODED=$(printf '%s' "${BRANCH}" | sed 's|/|%2F|g') STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \ -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ From 6cf34ea2ed10eb770975bd96cbc7c394342458a7 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:39:06 +0000 Subject: [PATCH 11/28] chore: sync ci-generic.yml from Template-Generic [skip ci] --- .mokogitea/workflows/ci-generic.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.mokogitea/workflows/ci-generic.yml b/.mokogitea/workflows/ci-generic.yml index 3a942ad..f556162 100644 --- a/.mokogitea/workflows/ci-generic.yml +++ b/.mokogitea/workflows/ci-generic.yml @@ -32,6 +32,8 @@ jobs: lint: name: Lint & Validate runs-on: ubuntu-latest + # Skip on template repos (Template-*) — they hold placeholder scaffolding, not buildable source. + if: ${{ !startsWith(github.event.repository.name, 'Template-') }} steps: - name: Checkout @@ -130,6 +132,8 @@ jobs: name: Tests runs-on: ubuntu-latest needs: lint + # Skip on template repos (Template-*) — see lint job. + if: ${{ !startsWith(github.event.repository.name, 'Template-') }} steps: - name: Checkout From ece864329ea63c55d1bc9f6709a2563afe5cf76e Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 19:39:08 +0000 Subject: [PATCH 12/28] chore: sync pr-check.yml from Template-Generic [skip ci] --- .mokogitea/workflows/pr-check.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mokogitea/workflows/pr-check.yml b/.mokogitea/workflows/pr-check.yml index 1652713..941e436 100644 --- a/.mokogitea/workflows/pr-check.yml +++ b/.mokogitea/workflows/pr-check.yml @@ -126,6 +126,8 @@ jobs: validate: name: Validate PR runs-on: ubuntu-latest + # Skip on template repos (Template-*) — no real manifest/source/changelog to validate. + if: ${{ !startsWith(github.event.repository.name, 'Template-') }} steps: - name: Checkout From c492d30b1c9e7e538a4c32bd0c02f92b66c4b98b Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Sat, 4 Jul 2026 20:20:57 +0000 Subject: [PATCH 13/28] chore(release): build 02.53.00 [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- CHANGELOG.md | 29 ++----------------- SECURITY.md | 2 +- .../com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../sql/updates/mysql/02.53.00.sql | 1 + .../mod_mokosuitebackup_cpanel.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- source/pkg_mokosuitebackup.xml | 2 +- 14 files changed, 15 insertions(+), 39 deletions(-) create mode 100644 source/packages/com_mokosuitebackup/sql/updates/mysql/02.53.00.sql diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 1357926..b34e35c 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 02.52.27 +# VERSION: 02.53.00 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/CHANGELOG.md b/CHANGELOG.md index a2ef16d..732634c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +## [02.53.00] --- 2026-07-04 + ## [02.52.24] --- 2026-06-30 @@ -26,30 +28,3 @@ - Backups with failed remote uploads were marked as "complete", hiding the upload failure ## [02.52.18] --- 2026-06-30 - -## [01.45.00] --- 2026-06-28 - -## [01.43.35] --- 2026-06-28 - -### Added -- Customizable restore script filename per backup profile (reduces discoverability on remote servers) -- MokoRestore standalone mode: multi-ZIP selector when multiple backup archives are present -- MokoRestore preflight: Joomla installation detection warning before overwriting an existing site -- MokoRestore error handling: try/catch on fetch calls, HTTP status checks, JSON parse recovery -- Download button on individual backup record detail toolbar -- Profile column in backup records list links to the profile edit view - -### Changed -- Moved download, browse archive, and view log actions from backup list rows into the individual backup record view -- Removed "Run Backup" / "Backup Now" buttons from profiles list, profile edit toolbar, and backup records view (backups are triggered from the dashboard only) -- Removed ordering field from profiles; default sort is now by ID ascending -- MokoRestore cleanup and security messages now reference the actual script filename instead of hardcoded "restore.php" - -### Fixed -- SSH key indicator detection and missing delete language key -- Bootstrap 5 modal conversion for snapshots view (data-bs-dismiss, modal-footer, getOrCreateInstance) -- ntfy default URL changed from ntfy.sh to ntfy.mokoconsulting.tech -- Untranslated JFIELD_ORDERING_ASC / JFIELD_ORDERING_LABEL language keys replaced with component-specific keys -- Options page title now shows "MokoSuiteBackup Options" instead of raw language key -- Profile dropdown IDs in backup records and dashboard show "#ID — Title (type)" format -- MokoRestore stalling: unhandled promise rejections from network errors or non-JSON responses left UI in loading state diff --git a/SECURITY.md b/SECURITY.md index 4a23ad4..fff694a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla INGROUP: Template-Joomla.Documentation REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla PATH: /SECURITY.md -VERSION: 02.52.27 +VERSION: 02.53.00 BRIEF: Security vulnerability reporting and handling policy --> diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index a63a72b..aaa511c 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> MokoSuiteBackup - 02.52.27 + 02.53.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.53.00.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.53.00.sql new file mode 100644 index 0000000..d20c9cc --- /dev/null +++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.53.00.sql @@ -0,0 +1 @@ +/* 02.53.00 — no schema changes */ diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml index b36e632..fe2783b 100644 --- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml +++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml @@ -8,7 +8,7 @@ --> mod_mokosuitebackup_cpanel - 02.52.27 + 02.53.00 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml index 2a28a92..c133b45 100644 --- a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Action Log - MokoSuiteBackup - 02.52.27 + 02.53.00 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml index 7247bc6..e0b8f09 100644 --- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Console - MokoSuiteBackup - 02.52.27 + 02.53.00 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml index 6ec6bad..c7c8954 100644 --- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Content - MokoSuiteBackup - 02.52.27 + 02.53.00 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml index 81725cf..e3f0fff 100644 --- a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml @@ -1,7 +1,7 @@ Quick Icon - MokoSuiteBackup - 02.52.27 + 02.53.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml index 83044c8..0e8265a 100644 --- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> System - MokoSuiteBackup - 02.52.27 + 02.53.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml index 5bda339..29def99 100644 --- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Task - MokoSuiteBackup - 02.52.27 + 02.53.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml index eb6df9b..1a3ae64 100644 --- a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Web Services - MokoSuiteBackup - 02.52.27 + 02.53.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index 56f0ac3..519a233 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -8,7 +8,7 @@ Package - MokoSuiteBackup mokosuitebackup - 02.52.27 + 02.53.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech From 6ff350fb1ce249c9f4a91848b09d31e6f562a90f Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Sat, 4 Jul 2026 20:21:10 +0000 Subject: [PATCH 14/28] =?UTF-8?q?chore:=20promote=20changelog=20[Unrelease?= =?UTF-8?q?d]=20=E2=86=92=20[02.53.00]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 732634c..5c1c3fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## [02.53.00] --- 2026-07-04 +## [02.53.00] --- 2026-07-04 + ## [02.52.24] --- 2026-06-30 From 84f37a8b519a1e73f1652021ba385f579d676a40 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 20:23:16 +0000 Subject: [PATCH 15/28] chore: sync ci-generic.yml from Template-Generic [skip ci] --- .mokogitea/workflows/ci-generic.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.mokogitea/workflows/ci-generic.yml b/.mokogitea/workflows/ci-generic.yml index f556162..72650d2 100644 --- a/.mokogitea/workflows/ci-generic.yml +++ b/.mokogitea/workflows/ci-generic.yml @@ -132,8 +132,9 @@ jobs: name: Tests runs-on: ubuntu-latest needs: lint - # Skip on template repos (Template-*) — see lint job. - if: ${{ !startsWith(github.event.repository.name, 'Template-') }} + # Run only when lint succeeded; always() forces evaluation so a skipped + # lint (e.g. template repos) skips this job cleanly instead of hanging. + if: ${{ always() && needs.lint.result == 'success' }} steps: - name: Checkout From 145155d06e6e4051e68516a62d390f00ca573d01 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 20:23:18 +0000 Subject: [PATCH 16/28] chore: sync issue-branch.yml from Template-Generic [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index b34e35c..11958bd 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 02.53.00 +# VERSION: 01.00.00 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" From 0df6008a3b015ae6d9323c179482c9a0d1f6edbd Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 20:23:20 +0000 Subject: [PATCH 17/28] chore: sync pr-check.yml from Template-Generic [skip ci] --- .mokogitea/workflows/pr-check.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.mokogitea/workflows/pr-check.yml b/.mokogitea/workflows/pr-check.yml index 941e436..c13b15e 100644 --- a/.mokogitea/workflows/pr-check.yml +++ b/.mokogitea/workflows/pr-check.yml @@ -494,6 +494,9 @@ jobs: name: Build RC Package runs-on: ubuntu-latest needs: [branch-policy, validate] + # Run only when both gates succeeded; always() forces evaluation so a skipped + # validate (e.g. template repos) skips this job cleanly instead of hanging. + if: ${{ always() && needs.branch-policy.result == 'success' && needs.validate.result == 'success' }} steps: - name: Trigger RC pre-release From d155958be35f7690eca461a2f042d81ecb038e96 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 4 Jul 2026 14:29:17 -0500 Subject: [PATCH 18/28] chore(manifests): hardcode names/descriptions and enforce Type - Name convention MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the package-XML convention, manifests must not use language strings for titles/descriptions, and must follow "Type - Name". - Component "MokoSuiteBackup" → "Component - MokoSuiteBackup" - Module "mod_mokosuitebackup_cpanel" → "Module - MokoSuiteBackup - cPanel" - Hardcode every (pkg, com, mod, all 7 plugins) with the literal text previously stored in the *_DESCRIPTION language constants - Hardcode the component admin submenu titles (Dashboard, Backup Records, Content Snapshots, Backup Profiles) Plugin values already followed the Group - Name format and are unchanged. All manifests validated as well-formed XML. --- .../packages/com_mokosuitebackup/mokosuitebackup.xml | 12 ++++++------ .../mod_mokosuitebackup_cpanel.xml | 4 ++-- .../mokosuitebackup.xml | 2 +- .../plg_console_mokosuitebackup/mokosuitebackup.xml | 2 +- .../plg_content_mokosuitebackup/mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../plg_system_mokosuitebackup/mokosuitebackup.xml | 2 +- .../plg_task_mokosuitebackup/mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- source/pkg_mokosuitebackup.xml | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index aaa511c..88f791f 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -6,7 +6,7 @@ * @license GNU General Public License version 3 or later; see LICENSE --> - MokoSuiteBackup + Component - MokoSuiteBackup 02.53.00 2026-06-02 Moko Consulting @@ -14,7 +14,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - COM_MOKOJOOMBACKUP_DESCRIPTION + Full-site backup and restore for Joomla — database, files, and configuration. Joomla\Component\MokoSuiteBackup @@ -41,16 +41,16 @@ COM_MOKOJOOMBACKUP_SUBMENU_DASHBOARD + alt="Dashboard">Dashboard COM_MOKOJOOMBACKUP_SUBMENU_BACKUPS + alt="Backups">Backup Records COM_MOKOJOOMBACKUP_SUBMENU_SNAPSHOTS + alt="Snapshots">Content Snapshots COM_MOKOJOOMBACKUP_SUBMENU_PROFILES + alt="Profiles">Backup Profiles access.xml diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml index fe2783b..567f4c8 100644 --- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml +++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml @@ -7,7 +7,7 @@ * @license GNU General Public License version 3 or later; see LICENSE --> - mod_mokosuitebackup_cpanel + Module - MokoSuiteBackup - cPanel 02.53.00 2026-06-23 Moko Consulting @@ -15,7 +15,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - MOD_MOKOSUITEBACKUP_CPANEL_DESCRIPTION + Displays backup status, Backup Now buttons, and quick links on the admin dashboard. Joomla\Module\MokoSuiteBackupCpanel diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml index c133b45..ec81674 100644 --- a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml @@ -14,7 +14,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - PLG_ACTIONLOG_MOKOJOOMBACKUP_DESCRIPTION + Logs MokoSuiteBackup actions (backup, restore, profile changes) to User Action Logs. Joomla\Plugin\Actionlog\MokoSuiteBackup diff --git a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml index e0b8f09..436c872 100644 --- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml @@ -14,7 +14,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - PLG_CONSOLE_MOKOJOOMBACKUP_DESCRIPTION + CLI commands for MokoSuiteBackup: run, list, profiles, restore, cleanup. Joomla\Plugin\Console\MokoSuiteBackup diff --git a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml index c7c8954..7ac8af3 100644 --- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml @@ -14,7 +14,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - PLG_CONTENT_MOKOJOOMBACKUP_DESCRIPTION + Automatically triggers a backup before extension installs or updates. Joomla\Plugin\Content\MokoSuiteBackup diff --git a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml index e3f0fff..0e5d047 100644 --- a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml @@ -8,7 +8,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - PLG_QUICKICON_MOKOJOOMBACKUP_DESCRIPTION + Shows backup status on the administrator dashboard. Joomla\Plugin\Quickicon\MokoSuiteBackup diff --git a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml index 0e8265a..945cdc8 100644 --- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml @@ -14,7 +14,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - PLG_SYSTEM_MOKOJOOMBACKUP_DESCRIPTION + Automatic cleanup of expired backup archives and scheduled backup triggers. Joomla\Plugin\System\MokoSuiteBackup diff --git a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml index 29def99..008ffe8 100644 --- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml @@ -14,7 +14,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - PLG_TASK_MOKOJOOMBACKUP_DESCRIPTION + Scheduled task plugin for MokoSuiteBackup. Run backup profiles on a schedule via Joomla's Scheduled Tasks. Joomla\Plugin\Task\MokoSuiteBackup diff --git a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml index 1a3ae64..9d66392 100644 --- a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml @@ -14,7 +14,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - PLG_WEBSERVICES_MOKOJOOMBACKUP_DESCRIPTION + REST API for remote backup management. Joomla\Plugin\WebServices\MokoSuiteBackup diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index 519a233..b41a721 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -15,7 +15,7 @@ https://mokoconsulting.tech Copyright (C) 2026 Moko Consulting. All rights reserved. GPL-3.0-or-later - PKG_MOKOJOOMBACKUP_DESCRIPTION + Full-site backup and restore for Joomla — database, files, and configuration. Includes admin component, system plugin, and REST API. script.php From 2e5b57fe5d0ddf77d29096b0e97c9490080f12df Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Sat, 4 Jul 2026 20:25:20 +0000 Subject: [PATCH 19/28] chore(release): build 02.54.00 [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- CHANGELOG.md | 23 ++----------------- SECURITY.md | 2 +- .../com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../sql/updates/mysql/02.54.00.sql | 1 + .../mod_mokosuitebackup_cpanel.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- .../mokosuitebackup.xml | 2 +- source/pkg_mokosuitebackup.xml | 2 +- 14 files changed, 15 insertions(+), 33 deletions(-) create mode 100644 source/packages/com_mokosuitebackup/sql/updates/mysql/02.54.00.sql diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 11958bd..eb1f3c3 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.00.00 +# VERSION: 02.54.00 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c1c3fb..53a5853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +## [02.54.00] --- 2026-07-04 + ## [02.53.00] --- 2026-07-04 ## [02.53.00] --- 2026-07-04 @@ -9,24 +11,3 @@ ## [02.52.24] --- 2026-06-30 - -## [02.52.22] --- 2026-06-30 - -### Added -- Cancel Stalled toolbar button on Backup Records view to cancel backups stuck in "running" status -- New ACL permission `mokosuitebackup.backup.cancel` for cancel stalled action -- AJAX endpoint `ajax.cancelBackup` for programmatic/API cancel -- Auto-timeout failsafe: preflight auto-cancels "running" backups older than 30 minutes -- Pre-extension-update backup progress modal (Bootstrap 5 modal with stepped AJAX progress bar) -- New `warning` backup status for records where archive succeeded but remote upload failed -- Warning-status records are downloadable, browsable, restorable, and purgeable -- Warning status filter option in Backup Records dropdown -- Yellow "Warning" badge in backup list, detail view, and cpanel module - -### Fixed -- Pre-update backup ran synchronously with no browser feedback — page hung until complete -- Stalled backups permanently blocked future backups for the same profile -- Preflight error message now directs users to Cancel Stalled action -- Backups with failed remote uploads were marked as "complete", hiding the upload failure - -## [02.52.18] --- 2026-06-30 diff --git a/SECURITY.md b/SECURITY.md index fff694a..ec3e33b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla INGROUP: Template-Joomla.Documentation REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla PATH: /SECURITY.md -VERSION: 02.53.00 +VERSION: 02.54.00 BRIEF: Security vulnerability reporting and handling policy --> diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index 88f791f..f72db88 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Component - MokoSuiteBackup - 02.53.00 + 02.54.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.54.00.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.54.00.sql new file mode 100644 index 0000000..79f1e75 --- /dev/null +++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.54.00.sql @@ -0,0 +1 @@ +/* 02.54.00 — no schema changes */ diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml index 567f4c8..f0e56e0 100644 --- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml +++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml @@ -8,7 +8,7 @@ --> Module - MokoSuiteBackup - cPanel - 02.53.00 + 02.54.00 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml index ec81674..1edf2cd 100644 --- a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Action Log - MokoSuiteBackup - 02.53.00 + 02.54.00 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml index 436c872..3e9f505 100644 --- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Console - MokoSuiteBackup - 02.53.00 + 02.54.00 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml index 7ac8af3..a110222 100644 --- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Content - MokoSuiteBackup - 02.53.00 + 02.54.00 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml index 0e5d047..22c10fd 100644 --- a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml @@ -1,7 +1,7 @@ Quick Icon - MokoSuiteBackup - 02.53.00 + 02.54.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml index 945cdc8..1c5e7eb 100644 --- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> System - MokoSuiteBackup - 02.53.00 + 02.54.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml index 008ffe8..5dc3c94 100644 --- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Task - MokoSuiteBackup - 02.53.00 + 02.54.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml index 9d66392..5fccdbe 100644 --- a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Web Services - MokoSuiteBackup - 02.53.00 + 02.54.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index b41a721..a50be4c 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -8,7 +8,7 @@ Package - MokoSuiteBackup mokosuitebackup - 02.53.00 + 02.54.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech From 4b2bb8b65587b269c257c3d22c46c05463fdf237 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Sat, 4 Jul 2026 20:25:31 +0000 Subject: [PATCH 20/28] =?UTF-8?q?chore:=20promote=20changelog=20[Unrelease?= =?UTF-8?q?d]=20=E2=86=92=20[02.54.00]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53a5853..9d1ce17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## [02.54.00] --- 2026-07-04 +## [02.54.00] --- 2026-07-04 + ## [02.53.00] --- 2026-07-04 ## [02.53.00] --- 2026-07-04 From 10248b284a5c501963f90a71e4e2220463086971 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 4 Jul 2026 13:43:58 -0500 Subject: [PATCH 21/28] fix: enforce per-profile retention and repair Purge Old Backups button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related backup-management fixes. Retention (records/days to keep): - The retention fieldset was defined in profile.xml but never rendered in the profile editor, so retention_days/retention_count were invisible. Render the retention fieldset on the Archive tab. - retention_days/retention_count were read by nothing, so they pruned no backups. Add RetentionManager::prune(), called from completeRecord() in both BackupEngine and SteppedBackupEngine after a backup finishes. Policy: delete a completed/warning backup when EITHER it is older than retention_days OR it falls outside the newest retention_count copies (0 = unlimited for that rule). Deleting a record also removes its archive and log file. - Correct misleading language/schema text ("use global default" — no such global backup-retention setting exists) to "0 = unlimited". Purge Old Backups button: - The modal only opened via a fragile selector match on the toolbar button's inline onclick, which Joomla 6's Atum toolbar does not render, so the button did nothing. Wrap Joomla.submitbutton to open the modal for the backups.purgeModal task, keeping the selector as a fallback. --- .../language/en-GB/com_mokosuitebackup.ini | 4 +- .../language/en-US/com_mokosuitebackup.ini | 7 ++ .../com_mokosuitebackup/sql/install.mysql.sql | 4 +- .../src/Engine/BackupEngine.php | 11 ++ .../src/Engine/RetentionManager.php | 118 ++++++++++++++++++ .../src/Engine/SteppedBackupEngine.php | 7 ++ .../tmpl/backups/default.php | 32 +++-- .../com_mokosuitebackup/tmpl/profile/edit.php | 1 + 8 files changed, 173 insertions(+), 11 deletions(-) create mode 100644 source/packages/com_mokosuitebackup/src/Engine/RetentionManager.php diff --git a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini index 46c7903..0e5e3c0 100644 --- a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini +++ b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini @@ -251,9 +251,9 @@ COM_MOKOJOOMBACKUP_FIELD_NOTIFY_FAILURE_DESC="Send an email when a backup fails. ; Retention COM_MOKOJOOMBACKUP_FIELDSET_RETENTION="Retention" COM_MOKOJOOMBACKUP_FIELD_RETENTION_DAYS="Keep Backups (days)" -COM_MOKOJOOMBACKUP_FIELD_RETENTION_DAYS_DESC="Delete completed backups from this profile older than this many days. Set to 0 to use the global default from component options." +COM_MOKOJOOMBACKUP_FIELD_RETENTION_DAYS_DESC="Delete completed backups from this profile older than this many days. Set to 0 for unlimited (keep by age disabled)." COM_MOKOJOOMBACKUP_FIELD_RETENTION_COUNT="Keep Backups (count)" -COM_MOKOJOOMBACKUP_FIELD_RETENTION_COUNT_DESC="Maximum number of completed backups to keep for this profile. Oldest are removed first. Set to 0 to use the global default from component options." +COM_MOKOJOOMBACKUP_FIELD_RETENTION_COUNT_DESC="Maximum number of completed backups to keep for this profile. Oldest are removed first. Set to 0 for unlimited (keep by count disabled)." COM_MOKOJOOMBACKUP_FIELD_NTFY_SPACER_DESC="Push Notifications (ntfy) — Send instant push notifications to your phone or desktop via ntfy.sh or a self-hosted ntfy server." COM_MOKOJOOMBACKUP_FIELD_NTFY_TOPIC="ntfy Topic" diff --git a/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini b/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini index 6a8d625..1cb697a 100644 --- a/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini +++ b/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini @@ -130,3 +130,10 @@ COM_MOKOJOOMBACKUP_STATUS_WARNING="Warning" ; ACL - Cancel COM_MOKOSUITEBACKUP_ACTION_BACKUP_CANCEL="Cancel Stalled Backup" COM_MOKOSUITEBACKUP_ACTION_BACKUP_CANCEL_DESC="Allows users to cancel backup records stuck in running status and clean up partial archive files." + +; Retention (per-profile) +COM_MOKOJOOMBACKUP_FIELDSET_RETENTION="Retention" +COM_MOKOJOOMBACKUP_FIELD_RETENTION_DAYS="Keep Backups (days)" +COM_MOKOJOOMBACKUP_FIELD_RETENTION_DAYS_DESC="Delete completed backups from this profile older than this many days. Set to 0 for unlimited (keep by age disabled)." +COM_MOKOJOOMBACKUP_FIELD_RETENTION_COUNT="Keep Backups (count)" +COM_MOKOJOOMBACKUP_FIELD_RETENTION_COUNT_DESC="Maximum number of completed backups to keep for this profile. Oldest are removed first. Set to 0 for unlimited (keep by count disabled)." diff --git a/source/packages/com_mokosuitebackup/sql/install.mysql.sql b/source/packages/com_mokosuitebackup/sql/install.mysql.sql index 705ebfd..d1c24aa 100644 --- a/source/packages/com_mokosuitebackup/sql/install.mysql.sql +++ b/source/packages/com_mokosuitebackup/sql/install.mysql.sql @@ -49,8 +49,8 @@ CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_profiles` ( `notify_user_groups` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Comma-separated Joomla user group IDs', `notify_on_success` TINYINT(1) NOT NULL DEFAULT 0, `notify_on_failure` TINYINT(1) NOT NULL DEFAULT 1, - `retention_days` INT(11) NOT NULL DEFAULT 0 COMMENT '0 = use global default', - `retention_count` INT(11) NOT NULL DEFAULT 0 COMMENT '0 = use global default', + `retention_days` INT(11) NOT NULL DEFAULT 0 COMMENT 'Delete backups older than N days; 0 = unlimited', + `retention_count` INT(11) NOT NULL DEFAULT 0 COMMENT 'Keep newest N backups; 0 = unlimited', `ntfy_topic` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'ntfy topic name', `ntfy_server` VARCHAR(512) NOT NULL DEFAULT 'https://ntfy.sh' COMMENT 'ntfy server URL', `ntfy_token` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'ntfy access token (optional)', diff --git a/source/packages/com_mokosuitebackup/src/Engine/BackupEngine.php b/source/packages/com_mokosuitebackup/src/Engine/BackupEngine.php index 04b8f33..e1a818c 100644 --- a/source/packages/com_mokosuitebackup/src/Engine/BackupEngine.php +++ b/source/packages/com_mokosuitebackup/src/Engine/BackupEngine.php @@ -403,6 +403,17 @@ class BackupEngine NotificationSender::send($profile, $update, false, "Remote upload failed — see backup log for details.\n\n" . implode("\n", $this->log)); } + // Enforce per-profile retention (age and/or copy count). + try { + $pruned = RetentionManager::prune($db, $profile); + + if ($pruned > 0) { + $this->log('Retention: pruned ' . $pruned . ' old backup(s)'); + } + } catch (\Throwable $e) { + error_log('MokoSuiteBackup: retention pass failed: ' . $e->getMessage()); + } + // Dispatch event for actionlog and other listeners $this->dispatchAfterRun(true, $recordId, $description, $profileId, $origin); diff --git a/source/packages/com_mokosuitebackup/src/Engine/RetentionManager.php b/source/packages/com_mokosuitebackup/src/Engine/RetentionManager.php new file mode 100644 index 0000000..8a611ba --- /dev/null +++ b/source/packages/com_mokosuitebackup/src/Engine/RetentionManager.php @@ -0,0 +1,118 @@ + + * @copyright Copyright (C) 2026 Moko Consulting. All rights reserved. + * @license GNU General Public License version 3 or later; see LICENSE + */ + +namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine; + +defined('_JEXEC') or die; + +use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory; + +/** + * Enforces per-profile backup retention. + * + * A profile may cap retained backups by age (retention_days) and/or by + * number of copies (retention_count). A backup is pruned when EITHER rule + * matches: it is older than retention_days OR it falls outside the newest + * retention_count copies. Deleting a record also removes its archive and + * log file, mirroring the Backup table's delete(). + */ +final class RetentionManager +{ + /** + * Prune old backups for a profile according to its retention settings. + * + * Called after a backup completes. Only 'complete' and 'warning' records + * are considered — pending/running/failed records are never pruned here. + * + * @param object $db Database driver + * @param object $profile Profile row (needs id, retention_days, retention_count) + * + * @return int Number of backup records deleted + */ + public static function prune(object $db, object $profile): int + { + $days = (int) ($profile->retention_days ?? 0); + $count = (int) ($profile->retention_count ?? 0); + + // No retention configured — nothing to do. + if ($days <= 0 && $count <= 0) { + return 0; + } + + // Newest first, so the index is the copy's position from the top. + $query = $db->getQuery(true) + ->select($db->quoteName(['id', 'absolute_path', 'backupstart'])) + ->from($db->quoteName('#__mokosuitebackup_records')) + ->where($db->quoteName('profile_id') . ' = ' . (int) $profile->id) + ->where($db->quoteName('status') . ' IN (' . implode(',', array_map([$db, 'quote'], ['complete', 'warning'])) . ')') + ->order($db->quoteName('backupstart') . ' DESC'); + $db->setQuery($query); + $records = $db->loadObjectList() ?: []; + + if (empty($records)) { + return 0; + } + + $cutoffTs = $days > 0 ? (time() - ($days * 86400)) : null; + $deleted = 0; + + foreach ($records as $index => $record) { + $tooOld = $cutoffTs !== null && strtotime((string) $record->backupstart) < $cutoffTs; + $overCount = $count > 0 && $index >= $count; + + // Delete-if-either: prune when age OR count rule is exceeded. + if (!$tooOld && !$overCount) { + continue; + } + + if (self::deleteRecord($db, $record)) { + $deleted++; + } + } + + return $deleted; + } + + /** + * Delete a single backup record and its on-disk archive + log file. + * + * The DB row is removed first; the files are only unlinked if that + * succeeds, so a failed delete never orphans the record from its files. + */ + private static function deleteRecord(object $db, object $record): bool + { + $query = $db->getQuery(true) + ->delete($db->quoteName('#__mokosuitebackup_records')) + ->where($db->quoteName('id') . ' = ' . (int) $record->id); + $db->setQuery($query); + + try { + $db->execute(); + } catch (\Throwable $e) { + error_log('MokoSuiteBackup: retention could not delete record ' . $record->id . ': ' . $e->getMessage()); + + return false; + } + + $archivePath = (string) ($record->absolute_path ?? ''); + + if ($archivePath !== '' && is_file($archivePath)) { + @unlink($archivePath); + + $logPath = BackupDirectory::logPathFromArchive($archivePath); + + if (is_file($logPath)) { + @unlink($logPath); + } + } + + return true; + } +} diff --git a/source/packages/com_mokosuitebackup/src/Engine/SteppedBackupEngine.php b/source/packages/com_mokosuitebackup/src/Engine/SteppedBackupEngine.php index ee640e7..b78eb19 100644 --- a/source/packages/com_mokosuitebackup/src/Engine/SteppedBackupEngine.php +++ b/source/packages/com_mokosuitebackup/src/Engine/SteppedBackupEngine.php @@ -686,6 +686,13 @@ class SteppedBackupEngine if ($uploadFailed) { NotificationSender::send($profile, $record, false, "Remote upload failed — see backup log for details.\n\n" . $logContent); } + + // Enforce per-profile retention (age and/or copy count). + $pruned = RetentionManager::prune($db, $profile); + + if ($pruned > 0) { + $session->log('Retention: pruned ' . $pruned . ' old backup(s)'); + } } } catch (\Throwable $e) { error_log('MokoSuiteBackup: SteppedBackupEngine notification failed: ' . $e->getMessage()); diff --git a/source/packages/com_mokosuitebackup/tmpl/backups/default.php b/source/packages/com_mokosuitebackup/tmpl/backups/default.php index 5417461..53fe54c 100644 --- a/source/packages/com_mokosuitebackup/tmpl/backups/default.php +++ b/source/packages/com_mokosuitebackup/tmpl/backups/default.php @@ -684,19 +684,37 @@ $listDirn = $this->escape($this->state->get('list.direction')); var PURGE_TOKEN = ; var purgeCountTimer = null; - // Intercept Purge toolbar button to show the modal + // Reset modal state and show it. + function openPurgeModal() { + document.getElementById('mb-purge-date').value = ''; + document.getElementById('mb-purge-count-wrapper').style.display = 'none'; + document.getElementById('mb-purge-none-wrapper').style.display = 'none'; + document.getElementById('mb-purge-submit').disabled = true; + bootstrap.Modal.getOrCreateInstance(document.getElementById('mb-purge-modal')).show(); + } + + // Primary: wrap Joomla.submitbutton so the Purge toolbar button opens the + // modal instead of submitting the no-op backups.purgeModal task. This is + // resilient to how the Atum toolbar renders the button markup. + if (window.Joomla && typeof Joomla.submitbutton === 'function') { + var origSubmitbutton = Joomla.submitbutton; + Joomla.submitbutton = function(task) { + if (task === 'backups.purgeModal') { + openPurgeModal(); + return false; + } + return origSubmitbutton.apply(this, arguments); + }; + } + document.addEventListener('DOMContentLoaded', function() { + // Fallback: if the button still exposes an inline onclick, bind directly. var purgeBtn = document.querySelector('[onclick*="backups.purgeModal"], .button-trash'); if (purgeBtn) { purgeBtn.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); - // Reset modal state - document.getElementById('mb-purge-date').value = ''; - document.getElementById('mb-purge-count-wrapper').style.display = 'none'; - document.getElementById('mb-purge-none-wrapper').style.display = 'none'; - document.getElementById('mb-purge-submit').disabled = true; - bootstrap.Modal.getOrCreateInstance(document.getElementById('mb-purge-modal')).show(); + openPurgeModal(); return false; }, true); } diff --git a/source/packages/com_mokosuitebackup/tmpl/profile/edit.php b/source/packages/com_mokosuitebackup/tmpl/profile/edit.php index 1f6e636..a19611e 100644 --- a/source/packages/com_mokosuitebackup/tmpl/profile/edit.php +++ b/source/packages/com_mokosuitebackup/tmpl/profile/edit.php @@ -42,6 +42,7 @@ $token = Session::getFormToken();
form->renderFieldset('archive'); ?> + form->renderFieldset('retention'); ?>
From 03bf5dff7b23fa87814e0e98eaabeee599f32af2 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 20:26:04 +0000 Subject: [PATCH 22/28] chore: sync issue-branch.yml from Template-Generic [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index eb1f3c3..11958bd 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 02.54.00 +# VERSION: 01.00.00 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" From 5c5af532bb4bcf48ef1acc9f8b97be3adb137db3 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 20:26:05 +0000 Subject: [PATCH 23/28] chore: sync pr-check.yml from Template-Generic [skip ci] --- .mokogitea/workflows/pr-check.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.mokogitea/workflows/pr-check.yml b/.mokogitea/workflows/pr-check.yml index c13b15e..019371d 100644 --- a/.mokogitea/workflows/pr-check.yml +++ b/.mokogitea/workflows/pr-check.yml @@ -47,15 +47,15 @@ jobs: fi ;; fix/*|bugfix/*) - if [ "$BASE" != "dev" ]; then + if [ "$BASE" != "dev" ] && [ "$BASE" != "main" ]; then ALLOWED=false - REASON="Fix branches must target 'dev', not '${BASE}'" + REASON="Fix branches must target 'dev' or 'main', not '${BASE}'" fi ;; patch/*) - if [ "$BASE" != "dev" ] && [ "$BASE" != "rc" ]; then + if [ "$BASE" != "dev" ] && [ "$BASE" != "rc" ] && [ "$BASE" != "main" ]; then ALLOWED=false - REASON="Patch branches must target 'dev' or 'rc', not '${BASE}'" + REASON="Patch branches must target 'dev', 'rc', or 'main', not '${BASE}'" fi ;; hotfix/*) @@ -86,7 +86,8 @@ jobs: echo "" >> $GITHUB_STEP_SUMMARY echo "### Allowed merge paths:" >> $GITHUB_STEP_SUMMARY echo "- \`feature/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY - echo "- \`fix/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY + echo "- \`fix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY + echo "- \`patch/*\` → \`dev\`, \`rc\`, or \`main\`" >> $GITHUB_STEP_SUMMARY echo "- \`hotfix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY echo "- \`dev\` → \`main\`" >> $GITHUB_STEP_SUMMARY echo "- \`rc/*\` → \`main\`" >> $GITHUB_STEP_SUMMARY @@ -149,11 +150,12 @@ jobs: - name: Detect platform id: platform run: | - # Read platform from XML manifest ( tag) or plain text fallback - PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1) - [ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogitea/manifest.xml 2>/dev/null | tr -d '[:space:]') + # Platform comes from the MokoGitea metadata API (public GET); manifest.xml is no longer used. + API="${GITHUB_SERVER_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${GITHUB_REPOSITORY}/metadata" + PLATFORM="$(curl -sf "$API" 2>/dev/null | python3 -c "import sys, json; print(json.load(sys.stdin).get('platform') or '')" 2>/dev/null || true)" [ -z "$PLATFORM" ] && PLATFORM="generic" echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" + echo "Detected platform: $PLATFORM" - name: Setup PHP if: steps.platform.outputs.platform == 'joomla' || steps.platform.outputs.platform == 'dolibarr' From 175869489397a8d4c62438bd89d35e8f1d4e65d7 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 4 Jul 2026 14:34:34 -0500 Subject: [PATCH 24/28] fix(installer): apply standard licensing + install-completion script pattern Adopts the Template-Joomla package-script pattern for download-key handling and post-install messaging, while preserving all MokoSuiteBackup-specific postflight steps (plugins, webcron secret, scheduled task, submenus, client_id fix, icon sync, backup_dir migration). - preflight (update): backupDownloadKey() caches the bare dlid value - postflight (update): restoreDownloadKey() re-writes extra_query as dlid= - postflight (install): installSuccessful() + warnMissingLicenseKey() - postflight (update): installSuccessful() - License nag now runs on install only (a fresh install never has a key), removing the previous always-run "is a key present?" guard - Licensing methods log via Joomla\CMS\Log\Log instead of error_log --- source/script.php | 117 ++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 61 deletions(-) diff --git a/source/script.php b/source/script.php index 67668df..ebf16d0 100644 --- a/source/script.php +++ b/source/script.php @@ -12,6 +12,7 @@ defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\Installer\InstallerAdapter; use Joomla\CMS\Language\Text; +use Joomla\CMS\Log\Log; use Joomla\CMS\Router\Route; class Pkg_MokoSuiteBackupInstallerScript @@ -73,22 +74,25 @@ class Pkg_MokoSuiteBackupInstallerScript /* Save download key before Joomla re-registers the update site */ if ($type === 'update') { - $this->preflight_saveKey(); + $this->backupDownloadKey(); } return true; } /** - * Called before install/update to preserve the download key. - * - * Joomla re-registers update sites from the manifest on every update, - * which can reset the extra_query (download key). We save it here - * and restore it in postflight. + * The download key cached during preflight so it survives an update. */ private ?string $savedDownloadKey = null; - public function preflight_saveKey(): void + /** + * Cache the existing download key from the update sites table before update runs. + * + * Joomla re-registers update sites from the manifest on every update, which + * can reset the extra_query (download key). We save it here and restore it + * in postflight. + */ + private function backupDownloadKey(): void { try { $db = Factory::getDbo(); @@ -108,19 +112,16 @@ class Pkg_MokoSuiteBackupInstallerScript ->where($db->quoteName('e.element') . ' = ' . $db->quote('pkg_mokosuitebackup')) ->where($db->quoteName('e.type') . ' = ' . $db->quote('package')) ->setLimit(1); - $db->setQuery($query); - $key = $db->loadResult(); - if (!empty($key)) { - $this->savedDownloadKey = $key; + $db->setQuery($query); + $extraQuery = (string) $db->loadResult(); + + if (!empty($extraQuery)) { + parse_str($extraQuery, $output); + $this->savedDownloadKey = $output['dlid'] ?? $extraQuery; } } catch (\Exception $e) { - error_log('MokoSuiteBackup: Could not save download key: ' . $e->getMessage()); - Factory::getApplication()->enqueueMessage( - 'MokoSuiteBackup could not preserve your download/license key before the update. ' - . 'Please verify your license key is still configured in System → Update Sites after this update completes.', - 'warning' - ); + Log::add('MokoSuiteBackup: Could not backup download key: ' . $e->getMessage(), Log::WARNING, 'jerror'); } } @@ -138,8 +139,8 @@ class Pkg_MokoSuiteBackupInstallerScript return; } - /* Restore download key if it was saved before update */ - if ($this->savedDownloadKey !== null) { + /* Restore the download key preserved before the update re-registered the site */ + if ($type === 'update') { $this->restoreDownloadKey(); } @@ -168,14 +169,17 @@ class Pkg_MokoSuiteBackupInstallerScript /* Sync submenu icons in #__menu (Joomla doesn't update icons on upgrades) */ $this->syncMenuIcons(); - /* Warn if no license key configured */ - $this->warnMissingLicenseKey(); - /* Migrate profiles with old default backup_dir values to [DEFAULT_DIR] placeholder */ $this->migrateDefaultBackupDir(); - /* Remind user to review backup profile settings */ + /* Install completion notice (install and update) */ + $this->installSuccessful(); + if ($type === 'install') { + /* Fresh install never carries a download key — prompt for one */ + $this->warnMissingLicenseKey(); + + /* Remind user to review backup profile settings */ $profileUrl = Route::_('index.php?option=com_mokosuitebackup&view=profiles'); Factory::getApplication()->enqueueMessage( @@ -640,66 +644,57 @@ class Pkg_MokoSuiteBackupInstallerScript ->where($db->quoteName('e.element') . ' = ' . $db->quote('pkg_mokosuitebackup')) ->where($db->quoteName('e.type') . ' = ' . $db->quote('package')) ->setLimit(1); + $db->setQuery($query); $updateSiteId = (int) $db->loadResult(); - if ($updateSiteId > 0) { + if ($updateSiteId > 0 && !empty($this->savedDownloadKey)) { $query = $db->getQuery(true) ->update($db->quoteName('#__update_sites')) - ->set($db->quoteName('extra_query') . ' = ' . $db->quote($this->savedDownloadKey)) + ->set($db->quoteName('extra_query') . ' = ' . $db->quote('dlid=' . $this->savedDownloadKey)) ->where($db->quoteName('update_site_id') . ' = ' . $updateSiteId); + $db->setQuery($query); $db->execute(); } } catch (\Exception $e) { - error_log('MokoSuiteBackup: Could not restore download key: ' . $e->getMessage()); + Log::add('MokoSuiteBackup: Could not restore download key: ' . $e->getMessage(), Log::WARNING, 'jerror'); + Factory::getApplication()->enqueueMessage( - 'MokoSuiteBackup: Your download/license key could not be preserved during the update. ' - . 'Please re-enter it in the Update Sites configuration to continue receiving updates.', + '

MokoSuiteBackup

' + . '

Your download/license key could not be preserved during the update.

' + . '

Please re-enter it in the Update Sites manager to continue receiving updates.

', 'warning' ); } } + /** + * Show post-install license key prompt. + */ private function warnMissingLicenseKey(): void { - try - { - $db = Factory::getDbo(); - $db->setQuery( - $db->getQuery(true) - ->select([$db->quoteName('update_site_id'), $db->quoteName('extra_query')]) - ->from($db->quoteName('#__update_sites')) - ->where('(' . $db->quoteName('name') . ' LIKE ' . $db->quote('%MokoSuiteBackup%') . ' OR ' . $db->quoteName('location') . ' LIKE ' . $db->quote('%MokoSuiteBackup%') . ')') - ->setLimit(1) - ); - $site = $db->loadObject(); - - if ($site) - { - $eq = (string) ($site->extra_query ?? ''); - if (!empty($eq) && strpos($eq, 'dlid=') !== false) { parse_str($eq, $p); if (!empty($p['dlid'])) { return; } } - $editUrl = 'index.php?option=com_installer&task=updatesite.edit&update_site_id=' . (int) $site->update_site_id; - } - else - { - $editUrl = 'index.php?option=com_installer&view=updatesites'; - } - + try { Factory::getApplication()->enqueueMessage( - 'Moko Consulting License Key Required — ' - . 'No download key is configured. Updates will not be available until a valid license key is entered. ' - . 'Enter License Key', + '

MokoSuiteBackup License Key Required

' + . '

A download/license key (DLID) is required to receive updates.

' + . '

Enter your key in the Update Sites manager ' + . 'or contact Moko Consulting Support to obtain one.

', 'warning' ); - } - catch (\Exception $e) { - error_log('MokoSuiteBackup: License key check failed: ' . $e->getMessage()); + } catch (\Exception $e) {} + } + + /** + * Show install successful prompt. + */ + private function installSuccessful(): void + { + try { Factory::getApplication()->enqueueMessage( - 'MokoSuiteBackup could not verify your license key status. ' - . 'Please check System → Update Sites to ensure a valid license key is configured.', - 'warning' + '

MokoSuiteBackup installed successfully!

', + 'info' ); - } + } catch (\Exception $e) {} } } From 772f2b75a1fc5001179ca71682477fcfda0613d5 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Sat, 4 Jul 2026 20:27:20 +0000 Subject: [PATCH 25/28] chore(release): build 02.54.00 [skip ci] --- CHANGELOG.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d1ce17..eeda661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,8 @@ ## [02.54.00] --- 2026-07-04 -## [02.53.00] --- 2026-07-04 +## [02.54.00] --- 2026-07-04 ## [02.53.00] --- 2026-07-04 -## [02.52.24] --- 2026-06-30 - - -## [02.52.24] --- 2026-06-30 +## [02.53.00] --- 2026-07-04 From 4dc8bc69122c3c44e0f873cc4825231b832e4191 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Sat, 4 Jul 2026 20:28:01 +0000 Subject: [PATCH 26/28] chore(release): build 02.55.00 [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- CHANGELOG.md | 4 ++-- SECURITY.md | 2 +- source/packages/com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../com_mokosuitebackup/sql/updates/mysql/02.55.00.sql | 1 + .../mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml | 2 +- .../plg_actionlog_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/plg_console_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/plg_content_mokosuitebackup/mokosuitebackup.xml | 2 +- .../plg_quickicon_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/plg_system_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml | 2 +- .../plg_webservices_mokosuitebackup/mokosuitebackup.xml | 2 +- source/pkg_mokosuitebackup.xml | 2 +- 14 files changed, 15 insertions(+), 14 deletions(-) create mode 100644 source/packages/com_mokosuitebackup/sql/updates/mysql/02.55.00.sql diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 11958bd..93398bb 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.00.00 +# VERSION: 02.55.00 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/CHANGELOG.md b/CHANGELOG.md index eeda661..27c8aff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +## [02.55.00] --- 2026-07-04 + ## [02.54.00] --- 2026-07-04 ## [02.54.00] --- 2026-07-04 @@ -8,5 +10,3 @@ ## [02.54.00] --- 2026-07-04 ## [02.53.00] --- 2026-07-04 - -## [02.53.00] --- 2026-07-04 diff --git a/SECURITY.md b/SECURITY.md index ec3e33b..c3466da 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla INGROUP: Template-Joomla.Documentation REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla PATH: /SECURITY.md -VERSION: 02.54.00 +VERSION: 02.55.00 BRIEF: Security vulnerability reporting and handling policy --> diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index f72db88..9784a0e 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Component - MokoSuiteBackup - 02.54.00 + 02.55.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.55.00.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.55.00.sql new file mode 100644 index 0000000..5278158 --- /dev/null +++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.55.00.sql @@ -0,0 +1 @@ +/* 02.55.00 — no schema changes */ diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml index f0e56e0..439582f 100644 --- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml +++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml @@ -8,7 +8,7 @@ --> Module - MokoSuiteBackup - cPanel - 02.54.00 + 02.55.00 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml index 1edf2cd..0028425 100644 --- a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Action Log - MokoSuiteBackup - 02.54.00 + 02.55.00 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml index 3e9f505..d3dd271 100644 --- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Console - MokoSuiteBackup - 02.54.00 + 02.55.00 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml index a110222..d9b0bbd 100644 --- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Content - MokoSuiteBackup - 02.54.00 + 02.55.00 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml index 22c10fd..c7f0749 100644 --- a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml @@ -1,7 +1,7 @@ Quick Icon - MokoSuiteBackup - 02.54.00 + 02.55.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml index 1c5e7eb..0a0470b 100644 --- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> System - MokoSuiteBackup - 02.54.00 + 02.55.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml index 5dc3c94..c5448a1 100644 --- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Task - MokoSuiteBackup - 02.54.00 + 02.55.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml index 5fccdbe..319fd0b 100644 --- a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Web Services - MokoSuiteBackup - 02.54.00 + 02.55.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index a50be4c..9f782dc 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -8,7 +8,7 @@ Package - MokoSuiteBackup mokosuitebackup - 02.54.00 + 02.55.00 2026-06-02 Moko Consulting hello@mokoconsulting.tech From 56154680428040a5c38e47b14fe120a63ba83d2d Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Sat, 4 Jul 2026 20:28:12 +0000 Subject: [PATCH 27/28] =?UTF-8?q?chore:=20promote=20changelog=20[Unrelease?= =?UTF-8?q?d]=20=E2=86=92=20[02.55.00]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27c8aff..9786647 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## [02.55.00] --- 2026-07-04 +## [02.55.00] --- 2026-07-04 + ## [02.54.00] --- 2026-07-04 ## [02.54.00] --- 2026-07-04 From 278c572e0f1faba10091df35b97d920900dd69d6 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 4 Jul 2026 20:28:29 +0000 Subject: [PATCH 28/28] chore: sync issue-branch.yml from Template-Generic [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 93398bb..11958bd 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 02.55.00 +# VERSION: 01.00.00 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch"