Current File : /home/pacjaorg/www/nsa/administrator/components/com_akeebabackup/src/Dispatcher/Dispatcher.php |
<?php
/**
* @package akeebabackup
* @copyright Copyright (c)2006-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace Akeeba\Component\AkeebaBackup\Administrator\Dispatcher;
defined('_JEXEC') || die;
use Akeeba\Component\AkeebaBackup\Administrator\Dispatcher\Mixin\AkeebaEngineAware;
use Akeeba\Component\AkeebaBackup\Administrator\Dispatcher\Mixin\TriggerEvent;
use Akeeba\Component\AkeebaBackup\Administrator\Helper\SecretWord;
use Akeeba\Engine\Platform;
use Exception;
use JLoader;
use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Dispatcher\ComponentDispatcher;
use Joomla\CMS\Document\HtmlDocument;
use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\WebAsset\WebAssetItem;
use Joomla\Database\DatabaseDriver;
use Joomla\Database\DatabaseInterface;
use ReflectionObject;
use Throwable;
class Dispatcher extends ComponentDispatcher
{
use TriggerEvent;
use AkeebaEngineAware;
/**
* The application instance
*
* @var CMSApplication
* @since 4.0.0
*/
protected $app;
/**
* The URL option for the component.
*
* @var string
* @since 9.0.0
*/
protected $option = 'com_akeebabackup';
protected $defaultController = 'controlpanel';
/**
* The database driver of the application
*
* @var DatabaseInterface|null
* @since 9.3.0
*/
protected $dbo = null;
public function dispatch()
{
// Check the minimum supported PHP version
$minPHPVersion = '7.2.0';
$softwareName = 'Akeeba Backup';
if (!@require_once __DIR__ . '/../../tmpl/commontemplates/wrongphp.php')
{
return;
}
// HHVM made sense in 2013. PHP 7 and later versions are a way better solution than a hybrid PHP interpreter.
if (defined('HHVM_VERSION'))
{
(include_once __DIR__ . '/../../tmpl/commontemplates/hhvm.php') || die('We have detected that you are running HHVM instead of PHP. This software WILL NOT WORK properly on HHVM. Please use PHP 7 or later instead.');
return;
}
try
{
$this->triggerEvent('onBeforeDispatch');
parent::dispatch();
// This will only execute if there is no redirection set by the Controller
$this->triggerEvent('onAfterDispatch');
}
catch (Throwable $e)
{
$title = 'Akeeba Backup';
$isPro = defined(AKEEBABACKUP_PRO) ? AKEEBABACKUP_PRO : @is_dir(__DIR__ . '/../../AliceChecks');
if (!(include_once __DIR__ . '/../../tmpl/commontemplates/errorhandler.php'))
{
throw $e;
}
}
}
/**
* Get the database driver object
*
* @return null|DatabaseInterface
* @since 9.3.0
*/
public function getDbo(): ?DatabaseInterface
{
return $this->dbo;
}
/**
* @param DatabaseInterface|null $dbo
*
* @return self
* @since 9.3.0
*/
public function setDbo(?DatabaseInterface $dbo): self
{
$this->dbo = $dbo;
return $this;
}
protected function onBeforeDispatch()
{
// Make sure we have a version loaded
@include_once(__DIR__ . '/../../version.php');
if (!defined('AKEEBABACKUP_VERSION'))
{
define('AKEEBABACKUP_VERSION', 'dev');
define('AKEEBABACKUP_DATE', date('Y-m-d'));
}
if (!defined('AKEEBABACKUP_PRO'))
{
define('AKEEBABACKUP_PRO', @is_dir(__DIR__ . '/../../AliceChecks'));
}
// Load the languages
$this->loadLanguage();
// Apply the view and controller from the request, falling back to the default view/controller if necessary
$this->applyViewAndController();
// Access control
$this->checkAccess();
// Load Akeeba Engine
$this->loadAkeebaEngine($this->getDbo(), $this->mvcFactory);
// Load the Akeeba Engine configuration
try
{
$this->loadAkeebaEngineConfiguration();
}
catch (Exception $e)
{
// Maybe the tables are not installed?
$msg = Text::_('COM_AKEEBABACKUP_CONTROLPANEL_MSG_REBUILTTABLES');
$this->app->enqueueMessage($msg, 'warning');
$this->app->redirect(Uri::base(), 307);
}
// Prevents the "SQLSTATE[HY000]: General error: 2014" due to resource sharing with Akeeba Engine
$this->fixPDOMySQLResourceSharing();
// Load the utils helper library
Platform::getInstance()->load_version_defines();
Platform::getInstance()->apply_quirk_definitions();
// Set up Alice's autoloader
if (defined('AKEEBABACKUP_PRO') && AKEEBABACKUP_PRO)
{
JLoader::registerNamespace('Akeeba\Alice', __DIR__ . '/../../AliceChecks');
}
// Make sure the front-end backup Secret Word is stored encrypted
$params = ComponentHelper::getParams($this->option);
SecretWord::enforceEncryption($params, 'frontend_secret_word');
$this->loadCommonStaticMedia();
}
/**
* Prevents the "SQLSTATE[HY000]: General error: 2014" due to resource sharing with Akeeba Engine.
*
* @since 7.5.2
*/
protected function fixPDOMySQLResourceSharing(): void
{
// This fix only applies to PHP 7.x, not 8.x
if (version_compare(PHP_VERSION, '8.0', 'ge'))
{
return;
}
$dbDriver = $this->dbo->getName() ?? $this->dbo->name ?? 'mysql';
if ($dbDriver !== 'pdomysql')
{
return;
}
$this->dbo->disconnect();
}
/**
* Load the language.
*
* Automatically loads en-GB and the site's fallback language (if different), then merges it with the language of
* the current user. First tries loading languages from the site's main folders before falling back to the ones
* shipped with the component itself.
*
* @return void
*
* @since 9.0.0
*/
protected function loadLanguage()
{
$jLang = $this->app->getLanguage();
$jLang->load($this->option, JPATH_BASE, 'en-GB', true, true) ||
$jLang->load($this->option, JPATH_COMPONENT, 'en-GB', true, true);
$jLang->load($this->option, JPATH_BASE, null, true) ||
$jLang->load($this->option, JPATH_COMPONENT, null, true);
}
protected function loadCommonStaticMedia()
{
// Make sure we run under a CMS application
if (!($this->app instanceof CMSApplication))
{
return;
}
// Make sure the document is HTML
$document = $this->app->getDocument();
if (!($document instanceof HtmlDocument))
{
return;
}
/**
* Joomla applies its own version string in OUR assets which is totally dumb. It inherently assumes that third
* party extensions assets are only updated when Joomla itself is updated. Typical Joomla core development,
* can't see past its own nose. We will work around that.
*/
$versionModifier = $this->app->get('debug') ? microtime() : '';
$akeebaMediaVersion = ApplicationHelper::getHash(AKEEBABACKUP_VERSION . AKEEBABACKUP_DATE . $versionModifier);
$waRegistry = $document->getWebAssetManager()->getRegistry();
$waRegistry->get('preset', 'com_akeebabackup.common');
$refObj = new ReflectionObject($waRegistry);
$refProp = $refObj->getProperty('assets');
$refProp->setAccessible(true);
$registeredAssets = $refProp->getValue($waRegistry);
foreach ($registeredAssets as $area => $assets)
{
$temp = [];
/** @var WebAssetItem $assetItem */
foreach ($assets as $key => $assetItem)
{
if (substr($key, 0, 17) != 'com_akeebabackup.')
{
$temp[$key] = $assetItem;
continue;
}
$refAI = new ReflectionObject($assetItem);
$refVersion = $refAI->getProperty('version');
$refVersion->setAccessible(true);
$refVersion->setValue($assetItem, $akeebaMediaVersion);
$temp[$key] = $assetItem;
}
$registeredAssets[$area] = $temp;
unset($temp);
}
$refProp->setValue($waRegistry, $registeredAssets);
// Finally, load our 'common' preset
$document->getWebAssetManager()
->usePreset('com_akeebabackup.common');
}
private function applyViewAndController(): void
{
// Handle a custom default controller name
$view = $this->input->getCmd('view', $this->defaultController);
$controller = $this->input->getCmd('controller', $view);
$task = $this->input->getCmd('task', 'main');
// Check for a controller.task command.
if (strpos($task, '.') !== false)
{
// Explode the controller.task command.
[$controller, $task] = explode('.', $task);
}
$this->input->set('view', $controller);
$this->input->set('controller', $controller);
$this->input->set('task', $task);
}
}