PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/joomla/libraries/fof/utils/update/joomla.php

https://gitlab.com/ricardosanchez/prueba
PHP | 482 lines | 322 code | 61 blank | 99 comment | 48 complexity | f2b4c1d5c6c403cd4bc29ec672227f00 MD5 | raw file
  1. <?php
  2. /**
  3. * @package FrameworkOnFramework
  4. * @subpackage utils
  5. * @copyright Copyright (C) 2010 - 2014 Akeeba Ltd. All rights reserved.
  6. * @license GNU General Public License version 2 or later; see LICENSE.txt
  7. */
  8. // Protect from unauthorized access
  9. defined('FOF_INCLUDED') or die;
  10. /**
  11. * A helper class which provides update information for the Joomla! CMS itself. This is slightly different than the
  12. * regular "extension" files as we need to know if a Joomla! version is STS, LTS, testing, current and so on.
  13. */
  14. class FOFUtilsUpdateJoomla extends FOFUtilsUpdateExtension
  15. {
  16. /**
  17. * The source for LTS updates
  18. *
  19. * @var string
  20. */
  21. protected static $lts_url = 'http://update.joomla.org/core/list.xml';
  22. /**
  23. * The source for STS updates
  24. *
  25. * @var string
  26. */
  27. protected static $sts_url = 'http://update.joomla.org/core/sts/list_sts.xml';
  28. /**
  29. * The source for test release updates
  30. *
  31. * @var string
  32. */
  33. protected static $test_url = 'http://update.joomla.org/core/test/list_test.xml';
  34. /**
  35. * Reads a "collection" XML update source and picks the correct source URL
  36. * for the extension update source.
  37. *
  38. * @param string $url The collection XML update source URL to read from
  39. * @param string $jVersion Joomla! version to fetch updates for, or null to use JVERSION
  40. *
  41. * @return string The URL of the extension update source, or empty if no updates are provided / fetching failed
  42. */
  43. public function getUpdateSourceFromCollection($url, $jVersion = null)
  44. {
  45. $provider = new FOFUtilsUpdateCollection;
  46. return $provider->getExtensionUpdateSource($url, 'file', 'joomla', $jVersion);
  47. }
  48. /**
  49. * Determines the properties of a version: STS/LTS, normal or testing
  50. *
  51. * @param string $jVersion The version number to check
  52. * @param string $currentVersion The current Joomla! version number
  53. *
  54. * @return array The properties analysis
  55. */
  56. public function getVersionProperties($jVersion, $currentVersion = null)
  57. {
  58. // Initialise
  59. $ret = array(
  60. 'lts' => true, // Is this an LTS release? False means STS.
  61. 'current' => false, // Is this a release in the $currentVersion branch?
  62. 'upgrade' => 'none', // Upgrade relation of $jVersion to $currentVersion: 'none' (can't upgrade), 'lts' (next or current LTS), 'sts' (next or current STS) or 'current' (same release, no upgrade available)
  63. 'testing' => false, // Is this a testing (alpha, beta, RC) release?
  64. );
  65. // Get the current version if none is defined
  66. if (is_null($currentVersion))
  67. {
  68. $currentVersion = JVERSION;
  69. }
  70. // Sanitise version numbers
  71. $jVersion = $this->sanitiseVersion($jVersion);
  72. $currentVersion = $this->sanitiseVersion($currentVersion);
  73. // Get the base version
  74. $baseVersion = substr($jVersion, 0, 3);
  75. // Get the minimum and maximum current version numbers
  76. $current_minimum = substr($currentVersion, 0, 3);
  77. $current_maximum = $current_minimum . '.9999';
  78. // Initialise STS/LTS version numbers
  79. $sts_minimum = false;
  80. $sts_maximum = false;
  81. $lts_minimum = false;
  82. // Is it an LTS or STS release?
  83. switch ($baseVersion)
  84. {
  85. case '1.5':
  86. $ret['lts'] = true;
  87. break;
  88. case '1.6':
  89. $ret['lts'] = false;
  90. $sts_minimum = '1.7';
  91. $sts_maximum = '1.7.999';
  92. $lts_minimum = '2.5';
  93. break;
  94. case '1.7':
  95. $ret['lts'] = false;
  96. $sts_minimum = false;
  97. $lts_minimum = '2.5';
  98. break;
  99. default:
  100. $majorVersion = (int)substr($jVersion, 0, 1);
  101. $minorVersion = (int)substr($jVersion, 2, 1);
  102. if ($minorVersion == 5)
  103. {
  104. $ret['lts'] = true;
  105. // This is an LTS release, it can be superseded by .0 through .4 STS releases on the next branch...
  106. $sts_minimum = ($majorVersion + 1) . '.0';
  107. $sts_maximum = ($majorVersion + 1) . '.4.9999';
  108. // ...or a .5 LTS on the next branch
  109. $lts_minimum = ($majorVersion + 1) . '.5';
  110. }
  111. else
  112. {
  113. $ret['lts'] = false;
  114. // This is an STS release, it can be superseded by a .1/.2/.3/.4 STS release on the same branch...
  115. $sts_minimum = $majorVersion . '.1';
  116. $sts_maximum = $majorVersion . '.4.9999';
  117. // ...or a .5 LTS on the same branch
  118. $lts_minimum = $majorVersion . '.5';
  119. }
  120. break;
  121. }
  122. // Is it a current release?
  123. if (version_compare($jVersion, $current_minimum, 'ge') && version_compare($jVersion, $current_maximum, 'le'))
  124. {
  125. $ret['current'] = true;
  126. }
  127. // Is this a testing release?
  128. $versionParts = explode('.', $jVersion);
  129. $lastVersionPart = array_pop($versionParts);
  130. if (in_array(substr($lastVersionPart, 0, 1), array('a', 'b')))
  131. {
  132. $ret['testing'] = true;
  133. }
  134. elseif (substr($lastVersionPart, 0, 2) == 'rc')
  135. {
  136. $ret['testing'] = true;
  137. }
  138. elseif (substr($lastVersionPart, 0, 3) == 'dev')
  139. {
  140. $ret['testing'] = true;
  141. }
  142. // Find the upgrade relation of $jVersion to $currentVersion
  143. if (version_compare($jVersion, $currentVersion, 'eq'))
  144. {
  145. $ret['upgrade'] = 'current';
  146. }
  147. elseif(($sts_minimum !== false) && version_compare($jVersion, $sts_minimum, 'ge') && version_compare($jVersion, $sts_maximum, 'le'))
  148. {
  149. $ret['upgrade'] = 'sts';
  150. }
  151. elseif(($lts_minimum !== false) && version_compare($jVersion, $lts_minimum, 'ge'))
  152. {
  153. $ret['upgrade'] = 'lts';
  154. }
  155. elseif($baseVersion == $current_minimum)
  156. {
  157. $ret['upgrade'] = $ret['lts'] ? 'lts' : 'sts';
  158. }
  159. else
  160. {
  161. $ret['upgrade'] = 'none';
  162. }
  163. return $ret;
  164. }
  165. /**
  166. * Filters a list of updates, making sure they apply to the specifed CMS
  167. * release.
  168. *
  169. * @param array $updates A list of update records returned by the getUpdatesFromExtension method
  170. * @param string $jVersion The current Joomla! version number
  171. *
  172. * @return array A filtered list of updates. Each update record also includes version relevance information.
  173. */
  174. public function filterApplicableUpdates($updates, $jVersion = null)
  175. {
  176. if (empty($jVersion))
  177. {
  178. $jVersion = JVERSION;
  179. }
  180. $versionParts = explode('.', $jVersion, 4);
  181. $platformVersionMajor = $versionParts[0];
  182. $platformVersionMinor = $platformVersionMajor . '.' . $versionParts[1];
  183. $platformVersionNormal = $platformVersionMinor . '.' . $versionParts[2];
  184. $platformVersionFull = (count($versionParts) > 3) ? $platformVersionNormal . '.' . $versionParts[3] : $platformVersionNormal;
  185. $ret = array();
  186. foreach ($updates as $update)
  187. {
  188. // Check each update for platform match
  189. if (strtolower($update['targetplatform']['name']) != 'joomla')
  190. {
  191. continue;
  192. }
  193. $targetPlatformVersion = $update['targetplatform']['version'];
  194. if (($targetPlatformVersion !== $platformVersionMajor) && ($targetPlatformVersion !== $platformVersionMinor) && ($targetPlatformVersion !== $platformVersionNormal) && ($targetPlatformVersion !== $platformVersionFull))
  195. {
  196. continue;
  197. }
  198. // Get some information from the version number
  199. $updateVersion = $update['version'];
  200. $versionProperties = $this->getVersionProperties($updateVersion, $jVersion);
  201. if ($versionProperties['upgrade'] == 'none')
  202. {
  203. continue;
  204. }
  205. // The XML files are ill-maintained. Maybe we already have this update?
  206. if (!array_key_exists($updateVersion, $ret))
  207. {
  208. $ret[$updateVersion] = array_merge($update, $versionProperties);
  209. }
  210. }
  211. return $ret;
  212. }
  213. /**
  214. * Joomla! has a lousy track record in naming its alpha, beta and release
  215. * candidate releases. The convention used seems to be "what the hell the
  216. * current package maintainer thinks looks better". This method tries to
  217. * figure out what was in the mind of the maintainer and translate the
  218. * funky version number to an actual PHP-format version string.
  219. *
  220. * @param string $version The whatever-format version number
  221. *
  222. * @return string A standard formatted version number
  223. */
  224. public function sanitiseVersion($version)
  225. {
  226. $test = strtolower($version);
  227. $alphaQualifierPosition = strpos($test, 'alpha-');
  228. $betaQualifierPosition = strpos($test, 'beta-');
  229. $rcQualifierPosition = strpos($test, 'rc-');
  230. $rcQualifierPosition2 = strpos($test, 'rc');
  231. $devQualifiedPosition = strpos($test, 'dev');
  232. if ($alphaQualifierPosition !== false)
  233. {
  234. $betaRevision = substr($test, $alphaQualifierPosition + 6);
  235. if (!$betaRevision)
  236. {
  237. $betaRevision = 1;
  238. }
  239. $test = substr($test, 0, $alphaQualifierPosition) . '.a' . $betaRevision;
  240. }
  241. elseif ($betaQualifierPosition !== false)
  242. {
  243. $betaRevision = substr($test, $betaQualifierPosition + 5);
  244. if (!$betaRevision)
  245. {
  246. $betaRevision = 1;
  247. }
  248. $test = substr($test, 0, $betaQualifierPosition) . '.b' . $betaRevision;
  249. }
  250. elseif ($rcQualifierPosition !== false)
  251. {
  252. $betaRevision = substr($test, $rcQualifierPosition + 5);
  253. if (!$betaRevision)
  254. {
  255. $betaRevision = 1;
  256. }
  257. $test = substr($test, 0, $rcQualifierPosition) . '.rc' . $betaRevision;
  258. }
  259. elseif ($rcQualifierPosition2 !== false)
  260. {
  261. $betaRevision = substr($test, $rcQualifierPosition2 + 5);
  262. if (!$betaRevision)
  263. {
  264. $betaRevision = 1;
  265. }
  266. $test = substr($test, 0, $rcQualifierPosition2) . '.rc' . $betaRevision;
  267. }
  268. elseif ($devQualifiedPosition !== false)
  269. {
  270. $betaRevision = substr($test, $devQualifiedPosition + 6);
  271. if (!$betaRevision)
  272. {
  273. $betaRevision = '';
  274. }
  275. $test = substr($test, 0, $devQualifiedPosition) . '.dev' . $betaRevision;
  276. }
  277. return $test;
  278. }
  279. /**
  280. * Reloads the list of all updates available for the specified Joomla! version
  281. * from the network.
  282. *
  283. * @param array $sources The enabled sources to look into
  284. * @param string $jVersion The Joomla! version we are checking updates for
  285. *
  286. * @return array A list of updates for the installed, current, lts and sts versions
  287. */
  288. public function getUpdates($sources = array(), $jVersion = null)
  289. {
  290. // Make sure we have a valid list of sources
  291. if (empty($sources) || !is_array($sources))
  292. {
  293. $sources = array();
  294. }
  295. $defaultSources = array('lts' => true, 'sts' => true, 'test' => true, 'custom' => '');
  296. $sources = array_merge($defaultSources, $sources);
  297. // Use the current JVERSION if none is specified
  298. if (empty($jVersion))
  299. {
  300. $jVersion = JVERSION;
  301. }
  302. // Get the current branch' min/max versions
  303. $versionParts = explode('.', $jVersion, 4);
  304. $currentMinVersion = $versionParts[0] . '.' . $versionParts[1];
  305. $currentMaxVersion = $versionParts[0] . '.' . $versionParts[1] . '.9999';
  306. // Retrieve all updates
  307. $allUpdates = array();
  308. foreach ($sources as $source => $value)
  309. {
  310. if (($value === false) || empty($value))
  311. {
  312. continue;
  313. }
  314. switch ($source)
  315. {
  316. case 'lts':
  317. $url = self::$lts_url;
  318. break;
  319. case 'sts':
  320. $url = self::$sts_url;
  321. break;
  322. case 'test':
  323. $url = self::$test_url;
  324. break;
  325. case 'custom':
  326. $url = $value;
  327. break;
  328. }
  329. $url = $this->getUpdateSourceFromCollection($url, $jVersion);
  330. if (!empty($url))
  331. {
  332. $updates = $this->getUpdatesFromExtension($url);
  333. if (!empty($updates))
  334. {
  335. $applicableUpdates = $this->filterApplicableUpdates($updates, $jVersion);
  336. if (!empty($applicableUpdates))
  337. {
  338. $allUpdates = array_merge($allUpdates, $applicableUpdates);
  339. }
  340. }
  341. }
  342. }
  343. $ret = array(
  344. // Currently installed version (used to reinstall, if available)
  345. 'installed' => array(
  346. 'version' => '',
  347. 'package' => '',
  348. 'infourl' => '',
  349. ),
  350. // Current branch
  351. 'current' => array(
  352. 'version' => '',
  353. 'package' => '',
  354. 'infourl' => '',
  355. ),
  356. // Upgrade to STS release
  357. 'sts' => array(
  358. 'version' => '',
  359. 'package' => '',
  360. 'infourl' => '',
  361. ),
  362. // Upgrade to LTS release
  363. 'lts' => array(
  364. 'version' => '',
  365. 'package' => '',
  366. 'infourl' => '',
  367. ),
  368. // Upgrade to LTS release
  369. 'test' => array(
  370. 'version' => '',
  371. 'package' => '',
  372. 'infourl' => '',
  373. ),
  374. );
  375. foreach ($allUpdates as $update)
  376. {
  377. $sections = array();
  378. if ($update['upgrade'] == 'current')
  379. {
  380. $sections[0] = 'installed';
  381. }
  382. elseif(version_compare($update['version'], $currentMinVersion, 'ge') && version_compare($update['version'], $currentMaxVersion, 'le'))
  383. {
  384. $sections[0] = 'current';
  385. }
  386. else
  387. {
  388. $sections[0] = '';
  389. }
  390. $sections[1] = $update['lts'] ? 'lts' : 'sts';
  391. if ($update['testing'])
  392. {
  393. $sections = array('test');
  394. }
  395. foreach ($sections as $section)
  396. {
  397. if (empty($section))
  398. {
  399. continue;
  400. }
  401. $existingVersionForSection = $ret[$section]['version'];
  402. if (empty($existingVersionForSection))
  403. {
  404. $existingVersionForSection = '0.0.0';
  405. }
  406. if (version_compare($update['version'], $existingVersionForSection, 'ge'))
  407. {
  408. $ret[$section]['version'] = $update['version'];
  409. $ret[$section]['package'] = $update['downloads'][0]['url'];
  410. $ret[$section]['infourl'] = $update['infourl']['url'];
  411. }
  412. }
  413. }
  414. // Catch the case when the latest current branch version is the installed version (up to date site)
  415. if (empty($ret['current']['version']) && !empty($ret['installed']['version']))
  416. {
  417. $ret['current'] = $ret['installed'];
  418. }
  419. return $ret;
  420. }
  421. }