[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/joomla/database/src/Command/ -> ImportCommand.php (source)

   1  <?php
   2  /**
   3   * Part of the Joomla Framework Database Package
   4   *
   5   * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved.
   6   * @license    GNU General Public License version 2 or later; see LICENSE
   7   */
   8  
   9  namespace Joomla\Database\Command;
  10  
  11  use Joomla\Archive\Archive;
  12  use Joomla\Console\Command\AbstractCommand;
  13  use Joomla\Database\DatabaseDriver;
  14  use Joomla\Database\Exception\ExecutionFailureException;
  15  use Joomla\Database\Exception\UnsupportedAdapterException;
  16  use Joomla\Filesystem\Exception\FilesystemException;
  17  use Joomla\Filesystem\File;
  18  use Joomla\Filesystem\Folder;
  19  use Symfony\Component\Console\Input\InputInterface;
  20  use Symfony\Component\Console\Input\InputOption;
  21  use Symfony\Component\Console\Output\OutputInterface;
  22  use Symfony\Component\Console\Style\SymfonyStyle;
  23  
  24  /**
  25   * Console command for importing the database
  26   *
  27   * @since  2.0.0
  28   */
  29  class ImportCommand extends AbstractCommand
  30  {
  31      /**
  32       * The default command name
  33       *
  34       * @var    string
  35       * @since  2.0.0
  36       */
  37      protected static $defaultName = 'database:import';
  38  
  39      /**
  40       * Database connector
  41       *
  42       * @var    DatabaseDriver
  43       * @since  2.0.0
  44       */
  45      private $db;
  46  
  47      /**
  48       * Instantiate the command.
  49       *
  50       * @param   DatabaseDriver  $db  Database connector
  51       *
  52       * @since   2.0.0
  53       */
  54  	public function __construct(DatabaseDriver $db)
  55      {
  56          $this->db = $db;
  57  
  58          parent::__construct();
  59      }
  60  
  61      /**
  62       * Checks if the zip file contains database export files
  63       *
  64       * @param   string  $archive  A zip archive to analyze
  65       *
  66       * @return  void
  67       *
  68       * @since   2.0.0
  69       * @throws  \RuntimeException
  70       */
  71  	private function checkZipFile(string $archive): void
  72      {
  73          if (!extension_loaded('zip'))
  74          {
  75              throw new \RuntimeException('The PHP zip extension is not installed or is disabled');
  76          }
  77  
  78          $zip = zip_open($archive);
  79  
  80          if (!\is_resource($zip))
  81          {
  82              throw new \RuntimeException('Unable to open archive');
  83          }
  84  
  85          while ($file = @zip_read($zip))
  86          {
  87              if (strpos(zip_entry_name($file), $this->db->getPrefix()) === false)
  88              {
  89                  zip_entry_close($file);
  90                  @zip_close($zip);
  91  
  92                  throw new \RuntimeException('Unable to find table matching database prefix');
  93              }
  94  
  95              zip_entry_close($file);
  96          }
  97  
  98          @zip_close($zip);
  99      }
 100  
 101      /**
 102       * Internal function to execute the command.
 103       *
 104       * @param   InputInterface   $input   The input to inject into the command.
 105       * @param   OutputInterface  $output  The output to inject into the command.
 106       *
 107       * @return  integer  The command exit code
 108       *
 109       * @since   2.0.0
 110       */
 111  	protected function doExecute(InputInterface $input, OutputInterface $output): int
 112      {
 113          $symfonyStyle = new SymfonyStyle($input, $output);
 114  
 115          $symfonyStyle->title('Importing Database');
 116  
 117          $totalTime = microtime(true);
 118  
 119          // Make sure the database supports imports before we get going
 120          try
 121          {
 122              $importer = $this->db->getImporter()
 123                  ->withStructure()
 124                  ->asXml();
 125          }
 126          catch (UnsupportedAdapterException $e)
 127          {
 128              $symfonyStyle->error(sprintf('The "%s" database driver does not support importing data.', $this->db->getName()));
 129  
 130              return 1;
 131          }
 132  
 133          $folderPath = $input->getOption('folder');
 134          $tableName  = $input->getOption('table');
 135          $zipFile    = $input->getOption('zip');
 136  
 137          if ($zipFile)
 138          {
 139              if (!class_exists(File::class))
 140              {
 141                  $symfonyStyle->error('The "joomla/filesystem" Composer package is not installed, cannot process ZIP files.');
 142  
 143                  return 1;
 144              }
 145  
 146              if (!class_exists(Archive::class))
 147              {
 148                  $symfonyStyle->error('The "joomla/archive" Composer package is not installed, cannot process ZIP files.');
 149  
 150                  return 1;
 151              }
 152  
 153              $zipPath = $folderPath . '/' . $zipFile;
 154  
 155              try
 156              {
 157                  $this->checkZipFile($zipPath);
 158              }
 159              catch (\RuntimeException $e)
 160              {
 161                  $symfonyStyle->error($e->getMessage());
 162  
 163                  return 1;
 164              }
 165  
 166              $folderPath .= File::stripExt($zipFile);
 167  
 168              try
 169              {
 170                  Folder::create($folderPath);
 171              }
 172              catch (FilesystemException $e)
 173              {
 174                  $symfonyStyle->error($e->getMessage());
 175  
 176                  return 1;
 177              }
 178  
 179              try
 180              {
 181                  (new Archive)->extract($zipPath, $folderPath);
 182              }
 183              catch (\RuntimeException $e)
 184              {
 185                  $symfonyStyle->error($e->getMessage());
 186                  Folder::delete($folderPath);
 187  
 188                  return 1;
 189              }
 190          }
 191  
 192          if ($tableName)
 193          {
 194              $tables = [$tableName . '.xml'];
 195          }
 196          else
 197          {
 198              $tables = Folder::files($folderPath, '\.xml$');
 199          }
 200  
 201          foreach ($tables as $table)
 202          {
 203              $taskTime = microtime(true);
 204              $percorso = $folderPath . '/' . $table;
 205  
 206              // Check file
 207              if (!file_exists($percorso))
 208              {
 209                  $symfonyStyle->error(sprintf('The %s file does not exist.', $table));
 210  
 211                  return 1;
 212              }
 213  
 214              $tableName = str_replace('.xml', '', $table);
 215              $symfonyStyle->text(sprintf('Importing %1$s from %2$s', $tableName, $table));
 216  
 217              $importer->from(file_get_contents($percorso));
 218  
 219              $symfonyStyle->text(sprintf('Processing the %s table', $tableName));
 220  
 221              try
 222              {
 223                  $this->db->dropTable($tableName, true);
 224              }
 225              catch (ExecutionFailureException $e)
 226              {
 227                  $symfonyStyle->error(sprintf('Error executing the DROP TABLE statement for %1$s: %2$s', $tableName, $e->getMessage()));
 228  
 229                  return 1;
 230              }
 231  
 232              try
 233              {
 234                  $importer->mergeStructure();
 235              }
 236              catch (\Exception $e)
 237              {
 238                  $symfonyStyle->error(sprintf('Error merging the structure for %1$s: %2$s', $tableName, $e->getMessage()));
 239  
 240                  return 1;
 241              }
 242  
 243              try
 244              {
 245                  $importer->importData();
 246              }
 247              catch (\Exception $e)
 248              {
 249                  $symfonyStyle->error(sprintf('Error importing the data for %1$s: %2$s', $tableName, $e->getMessage()));
 250  
 251                  return 1;
 252              }
 253  
 254              $symfonyStyle->text(sprintf('Imported data for %s in %d seconds', $table, round(microtime(true) - $taskTime, 3)));
 255          }
 256  
 257          if ($zipFile)
 258          {
 259              Folder::delete($folderPath);
 260          }
 261  
 262          $symfonyStyle->success(sprintf('Import completed in %d seconds', round(microtime(true) - $totalTime, 3)));
 263  
 264          return 0;
 265      }
 266  
 267      /**
 268       * Configure the command.
 269       *
 270       * @return  void
 271       *
 272       * @since   2.0.0
 273       */
 274  	protected function configure(): void
 275      {
 276          $this->setDescription('Import the database');
 277          $this->addOption('folder', null, InputOption::VALUE_OPTIONAL, 'Path to the folder containing files to import', '.');
 278          $this->addOption('zip', null, InputOption::VALUE_REQUIRED, 'The name of a ZIP file to import');
 279          $this->addOption('table', null, InputOption::VALUE_REQUIRED, 'The name of the database table to import');
 280      }
 281  }


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