Files
MokoSuiteBackup/source/packages/com_mokosuitebackup/src/View/Backups/HtmlView.php
T
Jonathan Miller 8e5913d706
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Failing after 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 7s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 11s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: PR Check / Secret Scan (pull_request) Successful in 10s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 33s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 5s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 54s
fix: enforce correct ACL permissions across all controllers (#137)
13 ACL fixes across 5 files:
- BackupsController: purge() uses backup.purge (was core.delete)
- SnapshotsController: delete() uses snapshot.manage (was core.delete)
- AjaxController: restoreInit/Step use backup.restore (was backup.run),
  browseArchive uses backup.browse (was core.manage),
  countPurge uses backup.purge (was core.delete),
  compareBackups uses backup.compare (was core.manage)
- API SnapshotsController: displayList/download use snapshot.manage
  (was core.manage)
- HtmlView: verify gated by core.manage, compare by backup.compare,
  purge separated from delete with backup.purge

Closes #137
2026-06-23 14:16:54 -05:00

144 lines
4.5 KiB
PHP

<?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\View\Backups;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
protected $items;
protected $pagination;
protected $state;
public $filterForm;
public $activeFilters = [];
public $profiles = [];
public function display($tpl = null): void
{
$this->items = $this->get('Items');
$this->pagination = $this->get('Pagination');
$this->state = $this->get('State');
$this->filterForm = $this->get('FilterForm');
$this->activeFilters = $this->get('ActiveFilters');
// Load published profiles for the backup selector
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName(['id', 'title', 'backup_type']))
->from($db->quoteName('#__mokosuitebackup_profiles'))
->where($db->quoteName('published') . ' = 1')
->order($db->quoteName('ordering') . ' ASC');
$db->setQuery($query);
$this->profiles = $db->loadObjectList() ?: [];
$this->checkUpdateSite();
$this->addToolbar();
parent::display($tpl);
}
/**
* Show an info notice linking to the update site record so the user
* can configure their download key for automatic updates.
*/
protected function checkUpdateSite(): void
{
try {
$db = Factory::getDbo();
// Find the update site linked to pkg_mokosuitebackup
$query = $db->getQuery(true)
->select([
$db->quoteName('us.update_site_id'),
$db->quoteName('us.extra_query'),
])
->from($db->quoteName('#__update_sites', 'us'))
->join(
'INNER',
$db->quoteName('#__update_sites_extensions', 'use')
. ' ON ' . $db->quoteName('use.update_site_id') . ' = ' . $db->quoteName('us.update_site_id')
)
->join(
'INNER',
$db->quoteName('#__extensions', 'e')
. ' ON ' . $db->quoteName('e.extension_id') . ' = ' . $db->quoteName('use.extension_id')
)
->where($db->quoteName('e.element') . ' = ' . $db->quote('pkg_mokosuitebackup'))
->where($db->quoteName('e.type') . ' = ' . $db->quote('package'))
->setLimit(1);
$db->setQuery($query);
$site = $db->loadObject();
if (!$site) {
Factory::getApplication()->enqueueMessage(
Text::_('COM_MOKOJOOMBACKUP_UPDATE_SITE_MISSING'),
'warning'
);
} 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]=mokosuitebackup'
);
Factory::getApplication()->enqueueMessage(
Text::sprintf('COM_MOKOJOOMBACKUP_UPDATE_SITE_NOTICE', $editUrl),
'info'
);
}
// If key is present, show nothing — all good
} catch (\Throwable $e) {
// Non-critical — silently ignore
}
}
protected function addToolbar(): void
{
$user = Factory::getApplication()->getIdentity();
ToolbarHelper::title(Text::_('COM_MOKOJOOMBACKUP_BACKUPS_TITLE'), 'database');
if ($user->authorise('mokosuitebackup.backup.run', 'com_mokosuitebackup')) {
ToolbarHelper::custom('backups.start', 'download', '', 'COM_MOKOJOOMBACKUP_TOOLBAR_BACKUP_NOW', false);
}
if ($user->authorise('mokosuitebackup.backup.restore', 'com_mokosuitebackup')) {
ToolbarHelper::custom('backups.restore', 'upload', '', 'COM_MOKOJOOMBACKUP_TOOLBAR_RESTORE', true);
}
if ($user->authorise('core.manage', 'com_mokosuitebackup')) {
ToolbarHelper::custom('backups.verify', 'shield', '', 'COM_MOKOJOOMBACKUP_TOOLBAR_VERIFY', true);
}
if ($user->authorise('mokosuitebackup.backup.compare', 'com_mokosuitebackup')) {
ToolbarHelper::custom('backups.compare', 'copy', '', 'COM_MOKOJOOMBACKUP_TOOLBAR_COMPARE', true);
}
if ($user->authorise('core.delete', 'com_mokosuitebackup')) {
ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'backups.delete');
}
if ($user->authorise('mokosuitebackup.backup.purge', 'com_mokosuitebackup')) {
ToolbarHelper::custom('backups.purgeModal', 'trash', '', 'COM_MOKOJOOMBACKUP_TOOLBAR_PURGE', false);
}
if ($user->authorise('core.admin', 'com_mokosuitebackup')) {
ToolbarHelper::preferences('com_mokosuitebackup');
}
}
}