PageRenderTime 26ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/downloader/lib/Mage/Connect/Rest.php

https://github.com/speedupmate/Magento-CE-Mirror
PHP | 387 lines | 205 code | 29 blank | 153 comment | 34 complexity | 1af9a005493704207c0d0d0f17f62260 MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magento.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magento.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Connect
  23. * @copyright Copyright (c) 2006-2020 Magento, Inc. (http://www.magento.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Class to work with remote REST interface
  28. *
  29. * @category Mage
  30. * @package Mage_Connect
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Connect_Rest
  34. {
  35. /**
  36. * Paths for xml config files
  37. */
  38. const CHANNELS_XML = "channels.xml";
  39. const CHANNEL_XML = "channel.xml";
  40. const PACKAGES_XML = "packages.xml";
  41. const RELEASES_XML = "releases.xml";
  42. const PACKAGE_XML = "package.xml";
  43. const EXT = "tgz";
  44. /**
  45. * HTTP Loader
  46. * @var Mage_HTTP_IClient
  47. */
  48. protected $_loader = null;
  49. /**
  50. * XML parser
  51. *
  52. * @var Mage_Xml_Parser
  53. */
  54. protected $_parser = null;
  55. /**
  56. * Channel URI
  57. *
  58. * @var string
  59. */
  60. protected $_chanUri = '';
  61. /**
  62. * Protocol HTTP or FTP
  63. *
  64. * @var string http or ftp
  65. */
  66. protected $_protocol = '';
  67. /**
  68. * States interpretation
  69. *
  70. * @var array
  71. */
  72. protected $states = array('b'=>'beta', 'd'=>'dev', 's'=>'stable', 'a'=>'alpha');
  73. /**
  74. * Constructor sets default protocol
  75. *
  76. * @param string $protocol
  77. */
  78. public function __construct($protocol="https")
  79. {
  80. switch ($protocol) {
  81. case 'http':
  82. $this->_protocol = 'http';
  83. break;
  84. default:
  85. $this->_protocol = 'https';
  86. break;
  87. }
  88. }
  89. /**
  90. * Set channel URI
  91. *
  92. * @param string $uri
  93. * @return void
  94. */
  95. public function setChannel($uri)
  96. {
  97. $this->_chanUri = $uri;
  98. }
  99. /**
  100. * Get HTTP loader
  101. *
  102. * @return Mage_HTTP_IClient|Mage_Connect_Loader_Ftp
  103. */
  104. public function getLoader()
  105. {
  106. if (is_null($this->_loader)) {
  107. $this->_loader = Mage_Connect_Loader::getInstance($this->_protocol);
  108. }
  109. return $this->_loader;
  110. }
  111. /**
  112. * Get parser
  113. *
  114. * @return Mage_Xml_Parser
  115. */
  116. protected function getParser()
  117. {
  118. if (is_null($this->_parser)) {
  119. $this->_parser = new Mage_Xml_Parser();
  120. }
  121. return $this->_parser;
  122. }
  123. /**
  124. * Load URI response
  125. *
  126. * @param string $uriSuffix
  127. * @return bool|string
  128. */
  129. protected function loadChannelUri($uriSuffix)
  130. {
  131. $url = $this->_chanUri . "/" . $uriSuffix;
  132. $this->getLoader()->get($url);
  133. $statusCode = $this->getLoader()->getStatus();
  134. if ($statusCode != 200) {
  135. return false;
  136. }
  137. return $this->getLoader()->getBody();
  138. }
  139. /**
  140. * Get channels list of URI
  141. *
  142. * @return array
  143. */
  144. public function getChannelInfo()
  145. {
  146. $out = $this->loadChannelUri(self::CHANNEL_XML);
  147. $statusCode = $this->getLoader()->getStatus();
  148. if ($statusCode != 200) {
  149. throw new Exception("Invalid server response for {$this->_chanUri}");
  150. }
  151. $parser = $this->getParser();
  152. $out = $parser->loadXML($out)->xmlToArray();
  153. $vo = new Mage_Connect_Channel_VO();
  154. $vo->fromArray($out['channel']);
  155. if (!$vo->validate()) {
  156. throw new Exception("Invalid channel.xml file");
  157. }
  158. return $vo;
  159. }
  160. /**
  161. * Get packages list of channel
  162. *
  163. * @return array
  164. */
  165. public function getPackages()
  166. {
  167. $out = $this->loadChannelUri(self::PACKAGES_XML);
  168. $statusCode = $this->getLoader()->getStatus();
  169. if ($statusCode != 200) {
  170. return false;
  171. }
  172. $parser = $this->getParser();
  173. $out = $parser->loadXML($out)->xmlToArray();
  174. if (!isset($out['data']['p'])) {
  175. return array();
  176. }
  177. if (isset($out['data']['p'][0])) {
  178. return $out['data']['p'];
  179. }
  180. if (is_array($out['data']['p'])) {
  181. return array($out['data']['p']);
  182. }
  183. return array();
  184. }
  185. /**
  186. * Return Channel Packages loaded from Channel Server
  187. *
  188. * @return array|bool|string
  189. */
  190. public function getPackagesHashed()
  191. {
  192. $out = $this->loadChannelUri(self::PACKAGES_XML);
  193. $statusCode = $this->getLoader()->getStatus();
  194. if ($statusCode != 200) {
  195. return false;
  196. }
  197. $parser = $this->getParser();
  198. $out = $parser->loadXML($out)->xmlToArray();
  199. $return = array();
  200. if (!isset($out['data']['p'])) {
  201. return $return;
  202. }
  203. if (isset($out['data']['p'][0])) {
  204. $return = $out['data']['p'];
  205. } elseif (is_array($out['data']['p'])) {
  206. $return = array($out['data']['p']);
  207. }
  208. $c = count($return);
  209. if ($c) {
  210. $output = array();
  211. for ($i=0; $i<$c; $i++) {
  212. $element = $return[$i];
  213. $output[$element['n']] = $element['r'];
  214. }
  215. $return = $output;
  216. }
  217. $out = array();
  218. foreach ($return as $name=>$package) {
  219. $stabilities = array_map(array($this, 'shortStateToLong'), array_keys($package));
  220. $versions = array_map('trim', array_values($package));
  221. $package = array_combine($versions, $stabilities);
  222. ksort($package);
  223. $out[$name] = $package;
  224. }
  225. return $out;
  226. }
  227. /**
  228. * Stub
  229. *
  230. * @param $n
  231. * @return unknown_type
  232. */
  233. public function escapePackageName($n)
  234. {
  235. return $n;
  236. }
  237. /**
  238. * Get releases list of package on current channel
  239. *
  240. * @param string $package package name
  241. * @return array|bool
  242. */
  243. public function getReleases($package)
  244. {
  245. $out = $this->loadChannelUri($this->escapePackageName($package) . "/" . self::RELEASES_XML);
  246. $statusCode = $this->getLoader()->getStatus();
  247. if ($statusCode != 200) {
  248. return false;
  249. }
  250. $parser = $this->getParser();
  251. $out = $parser->loadXML($out)->xmlToArray();
  252. if (!isset($out['releases']['r'])) {
  253. return array();
  254. }
  255. $src = $out['releases']['r'];
  256. if (!array_key_exists(0, $src)) {
  257. return array($src);
  258. }
  259. $this->sortReleases($src);
  260. return $src;
  261. }
  262. /**
  263. * Sort releases
  264. *
  265. * @param array $releases
  266. * @return void
  267. */
  268. public function sortReleases(array &$releases)
  269. {
  270. usort($releases, array($this, 'sortReleasesCallback'));
  271. $releases = array_reverse($releases);
  272. }
  273. /**
  274. * Sort releases callback
  275. *
  276. * @param string $a
  277. * @param srting $b
  278. * @return int
  279. */
  280. protected function sortReleasesCallback($a, $b)
  281. {
  282. return version_compare($a['v'],$b['v']);
  283. }
  284. /**
  285. * Get package info (package.xml)
  286. *
  287. * @param $package
  288. * @return unknown_type
  289. */
  290. public function getPackageInfo($package)
  291. {
  292. $out = $this->loadChannelUri($this->escapePackageName($package) . "/" . self::PACKAGE_XML);
  293. if (false === $out) {
  294. return false;
  295. }
  296. return new Mage_Connect_Package($out);
  297. }
  298. /**
  299. * Retrieve information on Package Release from the Channel Server
  300. *
  301. * @param $package
  302. * @param $version
  303. * @return Mage_Connect_Package|bool
  304. */
  305. public function getPackageReleaseInfo($package, $version)
  306. {
  307. $out = $this->loadChannelUri($this->escapePackageName($package) . "/" . $version . "/" . self::PACKAGE_XML);
  308. if (false === $out) {
  309. return false;
  310. }
  311. return new Mage_Connect_Package($out);
  312. }
  313. /**
  314. * Get package archive file of release
  315. *
  316. * @throws Exception
  317. * @param string $package package name
  318. * @param string $version package version
  319. * @param string $targetFile
  320. * @return bool
  321. */
  322. public function downloadPackageFileOfRelease($package, $version, $targetFile)
  323. {
  324. $package = $this->escapePackageName($package);
  325. $version = $this->escapePackageName($version);
  326. if (file_exists($targetFile)) {
  327. $chksum = $this->loadChannelUri($package . "/" . $version . "/checksum");
  328. $statusCode = $this->getLoader()->getStatus();
  329. if ($statusCode == 200) {
  330. if (md5_file($targetFile) == $chksum) {
  331. return true;
  332. }
  333. }
  334. }
  335. $out = $this->loadChannelUri($package . "/" . $version . "/" . $package . "-" . $version . "." . self::EXT);
  336. $statusCode = $this->getLoader()->getStatus();
  337. if ($statusCode != 200) {
  338. throw new Exception("Package not found: {$package} {$version}");
  339. }
  340. $dir = dirname($targetFile);
  341. @mkdir($dir, 0777, true);
  342. $result = @file_put_contents($targetFile, $out);
  343. if (false === $result) {
  344. throw new Exception("Cannot write to file {$targetFile}");
  345. }
  346. return true;
  347. }
  348. /**
  349. * Decode state
  350. *
  351. * @param string $s
  352. * @return string
  353. */
  354. public function shortStateToLong($s)
  355. {
  356. return isset($this->states[$s]) ? $this->states[$s] : 'dev';
  357. }
  358. }