diff --git a/.mokogitea/manifest.xml b/.mokogitea/manifest.xml index f9b4311..94057ae 100644 --- a/.mokogitea/manifest.xml +++ b/.mokogitea/manifest.xml @@ -5,7 +5,7 @@ Package - MokoJoomBackup MokoConsulting Full-site backup and restore for Joomla — database, files, and configuration - 01.07.00-dev + 01.07.01-dev GNU General Public License v3 diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 9681a9c..5bcc35c 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokoplatform.Automation -# VERSION: 01.07.00 +# VERSION: 01.07.01 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/README.md b/README.md index e49ab77..128fdac 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MokoJoomBackup - + Full-site backup and restore for Joomla — database, files, and configuration. diff --git a/source/packages/com_mokojoombackup/mokojoombackup.xml b/source/packages/com_mokojoombackup/mokojoombackup.xml index 542210d..22f4fff 100644 --- a/source/packages/com_mokojoombackup/mokojoombackup.xml +++ b/source/packages/com_mokojoombackup/mokojoombackup.xml @@ -8,7 +8,7 @@ --> com_mokojoombackup - 01.07.00 + 01.07.01-dev 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/com_mokojoombackup/src/Engine/AkeebaImporter.php b/source/packages/com_mokojoombackup/src/Engine/AkeebaImporter.php index c1fab5b..6861c78 100644 --- a/source/packages/com_mokojoombackup/src/Engine/AkeebaImporter.php +++ b/source/packages/com_mokojoombackup/src/Engine/AkeebaImporter.php @@ -30,6 +30,7 @@ namespace Joomla\Component\MokoJoomBackup\Administrator\Engine; defined('_JEXEC') or die; use Joomla\CMS\Factory; +use Joomla\Component\MokoJoomBackup\Administrator\Utility\BackupDirectory; class AkeebaImporter { @@ -484,7 +485,7 @@ class AkeebaImporter $dir = $config['akeeba.basic.output_directory'] ?? ''; if (empty($dir) || $dir === '[DEFAULT_OUTPUT]') { - return 'administrator/components/com_mokojoombackup/backups'; + return BackupDirectory::DEFAULT_RELATIVE; } // Convert absolute path to relative @@ -492,7 +493,7 @@ class AkeebaImporter $dir = ltrim(substr($dir, strlen(JPATH_ROOT)), '/\\'); } - return $dir ?: 'administrator/components/com_mokojoombackup/backups'; + return $dir ?: BackupDirectory::DEFAULT_RELATIVE; } private function mapRemoteStorage(array $config): string diff --git a/source/packages/plg_actionlog_mokojoombackup/mokojoombackup.xml b/source/packages/plg_actionlog_mokojoombackup/mokojoombackup.xml index 74f1ad2..4b5ddb1 100644 --- a/source/packages/plg_actionlog_mokojoombackup/mokojoombackup.xml +++ b/source/packages/plg_actionlog_mokojoombackup/mokojoombackup.xml @@ -8,7 +8,7 @@ --> plg_actionlog_mokojoombackup - 01.07.00 + 01.07.01-dev 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_console_mokojoombackup/mokojoombackup.xml b/source/packages/plg_console_mokojoombackup/mokojoombackup.xml index 34d4217..666cf4e 100644 --- a/source/packages/plg_console_mokojoombackup/mokojoombackup.xml +++ b/source/packages/plg_console_mokojoombackup/mokojoombackup.xml @@ -8,7 +8,7 @@ --> plg_console_mokojoombackup - 01.07.00 + 01.07.01-dev 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_content_mokojoombackup/mokojoombackup.xml b/source/packages/plg_content_mokojoombackup/mokojoombackup.xml index 8d545ef..aa8d129 100644 --- a/source/packages/plg_content_mokojoombackup/mokojoombackup.xml +++ b/source/packages/plg_content_mokojoombackup/mokojoombackup.xml @@ -8,7 +8,7 @@ --> plg_content_mokojoombackup - 01.07.00 + 01.07.01-dev 2026-06-04 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_quickicon_mokojoombackup/mokojoombackup.xml b/source/packages/plg_quickicon_mokojoombackup/mokojoombackup.xml index a2116b9..4c95d6d 100644 --- a/source/packages/plg_quickicon_mokojoombackup/mokojoombackup.xml +++ b/source/packages/plg_quickicon_mokojoombackup/mokojoombackup.xml @@ -1,7 +1,7 @@ plg_quickicon_mokojoombackup - 01.07.00 + 01.07.01-dev 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_system_mokojoombackup/mokojoombackup.xml b/source/packages/plg_system_mokojoombackup/mokojoombackup.xml index a9f86a2..71a6777 100644 --- a/source/packages/plg_system_mokojoombackup/mokojoombackup.xml +++ b/source/packages/plg_system_mokojoombackup/mokojoombackup.xml @@ -8,7 +8,7 @@ --> plg_system_mokojoombackup - 01.07.00 + 01.07.01-dev 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_task_mokojoombackup/mokojoombackup.xml b/source/packages/plg_task_mokojoombackup/mokojoombackup.xml index 200e91a..3c43da5 100644 --- a/source/packages/plg_task_mokojoombackup/mokojoombackup.xml +++ b/source/packages/plg_task_mokojoombackup/mokojoombackup.xml @@ -8,7 +8,7 @@ --> plg_task_mokojoombackup - 01.07.00 + 01.07.01-dev 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_webservices_mokojoombackup/mokojoombackup.xml b/source/packages/plg_webservices_mokojoombackup/mokojoombackup.xml index c81d863..949779d 100644 --- a/source/packages/plg_webservices_mokojoombackup/mokojoombackup.xml +++ b/source/packages/plg_webservices_mokojoombackup/mokojoombackup.xml @@ -8,7 +8,7 @@ --> plg_webservices_mokojoombackup - 01.07.00 + 01.07.01-dev 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokojoombackup.xml b/source/pkg_mokojoombackup.xml index 1bb3c1f..e74d451 100644 --- a/source/pkg_mokojoombackup.xml +++ b/source/pkg_mokojoombackup.xml @@ -8,7 +8,7 @@ Package - MokoJoomBackup mokojoombackup - 01.07.00 + 01.07.01-dev 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/script.php b/source/script.php index 0ceb68d..a4fdb3f 100644 --- a/source/script.php +++ b/source/script.php @@ -211,14 +211,125 @@ class Pkg_MokoJoomBackupInstallerScript file_put_contents($index, ''); } } + + // Create default scheduled task — every 30 days, profile 1 + $this->createDefaultScheduledTask(); + } + + if ($type === 'uninstall') { + return; } // Sync submenu icons in #__menu (Joomla doesn't update icons on upgrades) $this->syncMenuIcons(); - // Warn if no license key configured (skip on uninstall) - if ($type !== 'uninstall') { - $this->warnMissingLicenseKey(); + // Warn if no license key configured + $this->warnMissingLicenseKey(); + + // Warn if any profile still uses the default backup directory + $this->warnDefaultBackupDir(); + + // Remind user to review backup profile settings + if ($type === 'install') { + $profileUrl = Route::_('index.php?option=com_mokojoombackup&view=profiles'); + + Factory::getApplication()->enqueueMessage( + 'Review Your Backup Settings — ' + . 'A default backup profile has been created. Review the profile settings to configure ' + . 'backup type, schedule, storage location, and notifications. ' + . 'Review Profiles', + 'info' + ); + } + } + + private function warnDefaultBackupDir(): void + { + try { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__mokojoombackup_profiles')) + ->where($db->quoteName('published') . ' = 1') + ->where('(' . $db->quoteName('backup_dir') . ' = ' . $db->quote('administrator/components/com_mokojoombackup/backups') + . ' OR ' . $db->quoteName('backup_dir') . ' = ' . $db->quote('[DEFAULT_DIR]') + . ' OR ' . $db->quoteName('backup_dir') . ' = ' . $db->quote('') + . ' OR ' . $db->quoteName('backup_dir') . ' IS NULL)'); + $db->setQuery($query); + + if ((int) $db->loadResult() > 0) { + $profileUrl = Route::_('index.php?option=com_mokojoombackup&view=profiles'); + + Factory::getApplication()->enqueueMessage( + 'Backup Directory Warning — ' + . 'One or more profiles store backups in the default directory inside the web root. ' + . 'For better security, configure a backup directory outside the web root. ' + . 'Edit Profiles', + 'warning' + ); + } + } catch (\Throwable $e) { + error_log('MokoJoomBackup: warnDefaultBackupDir() failed: ' . $e->getMessage()); + } + } + + private function createDefaultScheduledTask(): void + { + try { + $db = Factory::getDbo(); + + // Check if a MokoJoomBackup task already exists + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__scheduler_tasks')) + ->where($db->quoteName('type') . ' = ' . $db->quote('mokojoombackup.run_profile')); + $db->setQuery($query); + + if ((int) $db->loadResult() > 0) { + return; + } + + $now = date('Y-m-d H:i:s'); + + $task = (object) [ + 'title' => 'MokoJoomBackup — Monthly Full Backup', + 'type' => 'mokojoombackup.run_profile', + 'execution_rules' => json_encode([ + 'rule-type' => 'interval-days', + 'interval-days' => '30', + 'exec-day' => '1', + 'exec-time' => '03:00:00', + ]), + 'cron_rules' => json_encode([ + 'type' => 'interval', + 'exp' => 'P30D', + ]), + 'state' => 1, + 'params' => json_encode([ + 'profile_id' => 1, + 'individual_log' => true, + 'log_file' => '', + 'notifications' => [ + 'success_mail' => '0', + 'failure_mail' => '1', + 'notification_failure_groups' => ['8'], + 'fatal_failure_mail' => '1', + 'notification_fatal_groups' => ['8'], + 'orphan_mail' => '0', + ], + ]), + 'priority' => 0, + 'ordering' => 0, + 'cli_exclusive' => 0, + 'note' => '', + 'created' => $now, + 'created_by' => Factory::getApplication()->getIdentity()->id ?? 0, + 'next_execution' => date('Y-m-d 03:00:00', strtotime('+1 day')), + ]; + + $db->insertObject('#__scheduler_tasks', $task); + } catch (\Throwable $e) { + error_log('MokoJoomBackup: createDefaultScheduledTask() failed: ' . $e->getMessage()); } }