<?php /* * @package bfNetwork * @copyright Copyright (C) 2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025 Blue Flame Digital Solutions Ltd. All rights reserved. * @license GNU General Public License version 3 or later * * @see https://mySites.guru/ * @see https://www.phil-taylor.com/ * * @author Phil Taylor / Blue Flame Digital Solutions Limited. * * bfNetwork is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * bfNetwork is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this package. If not, see http://www.gnu.org/licenses/ * * If you have any questions regarding this code, please contact [email protected] */ use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Filesystem\Folder; use Joomla\CMS\Language\Text; use Joomla\CMS\Log\Log; use Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel; // Decrypt or die require 'bfEncrypt.php'; /* * If we have got here then we have already passed through decrypting * the encrypted header and so we are sure we are now secure and no one * else cannot run the code below...... */ class bfUpgrade { private $_methods = [ 1 => 'getAllUpdates', 2 => 'downloadFile', 3 => 'createRestorationFile', 4 => 'extractUpdate', 5 => 'finishup', ]; /** * @var \stdClass */ private $_dataObj; public function __construct($dataObj) { // init Joomla if (! defined('BF_JOOMLA_INIT_DONE')) { require_once 'bfInitJoomla.php'; } if (! \defined('JPATH_COMPONENT_ADMINISTRATOR')) { \define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR . '/components/com_joomlaupdate'); } Factory::getApplication()->getLanguage()->load('com_joomlaupdate', JPATH_ADMINISTRATOR); Factory::getApplication()->getLanguage()->load('lib_joomla', JPATH_ADMINISTRATOR); // Do not allow jump's of series - for now. ComponentHelper::getParams('com_joomlaupdate')->set('updatesource', 'default'); if (file_exists(JPATH_BASE . '/administrator/cache/autoload_psr4.php')) { @unlink(JPATH_BASE . '/administrator/cache/autoload_psr4.php'); } // Set the request vars $this->_dataObj = $dataObj; } public function run() { if (property_exists($this->_dataObj, 'c')) { $c = (int) $this->_dataObj->c; if (array_key_exists($c, $this->_methods)) { // call the right method $this->{$this->_methods[$c]} (); } else { bfEncrypt::reply('error', 'No Such method #err1 - ' . $c); } } else { bfEncrypt::reply('error', 'No Such method #err2'); } } public function downloadFile() { /** @var UpdateModel $model */ $model = Factory::getApplication() ->bootComponent('com_joomlaupdate') ->getMVCFactory()->createModel('Update', 'Administrator', [ 'ignore_request' => true, ]); $result = $model->download(); if ($result['check'] === false) { $message = Text::_('COM_JOOMLAUPDATE_VIEW_UPDATE_CHECKSUM_WRONG'); try { Log::add($message, Log::ERROR, 'Update'); } catch (\RuntimeException $exception) { } bfEncrypt::reply('error', $message); } $file = $result['basename']; if ($file) { Log::add(Text::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_FILE', $file), Log::INFO, 'Update'); } else { $message = Text::_('COM_JOOMLAUPDATE_VIEW_UPDATE_DOWNLOADFAILED'); Log::add($message, Log::INFO, 'Update'); bfEncrypt::reply('error', $message); } $retArray = [ 'status' => true, 'error' => '', 'frag' => '-1', 'file' => $result['basename'], 'totalSize' => '', 'doneSize' => '', 'md5' => '', 'percent' => 100, ]; bfEncrypt::reply('success', $retArray); } public function createRestorationFile() { /** @var UpdateModel $model */ $model = Factory::getApplication() ->bootComponent('com_joomlaupdate') ->getMVCFactory()->createModel('Update', 'Administrator', [ 'ignore_request' => true, ]); if (! method_exists($model, 'createUpdateFile')) { $restoration_setup = [ 'kickstart.security.password' => '', ]; $model->createRestorationFile(); define('_AKEEBA_RESTORATION', 1); require JPATH_COMPONENT_ADMINISTRATOR . '/restoration.php'; bfEncrypt::reply('success', $restoration_setup['kickstart.security.password']); } else { $extractionSetup = [ 'security.password' => '', ]; $model->createUpdateFile(); define('_JOOMLA_UPDATE', 1); require JPATH_COMPONENT_ADMINISTRATOR . '/update.php'; bfEncrypt::reply('success', $extractionSetup['security.password']); } } public function purgeJoomlaUpdateCache() { bfLog::log('running purgeJoomlaUpdateCache'); $db = Factory::getContainer()->get('DatabaseDriver'); // Modify the database record $update_site = new stdClass(); $update_site->last_check_timestamp = 0; $update_site->enabled = 1; $update_site->update_site_id = 1; $db->updateObject('#__update_sites', $update_site, 'update_site_id'); $query = $db->getQuery(true) ->delete($db->quoteName('#__updates')) ->where($db->quoteName('update_site_id') . ' = ' . $db->quote('1')); $db->setQuery($query); if ($db->execute()) { return true; } return false; } public function finishup() { if (! defined('BF_JOOMLA_INIT_DONE')) { require_once 'bfInitJoomla.php'; } $updateModel = Factory::getApplication() ->bootComponent('com_joomlaupdate') ->getMVCFactory()->createModel('Update', 'Administrator', [ 'ignore_request' => true, ]); $updateModel->finaliseUpgrade(); // remove files that Joomla required UserState/Session to "see" $foundFile = glob(Factory::getApplication()->get('tmp_path') . '/Joomla*Update_Package*.zip'); if ([] !== $foundFile) { foreach ($foundFile as $file) { bfLog::log('Removing Upgrade Package File: ' . basename($file)); unlink($file); } } // Allow Joomla to clean up everything else $updateModel->cleanUp(); // Belt and braces if (file_exists(JPATH_BASE . '/administrator/cache/autoload_psr4.php')) { @unlink(JPATH_BASE . '/administrator/cache/autoload_psr4.php'); } bfEncrypt::reply('success', [ 'msg' => json_encode(true), ]); } public function getAllUpdates($force = false) { /** @var UpdateModel $model */ $model = Factory::getApplication() ->bootComponent('com_joomlaupdate') ->getMVCFactory()->createModel('Update', 'Administrator', [ 'ignore_request' => true, ]); $model->applyUpdateSite(); $model->refreshUpdates(true); $info = $model->getUpdateInformation(); $updateInfo = []; $updateInfo['downloadurl'] = $info['object']->downloadurl->_data; $updateInfo['infourl'] = $info['object']->get('infourl')->_data; $updateInfo['version'] = $info['latest']; $updateInfo['installed'] = $info['installed']; $updateInfo['updatesource'] = ComponentHelper::getParams('com_joomlaupdate')->get('updatesource'); if ($this->hasAkeebaBackup()) { $db = Factory::getContainer()->get('DatabaseDriver'); $query = $db->getQuery(true) ->select('MAX(id)') ->from('#__akeebabackup_backups') ->where('`origin` != "restorepoint"'); $db->setQuery($query); $lastBackup = $db->loadResult(); if ($lastBackup > 0) { $query = 'SELECT * FROM #__akeebabackup_backups WHERE tag <> "restorepoint" ORDER BY `backupstart` DESC LIMIT 1 '; $db->setQuery($query); $lastBackup = $db->loadObjectList(); } } else { $lastBackup = ''; } $data = [ $updateInfo, 'Currently_Installed_Version' => JVERSION, 'PHP_VERSION' => \PHP_VERSION, 'hasAkeebaBackup' => $this->hasAkeebaBackup(), 'lastBackupDetails' => $lastBackup, ]; bfEncrypt::reply('success', [ 'msg' => json_encode($data), ]); } public function hasAkeebaBackup() { // Is the component installed, at all? if (! Folder::exists(JPATH_ADMINISTRATOR . '/components/com_akeebabackup')) { return false; } // Make sure the component is enabled $component = ComponentHelper::getComponent('com_akeebabackup', true); if (! $component->enabled) { return false; } return true; } } // init this class $upgradeController = new bfUpgrade($dataObj); $upgradeController->run();