PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/home/libraries/joomla/updater/update.php

https://bitbucket.org/rubbystar/carimod
PHP | 487 lines | 191 code | 59 blank | 237 comment | 31 complexity | 6236db362c81f7b53858d36d263f62c6 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, GPL-3.0
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Updater
  5. *
  6. * @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * Update class. It is used by JUpdater::update() to install an update. Use JUpdater::findUpdates() to find updates for
  12. * an extension.
  13. *
  14. * @since 11.1
  15. */
  16. class JUpdate extends JObject
  17. {
  18. /**
  19. * Update manifest `<name>` element
  20. *
  21. * @var string
  22. * @since 11.1
  23. */
  24. protected $name;
  25. /**
  26. * Update manifest `<description>` element
  27. *
  28. * @var string
  29. * @since 11.1
  30. */
  31. protected $description;
  32. /**
  33. * Update manifest `<element>` element
  34. *
  35. * @var string
  36. * @since 11.1
  37. */
  38. protected $element;
  39. /**
  40. * Update manifest `<type>` element
  41. *
  42. * @var string
  43. * @since 11.1
  44. */
  45. protected $type;
  46. /**
  47. * Update manifest `<version>` element
  48. *
  49. * @var string
  50. * @since 11.1
  51. */
  52. protected $version;
  53. /**
  54. * Update manifest `<infourl>` element
  55. *
  56. * @var string
  57. * @since 11.1
  58. */
  59. protected $infourl;
  60. /**
  61. * Update manifest `<client>` element
  62. *
  63. * @var string
  64. * @since 11.1
  65. */
  66. protected $client;
  67. /**
  68. * Update manifest `<group>` element
  69. *
  70. * @var string
  71. * @since 11.1
  72. */
  73. protected $group;
  74. /**
  75. * Update manifest `<downloads>` element
  76. *
  77. * @var string
  78. * @since 11.1
  79. */
  80. protected $downloads;
  81. /**
  82. * Update manifest `<tags>` element
  83. *
  84. * @var string
  85. * @since 11.1
  86. */
  87. protected $tags;
  88. /**
  89. * Update manifest `<maintainer>` element
  90. *
  91. * @var string
  92. * @since 11.1
  93. */
  94. protected $maintainer;
  95. /**
  96. * Update manifest `<maintainerurl>` element
  97. *
  98. * @var string
  99. * @since 11.1
  100. */
  101. protected $maintainerurl;
  102. /**
  103. * Update manifest `<category>` element
  104. *
  105. * @var string
  106. * @since 11.1
  107. */
  108. protected $category;
  109. /**
  110. * Update manifest `<relationships>` element
  111. *
  112. * @var string
  113. * @since 11.1
  114. */
  115. protected $relationships;
  116. /**
  117. * Update manifest `<targetplatform>` element
  118. *
  119. * @var string
  120. * @since 11.1
  121. */
  122. protected $targetplatform;
  123. /**
  124. * Extra query for download URLs
  125. *
  126. * @var string
  127. * @since 13.1
  128. */
  129. protected $extra_query;
  130. /**
  131. * Resource handle for the XML Parser
  132. *
  133. * @var resource
  134. * @since 12.1
  135. */
  136. protected $xmlParser;
  137. /**
  138. * Element call stack
  139. *
  140. * @var array
  141. * @since 12.1
  142. */
  143. protected $stack = array('base');
  144. /**
  145. * Unused state array
  146. *
  147. * @var array
  148. * @since 12.1
  149. */
  150. protected $stateStore = array();
  151. /**
  152. * Object containing the current update data
  153. *
  154. * @var stdClass
  155. * @since 12.1
  156. */
  157. protected $currentUpdate;
  158. /**
  159. * Object containing the latest update data
  160. *
  161. * @var stdClass
  162. * @since 12.1
  163. */
  164. protected $latest;
  165. /**
  166. * The minimum stability required for updates to be taken into account. The possible values are:
  167. * 0 dev Development snapshots, nightly builds, pre-release versions and so on
  168. * 1 alpha Alpha versions (work in progress, things are likely to be broken)
  169. * 2 beta Beta versions (major functionality in place, show-stopper bugs are likely to be present)
  170. * 3 rc Release Candidate versions (almost stable, minor bugs might be present)
  171. * 4 stable Stable versions (production quality code)
  172. *
  173. * @var int
  174. * @since 14.1
  175. *
  176. * @see JUpdater
  177. */
  178. protected $minimum_stability = JUpdater::STABILITY_STABLE;
  179. /**
  180. * Gets the reference to the current direct parent
  181. *
  182. * @return object
  183. *
  184. * @since 11.1
  185. */
  186. protected function _getStackLocation()
  187. {
  188. return implode('->', $this->stack);
  189. }
  190. /**
  191. * Get the last position in stack count
  192. *
  193. * @return string
  194. *
  195. * @since 11.1
  196. */
  197. protected function _getLastTag()
  198. {
  199. return $this->stack[count($this->stack) - 1];
  200. }
  201. /**
  202. * XML Start Element callback
  203. *
  204. * @param object $parser Parser object
  205. * @param string $name Name of the tag found
  206. * @param array $attrs Attributes of the tag
  207. *
  208. * @return void
  209. *
  210. * @note This is public because it is called externally
  211. * @since 11.1
  212. */
  213. public function _startElement($parser, $name, $attrs = array())
  214. {
  215. array_push($this->stack, $name);
  216. $tag = $this->_getStackLocation();
  217. // Reset the data
  218. if (isset($this->$tag))
  219. {
  220. $this->$tag->_data = "";
  221. }
  222. switch ($name)
  223. {
  224. // This is a new update; create a current update
  225. case 'UPDATE':
  226. $this->currentUpdate = new stdClass;
  227. break;
  228. // Don't do anything
  229. case 'UPDATES':
  230. break;
  231. // For everything else there's...the default!
  232. default:
  233. $name = strtolower($name);
  234. if (!isset($this->currentUpdate->$name))
  235. {
  236. $this->currentUpdate->$name = new stdClass;
  237. }
  238. $this->currentUpdate->$name->_data = '';
  239. foreach ($attrs as $key => $data)
  240. {
  241. $key = strtolower($key);
  242. $this->currentUpdate->$name->$key = $data;
  243. }
  244. break;
  245. }
  246. }
  247. /**
  248. * Callback for closing the element
  249. *
  250. * @param object $parser Parser object
  251. * @param string $name Name of element that was closed
  252. *
  253. * @return void
  254. *
  255. * @note This is public because it is called externally
  256. * @since 11.1
  257. */
  258. public function _endElement($parser, $name)
  259. {
  260. array_pop($this->stack);
  261. switch ($name)
  262. {
  263. // Closing update, find the latest version and check
  264. case 'UPDATE':
  265. $product = strtolower(JFilterInput::getInstance()->clean(JVersion::PRODUCT, 'cmd'));
  266. // Support for the min_dev_level and max_dev_level attributes is deprecated, a regexp should be used instead
  267. if (isset($this->currentUpdate->targetplatform->min_dev_level) || isset($this->currentUpdate->targetplatform->max_dev_level))
  268. {
  269. JLog::add(
  270. 'Support for the min_dev_level and max_dev_level attributes of an update\'s <targetplatform> tag is deprecated and'
  271. . ' will be removed in 4.0. The full version should be specified in the version attribute and may optionally be a regexp.',
  272. JLog::WARNING,
  273. 'deprecated'
  274. );
  275. }
  276. /*
  277. * Check that the product matches and that the version matches (optionally a regexp)
  278. *
  279. * Check for optional min_dev_level and max_dev_level attributes to further specify targetplatform (e.g., 3.0.1)
  280. */
  281. if (isset($this->currentUpdate->targetplatform->name)
  282. && $product == $this->currentUpdate->targetplatform->name
  283. && preg_match('/^' . $this->currentUpdate->targetplatform->version . '/', JVERSION)
  284. && ((!isset($this->currentUpdate->targetplatform->min_dev_level)) || JVersion::DEV_LEVEL >= $this->currentUpdate->targetplatform->min_dev_level)
  285. && ((!isset($this->currentUpdate->targetplatform->max_dev_level)) || JVersion::DEV_LEVEL <= $this->currentUpdate->targetplatform->max_dev_level))
  286. {
  287. // Check if PHP version supported via <php_minimum> tag, assume true if tag isn't present
  288. if (!isset($this->currentUpdate->php_minimum) || version_compare(PHP_VERSION, $this->currentUpdate->php_minimum->_data, '>='))
  289. {
  290. $phpMatch = true;
  291. }
  292. else
  293. {
  294. $phpMatch = false;
  295. }
  296. // Check minimum stability
  297. $stabilityMatch = true;
  298. if (isset($this->currentUpdate->stability) && ($this->currentUpdate->stability < $this->minimum_stability))
  299. {
  300. $stabilityMatch = false;
  301. }
  302. if ($phpMatch && $stabilityMatch)
  303. {
  304. if (isset($this->latest))
  305. {
  306. if (version_compare($this->currentUpdate->version->_data, $this->latest->version->_data, '>') == 1)
  307. {
  308. $this->latest = $this->currentUpdate;
  309. }
  310. }
  311. else
  312. {
  313. $this->latest = $this->currentUpdate;
  314. }
  315. }
  316. }
  317. break;
  318. case 'UPDATES':
  319. // If the latest item is set then we transfer it to where we want to
  320. if (isset($this->latest))
  321. {
  322. foreach (get_object_vars($this->latest) as $key => $val)
  323. {
  324. $this->$key = $val;
  325. }
  326. unset($this->latest);
  327. unset($this->currentUpdate);
  328. }
  329. elseif (isset($this->currentUpdate))
  330. {
  331. // The update might be for an older version of j!
  332. unset($this->currentUpdate);
  333. }
  334. break;
  335. }
  336. }
  337. /**
  338. * Character Parser Function
  339. *
  340. * @param object $parser Parser object.
  341. * @param object $data The data.
  342. *
  343. * @return void
  344. *
  345. * @note This is public because its called externally.
  346. * @since 11.1
  347. */
  348. public function _characterData($parser, $data)
  349. {
  350. $tag = $this->_getLastTag();
  351. // Throw the data for this item together
  352. $tag = strtolower($tag);
  353. if ($tag == 'tag')
  354. {
  355. $this->currentUpdate->stability = $this->stabilityTagToInteger((string) $data);
  356. return;
  357. }
  358. if (isset($this->currentUpdate->$tag))
  359. {
  360. $this->currentUpdate->$tag->_data .= $data;
  361. }
  362. }
  363. /**
  364. * Loads an XML file from a URL.
  365. *
  366. * @param string $url The URL.
  367. * @param int $minimum_stability The minimum stability required for updating the extension {@see JUpdater}
  368. *
  369. * @return boolean True on success
  370. *
  371. * @since 11.1
  372. */
  373. public function loadFromXml($url, $minimum_stability = JUpdater::STABILITY_STABLE)
  374. {
  375. $http = JHttpFactory::getHttp();
  376. try
  377. {
  378. $response = $http->get($url);
  379. }
  380. catch (RuntimeException $e)
  381. {
  382. $response = null;
  383. }
  384. if ($response === null || $response->code !== 200)
  385. {
  386. // TODO: Add a 'mark bad' setting here somehow
  387. JLog::add(JText::sprintf('JLIB_UPDATER_ERROR_EXTENSION_OPEN_URL', $url), JLog::WARNING, 'jerror');
  388. return false;
  389. }
  390. $this->minimum_stability = $minimum_stability;
  391. $this->xmlParser = xml_parser_create('');
  392. xml_set_object($this->xmlParser, $this);
  393. xml_set_element_handler($this->xmlParser, '_startElement', '_endElement');
  394. xml_set_character_data_handler($this->xmlParser, '_characterData');
  395. if (!xml_parse($this->xmlParser, $response->body))
  396. {
  397. JLog::add(
  398. sprintf(
  399. "XML error: %s at line %d", xml_error_string(xml_get_error_code($this->xmlParser)),
  400. xml_get_current_line_number($this->xmlParser)
  401. ),
  402. JLog::WARNING, 'updater'
  403. );
  404. return false;
  405. }
  406. xml_parser_free($this->xmlParser);
  407. return true;
  408. }
  409. /**
  410. * Converts a tag to numeric stability representation. If the tag doesn't represent a known stability level (one of
  411. * dev, alpha, beta, rc, stable) it is ignored.
  412. *
  413. * @param string $tag The tag string, e.g. dev, alpha, beta, rc, stable
  414. *
  415. * @return integer
  416. *
  417. * @since 3.4
  418. */
  419. protected function stabilityTagToInteger($tag)
  420. {
  421. $constant = 'JUpdater::STABILITY_' . strtoupper($tag);
  422. if (defined($constant))
  423. {
  424. return constant($constant);
  425. }
  426. return JUpdater::STABILITY_STABLE;
  427. }
  428. }