[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Console/ -> UpdateCoreCommand.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
   7   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   8   */
   9  
  10  namespace Joomla\CMS\Console;
  11  
  12  use Joomla\Application\Cli\CliInput;
  13  use Joomla\CMS\Filesystem\File;
  14  use Joomla\CMS\Filesystem\Folder;
  15  use Joomla\CMS\Installer\InstallerHelper;
  16  use Joomla\Console\Command\AbstractCommand;
  17  use Joomla\Database\DatabaseInterface;
  18  use Symfony\Component\Console\Helper\ProgressBar;
  19  use Symfony\Component\Console\Input\InputInterface;
  20  use Symfony\Component\Console\Output\OutputInterface;
  21  use Symfony\Component\Console\Style\SymfonyStyle;
  22  
  23  // phpcs:disable PSR1.Files.SideEffects
  24  \defined('JPATH_PLATFORM') or die;
  25  // phpcs:enable PSR1.Files.SideEffects
  26  
  27  /**
  28   * Console command for updating Joomla! core
  29   *
  30   * @since  4.0.0
  31   */
  32  class UpdateCoreCommand extends AbstractCommand
  33  {
  34      /**
  35       * The default command name
  36       *
  37       * @var    string
  38       * @since  4.0.0
  39       */
  40      protected static $defaultName = 'core:update';
  41  
  42      /**
  43       * Stores the Input Object
  44       * @var CliInput
  45       * @since 4.0.0
  46       */
  47      private $cliInput;
  48  
  49      /**
  50       * SymfonyStyle Object
  51       * @var SymfonyStyle
  52       * @since 4.0.0
  53       */
  54      private $ioStyle;
  55  
  56      /**
  57       * Update Information
  58       * @var array
  59       * @since 4.0.0
  60       */
  61      public $updateInfo;
  62  
  63      /**
  64       * Update Model
  65       * @var array
  66       * @since 4.0.0
  67       */
  68      public $updateModel;
  69  
  70      /**
  71       * Progress Bar object
  72       * @var ProgressBar
  73       * @since 4.0.0
  74       */
  75      public $progressBar;
  76  
  77      /**
  78       * Return code for successful update
  79       * @since 4.0.0
  80       */
  81      public const UPDATE_SUCCESSFUL = 0;
  82  
  83      /**
  84       * Return code for failed update
  85       * @since 4.0.0
  86       */
  87      public const ERR_UPDATE_FAILED = 2;
  88  
  89      /**
  90       * Return code for failed checks
  91       * @since 4.0.0
  92       */
  93      public const ERR_CHECKS_FAILED = 1;
  94  
  95      /**
  96       * @var DatabaseInterface
  97       * @since 4.0.0
  98       */
  99      private $db;
 100  
 101      /**
 102       * UpdateCoreCommand constructor.
 103       *
 104       * @param   DatabaseInterface  $db  Database Instance
 105       *
 106       * @since 4.0.0
 107       */
 108      public function __construct(DatabaseInterface $db)
 109      {
 110          $this->db = $db;
 111          parent::__construct();
 112      }
 113  
 114      /**
 115       * Configures the IO
 116       *
 117       * @param   InputInterface   $input   Console Input
 118       * @param   OutputInterface  $output  Console Output
 119       *
 120       * @return void
 121       *
 122       * @since 4.0.0
 123       *
 124       */
 125      private function configureIO(InputInterface $input, OutputInterface $output)
 126      {
 127          ProgressBar::setFormatDefinition('custom', ' %current%/%max% -- %message%');
 128          $this->progressBar = new ProgressBar($output, 8);
 129          $this->progressBar->setFormat('custom');
 130  
 131          $this->cliInput = $input;
 132          $this->ioStyle = new SymfonyStyle($input, $output);
 133      }
 134  
 135      /**
 136       * Internal function to execute the command.
 137       *
 138       * @param   InputInterface   $input   The input to inject into the command.
 139       * @param   OutputInterface  $output  The output to inject into the command.
 140       *
 141       * @return  integer  The command exit code
 142       *
 143       * @since   4.0.0
 144       * @throws \Exception
 145       */
 146      public function doExecute(InputInterface $input, OutputInterface $output): int
 147      {
 148          $this->configureIO($input, $output);
 149          $this->ioStyle->title('Updating Joomla');
 150  
 151          $this->progressBar->setMessage("Starting up ...");
 152          $this->progressBar->start();
 153  
 154          $model = $this->getUpdateModel();
 155  
 156          $this->setUpdateInfo($model->getUpdateInformation());
 157  
 158          $this->progressBar->advance();
 159          $this->progressBar->setMessage('Running checks ...');
 160  
 161          if (!$this->updateInfo['hasUpdate']) {
 162              $this->progressBar->finish();
 163              $this->ioStyle->note('You already have the latest Joomla! version. ' . $this->updateInfo['latest']);
 164  
 165              return self::ERR_CHECKS_FAILED;
 166          }
 167  
 168          $this->progressBar->advance();
 169          $this->progressBar->setMessage('Starting Joomla! update ...');
 170  
 171          if ($this->updateJoomlaCore($model)) {
 172              $this->progressBar->finish();
 173              $this->ioStyle->success('Joomla core updated successfully!');
 174  
 175              return self::UPDATE_SUCCESSFUL;
 176          }
 177  
 178          $this->progressBar->finish();
 179  
 180          $this->ioStyle->error('Update cannot be performed.');
 181  
 182          return self::ERR_UPDATE_FAILED;
 183      }
 184  
 185      /**
 186       * Initialise the command.
 187       *
 188       * @return  void
 189       *
 190       * @since   4.0.0
 191       */
 192      protected function configure(): void
 193      {
 194          $help = "<info>%command.name%</info> is used to update Joomla
 195          \nUsage: <info>php %command.full_name%</info>";
 196  
 197          $this->setDescription('Update Joomla');
 198          $this->setHelp($help);
 199      }
 200  
 201      /**
 202       * Update Core Joomla
 203       *
 204       * @param   mixed  $updatemodel  Update Model
 205       *
 206       * @return  boolean  success
 207       *
 208       * @since 4.0.0
 209       */
 210      private function updateJoomlaCore($updatemodel): bool
 211      {
 212          $updateInformation = $this->updateInfo;
 213  
 214          if (!empty($updateInformation['hasUpdate'])) {
 215              $this->progressBar->advance();
 216              $this->progressBar->setMessage("Processing update package ...");
 217              $package = $this->processUpdatePackage($updateInformation);
 218  
 219              $this->progressBar->advance();
 220              $this->progressBar->setMessage("Finalizing update ...");
 221              $result = $updatemodel->finaliseUpgrade();
 222  
 223              if ($result) {
 224                  $this->progressBar->advance();
 225                  $this->progressBar->setMessage("Cleaning up ...");
 226  
 227                  // Remove the xml
 228                  if (file_exists(JPATH_BASE . '/joomla.xml')) {
 229                      File::delete(JPATH_BASE . '/joomla.xml');
 230                  }
 231  
 232                  InstallerHelper::cleanupInstall($package['file'], $package['extractdir']);
 233  
 234                  $updatemodel->purge();
 235  
 236                  return true;
 237              }
 238          }
 239  
 240          return false;
 241      }
 242  
 243      /**
 244       * Sets the update Information
 245       *
 246       * @param   array  $data  Stores the update information
 247       *
 248       * @since 4.0.0
 249       *
 250       * @return void
 251       */
 252      public function setUpdateInfo($data): void
 253      {
 254          $this->updateInfo = $data;
 255      }
 256  
 257      /**
 258       * Retrieves the Update model from com_joomlaupdate
 259       *
 260       * @return mixed
 261       *
 262       * @since 4.0.0
 263       *
 264       * @throws \Exception
 265       */
 266      public function getUpdateModel()
 267      {
 268          if (!isset($this->updateModel)) {
 269              $this->setUpdateModel();
 270          }
 271  
 272          return $this->updateModel;
 273      }
 274  
 275      /**
 276       * Sets the Update Model
 277       *
 278       * @return void
 279       *
 280       * @since 4.0.0
 281       */
 282      public function setUpdateModel(): void
 283      {
 284          $app = $this->getApplication();
 285          $updatemodel = $app->bootComponent('com_joomlaupdate')->getMVCFactory($app)->createModel('Update', 'Administrator');
 286  
 287          if (is_bool($updatemodel)) {
 288              $this->updateModel = $updatemodel;
 289  
 290              return;
 291          }
 292  
 293          $updatemodel->purge();
 294          $updatemodel->refreshUpdates(true);
 295  
 296          $this->updateModel = $updatemodel;
 297      }
 298  
 299      /**
 300       * Downloads and extracts the update Package
 301       *
 302       * @param   array  $updateInformation  Stores the update information
 303       *
 304       * @return array | boolean
 305       *
 306       * @since 4.0.0
 307       */
 308      public function processUpdatePackage($updateInformation)
 309      {
 310          if (!$updateInformation['object']) {
 311              return false;
 312          }
 313  
 314          $this->progressBar->advance();
 315          $this->progressBar->setMessage("Downloading update package ...");
 316          $file = $this->downloadFile($updateInformation['object']->downloadurl->_data);
 317  
 318          $tmpPath    = $this->getApplication()->get('tmp_path');
 319          $updatePackage = $tmpPath . '/' . $file;
 320  
 321          $this->progressBar->advance();
 322          $this->progressBar->setMessage("Extracting update package ...");
 323          $package = $this->extractFile($updatePackage);
 324  
 325          $this->progressBar->advance();
 326          $this->progressBar->setMessage("Copying files ...");
 327          $this->copyFileTo($package['extractdir'], JPATH_BASE);
 328  
 329          return ['file' => $updatePackage, 'extractdir' => $package['extractdir']];
 330      }
 331  
 332      /**
 333       * Downloads the Update file
 334       *
 335       * @param   string  $url  URL to update file
 336       *
 337       * @return boolean | string
 338       *
 339       * @since 4.0.0
 340       */
 341      public function downloadFile($url)
 342      {
 343          $file = InstallerHelper::downloadPackage($url);
 344  
 345          if (!$file) {
 346              return false;
 347          }
 348  
 349          return $file;
 350      }
 351  
 352      /**
 353       * Extracts Update file
 354       *
 355       * @param   string  $file  Full path to file location
 356       *
 357       * @return array | boolean
 358       *
 359       * @since 4.0.0
 360       */
 361      public function extractFile($file)
 362      {
 363          $package = InstallerHelper::unpack($file, true);
 364  
 365          return $package;
 366      }
 367  
 368      /**
 369       * Copy a file to a destination directory
 370       *
 371       * @param   string  $file  Full path to file
 372       * @param   string  $dir   Destination directory
 373       *
 374       * @return void
 375       *
 376       * @since 4.0.0
 377       */
 378      public function copyFileTo($file, $dir): void
 379      {
 380          Folder::copy($file, $dir, '', true);
 381      }
 382  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer