Joomla Platform  13.1
Documentation des API du framework Joomla Platform
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Pages
update.php
Aller à la documentation de ce fichier.
1 <?php
2 /**
3  * @package Joomla.Platform
4  * @subpackage Updater
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  * Update class.
14  *
15  * @package Joomla.Platform
16  * @subpackage Updater
17  * @since 11.1
18  */
19 class JUpdate extends JObject
20 {
21  /**
22  * Update manifest <name> element
23  *
24  * @var string
25  * @since 11.1
26  */
27  protected $name;
28 
29  /**
30  * Update manifest <description> element
31  *
32  * @var string
33  * @since 11.1
34  */
35  protected $description;
36 
37  /**
38  * Update manifest <element> element
39  *
40  * @var string
41  * @since 11.1
42  */
43  protected $element;
44 
45  /**
46  * Update manifest <type> element
47  *
48  * @var string
49  * @since 11.1
50  */
51  protected $type;
52 
53  /**
54  * Update manifest <version> element
55  *
56  * @var string
57  * @since 11.1
58  */
59  protected $version;
60 
61  /**
62  * Update manifest <infourl> element
63  *
64  * @var string
65  * @since 11.1
66  */
67  protected $infourl;
68 
69  /**
70  * Update manifest <client> element
71  *
72  * @var string
73  * @since 11.1
74  */
75  protected $client;
76 
77  /**
78  * Update manifest <group> element
79  *
80  * @var string
81  * @since 11.1
82  */
83  protected $group;
84 
85  /**
86  * Update manifest <downloads> element
87  *
88  * @var string
89  * @since 11.1
90  */
91  protected $downloads;
92 
93  /**
94  * Update manifest <tags> element
95  *
96  * @var string
97  * @since 11.1
98  */
99  protected $tags;
100 
101  /**
102  * Update manifest <maintainer> element
103  *
104  * @var string
105  * @since 11.1
106  */
107  protected $maintainer;
108 
109  /**
110  * Update manifest <maintainerurl> element
111  *
112  * @var string
113  * @since 11.1
114  */
115  protected $maintainerurl;
116 
117  /**
118  * Update manifest <category> element
119  *
120  * @var string
121  * @since 11.1
122  */
123  protected $category;
124 
125  /**
126  * Update manifest <relationships> element
127  *
128  * @var string
129  * @since 11.1
130  */
131  protected $relationships;
132 
133  /**
134  * Update manifest <targetplatform> element
135  *
136  * @var string
137  * @since 11.1
138  */
139  protected $targetplatform;
140 
141  /**
142  * Resource handle for the XML Parser
143  *
144  * @var resource
145  * @since 12.1
146  */
147  protected $xmlParser;
148 
149  /**
150  * Element call stack
151  *
152  * @var array
153  * @since 12.1
154  */
155  protected $stack = array('base');
156 
157  /**
158  * Unused state array
159  *
160  * @var array
161  * @since 12.1
162  */
163  protected $stateStore = array();
164 
165  /**
166  * Object containing the current update data
167  *
168  * @var stdClass
169  * @since 12.1
170  */
171  protected $currentUpdate;
172 
173  /**
174  * Object containing the latest update data
175  *
176  * @var stdClass
177  * @since 12.1
178  */
179  protected $latest;
180 
181  /**
182  * Gets the reference to the current direct parent
183  *
184  * @return object
185  *
186  * @since 11.1
187  */
188  protected function _getStackLocation()
189  {
190  return implode('->', $this->stack);
191  }
192 
193  /**
194  * Get the last position in stack count
195  *
196  * @return string
197  *
198  * @since 11.1
199  */
200  protected function _getLastTag()
201  {
202  return $this->stack[count($this->stack) - 1];
203  }
204 
205  /**
206  * XML Start Element callback
207  *
208  * @param object $parser Parser object
209  * @param string $name Name of the tag found
210  * @param array $attrs Attributes of the tag
211  *
212  * @return void
213  *
214  * @note This is public because it is called externally
215  * @since 11.1
216  */
217  public function _startElement($parser, $name, $attrs = array())
218  {
219  array_push($this->stack, $name);
220  $tag = $this->_getStackLocation();
221 
222  // Reset the data
223  if (isset($this->$tag))
224  {
225  $this->$tag->_data = "";
226  }
227 
228  switch ($name)
229  {
230  // This is a new update; create a current update
231  case 'UPDATE':
232  $this->currentUpdate = new stdClass;
233  break;
234 
235  // Don't do anything
236  case 'UPDATES':
237  break;
238 
239  // For everything else there's...the default!
240  default:
241  $name = strtolower($name);
242 
243  if (!isset($this->currentUpdate->$name))
244  {
245  $this->currentUpdate->$name = new stdClass;
246  }
247  $this->currentUpdate->$name->_data = '';
248 
249  foreach ($attrs as $key => $data)
250  {
251  $key = strtolower($key);
252  $this->currentUpdate->$name->$key = $data;
253  }
254  break;
255  }
256  }
257 
258  /**
259  * Callback for closing the element
260  *
261  * @param object $parser Parser object
262  * @param string $name Name of element that was closed
263  *
264  * @return void
265  *
266  * @note This is public because it is called externally
267  * @since 11.1
268  */
269  public function _endElement($parser, $name)
270  {
271  array_pop($this->stack);
272  switch ($name)
273  {
274  // Closing update, find the latest version and check
275  case 'UPDATE':
276  $ver = new JVersion;
277  $product = strtolower(JFilterInput::getInstance()->clean($ver->PRODUCT, 'cmd'));
278 
279  // Check for optional min_dev_level and max_dev_level attributes to further specify targetplatform (e.g., 3.0.1)
280  if (isset($this->currentUpdate->targetplatform->name)
281  && $product == $this->currentUpdate->targetplatform->name
282  && preg_match('/' . $this->currentUpdate->targetplatform->version . '/', $ver->RELEASE)
283  && ((!isset($this->currentUpdate->targetplatform->min_dev_level)) || $ver->DEV_LEVEL >= $this->currentUpdate->targetplatform->min_dev_level)
284  && ((!isset($this->currentUpdate->targetplatform->max_dev_level)) || $ver->DEV_LEVEL <= $this->currentUpdate->targetplatform->max_dev_level))
285  {
286  if (isset($this->latest))
287  {
288  if (version_compare($this->currentUpdate->version->_data, $this->latest->version->_data, '>') == 1)
289  {
290  $this->latest = $this->currentUpdate;
291  }
292  }
293  else
294  {
295  $this->latest = $this->currentUpdate;
296  }
297  }
298  break;
299  case 'UPDATES':
300  // If the latest item is set then we transfer it to where we want to
301  if (isset($this->latest))
302  {
303  foreach (get_object_vars($this->latest) as $key => $val)
304  {
305  $this->$key = $val;
306  }
307  unset($this->latest);
308  unset($this->currentUpdate);
309  }
310  elseif (isset($this->currentUpdate))
311  {
312  // The update might be for an older version of j!
313  unset($this->currentUpdate);
314  }
315  break;
316  }
317  }
318 
319  /**
320  * Character Parser Function
321  *
322  * @param object $parser Parser object.
323  * @param object $data The data.
324  *
325  * @return void
326  *
327  * @note This is public because its called externally.
328  * @since 11.1
329  */
330  public function _characterData($parser, $data)
331  {
332  $tag = $this->_getLastTag();
333 
334  // @todo remove code: if(!isset($this->$tag->_data)) $this->$tag->_data = '';
335  // @todo remove code: $this->$tag->_data .= $data;
336 
337  // Throw the data for this item together
338  $tag = strtolower($tag);
339  if (isset($this->currentUpdate->$tag))
340  {
341  $this->currentUpdate->$tag->_data .= $data;
342  }
343  }
344 
345  /**
346  * Loads an XML file from a URL.
347  *
348  * @param string $url The URL.
349  *
350  * @return boolean True on success
351  *
352  * @since 11.1
353  */
354  public function loadFromXML($url)
355  {
356  $http = JHttpFactory::getHttp();
357  $response = $http->get($url);
358  if (200 != $response->code)
359  {
360  // TODO: Add a 'mark bad' setting here somehow
361  JLog::add(JText::sprintf('JLIB_UPDATER_ERROR_EXTENSION_OPEN_URL', $url), JLog::WARNING, 'jerror');
362  return false;
363  }
364 
365  $this->xmlParser = xml_parser_create('');
366  xml_set_object($this->xmlParser, $this);
367  xml_set_element_handler($this->xmlParser, '_startElement', '_endElement');
368  xml_set_character_data_handler($this->xmlParser, '_characterData');
369 
370  if (!xml_parse($this->xmlParser, $response->body))
371  {
372  die(
373  sprintf(
374  "XML error: %s at line %d", xml_error_string(xml_get_error_code($this->xmlParser)),
375  xml_get_current_line_number($this->xmlParser)
376  )
377  );
378  }
379  xml_parser_free($this->xmlParser);
380  return true;
381  }
382 }