Current File : /home/pacjaorg/public_html/nsa/libraries/src/Console/UpdateCoreCommand.php
<?php
/**
 * Joomla! Content Management System
 *
 * @copyright  (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\CMS\Console;

\defined('JPATH_PLATFORM') or die;

use Joomla\Application\Cli\CliInput;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Installer\InstallerHelper;
use Joomla\Console\Command\AbstractCommand;
use Joomla\Database\DatabaseInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * Console command for updating Joomla! core
 *
 * @since  4.0.0
 */
class UpdateCoreCommand extends AbstractCommand
{
	/**
	 * The default command name
	 *
	 * @var    string
	 * @since  4.0.0
	 */
	protected static $defaultName = 'core:update';

	/**
	 * Stores the Input Object
	 * @var CliInput
	 * @since 4.0.0
	 */
	private $cliInput;

	/**
	 * SymfonyStyle Object
	 * @var SymfonyStyle
	 * @since 4.0.0
	 */
	private $ioStyle;

	/**
	 * Update Information
	 * @var array
	 * @since 4.0.0
	 */
	public $updateInfo;

	/**
	 * Update Model
	 * @var array
	 * @since 4.0.0
	 */
	public $updateModel;

	/**
	 * Progress Bar object
	 * @var ProgressBar
	 * @since 4.0.0
	 */
	public $progressBar;

	/**
	 * Return code for successful update
	 * @since 4.0.0
	 */
	public const UPDATE_SUCCESSFUL = 0;

	/**
	 * Return code for failed update
	 * @since 4.0.0
	 */
	public const ERR_UPDATE_FAILED = 2;

	/**
	 * Return code for failed checks
	 * @since 4.0.0
	 */
	public const ERR_CHECKS_FAILED = 1;

	/**
	 * @var DatabaseInterface
	 * @since 4.0.0
	 */
	private $db;

	/**
	 * UpdateCoreCommand constructor.
	 *
	 * @param   DatabaseInterface  $db  Database Instance
	 *
	 * @since 4.0.0
	 */
	public function __construct(DatabaseInterface $db)
	{
		$this->db = $db;
		parent::__construct();
	}

	/**
	 * Configures the IO
	 *
	 * @param   InputInterface   $input   Console Input
	 * @param   OutputInterface  $output  Console Output
	 *
	 * @return void
	 *
	 * @since 4.0.0
	 *
	 */
	private function configureIO(InputInterface $input, OutputInterface $output)
	{
		ProgressBar::setFormatDefinition('custom', ' %current%/%max% -- %message%');
		$this->progressBar = new ProgressBar($output, 8);
		$this->progressBar->setFormat('custom');

		$this->cliInput = $input;
		$this->ioStyle = new SymfonyStyle($input, $output);
	}

	/**
	 * Internal function to execute the command.
	 *
	 * @param   InputInterface   $input   The input to inject into the command.
	 * @param   OutputInterface  $output  The output to inject into the command.
	 *
	 * @return  integer  The command exit code
	 *
	 * @since   4.0.0
	 * @throws \Exception
	 */
	public function doExecute(InputInterface $input, OutputInterface $output): int
	{
		$this->configureIO($input, $output);

		$this->progressBar->setMessage("Starting up ...");
		$this->progressBar->start();

		$model = $this->getUpdateModel();

		$this->setUpdateInfo($model->getUpdateInformation());

		$this->progressBar->advance();
		$this->progressBar->setMessage('Running checks ...');

		if (!$this->updateInfo['hasUpdate'])
		{
			$this->progressBar->finish();
			$this->ioStyle->note('You already have the latest Joomla! version. ' . $this->updateInfo['latest']);

			return self::ERR_CHECKS_FAILED;
		}

		$this->progressBar->advance();
		$this->progressBar->setMessage('Starting Joomla! update ...');

		if ($this->updateJoomlaCore($model))
		{
			$this->progressBar->finish();
			$this->ioStyle->success('Joomla core updated successfully!');

			return self::UPDATE_SUCCESSFUL;
		}

		$this->progressBar->finish();

		$this->ioStyle->error('Update cannot be performed.');

		return self::ERR_UPDATE_FAILED;
	}

	/**
	 * Initialise the command.
	 *
	 * @return  void
	 *
	 * @since   4.0.0
	 */
	protected function configure(): void
	{
		$help = "<info>%command.name%</info> is used to update Joomla
		\nUsage: <info>php %command.full_name%</info>";

		$this->setDescription('Update Joomla');
		$this->setHelp($help);
	}

	/**
	 * Update Core Joomla
	 *
	 * @param   mixed  $updatemodel  Update Model
	 *
	 * @return  boolean  success
	 *
	 * @since 4.0.0
	 */
	private function updateJoomlaCore($updatemodel): bool
	{
		$updateInformation = $this->updateInfo;

		if (!empty($updateInformation['hasUpdate']))
		{
			$this->progressBar->advance();
			$this->progressBar->setMessage("Processing update package ...");
			$package = $this->processUpdatePackage($updateInformation);

			$this->progressBar->advance();
			$this->progressBar->setMessage("Finalizing update ...");
			$result = $updatemodel->finaliseUpgrade();

			if ($result)
			{
				$this->progressBar->advance();
				$this->progressBar->setMessage("Cleaning up ...");

				// Remove the xml
				if (file_exists(JPATH_BASE . '/joomla.xml'))
				{
					File::delete(JPATH_BASE . '/joomla.xml');
				}

				InstallerHelper::cleanupInstall($package['file'], $package['extractdir']);

				$updatemodel->purge();

				return true;
			}
		}

		return false;
	}

	/**
	 * Sets the update Information
	 *
	 * @param   array  $data  Stores the update information
	 *
	 * @since 4.0.0
	 *
	 * @return void
	 */
	public function setUpdateInfo($data): void
	{
		$this->updateInfo = $data;
	}

	/**
	 * Retrieves the Update model from com_joomlaupdate
	 *
	 * @return mixed
	 *
	 * @since 4.0.0
	 *
	 * @throws \Exception
	 */
	public function getUpdateModel()
	{
		if (!isset($this->updateModel))
		{
			$this->setUpdateModel();
		}

		return $this->updateModel;
	}

	/**
	 * Sets the Update Model
	 *
	 * @return void
	 *
	 * @since 4.0.0
	 */
	public function setUpdateModel(): void
	{
		$app = $this->getApplication();
		$updatemodel = $app->bootComponent('com_joomlaupdate')->getMVCFactory($app)->createModel('Update', 'Administrator');

		if (is_bool($updatemodel))
		{
			$this->updateModel = $updatemodel;

			return;
		}

		$updatemodel->purge();
		$updatemodel->refreshUpdates(true);

		$this->updateModel = $updatemodel;
	}

	/**
	 * Downloads and extracts the update Package
	 *
	 * @param   array  $updateInformation  Stores the update information
	 *
	 * @return array | boolean
	 *
	 * @since 4.0.0
	 */
	public function processUpdatePackage($updateInformation)
	{
		if (!$updateInformation['object'])
		{
			return false;
		}

		$this->progressBar->advance();
		$this->progressBar->setMessage("Downloading update package ...");
		$file = $this->downloadFile($updateInformation['object']->downloadurl->_data);

		$tmpPath    = $this->getApplication()->get('tmp_path');
		$updatePackage = $tmpPath . '/' . $file;

		$this->progressBar->advance();
		$this->progressBar->setMessage("Extracting update package ...");
		$package = $this->extractFile($updatePackage);

		$this->progressBar->advance();
		$this->progressBar->setMessage("Copying files ...");
		$this->copyFileTo($package['extractdir'], JPATH_BASE);

		return ['file' => $updatePackage, 'extractdir' => $package['extractdir']];
	}

	/**
	 * Downloads the Update file
	 *
	 * @param   string  $url  URL to update file
	 *
	 * @return boolean | string
	 *
	 * @since 4.0.0
	 */
	public function downloadFile($url)
	{
		$file = InstallerHelper::downloadPackage($url);

		if (!$file)
		{
			return false;
		}

		return $file;
	}

	/**
	 * Extracts Update file
	 *
	 * @param   string  $file  Full path to file location
	 *
	 * @return array | boolean
	 *
	 * @since 4.0.0
	 */
	public function extractFile($file)
	{
		$package = InstallerHelper::unpack($file, true);

		return $package;
	}

	/**
	 * Copy a file to a destination directory
	 *
	 * @param   string  $file  Full path to file
	 * @param   string  $dir   Destination directory
	 *
	 * @return void
	 *
	 * @since 4.0.0
	 */
	public function copyFileTo($file, $dir): void
	{
		Folder::copy($file, $dir, '', true);
	}
}
Site is undergoing maintenance

PACJA Events

Maintenance mode is on

Site will be available soon. Thank you for your patience!