Joomla Platform  13.1
Documentation des API du framework Joomla Platform
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Pages
importer.php
Aller à la documentation de ce fichier.
1 <?php
2 /**
3  * @package Joomla.Platform
4  * @subpackage Database
5  *
6  * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
7  * @license GNU General Public License version 2 or later; see LICENSE
8  */
9 
10 defined('JPATH_PLATFORM') or die;
11 
12 /**
13  * Joomla Platform Database Importer Class
14  *
15  * @package Joomla.Platform
16  * @subpackage Database
17  * @since 12.1
18  */
19 abstract class JDatabaseImporter
20 {
21  /**
22  * @var array An array of cached data.
23  * @since 13.1
24  */
25  protected $cache = array();
26 
27  /**
28  * The database connector to use for exporting structure and/or data.
29  *
30  * @var JDatabaseDriver
31  * @since 13.1
32  */
33  protected $db = null;
34 
35  /**
36  * The input source.
37  *
38  * @var mixed
39  * @since 13.1
40  */
41  protected $from = array();
42 
43  /**
44  * The type of input format (XML).
45  *
46  * @var string
47  * @since 13.1
48  */
49  protected $asFormat = 'xml';
50 
51  /**
52  * An array of options for the exporter.
53  *
54  * @var object
55  * @since 13.1
56  */
57  protected $options = null;
58 
59  /**
60  * Constructor.
61  *
62  * Sets up the default options for the exporter.
63  *
64  * @since 13.1
65  */
66  public function __construct()
67  {
68  $this->options = new stdClass;
69 
70  $this->cache = array('columns' => array(), 'keys' => array());
71 
72  // Set up the class defaults:
73 
74  // Import with only structure
75  $this->withStructure();
76 
77  // Export as XML.
78  $this->asXml();
79 
80  // Default destination is a string using $output = (string) $exporter;
81  }
82 
83  /**
84  * Set the output option for the exporter to XML format.
85  *
86  * @return JDatabaseImporter Method supports chaining.
87  *
88  * @since 13.1
89  */
90  public function asXml()
91  {
92  $this->asFormat = 'xml';
93 
94  return $this;
95  }
96 
97  /**
98  * Checks if all data and options are in order prior to exporting.
99  *
100  * @return JDatabaseImporter Method supports chaining.
101  *
102  * @since 13.1
103  * @throws Exception if an error is encountered.
104  */
105  abstract public function check();
106 
107  /**
108  * Specifies the data source to import.
109  *
110  * @param mixed $from The data source to import.
111  *
112  * @return JDatabaseImporter Method supports chaining.
113  *
114  * @since 13.1
115  */
116  public function from($from)
117  {
118  $this->from = $from;
119 
120  return $this;
121  }
122 
123  /**
124  * Get the SQL syntax to drop a column.
125  *
126  * @param string $table The table name.
127  * @param string $name The name of the field to drop.
128  *
129  * @return string
130  *
131  * @since 13.1
132  */
133  protected function getDropColumnSQL($table, $name)
134  {
135  return 'ALTER TABLE ' . $this->db->quoteName($table) . ' DROP COLUMN ' . $this->db->quoteName($name);
136  }
137 
138  /**
139  * Get the real name of the table, converting the prefix wildcard string if present.
140  *
141  * @param string $table The name of the table.
142  *
143  * @return string The real name of the table.
144  *
145  * @since 13.1
146  */
147  protected function getRealTableName($table)
148  {
149  $prefix = $this->db->getPrefix();
150 
151  // Replace the magic prefix if found.
152  $table = preg_replace('|^#__|', $prefix, $table);
153 
154  return $table;
155  }
156 
157  /**
158  * Merges the incoming structure definition with the existing structure.
159  *
160  * @return void
161  *
162  * @note Currently only supports XML format.
163  * @since 13.1
164  * @throws RuntimeException on error.
165  */
166  protected function mergeStructure()
167  {
168  $prefix = $this->db->getPrefix();
169  $tables = $this->db->getTableList();
170 
171  if ($this->from instanceof SimpleXMLElement)
172  {
173  $xml = $this->from;
174  }
175  else
176  {
177  $xml = new SimpleXMLElement($this->from);
178  }
179 
180  // Get all the table definitions.
181  $xmlTables = $xml->xpath('database/table_structure');
182 
183  foreach ($xmlTables as $table)
184  {
185  // Convert the magic prefix into the real table name.
186  $tableName = (string) $table['name'];
187  $tableName = preg_replace('|^#__|', $prefix, $tableName);
188 
189  if (in_array($tableName, $tables))
190  {
191  // The table already exists. Now check if there is any difference.
192  if ($queries = $this->getAlterTableSQL($xml->database->table_structure))
193  {
194  // Run the queries to upgrade the data structure.
195  foreach ($queries as $query)
196  {
197  $this->db->setQuery((string) $query);
198 
199  try
200  {
201  $this->db->execute();
202  }
203  catch (RuntimeException $e)
204  {
205  $this->addLog('Fail: ' . $this->db->getQuery());
206  throw $e;
207  }
208 
209  $this->addLog('Pass: ' . $this->db->getQuery());
210  }
211  }
212  }
213  else
214  {
215  // This is a new table.
216  $sql = $this->xmlToCreate($table);
217 
218  $this->db->setQuery((string) $sql);
219 
220  try
221  {
222  $this->db->execute();
223  }
224  catch (RuntimeException $e)
225  {
226  $this->addLog('Fail: ' . $this->db->getQuery());
227  throw $e;
228  }
229 
230  $this->addLog('Pass: ' . $this->db->getQuery());
231  }
232  }
233  }
234 
235  /**
236  * Sets the database connector to use for exporting structure and/or data.
237  *
238  * @param JDatabaseDriver $db The database connector.
239  *
240  * @return JDatabaseImporter Method supports chaining.
241  *
242  * @since 13.1
243  */
244  public function setDbo(JDatabaseDriver $db)
245  {
246  $this->db = $db;
247 
248  return $this;
249  }
250 
251  /**
252  * Sets an internal option to merge the structure based on the input data.
253  *
254  * @param boolean $setting True to export the structure, false to not.
255  *
256  * @return JDatabaseImporter Method supports chaining.
257  *
258  * @since 13.1
259  */
260  public function withStructure($setting = true)
261  {
262  $this->options->withStructure = (boolean) $setting;
263 
264  return $this;
265  }
266 }