feat: rename mokojoombackup → mokosuitebackup, add [HOME] placeholder for backup directory
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Renames all sub-extensions from mokojoombackup to mokosuitebackup
(package, component, 7 plugins, language files, manifests).
Adds [HOME] placeholder to BackupDirectory and PlaceholderResolver
so users can set backup_dir to [HOME]/backups (outside web root).
Fixes folder browser "access denied" on PHP-FPM shared hosting
where getenv('HOME') returns empty by adding POSIX and JPATH_ROOT
fallback detection.
This commit is contained in:
+16
-16
@@ -1,4 +1,4 @@
|
||||
# MokoJoomBackup
|
||||
# MokoSuiteBackup
|
||||
|
||||
Full-site backup and restore for Joomla — database, files, and configuration. Replaces Akeeba Backup Pro.
|
||||
|
||||
@@ -6,10 +6,10 @@ Full-site backup and restore for Joomla — database, files, and configuration.
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Package** | `pkg_mokojoombackup` |
|
||||
| **Package** | `pkg_mokosuitebackup` |
|
||||
| **Language** | PHP 8.1+ |
|
||||
| **Branch** | develop on `dev`, merge to `main` (protected) |
|
||||
| **Wiki** | [MokoJoomBackup Wiki](https://git.mokoconsulting.tech/MokoConsulting/MokoJoomBackup/wiki) |
|
||||
| **Wiki** | [MokoSuiteBackup Wiki](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteBackup/wiki) |
|
||||
|
||||
## Commands
|
||||
|
||||
@@ -26,32 +26,32 @@ composer install # Install PHP dependencies
|
||||
|
||||
Joomla **package** with four sub-extensions:
|
||||
|
||||
### com_mokojoombackup (Component)
|
||||
### com_mokosuitebackup (Component)
|
||||
- Admin backend for managing backup profiles and records
|
||||
- Backup engine: `Engine/BackupEngine`, `Engine/DatabaseDumper`, `Engine/FileScanner`, `Engine/Archiver`
|
||||
- Joomla 4/5 MVC: Controllers, Models, Views, Tables
|
||||
- Namespace: `Joomla\Component\MokoJoomBackup\Administrator`
|
||||
- DB tables: `#__mokojoombackup_profiles`, `#__mokojoombackup_records`
|
||||
- CLI: `cli/mokojoombackup.php` for cron-based backups
|
||||
- Namespace: `Joomla\Component\MokoSuiteBackup\Administrator`
|
||||
- DB tables: `#__mokosuitebackup_profiles`, `#__mokosuitebackup_records`
|
||||
- CLI: `cli/mokosuitebackup.php` for cron-based backups
|
||||
|
||||
### plg_system_mokojoombackup (System Plugin)
|
||||
### plg_system_mokosuitebackup (System Plugin)
|
||||
- Cleanup of expired backup archives (age + count limits)
|
||||
- Namespace: `Joomla\Plugin\System\MokoJoomBackup`
|
||||
- Namespace: `Joomla\Plugin\System\MokoSuiteBackup`
|
||||
|
||||
### plg_task_mokojoombackup (Task Plugin)
|
||||
### plg_task_mokosuitebackup (Task Plugin)
|
||||
- Integrates with Joomla's Scheduled Tasks (com_scheduler)
|
||||
- Registers "Run Backup Profile" task type
|
||||
- Namespace: `Joomla\Plugin\Task\MokoJoomBackup`
|
||||
- Namespace: `Joomla\Plugin\Task\MokoSuiteBackup`
|
||||
|
||||
### plg_webservices_mokojoombackup (WebServices Plugin)
|
||||
- REST API for remote backup management (wire-compatible with mcp_mokojoombackup)
|
||||
### plg_webservices_mokosuitebackup (WebServices Plugin)
|
||||
- REST API for remote backup management (wire-compatible with mcp_mokosuitebackup)
|
||||
- Endpoints: backup, backups, profiles, download, delete
|
||||
- Namespace: `Joomla\Plugin\WebServices\MokoJoomBackup`
|
||||
- Namespace: `Joomla\Plugin\WebServices\MokoSuiteBackup`
|
||||
|
||||
### Database Schema
|
||||
|
||||
- `#__mokojoombackup_profiles` — backup profiles (name, description, config JSON, filters JSON)
|
||||
- `#__mokojoombackup_records` — backup records (profile_id, status, origin, archive path, sizes, timestamps)
|
||||
- `#__mokosuitebackup_profiles` — backup profiles (name, description, config JSON, filters JSON)
|
||||
- `#__mokosuitebackup_records` — backup records (profile_id, status, origin, archive path, sizes, timestamps)
|
||||
|
||||
## Rules
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mokoplatform xmlns="https://standards.mokoconsulting.tech/mokoplatform/1.0" schema-version="1.0">
|
||||
<identity>
|
||||
<name>MokoJoomBackup</name>
|
||||
<display-name>Package - MokoJoomBackup</display-name>
|
||||
<name>MokoSuiteBackup</name>
|
||||
<display-name>Package - MokoSuiteBackup</display-name>
|
||||
<org>MokoConsulting</org>
|
||||
<description>Full-site backup and restore for Joomla — database, files, and configuration</description>
|
||||
<version>01.08.01-dev</version>
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: Gitea.Workflow
|
||||
# INGROUP: MokoPlatform.Universal
|
||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
|
||||
# PATH: /.mokogitea/workflows/rc-revert.yml
|
||||
# VERSION: 09.23.00
|
||||
# BRIEF: Rename rc/ branch back to dev/ when PR is closed without merge
|
||||
|
||||
name: "RC Revert"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
|
||||
jobs:
|
||||
revert:
|
||||
name: Rename rc/ back to dev/
|
||||
runs-on: ubuntu-latest
|
||||
if: >-
|
||||
github.event.pull_request.merged == false &&
|
||||
startsWith(github.event.pull_request.head.ref, 'rc/')
|
||||
|
||||
steps:
|
||||
- name: Rename branch
|
||||
run: |
|
||||
BRANCH="${{ github.event.pull_request.head.ref }}"
|
||||
SUFFIX="${BRANCH#rc/}"
|
||||
DEV_BRANCH="dev/${SUFFIX}"
|
||||
API="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}/api/v1/repos/${{ github.repository }}/branches"
|
||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
||||
|
||||
# Create dev/ branch from rc/ branch
|
||||
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X POST \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"new_branch_name\": \"${DEV_BRANCH}\", \"old_branch_name\": \"${BRANCH}\"}" \
|
||||
"${API}" 2>/dev/null || true)
|
||||
|
||||
if [ "$STATUS" = "201" ]; then
|
||||
echo "Created branch: ${DEV_BRANCH}" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "::error::Failed to create ${DEV_BRANCH} from ${BRANCH} (HTTP ${STATUS})"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Delete rc/ branch
|
||||
ENCODED=$(php -r "echo rawurlencode('${BRANCH}');")
|
||||
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
"${API}/${ENCODED}" 2>/dev/null || true)
|
||||
|
||||
if [ "$STATUS" = "204" ]; then
|
||||
echo "Deleted branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "::warning::Failed to delete ${BRANCH} (HTTP ${STATUS})"
|
||||
fi
|
||||
|
||||
echo "### RC Reverted" >> $GITHUB_STEP_SUMMARY
|
||||
echo "${BRANCH} → ${DEV_BRANCH}" >> $GITHUB_STEP_SUMMARY
|
||||
+2
-2
@@ -12,13 +12,13 @@
|
||||
|
||||
### Added
|
||||
- Dashboard submenu entry as default landing page with `class:home` icon
|
||||
- `[DEFAULT_DIR]` placeholder for portable backup directory configuration — resolves to `administrator/components/com_mokojoombackup/backups` at runtime
|
||||
- `[DEFAULT_DIR]` placeholder for portable backup directory configuration — resolves to `administrator/components/com_mokosuitebackup/backups` at runtime
|
||||
- Live AJAX directory validation on backup_dir field — checks existence, writability, and placeholder resolution as user types (debounced 400ms)
|
||||
- `checkDir` AJAX endpoint for real-time directory permission checking
|
||||
- Web-accessible warning badge on backup download buttons when archive is inside web root
|
||||
- Inline security warning in FolderPicker when default directory is selected
|
||||
- Auto `.htaccess` and `index.html` protection for web-accessible backup directories on profile save and at backup time
|
||||
- Font Awesome 6 submenu icons via CSS injection in `MokoJoomBackupComponent::boot()`
|
||||
- Font Awesome 6 submenu icons via CSS injection in `MokoSuiteBackupComponent::boot()`
|
||||
- `syncMenuIcons()` installer postflight — syncs icon classes to `#__menu` on install and update
|
||||
- `encryptionPassword` property on `SteppedSession` for upcoming stepped backup encryption support
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
# Contributing to MokoJoomBackup
|
||||
# Contributing to MokoSuiteBackup
|
||||
|
||||
Thank you for your interest in contributing to MokoJoomBackup.
|
||||
Thank you for your interest in contributing to MokoSuiteBackup.
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -27,7 +27,7 @@ Thank you for your interest in contributing to MokoJoomBackup.
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
Report bugs and feature requests via [Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoJoomBackup/issues).
|
||||
Report bugs and feature requests via [Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteBackup/issues).
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# MokoJoomBackup — Full-site backup and restore for Joomla
|
||||
# MokoSuiteBackup — Full-site backup and restore for Joomla
|
||||
#
|
||||
# Builds and releases are handled by CI workflows (pre-release.yml,
|
||||
# auto-release.yml). This Makefile provides local validation helpers
|
||||
@@ -12,7 +12,7 @@
|
||||
# CONFIGURATION
|
||||
# ==============================================================================
|
||||
|
||||
EXTENSION_NAME := mokojoombackup
|
||||
EXTENSION_NAME := mokosuitebackup
|
||||
EXTENSION_TYPE := package
|
||||
|
||||
SRC_DIR := source
|
||||
@@ -20,7 +20,7 @@ SRC_DIR := source
|
||||
# Gitea
|
||||
GITEA_URL := https://git.mokoconsulting.tech
|
||||
GITEA_ORG := MokoConsulting
|
||||
GITEA_REPO := MokoJoomBackup
|
||||
GITEA_REPO := MokoSuiteBackup
|
||||
|
||||
# Tools
|
||||
PHP := php
|
||||
@@ -44,7 +44,7 @@ COLOR_RED := \033[31m
|
||||
.PHONY: help
|
||||
help: ## Show this help message
|
||||
@echo "$(COLOR_BLUE)╔════════════════════════════════════════════════════════════╗$(COLOR_RESET)"
|
||||
@echo "$(COLOR_BLUE)║ MokoJoomBackup Makefile ║$(COLOR_RESET)"
|
||||
@echo "$(COLOR_BLUE)║ MokoSuiteBackup Makefile ║$(COLOR_RESET)"
|
||||
@echo "$(COLOR_BLUE)╚════════════════════════════════════════════════════════════╝$(COLOR_RESET)"
|
||||
@echo ""
|
||||
@echo "$(COLOR_GREEN)Available targets:$(COLOR_RESET)"
|
||||
@@ -158,7 +158,7 @@ release-rc: validate validate-xml ## Trigger release-candidate build via CI work
|
||||
|
||||
.PHONY: version
|
||||
version: ## Display version from package manifest
|
||||
@VERSION=$$(grep '<version>' $(SRC_DIR)/pkg_mokojoombackup.xml | sed 's/.*<version>\(.*\)<\/version>.*/\1/'); \
|
||||
@VERSION=$$(grep '<version>' $(SRC_DIR)/pkg_mokosuitebackup.xml | sed 's/.*<version>\(.*\)<\/version>.*/\1/'); \
|
||||
echo "$(COLOR_BLUE)$(EXTENSION_NAME)$(COLOR_RESET) v$$VERSION ($(EXTENSION_TYPE))"
|
||||
|
||||
# Default target
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# MokoJoomBackup
|
||||
# MokoSuiteBackup
|
||||
|
||||
<!-- VERSION: 01.08.01 -->
|
||||
|
||||
@@ -6,7 +6,7 @@ Full-site backup and restore for Joomla — database, files, and configuration.
|
||||
|
||||
## Overview
|
||||
|
||||
MokoJoomBackup is a comprehensive backup solution for Joomla 4/5/6 sites. It creates complete site backups including the database, files, and configuration, packaged into downloadable ZIP archives. Supports multiple backup profiles, scheduled backups via CLI/cron, and a REST API for remote management.
|
||||
MokoSuiteBackup is a comprehensive backup solution for Joomla 4/5/6 sites. It creates complete site backups including the database, files, and configuration, packaged into downloadable ZIP archives. Supports multiple backup profiles, scheduled backups via CLI/cron, and a REST API for remote management.
|
||||
|
||||
## Features
|
||||
|
||||
@@ -25,13 +25,13 @@ MokoJoomBackup is a comprehensive backup solution for Joomla 4/5/6 sites. It cre
|
||||
|
||||
## Installation
|
||||
|
||||
1. Download `pkg_mokobackup-*.zip` from [Releases](https://git.mokoconsulting.tech/MokoConsulting/MokoJoomBackup/releases)
|
||||
1. Download `pkg_mokobackup-*.zip` from [Releases](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteBackup/releases)
|
||||
2. Joomla Administrator > Extensions > Install
|
||||
3. System plugin enabled automatically on install
|
||||
|
||||
## Configuration
|
||||
|
||||
- **Component**: Administrator > Components > MokoJoomBackup
|
||||
- **Component**: Administrator > Components > MokoSuiteBackup
|
||||
- **Profiles**: Create backup profiles with different file/database filters
|
||||
- **System Plugin**: Configure scheduled backup triggers and notifications
|
||||
- **CLI**: `php cli/mokobackup.php --profile=1` for cron-based backups
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
; MokoJoomBackup — Package language file (en-GB)
|
||||
; @package MokoJoomBackup
|
||||
; @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
; @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; @license GPL-3.0-or-later
|
||||
|
||||
PKG_MOKOJOOMBACKUP="Package - MokoJoomBackup"
|
||||
PKG_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla — database, files, and configuration. Includes admin component, system plugin, and REST API."
|
||||
PKG_MOKOJOOMBACKUP_PHP_VERSION_ERROR="MokoJoomBackup requires PHP %s or later."
|
||||
PKG_MOKOJOOMBACKUP_POSTINSTALL_UPDATE_SITE="MokoJoomBackup installed successfully. Configure your <a href=\"%s\">Update Site</a> to receive automatic updates."
|
||||
@@ -0,0 +1,10 @@
|
||||
; MokoSuiteBackup — Package language file (en-GB)
|
||||
; @package MokoSuiteBackup
|
||||
; @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
; @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; @license GPL-3.0-or-later
|
||||
|
||||
PKG_MOKOJOOMBACKUP="Package - MokoSuiteBackup"
|
||||
PKG_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla — database, files, and configuration. Includes admin component, system plugin, and REST API."
|
||||
PKG_MOKOJOOMBACKUP_PHP_VERSION_ERROR="MokoSuiteBackup requires PHP %s or later."
|
||||
PKG_MOKOJOOMBACKUP_POSTINSTALL_UPDATE_SITE="MokoSuiteBackup installed successfully. Configure your <a href=\"%s\">Update Site</a> to receive automatic updates."
|
||||
@@ -1,10 +0,0 @@
|
||||
; MokoJoomBackup — Package language file (en-US)
|
||||
; @package MokoJoomBackup
|
||||
; @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
; @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; @license GPL-3.0-or-later
|
||||
|
||||
PKG_MOKOJOOMBACKUP="Package - MokoJoomBackup"
|
||||
PKG_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla — database, files, and configuration. Includes admin component, system plugin, and REST API."
|
||||
PKG_MOKOJOOMBACKUP_PHP_VERSION_ERROR="MokoJoomBackup requires PHP %s or later."
|
||||
PKG_MOKOJOOMBACKUP_POSTINSTALL_UPDATE_SITE="MokoJoomBackup installed successfully. Configure your <a href=\"%s\">Update Site</a> to receive automatic updates."
|
||||
@@ -0,0 +1,10 @@
|
||||
; MokoSuiteBackup — Package language file (en-US)
|
||||
; @package MokoSuiteBackup
|
||||
; @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
; @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; @license GPL-3.0-or-later
|
||||
|
||||
PKG_MOKOJOOMBACKUP="Package - MokoSuiteBackup"
|
||||
PKG_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla — database, files, and configuration. Includes admin component, system plugin, and REST API."
|
||||
PKG_MOKOJOOMBACKUP_PHP_VERSION_ERROR="MokoSuiteBackup requires PHP %s or later."
|
||||
PKG_MOKOJOOMBACKUP_POSTINSTALL_UPDATE_SITE="MokoSuiteBackup installed successfully. Configure your <a href=\"%s\">Update Site</a> to receive automatic updates."
|
||||
@@ -1,2 +0,0 @@
|
||||
DROP TABLE IF EXISTS `#__mokojoombackup_records`;
|
||||
DROP TABLE IF EXISTS `#__mokojoombackup_profiles`;
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE `#__mokojoombackup_profiles` CHANGE `include_kickstart` `include_mokorestore` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Include MokoRestore standalone restore script in archive';
|
||||
@@ -1,12 +0,0 @@
|
||||
-- MokoJoomBackup 01.01.02
|
||||
-- Consolidated schema updates: NULL defaults, notifications, archive name format
|
||||
|
||||
-- Fix: allow NULL defaults for manifest and log columns
|
||||
ALTER TABLE `#__mokojoombackup_records` MODIFY `manifest` LONGTEXT DEFAULT NULL;
|
||||
ALTER TABLE `#__mokojoombackup_records` MODIFY `log` MEDIUMTEXT DEFAULT NULL;
|
||||
|
||||
-- Add user group notifications column to profiles
|
||||
ALTER TABLE `#__mokojoombackup_profiles` ADD COLUMN `notify_user_groups` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Comma-separated Joomla user group IDs' AFTER `notify_email`;
|
||||
|
||||
-- Add archive_name_format column with placeholder support
|
||||
ALTER TABLE `#__mokojoombackup_profiles` ADD COLUMN `archive_name_format` VARCHAR(512) NOT NULL DEFAULT '[host]_[datetime]_profile[profile_id]' COMMENT 'Filename format with placeholders' AFTER `backup_dir`;
|
||||
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Extension;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Extension\MVCComponent;
|
||||
use Joomla\CMS\Factory;
|
||||
|
||||
class MokoJoomBackupComponent extends MVCComponent
|
||||
{
|
||||
public function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
try {
|
||||
$app = Factory::getApplication();
|
||||
|
||||
if (!$app->isClient('administrator')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wa = $app->getDocument()->getWebAssetManager();
|
||||
$wa->addInlineStyle(
|
||||
'#menu a[href*="com_mokojoombackup"][href*="view=dashboard"] .sidebar-item-title::before,'
|
||||
. ' #menu a[href*="com_mokojoombackup"][href*="view=backups"] .sidebar-item-title::before,'
|
||||
. ' #menu a[href*="com_mokojoombackup"][href*="view=profiles"] .sidebar-item-title::before'
|
||||
. ' { font-family: "Font Awesome 6 Free"; font-weight: 900; margin-right: .5em; }'
|
||||
. ' #menu a[href*="com_mokojoombackup"][href*="view=dashboard"] .sidebar-item-title::before { content: "\f015"; }'
|
||||
. ' #menu a[href*="com_mokojoombackup"][href*="view=backups"] .sidebar-item-title::before { content: "\f1c0"; }'
|
||||
. ' #menu a[href*="com_mokojoombackup"][href*="view=profiles"] .sidebar-item-title::before { content: "\f013"; }'
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
error_log('MokoJoomBackup: boot() CSS injection failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -1,19 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Api\Controller;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Api\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\ApiController;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Engine\BackupEngine;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Engine\BackupEngine;
|
||||
|
||||
class BackupsController extends ApiController
|
||||
{
|
||||
@@ -21,7 +21,7 @@ class BackupsController extends ApiController
|
||||
protected $default_view = 'backups';
|
||||
|
||||
/**
|
||||
* Start a new backup (POST /api/index.php/v1/mokojoombackup/backup)
|
||||
* Start a new backup (POST /api/index.php/v1/mokosuitebackup/backup)
|
||||
*/
|
||||
public function backup(): static
|
||||
{
|
||||
@@ -47,7 +47,7 @@ class BackupsController extends ApiController
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a backup archive (GET /api/index.php/v1/mokojoombackup/backup/:id/download)
|
||||
* Download a backup archive (GET /api/index.php/v1/mokosuitebackup/backup/:id/download)
|
||||
*/
|
||||
public function download(): static
|
||||
{
|
||||
@@ -74,7 +74,7 @@ class BackupsController extends ApiController
|
||||
}
|
||||
|
||||
/**
|
||||
* List backup profiles (GET /api/index.php/v1/mokojoombackup/profiles)
|
||||
* List backup profiles (GET /api/index.php/v1/mokosuitebackup/profiles)
|
||||
*/
|
||||
public function profiles(): static
|
||||
{
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Api\View\Backups;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Api\View\Backups;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -10,7 +10,7 @@
|
||||
* CLI backup script for cron/scheduled use.
|
||||
*
|
||||
* Usage:
|
||||
* php cli/mokojoombackup.php --profile=1 --description="Scheduled backup"
|
||||
* php cli/mokosuitebackup.php --profile=1 --description="Scheduled backup"
|
||||
*
|
||||
* Must be run from the Joomla root directory.
|
||||
*/
|
||||
@@ -30,7 +30,7 @@ if (!defined('JPATH_BASE')) {
|
||||
require_once JPATH_BASE . '/includes/framework.php';
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Engine\BackupEngine;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Engine\BackupEngine;
|
||||
|
||||
// Parse CLI arguments
|
||||
$profileId = 1;
|
||||
@@ -51,7 +51,7 @@ if (empty($description)) {
|
||||
// Boot the application
|
||||
$app = Factory::getApplication('administrator');
|
||||
|
||||
echo "MokoJoomBackup CLI\n";
|
||||
echo "MokoSuiteBackup CLI\n";
|
||||
echo "Profile: {$profileId}\n";
|
||||
echo "Description: {$description}\n";
|
||||
echo "Starting backup...\n\n";
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -13,15 +13,15 @@
|
||||
type="FolderPicker"
|
||||
label="COM_MOKOJOOMBACKUP_CONFIG_DEFAULT_BACKUP_DIR"
|
||||
description="COM_MOKOJOOMBACKUP_CONFIG_DEFAULT_BACKUP_DIR_DESC"
|
||||
default="administrator/components/com_mokojoombackup/backups"
|
||||
addfieldprefix="Joomla\Component\MokoJoomBackup\Administrator\Field"
|
||||
default="administrator/components/com_mokosuitebackup/backups"
|
||||
addfieldprefix="Joomla\Component\MokoSuiteBackup\Administrator\Field"
|
||||
/>
|
||||
<field
|
||||
name="default_profile"
|
||||
type="sql"
|
||||
label="COM_MOKOJOOMBACKUP_CONFIG_DEFAULT_PROFILE"
|
||||
description="COM_MOKOJOOMBACKUP_CONFIG_DEFAULT_PROFILE_DESC"
|
||||
query="SELECT id AS value, title AS text FROM #__mokojoombackup_profiles WHERE published = 1 ORDER BY ordering ASC"
|
||||
query="SELECT id AS value, title AS text FROM #__mokosuitebackup_profiles WHERE published = 1 ORDER BY ordering ASC"
|
||||
default="1"
|
||||
>
|
||||
<option value="1">Default Backup Profile</option>
|
||||
@@ -133,7 +133,7 @@
|
||||
label="JCONFIG_PERMISSIONS_LABEL"
|
||||
filter="rules"
|
||||
validate="rules"
|
||||
component="com_mokojoombackup"
|
||||
component="com_mokosuitebackup"
|
||||
section="component"
|
||||
/>
|
||||
</fieldset>
|
||||
+4
-4
@@ -68,7 +68,7 @@
|
||||
label="COM_MOKOJOOMBACKUP_FIELD_BACKUP_DIR"
|
||||
description="COM_MOKOJOOMBACKUP_FIELD_BACKUP_DIR_DESC"
|
||||
default="[DEFAULT_DIR]"
|
||||
addfieldprefix="Joomla\Component\MokoJoomBackup\Administrator\Field"
|
||||
addfieldprefix="Joomla\Component\MokoSuiteBackup\Administrator\Field"
|
||||
/>
|
||||
<field
|
||||
name="archive_name_format"
|
||||
@@ -129,7 +129,7 @@
|
||||
description="COM_MOKOJOOMBACKUP_FIELD_EXCLUDE_DIRS_DESC"
|
||||
filter="raw"
|
||||
hint="tmp"
|
||||
addfieldprefix="Joomla\Component\MokoJoomBackup\Administrator\Field"
|
||||
addfieldprefix="Joomla\Component\MokoSuiteBackup\Administrator\Field"
|
||||
/>
|
||||
<field
|
||||
name="exclude_files"
|
||||
@@ -138,7 +138,7 @@
|
||||
description="COM_MOKOJOOMBACKUP_FIELD_EXCLUDE_FILES_DESC"
|
||||
filter="raw"
|
||||
hint="*.bak"
|
||||
addfieldprefix="Joomla\Component\MokoJoomBackup\Administrator\Field"
|
||||
addfieldprefix="Joomla\Component\MokoSuiteBackup\Administrator\Field"
|
||||
/>
|
||||
<field
|
||||
name="exclude_tables"
|
||||
@@ -146,7 +146,7 @@
|
||||
label="COM_MOKOJOOMBACKUP_FIELD_EXCLUDE_TABLES"
|
||||
description="COM_MOKOJOOMBACKUP_FIELD_EXCLUDE_TABLES_DESC"
|
||||
filter="raw"
|
||||
addfieldprefix="Joomla\Component\MokoJoomBackup\Administrator\Field"
|
||||
addfieldprefix="Joomla\Component\MokoSuiteBackup\Administrator\Field"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
+8
-8
@@ -1,10 +1,10 @@
|
||||
; MokoJoomBackup — Component language file (en-GB)
|
||||
; @package MokoJoomBackup
|
||||
; MokoSuiteBackup — Component language file (en-GB)
|
||||
; @package MokoSuiteBackup
|
||||
; @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
; @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; @license GPL-3.0-or-later
|
||||
|
||||
COM_MOKOJOOMBACKUP="MokoJoomBackup"
|
||||
COM_MOKOJOOMBACKUP="MokoSuiteBackup"
|
||||
COM_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla"
|
||||
|
||||
; Submenu
|
||||
@@ -13,7 +13,7 @@ COM_MOKOJOOMBACKUP_SUBMENU_BACKUPS="Backup Records"
|
||||
COM_MOKOJOOMBACKUP_SUBMENU_PROFILES="Backup Profiles"
|
||||
|
||||
; Dashboard view
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_TITLE="MokoJoomBackup Dashboard"
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_TITLE="MokoSuiteBackup Dashboard"
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_LAST_BACKUP="Last Backup"
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_NO_BACKUPS="No backups yet"
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_NEXT_SCHEDULED="Next Scheduled"
|
||||
@@ -94,7 +94,7 @@ COM_MOKOJOOMBACKUP_FIELD_ENCRYPTION_PASSWORD_DESC="Set a password to encrypt the
|
||||
COM_MOKOJOOMBACKUP_FIELD_SPLIT_SIZE="Split Size (MB)"
|
||||
COM_MOKOJOOMBACKUP_FIELD_SPLIT_SIZE_DESC="Split archive into parts of this size in MB. 0 = no splitting."
|
||||
COM_MOKOJOOMBACKUP_FIELD_BACKUP_DIR="Backup Directory"
|
||||
COM_MOKOJOOMBACKUP_FIELD_BACKUP_DIR_DESC="Directory where backup archives are stored. Supports placeholders: [host], [date], [year], [month], [day], [profile_name], [site_name], [type]. Absolute paths (starting with /) are used as-is; relative paths resolve from the Joomla root."
|
||||
COM_MOKOJOOMBACKUP_FIELD_BACKUP_DIR_DESC="Directory where backup archives are stored. Supports placeholders: [HOME] (user home directory), [host], [date], [year], [month], [day], [profile_name], [site_name], [type]. Use [HOME]/backups to store outside the web root. Absolute paths (starting with /) are used as-is; relative paths resolve from the Joomla root."
|
||||
COM_MOKOJOOMBACKUP_FIELD_ARCHIVE_NAME_FORMAT="Archive Name Format"
|
||||
COM_MOKOJOOMBACKUP_FIELD_ARCHIVE_NAME_FORMAT_DESC="Filename template for backup archives (without extension). Placeholders: [host] hostname, [date] Ymd, [time] His, [datetime] Ymd_His, [year] [month] [day] [hour] [minute] [second], [profile_id], [profile_name], [site_name], [type], [random]."
|
||||
COM_MOKOJOOMBACKUP_FIELD_INCLUDE_MOKORESTORE="Include Restore Script"
|
||||
@@ -216,8 +216,8 @@ COM_MOKOJOOMBACKUP_AKEEBA_NOT_FOUND="Akeeba Backup tables not found. Is Akeeba B
|
||||
|
||||
; Update site notice
|
||||
COM_MOKOJOOMBACKUP_UPDATE_SITE_NOTICE="To receive automatic updates, configure your <a href=\"%s\">Update Site</a> with your download key."
|
||||
COM_MOKOJOOMBACKUP_UPDATE_SITE_MISSING="MokoJoomBackup update site not found. Reinstall the package to register the update server."
|
||||
COM_MOKOJOOMBACKUP_POSTINSTALL_UPDATE_SITE="MokoJoomBackup installed successfully. Configure your <a href=\"%s\">Update Site</a> to receive automatic updates."
|
||||
COM_MOKOJOOMBACKUP_UPDATE_SITE_MISSING="MokoSuiteBackup update site not found. Reinstall the package to register the update server."
|
||||
COM_MOKOJOOMBACKUP_POSTINSTALL_UPDATE_SITE="MokoSuiteBackup installed successfully. Configure your <a href=\"%s\">Update Site</a> to receive automatic updates."
|
||||
|
||||
; Component Options (config.xml)
|
||||
COM_MOKOJOOMBACKUP_CONFIG_GENERAL="General"
|
||||
@@ -245,7 +245,7 @@ COM_MOKOJOOMBACKUP_CONFIG_WEBCRON="Web Cron"
|
||||
COM_MOKOJOOMBACKUP_CONFIG_WEBCRON_ENABLED="Enable Web Cron"
|
||||
COM_MOKOJOOMBACKUP_CONFIG_WEBCRON_ENABLED_DESC="Allow backups to be triggered via a URL with a secret key. Use this when crontab is not available on shared hosting."
|
||||
COM_MOKOJOOMBACKUP_CONFIG_WEBCRON_SECRET="Secret Word"
|
||||
COM_MOKOJOOMBACKUP_CONFIG_WEBCRON_SECRET_DESC="The secret key required in the URL to trigger a backup. Use a long, random string. URL format: index.php?mokojoombackup_cron=YOUR_SECRET&profile_id=1"
|
||||
COM_MOKOJOOMBACKUP_CONFIG_WEBCRON_SECRET_DESC="The secret key required in the URL to trigger a backup. Use a long, random string. URL format: index.php?mokosuitebackup_cron=YOUR_SECRET&profile_id=1"
|
||||
COM_MOKOJOOMBACKUP_CONFIG_WEBCRON_IP="IP Whitelist"
|
||||
COM_MOKOJOOMBACKUP_CONFIG_WEBCRON_IP_DESC="Comma-separated list of IP addresses allowed to trigger web cron. Leave blank to allow any IP."
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
; MokoJoomBackup — Component system language file (en-GB)
|
||||
; @package MokoJoomBackup
|
||||
; MokoSuiteBackup — Component system language file (en-GB)
|
||||
; @package MokoSuiteBackup
|
||||
; @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
; @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; @license GPL-3.0-or-later
|
||||
|
||||
COM_MOKOJOOMBACKUP="MokoJoomBackup"
|
||||
COM_MOKOJOOMBACKUP="MokoSuiteBackup"
|
||||
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"
|
||||
+6
-6
@@ -1,15 +1,15 @@
|
||||
; MokoJoomBackup — Component language file (en-US)
|
||||
; @package MokoJoomBackup
|
||||
; MokoSuiteBackup — Component language file (en-US)
|
||||
; @package MokoSuiteBackup
|
||||
; @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
; @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; @license GPL-3.0-or-later
|
||||
|
||||
COM_MOKOJOOMBACKUP="MokoJoomBackup"
|
||||
COM_MOKOJOOMBACKUP="MokoSuiteBackup"
|
||||
COM_MOKOJOOMBACKUP_DESCRIPTION="Full-site backup and restore for Joomla"
|
||||
COM_MOKOJOOMBACKUP_SUBMENU_DASHBOARD="Dashboard"
|
||||
COM_MOKOJOOMBACKUP_SUBMENU_BACKUPS="Backup Records"
|
||||
COM_MOKOJOOMBACKUP_SUBMENU_PROFILES="Backup Profiles"
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_TITLE="MokoJoomBackup Dashboard"
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_TITLE="MokoSuiteBackup Dashboard"
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_LAST_BACKUP="Last Backup"
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_NO_BACKUPS="No backups yet"
|
||||
COM_MOKOJOOMBACKUP_DASHBOARD_NEXT_SCHEDULED="Next Scheduled"
|
||||
@@ -27,8 +27,8 @@ 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."
|
||||
COM_MOKOJOOMBACKUP_UPDATE_SITE_NOTICE="To receive automatic updates, configure your <a href=\"%s\">Update Site</a> with your download key."
|
||||
COM_MOKOJOOMBACKUP_UPDATE_SITE_MISSING="MokoJoomBackup update site not found. Reinstall the package to register the update server."
|
||||
COM_MOKOJOOMBACKUP_POSTINSTALL_UPDATE_SITE="MokoJoomBackup installed successfully. Configure your <a href=\"%s\">Update Site</a> to receive automatic updates."
|
||||
COM_MOKOJOOMBACKUP_UPDATE_SITE_MISSING="MokoSuiteBackup update site not found. Reinstall the package to register the update server."
|
||||
COM_MOKOJOOMBACKUP_POSTINSTALL_UPDATE_SITE="MokoSuiteBackup installed successfully. Configure your <a href=\"%s\">Update Site</a> to receive automatic updates."
|
||||
COM_MOKOJOOMBACKUP_CONFIG_GENERAL="General"
|
||||
COM_MOKOJOOMBACKUP_CONFIG_DEFAULT_BACKUP_DIR="Default Backup Directory"
|
||||
COM_MOKOJOOMBACKUP_CONFIG_DEFAULT_BACKUP_DIR_DESC="Default directory for backup archives, relative to Joomla root. Can be overridden per profile."
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
; MokoJoomBackup — Component system language file (en-US)
|
||||
; @package MokoJoomBackup
|
||||
; MokoSuiteBackup — Component system language file (en-US)
|
||||
; @package MokoSuiteBackup
|
||||
; @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
; @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; @license GPL-3.0-or-later
|
||||
|
||||
COM_MOKOJOOMBACKUP="MokoJoomBackup"
|
||||
COM_MOKOJOOMBACKUP="MokoSuiteBackup"
|
||||
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"
|
||||
+10
-10
@@ -1,14 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
-->
|
||||
<extension type="component" method="upgrade">
|
||||
<name>com_mokojoombackup</name>
|
||||
<version>01.08.01-dev</version>
|
||||
<name>com_mokosuitebackup</name>
|
||||
<version>01.07.00</version>
|
||||
<creationDate>2026-06-02</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
@@ -17,7 +17,7 @@
|
||||
<license>GPL-3.0-or-later</license>
|
||||
<description>COM_MOKOJOOMBACKUP_DESCRIPTION</description>
|
||||
|
||||
<namespace path="src">Joomla\Component\MokoJoomBackup</namespace>
|
||||
<namespace path="src">Joomla\Component\MokoSuiteBackup</namespace>
|
||||
|
||||
<install>
|
||||
<sql>
|
||||
@@ -40,9 +40,9 @@
|
||||
<administration>
|
||||
<menu img="class:archive">COM_MOKOJOOMBACKUP</menu>
|
||||
<submenu>
|
||||
<menu link="option=com_mokojoombackup&view=dashboard" img="class:home">COM_MOKOJOOMBACKUP_SUBMENU_DASHBOARD</menu>
|
||||
<menu link="option=com_mokojoombackup&view=backups" img="class:database">COM_MOKOJOOMBACKUP_SUBMENU_BACKUPS</menu>
|
||||
<menu link="option=com_mokojoombackup&view=profiles" img="class:cog">COM_MOKOJOOMBACKUP_SUBMENU_PROFILES</menu>
|
||||
<menu link="option=com_mokosuitebackup&view=dashboard" img="class:home">COM_MOKOJOOMBACKUP_SUBMENU_DASHBOARD</menu>
|
||||
<menu link="option=com_mokosuitebackup&view=backups" img="class:database">COM_MOKOJOOMBACKUP_SUBMENU_BACKUPS</menu>
|
||||
<menu link="option=com_mokosuitebackup&view=profiles" img="class:cog">COM_MOKOJOOMBACKUP_SUBMENU_PROFILES</menu>
|
||||
</submenu>
|
||||
<files folder=".">
|
||||
<folder>cli</folder>
|
||||
@@ -53,8 +53,8 @@
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages folder="language">
|
||||
<language tag="en-GB">en-GB/com_mokojoombackup.ini</language>
|
||||
<language tag="en-GB">en-GB/com_mokojoombackup.sys.ini</language>
|
||||
<language tag="en-GB">en-GB/com_mokosuitebackup.ini</language>
|
||||
<language tag="en-GB">en-GB/com_mokosuitebackup.sys.ini</language>
|
||||
</languages>
|
||||
</administration>
|
||||
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -15,20 +15,20 @@ use Joomla\CMS\Extension\ComponentInterface;
|
||||
use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\MVCFactory;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Extension\MokoJoomBackupComponent;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Extension\MokoSuiteBackupComponent;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
return new class () implements ServiceProviderInterface {
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\MokoJoomBackup'));
|
||||
$container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\MokoJoomBackup'));
|
||||
$container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\MokoSuiteBackup'));
|
||||
$container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\MokoSuiteBackup'));
|
||||
|
||||
$container->set(
|
||||
ComponentInterface::class,
|
||||
function (Container $container) {
|
||||
$component = new MokoJoomBackupComponent(
|
||||
$component = new MokoSuiteBackupComponent(
|
||||
$container->get(ComponentDispatcherFactoryInterface::class)
|
||||
);
|
||||
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
CREATE TABLE IF NOT EXISTS `#__mokojoombackup_profiles` (
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_profiles` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`title` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`description` TEXT NOT NULL,
|
||||
@@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS `#__mokojoombackup_profiles` (
|
||||
`archive_format` VARCHAR(10) NOT NULL DEFAULT 'zip',
|
||||
`compression_level` TINYINT(1) UNSIGNED NOT NULL DEFAULT 5 COMMENT '0=none, 9=max',
|
||||
`split_size` INT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '0=no split, otherwise MB per part',
|
||||
`backup_dir` VARCHAR(512) NOT NULL DEFAULT 'administrator/components/com_mokojoombackup/backups',
|
||||
`backup_dir` VARCHAR(512) NOT NULL DEFAULT 'administrator/components/com_mokosuitebackup/backups',
|
||||
`archive_name_format` VARCHAR(512) NOT NULL DEFAULT '[host]_[datetime]_profile[profile_id]' COMMENT 'Filename format with placeholders',
|
||||
`exclude_dirs` TEXT NOT NULL COMMENT 'Newline-separated directory paths to exclude',
|
||||
`exclude_files` TEXT NOT NULL COMMENT 'Newline-separated filename patterns to exclude',
|
||||
@@ -44,7 +44,7 @@ CREATE TABLE IF NOT EXISTS `#__mokojoombackup_profiles` (
|
||||
KEY `idx_published` (`published`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokojoombackup_records` (
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_records` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`profile_id` INT(11) UNSIGNED NOT NULL DEFAULT 1,
|
||||
`description` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
@@ -74,15 +74,15 @@ CREATE TABLE IF NOT EXISTS `#__mokojoombackup_records` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Insert default backup profile (IGNORE prevents duplicate key error on update)
|
||||
INSERT IGNORE INTO `#__mokojoombackup_profiles` (
|
||||
INSERT IGNORE INTO `#__mokosuitebackup_profiles` (
|
||||
`id`, `title`, `description`, `backup_type`,
|
||||
`archive_format`, `compression_level`, `split_size`, `backup_dir`,
|
||||
`exclude_dirs`, `exclude_files`, `exclude_tables`,
|
||||
`published`, `ordering`, `created`, `modified`
|
||||
) VALUES (
|
||||
1, 'Default Backup Profile', 'Full site backup with default settings', 'full',
|
||||
'zip', 5, 0, 'administrator/components/com_mokojoombackup/backups',
|
||||
'administrator/components/com_mokojoombackup/backups\ntmp\ncache\nlogs\nadministrator/logs',
|
||||
'zip', 5, 0, 'administrator/components/com_mokosuitebackup/backups',
|
||||
'administrator/components/com_mokosuitebackup/backups\ntmp\ncache\nlogs\nadministrator/logs',
|
||||
'.gitignore\n.htaccess.bak',
|
||||
'#__session',
|
||||
1, 1, NOW(), NOW()
|
||||
@@ -0,0 +1,2 @@
|
||||
DROP TABLE IF EXISTS `#__mokosuitebackup_records`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebackup_profiles`;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `#__mokosuitebackup_profiles` CHANGE `include_kickstart` `include_mokorestore` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Include MokoRestore standalone restore script in archive';
|
||||
@@ -0,0 +1,12 @@
|
||||
-- MokoSuiteBackup 01.01.02
|
||||
-- Consolidated schema updates: NULL defaults, notifications, archive name format
|
||||
|
||||
-- Fix: allow NULL defaults for manifest and log columns
|
||||
ALTER TABLE `#__mokosuitebackup_records` MODIFY `manifest` LONGTEXT DEFAULT NULL;
|
||||
ALTER TABLE `#__mokosuitebackup_records` MODIFY `log` MEDIUMTEXT DEFAULT NULL;
|
||||
|
||||
-- Add user group notifications column to profiles
|
||||
ALTER TABLE `#__mokosuitebackup_profiles` ADD COLUMN `notify_user_groups` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Comma-separated Joomla user group IDs' AFTER `notify_email`;
|
||||
|
||||
-- Add archive_name_format column with placeholder support
|
||||
ALTER TABLE `#__mokosuitebackup_profiles` ADD COLUMN `archive_name_format` VARCHAR(512) NOT NULL DEFAULT '[host]_[datetime]_profile[profile_id]' COMMENT 'Filename format with placeholders' AFTER `backup_dir`;
|
||||
+9
-9
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -11,14 +11,14 @@
|
||||
* Handles init and step requests from the admin UI JavaScript.
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Controller;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Session\Session;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Engine\SteppedBackupEngine;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Engine\SteppedBackupEngine;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory;
|
||||
|
||||
class AjaxController extends BaseController
|
||||
{
|
||||
@@ -86,7 +86,7 @@ class AjaxController extends BaseController
|
||||
|
||||
// Security: restrict browsing to site root and current user's home
|
||||
$jRoot = realpath(JPATH_ROOT);
|
||||
$homeDir = getenv('HOME') ?: (getenv('USERPROFILE') ?: '');
|
||||
$homeDir = BackupDirectory::getHomeDirectory();
|
||||
$allowed = false;
|
||||
|
||||
if ($jRoot !== false && strpos($path, $jRoot) === 0) {
|
||||
@@ -143,7 +143,7 @@ class AjaxController extends BaseController
|
||||
if ($parent !== $path) {
|
||||
if ($jRoot !== false && strpos($parent, $jRoot) === 0) {
|
||||
$parentAllowed = true;
|
||||
} elseif ($homeDir !== '' && strpos($parent, $homeDir) === 0) {
|
||||
} elseif ($homeDir !== '' && (strpos($parent, $homeDir) === 0 || $parent === \dirname($homeDir))) {
|
||||
$parentAllowed = true;
|
||||
}
|
||||
}
|
||||
@@ -185,7 +185,7 @@ class AjaxController extends BaseController
|
||||
$db = \Joomla\CMS\Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(['absolute_path', 'log']))
|
||||
->from($db->quoteName('#__mokojoombackup_records'))
|
||||
->from($db->quoteName('#__mokosuitebackup_records'))
|
||||
->where($db->quoteName('id') . ' = ' . (int) $id);
|
||||
$db->setQuery($query);
|
||||
$record = $db->loadObject();
|
||||
@@ -226,7 +226,7 @@ class AjaxController extends BaseController
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->app->getIdentity()->authorise('core.manage', 'com_mokojoombackup')) {
|
||||
if (!$this->app->getIdentity()->authorise('core.manage', 'com_mokosuitebackup')) {
|
||||
$this->sendJson(['error' => true, 'message' => 'Access denied']);
|
||||
|
||||
return;
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Controller;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+14
-14
@@ -1,21 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Controller;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\AdminController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Engine\BackupEngine;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Engine\RestoreEngine;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Engine\BackupEngine;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Engine\RestoreEngine;
|
||||
|
||||
class BackupsController extends AdminController
|
||||
{
|
||||
@@ -47,7 +47,7 @@ class BackupsController extends AdminController
|
||||
$this->setMessage($result['message'], 'error');
|
||||
}
|
||||
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=backups', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=backups', false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ class BackupsController extends AdminController
|
||||
|
||||
if (!$item || !$item->id || !$item->filesexist || !is_file($item->absolute_path)) {
|
||||
$this->setMessage('COM_MOKOJOOMBACKUP_ERROR_FILE_NOT_FOUND', 'error');
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=backups', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=backups', false));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -109,7 +109,7 @@ class BackupsController extends AdminController
|
||||
|
||||
if (!$id) {
|
||||
$this->setMessage('COM_MOKOJOOMBACKUP_ERROR_NO_RECORD_SELECTED', 'error');
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=backups', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=backups', false));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ class BackupsController extends AdminController
|
||||
$this->setMessage($result['message'], 'error');
|
||||
}
|
||||
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=backups', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=backups', false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,7 +138,7 @@ class BackupsController extends AdminController
|
||||
|
||||
if (!$id) {
|
||||
$this->setMessage('COM_MOKOJOOMBACKUP_ERROR_NO_RECORD_SELECTED', 'error');
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=backups', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=backups', false));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -148,21 +148,21 @@ class BackupsController extends AdminController
|
||||
|
||||
if (!$item || !$item->id) {
|
||||
$this->setMessage('COM_MOKOJOOMBACKUP_ERROR_NO_RECORD_SELECTED', 'error');
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=backups', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=backups', false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_file($item->absolute_path)) {
|
||||
$this->setMessage('COM_MOKOJOOMBACKUP_ERROR_FILE_NOT_FOUND', 'error');
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=backups', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=backups', false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($item->checksum)) {
|
||||
$this->setMessage('COM_MOKOJOOMBACKUP_VERIFY_NO_CHECKSUM', 'warning');
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=backups', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=backups', false));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -175,6 +175,6 @@ class BackupsController extends AdminController
|
||||
$this->setMessage('COM_MOKOJOOMBACKUP_VERIFY_FAILED', 'error');
|
||||
}
|
||||
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=backups', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=backups', false));
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Controller;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Controller;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+6
-6
@@ -1,21 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Controller;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Controller\AdminController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Engine\AkeebaImporter;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Engine\AkeebaImporter;
|
||||
|
||||
class ProfilesController extends AdminController
|
||||
{
|
||||
@@ -40,7 +40,7 @@ class ProfilesController extends AdminController
|
||||
|
||||
if (!$detection['profiles']) {
|
||||
$this->setMessage('COM_MOKOJOOMBACKUP_AKEEBA_NOT_FOUND', 'error');
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=profiles', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=profiles', false));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -55,7 +55,7 @@ class ProfilesController extends AdminController
|
||||
$this->setMessage($result['message'], 'error');
|
||||
}
|
||||
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokojoombackup&view=profiles', false));
|
||||
$this->setRedirect(Route::_('index.php?option=com_mokosuitebackup&view=profiles', false));
|
||||
}
|
||||
|
||||
/**
|
||||
+12
-12
@@ -1,16 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*
|
||||
* Imports Akeeba Backup Pro profiles and backup history into MokoJoomBackup.
|
||||
* Imports Akeeba Backup Pro profiles and backup history into MokoSuiteBackup.
|
||||
*
|
||||
* Reads from #__ak_profiles and #__ak_stats, maps Akeeba's configuration
|
||||
* format to MokoJoomBackup's individual column format.
|
||||
* format to MokoSuiteBackup's individual column format.
|
||||
*
|
||||
* Akeeba config format:
|
||||
* INI-style with dot-notation keys, e.g.:
|
||||
@@ -25,12 +25,12 @@
|
||||
* "databases": {"include": {...}, "exclude": {...}}}
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory;
|
||||
|
||||
class AkeebaImporter
|
||||
{
|
||||
@@ -90,7 +90,7 @@ class AkeebaImporter
|
||||
}
|
||||
|
||||
/**
|
||||
* Import all Akeeba profiles into MokoJoomBackup.
|
||||
* Import all Akeeba profiles into MokoSuiteBackup.
|
||||
*
|
||||
* @param bool $importHistory Also import backup history from #__ak_stats
|
||||
*
|
||||
@@ -120,7 +120,7 @@ class AkeebaImporter
|
||||
$akProfiles = $db->loadObjectList();
|
||||
|
||||
$profilesImported = 0;
|
||||
$profileIdMap = []; // akeeba_id => mokojoombackup_id
|
||||
$profileIdMap = []; // akeeba_id => mokosuitebackup_id
|
||||
|
||||
foreach ($akProfiles as $akProfile) {
|
||||
$config = $this->parseAkeebaConfig($akProfile->configuration ?? '');
|
||||
@@ -128,11 +128,11 @@ class AkeebaImporter
|
||||
|
||||
$mokoProfile = $this->mapToMokoProfile($akProfile, $config, $filters);
|
||||
|
||||
$db->insertObject('#__mokojoombackup_profiles', $mokoProfile, 'id');
|
||||
$db->insertObject('#__mokosuitebackup_profiles', $mokoProfile, 'id');
|
||||
$profileIdMap[$akProfile->id] = $mokoProfile->id;
|
||||
$profilesImported++;
|
||||
|
||||
$this->log('Imported profile: "' . $akProfile->description . '" (Akeeba #' . $akProfile->id . ' → MokoJoomBackup #' . $mokoProfile->id . ')');
|
||||
$this->log('Imported profile: "' . $akProfile->description . '" (Akeeba #' . $akProfile->id . ' → MokoSuiteBackup #' . $mokoProfile->id . ')');
|
||||
}
|
||||
|
||||
// Import backup history
|
||||
@@ -201,7 +201,7 @@ class AkeebaImporter
|
||||
'log' => 'Imported from Akeeba Backup record #' . $stat->id,
|
||||
];
|
||||
|
||||
$db->insertObject('#__mokojoombackup_records', $record, 'id');
|
||||
$db->insertObject('#__mokosuitebackup_records', $record, 'id');
|
||||
$imported++;
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ class AkeebaImporter
|
||||
}
|
||||
|
||||
/**
|
||||
* Map an Akeeba profile to a MokoJoomBackup profile object.
|
||||
* Map an Akeeba profile to a MokoSuiteBackup profile object.
|
||||
*/
|
||||
private function mapToMokoProfile(object $akProfile, array $config, array $filters): object
|
||||
{
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+14
-14
@@ -1,19 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Event\Event;
|
||||
|
||||
class BackupEngine
|
||||
@@ -47,7 +47,7 @@ class BackupEngine
|
||||
// Load profile
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__mokojoombackup_profiles'))
|
||||
->from($db->quoteName('#__mokosuitebackup_profiles'))
|
||||
->where($db->quoteName('id') . ' = ' . $profileId);
|
||||
$db->setQuery($query);
|
||||
$profile = $db->loadObject();
|
||||
@@ -105,7 +105,7 @@ class BackupEngine
|
||||
'log' => '',
|
||||
];
|
||||
|
||||
$db->insertObject('#__mokojoombackup_records', $record, 'id');
|
||||
$db->insertObject('#__mokosuitebackup_records', $record, 'id');
|
||||
$recordId = $record->id;
|
||||
|
||||
try {
|
||||
@@ -249,7 +249,7 @@ class BackupEngine
|
||||
$logContent = implode("\n", $this->log);
|
||||
$logPath = preg_replace('/\.(zip|tar\.gz)$/i', '.log', $archivePath);
|
||||
if (@file_put_contents($logPath, $logContent) === false) {
|
||||
error_log('MokoJoomBackup: Could not write log file: ' . $logPath);
|
||||
error_log('MokoSuiteBackup: Could not write log file: ' . $logPath);
|
||||
}
|
||||
|
||||
// Final record update
|
||||
@@ -268,7 +268,7 @@ class BackupEngine
|
||||
'log' => $logContent,
|
||||
];
|
||||
|
||||
$db->updateObject('#__mokojoombackup_records', $update, 'id');
|
||||
$db->updateObject('#__mokosuitebackup_records', $update, 'id');
|
||||
|
||||
// Send success notification
|
||||
NotificationSender::send($profile, $update, true, implode("\n", $this->log));
|
||||
@@ -296,7 +296,7 @@ class BackupEngine
|
||||
'log' => implode("\n", $this->log),
|
||||
];
|
||||
|
||||
$db->updateObject('#__mokojoombackup_records', $update, 'id');
|
||||
$db->updateObject('#__mokosuitebackup_records', $update, 'id');
|
||||
|
||||
// Send failure notification
|
||||
NotificationSender::send($profile, $update, false, implode("\n", $this->log));
|
||||
@@ -416,7 +416,7 @@ class BackupEngine
|
||||
{
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('manifest'))
|
||||
->from($db->quoteName('#__mokojoombackup_records'))
|
||||
->from($db->quoteName('#__mokosuitebackup_records'))
|
||||
->where($db->quoteName('profile_id') . ' = ' . $profileId)
|
||||
->where($db->quoteName('status') . ' = ' . $db->quote('complete'))
|
||||
->where($db->quoteName('manifest') . ' != ' . $db->quote(''))
|
||||
@@ -472,14 +472,14 @@ class BackupEngine
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the onMokoJoomBackupAfterRun event so plugins (actionlog, etc.) can react.
|
||||
* Dispatch the onMokoSuiteBackupAfterRun event so plugins (actionlog, etc.) can react.
|
||||
*/
|
||||
private function dispatchAfterRun(bool $success, int $recordId, string $description, int $profileId, string $origin): void
|
||||
{
|
||||
try {
|
||||
$app = Factory::getApplication();
|
||||
|
||||
$event = new Event('onMokoJoomBackupAfterRun', [
|
||||
$event = new Event('onMokoSuiteBackupAfterRun', [
|
||||
'success' => $success,
|
||||
'record_id' => $recordId,
|
||||
'description' => $description,
|
||||
@@ -487,10 +487,10 @@ class BackupEngine
|
||||
'origin' => $origin,
|
||||
]);
|
||||
|
||||
$app->getDispatcher()->dispatch('onMokoJoomBackupAfterRun', $event);
|
||||
$app->getDispatcher()->dispatch('onMokoSuiteBackupAfterRun', $event);
|
||||
} catch (\Throwable $e) {
|
||||
// Never let a listener failure break the backup result, but log it
|
||||
error_log('MokoJoomBackup: onAfterRun listener error: ' . $e->getMessage());
|
||||
error_log('MokoSuiteBackup: onAfterRun listener error: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -56,7 +56,7 @@ class DatabaseDumper
|
||||
$prefix = $db->getPrefix();
|
||||
$output = [];
|
||||
|
||||
$output[] = '-- MokoJoomBackup Database Dump';
|
||||
$output[] = '-- MokoSuiteBackup Database Dump';
|
||||
$output[] = '-- Generated: ' . date('Y-m-d H:i:s');
|
||||
$output[] = '-- Server: ' . $db->getServerType();
|
||||
$output[] = '-- Database: ' . $db->getName();
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -12,7 +12,7 @@
|
||||
* and DROP TABLE before CREATE TABLE for clean restores.
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -101,7 +101,7 @@ class DatabaseImporter
|
||||
// Log but don't abort — some statements may fail on
|
||||
// different MySQL versions (e.g. charset differences)
|
||||
// but the overall restore should continue.
|
||||
error_log('MokoJoomBackup SQL import warning: ' . $e->getMessage());
|
||||
error_log('MokoSuiteBackup SQL import warning: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ class DatabaseImporter
|
||||
$db->execute();
|
||||
$statementsExecuted++;
|
||||
} catch (\Exception $e) {
|
||||
error_log('MokoJoomBackup SQL import warning (final): ' . $e->getMessage());
|
||||
error_log('MokoSuiteBackup SQL import warning (final): ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -15,7 +15,7 @@
|
||||
* {"path/to/file": {"size": 1234, "mtime": 1717350000}, ...}
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -11,7 +11,7 @@
|
||||
* Skips database.sql and sensitive files that should not be overwritten.
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -12,7 +12,7 @@
|
||||
* No SDK dependency — pure PHP with cURL.
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -19,7 +19,7 @@
|
||||
* The RestoreEngine can then restore from the extracted files.
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -21,7 +21,7 @@
|
||||
* with a Joomla-styled wizard interface.
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -89,7 +89,7 @@ class MokoRestore
|
||||
*
|
||||
* DELETE THIS FILE AFTER INSTALLATION IS COMPLETE.
|
||||
*
|
||||
* @package MokoJoomBackup
|
||||
* @package MokoSuiteBackup
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GPL-3.0-or-later
|
||||
*/
|
||||
@@ -763,7 +763,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica N
|
||||
<body>
|
||||
<div class="mr-header">
|
||||
<h1>MokoRestore</h1>
|
||||
<p>Standalone Site Installer — MokoJoomBackup</p>
|
||||
<p>Standalone Site Installer — MokoSuiteBackup</p>
|
||||
</div>
|
||||
|
||||
<div class="mr-container">
|
||||
@@ -927,7 +927,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica N
|
||||
|
||||
<div class="mr-footer">
|
||||
MokoRestore — <a href="https://mokoconsulting.tech" target="_blank">Moko Consulting</a>
|
||||
— Part of MokoJoomBackup
|
||||
— Part of MokoSuiteBackup
|
||||
</div>
|
||||
|
||||
<script>
|
||||
+8
-8
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -11,7 +11,7 @@
|
||||
* Uses Joomla's built-in mail system (Factory::getMailer()).
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -73,7 +73,7 @@ class NotificationSender
|
||||
|
||||
// Build subject
|
||||
$statusLabel = $success ? 'SUCCESS' : 'FAILED';
|
||||
$mailer->setSubject("[MokoJoomBackup] {$statusLabel}: {$record->description} — {$siteName}");
|
||||
$mailer->setSubject("[MokoSuiteBackup] {$statusLabel}: {$record->description} — {$siteName}");
|
||||
|
||||
// Build body
|
||||
$duration = '';
|
||||
@@ -92,7 +92,7 @@ class NotificationSender
|
||||
? number_format($record->total_size / 1048576, 2) . ' MB'
|
||||
: 'N/A';
|
||||
|
||||
$body = "MokoJoomBackup Notification\n"
|
||||
$body = "MokoSuiteBackup Notification\n"
|
||||
. "============================\n\n"
|
||||
. "Site: {$siteName}\n"
|
||||
. "URL: {$siteUrl}\n"
|
||||
@@ -125,7 +125,7 @@ class NotificationSender
|
||||
}
|
||||
|
||||
$body .= "\n--\n"
|
||||
. "MokoJoomBackup — https://mokoconsulting.tech\n";
|
||||
. "MokoSuiteBackup — https://mokoconsulting.tech\n";
|
||||
|
||||
$mailer->setBody($body);
|
||||
$mailer->isHtml(false);
|
||||
@@ -133,7 +133,7 @@ class NotificationSender
|
||||
return $mailer->Send();
|
||||
} catch (\Throwable $e) {
|
||||
// Don't let notification failure break the backup flow
|
||||
error_log('MokoJoomBackup notification error: ' . $e->getMessage());
|
||||
error_log('MokoSuiteBackup notification error: ' . $e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ class NotificationSender
|
||||
|
||||
return $db->loadColumn() ?: [];
|
||||
} catch (\Throwable $e) {
|
||||
error_log('MokoJoomBackup: Could not resolve user group emails: ' . $e->getMessage());
|
||||
error_log('MokoSuiteBackup: Could not resolve user group emails: ' . $e->getMessage());
|
||||
|
||||
return [];
|
||||
}
|
||||
+6
-4
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -11,12 +11,12 @@
|
||||
* directory paths and archive filename formats.
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory;
|
||||
|
||||
class PlaceholderResolver
|
||||
{
|
||||
@@ -40,6 +40,7 @@ class PlaceholderResolver
|
||||
'[type]' => 'Backup type (full, database, files, differential)',
|
||||
'[random]' => 'Random 6-character hex string',
|
||||
'[DEFAULT_DIR]' => 'Default backup directory',
|
||||
'[HOME]' => 'Home directory of the PHP process owner',
|
||||
];
|
||||
|
||||
private array $replacements;
|
||||
@@ -77,6 +78,7 @@ class PlaceholderResolver
|
||||
'[type]' => $profile->backup_type ?? 'full',
|
||||
'[random]' => bin2hex(random_bytes(3)),
|
||||
'[DEFAULT_DIR]' => BackupDirectory::getDefaultAbsolute(),
|
||||
'[HOME]' => BackupDirectory::getHomeDirectory(),
|
||||
];
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -18,7 +18,7 @@
|
||||
* 6. Clean up staging directory
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -57,7 +57,7 @@ class RestoreEngine
|
||||
// Load backup record
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__mokojoombackup_records'))
|
||||
->from($db->quoteName('#__mokosuitebackup_records'))
|
||||
->where($db->quoteName('id') . ' = ' . $recordId);
|
||||
$db->setQuery($query);
|
||||
$record = $db->loadObject();
|
||||
@@ -77,7 +77,7 @@ class RestoreEngine
|
||||
}
|
||||
|
||||
// Create staging directory
|
||||
$this->stagingDir = JPATH_ROOT . '/tmp/mokojoombackup-restore-' . $record->tag;
|
||||
$this->stagingDir = JPATH_ROOT . '/tmp/mokosuitebackup-restore-' . $record->tag;
|
||||
|
||||
if (is_dir($this->stagingDir)) {
|
||||
$this->recursiveDelete($this->stagingDir);
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -12,7 +12,7 @@
|
||||
* No SDK dependency — pure PHP with cURL.
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+14
-14
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -16,12 +16,12 @@
|
||||
* where ini_set() and set_time_limit() are disabled.
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory;
|
||||
|
||||
class SteppedBackupEngine
|
||||
{
|
||||
@@ -37,7 +37,7 @@ class SteppedBackupEngine
|
||||
// Load profile
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__mokojoombackup_profiles'))
|
||||
->from($db->quoteName('#__mokosuitebackup_profiles'))
|
||||
->where($db->quoteName('id') . ' = ' . $profileId);
|
||||
$db->setQuery($query);
|
||||
$profile = $db->loadObject();
|
||||
@@ -100,7 +100,7 @@ class SteppedBackupEngine
|
||||
'log' => '',
|
||||
];
|
||||
|
||||
$db->insertObject('#__mokojoombackup_records', $record, 'id');
|
||||
$db->insertObject('#__mokosuitebackup_records', $record, 'id');
|
||||
$session->recordId = $record->id;
|
||||
|
||||
// Determine what work needs to be done and estimate steps
|
||||
@@ -228,7 +228,7 @@ class SteppedBackupEngine
|
||||
$flags = $session->tableIndex === 0 ? 0 : FILE_APPEND;
|
||||
|
||||
if ($session->tableIndex === 0) {
|
||||
$header = "-- MokoJoomBackup Database Dump\n"
|
||||
$header = "-- MokoSuiteBackup Database Dump\n"
|
||||
. "-- Generated: " . date('Y-m-d H:i:s') . "\n"
|
||||
. "-- Prefix: " . $db->getPrefix() . "\n\n"
|
||||
. "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";\n"
|
||||
@@ -315,7 +315,7 @@ class SteppedBackupEngine
|
||||
|
||||
// Clean up temp SQL file
|
||||
if (is_file($sqlFile) && !@unlink($sqlFile)) {
|
||||
error_log('MokoJoomBackup: Could not delete temp SQL file: ' . $sqlFile);
|
||||
error_log('MokoSuiteBackup: Could not delete temp SQL file: ' . $sqlFile);
|
||||
}
|
||||
|
||||
$totalSize = file_exists($session->archivePath) ? filesize($session->archivePath) : 0;
|
||||
@@ -344,7 +344,7 @@ class SteppedBackupEngine
|
||||
'filesexist' => 1,
|
||||
];
|
||||
|
||||
$db->updateObject('#__mokojoombackup_records', $update, 'id');
|
||||
$db->updateObject('#__mokosuitebackup_records', $update, 'id');
|
||||
|
||||
$session->currentStep++;
|
||||
$session->phase = ($session->remoteStorage !== 'none') ? 'upload' : 'complete';
|
||||
@@ -366,7 +366,7 @@ class SteppedBackupEngine
|
||||
// Reload profile for remote settings
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__mokojoombackup_profiles'))
|
||||
->from($db->quoteName('#__mokosuitebackup_profiles'))
|
||||
->where($db->quoteName('id') . ' = ' . $session->profileId);
|
||||
$db->setQuery($query);
|
||||
$profile = $db->loadObject();
|
||||
@@ -402,7 +402,7 @@ class SteppedBackupEngine
|
||||
'filesexist' => is_file($session->archivePath) ? 1 : 0,
|
||||
];
|
||||
|
||||
$db->updateObject('#__mokojoombackup_records', $update, 'id');
|
||||
$db->updateObject('#__mokosuitebackup_records', $update, 'id');
|
||||
|
||||
$session->currentStep++;
|
||||
$session->phase = 'complete';
|
||||
@@ -421,7 +421,7 @@ class SteppedBackupEngine
|
||||
// Write log file alongside the archive
|
||||
$logPath = BackupDirectory::logPathFromArchive($session->archivePath);
|
||||
if (@file_put_contents($logPath, $logContent) === false) {
|
||||
error_log('MokoJoomBackup: Could not write log file: ' . $logPath);
|
||||
error_log('MokoSuiteBackup: Could not write log file: ' . $logPath);
|
||||
}
|
||||
|
||||
$update = (object) [
|
||||
@@ -431,7 +431,7 @@ class SteppedBackupEngine
|
||||
'log' => $logContent,
|
||||
];
|
||||
|
||||
$db->updateObject('#__mokojoombackup_records', $update, 'id');
|
||||
$db->updateObject('#__mokosuitebackup_records', $update, 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -447,7 +447,7 @@ class SteppedBackupEngine
|
||||
'log' => implode("\n", $session->log),
|
||||
];
|
||||
|
||||
$db->updateObject('#__mokojoombackup_records', $update, 'id');
|
||||
$db->updateObject('#__mokosuitebackup_records', $update, 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -17,7 +17,7 @@
|
||||
* Phases: init → database → files → finalize → upload → complete
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -63,7 +63,7 @@ class SteppedSession
|
||||
|
||||
private static function getSessionDir(): string
|
||||
{
|
||||
$dir = JPATH_ROOT . '/tmp/mokojoombackup-sessions';
|
||||
$dir = JPATH_ROOT . '/tmp/mokosuitebackup-sessions';
|
||||
|
||||
if (!is_dir($dir)) {
|
||||
if (!mkdir($dir, 0755, true)) {
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Engine;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Engine;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @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\Extension;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Extension\MVCComponent;
|
||||
use Joomla\CMS\Factory;
|
||||
|
||||
class MokoSuiteBackupComponent extends MVCComponent
|
||||
{
|
||||
public function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
try {
|
||||
$app = Factory::getApplication();
|
||||
|
||||
if (!$app->isClient('administrator')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wa = $app->getDocument()->getWebAssetManager();
|
||||
$wa->addInlineStyle(
|
||||
'#menu a[href*="com_mokosuitebackup"][href*="view=dashboard"] .sidebar-item-title::before,'
|
||||
. ' #menu a[href*="com_mokosuitebackup"][href*="view=backups"] .sidebar-item-title::before,'
|
||||
. ' #menu a[href*="com_mokosuitebackup"][href*="view=profiles"] .sidebar-item-title::before'
|
||||
. ' { font-family: "Font Awesome 6 Free"; font-weight: 900; margin-right: .5em; }'
|
||||
. ' #menu a[href*="com_mokosuitebackup"][href*="view=dashboard"] .sidebar-item-title::before { content: "\f015"; }'
|
||||
. ' #menu a[href*="com_mokosuitebackup"][href*="view=backups"] .sidebar-item-title::before { content: "\f1c0"; }'
|
||||
. ' #menu a[href*="com_mokosuitebackup"][href*="view=profiles"] .sidebar-item-title::before { content: "\f013"; }'
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
error_log('MokoSuiteBackup: boot() CSS injection failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Field;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Field;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
@@ -11,7 +11,7 @@
|
||||
* Loads the directory tree from the server via AJAX (browseDir endpoint).
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Field;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Field;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -163,7 +163,7 @@ class DirectoryFilterField extends FormField
|
||||
const tokenName = Joomla.getOptions('csrf.token') || '';
|
||||
if (tokenName) form.append(tokenName, '1');
|
||||
|
||||
fetch('index.php?option=com_mokojoombackup&format=json', {
|
||||
fetch('index.php?option=com_mokosuitebackup&format=json', {
|
||||
method: 'POST', body: form,
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
||||
})
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Field;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Field;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
+9
-8
@@ -1,21 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Field;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Field;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\FormField;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory;
|
||||
|
||||
class FolderPickerField extends FormField
|
||||
{
|
||||
@@ -51,6 +51,7 @@ class FolderPickerField extends FormField
|
||||
|
||||
$placeholders = [
|
||||
'[DEFAULT_DIR]' => BackupDirectory::getDefaultAbsolute(),
|
||||
'[HOME]' => BackupDirectory::getHomeDirectory(),
|
||||
'[host]' => $hostname,
|
||||
'[site_name]' => $sanitizedSiteName ?: 'joomla',
|
||||
'[profile_id]' => '1',
|
||||
@@ -90,7 +91,7 @@ class FolderPickerField extends FormField
|
||||
<div class="input-group">
|
||||
<input type="text" name="{$name}" id="{$id}" value="{$value}"
|
||||
class="form-control" maxlength="512"
|
||||
placeholder="[DEFAULT_DIR] or /home/user/backups/[host]" />
|
||||
placeholder="[HOME]/backups or [DEFAULT_DIR]" />
|
||||
<button type="button" class="btn btn-outline-secondary" id="{$id}_btn">
|
||||
<span class="icon-folder-open" aria-hidden="true"></span>
|
||||
Browse
|
||||
@@ -162,7 +163,7 @@ class FolderPickerField extends FormField
|
||||
function setDefaultDirWarning() {
|
||||
var warn = document.getElementById(fieldId + '_defaultwarn');
|
||||
var val = input.value.trim();
|
||||
var isDefault = (!val || val === '[DEFAULT_DIR]' || val === 'administrator/components/com_mokojoombackup/backups');
|
||||
var isDefault = (!val || val === '[DEFAULT_DIR]' || val === 'administrator/components/com_mokosuitebackup/backups' || val === 'administrator/components/com_mokojoombackup/backups');
|
||||
if (warn) warn.style.display = isDefault ? 'block' : 'none';
|
||||
}
|
||||
|
||||
@@ -179,7 +180,7 @@ class FolderPickerField extends FormField
|
||||
var tokenName = Joomla.getOptions('csrf.token') || '';
|
||||
if (tokenName) form.append(tokenName, '1');
|
||||
|
||||
fetch('index.php?option=com_mokojoombackup&format=json', {
|
||||
fetch('index.php?option=com_mokosuitebackup&format=json', {
|
||||
method: 'POST',
|
||||
body: form,
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
||||
@@ -237,7 +238,7 @@ class FolderPickerField extends FormField
|
||||
var tokenName = Joomla.getOptions('csrf.token') || '';
|
||||
if (tokenName) form.append(tokenName, '1');
|
||||
|
||||
fetch('index.php?option=com_mokojoombackup&format=json', {
|
||||
fetch('index.php?option=com_mokosuitebackup&format=json', {
|
||||
method: 'POST',
|
||||
body: form,
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
||||
+5
-5
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Model;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Model;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -20,7 +20,7 @@ class BackupModel extends AdminModel
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
$form = $this->loadForm(
|
||||
'com_mokojoombackup.backup',
|
||||
'com_mokosuitebackup.backup',
|
||||
'backup',
|
||||
['control' => 'jform', 'load_data' => $loadData]
|
||||
);
|
||||
@@ -30,7 +30,7 @@ class BackupModel extends AdminModel
|
||||
|
||||
protected function loadFormData(): object
|
||||
{
|
||||
$data = Factory::getApplication()->getUserState('com_mokojoombackup.edit.backup.data', []);
|
||||
$data = Factory::getApplication()->getUserState('com_mokosuitebackup.edit.backup.data', []);
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->getItem();
|
||||
+5
-5
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Model;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Model;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -41,11 +41,11 @@ class BackupsModel extends ListModel
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select('a.*')
|
||||
->from($db->quoteName('#__mokojoombackup_records', 'a'));
|
||||
->from($db->quoteName('#__mokosuitebackup_records', 'a'));
|
||||
|
||||
// Join profile title
|
||||
$query->select($db->quoteName('p.title', 'profile_title'))
|
||||
->join('LEFT', $db->quoteName('#__mokojoombackup_profiles', 'p') . ' ON p.id = a.profile_id');
|
||||
->join('LEFT', $db->quoteName('#__mokosuitebackup_profiles', 'p') . ' ON p.id = a.profile_id');
|
||||
|
||||
// Filter by status
|
||||
$status = $this->getState('filter.status');
|
||||
+13
-13
@@ -1,20 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Model;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Model;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory;
|
||||
|
||||
class DashboardModel extends BaseDatabaseModel
|
||||
{
|
||||
@@ -28,8 +28,8 @@ class DashboardModel extends BaseDatabaseModel
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select('r.*, p.title AS profile_title')
|
||||
->from($db->quoteName('#__mokojoombackup_records', 'r'))
|
||||
->join('LEFT', $db->quoteName('#__mokojoombackup_profiles', 'p') . ' ON p.id = r.profile_id')
|
||||
->from($db->quoteName('#__mokosuitebackup_records', 'r'))
|
||||
->join('LEFT', $db->quoteName('#__mokosuitebackup_profiles', 'p') . ' ON p.id = r.profile_id')
|
||||
->where($db->quoteName('r.status') . ' = ' . $db->quote('complete'))
|
||||
->order($db->quoteName('r.backupend') . ' DESC');
|
||||
$db->setQuery($query, 0, 1);
|
||||
@@ -38,7 +38,7 @@ class DashboardModel extends BaseDatabaseModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Query com_scheduler for the next scheduled MokoJoomBackup task.
|
||||
* Query com_scheduler for the next scheduled MokoSuiteBackup task.
|
||||
*
|
||||
* @return object|null Object with next_execution and title, or null
|
||||
*/
|
||||
@@ -50,7 +50,7 @@ class DashboardModel extends BaseDatabaseModel
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(['t.next_execution', 't.title']))
|
||||
->from($db->quoteName('#__scheduler_tasks', 't'))
|
||||
->where($db->quoteName('t.type') . ' = ' . $db->quote('mokojoombackup.run_profile'))
|
||||
->where($db->quoteName('t.type') . ' = ' . $db->quote('mokosuitebackup.run_profile'))
|
||||
->where($db->quoteName('t.state') . ' = 1')
|
||||
->order($db->quoteName('t.next_execution') . ' ASC');
|
||||
$db->setQuery($query, 0, 1);
|
||||
@@ -74,7 +74,7 @@ class DashboardModel extends BaseDatabaseModel
|
||||
$query = $db->getQuery(true)
|
||||
->select('COUNT(*) AS total_count')
|
||||
->select('COALESCE(SUM(' . $db->quoteName('total_size') . '), 0) AS total_size')
|
||||
->from($db->quoteName('#__mokojoombackup_records'))
|
||||
->from($db->quoteName('#__mokosuitebackup_records'))
|
||||
->where($db->quoteName('status') . ' = ' . $db->quote('complete'));
|
||||
$db->setQuery($query);
|
||||
$stats = $db->loadObject();
|
||||
@@ -83,7 +83,7 @@ class DashboardModel extends BaseDatabaseModel
|
||||
$cutoff = date('Y-m-d H:i:s', strtotime('-7 days'));
|
||||
$query = $db->getQuery(true)
|
||||
->select('COUNT(*) AS fail_count')
|
||||
->from($db->quoteName('#__mokojoombackup_records'))
|
||||
->from($db->quoteName('#__mokosuitebackup_records'))
|
||||
->where($db->quoteName('status') . ' = ' . $db->quote('fail'))
|
||||
->where($db->quoteName('backupstart') . ' >= ' . $db->quote($cutoff));
|
||||
$db->setQuery($query);
|
||||
@@ -129,7 +129,7 @@ class DashboardModel extends BaseDatabaseModel
|
||||
$db2 = $this->getDatabase();
|
||||
$qDir = $db2->getQuery(true)
|
||||
->select($db2->quoteName('backup_dir'))
|
||||
->from($db2->quoteName('#__mokojoombackup_profiles'))
|
||||
->from($db2->quoteName('#__mokosuitebackup_profiles'))
|
||||
->where($db2->quoteName('published') . ' = 1')
|
||||
->where($db2->quoteName('backup_dir') . ' != ' . $db2->quote(''))
|
||||
->where($db2->quoteName('backup_dir') . ' IS NOT NULL');
|
||||
@@ -177,7 +177,7 @@ class DashboardModel extends BaseDatabaseModel
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select('COUNT(*)')
|
||||
->from($db->quoteName('#__mokojoombackup_profiles'))
|
||||
->from($db->quoteName('#__mokosuitebackup_profiles'))
|
||||
->where($db->quoteName('published') . ' = 1')
|
||||
->where('(' . $db->quoteName('backup_dir') . ' = ' . $db->quote(BackupDirectory::DEFAULT_RELATIVE)
|
||||
. ' OR ' . $db->quoteName('backup_dir') . ' = ' . $db->quote(BackupDirectory::PLACEHOLDER)
|
||||
@@ -198,7 +198,7 @@ class DashboardModel extends BaseDatabaseModel
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(['id', 'title', 'backup_type']))
|
||||
->from($db->quoteName('#__mokojoombackup_profiles'))
|
||||
->from($db->quoteName('#__mokosuitebackup_profiles'))
|
||||
->where($db->quoteName('published') . ' = 1')
|
||||
->order($db->quoteName('ordering') . ' ASC');
|
||||
$db->setQuery($query);
|
||||
+5
-5
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Model;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Model;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -20,7 +20,7 @@ class ProfileModel extends AdminModel
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
$form = $this->loadForm(
|
||||
'com_mokojoombackup.profile',
|
||||
'com_mokosuitebackup.profile',
|
||||
'profile',
|
||||
['control' => 'jform', 'load_data' => $loadData]
|
||||
);
|
||||
@@ -30,7 +30,7 @@ class ProfileModel extends AdminModel
|
||||
|
||||
protected function loadFormData(): object
|
||||
{
|
||||
$data = Factory::getApplication()->getUserState('com_mokojoombackup.edit.profile.data', []);
|
||||
$data = Factory::getApplication()->getUserState('com_mokosuitebackup.edit.profile.data', []);
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->getItem();
|
||||
+4
-4
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Model;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Model;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -38,7 +38,7 @@ class ProfilesModel extends ListModel
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select('a.*')
|
||||
->from($db->quoteName('#__mokojoombackup_profiles', 'a'));
|
||||
->from($db->quoteName('#__mokosuitebackup_profiles', 'a'));
|
||||
|
||||
$published = $this->getState('filter.published');
|
||||
|
||||
+4
-4
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Table;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Table;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -19,7 +19,7 @@ class BackupTable extends Table
|
||||
{
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
parent::__construct('#__mokojoombackup_records', 'id', $db);
|
||||
parent::__construct('#__mokosuitebackup_records', 'id', $db);
|
||||
}
|
||||
|
||||
public function check(): bool
|
||||
+5
-5
@@ -1,26 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Table;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Table;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Table\Table;
|
||||
use Joomla\Component\MokoJoomBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory;
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
|
||||
class ProfileTable extends Table
|
||||
{
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
parent::__construct('#__mokojoombackup_profiles', 'id', $db);
|
||||
parent::__construct('#__mokosuitebackup_profiles', 'id', $db);
|
||||
}
|
||||
|
||||
public function store($updateNulls = true): bool
|
||||
+59
-9
@@ -1,20 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\Utility;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\Utility;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
class BackupDirectory
|
||||
{
|
||||
public const DEFAULT_RELATIVE = 'administrator/components/com_mokojoombackup/backups';
|
||||
public const DEFAULT_RELATIVE = 'administrator/components/com_mokosuitebackup/backups';
|
||||
|
||||
public const PLACEHOLDER = '[DEFAULT_DIR]';
|
||||
|
||||
@@ -32,17 +32,58 @@ HTACCESS;
|
||||
|
||||
private const INDEX_CONTENT = '<!DOCTYPE html><title></title>';
|
||||
|
||||
public const HOME_PLACEHOLDER = '[HOME]';
|
||||
|
||||
/**
|
||||
* Get the absolute default backup directory path.
|
||||
*/
|
||||
public static function getDefaultAbsolute(): string
|
||||
{
|
||||
return JPATH_ADMINISTRATOR . '/components/com_mokojoombackup/backups';
|
||||
return JPATH_ADMINISTRATOR . '/components/com_mokosuitebackup/backups';
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a backup directory path. Replaces [DEFAULT_DIR] placeholder,
|
||||
* then resolves relative paths from JPATH_ROOT.
|
||||
* Detect the home directory of the PHP process owner.
|
||||
*
|
||||
* Tries multiple sources because PHP-FPM on shared hosting
|
||||
* often strips shell environment variables.
|
||||
*
|
||||
* @return string Absolute home path, or empty string if undetectable
|
||||
*/
|
||||
public static function getHomeDirectory(): string
|
||||
{
|
||||
// 1. Environment variables (works in CLI and some FPM configs)
|
||||
$home = getenv('HOME') ?: ($_SERVER['HOME'] ?? '');
|
||||
|
||||
if ($home === '') {
|
||||
$home = getenv('USERPROFILE') ?: ($_SERVER['USERPROFILE'] ?? '');
|
||||
}
|
||||
|
||||
// 2. POSIX: read from /etc/passwd (most reliable on Linux)
|
||||
if ($home === '' && \function_exists('posix_getpwuid') && \function_exists('posix_geteuid')) {
|
||||
$info = posix_getpwuid(posix_geteuid());
|
||||
|
||||
if ($info && !empty($info['dir'])) {
|
||||
$home = $info['dir'];
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Derive from JPATH_ROOT — walk up until we find a home-like path
|
||||
if ($home === '' && \defined('JPATH_ROOT')) {
|
||||
$parts = explode('/', rtrim(JPATH_ROOT, '/'));
|
||||
|
||||
// Typical pattern: /home/{user}/domain/public_html
|
||||
if (count($parts) >= 3 && $parts[1] === 'home') {
|
||||
$home = '/' . $parts[1] . '/' . $parts[2];
|
||||
}
|
||||
}
|
||||
|
||||
return rtrim($home, '/\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a backup directory path. Replaces [DEFAULT_DIR] and [HOME]
|
||||
* placeholders, then resolves relative paths from JPATH_ROOT.
|
||||
*
|
||||
* @param string $dir Raw directory value from profile
|
||||
*
|
||||
@@ -56,6 +97,15 @@ HTACCESS;
|
||||
$dir = str_replace(self::PLACEHOLDER, self::getDefaultAbsolute(), $dir);
|
||||
}
|
||||
|
||||
// Resolve [HOME] placeholder
|
||||
if (strpos($dir, self::HOME_PLACEHOLDER) !== false) {
|
||||
$home = self::getHomeDirectory();
|
||||
|
||||
if ($home !== '') {
|
||||
$dir = str_replace(self::HOME_PLACEHOLDER, $home, $dir);
|
||||
}
|
||||
}
|
||||
|
||||
if ($dir !== '' && ($dir[0] === '/' || preg_match('#^[A-Za-z]:[/\\\\]#', $dir))) {
|
||||
return rtrim($dir, '/\\');
|
||||
}
|
||||
@@ -96,7 +146,7 @@ HTACCESS;
|
||||
|
||||
if (!is_file($htaccess)) {
|
||||
if (@file_put_contents($htaccess, self::HTACCESS_CONTENT . "\n") === false) {
|
||||
error_log('MokoJoomBackup: Could not create .htaccess in: ' . $dir);
|
||||
error_log('MokoSuiteBackup: Could not create .htaccess in: ' . $dir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +154,7 @@ HTACCESS;
|
||||
|
||||
if (!is_file($index)) {
|
||||
if (@file_put_contents($index, self::INDEX_CONTENT) === false) {
|
||||
error_log('MokoJoomBackup: Could not create index.html in: ' . $dir);
|
||||
error_log('MokoSuiteBackup: Could not create index.html in: ' . $dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\View\Backup;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\View\Backup;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -34,6 +34,6 @@ class HtmlView extends BaseHtmlView
|
||||
protected function addToolbar(): void
|
||||
{
|
||||
ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_BACKUP_DETAIL'), 'database');
|
||||
ToolbarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mokojoombackup&view=backups');
|
||||
ToolbarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mokosuitebackup&view=backups');
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoJoomBackup
|
||||
* @subpackage com_mokojoombackup
|
||||
* @package MokoSuiteBackup
|
||||
* @subpackage com_mokosuitebackup
|
||||
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoJoomBackup\Administrator\View\Backups;
|
||||
namespace Joomla\Component\MokoSuiteBackup\Administrator\View\Backups;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
@@ -39,7 +39,7 @@ class HtmlView extends BaseHtmlView
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(['id', 'title', 'backup_type']))
|
||||
->from($db->quoteName('#__mokojoombackup_profiles'))
|
||||
->from($db->quoteName('#__mokosuitebackup_profiles'))
|
||||
->where($db->quoteName('published') . ' = 1')
|
||||
->order($db->quoteName('ordering') . ' ASC');
|
||||
$db->setQuery($query);
|
||||
@@ -60,7 +60,7 @@ class HtmlView extends BaseHtmlView
|
||||
try {
|
||||
$db = Factory::getDbo();
|
||||
|
||||
// Find the update site linked to pkg_mokojoombackup
|
||||
// Find the update site linked to pkg_mokosuitebackup
|
||||
$query = $db->getQuery(true)
|
||||
->select([
|
||||
$db->quoteName('us.update_site_id'),
|
||||
@@ -77,7 +77,7 @@ class HtmlView extends BaseHtmlView
|
||||
$db->quoteName('#__extensions', 'e')
|
||||
. ' ON ' . $db->quoteName('e.extension_id') . ' = ' . $db->quoteName('use.extension_id')
|
||||
)
|
||||
->where($db->quoteName('e.element') . ' = ' . $db->quote('pkg_mokojoombackup'))
|
||||
->where($db->quoteName('e.element') . ' = ' . $db->quote('pkg_mokosuitebackup'))
|
||||
->where($db->quoteName('e.type') . ' = ' . $db->quote('package'))
|
||||
->setLimit(1);
|
||||
|
||||
@@ -92,7 +92,7 @@ class HtmlView extends BaseHtmlView
|
||||
} elseif (empty($site->extra_query) || strpos($site->extra_query, 'dlid=') === false) {
|
||||
// Update site exists but no download key configured
|
||||
$editUrl = Route::_(
|
||||
'index.php?option=com_installer&view=updatesites&filter[search]=mokojoombackup'
|
||||
'index.php?option=com_installer&view=updatesites&filter[search]=mokosuitebackup'
|
||||
);
|
||||
|
||||
Factory::getApplication()->enqueueMessage(
|
||||
@@ -113,6 +113,6 @@ class HtmlView extends BaseHtmlView
|
||||
ToolbarHelper::custom('backups.restore', 'upload', '', 'COM_MOKOJOOMBACKUP_TOOLBAR_RESTORE', true);
|
||||
ToolbarHelper::custom('backups.verify', 'shield', '', 'COM_MOKOJOOMBACKUP_TOOLBAR_VERIFY', true);
|
||||
ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'backups.delete');
|
||||
ToolbarHelper::preferences('com_mokojoombackup');
|
||||
ToolbarHelper::preferences('com_mokosuitebackup');
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user