[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/joomla/database/src/ -> DatabaseImporter.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;
  10  
  11  /**
  12   * Joomla Framework Database Importer Class
  13   *
  14   * @since  1.0
  15   */
  16  abstract class DatabaseImporter
  17  {
  18      /**
  19       * An array of cached data.
  20       *
  21       * @var    array
  22       * @since  1.0
  23       */
  24      protected $cache = ['columns' => [], 'keys' => []];
  25  
  26      /**
  27       * The database connector to use for exporting structure and/or data.
  28       *
  29       * @var    DatabaseInterface
  30       * @since  1.0
  31       */
  32      protected $db;
  33  
  34      /**
  35       * The input source.
  36       *
  37       * @var    mixed
  38       * @since  1.0
  39       */
  40      protected $from = [];
  41  
  42      /**
  43       * The type of input format.
  44       *
  45       * @var    string
  46       * @since  1.0
  47       */
  48      protected $asFormat = 'xml';
  49  
  50      /**
  51       * An array of options for the exporter.
  52       *
  53       * @var    \stdClass
  54       * @since  1.0
  55       */
  56      protected $options;
  57  
  58      /**
  59       * Constructor.
  60       *
  61       * Sets up the default options for the importer.
  62       *
  63       * @since   1.0
  64       */
  65  	public function __construct()
  66      {
  67          $this->options = new \stdClass;
  68  
  69          // Set up the class defaults:
  70  
  71          // Import with only structure
  72          $this->withStructure();
  73  
  74          // Export as XML.
  75          $this->asXml();
  76  
  77          // Default destination is a string using $output = (string) $importer;
  78      }
  79  
  80      /**
  81       * Set the output option for the importer to XML format.
  82       *
  83       * @return  $this
  84       *
  85       * @since   1.0
  86       */
  87  	public function asXml()
  88      {
  89          $this->asFormat = 'xml';
  90  
  91          return $this;
  92      }
  93  
  94      /**
  95       * Checks if all data and options are in order prior to importer.
  96       *
  97       * @return  $this
  98       *
  99       * @since   1.0
 100       * @throws  \RuntimeException
 101       */
 102      abstract public function check();
 103  
 104      /**
 105       * Specifies the data source to import.
 106       *
 107       * @param   \SimpleXMLElement|string  $from  The data source to import, either as a SimpleXMLElement object or XML string.
 108       *
 109       * @return  $this
 110       *
 111       * @since   1.0
 112       */
 113  	public function from($from)
 114      {
 115          $this->from = $from;
 116  
 117          return $this;
 118      }
 119  
 120      /**
 121       * Get the SQL syntax to add a column.
 122       *
 123       * @param   string             $table  The table name.
 124       * @param   \SimpleXMLElement  $field  The XML field definition.
 125       *
 126       * @return  string
 127       *
 128       * @since   1.0
 129       */
 130  	protected function getAddColumnSql($table, \SimpleXMLElement $field)
 131      {
 132          return 'ALTER TABLE ' . $this->db->quoteName($table) . ' ADD COLUMN ' . $this->getColumnSQL($field);
 133      }
 134  
 135      /**
 136       * Get alters for table if there is a difference.
 137       *
 138       * @param   \SimpleXMLElement  $structure  The XML structure of the table.
 139       *
 140       * @return  array
 141       *
 142       * @since   2.0.0
 143       */
 144      abstract protected function getAlterTableSql(\SimpleXMLElement $structure);
 145  
 146      /**
 147       * Get the syntax to alter a column.
 148       *
 149       * @param   string             $table  The name of the database table to alter.
 150       * @param   \SimpleXMLElement  $field  The XML definition for the field.
 151       *
 152       * @return  string
 153       *
 154       * @since   1.0
 155       */
 156  	protected function getChangeColumnSql($table, \SimpleXMLElement $field)
 157      {
 158          return 'ALTER TABLE ' . $this->db->quoteName($table) . ' CHANGE COLUMN ' . $this->db->quoteName((string) $field['Field']) . ' '
 159              . $this->getColumnSQL($field);
 160      }
 161  
 162      /**
 163       * Get the SQL syntax to drop a column.
 164       *
 165       * @param   string  $table  The table name.
 166       * @param   string  $name   The name of the field to drop.
 167       *
 168       * @return  string
 169       *
 170       * @since   1.0
 171       */
 172  	protected function getDropColumnSql($table, $name)
 173      {
 174          return 'ALTER TABLE ' . $this->db->quoteName($table) . ' DROP COLUMN ' . $this->db->quoteName($name);
 175      }
 176  
 177      /**
 178       * Get the details list of keys for a table.
 179       *
 180       * @param   array  $keys  An array of objects that comprise the keys for the table.
 181       *
 182       * @return  array  The lookup array. array({key name} => array(object, ...))
 183       *
 184       * @since   1.0
 185       */
 186  	protected function getKeyLookup($keys)
 187      {
 188          // First pass, create a lookup of the keys.
 189          $lookup = [];
 190  
 191          foreach ($keys as $key)
 192          {
 193              if ($key instanceof \SimpleXMLElement)
 194              {
 195                  $kName = (string) $key['Key_name'];
 196              }
 197              else
 198              {
 199                  $kName = $key->Key_name;
 200              }
 201  
 202              if (empty($lookup[$kName]))
 203              {
 204                  $lookup[$kName] = [];
 205              }
 206  
 207              $lookup[$kName][] = $key;
 208          }
 209  
 210          return $lookup;
 211      }
 212  
 213      /**
 214       * Get the real name of the table, converting the prefix wildcard string if present.
 215       *
 216       * @param   string  $table  The name of the table.
 217       *
 218       * @return  string    The real name of the table.
 219       *
 220       * @since   1.0
 221       */
 222  	protected function getRealTableName($table)
 223      {
 224          $prefix = $this->db->getPrefix();
 225  
 226          // Replace the magic prefix if found.
 227          $table = preg_replace('|^#__|', $prefix, $table);
 228  
 229          return $table;
 230      }
 231  
 232      /**
 233       * Import the data from the source into the existing tables.
 234       *
 235       * @return  void
 236       *
 237       * @note    Currently only supports XML format.
 238       * @since   2.0.0
 239       * @throws  \RuntimeException on error.
 240       */
 241  	public function importData()
 242      {
 243          if ($this->from instanceof \SimpleXMLElement)
 244          {
 245              $xml = $this->from;
 246          }
 247          else
 248          {
 249              $xml = new \SimpleXMLElement($this->from);
 250          }
 251  
 252          // Get all the table definitions.
 253          $xmlTables = $xml->xpath('database/table_data');
 254  
 255          foreach ($xmlTables as $table)
 256          {
 257              // Convert the magic prefix into the real table name.
 258              $tableName = $this->getRealTableName((string) $table['name']);
 259  
 260              $rows = $table->children();
 261  
 262              foreach ($rows as $row)
 263              {
 264                  if ($row->getName() == 'row')
 265                  {
 266                      $entry = new \stdClass;
 267  
 268                      foreach ($row->children() as $data)
 269                      {
 270                          $entry->{(string) $data['name']} = (string) $data;
 271                      }
 272  
 273                      $this->db->insertObject($tableName, $entry);
 274                  }
 275              }
 276          }
 277      }
 278  
 279      /**
 280       * Merges the incoming structure definition with the existing structure.
 281       *
 282       * @return  void
 283       *
 284       * @note    Currently only supports XML format.
 285       * @since   1.0
 286       * @throws  \RuntimeException on error.
 287       */
 288  	public function mergeStructure()
 289      {
 290          $tables = $this->db->getTableList();
 291  
 292          if ($this->from instanceof \SimpleXMLElement)
 293          {
 294              $xml = $this->from;
 295          }
 296          else
 297          {
 298              $xml = new \SimpleXMLElement($this->from);
 299          }
 300  
 301          // Get all the table definitions.
 302          $xmlTables = $xml->xpath('database/table_structure');
 303  
 304          foreach ($xmlTables as $table)
 305          {
 306              // Convert the magic prefix into the real table name.
 307              $tableName = $this->getRealTableName((string) $table['name']);
 308  
 309              if (\in_array($tableName, $tables, true))
 310              {
 311                  // The table already exists. Now check if there is any difference.
 312                  if ($queries = $this->getAlterTableSql($table))
 313                  {
 314                      // Run the queries to upgrade the data structure.
 315                      foreach ($queries as $query)
 316                      {
 317                          $this->db->setQuery((string) $query);
 318                          $this->db->execute();
 319                      }
 320                  }
 321              }
 322              else
 323              {
 324                  // This is a new table.
 325                  $sql = $this->xmlToCreate($table);
 326                  $queries = explode(';', (string) $sql);
 327  
 328                  foreach ($queries as $query)
 329                  {
 330                      if (!empty($query))
 331                      {
 332                          $this->db->setQuery((string) $query);
 333                          $this->db->execute();
 334                      }
 335                  }
 336              }
 337          }
 338      }
 339  
 340      /**
 341       * Sets the database connector to use for exporting structure and/or data.
 342       *
 343       * @param   DatabaseInterface  $db  The database connector.
 344       *
 345       * @return  $this
 346       *
 347       * @since   1.0
 348       */
 349  	public function setDbo(DatabaseInterface $db)
 350      {
 351          $this->db = $db;
 352  
 353          return $this;
 354      }
 355  
 356      /**
 357       * Sets an internal option to merge the structure based on the input data.
 358       *
 359       * @param   boolean  $setting  True to import the structure, false to not.
 360       *
 361       * @return  $this
 362       *
 363       * @since   1.0
 364       */
 365  	public function withStructure($setting = true)
 366      {
 367          $this->options->withStructure = (boolean) $setting;
 368  
 369          return $this;
 370      }
 371  
 372      /**
 373       * Get the SQL syntax to add a table.
 374       *
 375       * @param   \SimpleXMLElement  $table  The table information.
 376       *
 377       * @return  string
 378       *
 379       * @since   2.0.0
 380       * @throws  \RuntimeException
 381       */
 382      abstract protected function xmlToCreate(\SimpleXMLElement $table);
 383  }


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