Mss_Connector - Version 2.6.3

Version Notes

1.Google Login Functionality Bug Removed.
2.Product Listing Filter Improved.

Download this release

Release Info

Developer mss
Extension Mss_Connector
Version 2.6.3
Comparing to
See all releases


Code changes from version 2.6.2 to 2.6.3

Files changed (200) hide show
  1. app/code/local/Mss/Bargain/Helper/Data.php +5 -0
  2. app/code/local/Mss/Bargain/controllers/IndexController.php +263 -0
  3. app/code/local/Mss/Bargain/etc/config.xml +33 -0
  4. app/code/local/Mss/Connector/controllers/CustomerController.php +3 -2
  5. app/code/local/Mss/Connector/controllers/IndexController.php +10 -6
  6. app/code/local/Mss/Connector/controllers/StaticpagesController.php +1 -1
  7. app/code/local/Mss/Connector/controllers/index.php +89 -0
  8. app/code/local/Mss/Connector/etc/config.xml +1 -1
  9. app/code/local/Mss/Popup/Block/Popup.php +4 -0
  10. app/code/local/Mss/Popup/Helper/Data.php +24 -0
  11. app/code/local/Mss/Popup/Model/Source/Page.php +18 -0
  12. app/code/local/Mss/Popup/Model/Source/Truefalse.php +11 -0
  13. app/code/local/Mss/Popup/etc/adminhtml.xml +26 -0
  14. app/code/local/Mss/Popup/etc/config.xml +52 -0
  15. app/code/local/Mss/Sociallogin/Helper/Data.php +1 -1
  16. app/code/local/Mss/cache.cfg +0 -0
  17. app/code/local/Mss/connect.cfg +1 -0
  18. app/code/local/Mss/downloader/.cache/community/Bricks_Chekcout-0.0.1.tgz +0 -0
  19. app/code/local/Mss/downloader/.cache/community/Exit_Screen_Pop_Up-1.0.2.tgz +0 -0
  20. app/code/local/Mss/downloader/.cache/community/Mss_Connector-2.5.0.tgz +0 -0
  21. app/code/local/Mss/downloader/.cache/community/Mss_Connector-2.5.1.tgz +0 -0
  22. app/code/local/Mss/downloader/.cache/community/Mss_Connector-2.5.2.tgz +0 -0
  23. app/code/local/Mss/downloader/.cache/community/Mss_Connector-2.6.1.tgz +0 -0
  24. app/code/local/Mss/downloader/.cache/community/OrganicInternet_SimpleConfigurableProducts-0.7.4.tgz +0 -0
  25. app/code/local/Mss/downloader/.cache/community/Owebia_Shipping_2-2.6.0.tgz +0 -0
  26. app/code/local/Mss/downloader/.cache/community/toogas_featured_popup_free_version-1.0.6.tgz +0 -0
  27. app/code/local/Mss/downloader/.cache/community@/Auctionmaid_Matrxrate-5.1.1.tgz +0 -0
  28. app/code/local/Mss/downloader/.cache/community@/CashOnDelivery-1.0.8.tgz +0 -0
  29. app/code/local/Mss/downloader/.cache/community@/Craig_Tco-2.4.2.tgz +0 -0
  30. app/code/local/Mss/downloader/.cache/community@/Mss_Connector-2.4.9.tgz +0 -0
  31. app/code/local/Mss/downloader/.cache/community@/PayU-India-Basic-1.0.0.tgz +0 -0
  32. app/code/local/Mss/downloader/.cache/community@/Pook_CollectInStore-1.0.5.tgz +0 -0
  33. app/code/local/Mss/downloader/.cache/community@/Zero1_Customshipprice-1.0.1.tgz +0 -0
  34. app/code/local/Mss/downloader/.htaccess +11 -0
  35. app/code/local/Mss/downloader/Maged/.htaccess +2 -0
  36. app/code/local/Mss/downloader/Maged/Connect.php +517 -0
  37. app/code/local/Mss/downloader/Maged/Connect/Frontend.php +150 -0
  38. app/code/local/Mss/downloader/Maged/Controller.php +1154 -0
  39. app/code/local/Mss/downloader/Maged/Exception.php +37 -0
  40. app/code/local/Mss/downloader/Maged/Model.php +99 -0
  41. app/code/local/Mss/downloader/Maged/Model/Config.php +84 -0
  42. app/code/local/Mss/downloader/Maged/Model/Config/Abstract.php +134 -0
  43. app/code/local/Mss/downloader/Maged/Model/Config/Community.php +112 -0
  44. app/code/local/Mss/downloader/Maged/Model/Config/Interface.php +90 -0
  45. app/code/local/Mss/downloader/Maged/Model/Connect.php +497 -0
  46. app/code/local/Mss/downloader/Maged/Model/Connect/Request.php +43 -0
  47. app/code/local/Mss/downloader/Maged/Model/Dowloader.php +30 -0
  48. app/code/local/Mss/downloader/Maged/Model/Session.php +257 -0
  49. app/code/local/Mss/downloader/Maged/View.php +197 -0
  50. app/code/local/Mss/downloader/cache.cfg +0 -0
  51. app/code/local/Mss/downloader/config.ini +1 -0
  52. app/code/local/Mss/downloader/connect.cfg +1 -0
  53. app/code/local/Mss/downloader/favicon.ico +0 -0
  54. app/code/local/Mss/downloader/index.php +36 -0
  55. app/code/local/Mss/downloader/js/prototype.js +3277 -0
  56. app/code/local/Mss/downloader/lib/.htaccess +2 -0
  57. app/code/local/Mss/downloader/lib/Mage/Archive.php +222 -0
  58. app/code/local/Mss/downloader/lib/Mage/Archive/Abstract.php +87 -0
  59. app/code/local/Mss/downloader/lib/Mage/Archive/Bz.php +89 -0
  60. app/code/local/Mss/downloader/lib/Mage/Archive/Gz.php +87 -0
  61. app/code/local/Mss/downloader/lib/Mage/Archive/Helper/File.php +274 -0
  62. app/code/local/Mss/downloader/lib/Mage/Archive/Helper/File/Bz.php +92 -0
  63. app/code/local/Mss/downloader/lib/Mage/Archive/Helper/File/Gz.php +98 -0
  64. app/code/local/Mss/downloader/lib/Mage/Archive/Interface.php +53 -0
  65. app/code/local/Mss/downloader/lib/Mage/Archive/Tar.php +690 -0
  66. app/code/local/Mss/downloader/lib/Mage/Autoload/Simple.php +52 -0
  67. app/code/local/Mss/downloader/lib/Mage/Backup.php +59 -0
  68. app/code/local/Mss/downloader/lib/Mage/Backup/Abstract.php +318 -0
  69. app/code/local/Mss/downloader/lib/Mage/Backup/Archive/Tar.php +82 -0
  70. app/code/local/Mss/downloader/lib/Mage/Backup/Db.php +119 -0
  71. app/code/local/Mss/downloader/lib/Mage/Backup/Exception.php +36 -0
  72. app/code/local/Mss/downloader/lib/Mage/Backup/Exception/CantLoadSnapshot.php +36 -0
  73. app/code/local/Mss/downloader/lib/Mage/Backup/Exception/FtpConnectionFailed.php +36 -0
  74. app/code/local/Mss/downloader/lib/Mage/Backup/Exception/FtpValidationFailed.php +36 -0
  75. app/code/local/Mss/downloader/lib/Mage/Backup/Exception/NotEnoughFreeSpace.php +36 -0
  76. app/code/local/Mss/downloader/lib/Mage/Backup/Exception/NotEnoughPermissions.php +36 -0
  77. app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem.php +284 -0
  78. app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Helper.php +137 -0
  79. app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Iterator/File.php +112 -0
  80. app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Iterator/Filter.php +77 -0
  81. app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Rollback/Abstract.php +57 -0
  82. app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Rollback/Fs.php +78 -0
  83. app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Rollback/Ftp.php +194 -0
  84. app/code/local/Mss/downloader/lib/Mage/Backup/Interface.php +88 -0
  85. app/code/local/Mss/downloader/lib/Mage/Backup/Media.php +99 -0
  86. app/code/local/Mss/downloader/lib/Mage/Backup/Nomedia.php +82 -0
  87. app/code/local/Mss/downloader/lib/Mage/Backup/Snapshot.php +140 -0
  88. app/code/local/Mss/downloader/lib/Mage/Connect/Backup.php +169 -0
  89. app/code/local/Mss/downloader/lib/Mage/Connect/Channel/Generator.php +63 -0
  90. app/code/local/Mss/downloader/lib/Mage/Connect/Channel/Parser.php +25 -0
  91. app/code/local/Mss/downloader/lib/Mage/Connect/Channel/VO.php +113 -0
  92. app/code/local/Mss/downloader/lib/Mage/Connect/Command.php +463 -0
  93. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Channels.php +189 -0
  94. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Channels_Header.php +104 -0
  95. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Config.php +216 -0
  96. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Config_Header.php +100 -0
  97. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Install.php +568 -0
  98. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Install_Header.php +237 -0
  99. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Package.php +225 -0
  100. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Package_Header.php +76 -0
  101. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Registry.php +364 -0
  102. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Registry_Header.php +84 -0
  103. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Remote.php +231 -0
  104. app/code/local/Mss/downloader/lib/Mage/Connect/Command/Remote_Header.php +88 -0
  105. app/code/local/Mss/downloader/lib/Mage/Connect/Config.php +617 -0
  106. app/code/local/Mss/downloader/lib/Mage/Connect/Converter.php +336 -0
  107. app/code/local/Mss/downloader/lib/Mage/Connect/Frontend.php +267 -0
  108. app/code/local/Mss/downloader/lib/Mage/Connect/Frontend/CLI.php +456 -0
  109. app/code/local/Mss/downloader/lib/Mage/Connect/Ftp.php +533 -0
  110. app/code/local/Mss/downloader/lib/Mage/Connect/Loader.php +50 -0
  111. app/code/local/Mss/downloader/lib/Mage/Connect/Loader/Ftp.php +155 -0
  112. app/code/local/Mss/downloader/lib/Mage/Connect/Package.php +1499 -0
  113. app/code/local/Mss/downloader/lib/Mage/Connect/Package/Extension.php +25 -0
  114. app/code/local/Mss/downloader/lib/Mage/Connect/Package/Hotfix.php +137 -0
  115. app/code/local/Mss/downloader/lib/Mage/Connect/Package/Maintainer.php +25 -0
  116. app/code/local/Mss/downloader/lib/Mage/Connect/Package/Reader.php +150 -0
  117. app/code/local/Mss/downloader/lib/Mage/Connect/Package/Target.php +126 -0
  118. app/code/local/Mss/downloader/lib/Mage/Connect/Package/VO.php +96 -0
  119. app/code/local/Mss/downloader/lib/Mage/Connect/Package/Writer.php +177 -0
  120. app/code/local/Mss/downloader/lib/Mage/Connect/Packager.php +1052 -0
  121. app/code/local/Mss/downloader/lib/Mage/Connect/Repository.php +25 -0
  122. app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Abstract.php +25 -0
  123. app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel.php +25 -0
  124. app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel/Abstract.php +25 -0
  125. app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel/Commercial.php +25 -0
  126. app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel/Community.php +25 -0
  127. app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel/Core.php +25 -0
  128. app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Local.php +25 -0
  129. app/code/local/Mss/downloader/lib/Mage/Connect/Rest.php +387 -0
  130. app/code/local/Mss/downloader/lib/Mage/Connect/Rest/Builder.php +76 -0
  131. app/code/local/Mss/downloader/lib/Mage/Connect/Rest/Factory.php +41 -0
  132. app/code/local/Mss/downloader/lib/Mage/Connect/Singleconfig.php +1060 -0
  133. app/code/local/Mss/downloader/lib/Mage/Connect/Structures/Graph.php +248 -0
  134. app/code/local/Mss/downloader/lib/Mage/Connect/Structures/Node.php +257 -0
  135. app/code/local/Mss/downloader/lib/Mage/Connect/Validator.php +483 -0
  136. app/code/local/Mss/downloader/lib/Mage/DB/Exception.php +36 -0
  137. app/code/local/Mss/downloader/lib/Mage/DB/Mysqli.php +532 -0
  138. app/code/local/Mss/downloader/lib/Mage/Exception.php +35 -0
  139. app/code/local/Mss/downloader/lib/Mage/HTTP/Client.php +82 -0
  140. app/code/local/Mss/downloader/lib/Mage/HTTP/Client/Curl.php +576 -0
  141. app/code/local/Mss/downloader/lib/Mage/HTTP/Client/Socket.php +537 -0
  142. app/code/local/Mss/downloader/lib/Mage/HTTP/IClient.php +145 -0
  143. app/code/local/Mss/downloader/lib/Mage/System/Args.php +102 -0
  144. app/code/local/Mss/downloader/lib/Mage/System/Dirs.php +104 -0
  145. app/code/local/Mss/downloader/lib/Mage/System/Ftp.php +509 -0
  146. app/code/local/Mss/downloader/lib/Mage/Xml/Generator.php +114 -0
  147. app/code/local/Mss/downloader/lib/Mage/Xml/Parser.php +115 -0
  148. app/code/local/Mss/downloader/mage.php +156 -0
  149. app/code/local/Mss/downloader/skin/boxes.css +217 -0
  150. app/code/local/Mss/downloader/skin/ie7boxes.css +27 -0
  151. app/code/local/Mss/downloader/skin/ieboxes.css +29 -0
  152. app/code/local/Mss/downloader/skin/images/Magento_Connect.jpg +0 -0
  153. app/code/local/Mss/downloader/skin/images/ajax-loader-tr.gif +0 -0
  154. app/code/local/Mss/downloader/skin/images/btn_bg.gif +0 -0
  155. app/code/local/Mss/downloader/skin/images/header_bg.gif +0 -0
  156. app/code/local/Mss/downloader/skin/images/logo.gif +0 -0
  157. app/code/local/Mss/downloader/skin/images/nav_bg.gif +0 -0
  158. app/code/local/Mss/downloader/skin/images/nav_separator.gif +0 -0
  159. app/code/local/Mss/downloader/skin/install/boxes.css +414 -0
  160. app/code/local/Mss/downloader/skin/install/clears.css +70 -0
  161. app/code/local/Mss/downloader/skin/install/ie7minus.css +40 -0
  162. app/code/local/Mss/downloader/skin/install/iestyles.css +78 -0
  163. app/code/local/Mss/downloader/skin/install/images/error_msg_icon.gif +0 -0
  164. app/code/local/Mss/downloader/skin/install/images/footer_bg.gif +0 -0
  165. app/code/local/Mss/downloader/skin/install/images/footer_container_bg.gif +0 -0
  166. app/code/local/Mss/downloader/skin/install/images/footer_info_separator.gif +0 -0
  167. app/code/local/Mss/downloader/skin/install/images/footer_informational_bg.gif +0 -0
  168. app/code/local/Mss/downloader/skin/install/images/footer_left.gif +0 -0
  169. app/code/local/Mss/downloader/skin/install/images/footer_legality_bg.gif +0 -0
  170. app/code/local/Mss/downloader/skin/install/images/footer_right.gif +0 -0
  171. app/code/local/Mss/downloader/skin/install/images/header_bg.gif +0 -0
  172. app/code/local/Mss/downloader/skin/install/images/header_nav_bg.gif +0 -0
  173. app/code/local/Mss/downloader/skin/install/images/header_top_bg.jpg +0 -0
  174. app/code/local/Mss/downloader/skin/install/images/header_top_container_bg.jpg +0 -0
  175. app/code/local/Mss/downloader/skin/install/images/logo.gif +0 -0
  176. app/code/local/Mss/downloader/skin/install/images/main_bg.gif +0 -0
  177. app/code/local/Mss/downloader/skin/install/images/main_container_bg.gif +0 -0
  178. app/code/local/Mss/downloader/skin/install/images/note_msg_icon.gif +0 -0
  179. app/code/local/Mss/downloader/skin/install/images/success_msg_icon.gif +0 -0
  180. app/code/local/Mss/downloader/skin/install/images/validation_advice_bg.gif +0 -0
  181. app/code/local/Mss/downloader/skin/install/reset.css +83 -0
  182. app/code/local/Mss/downloader/target.xml +41 -0
  183. app/code/local/Mss/downloader/template/.htaccess +2 -0
  184. app/code/local/Mss/downloader/template/connect/iframe.phtml +125 -0
  185. app/code/local/Mss/downloader/template/connect/packages.phtml +266 -0
  186. app/code/local/Mss/downloader/template/connect/packages_prepare.phtml +79 -0
  187. app/code/local/Mss/downloader/template/exception.phtml +36 -0
  188. app/code/local/Mss/downloader/template/footer.phtml +40 -0
  189. app/code/local/Mss/downloader/template/header.phtml +73 -0
  190. app/code/local/Mss/downloader/template/index.phtml +36 -0
  191. app/code/local/Mss/downloader/template/install/download.phtml +194 -0
  192. app/code/local/Mss/downloader/template/install/footer.phtml +49 -0
  193. app/code/local/Mss/downloader/template/install/header.phtml +99 -0
  194. app/code/local/Mss/downloader/template/install/writable.phtml +40 -0
  195. app/code/local/Mss/downloader/template/login.phtml +44 -0
  196. app/code/local/Mss/downloader/template/messages.phtml +39 -0
  197. app/code/local/Mss/downloader/template/noroute.phtml +31 -0
  198. app/code/local/Mss/downloader/template/settings.phtml +167 -0
  199. app/code/local/Mss/downloader/template/writable.phtml +35 -0
  200. package.xml +7 -6
app/code/local/Mss/Bargain/Helper/Data.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ class Mss_Bargain_Helper_Data extends Mage_Core_Helper_Abstract
3
+ {
4
+ }
5
+
app/code/local/Mss/Bargain/controllers/IndexController.php ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Mss_Bargain_IndexController extends Mage_Core_Controller_Front_Action
3
+ {
4
+
5
+ public function IndexAction()
6
+ {
7
+ if (Mage::getSingleton('customer/session')->isLoggedIn()) {
8
+ $ProductId = $this->getRequest()->getParam('product_id');
9
+ if ($ProductId) {
10
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
11
+ $model = Mage::getModel('catalog/product')->load($ProductId);
12
+ $result = array();
13
+ $result['product_name'] = $model->getName();
14
+ $result['product_sku'] = $model->getSku();
15
+ $result['customer_email'] = $customer->getEmail();
16
+ $result['customer_name'] = $customer->getName();
17
+ $result['customer_id'] = $customer->getEntityId();
18
+ $result['product_price'] = $model->getFinalPrice();
19
+ $FinalResult = array();
20
+ $FinalResult['status'] = 'success';
21
+ $FinalResult['data'] = $result;
22
+
23
+ echo Mage::helper('core')->jsonEncode($FinalResult);
24
+ exit();
25
+
26
+ } else {
27
+ $result = array();
28
+ $result['status'] = 'error';
29
+ $result['message'] = 'Product Id not Supesified';
30
+ echo Mage::helper('core')->jsonEncode($result);
31
+ exit();
32
+ }
33
+ } else {
34
+ $result = array();
35
+ $result['status'] = 'error';
36
+ $result['message'] = 'Customer is not Loged in';
37
+ echo Mage::helper('core')->jsonEncode($result);
38
+ exit();
39
+ }
40
+
41
+ }
42
+
43
+ public function subformAction()
44
+ {
45
+ $params = Mage::app()->getRequest()->getParams();
46
+
47
+ $valid_price = is_numeric($params['new_price']);
48
+
49
+ if ($valid_price == true):
50
+
51
+ $data = array('customer_id' => $params['customer_id'], 'customer_name' => $params['customer_name'], 'customer_email' => $params['customer_email'], 'product_id' => $params['product_id'], 'product_sku' => $params['product_sku'], 'product_name' => $params['product_name'], 'product_price' => $params['product_price'], 'new_price' => $params['new_price'], 'message' => $params['new_message']);
52
+ $model = Mage::getModel('bargainprice/bargainprice');
53
+ $model->setData($data);
54
+ $model->save();
55
+ if ($model->save()):
56
+
57
+ $emailTemplate = Mage::getModel('core/email_template')
58
+ ->loadDefault('bargainprice_email_template');
59
+ $emailTemplateVariables = array();
60
+ $emailTemplateVariables['customer_name'] = $params['customer_name'];
61
+ $emailTemplateVariables['customer_email'] = $params['customer_email'];
62
+ $emailTemplateVariables['product'] = $params['product_name'];
63
+ $emailTemplateVariables['product_price'] = $params['product_price'];
64
+ $emailTemplateVariables['new_price'] = $params['new_price'];
65
+ $emailTemplateVariables['content'] = $params['new_message'];
66
+ $processedTemplate = $emailTemplate->getProcessedTemplate($emailTemplateVariables);
67
+ $emailTemplate->setSenderName($params['customer_name']);
68
+ $emailTemplate->setSenderEmail($params['customer_email']);
69
+ $emailTemplate->setTemplateSubject('New Price Request by Customer (' . $params['customer_name'] . ')');
70
+
71
+ $emailTemplate->send(Mage::getStoreConfig('trans_email/ident_general/email'), Mage::getStoreConfig('trans_email/ident_general/name'), $emailTemplateVariables);
72
+
73
+ $result = array();
74
+ $result['status'] = 'success';
75
+ $result['message'] = 'Success! Your Bargain price has been submitted. We will contact you through email.';
76
+ echo Mage::helper('core')->jsonEncode($result);
77
+ exit();
78
+
79
+ else:
80
+
81
+ $result = array();
82
+ $result['status'] = 'error';
83
+ $result['message'] = 'Error! Something wrong Happend,Please Try Again Later.';
84
+ echo Mage::helper('core')->jsonEncode($result);
85
+ exit();
86
+
87
+ endif;
88
+
89
+ else:
90
+ $result = array();
91
+ $result['status'] = 'error';
92
+ $result['message'] = 'Error! Please Enter Valid Price ,Do not use Price Symbol.';
93
+ echo Mage::helper('core')->jsonEncode($result);
94
+ exit();
95
+ endif;
96
+ }
97
+
98
+ public function customerrejectAction()
99
+ {
100
+
101
+ $couponid = $this->getRequest()->getPost('coupon_id');
102
+
103
+ $ownerbid = Mage::getModel('bargainprice/bargainprice')->getCollection()
104
+ ->addFieldToFilter('bargainprice_id', $couponid)
105
+ ->addFieldToSelect('*');
106
+
107
+ $record = Mage::getModel('bargainprice/bargainprice')->load($couponid);
108
+
109
+ foreach ($ownerbid as $finalbid):
110
+
111
+ $customer_status = $finalbid['status_customer'];
112
+ $discount = $finalbid['discount_code'];
113
+
114
+ endforeach;
115
+
116
+ if (empty($discount)):
117
+ if ($customer_status == 0):
118
+
119
+ $record->setData('status_customer', 3);
120
+ $record->save();
121
+
122
+ if ($record->save()):
123
+
124
+ $result = array();
125
+ $result['status'] = 'error';
126
+ $result['message'] = 'Success! You Rejected Request Successfully.';
127
+ echo Mage::helper('core')->jsonEncode($result);
128
+ exit();
129
+
130
+ else:
131
+ $result = array();
132
+ $result['status'] = 'error';
133
+ $result['message'] = 'Error! Something wrong Happend,Please Try Again Later.';
134
+ echo Mage::helper('core')->jsonEncode($result);
135
+ exit();
136
+
137
+ endif;
138
+ endif;
139
+ endif;
140
+ }
141
+
142
+ public function customeracceptAction()
143
+ {
144
+
145
+ $couponid = $this->getRequest()->getPost('coupon_id');
146
+
147
+ $ownerbid = Mage::getModel('bargainprice/bargainprice')->getCollection()
148
+ ->addFieldToFilter('bargainprice_id', $couponid)
149
+ ->addFieldToSelect('*');
150
+
151
+ $record = Mage::getModel('bargainprice/bargainprice')->load($couponid);
152
+ foreach ($ownerbid as $finalbid):
153
+
154
+ $customer_status = $finalbid['status_customer'];
155
+ $discount = $finalbid['discount_code'];
156
+ $final = $finalbid['owner_bid'];
157
+
158
+ endforeach;
159
+
160
+ if (empty($discount)):
161
+
162
+ if (($customer_status == 0 || $customer_status == 3) && !empty($final)):
163
+
164
+ $record->setData('status_customer', 1);
165
+ $record->save();
166
+ if ($record->save()):
167
+ $result = array();
168
+ $result['status'] = 'error';
169
+ $result['message'] = 'Success! You Approved Request Successfully.';
170
+ echo Mage::helper('core')->jsonEncode($result);
171
+ exit();
172
+ else:
173
+ $result = array();
174
+ $result['status'] = 'error';
175
+ $result['message'] = 'Error! Something wrong Happend,Please Try Again Later.';
176
+ echo Mage::helper('core')->jsonEncode($result);
177
+ exit();
178
+ endif;
179
+ endif;
180
+ endif;
181
+
182
+ }
183
+
184
+ public function gridViewAction()
185
+ {
186
+ if ($configValue = Mage::getStoreConfig('bargainprice/bargainselect/enabled') == 1) {
187
+ $customerData = Mage::getSingleton('customer/session')->getCustomer();
188
+ if (Mage::getSingleton('customer/session')->isLoggedIn()) {
189
+ $customer_id = $customerData->getId();
190
+ $bargainprice_collection = Mage::getModel('bargainprice/bargainprice')->getCollection();
191
+ $bargainprice_collection->addFieldToFilter('customer_id', array('eq' => $customer_id));
192
+ $i = 0;
193
+ $FinalResult = array();
194
+ foreach ($bargainprice_collection as $bargainprice_coupon) {
195
+ $FinalResult[$i]['id'] = $bargainprice_coupon['bargainprice_id'];
196
+ $FinalResult[$i]['discount_code'] = $bargainprice_coupon['discount_code'];
197
+ $FinalResult[$i]['product_name'] = $bargainprice_coupon['product_name'];
198
+ $FinalResult[$i]['product_sku'] = $bargainprice_coupon['product_sku'];
199
+ $FinalResult[$i]['product_price'] = $bargainprice_coupon['product_price'];
200
+ $FinalResult[$i]['new_price'] = $bargainprice_coupon['new_price'];
201
+ if (empty($bargainprice_coupon['owner_bid'])) {
202
+ if ($bargainprice_coupon['status_owner'] == 3) {
203
+ $FinalResult[$i]['owner_bid'] = "--";
204
+ } else {
205
+ $FinalResult[$i]['owner_bid'] = "Processing";
206
+ }
207
+
208
+ } else {
209
+ $FinalResult[$i]['owner_bid'] = $bargainprice_coupon['owner_bid'];
210
+ }
211
+
212
+ if (($bargainprice_coupon['status_customer'] == 0) && !empty($bargainprice_coupon['owner_bid'])) {
213
+ $FinalResult[$i]['status_customer'] = "<b><a class='yes' id='".$bargainprice_coupon['bargainprice_id']."'>Yes</a>&nbsp;|&nbsp;<a class='no' id='".$bargainprice_coupon['bargainprice_id']."'>No</a></b>";
214
+
215
+ } elseif (($bargainprice_coupon['status_customer'] == 3)) {
216
+ $FinalResult[$i]['status_customer'] = "rejected";
217
+
218
+ } elseif (($bargainprice_coupon['status_customer'] == 1)) {
219
+ $FinalResult[$i]['status_customer'] = "accepted";
220
+
221
+ } elseif (empty($bargainprice_coupon['owner_bid'])) {
222
+ $FinalResult[$i]['status_customer'] = "No bid Yet";
223
+
224
+ }
225
+
226
+ if ($bargainprice_coupon['status_owner'] == 1) {
227
+
228
+ $FinalResult[$i]['status_owner'] = 'Approved';
229
+ } elseif ($bargainprice_coupon['status_owner'] == 2) {
230
+
231
+ $FinalResult[$i]['status_owner'] = 'Waiting';
232
+ } elseif ($bargainprice_coupon['status_owner'] == 0) {
233
+
234
+ $FinalResult[$i]['status_owner'] = 'Pending';
235
+ } elseif ($bargainprice_coupon['status_owner'] == 3) {
236
+
237
+ $FinalResult[$i]['status_owner'] = 'Rejected';
238
+ }
239
+
240
+ }
241
+ $result = array();
242
+ $result['status'] = 'success';
243
+ $result['data'] = $FinalResult;
244
+ echo Mage::helper('core')->jsonEncode($result);
245
+ exit();
246
+
247
+ } else {
248
+ $result = array();
249
+ $result['status'] = 'error';
250
+ $result['message'] = 'Customer is not loged in';
251
+ echo Mage::helper('core')->jsonEncode($result);
252
+ exit();
253
+ }
254
+
255
+ } else {
256
+ $result = array();
257
+ $result['status'] = 'error';
258
+ $result['message'] = 'Bargain is not activated.';
259
+ echo Mage::helper('core')->jsonEncode($result);
260
+ exit();
261
+ }
262
+ }
263
+ }
app/code/local/Mss/Bargain/etc/config.xml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Mss_Bargain>
5
+ <version>0.1.0</version>
6
+ </Mss_Bargain>
7
+ </modules>
8
+ <frontend>
9
+ <routers>
10
+ <bargain>
11
+ <use>standard</use>
12
+ <args>
13
+ <module>Mss_Bargain</module>
14
+ <frontName>bargain</frontName>
15
+ </args>
16
+ </bargain>
17
+ </routers>
18
+ <layout>
19
+ <updates>
20
+ <bargain>
21
+ <file>bargain.xml</file>
22
+ </bargain>
23
+ </updates>
24
+ </layout>
25
+ </frontend>
26
+ <global>
27
+ <helpers>
28
+ <bargain>
29
+ <class>Mss_Bargain_Helper</class>
30
+ </bargain>
31
+ </helpers>
32
+ </global>
33
+ </config>
app/code/local/Mss/Connector/controllers/CustomerController.php CHANGED
@@ -96,7 +96,8 @@ class Mss_Connector_CustomerController extends Mage_Core_Controller_Front_Action
96
  switch ($e->getCode ()) {
97
  case Mage_Customer_Model_Customer::EXCEPTION_EMAIL_NOT_CONFIRMED :
98
  $value = Mage::helper ( 'customer' )->getEmailConfirmationUrl ( $username );
99
- $message = Mage::helper ( 'customer' )->__ ( 'This account is not confirmed. <a href="%s">Click here</a> to resend confirmation email.', $value );
 
100
  echo json_encode ( array (
101
  'status' => 'error',
102
  'message' => $this->__($message )
@@ -182,7 +183,7 @@ class Mss_Connector_CustomerController extends Mage_Core_Controller_Front_Action
182
  } catch ( Mage_Core_Exception $e ) {
183
  if ($e->getCode () === Mage_Customer_Model_Customer::EXCEPTION_EMAIL_EXISTS) {
184
  $url = Mage::getUrl ( 'customer/account/forgotpassword' );
185
- $message = $this->__( 'There is already an account with this email address. If you are sure that it is your email address, <a href="%s">click here</a> to get your password and access your account.', $url );
186
  $session->setEscapeMessages ( false );
187
  } else {
188
  $message = $this->__($e->getMessage ());
96
  switch ($e->getCode ()) {
97
  case Mage_Customer_Model_Customer::EXCEPTION_EMAIL_NOT_CONFIRMED :
98
  $value = Mage::helper ( 'customer' )->getEmailConfirmationUrl ( $username );
99
+ // $message = Mage::helper ( 'customer' )->__ ( 'This account is not confirmed. <a href="%s">Click here</a> to resend confirmation email.', $value );
100
+ $message = Mage::helper( 'customer' )->__ ( 'This account is not confirmed.Please check your registered email.', $value );
101
  echo json_encode ( array (
102
  'status' => 'error',
103
  'message' => $this->__($message )
183
  } catch ( Mage_Core_Exception $e ) {
184
  if ($e->getCode () === Mage_Customer_Model_Customer::EXCEPTION_EMAIL_EXISTS) {
185
  $url = Mage::getUrl ( 'customer/account/forgotpassword' );
186
+ $message = Mage::helper ( 'customer' )->__ ( 'This account is not confirmed.Please check your registered email.', $value );
187
  $session->setEscapeMessages ( false );
188
  } else {
189
  $message = $this->__($e->getMessage ());
app/code/local/Mss/Connector/controllers/IndexController.php CHANGED
@@ -211,8 +211,8 @@ class Mss_Connector_IndexController extends Mage_Core_Controller_Front_Action {
211
 
212
  $price = explode(',',$filter[0]);
213
  $price_filter = array('0'=>$price['0'],'1'=>$price['1']);
214
- $collection = $collection->addAttributeToFilter ( 'price', array ('gt' => $price['0'] ) );
215
- $collection = $collection->addAttributeToFilter ( 'price', array ('lt' => $price['1']) );
216
  else:
217
  $collection = $collection->addAttributeToFilter ( $key, array('in' => $filter) );
218
  endif;
@@ -513,7 +513,7 @@ class Mss_Connector_IndexController extends Mage_Core_Controller_Front_Action {
513
 
514
  if(sizeof($price_filter)):
515
 
516
- if($product->getFinalPrice() > $price_filter['0'] AND $product->getFinalPrice() < $price_filter['1']):
517
 
518
  $productlist [] = array (
519
  'entity_id' => $product->getId (),
@@ -630,7 +630,11 @@ class Mss_Connector_IndexController extends Mage_Core_Controller_Front_Action {
630
 
631
  $product = Mage::getModel ( 'catalog/product' )->load ( $product ['entity_id'] );
632
  $rating = Mage::getModel('rating/rating')->getEntitySummary($product->getId());
633
- $rating_final = ($rating->getSum()/$rating->getCount())/20;
 
 
 
 
634
 
635
  if($product->getTypeId() == "configurable")
636
  $qty = Mage::helper('connector')->getProductStockInfoById($product->getId());
@@ -686,8 +690,8 @@ class Mss_Connector_IndexController extends Mage_Core_Controller_Front_Action {
686
 
687
 
688
  $now = date('Y-m-d');
689
- $newsFrom= substr($_productCollection->getData('news_from_date'),0,10);
690
- $newsTo= substr($_productCollection->getData('news_to_date'),0,10);
691
 
692
  Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($_productCollection);
693
 
211
 
212
  $price = explode(',',$filter[0]);
213
  $price_filter = array('0'=>$price['0'],'1'=>$price['1']);
214
+ $collection = $collection->addAttributeToFilter ( 'price', array ('gteq' => $price['0'] ) );
215
+ $collection = $collection->addAttributeToFilter ( 'price', array ('lteq' => $price['1']) );
216
  else:
217
  $collection = $collection->addAttributeToFilter ( $key, array('in' => $filter) );
218
  endif;
513
 
514
  if(sizeof($price_filter)):
515
 
516
+ if($product->getFinalPrice() >= $price_filter['0'] AND $product->getFinalPrice() <= $price_filter['1']):
517
 
518
  $productlist [] = array (
519
  'entity_id' => $product->getId (),
630
 
631
  $product = Mage::getModel ( 'catalog/product' )->load ( $product ['entity_id'] );
632
  $rating = Mage::getModel('rating/rating')->getEntitySummary($product->getId());
633
+ if($rating->getCount()){
634
+ $rating_final = ($rating->getSum()/$rating->getCount())/20;
635
+ } else {
636
+ $rating_final = ($rating->getSum())/20;
637
+ }
638
 
639
  if($product->getTypeId() == "configurable")
640
  $qty = Mage::helper('connector')->getProductStockInfoById($product->getId());
690
 
691
 
692
  $now = date('Y-m-d');
693
+ $newsFrom= @substr($_productCollection->getData('news_from_date'),0,10);
694
+ $newsTo= @substr($_productCollection->getData('news_to_date'),0,10);
695
 
696
  Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($_productCollection);
697
 
app/code/local/Mss/Connector/controllers/StaticpagesController.php CHANGED
@@ -19,7 +19,7 @@ class Mss_Connector_StaticpagesController extends Mage_Core_Controller_Front_Act
19
  if($page):
20
  $page_model = Mage::getModel('cms/page')->load($page, 'identifier');
21
  $data [] = array('page_title'=>$page_model->getTitle(),
22
- 'page_content'=>$processor->filter($page_model->getContent()),
23
  'identifier'=>$page_model->getIdentifier());
24
  endif;
25
  endforeach;
19
  if($page):
20
  $page_model = Mage::getModel('cms/page')->load($page, 'identifier');
21
  $data [] = array('page_title'=>$page_model->getTitle(),
22
+ 'page_content'=> preg_replace('/<\/?a[^>]*>/','',$processor->filter($page_model->getContent())),
23
  'identifier'=>$page_model->getIdentifier());
24
  endif;
25
  endforeach;
app/code/local/Mss/Connector/controllers/index.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // ini_set('display_errors', 1);
3
+ // error_reporting(E_ALL);
4
+
5
+ // $_SERVER['MAGE_IS_DEVELOPER_MODE'] = true;
6
+
7
+
8
+ /**
9
+ * Magento
10
+ *
11
+ * NOTICE OF LICENSE
12
+ *
13
+ * This source file is subject to the Open Software License (OSL 3.0)
14
+ * that is bundled with this package in the file LICENSE.txt.
15
+ * It is also available through the world-wide-web at this URL:
16
+ * http://opensource.org/licenses/osl-3.0.php
17
+ * If you did not receive a copy of the license and are unable to
18
+ * obtain it through the world-wide-web, please send an email
19
+ * to license@magento.com so we can send you a copy immediately.
20
+ *
21
+ * DISCLAIMER
22
+ *
23
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
24
+ * versions in the future. If you wish to customize Magento for your
25
+ * needs please refer to http://www.magento.com for more information.
26
+ *
27
+ * @category Mage
28
+ * @package Mage
29
+ * @copyright Copyright (c) 2006-2017 X.commerce, Inc. and affiliates (http://www.magento.com)
30
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
31
+ */
32
+
33
+ if (version_compare(phpversion(), '5.3.0', '<')===true) {
34
+ echo '<div style="font:12px/1.35em arial, helvetica, sans-serif;">
35
+ <div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;">
36
+ <h3 style="margin:0; font-size:1.7em; font-weight:normal; text-transform:none; text-align:left; color:#2f2f2f;">
37
+ Whoops, it looks like you have an invalid PHP version.</h3></div><p>Magento supports PHP 5.3.0 or newer.
38
+ <a href="http://www.magentocommerce.com/install" target="">Find out</a> how to install</a>
39
+ Magento using PHP-CGI as a work-around.</p></div>';
40
+ exit;
41
+ }
42
+
43
+ /**
44
+ * Compilation includes configuration file
45
+ */
46
+ define('MAGENTO_ROOT', getcwd());
47
+
48
+ $compilerConfig = MAGENTO_ROOT . '/includes/config.php';
49
+ if (file_exists($compilerConfig)) {
50
+ include $compilerConfig;
51
+ }
52
+
53
+ $mageFilename = MAGENTO_ROOT . '/app/Mage.php';
54
+ $maintenanceFile = 'maintenance.flag';
55
+
56
+ if (!file_exists($mageFilename)) {
57
+ if (is_dir('downloader')) {
58
+ header("Location: downloader");
59
+ } else {
60
+ echo $mageFilename." was not found";
61
+ }
62
+ exit;
63
+ }
64
+
65
+ if (file_exists($maintenanceFile)) {
66
+ include_once dirname(__FILE__) . '/errors/503.php';
67
+ exit;
68
+ }
69
+
70
+ require MAGENTO_ROOT . '/app/bootstrap.php';
71
+ require_once $mageFilename;
72
+
73
+ #Varien_Profiler::enable();
74
+
75
+ if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) {
76
+ Mage::setIsDeveloperMode(true);
77
+ }
78
+
79
+ #ini_set('display_errors', 1);
80
+
81
+ umask(0);
82
+
83
+ /* Store or website code */
84
+ $mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
85
+
86
+ /* Run store or run website */
87
+ $mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
88
+
89
+ Mage::run($mageRunCode, $mageRunType);
app/code/local/Mss/Connector/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <Mss_Connector>
5
- <version>2.6.2</version>
6
  </Mss_Connector>
7
  </modules>
8
  <frontend>
2
  <config>
3
  <modules>
4
  <Mss_Connector>
5
+ <version>2.6.3</version>
6
  </Mss_Connector>
7
  </modules>
8
  <frontend>
app/code/local/Mss/Popup/Block/Popup.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ class Mss_Popup_Block_Popup extends Mage_Catalog_Block_Product_Abstract{
3
+
4
+ }
app/code/local/Mss/Popup/Helper/Data.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Mss_Popup_Helper_Data extends Mage_Core_Helper_Abstract{
3
+ public function getDelayTime(){
4
+ $delay = Mage::getStoreConfig('msspopup/settings/popup_delay');
5
+ $delayHours = $delay/1440;
6
+ return $delayHours;
7
+ }
8
+ public function getCookieExpire(){
9
+ $cookie = Mage::getStoreConfig('msspopup/settings/popup_cookie');
10
+ $cookieHours = $cookie/24;
11
+ return $cookieHours;
12
+ }
13
+ public function showPopUp(){
14
+ $allowedPages = Mage::getStoreConfig('msspopup/settings/popup_pages');
15
+ $currCmsPage = Mage::getSingleton('cms/page')->getIdentifier();
16
+ $currModule = Mage::app()->getFrontController()->getRequest()->getModuleName();
17
+ $pageArr = explode(',',$allowedPages);
18
+ foreach($pageArr as $key => $value){
19
+ if($currCmsPage == $value || $currModule == $value){
20
+ return "Y";
21
+ }
22
+ }
23
+ }
24
+ }
app/code/local/Mss/Popup/Model/Source/Page.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Mss_Popup_Model_Source_Page
3
+ {
4
+
5
+ protected $_options;
6
+
7
+ public function toOptionArray()
8
+ {
9
+ if (!$this->_options)
10
+ {
11
+ $this->_options = Mage::getResourceModel('cms/page_collection')
12
+ ->load()->toOptionIdArray();
13
+ }
14
+ $this->_options[] = array('value' => 'catalog', 'label' => 'Catalog');
15
+ $this->_options[] = array('value' => 'checkout', 'label' => 'Checkout');
16
+ return $this->_options;
17
+ }
18
+ }
app/code/local/Mss/Popup/Model/Source/Truefalse.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Mss_Popup_Model_Source_Truefalse
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return array(
7
+ array('value' => 'true', 'label' => 'True'),
8
+ array('value' => 'false', 'label' => 'False'),
9
+ );
10
+ }
11
+ }
app/code/local/Mss/Popup/etc/adminhtml.xml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <all>
6
+ <title>Allow Everything</title>
7
+ </all>
8
+ <admin>
9
+ <children>
10
+ <system>
11
+ <children>
12
+ <config>
13
+ <children>
14
+ <msspopup translate="title" module="connector">
15
+ <title>Popup</title>
16
+ <sort_order>10</sort_order>
17
+ </msspopup>
18
+ </children>
19
+ </config>
20
+ </children>
21
+ </system>
22
+ </children>
23
+ </admin>
24
+ </resources>
25
+ </acl>
26
+ </config>
app/code/local/Mss/Popup/etc/config.xml ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Mss_Popup>
5
+ <version>0.1.0</version>
6
+ </Mss_Popup>
7
+ </modules>
8
+ <frontend>
9
+ <layout>
10
+ <updates>
11
+ <popup>
12
+ <file>msspopup/popup.xml</file>
13
+ </popup>
14
+ </updates>
15
+ </layout>
16
+ </frontend>
17
+ <global>
18
+ <helpers>
19
+ <popup>
20
+ <class>Mss_Popup_Helper</class>
21
+ </popup>
22
+ </helpers>
23
+ <blocks>
24
+ <popup>
25
+ <class>Mss_Popup_Block</class>
26
+ </popup>
27
+ </blocks>
28
+ <models>
29
+ <popup>
30
+ <class>Mss_Popup_Model</class>
31
+ </popup>
32
+ </models>
33
+ <resources>
34
+ <!-- <popup_setup>
35
+ <setup>
36
+ <module>Mss_Popup</module>
37
+ </setup>
38
+ <connection>
39
+ <use>core_setup</use>
40
+ </connection>
41
+ </popup_setup> -->
42
+ </resources>
43
+ </global>
44
+ <default>
45
+ <msspopup>
46
+ <settings>
47
+ <popup_cookie>10</popup_cookie>
48
+ <popup_delay>.1</popup_delay>
49
+ </settings>
50
+ </msspopup>
51
+ </default>
52
+ </config>
app/code/local/Mss/Sociallogin/Helper/Data.php CHANGED
@@ -4,7 +4,7 @@ class Mss_Sociallogin_Helper_Data extends Mage_Core_Helper_Abstract
4
 
5
  private $sociallogin_support = array('facebook','google');
6
  private $f_url = 'https://graph.facebook.com/me?fields=first_name,last_name,gender,email&format=json&access_token=';
7
- private $g_url = 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&alt=json&access_token=';
8
  private $sociallogin_type;
9
 
10
  public function socialloginRequest($token,$sociallogintype){
4
 
5
  private $sociallogin_support = array('facebook','google');
6
  private $f_url = 'https://graph.facebook.com/me?fields=first_name,last_name,gender,email&format=json&access_token=';
7
+ private $g_url = 'https://www.googleapis.com/oauth2/v3/tokeninfo?alt=json&id_token=';
8
  private $sociallogin_type;
9
 
10
  public function socialloginRequest($token,$sociallogintype){
app/code/local/Mss/cache.cfg ADDED
Binary file
app/code/local/Mss/connect.cfg ADDED
@@ -0,0 +1 @@
 
1
+ ::ConnectConfig::v::1.0::a:12:{s:7:"php_ini";s:0:"";s:8:"protocol";s:5:"https";s:15:"preferred_state";s:6:"stable";s:27:"use_custom_permissions_mode";b:0;s:15:"global_dir_mode";i:511;s:16:"global_file_mode";i:438;s:15:"downloader_path";s:10:"downloader";s:12:"magento_root";s:42:"/var/www/html/magento-latest/downloader/..";s:16:"root_channel_uri";s:39:"connect20.magentocommerce.com/community";s:12:"root_channel";s:9:"community";s:13:"remote_config";s:0:"";s:9:"sync_pear";b:0;}
app/code/local/Mss/downloader/.cache/community/Bricks_Chekcout-0.0.1.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community/Exit_Screen_Pop_Up-1.0.2.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community/Mss_Connector-2.5.0.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community/Mss_Connector-2.5.1.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community/Mss_Connector-2.5.2.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community/Mss_Connector-2.6.1.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community/OrganicInternet_SimpleConfigurableProducts-0.7.4.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community/Owebia_Shipping_2-2.6.0.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community/toogas_featured_popup_free_version-1.0.6.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community@/Auctionmaid_Matrxrate-5.1.1.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community@/CashOnDelivery-1.0.8.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community@/Craig_Tco-2.4.2.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community@/Mss_Connector-2.4.9.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community@/PayU-India-Basic-1.0.0.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community@/Pook_CollectInStore-1.0.5.tgz ADDED
Binary file
app/code/local/Mss/downloader/.cache/community@/Zero1_Customshipprice-1.0.1.tgz ADDED
Binary file
app/code/local/Mss/downloader/.htaccess ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <IfModule mod_deflate.c>
2
+
3
+ RemoveOutputFilter DEFLATE
4
+ RemoveOutputFilter GZIP
5
+
6
+ </IfModule>
7
+
8
+ <Files ~ "\.(cfg|ini|xml)$">
9
+ order allow,deny
10
+ deny from all
11
+ </Files>
app/code/local/Mss/downloader/Maged/.htaccess ADDED
@@ -0,0 +1,2 @@
 
 
1
+ Order deny,allow
2
+ Deny from all
app/code/local/Mss/downloader/Maged/Connect.php ADDED
@@ -0,0 +1,517 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ error_reporting(E_ALL & ~E_NOTICE);
28
+
29
+ // just a shortcut
30
+ if (!defined('DS')) {
31
+ define('DS', DIRECTORY_SEPARATOR);
32
+ }
33
+
34
+ // add Mage lib in include_path if needed
35
+ $_includePath = get_include_path();
36
+ $_libDir = dirname(dirname(__FILE__)) . DS . 'lib';
37
+ if (strpos($_includePath, $_libDir) === false) {
38
+ if (substr($_includePath, 0, 2) === '.' . PATH_SEPARATOR) {
39
+ $_includePath = '.' . PATH_SEPARATOR . $_libDir . PATH_SEPARATOR . substr($_includePath, 2);
40
+ } else {
41
+ $_includePath = $_libDir . PATH_SEPARATOR . $_includePath;
42
+ }
43
+ set_include_path($_includePath);
44
+ }
45
+
46
+ /**
47
+ * Class for connect
48
+ *
49
+ * @category Mage
50
+ * @package Mage_Connect
51
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
52
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
53
+ */
54
+ class Maged_Connect
55
+ {
56
+
57
+ /**
58
+ * Object of config
59
+ *
60
+ * @var Mage_Connect_Config
61
+ */
62
+ protected $_config;
63
+
64
+ /**
65
+ * Object of single config
66
+ *
67
+ * @var Mage_Connect_Singleconfig
68
+ */
69
+ protected $_sconfig;
70
+
71
+ /**
72
+ * Object of frontend
73
+ *
74
+ * @var Mage_Connect_Frontend
75
+ */
76
+ protected $_frontend;
77
+
78
+ /**
79
+ * Internal cache for command objects
80
+ *
81
+ * @var array
82
+ */
83
+ protected $_cmdCache = array();
84
+
85
+ /**
86
+ * Console Started flag
87
+ *
88
+ * @var boolean
89
+ */
90
+ protected $_consoleStarted = false;
91
+
92
+ /**
93
+ * Instance of class
94
+ *
95
+ * @var Maged_Connect
96
+ */
97
+ static protected $_instance;
98
+
99
+ /**
100
+ * Constructor loads Config, Cache Config and initializes Frontend
101
+ */
102
+ public function __construct()
103
+ {
104
+ $this->getConfig();
105
+ $this->getSingleConfig();
106
+ $this->getFrontend();
107
+ }
108
+
109
+ /**
110
+ * Destructor, sends Console footer if Console started
111
+ */
112
+ public function __destruct()
113
+ {
114
+ if ($this->_consoleStarted) {
115
+ $this->_consoleFooter();
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Initialize instance
121
+ *
122
+ * @return Maged_Connect
123
+ */
124
+ public static function getInstance()
125
+ {
126
+ if (!self::$_instance) {
127
+ self::$_instance = new self;
128
+ }
129
+ return self::$_instance;
130
+ }
131
+
132
+ /**
133
+ * Retrieve object of config and set it to Mage_Connect_Command
134
+ *
135
+ * @return Mage_Connect_Config
136
+ */
137
+ public function getConfig()
138
+ {
139
+ if (!$this->_config) {
140
+ $this->_config = new Mage_Connect_Config();
141
+ $ftp=$this->_config->__get('remote_config');
142
+ if(!empty($ftp)){
143
+ $packager = new Mage_Connect_Packager();
144
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
145
+ $this->_config=$config;
146
+ $this->_sconfig=$cache;
147
+ }
148
+ $this->_config->magento_root = dirname(dirname(__FILE__)).DS.'..';
149
+ Mage_Connect_Command::setConfigObject($this->_config);
150
+ }
151
+ return $this->_config;
152
+ }
153
+
154
+ /**
155
+ * Retrieve object of single config and set it to Mage_Connect_Command
156
+ *
157
+ * @param bool $reload
158
+ * @return Mage_Connect_Singleconfig
159
+ */
160
+ public function getSingleConfig($reload = false)
161
+ {
162
+ if(!$this->_sconfig || $reload) {
163
+ $this->_sconfig = new Mage_Connect_Singleconfig(
164
+ $this->getConfig()->magento_root . DIRECTORY_SEPARATOR
165
+ . $this->getConfig()->downloader_path . DIRECTORY_SEPARATOR
166
+ . Mage_Connect_Singleconfig::DEFAULT_SCONFIG_FILENAME
167
+ );
168
+ }
169
+ Mage_Connect_Command::setSconfig($this->_sconfig);
170
+ return $this->_sconfig;
171
+
172
+ }
173
+
174
+ /**
175
+ * Retrieve object of frontend and set it to Mage_Connect_Command
176
+ *
177
+ * @return Maged_Connect_Frontend
178
+ */
179
+ public function getFrontend()
180
+ {
181
+ if (!$this->_frontend) {
182
+ $this->_frontend = new Maged_Connect_Frontend();
183
+ Mage_Connect_Command::setFrontendObject($this->_frontend);
184
+ }
185
+ return $this->_frontend;
186
+ }
187
+
188
+ /**
189
+ * Retrieve lof from frontend
190
+ *
191
+ * @return array
192
+ */
193
+ public function getLog()
194
+ {
195
+ return $this->getFrontend()->getLog();
196
+ }
197
+
198
+ /**
199
+ * Retrieve output from frontend
200
+ *
201
+ * @return array
202
+ */
203
+ public function getOutput()
204
+ {
205
+ return $this->getFrontend()->getOutput();
206
+ }
207
+
208
+ /**
209
+ * Clean registry
210
+ *
211
+ * @return Maged_Connect
212
+ */
213
+ public function cleanSconfig()
214
+ {
215
+ $this->getSingleConfig()->clear();
216
+ return $this;
217
+ }
218
+
219
+ /**
220
+ * Delete directory recursively
221
+ *
222
+ * @param string $path
223
+ * @return Maged_Connect
224
+ */
225
+ public function delTree($path) {
226
+ if (@is_dir($path)) {
227
+ $entries = @scandir($path);
228
+ foreach ($entries as $entry) {
229
+ if ($entry != '.' && $entry != '..') {
230
+ $this->delTree($path.DS.$entry);
231
+ }
232
+ }
233
+ @rmdir($path);
234
+ } else {
235
+ @unlink($path);
236
+ }
237
+ return $this;
238
+ }
239
+
240
+ /**
241
+ * Run commands from Mage_Connect_Command
242
+ *
243
+ * @param string $command
244
+ * @param array $options
245
+ * @param array $params
246
+ * @return boolean|Mage_Connect_Error
247
+ */
248
+ public function run($command, $options=array(), $params=array())
249
+ {
250
+ @set_time_limit(0);
251
+ @ini_set('memory_limit', '256M');
252
+
253
+ if (empty($this->_cmdCache[$command])) {
254
+ Mage_Connect_Command::getCommands();
255
+ /**
256
+ * @var $cmd Mage_Connect_Command
257
+ */
258
+ $cmd = Mage_Connect_Command::getInstance($command);
259
+ if ($cmd instanceof Mage_Connect_Error) {
260
+ return $cmd;
261
+ }
262
+ $this->_cmdCache[$command] = $cmd;
263
+ } else {
264
+ /**
265
+ * @var $cmd Mage_Connect_Command
266
+ */
267
+ $cmd = $this->_cmdCache[$command];
268
+ }
269
+ $ftp=$this->getConfig()->remote_config;
270
+ if(strlen($ftp)>0){
271
+ $options=array_merge($options, array('ftp'=>$ftp));
272
+ }
273
+ $cmd->run($command, $options, $params);
274
+ if ($cmd->ui()->hasErrors()) {
275
+ return false;
276
+ } else {
277
+ return true;
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Set remote Config by URI
283
+ *
284
+ * @param $uri
285
+ * @return Maged_Connect
286
+ */
287
+ public function setRemoteConfig($uri)
288
+ {
289
+ $this->getConfig()->remote_config=$uri;
290
+ return $this;
291
+ }
292
+
293
+ /**
294
+ * Show Errors
295
+ *
296
+ * @param array $errors Error messages
297
+ * @return Maged_Connect
298
+ */
299
+ public function showConnectErrors($errors)
300
+ {
301
+ echo '<script type="text/javascript">';
302
+ $run = new Maged_Model_Connect_Request();
303
+ if ($callback = $run->get('failure_callback')) {
304
+ if (is_array($callback)) {
305
+ call_user_func_array($callback, array($errors));
306
+ } else {
307
+ echo $callback;
308
+ }
309
+ }
310
+ echo '</script>';
311
+
312
+ return $this;
313
+ }
314
+
315
+ /**
316
+ * Run Mage_Connect_Command with html output console style
317
+ *
318
+ * @throws Maged_Exception
319
+ * @param array|string|Maged_Model $runParams command, options, params, comment, success_callback, failure_callback
320
+ * @return bool|Mage_Connect_Error
321
+ */
322
+ public function runHtmlConsole($runParams)
323
+ {
324
+ if (function_exists('apache_setenv')) {
325
+ apache_setenv('no-gzip', '1');
326
+ }
327
+ @ini_set('zlib.output_compression', 0);
328
+ @ini_set('implicit_flush', 1);
329
+ for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
330
+ ob_implicit_flush();
331
+
332
+ $fe = $this->getFrontend();
333
+ $oldLogStream = $fe->getLogStream();
334
+ $fe->setLogStream('stdout');
335
+
336
+ if ($runParams instanceof Maged_Model) {
337
+ $run = $runParams;
338
+ } elseif (is_array($runParams)) {
339
+ $run = new Maged_Model_Connect_Request($runParams);
340
+ } elseif (is_string($runParams)) {
341
+ $run = new Maged_Model_Connect_Request(array('comment'=>$runParams));
342
+ } else {
343
+ throw Maged_Exception("Invalid run parameters");
344
+ }
345
+
346
+ if (!$run->get('no-header')) {
347
+ $this->_consoleHeader();
348
+ }
349
+ echo htmlspecialchars($run->get('comment')).'<br/>';
350
+
351
+ if ($command = $run->get('command')) {
352
+ $result = $this->run($command, $run->get('options'), $run->get('params'));
353
+
354
+ if ($this->getFrontend()->hasErrors()) {
355
+ echo "<br/>CONNECT ERROR: ";
356
+ foreach ($this->getFrontend()->getErrors(false) as $error) {
357
+ echo nl2br($error[1]);
358
+ echo '<br/>';
359
+ }
360
+ }
361
+ echo '<script type="text/javascript">';
362
+ if ($this->getFrontend()->hasErrors()) {
363
+ if ($callback = $run->get('failure_callback')) {
364
+ if (is_array($callback)) {
365
+ call_user_func_array($callback, array($result));
366
+ } else {
367
+ echo $callback;
368
+ }
369
+ }
370
+ } else {
371
+ if (!$run->get('no-footer')) {
372
+ if ($callback = $run->get('success_callback')) {
373
+ if (is_array($callback)) {
374
+ call_user_func_array($callback, array($result));
375
+ } else {
376
+ echo $callback;
377
+ }
378
+ }
379
+ }
380
+ }
381
+ echo '</script>';
382
+ } else {
383
+ $result = false;
384
+ }
385
+ if ($this->getFrontend()->getErrors() || !$run->get('no-footer')) {
386
+ //$this->_consoleFooter();
387
+ $fe->setLogStream($oldLogStream);
388
+ }
389
+ return $result;
390
+ }
391
+
392
+ /**
393
+ * Show HTML Console Header
394
+ *
395
+ * @return void
396
+ */
397
+ protected function _consoleHeader() {
398
+ if (!$this->_consoleStarted) {
399
+ ?>
400
+ <html><head><style type="text/css">
401
+ body { margin:0px;
402
+ padding:3px;
403
+ background:black;
404
+ color:#2EC029;
405
+ font:normal 11px Lucida Console, Courier New, serif;
406
+ }
407
+ </style></head><body>
408
+ <script type="text/javascript">
409
+ if (parent && parent.disableInputs) {
410
+ parent.disableInputs(true);
411
+ }
412
+ if (typeof auto_scroll=='undefined') {
413
+ var auto_scroll = window.setInterval(console_scroll, 10);
414
+ }
415
+ function console_scroll()
416
+ {
417
+ if (typeof top.$ != 'function') {
418
+ return;
419
+ }
420
+ if (top.$('connect_iframe_scroll').checked) {
421
+ document.body.scrollTop+=3;
422
+ }
423
+ }
424
+ function show_message(message, newline)
425
+ {
426
+ var bodyElement = document.getElementsByTagName('body')[0];
427
+ if (typeof newline == 'undefined') {
428
+ newline = true
429
+ }
430
+ if (newline) {
431
+ bodyElement.innerHTML += '<br/>';
432
+ }
433
+ bodyElement.innerHTML += message;
434
+ }
435
+ function clear_cache(callbacks)
436
+ {
437
+ if (typeof top.Ajax != 'object') {
438
+ return;
439
+ }
440
+ var message = 'Exception during cache and session cleaning';
441
+ var url = window.location.href.split('?')[0] + '?A=cleanCache';
442
+ var intervalID = setInterval(function() {show_message('.', false); }, 500);
443
+ var clean = 0;
444
+ var maintenance = 0;
445
+ if (window.location.href.indexOf('clean_sessions') >= 0) {
446
+ clean = 1;
447
+ }
448
+ if (window.location.href.indexOf('maintenance') >= 0) {
449
+ maintenance = 1;
450
+ }
451
+
452
+ new top.Ajax.Request(url, {
453
+ method: 'post',
454
+ parameters: {clean_sessions:clean, maintenance:maintenance},
455
+ onCreate: function() {
456
+ show_message('Cleaning cache');
457
+ show_message('');
458
+ },
459
+ onSuccess: function(transport, json) {
460
+ var result = true;
461
+ try{
462
+ var response = eval('(' + transport.responseText + ')');
463
+ if (typeof response.result != 'undefined') {
464
+ result = response.result;
465
+ } else {
466
+ result = false;
467
+ }
468
+ if (typeof response.message != 'undefined') {
469
+ if (response.message.length > 0) {
470
+ message = response.message;
471
+ } else {
472
+ message = 'Cache cleaned successfully';
473
+ }
474
+ }
475
+ } catch (ex){
476
+ result = false;
477
+ }
478
+ if (result) {
479
+ callbacks.success();
480
+ } else {
481
+ callbacks.fail();
482
+ }
483
+ },
484
+ onFailure: function() {
485
+ callbacks.fail();
486
+ },
487
+ onComplete: function(transport) {
488
+ clearInterval(intervalID);
489
+ show_message(message);
490
+ }
491
+ });
492
+ }
493
+ </script>
494
+ <?php
495
+ $this->_consoleStarted = true;
496
+ }
497
+ }
498
+
499
+ /**
500
+ * Show HTML Console Footer
501
+ *
502
+ * @return void
503
+ */
504
+ protected function _consoleFooter() {
505
+ if ($this->_consoleStarted) {
506
+ ?>
507
+ <script type="text/javascript">
508
+ if (parent && parent.disableInputs) {
509
+ parent.disableInputs(false);
510
+ }
511
+ </script>
512
+ </body></html>
513
+ <?php
514
+ $this->_consoleStarted = false;
515
+ }
516
+ }
517
+ }
app/code/local/Mss/downloader/Maged/Connect/Frontend.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class frontend
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ class Maged_Connect_Frontend extends Mage_Connect_Frontend
36
+ {
37
+
38
+ /**
39
+ * Log stream or not
40
+ *
41
+ * @var string
42
+ */
43
+ protected $_logStream = null;
44
+
45
+ /**
46
+ * Output cache
47
+ *
48
+ * @var array
49
+ */
50
+ protected $_out = array();
51
+
52
+ /**
53
+ * Set log stream
54
+ *
55
+ * @param string|resource $stream 'stdout' or open php stream
56
+ */
57
+ public function setLogStream($stream)
58
+ {
59
+ $this->_logStream = $stream;
60
+ return $this;
61
+ }
62
+
63
+ /**
64
+ * Retrieve log stream
65
+ *
66
+ * @return string
67
+ */
68
+ public function getLogStream()
69
+ {
70
+ return $this->_logStream;
71
+ }
72
+
73
+ /**
74
+ * Echo data from executed command
75
+ */
76
+ public function output($data)
77
+ {
78
+
79
+ $this->_out = $data;
80
+
81
+ if ('stdout'===$this->_logStream) {
82
+ if (is_string($data)) {
83
+ echo $data."<br/>".str_repeat(" ", 256);
84
+ } elseif (is_array($data)) {
85
+ $data = array_pop($data);
86
+ if (!empty($data['message']) && is_string($data['message'])) {
87
+ echo $data['message']."<br/>".str_repeat(" ", 256);
88
+ } elseif (!empty($data['data'])) {
89
+ if (is_string($data['data'])) {
90
+ echo $data['data']."<br/>".str_repeat(" ", 256);
91
+ } else {
92
+ if (isset($data['title'])) {
93
+ echo $data['title']."<br/>".str_repeat(" ", 256);
94
+ }
95
+ if (is_array($data['data'])) {
96
+ foreach ($data['data'] as $row) {
97
+ foreach ($row as $msg) {
98
+ echo "&nbsp;".$msg;
99
+ }
100
+ echo "<br/>".str_repeat(" ", 256);
101
+ }
102
+ } else {
103
+ echo "&nbsp;".$data['data'];
104
+ }
105
+ }
106
+ }
107
+ } else {
108
+ print_r($data);
109
+ }
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Method for ask client about rewrite all files.
115
+ *
116
+ * @param $string
117
+ */
118
+ public function confirm($string)
119
+ {
120
+ $formId = $_POST['form_id'];
121
+ echo <<<SCRIPT
122
+ <script type="text/javascript">
123
+ if (confirm("{$string}")) {
124
+ parent.document.getElementById('ignore_local_modification').value=1;
125
+ parent.onSuccess();
126
+ if (parent && parent.disableInputs) {
127
+ parent.disableInputs(false);
128
+ }
129
+ window.onload = function () {
130
+ parent.document.getElementById('{$formId}').submit();
131
+ parent.document.getElementById('ignore_local_modification').value='';
132
+ }
133
+ }
134
+ </script>
135
+ SCRIPT;
136
+ }
137
+
138
+ /**
139
+ * Retrieve output cache
140
+ *
141
+ * @param bool $clearPrevious
142
+ * @return array|mixed
143
+ */
144
+ public function getOutput($clearPrevious = false)
145
+ {
146
+ return $this->_out;
147
+ }
148
+
149
+ }
150
+
app/code/local/Mss/downloader/Maged/Controller.php ADDED
@@ -0,0 +1,1154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class Controller
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ final class Maged_Controller
36
+ {
37
+ /**
38
+ * Request key of action
39
+ */
40
+ const ACTION_KEY = 'A';
41
+
42
+ /**
43
+ * Instance of class
44
+ *
45
+ * @var Maged_Controller
46
+ */
47
+ private static $_instance;
48
+
49
+ /**
50
+ * Current action name
51
+ *
52
+ * @var string
53
+ */
54
+ private $_action;
55
+
56
+ /**
57
+ * Controller is dispathed flag
58
+ *
59
+ * @var bool
60
+ */
61
+ private $_isDispatched = false;
62
+
63
+ /**
64
+ * Redirect to URL
65
+ *
66
+ * @var string
67
+ */
68
+ private $_redirectUrl;
69
+
70
+ /**
71
+ * Downloader dir path
72
+ *
73
+ * @var string
74
+ */
75
+ private $_rootDir;
76
+
77
+ /**
78
+ * Magento root dir path
79
+ *
80
+ * @var string
81
+ */
82
+ private $_mageDir;
83
+
84
+ /**
85
+ * View instance
86
+ *
87
+ * @var Maged_View
88
+ */
89
+ private $_view;
90
+
91
+ /**
92
+ * Connect config instance
93
+ *
94
+ * @var Mage_Connect_Config
95
+ */
96
+ private $_config;
97
+
98
+ /**
99
+ * Config instance
100
+ *
101
+ * @var Maged_Model_Config
102
+ */
103
+ private $_localConfig;
104
+
105
+ /**
106
+ * Session instance
107
+ *
108
+ * @var Maged_Model_Session
109
+ */
110
+ private $_session;
111
+
112
+ /**
113
+ * Root dir is writable flag
114
+ *
115
+ * @var bool
116
+ */
117
+ private $_writable;
118
+
119
+ /**
120
+ * Use maintenance flag
121
+ *
122
+ * @var bool
123
+ */
124
+ protected $_maintenance;
125
+
126
+ /**
127
+ * Maintenance file path
128
+ *
129
+ * @var string
130
+ */
131
+ protected $_maintenanceFile;
132
+
133
+ /**
134
+ * Register array for singletons
135
+ *
136
+ * @var array
137
+ */
138
+ protected $_singletons = array();
139
+
140
+ //////////////////////////// ACTIONS
141
+
142
+
143
+ /**
144
+ * Get ftp string from post data
145
+ *
146
+ * @param array $post post data
147
+ * @return string FTP Url
148
+ */
149
+ private function getFtpPost($post){
150
+ if (empty($post['ftp_host'])) {
151
+ $_POST['ftp'] = '';
152
+ return '';
153
+ }
154
+ $ftp = 'ftp://';
155
+ $post['ftp_proto'] = 'ftp://';
156
+
157
+ if (!empty($post['ftp_path']) && strlen(trim($post['ftp_path'], '\\/')) > 0) {
158
+ $post['ftp_path'] = '/' . trim($post['ftp_path'], '\\/') . '/';
159
+ } else {
160
+ $post['ftp_path'] = '/';
161
+ }
162
+
163
+ $start = stripos($post['ftp_host'],'ftp://');
164
+ if ($start !== false){
165
+ $post['ftp_proto'] = 'ftp://';
166
+ $post['ftp_host'] = substr($post['ftp_host'], $start + 6 - 1);
167
+ }
168
+ $start = stripos($post['ftp_host'],'ftps://');
169
+ if ($start !== false) {
170
+ $post['ftp_proto'] = 'ftps://';
171
+ $post['ftp_host'] = substr($post['ftp_host'], $start + 7 - 1);
172
+ }
173
+
174
+ $post['ftp_host'] = trim($post['ftp_host'], '\\/');
175
+
176
+ if (!empty($post['ftp_login']) && !empty($post['ftp_password'])){
177
+ $ftp = sprintf("%s%s:%s@%s%s",
178
+ $post['ftp_proto'],
179
+ $post['ftp_login'],
180
+ $post['ftp_password'],
181
+ $post['ftp_host'],
182
+ $post['ftp_path']
183
+ );
184
+ } elseif (!empty($post['ftp_login'])) {
185
+ $ftp = sprintf(
186
+ "%s%s@%s%s",
187
+ $post['ftp_proto'],
188
+ $post['ftp_login'],
189
+ $post['ftp_host'],
190
+ $post['ftp_path']
191
+ );
192
+ } else {
193
+ $ftp = $post['ftp_proto'] . $post['ftp_host'] . $post['ftp_path'];
194
+ }
195
+
196
+ $_POST['ftp'] = $ftp;
197
+ return $ftp;
198
+ }
199
+
200
+ /**
201
+ * NoRoute
202
+ */
203
+ public function norouteAction()
204
+ {
205
+ header("HTTP/1.0 404 Invalid Action");
206
+ echo $this->view()->template('noroute.phtml');
207
+ }
208
+
209
+ /**
210
+ * Login
211
+ */
212
+ public function loginAction()
213
+ {
214
+ $this->view()->set('username', !empty($_GET['username']) ? $_GET['username'] : '');
215
+ echo $this->view()->template('login.phtml');
216
+ }
217
+
218
+ /**
219
+ * Logout
220
+ */
221
+ public function logoutAction()
222
+ {
223
+ $this->session()->logout();
224
+ $this->redirect($this->url());
225
+ }
226
+
227
+ /**
228
+ * Index
229
+ */
230
+ public function indexAction()
231
+ {
232
+ $config = $this->config();
233
+ if (!$this->isInstalled()) {
234
+ $this->view()->set('mage_url', dirname(dirname($_SERVER['SCRIPT_NAME'])));
235
+ $this->view()->set(
236
+ 'use_custom_permissions_mode',
237
+ $config->__get('use_custom_permissions_mode')
238
+ ? $config->__get('use_custom_permissions_mode')
239
+ : '0'
240
+ );
241
+ $this->view()->set('mkdir_mode', decoct($config->__get('global_dir_mode')));
242
+ $this->view()->set('chmod_file_mode', decoct($config->__get('global_file_mode')));
243
+ $this->view()->set('protocol', $config->__get('protocol'));
244
+ $this->channelConfig()->setInstallView($config,$this->view());
245
+
246
+ echo $this->view()->template('install/download.phtml');
247
+ } elseif (!$config->sync_pear) {
248
+ $this->model('connect', true)->connect()->run('sync');
249
+ $this->forward('connectPackages');
250
+ } else {
251
+ $this->forward('connectPackages');
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Empty Action
257
+ */
258
+ public function emptyAction()
259
+ {
260
+ $this->model('connect', true)
261
+ ->connect()
262
+ ->runHtmlConsole('Please wait, preparing for updates...');
263
+ }
264
+
265
+ /**
266
+ * Install all magento
267
+ */
268
+ public function connectInstallAllAction()
269
+ {
270
+ $p = &$_POST;
271
+ $this->getFtpPost($p);
272
+ $errors = $this->model('connect', true)->validateConfigPost($p);
273
+ /* todo show errors */
274
+ if ($errors) {
275
+ $message = "CONNECT ERROR: ";
276
+ foreach ($errors as $err) {
277
+ $message .= $err . "\n";
278
+ }
279
+ $this->model('connect', true)->connect()->runHtmlConsole($message);
280
+ $this->model('connect', true)->connect()->showConnectErrors($errors);
281
+ return;
282
+ }
283
+
284
+ if( 1 == $p['inst_protocol']){
285
+ $this->model('connect', true)->connect()->setRemoteConfig($this->getFtpPost($p));
286
+ }
287
+
288
+ $this->channelConfig()->setPostData($this->config(),$p);
289
+
290
+ $chan = $this->config()->__get('root_channel');
291
+ $this->model('connect', true)->saveConfigPost($_POST);
292
+ $this->channelConfig()->setSettingsSession($_POST, $this->session());
293
+ $this->model('connect', true)->installAll(!empty($_GET['force']), $chan);
294
+ $p = null;
295
+ }
296
+
297
+ /**
298
+ * Connect packages
299
+ */
300
+ public function connectPackagesAction()
301
+ {
302
+ $connect = $this->model('connect', true);
303
+
304
+ if (isset($_GET['loggedin'])) {
305
+ $connect->connect()->run('sync');
306
+ }
307
+
308
+ $this->view()->set('connect', $connect);
309
+ $this->view()->set('channel_config', $this->channelConfig());
310
+ $remoteConfig = $this->config()->remote_config;
311
+ if (!$this->isWritable() && empty($remoteConfig)) {
312
+ $this->view()->set('writable_warning', true);
313
+ }
314
+
315
+ echo $this->view()->template('connect/packages.phtml');
316
+ }
317
+
318
+ /**
319
+ * Connect packages POST
320
+ */
321
+ public function connectPackagesPostAction()
322
+ {
323
+ if (!$this->_validateFormKey()) {
324
+ echo "INVALID POST DATA";
325
+ return;
326
+ }
327
+ $actions = isset($_POST['actions']) ? $_POST['actions'] : array();
328
+ if (isset($_POST['ignore_local_modification'])) {
329
+ $ignoreLocalModification = $_POST['ignore_local_modification'];
330
+ } else {
331
+ $ignoreLocalModification = '';
332
+ }
333
+ $this->model('connect', true)->applyPackagesActions($actions, $ignoreLocalModification);
334
+ }
335
+
336
+ /**
337
+ * Prepare package to install, get dependency info.
338
+ */
339
+ public function connectPreparePackagePostAction()
340
+ {
341
+ if (!$this->_validateFormKey()) {
342
+ echo "INVALID POST DATA";
343
+ return;
344
+ }
345
+ if (!$_POST) {
346
+ echo "INVALID POST DATA";
347
+ return;
348
+ }
349
+ $prepareResult = $this->model('connect', true)->prepareToInstall($_POST['install_package_id']);
350
+
351
+ $packages = isset($prepareResult['data']) ? $prepareResult['data'] : array();
352
+ $errors = isset($prepareResult['errors']) ? $prepareResult['errors'] : array();
353
+
354
+ $this->view()->set('packages', $packages);
355
+ $this->view()->set('errors', $errors);
356
+ $this->view()->set('package_id', $_POST['install_package_id']);
357
+
358
+ echo $this->view()->template('connect/packages_prepare.phtml');
359
+ }
360
+
361
+ /**
362
+ * Install package
363
+ */
364
+ public function connectInstallPackagePostAction()
365
+ {
366
+ if (!$this->_validateFormKey()) {
367
+ echo "INVALID POST DATA";
368
+ return;
369
+ }
370
+ if (!$_POST) {
371
+ echo "INVALID POST DATA";
372
+ return;
373
+ }
374
+ $this->model('connect', true)->installPackage($_POST['install_package_id']);
375
+ }
376
+
377
+ /**
378
+ * Install uploaded package
379
+ */
380
+ public function connectInstallPackageUploadAction()
381
+ {
382
+ if (!$this->_validateFormKey()) {
383
+ echo "No file was uploaded";
384
+ return;
385
+ }
386
+
387
+ if (!$_FILES) {
388
+ echo "No file was uploaded";
389
+ return;
390
+ }
391
+
392
+ if(empty($_FILES['file'])) {
393
+ echo "No file was uploaded";
394
+ return;
395
+ }
396
+
397
+ $info =& $_FILES['file'];
398
+
399
+ if(0 !== intval($info['error'])) {
400
+ echo "File upload problem";
401
+ return;
402
+ }
403
+
404
+ $target = $this->_mageDir . DS . "var/" . uniqid() . $info['name'];
405
+ $res = move_uploaded_file($info['tmp_name'], $target);
406
+ if(false === $res) {
407
+ echo "Error moving uploaded file";
408
+ return;
409
+ }
410
+
411
+ $this->model('connect', true)->installUploadedPackage($target);
412
+ @unlink($target);
413
+ }
414
+
415
+ /**
416
+ * Clean cache on ajax request
417
+ */
418
+ public function cleanCacheAction()
419
+ {
420
+ $result = $this->cleanCache();
421
+ echo json_encode($result);
422
+ }
423
+
424
+ /**
425
+ * Settings
426
+ */
427
+ public function settingsAction()
428
+ {
429
+ $config = $this->config();
430
+ $this->view()->set('preferred_state', $config->__get('preferred_state'));
431
+ $this->view()->set('protocol', $config->__get('protocol'));
432
+
433
+ $this->view()->set('use_custom_permissions_mode', $config->__get('use_custom_permissions_mode'));
434
+ $this->view()->set('mkdir_mode', decoct($config->__get('global_dir_mode')));
435
+ $this->view()->set('chmod_file_mode', decoct($config->__get('global_file_mode')));
436
+
437
+ $this->channelConfig()->setSettingsView($this->session(), $this->view());
438
+
439
+ $fs_disabled =! $this->isWritable();
440
+ $ftpParams = $config->__get('remote_config') ? @parse_url($config->__get('remote_config')) : '';
441
+
442
+ $this->view()->set('fs_disabled', $fs_disabled);
443
+ $this->view()->set('deployment_type', ($fs_disabled || !empty($ftpParams) ? 'ftp' : 'fs'));
444
+
445
+ if (!empty($ftpParams)) {
446
+ $this->view()->set('ftp_host', sprintf("%s://%s", $ftpParams['scheme'], $ftpParams['host']));
447
+ $this->view()->set('ftp_login', $ftpParams['user']);
448
+ $this->view()->set('ftp_password', $ftpParams['pass']);
449
+ $this->view()->set('ftp_path', $ftpParams['path']);
450
+ }
451
+ echo $this->view()->template('settings.phtml');
452
+ }
453
+
454
+ /**
455
+ * Settings post
456
+ */
457
+ public function settingsPostAction()
458
+ {
459
+ if (!$this->_validateFormKey()) {
460
+ $this->session()->addMessage('error', "Unable to save settings");
461
+ $this->redirect($this->url('settings'));
462
+ return;
463
+ }
464
+ if ($_POST) {
465
+ $ftp = $this->getFtpPost($_POST);
466
+
467
+ /* clear startup messages */
468
+ $this->config();
469
+ $this->session()->getMessages();
470
+
471
+ $errors = $this->model('connect', true)->validateConfigPost($_POST);
472
+ if ($errors) {
473
+ foreach ($errors as $err) {
474
+ $this->session()->addMessage('error', $err);
475
+ }
476
+ $this->redirect($this->url('settings'));
477
+ return;
478
+ }
479
+ try {
480
+ if ('ftp' == $_POST['deployment_type'] && !empty($_POST['ftp_host'])) {
481
+ $this->model('connect', true)->connect()->setRemoteConfig($ftp);
482
+ } else {
483
+ $this->model('connect', true)->connect()->setRemoteConfig('');
484
+ $_POST['ftp'] = '';
485
+ }
486
+ $this->channelConfig()->setPostData($this->config(), $_POST);
487
+ $this->model('connect', true)->saveConfigPost($_POST);
488
+ $this->channelConfig()->setSettingsSession($_POST, $this->session());
489
+ $this->model('connect', true)->connect()->run('sync');
490
+ } catch (Exception $e) {
491
+ $this->session()->addMessage('error', "Unable to save settings: " . $e->getMessage());
492
+ }
493
+ }
494
+ $this->redirect($this->url('settings'));
495
+ }
496
+
497
+ //////////////////////////// ABSTRACT
498
+
499
+ /**
500
+ * Constructor
501
+ */
502
+ public function __construct()
503
+ {
504
+ $this->_rootDir = dirname(dirname(__FILE__));
505
+ $this->_mageDir = dirname($this->_rootDir);
506
+ }
507
+
508
+ /**
509
+ * Run
510
+ */
511
+ public static function run()
512
+ {
513
+ try {
514
+ self::singleton()->dispatch();
515
+ } catch (Exception $e) {
516
+ echo $e->getMessage();
517
+ }
518
+ }
519
+
520
+ /**
521
+ * Initialize object of class
522
+ *
523
+ * @return Maged_Controller
524
+ */
525
+ public static function singleton()
526
+ {
527
+ if (!self::$_instance) {
528
+ self::$_instance = new self;
529
+
530
+ if (self::$_instance->isDownloaded() && self::$_instance->isInstalled()) {
531
+ Mage::app('', 'store', array('global_ban_use_cache'=>true));
532
+ Mage::getSingleton('adminhtml/url')->turnOffSecretKey();
533
+ }
534
+ }
535
+ return self::$_instance;
536
+ }
537
+
538
+ /**
539
+ * Retrieve Downloader root dir
540
+ *
541
+ * @return string
542
+ */
543
+ public function getRootDir()
544
+ {
545
+ return $this->_rootDir;
546
+ }
547
+
548
+ /**
549
+ * Retrieve Magento root dir
550
+ *
551
+ * @return string
552
+ */
553
+ public function getMageDir()
554
+ {
555
+ return $this->_mageDir;
556
+ }
557
+
558
+ /**
559
+ * Retrieve Mage Class file path
560
+ *
561
+ * @return string
562
+ */
563
+ public function getMageFilename()
564
+ {
565
+ $ds = DIRECTORY_SEPARATOR;
566
+ return $this->getMageDir() . $ds . 'app' . $ds . 'Mage.php';
567
+ }
568
+
569
+ /**
570
+ * Retrieve path for Varien_Profiler
571
+ *
572
+ * @return string
573
+ */
574
+ public function getVarFilename()
575
+ {
576
+ $ds = DIRECTORY_SEPARATOR;
577
+ return $this->getMageDir() . $ds . 'lib' . $ds . 'Varien' . $ds . 'Profiler.php';
578
+ }
579
+
580
+ /**
581
+ * Retrieve downloader file path
582
+ *
583
+ * @param string $name
584
+ * @return string
585
+ */
586
+ public function filepath($name = '')
587
+ {
588
+ $ds = DIRECTORY_SEPARATOR;
589
+ return rtrim($this->getRootDir() . $ds . str_replace('/', $ds, $name), $ds);
590
+ }
591
+
592
+ /**
593
+ * Retrieve object of view
594
+ *
595
+ * @return Maged_View
596
+ */
597
+ public function view()
598
+ {
599
+ if (!$this->_view) {
600
+ $this->_view = new Maged_View;
601
+ }
602
+ return $this->_view;
603
+ }
604
+
605
+ /**
606
+ * Retrieve object of model
607
+ *
608
+ * @param string $model
609
+ * @param boolean $singleton
610
+ * @return Maged_Model
611
+ */
612
+ public function model($model = null, $singleton = false)
613
+ {
614
+ if ($singleton && isset($this->_singletons[$model])) {
615
+ return $this->_singletons[$model];
616
+ }
617
+
618
+ if (is_null($model)) {
619
+ $class = 'Maged_Model';
620
+ } else {
621
+ $class = 'Maged_Model_' . str_replace(' ', '_', ucwords(str_replace('_', ' ', $model)));
622
+ if (!class_exists($class, false)) {
623
+ include_once str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
624
+ }
625
+ }
626
+
627
+ $object = new $class();
628
+
629
+ if ($singleton) {
630
+ $this->_singletons[$model] = $object;
631
+ }
632
+
633
+ return $object;
634
+ }
635
+
636
+ /**
637
+ * Retrieve object of config
638
+ *
639
+ * @return Mage_Connect_Config
640
+ */
641
+ public function config()
642
+ {
643
+ if (!$this->_config) {
644
+ $this->_config = $this->model('connect', true)->connect()->getConfig();
645
+ if (!$this->_config->isLoaded()) {
646
+ $this->session()->addMessage('error', "Settings has not been loaded. Used default settings");
647
+ if ($this->_config->getError()) {
648
+ $this->session()->addMessage('error', $this->_config->getError());
649
+ }
650
+ }
651
+ }
652
+ return $this->_config;
653
+ }
654
+
655
+ /**
656
+ * Retrieve object of channel config
657
+ *
658
+ * @return Maged_Model_Config_Interface
659
+ */
660
+ public function channelConfig()
661
+ {
662
+ if (!$this->_localConfig) {
663
+ $this->_localConfig = $this->model('config', true)->getChannelConfig();
664
+ }
665
+ return $this->_localConfig;
666
+ }
667
+
668
+ /**
669
+ * Retrieve object of session
670
+ *
671
+ * @return Maged_Model_Session
672
+ */
673
+ public function session()
674
+ {
675
+ if (!$this->_session) {
676
+ $this->_session = $this->model('session')->start();
677
+ }
678
+ return $this->_session;
679
+ }
680
+
681
+ /**
682
+ * Set Controller action
683
+ *
684
+ * @param string $action
685
+ * @return Maged_Controller
686
+ */
687
+ public function setAction($action=null)
688
+ {
689
+ if (is_null($action)) {
690
+ if (!empty($this->_action)) {
691
+ return $this;
692
+ }
693
+ $action = !empty($_GET[self::ACTION_KEY]) ? $_GET[self::ACTION_KEY] : 'index';
694
+ }
695
+ if (empty($action) || !is_string($action) || !method_exists($this, $this->getActionMethod($action))) {
696
+ //$action = 'noroute';
697
+ $action = 'index';
698
+ }
699
+ $this->_action = $action;
700
+ return $this;
701
+ }
702
+
703
+ /**
704
+ * Retrieve Controller action name
705
+ *
706
+ * @return string
707
+ */
708
+ public function getAction()
709
+ {
710
+ return $this->_action;
711
+ }
712
+
713
+ /**
714
+ * Set Redirect to URL
715
+ *
716
+ * @param string $url
717
+ * @param bool $force
718
+ * @return Maged_Controller
719
+ */
720
+ public function redirect($url, $force = false)
721
+ {
722
+ $this->_redirectUrl = $url;
723
+ if ($force) {
724
+ $this->processRedirect();
725
+ }
726
+ return $this;
727
+ }
728
+
729
+ /**
730
+ * Precess redirect
731
+ *
732
+ * @return Maged_Controller
733
+ */
734
+ public function processRedirect()
735
+ {
736
+ if ($this->_redirectUrl) {
737
+ if (headers_sent()) {
738
+ echo '<script type="text/javascript">location.href="' . $this->_redirectUrl . '"</script>';
739
+ exit;
740
+ } else {
741
+ header("Location: " . $this->_redirectUrl);
742
+ exit;
743
+ }
744
+ }
745
+ return $this;
746
+ }
747
+
748
+ /**
749
+ * Forward to action
750
+ *
751
+ * @param string $action
752
+ * @return Maged_Controller
753
+ */
754
+ public function forward($action)
755
+ {
756
+ $this->setAction($action);
757
+ $this->_isDispatched = false;
758
+ return $this;
759
+ }
760
+
761
+ /**
762
+ * Retrieve action method by action name
763
+ *
764
+ * @param string $action
765
+ * @return string
766
+ */
767
+ public function getActionMethod($action = null)
768
+ {
769
+ $method = (!is_null($action) ? $action : $this->_action) . 'Action';
770
+ return $method;
771
+ }
772
+
773
+ /**
774
+ * Generate URL for action
775
+ *
776
+ * @param string $action
777
+ * @param array $params
778
+ */
779
+ public function url($action = '', $params = array())
780
+ {
781
+ $args = array();
782
+ foreach ($params as $k => $v) {
783
+ $args[] = sprintf('%s=%s', rawurlencode($k), rawurlencode($v));
784
+ }
785
+ $args = $args ? join('&', $args) : '';
786
+
787
+ return sprintf('%s?%s=%s%s', $_SERVER['SCRIPT_NAME'], self::ACTION_KEY, rawurlencode($action), $args);
788
+ }
789
+
790
+ /**
791
+ * Add domain policy header according to admin area settings
792
+ */
793
+ protected function _addDomainPolicyHeader()
794
+ {
795
+ if ($this->isInstalled()) {
796
+ /** @var Mage_Core_Model_Domainpolicy $domainPolicy */
797
+ $domainPolicy = Mage::getModel('core/domainpolicy');
798
+ if ($domainPolicy) {
799
+ $policy = $domainPolicy->getBackendPolicy();
800
+ if ($policy) {
801
+ header('X-Frame-Options: ' . $policy);
802
+ }
803
+ }
804
+ }
805
+ }
806
+
807
+ /**
808
+ * Dispatch process
809
+ */
810
+ public function dispatch()
811
+ {
812
+ header('Content-type: text/html; charset=UTF-8');
813
+
814
+ $this->_addDomainPolicyHeader();
815
+
816
+ $this->setAction();
817
+
818
+ if (!$this->isInstalled()) {
819
+ if (!in_array($this->getAction(), array('index', 'connectInstallAll', 'empty', 'cleanCache'))) {
820
+ $this->setAction('index');
821
+ }
822
+ } else {
823
+ $this->session()->authenticate();
824
+ }
825
+
826
+ while (!$this->_isDispatched) {
827
+ $this->_isDispatched = true;
828
+
829
+ $method = $this->getActionMethod();
830
+ $this->$method();
831
+ }
832
+
833
+ $this->processRedirect();
834
+ }
835
+
836
+ /**
837
+ * Check root dir is writable
838
+ *
839
+ * @return bool
840
+ */
841
+ public function isWritable()
842
+ {
843
+ if (is_null($this->_writable)) {
844
+ $this->_writable = is_writable($this->getMageDir() . DIRECTORY_SEPARATOR)
845
+ && is_writable($this->filepath())
846
+ && (!file_exists($this->filepath('config.ini') || is_writable($this->filepath('config.ini'))));
847
+ }
848
+ return $this->_writable;
849
+ }
850
+
851
+ /**
852
+ * Check is Magento files downloaded
853
+ *
854
+ * @return bool
855
+ */
856
+ public function isDownloaded()
857
+ {
858
+ return file_exists($this->getMageFilename()) && file_exists($this->getVarFilename());
859
+ }
860
+
861
+ /**
862
+ * Check is Magento installed
863
+ *
864
+ * @return bool
865
+ */
866
+ public function isInstalled()
867
+ {
868
+ if (!$this->isDownloaded()) {
869
+ return false;
870
+ }
871
+ if (!class_exists('Mage', false)) {
872
+ if (!file_exists($this->getMageFilename())) {
873
+ return false;
874
+ }
875
+ include_once $this->getMageFilename();
876
+ Mage::setIsDownloader();
877
+ }
878
+ return Mage::isInstalled();
879
+ }
880
+
881
+ /**
882
+ * Retrieve Maintenance flag
883
+ *
884
+ * @return bool
885
+ */
886
+ protected function _getMaintenanceFlag()
887
+ {
888
+ if (is_null($this->_maintenance)) {
889
+ $this->_maintenance = !empty($_REQUEST['maintenance']) && $_REQUEST['maintenance'] == '1' ? true : false;
890
+ }
891
+ return $this->_maintenance;
892
+ }
893
+
894
+ /**
895
+ * Retrieve Maintenance Flag file path
896
+ *
897
+ * @return string
898
+ */
899
+ protected function _getMaintenanceFilePath()
900
+ {
901
+ if (is_null($this->_maintenanceFile)) {
902
+ $path = dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR;
903
+ $this->_maintenanceFile = $path . 'maintenance.flag';
904
+ }
905
+ return $this->_maintenanceFile;
906
+ }
907
+
908
+ /**
909
+ * Begin install package(s)
910
+ */
911
+ public function startInstall()
912
+ {
913
+ if ($this->_getMaintenanceFlag()) {
914
+ $maintenance_filename='maintenance.flag';
915
+ $config = $this->config();
916
+ if (!$this->isWritable() || strlen($config->__get('remote_config')) > 0) {
917
+ $ftpObj = new Mage_Connect_Ftp();
918
+ $ftpObj->connect($config->__get('remote_config'));
919
+ $tempFile = tempnam(sys_get_temp_dir(),'maintenance');
920
+ @file_put_contents($tempFile, 'maintenance');
921
+ $ftpObj->upload($maintenance_filename, $tempFile);
922
+ $ftpObj->close();
923
+ } else {
924
+ @file_put_contents($this->_getMaintenanceFilePath(), 'maintenance');
925
+ }
926
+ }
927
+
928
+ if (!empty($_GET['archive_type'])) {
929
+
930
+ $backupName = $_GET['backup_name'];
931
+ $connect = $this->model('connect', true)->connect();
932
+ $isSuccess = true;
933
+
934
+ if (!preg_match('/^[a-zA-Z0-9\ ]{0,50}$/', $backupName)) {
935
+ $connect->runHtmlConsole('Please use only letters (a-z or A-Z), numbers (0-9) or space in '
936
+ . 'Backup Name field. Other characters are not allowed.');
937
+ $isSuccess = false;
938
+ }
939
+
940
+ if ($isSuccess) {
941
+ $isSuccess = $this->_createBackup($_GET['archive_type'], $_GET['backup_name']);
942
+ }
943
+
944
+ if (!$isSuccess) {
945
+ $this->endInstall();
946
+ $this->cleanCache();
947
+ throw new Mage_Exception(
948
+ 'The installation process has been canceled because of the backup creation error'
949
+ );
950
+ }
951
+ }
952
+ }
953
+
954
+ /**
955
+ * End install package(s)
956
+ */
957
+ public function endInstall()
958
+ {
959
+ //$connect
960
+ /** @var $connect Maged_Model_Connect */
961
+ $frontend = $this->model('connect', true)->connect()->getFrontend();
962
+ if (!($frontend instanceof Maged_Connect_Frontend)) {
963
+ $this->cleanCache();
964
+ }
965
+ }
966
+
967
+ protected function cleanCache()
968
+ {
969
+ $result = true;
970
+ $message = '';
971
+ try {
972
+ if ($this->isInstalled()) {
973
+ if (!empty($_REQUEST['clean_sessions'])) {
974
+ Mage::app()->cleanAllSessions();
975
+ $message .= 'Session cleaned successfully. ';
976
+ }
977
+ Mage::app()->cleanCache();
978
+
979
+ // reinit config and apply all updates
980
+ Mage::app()->getConfig()->reinit();
981
+ Mage_Core_Model_Resource_Setup::applyAllUpdates();
982
+ Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
983
+ $message .= 'Cache cleaned successfully';
984
+ } else {
985
+ $result = true;
986
+ }
987
+ } catch (Exception $e) {
988
+ $result = false;
989
+ $message = "Exception during cache and session cleaning: ".$e->getMessage();
990
+ $this->session()->addMessage('error', $message);
991
+ }
992
+
993
+ if ($result && $this->_getMaintenanceFlag()) {
994
+ $maintenance_filename='maintenance.flag';
995
+ $config = $this->config();
996
+ if (!$this->isWritable() && strlen($config->__get('remote_config')) > 0) {
997
+ $ftpObj = new Mage_Connect_Ftp();
998
+ $ftpObj->connect($config->__get('remote_config'));
999
+ $ftpObj->delete($maintenance_filename);
1000
+ $ftpObj->close();
1001
+ } else {
1002
+ @unlink($this->_getMaintenanceFilePath());
1003
+ }
1004
+ }
1005
+ return array('result' => $result, 'message' => $message);
1006
+ }
1007
+
1008
+ /**
1009
+ * Gets the current Magento Connect Manager (Downloader) version string
1010
+ * @link http://www.magentocommerce.com/blog/new-community-edition-release-process/
1011
+ *
1012
+ * @return string
1013
+ */
1014
+ public static function getVersion()
1015
+ {
1016
+ $i = self::getVersionInfo();
1017
+ return trim(
1018
+ "{$i['major']}.{$i['minor']}.{$i['revision']}"
1019
+ . ($i['patch'] != '' ? ".{$i['patch']}" : "")
1020
+ . "-{$i['stability']}{$i['number']}",
1021
+ '.-'
1022
+ );
1023
+ }
1024
+
1025
+ /**
1026
+ * Gets the detailed Magento Connect Manager (Downloader) version information
1027
+ * @link http://www.magentocommerce.com/blog/new-community-edition-release-process/
1028
+ *
1029
+ * @return array
1030
+ */
1031
+ public static function getVersionInfo()
1032
+ {
1033
+ return array(
1034
+ 'major' => '1',
1035
+ 'minor' => '9',
1036
+ 'revision' => '2',
1037
+ 'patch' => '4',
1038
+ 'stability' => '',
1039
+ 'number' => '',
1040
+ );
1041
+ }
1042
+
1043
+ /**
1044
+ * Create Backup
1045
+ *
1046
+ * @param string $archiveType
1047
+ * @param string $archiveName
1048
+ * @return bool
1049
+ */
1050
+ protected function _createBackup($archiveType, $archiveName){
1051
+ /** @var $connect Maged_Connect */
1052
+ $connect = $this->model('connect', true)->connect();
1053
+ $connect->runHtmlConsole('Creating backup...');
1054
+
1055
+ $isSuccess = false;
1056
+
1057
+ try {
1058
+ $type = $this->_getBackupTypeByCode($archiveType);
1059
+
1060
+ $backupManager = Mage_Backup::getBackupInstance($type)
1061
+ ->setBackupExtension(Mage::helper('backup')->getExtensionByType($type))
1062
+ ->setTime(time())
1063
+ ->setName($archiveName)
1064
+ ->setBackupsDir(Mage::helper('backup')->getBackupsDir());
1065
+
1066
+ Mage::register('backup_manager', $backupManager);
1067
+
1068
+ if ($type != Mage_Backup_Helper_Data::TYPE_DB) {
1069
+ $backupManager->setRootDir(Mage::getBaseDir())
1070
+ ->addIgnorePaths(Mage::helper('backup')->getBackupIgnorePaths());
1071
+ }
1072
+ $backupManager->create();
1073
+ $connect->runHtmlConsole(
1074
+ $this->_getCreateBackupSuccessMessageByType($type)
1075
+ );
1076
+ $isSuccess = true;
1077
+ } catch (Mage_Backup_Exception_NotEnoughFreeSpace $e) {
1078
+ $connect->runHtmlConsole('Not enough free space to create backup.');
1079
+ Mage::logException($e);
1080
+ } catch (Mage_Backup_Exception_NotEnoughPermissions $e) {
1081
+ $connect->runHtmlConsole('Not enough permissions to create backup.');
1082
+ Mage::logException($e);
1083
+ } catch (Exception $e) {
1084
+ $connect->runHtmlConsole('An error occurred while creating the backup.');
1085
+ Mage::logException($e);
1086
+ }
1087
+
1088
+ return $isSuccess;
1089
+ }
1090
+
1091
+ /**
1092
+ * Retrieve Backup Type by Code
1093
+ *
1094
+ * @param int $code
1095
+ * @return string
1096
+ */
1097
+ protected function _getBackupTypeByCode($code)
1098
+ {
1099
+ $typeMap = array(
1100
+ 1 => Mage_Backup_Helper_Data::TYPE_DB,
1101
+ 2 => Mage_Backup_Helper_Data::TYPE_SYSTEM_SNAPSHOT,
1102
+ 3 => Mage_Backup_Helper_Data::TYPE_SNAPSHOT_WITHOUT_MEDIA,
1103
+ 4 => Mage_Backup_Helper_Data::TYPE_MEDIA
1104
+ );
1105
+
1106
+ if (!isset($typeMap[$code])) {
1107
+ Mage::throwException('Unknown backup type');
1108
+ }
1109
+
1110
+ return $typeMap[$code];
1111
+ }
1112
+
1113
+ /**
1114
+ * Get backup create success message by backup type
1115
+ *
1116
+ * @param string $type
1117
+ * @return string
1118
+ */
1119
+ protected function _getCreateBackupSuccessMessageByType($type)
1120
+ {
1121
+ $messagesMap = array(
1122
+ Mage_Backup_Helper_Data::TYPE_SYSTEM_SNAPSHOT => 'System backup has been created',
1123
+ Mage_Backup_Helper_Data::TYPE_SNAPSHOT_WITHOUT_MEDIA => 'System (excluding Media) backup has been created',
1124
+ Mage_Backup_Helper_Data::TYPE_MEDIA => 'Database and media backup has been created',
1125
+ Mage_Backup_Helper_Data::TYPE_DB => 'Database backup has been created'
1126
+ );
1127
+
1128
+ if (!isset($messagesMap[$type])) {
1129
+ return '';
1130
+ }
1131
+
1132
+ return $messagesMap[$type];
1133
+ }
1134
+
1135
+ /**
1136
+ * Validate Form Key
1137
+ *
1138
+ * @return bool
1139
+ */
1140
+ protected function _validateFormKey()
1141
+ {
1142
+ return $this->session()->validateFormKey();
1143
+ }
1144
+
1145
+ /**
1146
+ * Retrieve Session Form Key
1147
+ *
1148
+ * @return string
1149
+ */
1150
+ public function getFormKey()
1151
+ {
1152
+ return $this->session()->getFormKey();
1153
+ }
1154
+ }
app/code/local/Mss/downloader/Maged/Exception.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ class Maged_Exception extends Exception
36
+ {
37
+ }
app/code/local/Mss/downloader/Maged/Model.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class Model
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ class Maged_Model
36
+ {
37
+
38
+ /**
39
+ * Internal cache
40
+ *
41
+ * @var array
42
+ */
43
+ protected $_data;
44
+
45
+ /**
46
+ * Constructor
47
+ */
48
+ public function __construct()
49
+ {
50
+ $args = func_get_args();
51
+ if (empty($args[0])) {
52
+ $args[0] = array();
53
+ }
54
+ $this->_data = $args[0];
55
+
56
+ $this->_construct();
57
+ }
58
+
59
+ /**
60
+ * Constructor for covering
61
+ */
62
+ protected function _construct()
63
+ {
64
+
65
+ }
66
+
67
+ /**
68
+ * Retrieve controller
69
+ * @return Maged_Controller
70
+ */
71
+ public function controller()
72
+ {
73
+ return Maged_Controller::singleton();
74
+ }
75
+
76
+ /**
77
+ * Set value for key
78
+ *
79
+ * @param string $key
80
+ * @param mixed $value
81
+ * @return Maged_Model
82
+ */
83
+ public function set($key, $value)
84
+ {
85
+ $this->_data[$key] = $value;
86
+ return $this;
87
+ }
88
+
89
+ /**
90
+ * Get value by key
91
+ *
92
+ * @param string $key
93
+ * @return mixed
94
+ */
95
+ public function get($key)
96
+ {
97
+ return isset($this->_data[$key]) ? $this->_data[$key] : null;
98
+ }
99
+ }
app/code/local/Mss/downloader/Maged/Model/Config.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class config
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ class Maged_Model_Config extends Maged_Model_Config_Abstract
36
+ {
37
+ /**
38
+ * Get channel config class
39
+ * @return Maged_Model_Config_Interface
40
+ */
41
+ public function getChannelConfig()
42
+ {
43
+ $this->load();
44
+ $channel = trim($this->get('root_channel'));
45
+ if (!empty($channel)) {
46
+ try {
47
+ return $this->controller()->model('config_'.$channel, true);
48
+ } catch (Exception $e) {
49
+ throw new Exception('Not valid config.ini file.');
50
+ }
51
+ } else {
52
+ throw new Exception('Not valid config.ini file.');
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Save post data to config
58
+ *
59
+ * @param array $p
60
+ * @return Maged_Model_Config
61
+ */
62
+ public function saveConfigPost($p)
63
+ {
64
+ $configParams = array(
65
+ 'protocol',
66
+ 'preferred_state',
67
+ 'use_custom_permissions_mode',
68
+ 'mkdir_mode',
69
+ 'chmod_file_mode',
70
+ 'magento_root',
71
+ 'downloader_path',
72
+ 'root_channel_uri',
73
+ 'root_channel',
74
+ 'ftp',
75
+ );
76
+ foreach ($configParams as $paramName){
77
+ if (isset($p[$paramName])) {
78
+ $this->set($paramName, $p[$paramName]);
79
+ }
80
+ }
81
+ $this->save();
82
+ return $this;
83
+ }
84
+ }
app/code/local/Mss/downloader/Maged/Model/Config/Abstract.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class config
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ class Maged_Model_Config_Abstract extends Maged_Model
36
+ {
37
+ /**
38
+ * Retrive file name
39
+ *
40
+ * @return string
41
+ */
42
+ public function getFilename()
43
+ {
44
+ return $this->controller()->filepath('config.ini');
45
+ }
46
+
47
+ /**
48
+ * Load file
49
+ *
50
+ * @return Maged_Model_Config
51
+ */
52
+ public function load()
53
+ {
54
+ if (!file_exists($this->getFilename())) {
55
+ return $this;
56
+ }
57
+ $rows = file($this->getFilename());
58
+ if (!$rows) {
59
+ return $this;
60
+ }
61
+ foreach ($rows as $row) {
62
+ $arr = explode('=', $row, 2);
63
+ if (count($arr)!==2) {
64
+ continue;
65
+ }
66
+ $key = trim($arr[0]);
67
+ $value = trim($arr[1], " \t\"'\n\r");
68
+ if (!$key || $key[0]=='#' || $key[0]==';') {
69
+ continue;
70
+ }
71
+ $this->set($key, $value);
72
+ }
73
+ return $this;
74
+ }
75
+
76
+ /**
77
+ * Save file
78
+ *
79
+ * @return Maged_Model_Config
80
+ */
81
+ public function save()
82
+ {
83
+ if ((!is_writable($this->getFilename())&&is_file($this->getFilename()))||(dirname($this->getFilename())!=''&&!is_writable(dirname($this->getFilename())))) {
84
+ if(isset($this->_data['ftp'])&&!empty($this->_data['ftp'])&&strlen($this->get('downloader_path'))>0){
85
+ $confFile=$this->get('downloader_path').DIRECTORY_SEPARATOR.basename($this->getFilename());
86
+ $ftpObj = new Mage_Connect_Ftp();
87
+ $ftpObj->connect($this->_data['ftp']);
88
+ $tempFile = tempnam(sys_get_temp_dir(),'configini');
89
+ $fp = fopen($tempFile, 'w');
90
+ foreach ($this->_data as $k=>$v) {
91
+ fwrite($fp, $k.'='.$v."\n");
92
+ }
93
+ fclose($fp);
94
+ $ret=$ftpObj->upload($confFile, $tempFile);
95
+ $ftpObj->close();
96
+ }else{
97
+ /* @TODO: show Warning message*/
98
+ $this->controller()->session()
99
+ ->addMessage('warning', 'Invalid file permissions, could not save configuration.');
100
+ return $this;
101
+ }
102
+ /**/
103
+ }else{
104
+ $fp = fopen($this->getFilename(), 'w');
105
+ foreach ($this->_data as $k=>$v) {
106
+ fwrite($fp, $k.'='.$v."\n");
107
+ }
108
+ fclose($fp);
109
+ }
110
+ return $this;
111
+ }
112
+
113
+ /**
114
+ * Return channel label for channel name
115
+ *
116
+ * @param string $channel
117
+ * @return string
118
+ */
119
+ public function getChannelLabel($channel)
120
+ {
121
+ $channelLabel = '';
122
+ switch($channel)
123
+ {
124
+ case 'community':
125
+ $channelLabel = 'Magento Community Edition';
126
+ break;
127
+ default:
128
+ $channelLabel = $channel;
129
+ break;
130
+ }
131
+ return $channelLabel;
132
+ }
133
+ }
134
+ ?>
app/code/local/Mss/downloader/Maged/Model/Config/Community.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class config
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ class Maged_Model_Config_Community extends Maged_Model_Config_Abstract implements Maged_Model_Config_Interface
36
+ {
37
+
38
+ /**
39
+ * Initialization
40
+ */
41
+ protected function _construct()
42
+ {
43
+ $this->load();
44
+ }
45
+
46
+ /**
47
+ * Set data for Settings View
48
+ *
49
+ * @param Mage_Connect_Config $config
50
+ * @param Maged_View $view
51
+ * @return null
52
+ */
53
+ public function setInstallView($config, $view)
54
+ {
55
+ $view->set('channel_logo', 'logo');
56
+ }
57
+
58
+ /**
59
+ * Set data for Settings View
60
+ * @param Mage_Connect_Config $config
61
+ * @param Maged_View $view
62
+ * @return null
63
+ */
64
+ public function setSettingsView($config, $view)
65
+ {
66
+ }
67
+
68
+ /**
69
+ * Set session data for Settings
70
+ * @param array $post post data
71
+ * @param mixed $session Session object
72
+ * @return null
73
+ */
74
+ public function setSettingsSession($post, $session)
75
+ {
76
+ }
77
+
78
+ /**
79
+ * Get root channel URI
80
+ *
81
+ * @return string Root channel URI
82
+ */
83
+ public function getRootChannelUri(){
84
+ if (!$this->get('root_channel_uri')) {
85
+ $this->set('root_channel_uri', 'connect20.magentocommerce.com/community');
86
+ }
87
+ return $this->get('root_channel_uri');
88
+ }
89
+
90
+ /**
91
+ * Set config data from POST
92
+ *
93
+ * @param Mage_Connect_Config $config Config object
94
+ * @param array $post post data
95
+ * @return null
96
+ */
97
+ public function setPostData($config, &$post)
98
+ {
99
+ }
100
+
101
+ /**
102
+ * Set additional command options
103
+ *
104
+ * @param mixed $session Session object
105
+ * @param array $options
106
+ * @return null
107
+ */
108
+ public function setCommandOptions($session, &$options)
109
+ {
110
+ }
111
+ }
112
+ ?>
app/code/local/Mss/downloader/Maged/Model/Config/Interface.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class config
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ interface Maged_Model_Config_Interface
36
+ {
37
+
38
+ /**
39
+ * Set data for Settings View
40
+ *
41
+ * @param Mage_Connect_Config $config
42
+ * @param Maged_View $view
43
+ * @return null
44
+ */
45
+ public function setInstallView($config, $view);
46
+
47
+ /**
48
+ * Set data for Settings View
49
+ *
50
+ * @param mixed $session Session object
51
+ * @param Maged_View $view
52
+ * @return null
53
+ */
54
+ public function setSettingsView($session, $view);
55
+
56
+ /**
57
+ * Set session data for Settings
58
+ *
59
+ * @param array $post post data
60
+ * @param mixed $session Session object
61
+ * @return null
62
+ */
63
+ public function setSettingsSession($post, $session);
64
+
65
+ /**
66
+ * Set config data from POST
67
+ *
68
+ * @param Mage_Connect_Config $config Config object
69
+ * @param array $post post data
70
+ * @return boolean
71
+ */
72
+ public function setPostData($config, &$post);
73
+
74
+ /**
75
+ * Get root channel URI
76
+ *
77
+ * @return string Root channel URI
78
+ */
79
+ public function getRootChannelUri();
80
+
81
+ /**
82
+ * Set additional command options
83
+ *
84
+ * @param mixed $session Session object
85
+ * @param array $options
86
+ * @return null
87
+ */
88
+ public function setCommandOptions($session, &$options);
89
+ }
90
+ ?>
app/code/local/Mss/downloader/Maged/Model/Connect.php ADDED
@@ -0,0 +1,497 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ include_once "Maged/Connect.php";
28
+
29
+ /**
30
+ * Class for initialize Mage_Connect lib
31
+ *
32
+ * @category Mage
33
+ * @package Mage_Connect
34
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
35
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
36
+ */
37
+
38
+ class Maged_Model_Connect extends Maged_Model
39
+ {
40
+
41
+ /**
42
+ * Constructor
43
+ */
44
+ protected function _construct()
45
+ {
46
+ parent::_construct();
47
+ }
48
+
49
+ /**
50
+ * Retrive object of Maged_Connect
51
+ *
52
+ * @return Maged_Connect
53
+ */
54
+ public function connect()
55
+ {
56
+ return Maged_Connect::getInstance();
57
+ }
58
+
59
+ /**
60
+ * Install All Magento
61
+ *
62
+ * @param boolean $force
63
+ */
64
+ public function installAll($force=false, $chanName='')
65
+ {
66
+ $options = array('install_all'=>true);
67
+ if ($force) {
68
+ $this->connect()->cleanSconfig();
69
+ $options['force'] = 1;
70
+ }
71
+ $packages = array(
72
+ 'Mage_All_Latest',
73
+ );
74
+ $connectConfig = $this->connect()->getConfig();
75
+ $ftp = $connectConfig->remote_config;
76
+ if (!empty($ftp)) {
77
+ $options['ftp'] = $ftp;
78
+ }
79
+ $params = array();
80
+
81
+ $uri = $this->controller()->channelConfig()->getRootChannelUri();
82
+
83
+ $this->controller()->channelConfig()->setCommandOptions($this->controller()->session(), $options);
84
+
85
+ $connectConfig->root_channel = $chanName;
86
+ foreach ($packages as $package) {
87
+ $params[] = $uri;
88
+ $params[] = $package;
89
+ }
90
+ $this->connect()->runHtmlConsole(array('command'=>'install', 'options'=>$options, 'params'=>$params));
91
+ }
92
+
93
+ /**
94
+ * Prepare to install package
95
+ *
96
+ * @param string $id
97
+ * @return array
98
+ */
99
+ public function prepareToInstall($id)
100
+ {
101
+ $match = array();
102
+ if (!$this->checkExtensionKey($id, $match)) {
103
+ $errorMessage[] = sprintf('Invalid package identifier provided: %s', $id);
104
+ $packages = array(
105
+ 'errors' => array('error'=> $errorMessage)
106
+ );
107
+ return $packages;
108
+ }
109
+
110
+ $channel = $match[1];
111
+ $package = $match[2];
112
+ $version = (!empty($match[3]) ? trim($match[3],'/\-') : '');
113
+
114
+ $connect = $this->connect();
115
+ $sconfig = $connect->getSingleConfig();
116
+
117
+ $options = array();
118
+ $params = array($channel, $package, $version, $version);
119
+ $this->controller()->channelConfig()->setCommandOptions($this->controller()->session(), $options);
120
+
121
+ $connect->run('package-prepare', $options, $params);
122
+ $output = $connect->getOutput();
123
+ $errors = $connect->getFrontend()->getErrors();
124
+ $package_error = array();
125
+ foreach ($errors as $error){
126
+ if (isset($error[1])){
127
+ $package_error[] = $error[1];
128
+ }
129
+ }
130
+
131
+ $packages = array();
132
+ if (is_array($output) && isset($output['package-prepare'])){
133
+ $packages = array_merge($output['package-prepare'], array('errors'=>array('error'=>$package_error)));
134
+ } elseif (is_array($output) && !empty($package_error)) {
135
+ $packages = array('errors'=>array('error'=>$package_error));
136
+ }
137
+ return $packages;
138
+ }
139
+
140
+
141
+ /**
142
+ * Retrieve all installed packages
143
+ *
144
+ * @return array
145
+ */
146
+ public function getAllInstalledPackages()
147
+ {
148
+ $connect = $this->connect();
149
+ $sconfig = $connect->getSingleConfig(true);
150
+ $connect->run('list-installed');
151
+ $output = $connect->getOutput();
152
+ $packages = array();
153
+ if (is_array($output) && isset($output['list-installed']['data'])){
154
+ $packages = $output['list-installed']['data'];
155
+ } else {
156
+
157
+ }
158
+ foreach ($packages as $channel=>$package) {
159
+ foreach ($package as $name=>$data) {
160
+ $summary = $sconfig->getPackageObject($channel, $name)->getSummary();
161
+ $addition = array('summary'=>$summary, 'upgrade_versions'=>array(), 'upgrade_latest'=>'');
162
+ $packages[$channel][$name] = array_merge($data, $addition);
163
+ }
164
+ }
165
+
166
+ if (!empty($_GET['updates'])) {
167
+ $options = array();
168
+ $this->controller()->channelConfig()->setCommandOptions($this->controller()->session(), $options);
169
+ $result = $connect->run('list-upgrades', $options);
170
+ $output = $connect->getOutput();
171
+ if (is_array($output)) {
172
+ $channelData = $output;
173
+ if (!empty($channelData['list-upgrades']['data']) && is_array($channelData['list-upgrades']['data'])) {
174
+ foreach ($channelData['list-upgrades']['data'] as $channel=>$package) {
175
+ foreach ($package as $name=>$data) {
176
+ if (!isset($packages[$channel][$name])) {
177
+ continue;
178
+ }
179
+ $packages[$channel][$name]['upgrade_latest'] = $data['to'].' ('.$data['from'].')';
180
+ }
181
+ }
182
+ }
183
+ }
184
+ }
185
+
186
+ $states = array('snapshot'=>0, 'devel'=>1, 'alpha'=>2, 'beta'=>3, 'stable'=>4);
187
+ $preferredState = $states[$this->getPreferredState()];
188
+
189
+ foreach ($packages as $channel=>&$package) {
190
+ foreach ($package as $name=>&$data) {
191
+ $actions = array();
192
+ $systemPkg = $name==='Mage_Downloader';
193
+ if (!empty($data['upgrade_latest'])) {
194
+ $status = 'upgrade-available';
195
+ $releases = array();
196
+ $connect->run('info', array(), array($channel, $name));
197
+ $output = $connect->getOutput();
198
+ if (!empty($output['info']['releases'])) {
199
+ foreach ($output['info']['releases'] as $release) {
200
+ $stability = $packages[$channel][$name]['stability'];
201
+ if ($states[$release['s']] < min($preferredState, $states[$stability])) {
202
+ continue;
203
+ }
204
+ if (version_compare($release['v'], $packages[$channel][$name]['version']) < 1) {
205
+ continue;
206
+ }
207
+ $releases[$release['v']] = $release['v'].' ('.$release['s'].')';
208
+ }
209
+ }
210
+
211
+ if ($releases) {
212
+ uksort($releases, 'version_compare');
213
+ foreach ($releases as $version => $release) {
214
+ $actions['upgrade|'.$version] = 'Upgrade to '.$release;
215
+ }
216
+ } else {
217
+ $a = explode(' ', $data['upgrade_latest'], 2);
218
+ $actions['upgrade|'.$a[0]] = 'Upgrade';
219
+ }
220
+ if (!$systemPkg) {
221
+ $actions['uninstall'] = 'Uninstall';
222
+ }
223
+ } else {
224
+ $status = 'installed';
225
+ $actions['reinstall'] = 'Reinstall';
226
+ if (!$systemPkg) {
227
+ $actions['uninstall'] = 'Uninstall';
228
+ }
229
+ }
230
+ $packages[$channel][$name]['actions'] = $actions;
231
+ $packages[$channel][$name]['status'] = $status;
232
+ }
233
+ }
234
+ return $packages;
235
+ }
236
+
237
+ /**
238
+ * Run packages action
239
+ *
240
+ * @param mixed $packages
241
+ */
242
+ public function applyPackagesActions($packages, $ignoreLocalModification='')
243
+ {
244
+ $actions = array();
245
+ foreach ($packages as $package=>$action) {
246
+ if ($action) {
247
+ $a = explode('|', $package);
248
+ $b = explode('|', $action);
249
+ $package = $a[1];
250
+ $channel = $a[0];
251
+ $version = '';
252
+ if ($b[0]=='upgrade') {
253
+ $version = $b[1];
254
+ }
255
+ $actions[$b[0]][] = array($channel, $package, $version, $version);
256
+ }
257
+ }
258
+ if (empty($actions)) {
259
+ $this->connect()->runHtmlConsole('No actions selected');
260
+ exit;
261
+ }
262
+
263
+ $this->controller()->startInstall();
264
+
265
+ $options = array();
266
+ if (!empty($ignoreLocalModification)) {
267
+ $options = array('ignorelocalmodification'=>1);
268
+ }
269
+ if(!$this->controller()->isWritable()||strlen($this->connect()->getConfig()->__get('remote_config'))>0){
270
+ $options['ftp'] = $this->connect()->getConfig()->__get('remote_config');
271
+ }
272
+
273
+ $this->controller()->channelConfig()->setCommandOptions($this->controller()->session(), $options);
274
+
275
+ foreach ($actions as $action=>$packages) {
276
+ foreach ($packages as $package) {
277
+ switch ($action) {
278
+ case 'install': case 'uninstall': case 'upgrade':
279
+ $this->connect()->runHtmlConsole(array(
280
+ 'command'=>$action,
281
+ 'options'=>$options,
282
+ 'params'=>$package
283
+ ));
284
+ break;
285
+
286
+ case 'reinstall':
287
+ $package_info = $this->connect()->getSingleConfig()->getPackage($package[0], $package[1]);
288
+ if (isset($package_info['version'])) {
289
+ $package[2] = $package_info['version'];
290
+ $package[3] = $package_info['version'];
291
+ }
292
+ $this->connect()->runHtmlConsole(array(
293
+ 'command'=>'install',
294
+ 'options'=>array_merge($options, array('force'=>1, 'nodeps'=>1)),
295
+ 'params'=>$package
296
+ ));
297
+ break;
298
+ }
299
+ }
300
+ }
301
+
302
+ $this->controller()->endInstall();
303
+ }
304
+
305
+
306
+ public function installUploadedPackage($file)
307
+ {
308
+ $this->controller()->startInstall();
309
+
310
+ $options = array();
311
+ if(!$this->controller()->isWritable()||strlen($this->connect()->getConfig()->__get('remote_config'))>0){
312
+ $options['ftp'] = $this->connect()->getConfig()->__get('remote_config');
313
+ }
314
+ $this->connect()->runHtmlConsole(array(
315
+ 'command'=>'install-file',
316
+ 'options'=>$options,
317
+ 'params'=>array($file),
318
+ ));
319
+ $this->controller()->endInstall();
320
+ }
321
+
322
+ /**
323
+ * Install package by id
324
+ *
325
+ * @param string $id
326
+ * @param boolean $force
327
+ */
328
+ public function installPackage($id, $force=false)
329
+ {
330
+ $match = array();
331
+ if (!$this->checkExtensionKey($id, $match)) {
332
+ $this->connect()->runHtmlConsole('Invalid package identifier provided: '.$id);
333
+ exit;
334
+ }
335
+
336
+ $channel = $match[1];
337
+ $package = $match[2];//.(!empty($match[3]) ? $match[3] : '');
338
+ $version = (!empty($match[3]) ? trim($match[3],'/\-') : '');
339
+
340
+ $this->controller()->startInstall();
341
+
342
+ $options = array();
343
+ if ($force) {
344
+ $options['force'] = 1;
345
+ }
346
+ if(!$this->controller()->isWritable()||strlen($this->connect()->getConfig()->__get('remote_config'))>0){
347
+ $options['ftp'] = $this->connect()->getConfig()->__get('remote_config');
348
+ }
349
+
350
+ $this->controller()->channelConfig()->setCommandOptions($this->controller()->session(), $options);
351
+
352
+ $this->connect()->runHtmlConsole(array(
353
+ 'command'=>'install',
354
+ 'options'=>$options,
355
+ 'params'=>array(0=>$channel, 1=>$package, 2=>$version),
356
+ ));
357
+
358
+ $this->controller()->endInstall();
359
+ }
360
+
361
+ /**
362
+ * Retrieve stability choosen client
363
+ *
364
+ * @return string alpha, beta, ...
365
+ */
366
+ public function getPreferredState()
367
+ {
368
+ if (is_null($this->get('preferred_state'))) {
369
+ $connectConfig = $this->connect()->getConfig();
370
+ $this->set('preferred_state', $connectConfig->__get('preferred_state'));
371
+ }
372
+ return $this->get('preferred_state');
373
+ }
374
+
375
+ /**
376
+ * Retrieve protocol choosen client
377
+ *
378
+ * @return string http, ftp
379
+ */
380
+ public function getProtocol()
381
+ {
382
+ if (is_null($this->get('protocol'))) {
383
+ $connectConfig = $this->connect()->getConfig();
384
+ $this->set('protocol', $connectConfig->__get('protocol'));
385
+ }
386
+ return $this->get('protocol');
387
+ }
388
+
389
+ /**
390
+ * Validate settings post data.
391
+ *
392
+ * @param array $p
393
+ */
394
+ public function validateConfigPost($p)
395
+ {
396
+ $errors = array();
397
+ $configTestFile = 'connect.cfgt';
398
+ $configObj = $this->connect()->getConfig();
399
+ if ('ftp' == $p['deployment_type'] || '1' == $p['inst_protocol']) {
400
+ /*check ftp*/
401
+
402
+ $confFile = $configObj->downloader_path.DIRECTORY_SEPARATOR.$configTestFile;
403
+ try {
404
+ $ftpObj = new Mage_Connect_Ftp();
405
+ $ftpObj->connect($p['ftp']);
406
+ $tempFile = tempnam(sys_get_temp_dir(),'config');
407
+ $serial = md5('config test file');
408
+ $f = @fopen($tempFile, "w+");
409
+ @fwrite($f, $serial);
410
+ @fclose($f);
411
+ $ret=$ftpObj->upload($confFile, $tempFile);
412
+
413
+ //read file
414
+ if (!$errors && is_file($configTestFile)) {
415
+ $size = filesize($configTestFile);
416
+ if(!$size) {
417
+ $errors[]='Unable to read saved settings. Please check Installation Path of FTP Connection.';
418
+ }
419
+
420
+ if (!$errors) {
421
+ $f = @fopen($configTestFile, "r");
422
+ @fseek($f, 0, SEEK_SET);
423
+
424
+ $contents = @fread($f, strlen($serial));
425
+ if ($serial != $contents) {
426
+ $errors[]='Wrong Installation Path of FTP Connection.';
427
+ }
428
+ fclose($f);
429
+ }
430
+ } else {
431
+ $errors[] = 'Unable to read saved settings. Please check Installation Path of FTP Connection.';
432
+ }
433
+ $ftpObj->delete($confFile);
434
+ $ftpObj->close();
435
+ } catch (Exception $e) {
436
+ $errors[] = 'Deployment FTP Error. ' . $e->getMessage();
437
+ }
438
+ } else {
439
+ $p['ftp'] = '';
440
+ }
441
+
442
+ if ('1' == $p['use_custom_permissions_mode']) {
443
+ /*check permissions*/
444
+ if (octdec(intval($p['mkdir_mode'])) < 73 || octdec(intval($p['mkdir_mode'])) > 511) {
445
+ $errors[]='Folders permissions not valid. ';
446
+ }
447
+ if (octdec(intval($p['chmod_file_mode'])) < 73 || octdec(intval($p['chmod_file_mode'])) > 511) {
448
+ $errors[]='Files permissions not valid. ';
449
+ }
450
+ }
451
+ //$this->controller()->session()->addMessage('success', 'Settings has been successfully saved');
452
+ return $errors;
453
+ }
454
+ /**
455
+ * Save settings.
456
+ *
457
+ * @param array $p
458
+ */
459
+ public function saveConfigPost($p)
460
+ {
461
+ $configObj = $this->connect()->getConfig();
462
+ if ('ftp' == $p['deployment_type'] || '1' == $p['inst_protocol']){
463
+ $this->set('ftp',$p['ftp']);
464
+ } else {
465
+ $p['ftp'] = '';
466
+ }
467
+ $configObj->remote_config = $p['ftp'];
468
+ $configObj->preferred_state = $p['preferred_state'];
469
+ $configObj->protocol = $p['protocol'];
470
+ $configObj->use_custom_permissions_mode = $p['use_custom_permissions_mode'];
471
+ if ('1' == $p['use_custom_permissions_mode']) {
472
+ $configObj->global_dir_mode = octdec(intval($p['mkdir_mode']));
473
+ $configObj->global_file_mode = octdec(intval($p['chmod_file_mode']));
474
+ }
475
+ if ($configObj->save()) {
476
+ $this->controller()->session()->addMessage('success', 'Settings has been successfully saved');
477
+ } else {
478
+ $this->controller()->session()->addMessage('error', 'Settings cannot be saved');
479
+ }
480
+ return $this;
481
+ }
482
+
483
+ /**
484
+ * Check Extension Key
485
+ *
486
+ * @param string $id
487
+ * @param array $match
488
+ * @return int
489
+ */
490
+ public function checkExtensionKey($id, &$match)
491
+ {
492
+ if (preg_match('#^(.+)\/(.+)-([\.\d]+)$#', $id, $match)) {
493
+ return $match;
494
+ }
495
+ return preg_match('#^(.+)\/(.+)$#', $id, $match);
496
+ }
497
+ }
app/code/local/Mss/downloader/Maged/Model/Connect/Request.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class request
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ class Maged_Model_Connect_Request extends Maged_Model
36
+ {
37
+ protected function _construct()
38
+ {
39
+ parent::_construct();
40
+ $this->set('success_callback', 'clear_cache({success:parent.onSuccess, fail:parent.onFailure})');
41
+ $this->set('failure_callback', 'parent.onFailure()');
42
+ }
43
+ }
app/code/local/Mss/downloader/Maged/Model/Dowloader.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ class Maged_Model_Downloader extends Maged_Model
28
+ {
29
+
30
+ }
app/code/local/Mss/downloader/Maged/Model/Session.php ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class session
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ class Maged_Model_Session extends Maged_Model
36
+ {
37
+ /**
38
+ * Session
39
+ *
40
+ * @var Mage_Admin_Model_Session
41
+ */
42
+ protected $_session;
43
+
44
+ /**
45
+ * Init session
46
+ *
47
+ * @return Maged_Model_Session
48
+ */
49
+ public function start()
50
+ {
51
+ if ($this->controller()->isInstalled()) {
52
+ // initialize Magento Config
53
+ Mage::app();
54
+ $this->_session = Mage::getSingleton('admin/session');
55
+ } else {
56
+ session_start();
57
+ }
58
+ return $this;
59
+ }
60
+
61
+ /**
62
+ * Get value by key
63
+ *
64
+ * @param string $key
65
+ * @return mixed
66
+ */
67
+ public function get($key)
68
+ {
69
+ return isset($_SESSION[$key]) ? $_SESSION[$key] : null;
70
+ }
71
+
72
+ /**
73
+ * Set value for key
74
+ *
75
+ * @param string $key
76
+ * @param mixed $value
77
+ */
78
+ public function set($key, $value)
79
+ {
80
+ $_SESSION[$key] = $value;
81
+ return $this;
82
+ }
83
+
84
+ /**
85
+ * Authentication to downloader
86
+ */
87
+ public function authenticate()
88
+ {
89
+ if (!$this->_session) {
90
+ return $this;
91
+ }
92
+
93
+ if (!empty($_GET['return'])) {
94
+ $this->set('return_url', $_GET['return']);
95
+ }
96
+
97
+ if ($this->_checkUserAccess()) {
98
+ return $this;
99
+ }
100
+
101
+ if (!$this->controller()->isInstalled()) {
102
+ return $this;
103
+ }
104
+
105
+ try {
106
+ if (isset($_POST['username']) && !$this->validateFormKey()) {
107
+ $this->controller()
108
+ ->redirect(
109
+ $this->controller()->url(),
110
+ true
111
+ );
112
+ }
113
+ if ( (isset($_POST['username']) && empty($_POST['username']))
114
+ || (isset($_POST['password']) && empty($_POST['password']))) {
115
+ $this->addMessage('error', 'Invalid user name or password');
116
+ }
117
+ if (empty($_POST['username']) || empty($_POST['password'])) {
118
+ $this->controller()->setAction('login');
119
+ return $this;
120
+ }
121
+ $user = $this->_session->login($_POST['username'], $_POST['password']);
122
+ $this->_session->refreshAcl();
123
+ if ($this->_checkUserAccess($user)) {
124
+ return $this;
125
+ }
126
+ } catch (Exception $e) {
127
+ $this->addMessage('error', $e->getMessage());
128
+ }
129
+
130
+ $this->controller()
131
+ ->redirect(
132
+ $this->controller()->url('loggedin'),
133
+ true
134
+ );
135
+ }
136
+
137
+ /**
138
+ * Check is user logged in and permissions
139
+ *
140
+ * @param Mage_Admin_Model_User|null $user
141
+ * @return bool
142
+ */
143
+ protected function _checkUserAccess($user = null)
144
+ {
145
+ if ($user && !$user->getId()) {
146
+ $this->addMessage('error', 'Invalid user name or password');
147
+ $this->controller()->setAction('login');
148
+ } elseif ($this->getUserId() || ($user && $user->getId())) {
149
+ if ($this->_session->isAllowed('all')) {
150
+ return true;
151
+ } else {
152
+ $this->logout();
153
+ $this->addMessage('error', 'Access Denied', true);
154
+ $this->controller()->setAction('login');
155
+ }
156
+ }
157
+ return false;
158
+ }
159
+
160
+ /**
161
+ * Log Out
162
+ *
163
+ * @return Maged_Model_Session
164
+ */
165
+ public function logout()
166
+ {
167
+ if (!$this->_session) {
168
+ return $this;
169
+ }
170
+ $this->_session->unsUser();
171
+ return $this;
172
+ }
173
+
174
+ /**
175
+ * Retrieve user
176
+ *
177
+ * @return mixed
178
+ */
179
+ public function getUserId()
180
+ {
181
+ if (($session = $this->_session) && ($user = $session->getUser())) {
182
+ return $user->getId();
183
+ }
184
+ return false;
185
+ }
186
+
187
+ /**
188
+ * Add Message
189
+ *
190
+ * @param string $type
191
+ * @param string $msg
192
+ * @param string $clear
193
+ * @return Maged_Model_Session
194
+ */
195
+ public function addMessage($type, $msg, $clear = false)
196
+ {
197
+ $msgs = $this->getMessages($clear);
198
+ $msgs[$type][] = $msg;
199
+ $this->set('messages', $msgs);
200
+ return $this;
201
+ }
202
+
203
+ /**
204
+ * Retrieve messages from cache
205
+ *
206
+ * @param boolean $clear
207
+ * @return mixed
208
+ */
209
+ public function getMessages($clear = true)
210
+ {
211
+ $msgs = $this->get('messages');
212
+ $msgs = $msgs ? $msgs : array();
213
+ if ($clear) {
214
+ unset($_SESSION['messages']);
215
+ }
216
+ return $msgs;
217
+ }
218
+
219
+ /**
220
+ * Retrieve url to adminhtml
221
+ *
222
+ * @return string
223
+ */
224
+ public function getReturnUrl()
225
+ {
226
+ if (!$this->_session || !$this->_session->isLoggedIn()) {
227
+ return '';
228
+ }
229
+ return Mage::getSingleton('adminhtml/url')->getUrl('adminhtml');
230
+ }
231
+
232
+ /**
233
+ * Retrieve Session Form Key
234
+ *
235
+ * @return string A 16 bit unique key for forms
236
+ */
237
+ public function getFormKey()
238
+ {
239
+ if (!$this->get('_form_key')) {
240
+ $this->set('_form_key', Mage::helper('core')->getRandomString(16));
241
+ }
242
+ return $this->get('_form_key');
243
+ }
244
+
245
+ /**
246
+ * Validate Form Key
247
+ *
248
+ * @return bool
249
+ */
250
+ public function validateFormKey()
251
+ {
252
+ if (!($formKey = $_REQUEST['form_key']) || $formKey != $this->getFormKey()) {
253
+ return false;
254
+ }
255
+ return true;
256
+ }
257
+ }
app/code/local/Mss/downloader/Maged/View.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class for viewer
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
33
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
+ */
35
+ class Maged_View
36
+ {
37
+ /**
38
+ * Internal cache
39
+ *
40
+ * @var array
41
+ */
42
+ protected $_data = array();
43
+
44
+ /**
45
+ * Constructor
46
+ */
47
+ public function __construct()
48
+ {
49
+
50
+ }
51
+
52
+ /**
53
+ * Retrieve Controller as singleton
54
+ *
55
+ * @return Maged_Controller
56
+ */
57
+ public function controller()
58
+ {
59
+ return Maged_Controller::singleton();
60
+ }
61
+
62
+ /**
63
+ * Create url by action and params
64
+ *
65
+ * @param mixed $action
66
+ * @param mixed $params
67
+ * @return string
68
+ */
69
+ public function url($action='', $params=array())
70
+ {
71
+ return $this->controller()->url($action, $params);
72
+ }
73
+
74
+ /**
75
+ * Retrieve base url
76
+ *
77
+ * @return string
78
+ */
79
+ public function baseUrl()
80
+ {
81
+ return str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']));
82
+ }
83
+
84
+ /**
85
+ * Retrieve url of magento
86
+ *
87
+ * @return string
88
+ */
89
+ public function mageUrl()
90
+ {
91
+ return str_replace('\\', '/', dirname($this->baseUrl()));
92
+ }
93
+
94
+ /**
95
+ * Include template
96
+ *
97
+ * @param string $name
98
+ * @return string
99
+ */
100
+ public function template($name)
101
+ {
102
+ ob_start();
103
+ include $this->controller()->filepath('template/'.$name);
104
+ return ob_get_clean();
105
+ }
106
+
107
+ /**
108
+ * Set value for key
109
+ *
110
+ * @param string $key
111
+ * @param mixed $value
112
+ * @return Maged_Controller
113
+ */
114
+ public function set($key, $value)
115
+ {
116
+ $this->_data[$key] = $value;
117
+ return $this;
118
+ }
119
+
120
+ /**
121
+ * Get value by key
122
+ *
123
+ * @param string $key
124
+ * @return mixed
125
+ */
126
+ public function get($key)
127
+ {
128
+ return isset($this->_data[$key]) ? $this->_data[$key] : null;
129
+ }
130
+
131
+ /**
132
+ * Translator
133
+ *
134
+ * @param string $string
135
+ * @return string
136
+ */
137
+ public function __($string)
138
+ {
139
+ return $string;
140
+ }
141
+
142
+ /**
143
+ * Retrieve link for header menu
144
+ *
145
+ * @param mixed $action
146
+ */
147
+ public function getNavLinkParams($action)
148
+ {
149
+ $params = 'href="'.$this->url($action).'"';
150
+ if ($this->controller()->getAction()==$action) {
151
+ $params .= ' class="active"';
152
+ }
153
+ return $params;
154
+ }
155
+
156
+ /**
157
+ * Retrieve Session Form Key
158
+ *
159
+ * @return string
160
+ */
161
+ public function getFormKey()
162
+ {
163
+ return $this->controller()->getFormKey();
164
+ }
165
+
166
+ /**
167
+ * Escape html entities
168
+ *
169
+ * @param mixed $data
170
+ * @param array $allowedTags
171
+ * @return mixed
172
+ */
173
+ public function escapeHtml($data, $allowedTags = null)
174
+ {
175
+ if (is_array($data)) {
176
+ $result = array();
177
+ foreach ($data as $item) {
178
+ $result[] = $this->escapeHtml($item);
179
+ }
180
+ } else {
181
+ // process single item
182
+ if (strlen($data)) {
183
+ if (is_array($allowedTags) and !empty($allowedTags)) {
184
+ $allowed = implode('|', $allowedTags);
185
+ $result = preg_replace('/<([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)>/si', '##$1$2$3##', $data);
186
+ $result = htmlspecialchars($result, ENT_COMPAT, 'UTF-8', false);
187
+ $result = preg_replace('/##([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)##/si', '<$1$2$3>', $result);
188
+ } else {
189
+ $result = htmlspecialchars($data, ENT_COMPAT, 'UTF-8', false);
190
+ }
191
+ } else {
192
+ $result = $data;
193
+ }
194
+ }
195
+ return $result;
196
+ }
197
+ }
app/code/local/Mss/downloader/cache.cfg ADDED
Binary file
app/code/local/Mss/downloader/config.ini ADDED
@@ -0,0 +1 @@
 
1
+ root_channel=community
app/code/local/Mss/downloader/connect.cfg ADDED
@@ -0,0 +1 @@
 
1
+ ::ConnectConfig::v::1.0::a:12:{s:7:"php_ini";s:0:"";s:8:"protocol";s:5:"https";s:15:"preferred_state";s:6:"stable";s:27:"use_custom_permissions_mode";b:0;s:15:"global_dir_mode";i:511;s:16:"global_file_mode";i:438;s:15:"downloader_path";s:10:"downloader";s:12:"magento_root";s:42:"/var/www/html/magento-latest/downloader/..";s:16:"root_channel_uri";s:39:"connect20.magentocommerce.com/community";s:12:"root_channel";s:9:"community";s:13:"remote_config";s:0:"";s:9:"sync_pear";b:0;}
app/code/local/Mss/downloader/favicon.ico ADDED
Binary file
app/code/local/Mss/downloader/index.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ if (version_compare(phpversion(), '5.2.0', '<')===true) {
28
+ echo '<div style="font:12px/1.35em arial, helvetica, sans-serif;"><div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;"><h3 style="margin:0; font-size:1.7em; font-weight:normal; text-transform:none; text-align:left; color:#2f2f2f;">Whoops, it looks like you have an invalid PHP version.</h3></div><p>Magento supports PHP 5.2.0 or newer. <a href="http://www.magentocommerce.com/install" target="">Find out</a> how to install</a> Magento using PHP-CGI as a work-around.</p></div>';
29
+ exit;
30
+ }
31
+
32
+ require_once("lib/Mage/Autoload/Simple.php");
33
+ Mage_Autoload_Simple::register();
34
+
35
+ umask(0);
36
+ Maged_Controller::run();
app/code/local/Mss/downloader/js/prototype.js ADDED
@@ -0,0 +1,3277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Prototype JavaScript framework, version 1.5.1.1
2
+ * (c) 2005-2007 Sam Stephenson
3
+ *
4
+ * Prototype is freely distributable under the terms of an MIT-style license.
5
+ * For details, see the Prototype web site: http://www.prototypejs.org/
6
+ *
7
+ /*--------------------------------------------------------------------------*/
8
+
9
+ var Prototype = {
10
+ Version: '1.5.1.1',
11
+
12
+ Browser: {
13
+ IE: !!(window.attachEvent && !window.opera),
14
+ Opera: !!window.opera,
15
+ WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
16
+ Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
17
+ },
18
+
19
+ BrowserFeatures: {
20
+ XPath: !!document.evaluate,
21
+ ElementExtensions: !!window.HTMLElement,
22
+ SpecificElementExtensions:
23
+ (document.createElement('div').__proto__ !==
24
+ document.createElement('form').__proto__)
25
+ },
26
+
27
+ ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
28
+ JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
29
+
30
+ emptyFunction: function() { },
31
+ K: function(x) { return x }
32
+ }
33
+
34
+ var Class = {
35
+ create: function() {
36
+ return function() {
37
+ this.initialize.apply(this, arguments);
38
+ }
39
+ }
40
+ }
41
+
42
+ var Abstract = new Object();
43
+
44
+ Object.extend = function(destination, source) {
45
+ for (var property in source) {
46
+ destination[property] = source[property];
47
+ }
48
+ return destination;
49
+ }
50
+
51
+ Object.extend(Object, {
52
+ inspect: function(object) {
53
+ try {
54
+ if (object === undefined) return 'undefined';
55
+ if (object === null) return 'null';
56
+ return object.inspect ? object.inspect() : object.toString();
57
+ } catch (e) {
58
+ if (e instanceof RangeError) return '...';
59
+ throw e;
60
+ }
61
+ },
62
+
63
+ toJSON: function(object) {
64
+ var type = typeof object;
65
+ switch(type) {
66
+ case 'undefined':
67
+ case 'function':
68
+ case 'unknown': return;
69
+ case 'boolean': return object.toString();
70
+ }
71
+ if (object === null) return 'null';
72
+ if (object.toJSON) return object.toJSON();
73
+ if (object.ownerDocument === document) return;
74
+ var results = [];
75
+ for (var property in object) {
76
+ var value = Object.toJSON(object[property]);
77
+ if (value !== undefined)
78
+ results.push(property.toJSON() + ': ' + value);
79
+ }
80
+ return '{' + results.join(', ') + '}';
81
+ },
82
+
83
+ keys: function(object) {
84
+ var keys = [];
85
+ for (var property in object)
86
+ keys.push(property);
87
+ return keys;
88
+ },
89
+
90
+ values: function(object) {
91
+ var values = [];
92
+ for (var property in object)
93
+ values.push(object[property]);
94
+ return values;
95
+ },
96
+
97
+ clone: function(object) {
98
+ return Object.extend({}, object);
99
+ }
100
+ });
101
+
102
+ Function.prototype.bind = function() {
103
+ var __method = this, args = $A(arguments), object = args.shift();
104
+ return function() {
105
+ return __method.apply(object, args.concat($A(arguments)));
106
+ }
107
+ }
108
+
109
+ Function.prototype.bindAsEventListener = function(object) {
110
+ var __method = this, args = $A(arguments), object = args.shift();
111
+ return function(event) {
112
+ return __method.apply(object, [event || window.event].concat(args));
113
+ }
114
+ }
115
+
116
+ Object.extend(Number.prototype, {
117
+ toColorPart: function() {
118
+ return this.toPaddedString(2, 16);
119
+ },
120
+
121
+ succ: function() {
122
+ return this + 1;
123
+ },
124
+
125
+ times: function(iterator) {
126
+ $R(0, this, true).each(iterator);
127
+ return this;
128
+ },
129
+
130
+ toPaddedString: function(length, radix) {
131
+ var string = this.toString(radix || 10);
132
+ return '0'.times(length - string.length) + string;
133
+ },
134
+
135
+ toJSON: function() {
136
+ return isFinite(this) ? this.toString() : 'null';
137
+ }
138
+ });
139
+
140
+ Date.prototype.toJSON = function() {
141
+ return '"' + this.getFullYear() + '-' +
142
+ (this.getMonth() + 1).toPaddedString(2) + '-' +
143
+ this.getDate().toPaddedString(2) + 'T' +
144
+ this.getHours().toPaddedString(2) + ':' +
145
+ this.getMinutes().toPaddedString(2) + ':' +
146
+ this.getSeconds().toPaddedString(2) + '"';
147
+ };
148
+
149
+ var Try = {
150
+ these: function() {
151
+ var returnValue;
152
+
153
+ for (var i = 0, length = arguments.length; i < length; i++) {
154
+ var lambda = arguments[i];
155
+ try {
156
+ returnValue = lambda();
157
+ break;
158
+ } catch (e) {}
159
+ }
160
+
161
+ return returnValue;
162
+ }
163
+ }
164
+
165
+ /*--------------------------------------------------------------------------*/
166
+
167
+ var PeriodicalExecuter = Class.create();
168
+ PeriodicalExecuter.prototype = {
169
+ initialize: function(callback, frequency) {
170
+ this.callback = callback;
171
+ this.frequency = frequency;
172
+ this.currentlyExecuting = false;
173
+
174
+ this.registerCallback();
175
+ },
176
+
177
+ registerCallback: function() {
178
+ this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
179
+ },
180
+
181
+ stop: function() {
182
+ if (!this.timer) return;
183
+ clearInterval(this.timer);
184
+ this.timer = null;
185
+ },
186
+
187
+ onTimerEvent: function() {
188
+ if (!this.currentlyExecuting) {
189
+ try {
190
+ this.currentlyExecuting = true;
191
+ this.callback(this);
192
+ } finally {
193
+ this.currentlyExecuting = false;
194
+ }
195
+ }
196
+ }
197
+ }
198
+ Object.extend(String, {
199
+ interpret: function(value) {
200
+ return value == null ? '' : String(value);
201
+ },
202
+ specialChar: {
203
+ '\b': '\\b',
204
+ '\t': '\\t',
205
+ '\n': '\\n',
206
+ '\f': '\\f',
207
+ '\r': '\\r',
208
+ '\\': '\\\\'
209
+ }
210
+ });
211
+
212
+ Object.extend(String.prototype, {
213
+ gsub: function(pattern, replacement) {
214
+ var result = '', source = this, match;
215
+ replacement = arguments.callee.prepareReplacement(replacement);
216
+
217
+ while (source.length > 0) {
218
+ if (match = source.match(pattern)) {
219
+ result += source.slice(0, match.index);
220
+ result += String.interpret(replacement(match));
221
+ source = source.slice(match.index + match[0].length);
222
+ } else {
223
+ result += source, source = '';
224
+ }
225
+ }
226
+ return result;
227
+ },
228
+
229
+ sub: function(pattern, replacement, count) {
230
+ replacement = this.gsub.prepareReplacement(replacement);
231
+ count = count === undefined ? 1 : count;
232
+
233
+ return this.gsub(pattern, function(match) {
234
+ if (--count < 0) return match[0];
235
+ return replacement(match);
236
+ });
237
+ },
238
+
239
+ scan: function(pattern, iterator) {
240
+ this.gsub(pattern, iterator);
241
+ return this;
242
+ },
243
+
244
+ truncate: function(length, truncation) {
245
+ length = length || 30;
246
+ truncation = truncation === undefined ? '...' : truncation;
247
+ return this.length > length ?
248
+ this.slice(0, length - truncation.length) + truncation : this;
249
+ },
250
+
251
+ strip: function() {
252
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
253
+ },
254
+
255
+ stripTags: function() {
256
+ return this.replace(/<\/?[^>]+>/gi, '');
257
+ },
258
+
259
+ stripScripts: function() {
260
+ return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
261
+ },
262
+
263
+ extractScripts: function() {
264
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
265
+ var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
266
+ return (this.match(matchAll) || []).map(function(scriptTag) {
267
+ return (scriptTag.match(matchOne) || ['', ''])[1];
268
+ });
269
+ },
270
+
271
+ evalScripts: function() {
272
+ return this.extractScripts().map(function(script) { return eval(script) });
273
+ },
274
+
275
+ escapeHTML: function() {
276
+ var self = arguments.callee;
277
+ self.text.data = this;
278
+ return self.div.innerHTML;
279
+ },
280
+
281
+ unescapeHTML: function() {
282
+ var div = document.createElement('div');
283
+ div.innerHTML = this.stripTags();
284
+ return div.childNodes[0] ? (div.childNodes.length > 1 ?
285
+ $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
286
+ div.childNodes[0].nodeValue) : '';
287
+ },
288
+
289
+ toQueryParams: function(separator) {
290
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
291
+ if (!match) return {};
292
+
293
+ return match[1].split(separator || '&').inject({}, function(hash, pair) {
294
+ if ((pair = pair.split('='))[0]) {
295
+ var key = decodeURIComponent(pair.shift());
296
+ var value = pair.length > 1 ? pair.join('=') : pair[0];
297
+ if (value != undefined) value = decodeURIComponent(value);
298
+
299
+ if (key in hash) {
300
+ if (hash[key].constructor != Array) hash[key] = [hash[key]];
301
+ hash[key].push(value);
302
+ }
303
+ else hash[key] = value;
304
+ }
305
+ return hash;
306
+ });
307
+ },
308
+
309
+ toArray: function() {
310
+ return this.split('');
311
+ },
312
+
313
+ succ: function() {
314
+ return this.slice(0, this.length - 1) +
315
+ String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
316
+ },
317
+
318
+ times: function(count) {
319
+ var result = '';
320
+ for (var i = 0; i < count; i++) result += this;
321
+ return result;
322
+ },
323
+
324
+ camelize: function() {
325
+ var parts = this.split('-'), len = parts.length;
326
+ if (len == 1) return parts[0];
327
+
328
+ var camelized = this.charAt(0) == '-'
329
+ ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
330
+ : parts[0];
331
+
332
+ for (var i = 1; i < len; i++)
333
+ camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
334
+
335
+ return camelized;
336
+ },
337
+
338
+ capitalize: function() {
339
+ return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
340
+ },
341
+
342
+ underscore: function() {
343
+ return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
344
+ },
345
+
346
+ dasherize: function() {
347
+ return this.gsub(/_/,'-');
348
+ },
349
+
350
+ inspect: function(useDoubleQuotes) {
351
+ var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
352
+ var character = String.specialChar[match[0]];
353
+ return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
354
+ });
355
+ if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
356
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
357
+ },
358
+
359
+ toJSON: function() {
360
+ return this.inspect(true);
361
+ },
362
+
363
+ unfilterJSON: function(filter) {
364
+ return this.sub(filter || Prototype.JSONFilter, '#{1}');
365
+ },
366
+
367
+ isJSON: function() {
368
+ var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
369
+ return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
370
+ },
371
+
372
+ evalJSON: function(sanitize) {
373
+ var json = this.unfilterJSON();
374
+ try {
375
+ if (!sanitize || json.isJSON()) return eval('(' + json + ')');
376
+ } catch (e) { }
377
+ throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
378
+ },
379
+
380
+ include: function(pattern) {
381
+ return this.indexOf(pattern) > -1;
382
+ },
383
+
384
+ startsWith: function(pattern) {
385
+ return this.indexOf(pattern) === 0;
386
+ },
387
+
388
+ endsWith: function(pattern) {
389
+ var d = this.length - pattern.length;
390
+ return d >= 0 && this.lastIndexOf(pattern) === d;
391
+ },
392
+
393
+ empty: function() {
394
+ return this == '';
395
+ },
396
+
397
+ blank: function() {
398
+ return /^\s*$/.test(this);
399
+ }
400
+ });
401
+
402
+ if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
403
+ escapeHTML: function() {
404
+ return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
405
+ },
406
+ unescapeHTML: function() {
407
+ return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
408
+ }
409
+ });
410
+
411
+ String.prototype.gsub.prepareReplacement = function(replacement) {
412
+ if (typeof replacement == 'function') return replacement;
413
+ var template = new Template(replacement);
414
+ return function(match) { return template.evaluate(match) };
415
+ }
416
+
417
+ String.prototype.parseQuery = String.prototype.toQueryParams;
418
+
419
+ Object.extend(String.prototype.escapeHTML, {
420
+ div: document.createElement('div'),
421
+ text: document.createTextNode('')
422
+ });
423
+
424
+ with (String.prototype.escapeHTML) div.appendChild(text);
425
+
426
+ var Template = Class.create();
427
+ Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
428
+ Template.prototype = {
429
+ initialize: function(template, pattern) {
430
+ this.template = template.toString();
431
+ this.pattern = pattern || Template.Pattern;
432
+ },
433
+
434
+ evaluate: function(object) {
435
+ return this.template.gsub(this.pattern, function(match) {
436
+ var before = match[1];
437
+ if (before == '\\') return match[2];
438
+ return before + String.interpret(object[match[3]]);
439
+ });
440
+ }
441
+ }
442
+
443
+ var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead');
444
+
445
+ var Enumerable = {
446
+ each: function(iterator) {
447
+ var index = 0;
448
+ try {
449
+ this._each(function(value) {
450
+ iterator(value, index++);
451
+ });
452
+ } catch (e) {
453
+ if (e != $break) throw e;
454
+ }
455
+ return this;
456
+ },
457
+
458
+ eachSlice: function(number, iterator) {
459
+ var index = -number, slices = [], array = this.toArray();
460
+ while ((index += number) < array.length)
461
+ slices.push(array.slice(index, index+number));
462
+ return slices.map(iterator);
463
+ },
464
+
465
+ all: function(iterator) {
466
+ var result = true;
467
+ this.each(function(value, index) {
468
+ result = result && !!(iterator || Prototype.K)(value, index);
469
+ if (!result) throw $break;
470
+ });
471
+ return result;
472
+ },
473
+
474
+ any: function(iterator) {
475
+ var result = false;
476
+ this.each(function(value, index) {
477
+ if (result = !!(iterator || Prototype.K)(value, index))
478
+ throw $break;
479
+ });
480
+ return result;
481
+ },
482
+
483
+ collect: function(iterator) {
484
+ var results = [];
485
+ this.each(function(value, index) {
486
+ results.push((iterator || Prototype.K)(value, index));
487
+ });
488
+ return results;
489
+ },
490
+
491
+ detect: function(iterator) {
492
+ var result;
493
+ this.each(function(value, index) {
494
+ if (iterator(value, index)) {
495
+ result = value;
496
+ throw $break;
497
+ }
498
+ });
499
+ return result;
500
+ },
501
+
502
+ findAll: function(iterator) {
503
+ var results = [];
504
+ this.each(function(value, index) {
505
+ if (iterator(value, index))
506
+ results.push(value);
507
+ });
508
+ return results;
509
+ },
510
+
511
+ grep: function(pattern, iterator) {
512
+ var results = [];
513
+ this.each(function(value, index) {
514
+ var stringValue = value.toString();
515
+ if (stringValue.match(pattern))
516
+ results.push((iterator || Prototype.K)(value, index));
517
+ })
518
+ return results;
519
+ },
520
+
521
+ include: function(object) {
522
+ var found = false;
523
+ this.each(function(value) {
524
+ if (value == object) {
525
+ found = true;
526
+ throw $break;
527
+ }
528
+ });
529
+ return found;
530
+ },
531
+
532
+ inGroupsOf: function(number, fillWith) {
533
+ fillWith = fillWith === undefined ? null : fillWith;
534
+ return this.eachSlice(number, function(slice) {
535
+ while(slice.length < number) slice.push(fillWith);
536
+ return slice;
537
+ });
538
+ },
539
+
540
+ inject: function(memo, iterator) {
541
+ this.each(function(value, index) {
542
+ memo = iterator(memo, value, index);
543
+ });
544
+ return memo;
545
+ },
546
+
547
+ invoke: function(method) {
548
+ var args = $A(arguments).slice(1);
549
+ return this.map(function(value) {
550
+ return value[method].apply(value, args);
551
+ });
552
+ },
553
+
554
+ max: function(iterator) {
555
+ var result;
556
+ this.each(function(value, index) {
557
+ value = (iterator || Prototype.K)(value, index);
558
+ if (result == undefined || value >= result)
559
+ result = value;
560
+ });
561
+ return result;
562
+ },
563
+
564
+ min: function(iterator) {
565
+ var result;
566
+ this.each(function(value, index) {
567
+ value = (iterator || Prototype.K)(value, index);
568
+ if (result == undefined || value < result)
569
+ result = value;
570
+ });
571
+ return result;
572
+ },
573
+
574
+ partition: function(iterator) {
575
+ var trues = [], falses = [];
576
+ this.each(function(value, index) {
577
+ ((iterator || Prototype.K)(value, index) ?
578
+ trues : falses).push(value);
579
+ });
580
+ return [trues, falses];
581
+ },
582
+
583
+ pluck: function(property) {
584
+ var results = [];
585
+ this.each(function(value, index) {
586
+ results.push(value[property]);
587
+ });
588
+ return results;
589
+ },
590
+
591
+ reject: function(iterator) {
592
+ var results = [];
593
+ this.each(function(value, index) {
594
+ if (!iterator(value, index))
595
+ results.push(value);
596
+ });
597
+ return results;
598
+ },
599
+
600
+ sortBy: function(iterator) {
601
+ return this.map(function(value, index) {
602
+ return {value: value, criteria: iterator(value, index)};
603
+ }).sort(function(left, right) {
604
+ var a = left.criteria, b = right.criteria;
605
+ return a < b ? -1 : a > b ? 1 : 0;
606
+ }).pluck('value');
607
+ },
608
+
609
+ toArray: function() {
610
+ return this.map();
611
+ },
612
+
613
+ zip: function() {
614
+ var iterator = Prototype.K, args = $A(arguments);
615
+ if (typeof args.last() == 'function')
616
+ iterator = args.pop();
617
+
618
+ var collections = [this].concat(args).map($A);
619
+ return this.map(function(value, index) {
620
+ return iterator(collections.pluck(index));
621
+ });
622
+ },
623
+
624
+ size: function() {
625
+ return this.toArray().length;
626
+ },
627
+
628
+ inspect: function() {
629
+ return '#<Enumerable:' + this.toArray().inspect() + '>';
630
+ }
631
+ }
632
+
633
+ Object.extend(Enumerable, {
634
+ map: Enumerable.collect,
635
+ find: Enumerable.detect,
636
+ select: Enumerable.findAll,
637
+ member: Enumerable.include,
638
+ entries: Enumerable.toArray
639
+ });
640
+ var $A = Array.from = function(iterable) {
641
+ if (!iterable) return [];
642
+ if (iterable.toArray) {
643
+ return iterable.toArray();
644
+ } else {
645
+ var results = [];
646
+ for (var i = 0, length = iterable.length; i < length; i++)
647
+ results.push(iterable[i]);
648
+ return results;
649
+ }
650
+ }
651
+
652
+ if (Prototype.Browser.WebKit) {
653
+ $A = Array.from = function(iterable) {
654
+ if (!iterable) return [];
655
+ if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
656
+ iterable.toArray) {
657
+ return iterable.toArray();
658
+ } else {
659
+ var results = [];
660
+ for (var i = 0, length = iterable.length; i < length; i++)
661
+ results.push(iterable[i]);
662
+ return results;
663
+ }
664
+ }
665
+ }
666
+
667
+ Object.extend(Array.prototype, Enumerable);
668
+
669
+ if (!Array.prototype._reverse)
670
+ Array.prototype._reverse = Array.prototype.reverse;
671
+
672
+ Object.extend(Array.prototype, {
673
+ _each: function(iterator) {
674
+ for (var i = 0, length = this.length; i < length; i++)
675
+ iterator(this[i]);
676
+ },
677
+
678
+ clear: function() {
679
+ this.length = 0;
680
+ return this;
681
+ },
682
+
683
+ first: function() {
684
+ return this[0];
685
+ },
686
+
687
+ last: function() {
688
+ return this[this.length - 1];
689
+ },
690
+
691
+ compact: function() {
692
+ return this.select(function(value) {
693
+ return value != null;
694
+ });
695
+ },
696
+
697
+ flatten: function() {
698
+ return this.inject([], function(array, value) {
699
+ return array.concat(value && value.constructor == Array ?
700
+ value.flatten() : [value]);
701
+ });
702
+ },
703
+
704
+ without: function() {
705
+ var values = $A(arguments);
706
+ return this.select(function(value) {
707
+ return !values.include(value);
708
+ });
709
+ },
710
+
711
+ indexOf: function(object) {
712
+ for (var i = 0, length = this.length; i < length; i++)
713
+ if (this[i] == object) return i;
714
+ return -1;
715
+ },
716
+
717
+ reverse: function(inline) {
718
+ return (inline !== false ? this : this.toArray())._reverse();
719
+ },
720
+
721
+ reduce: function() {
722
+ return this.length > 1 ? this : this[0];
723
+ },
724
+
725
+ uniq: function(sorted) {
726
+ return this.inject([], function(array, value, index) {
727
+ if (0 == index || (sorted ? array.last() != value : !array.include(value)))
728
+ array.push(value);
729
+ return array;
730
+ });
731
+ },
732
+
733
+ clone: function() {
734
+ return [].concat(this);
735
+ },
736
+
737
+ size: function() {
738
+ return this.length;
739
+ },
740
+
741
+ inspect: function() {
742
+ return '[' + this.map(Object.inspect).join(', ') + ']';
743
+ },
744
+
745
+ toJSON: function() {
746
+ var results = [];
747
+ this.each(function(object) {
748
+ var value = Object.toJSON(object);
749
+ if (value !== undefined) results.push(value);
750
+ });
751
+ return '[' + results.join(', ') + ']';
752
+ }
753
+ });
754
+
755
+ Array.prototype.toArray = Array.prototype.clone;
756
+
757
+ function $w(string) {
758
+ string = string.strip();
759
+ return string ? string.split(/\s+/) : [];
760
+ }
761
+
762
+ if (Prototype.Browser.Opera){
763
+ Array.prototype.concat = function() {
764
+ var array = [];
765
+ for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
766
+ for (var i = 0, length = arguments.length; i < length; i++) {
767
+ if (arguments[i].constructor == Array) {
768
+ for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
769
+ array.push(arguments[i][j]);
770
+ } else {
771
+ array.push(arguments[i]);
772
+ }
773
+ }
774
+ return array;
775
+ }
776
+ }
777
+ var Hash = function(object) {
778
+ if (object instanceof Hash) this.merge(object);
779
+ else Object.extend(this, object || {});
780
+ };
781
+
782
+ Object.extend(Hash, {
783
+ toQueryString: function(obj) {
784
+ var parts = [];
785
+ parts.add = arguments.callee.addPair;
786
+
787
+ this.prototype._each.call(obj, function(pair) {
788
+ if (!pair.key) return;
789
+ var value = pair.value;
790
+
791
+ if (value && typeof value == 'object') {
792
+ if (value.constructor == Array) value.each(function(value) {
793
+ parts.add(pair.key, value);
794
+ });
795
+ return;
796
+ }
797
+ parts.add(pair.key, value);
798
+ });
799
+
800
+ return parts.join('&');
801
+ },
802
+
803
+ toJSON: function(object) {
804
+ var results = [];
805
+ this.prototype._each.call(object, function(pair) {
806
+ var value = Object.toJSON(pair.value);
807
+ if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
808
+ });
809
+ return '{' + results.join(', ') + '}';
810
+ }
811
+ });
812
+
813
+ Hash.toQueryString.addPair = function(key, value, prefix) {
814
+ key = encodeURIComponent(key);
815
+ if (value === undefined) this.push(key);
816
+ else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
817
+ }
818
+
819
+ Object.extend(Hash.prototype, Enumerable);
820
+ Object.extend(Hash.prototype, {
821
+ _each: function(iterator) {
822
+ for (var key in this) {
823
+ var value = this[key];
824
+ if (value && value == Hash.prototype[key]) continue;
825
+
826
+ var pair = [key, value];
827
+ pair.key = key;
828
+ pair.value = value;
829
+ iterator(pair);
830
+ }
831
+ },
832
+
833
+ keys: function() {
834
+ return this.pluck('key');
835
+ },
836
+
837
+ values: function() {
838
+ return this.pluck('value');
839
+ },
840
+
841
+ merge: function(hash) {
842
+ return $H(hash).inject(this, function(mergedHash, pair) {
843
+ mergedHash[pair.key] = pair.value;
844
+ return mergedHash;
845
+ });
846
+ },
847
+
848
+ remove: function() {
849
+ var result;
850
+ for(var i = 0, length = arguments.length; i < length; i++) {
851
+ var value = this[arguments[i]];
852
+ if (value !== undefined){
853
+ if (result === undefined) result = value;
854
+ else {
855
+ if (result.constructor != Array) result = [result];
856
+ result.push(value)
857
+ }
858
+ }
859
+ delete this[arguments[i]];
860
+ }
861
+ return result;
862
+ },
863
+
864
+ toQueryString: function() {
865
+ return Hash.toQueryString(this);
866
+ },
867
+
868
+ inspect: function() {
869
+ return '#<Hash:{' + this.map(function(pair) {
870
+ return pair.map(Object.inspect).join(': ');
871
+ }).join(', ') + '}>';
872
+ },
873
+
874
+ toJSON: function() {
875
+ return Hash.toJSON(this);
876
+ }
877
+ });
878
+
879
+ function $H(object) {
880
+ if (object instanceof Hash) return object;
881
+ return new Hash(object);
882
+ };
883
+
884
+ // Safari iterates over shadowed properties
885
+ if (function() {
886
+ var i = 0, Test = function(value) { this.key = value };
887
+ Test.prototype.key = 'foo';
888
+ for (var property in new Test('bar')) i++;
889
+ return i > 1;
890
+ }()) Hash.prototype._each = function(iterator) {
891
+ var cache = [];
892
+ for (var key in this) {
893
+ var value = this[key];
894
+ if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
895
+ cache.push(key);
896
+ var pair = [key, value];
897
+ pair.key = key;
898
+ pair.value = value;
899
+ iterator(pair);
900
+ }
901
+ };
902
+ ObjectRange = Class.create();
903
+ Object.extend(ObjectRange.prototype, Enumerable);
904
+ Object.extend(ObjectRange.prototype, {
905
+ initialize: function(start, end, exclusive) {
906
+ this.start = start;
907
+ this.end = end;
908
+ this.exclusive = exclusive;
909
+ },
910
+
911
+ _each: function(iterator) {
912
+ var value = this.start;
913
+ while (this.include(value)) {
914
+ iterator(value);
915
+ value = value.succ();
916
+ }
917
+ },
918
+
919
+ include: function(value) {
920
+ if (value < this.start)
921
+ return false;
922
+ if (this.exclusive)
923
+ return value < this.end;
924
+ return value <= this.end;
925
+ }
926
+ });
927
+
928
+ var $R = function(start, end, exclusive) {
929
+ return new ObjectRange(start, end, exclusive);
930
+ }
931
+
932
+ var Ajax = {
933
+ getTransport: function() {
934
+ return Try.these(
935
+ function() {return new XMLHttpRequest()},
936
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
937
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
938
+ ) || false;
939
+ },
940
+
941
+ activeRequestCount: 0
942
+ }
943
+
944
+ Ajax.Responders = {
945
+ responders: [],
946
+
947
+ _each: function(iterator) {
948
+ this.responders._each(iterator);
949
+ },
950
+
951
+ register: function(responder) {
952
+ if (!this.include(responder))
953
+ this.responders.push(responder);
954
+ },
955
+
956
+ unregister: function(responder) {
957
+ this.responders = this.responders.without(responder);
958
+ },
959
+
960
+ dispatch: function(callback, request, transport, json) {
961
+ this.each(function(responder) {
962
+ if (typeof responder[callback] == 'function') {
963
+ try {
964
+ responder[callback].apply(responder, [request, transport, json]);
965
+ } catch (e) {}
966
+ }
967
+ });
968
+ }
969
+ };
970
+
971
+ Object.extend(Ajax.Responders, Enumerable);
972
+
973
+ Ajax.Responders.register({
974
+ onCreate: function() {
975
+ Ajax.activeRequestCount++;
976
+ },
977
+ onComplete: function() {
978
+ Ajax.activeRequestCount--;
979
+ }
980
+ });
981
+
982
+ Ajax.Base = function() {};
983
+ Ajax.Base.prototype = {
984
+ setOptions: function(options) {
985
+ this.options = {
986
+ method: 'post',
987
+ asynchronous: true,
988
+ contentType: 'application/x-www-form-urlencoded',
989
+ encoding: 'UTF-8',
990
+ parameters: ''
991
+ }
992
+ Object.extend(this.options, options || {});
993
+
994
+ this.options.method = this.options.method.toLowerCase();
995
+ if (typeof this.options.parameters == 'string')
996
+ this.options.parameters = this.options.parameters.toQueryParams();
997
+ }
998
+ }
999
+
1000
+ Ajax.Request = Class.create();
1001
+ Ajax.Request.Events =
1002
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
1003
+
1004
+ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
1005
+ _complete: false,
1006
+
1007
+ initialize: function(url, options) {
1008
+ this.transport = Ajax.getTransport();
1009
+ this.setOptions(options);
1010
+ this.request(url);
1011
+ },
1012
+
1013
+ request: function(url) {
1014
+ this.url = url;
1015
+ this.method = this.options.method;
1016
+ var params = Object.clone(this.options.parameters);
1017
+
1018
+ if (!['get', 'post'].include(this.method)) {
1019
+ // simulate other verbs over post
1020
+ params['_method'] = this.method;
1021
+ this.method = 'post';
1022
+ }
1023
+
1024
+ this.parameters = params;
1025
+
1026
+ if (params = Hash.toQueryString(params)) {
1027
+ // when GET, append parameters to URL
1028
+ if (this.method == 'get')
1029
+ this.url += (this.url.include('?') ? '&' : '?') + params;
1030
+ else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
1031
+ params += '&_=';
1032
+ }
1033
+
1034
+ try {
1035
+ if (this.options.onCreate) this.options.onCreate(this.transport);
1036
+ Ajax.Responders.dispatch('onCreate', this, this.transport);
1037
+
1038
+ this.transport.open(this.method.toUpperCase(), this.url,
1039
+ this.options.asynchronous);
1040
+
1041
+ if (this.options.asynchronous)
1042
+ setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
1043
+
1044
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
1045
+ this.setRequestHeaders();
1046
+
1047
+ this.body = this.method == 'post' ? (this.options.postBody || params) : null;
1048
+ this.transport.send(this.body);
1049
+
1050
+ /* Force Firefox to handle ready state 4 for synchronous requests */
1051
+ if (!this.options.asynchronous && this.transport.overrideMimeType)
1052
+ this.onStateChange();
1053
+
1054
+ }
1055
+ catch (e) {
1056
+ this.dispatchException(e);
1057
+ }
1058
+ },
1059
+
1060
+ onStateChange: function() {
1061
+ var readyState = this.transport.readyState;
1062
+ if (readyState > 1 && !((readyState == 4) && this._complete))
1063
+ this.respondToReadyState(this.transport.readyState);
1064
+ },
1065
+
1066
+ setRequestHeaders: function() {
1067
+ var headers = {
1068
+ 'X-Requested-With': 'XMLHttpRequest',
1069
+ 'X-Prototype-Version': Prototype.Version,
1070
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
1071
+ };
1072
+
1073
+ if (this.method == 'post') {
1074
+ headers['Content-type'] = this.options.contentType +
1075
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
1076
+
1077
+ /* Force "Connection: close" for older Mozilla browsers to work
1078
+ * around a bug where XMLHttpRequest sends an incorrect
1079
+ * Content-length header. See Mozilla Bugzilla #246651.
1080
+ */
1081
+ if (this.transport.overrideMimeType &&
1082
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
1083
+ headers['Connection'] = 'close';
1084
+ }
1085
+
1086
+ // user-defined headers
1087
+ if (typeof this.options.requestHeaders == 'object') {
1088
+ var extras = this.options.requestHeaders;
1089
+
1090
+ if (typeof extras.push == 'function')
1091
+ for (var i = 0, length = extras.length; i < length; i += 2)
1092
+ headers[extras[i]] = extras[i+1];
1093
+ else
1094
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
1095
+ }
1096
+
1097
+ for (var name in headers)
1098
+ this.transport.setRequestHeader(name, headers[name]);
1099
+ },
1100
+
1101
+ success: function() {
1102
+ return !this.transport.status
1103
+ || (this.transport.status >= 200 && this.transport.status < 300);
1104
+ },
1105
+
1106
+ respondToReadyState: function(readyState) {
1107
+ var state = Ajax.Request.Events[readyState];
1108
+ var transport = this.transport, json = this.evalJSON();
1109
+
1110
+ if (state == 'Complete') {
1111
+ try {
1112
+ this._complete = true;
1113
+ (this.options['on' + this.transport.status]
1114
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
1115
+ || Prototype.emptyFunction)(transport, json);
1116
+ } catch (e) {
1117
+ this.dispatchException(e);
1118
+ }
1119
+
1120
+ var contentType = this.getHeader('Content-type');
1121
+ if (contentType && contentType.strip().
1122
+ match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
1123
+ this.evalResponse();
1124
+ }
1125
+
1126
+ try {
1127
+ (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
1128
+ Ajax.Responders.dispatch('on' + state, this, transport, json);
1129
+ } catch (e) {
1130
+ this.dispatchException(e);
1131
+ }
1132
+
1133
+ if (state == 'Complete') {
1134
+ // avoid memory leak in MSIE: clean up
1135
+ this.transport.onreadystatechange = Prototype.emptyFunction;
1136
+ }
1137
+ },
1138
+
1139
+ getHeader: function(name) {
1140
+ try {
1141
+ return this.transport.getResponseHeader(name);
1142
+ } catch (e) { return null }
1143
+ },
1144
+
1145
+ evalJSON: function() {
1146
+ try {
1147
+ var json = this.getHeader('X-JSON');
1148
+ return json ? json.evalJSON() : null;
1149
+ } catch (e) { return null }
1150
+ },
1151
+
1152
+ evalResponse: function() {
1153
+ try {
1154
+ return eval((this.transport.responseText || '').unfilterJSON());
1155
+ } catch (e) {
1156
+ this.dispatchException(e);
1157
+ }
1158
+ },
1159
+
1160
+ dispatchException: function(exception) {
1161
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
1162
+ Ajax.Responders.dispatch('onException', this, exception);
1163
+ }
1164
+ });
1165
+
1166
+ Ajax.Updater = Class.create();
1167
+
1168
+ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
1169
+ initialize: function(container, url, options) {
1170
+ this.container = {
1171
+ success: (container.success || container),
1172
+ failure: (container.failure || (container.success ? null : container))
1173
+ }
1174
+
1175
+ this.transport = Ajax.getTransport();
1176
+ this.setOptions(options);
1177
+
1178
+ var onComplete = this.options.onComplete || Prototype.emptyFunction;
1179
+ this.options.onComplete = (function(transport, param) {
1180
+ this.updateContent();
1181
+ onComplete(transport, param);
1182
+ }).bind(this);
1183
+
1184
+ this.request(url);
1185
+ },
1186
+
1187
+ updateContent: function() {
1188
+ var receiver = this.container[this.success() ? 'success' : 'failure'];
1189
+ var response = this.transport.responseText;
1190
+
1191
+ if (!this.options.evalScripts) response = response.stripScripts();
1192
+
1193
+ if (receiver = $(receiver)) {
1194
+ if (this.options.insertion)
1195
+ new this.options.insertion(receiver, response);
1196
+ else
1197
+ receiver.update(response);
1198
+ }
1199
+
1200
+ if (this.success()) {
1201
+ if (this.onComplete)
1202
+ setTimeout(this.onComplete.bind(this), 10);
1203
+ }
1204
+ }
1205
+ });
1206
+
1207
+ Ajax.PeriodicalUpdater = Class.create();
1208
+ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
1209
+ initialize: function(container, url, options) {
1210
+ this.setOptions(options);
1211
+ this.onComplete = this.options.onComplete;
1212
+
1213
+ this.frequency = (this.options.frequency || 2);
1214
+ this.decay = (this.options.decay || 1);
1215
+
1216
+ this.updater = {};
1217
+ this.container = container;
1218
+ this.url = url;
1219
+
1220
+ this.start();
1221
+ },
1222
+
1223
+ start: function() {
1224
+ this.options.onComplete = this.updateComplete.bind(this);
1225
+ this.onTimerEvent();
1226
+ },
1227
+
1228
+ stop: function() {
1229
+ this.updater.options.onComplete = undefined;
1230
+ clearTimeout(this.timer);
1231
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
1232
+ },
1233
+
1234
+ updateComplete: function(request) {
1235
+ if (this.options.decay) {
1236
+ this.decay = (request.responseText == this.lastText ?
1237
+ this.decay * this.options.decay : 1);
1238
+
1239
+ this.lastText = request.responseText;
1240
+ }
1241
+ this.timer = setTimeout(this.onTimerEvent.bind(this),
1242
+ this.decay * this.frequency * 1000);
1243
+ },
1244
+
1245
+ onTimerEvent: function() {
1246
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
1247
+ }
1248
+ });
1249
+ function $(element) {
1250
+ if (arguments.length > 1) {
1251
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
1252
+ elements.push($(arguments[i]));
1253
+ return elements;
1254
+ }
1255
+ if (typeof element == 'string')
1256
+ element = document.getElementById(element);
1257
+ return Element.extend(element);
1258
+ }
1259
+
1260
+ if (Prototype.BrowserFeatures.XPath) {
1261
+ document._getElementsByXPath = function(expression, parentElement) {
1262
+ var results = [];
1263
+ var query = document.evaluate(expression, $(parentElement) || document,
1264
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
1265
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
1266
+ results.push(query.snapshotItem(i));
1267
+ return results;
1268
+ };
1269
+
1270
+ document.getElementsByClassName = function(className, parentElement) {
1271
+ var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
1272
+ return document._getElementsByXPath(q, parentElement);
1273
+ }
1274
+
1275
+ } else document.getElementsByClassName = function(className, parentElement) {
1276
+ var children = ($(parentElement) || document.body).getElementsByTagName('*');
1277
+ var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");
1278
+ for (var i = 0, length = children.length; i < length; i++) {
1279
+ child = children[i];
1280
+ var elementClassName = child.className;
1281
+ if (elementClassName.length == 0) continue;
1282
+ if (elementClassName == className || elementClassName.match(pattern))
1283
+ elements.push(Element.extend(child));
1284
+ }
1285
+ return elements;
1286
+ };
1287
+
1288
+ /*--------------------------------------------------------------------------*/
1289
+
1290
+ if (!window.Element) var Element = {};
1291
+
1292
+ Element.extend = function(element) {
1293
+ var F = Prototype.BrowserFeatures;
1294
+ if (!element || !element.tagName || element.nodeType == 3 ||
1295
+ element._extended || F.SpecificElementExtensions || element == window)
1296
+ return element;
1297
+
1298
+ var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
1299
+ T = Element.Methods.ByTag;
1300
+
1301
+ // extend methods for all tags (Safari doesn't need this)
1302
+ if (!F.ElementExtensions) {
1303
+ Object.extend(methods, Element.Methods),
1304
+ Object.extend(methods, Element.Methods.Simulated);
1305
+ }
1306
+
1307
+ // extend methods for specific tags
1308
+ if (T[tagName]) Object.extend(methods, T[tagName]);
1309
+
1310
+ for (var property in methods) {
1311
+ var value = methods[property];
1312
+ if (typeof value == 'function' && !(property in element))
1313
+ element[property] = cache.findOrStore(value);
1314
+ }
1315
+
1316
+ element._extended = Prototype.emptyFunction;
1317
+ return element;
1318
+ };
1319
+
1320
+ Element.extend.cache = {
1321
+ findOrStore: function(value) {
1322
+ return this[value] = this[value] || function() {
1323
+ return value.apply(null, [this].concat($A(arguments)));
1324
+ }
1325
+ }
1326
+ };
1327
+
1328
+ Element.Methods = {
1329
+ visible: function(element) {
1330
+ return $(element).style.display != 'none';
1331
+ },
1332
+
1333
+ toggle: function(element) {
1334
+ element = $(element);
1335
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
1336
+ return element;
1337
+ },
1338
+
1339
+ hide: function(element) {
1340
+ $(element).style.display = 'none';
1341
+ return element;
1342
+ },
1343
+
1344
+ show: function(element) {
1345
+ $(element).style.display = '';
1346
+ return element;
1347
+ },
1348
+
1349
+ remove: function(element) {
1350
+ element = $(element);
1351
+ element.parentNode.removeChild(element);
1352
+ return element;
1353
+ },
1354
+
1355
+ update: function(element, html) {
1356
+ html = typeof html == 'undefined' ? '' : html.toString();
1357
+ $(element).innerHTML = html.stripScripts();
1358
+ setTimeout(function() {html.evalScripts()}, 10);
1359
+ return element;
1360
+ },
1361
+
1362
+ replace: function(element, html) {
1363
+ element = $(element);
1364
+ html = typeof html == 'undefined' ? '' : html.toString();
1365
+ if (element.outerHTML) {
1366
+ element.outerHTML = html.stripScripts();
1367
+ } else {
1368
+ var range = element.ownerDocument.createRange();
1369
+ range.selectNodeContents(element);
1370
+ element.parentNode.replaceChild(
1371
+ range.createContextualFragment(html.stripScripts()), element);
1372
+ }
1373
+ setTimeout(function() {html.evalScripts()}, 10);
1374
+ return element;
1375
+ },
1376
+
1377
+ inspect: function(element) {
1378
+ element = $(element);
1379
+ var result = '<' + element.tagName.toLowerCase();
1380
+ $H({'id': 'id', 'className': 'class'}).each(function(pair) {
1381
+ var property = pair.first(), attribute = pair.last();
1382
+ var value = (element[property] || '').toString();
1383
+ if (value) result += ' ' + attribute + '=' + value.inspect(true);
1384
+ });
1385
+ return result + '>';
1386
+ },
1387
+
1388
+ recursivelyCollect: function(element, property) {
1389
+ element = $(element);
1390
+ var elements = [];
1391
+ while (element = element[property])
1392
+ if (element.nodeType == 1)
1393
+ elements.push(Element.extend(element));
1394
+ return elements;
1395
+ },
1396
+
1397
+ ancestors: function(element) {
1398
+ return $(element).recursivelyCollect('parentNode');
1399
+ },
1400
+
1401
+ descendants: function(element) {
1402
+ return $A($(element).getElementsByTagName('*')).each(Element.extend);
1403
+ },
1404
+
1405
+ firstDescendant: function(element) {
1406
+ element = $(element).firstChild;
1407
+ while (element && element.nodeType != 1) element = element.nextSibling;
1408
+ return $(element);
1409
+ },
1410
+
1411
+ immediateDescendants: function(element) {
1412
+ if (!(element = $(element).firstChild)) return [];
1413
+ while (element && element.nodeType != 1) element = element.nextSibling;
1414
+ if (element) return [element].concat($(element).nextSiblings());
1415
+ return [];
1416
+ },
1417
+
1418
+ previousSiblings: function(element) {
1419
+ return $(element).recursivelyCollect('previousSibling');
1420
+ },
1421
+
1422
+ nextSiblings: function(element) {
1423
+ return $(element).recursivelyCollect('nextSibling');
1424
+ },
1425
+
1426
+ siblings: function(element) {
1427
+ element = $(element);
1428
+ return element.previousSiblings().reverse().concat(element.nextSiblings());
1429
+ },
1430
+
1431
+ match: function(element, selector) {
1432
+ if (typeof selector == 'string')
1433
+ selector = new Selector(selector);
1434
+ return selector.match($(element));
1435
+ },
1436
+
1437
+ up: function(element, expression, index) {
1438
+ element = $(element);
1439
+ if (arguments.length == 1) return $(element.parentNode);
1440
+ var ancestors = element.ancestors();
1441
+ return expression ? Selector.findElement(ancestors, expression, index) :
1442
+ ancestors[index || 0];
1443
+ },
1444
+
1445
+ down: function(element, expression, index) {
1446
+ element = $(element);
1447
+ if (arguments.length == 1) return element.firstDescendant();
1448
+ var descendants = element.descendants();
1449
+ return expression ? Selector.findElement(descendants, expression, index) :
1450
+ descendants[index || 0];
1451
+ },
1452
+
1453
+ previous: function(element, expression, index) {
1454
+ element = $(element);
1455
+ if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
1456
+ var previousSiblings = element.previousSiblings();
1457
+ return expression ? Selector.findElement(previousSiblings, expression, index) :
1458
+ previousSiblings[index || 0];
1459
+ },
1460
+
1461
+ next: function(element, expression, index) {
1462
+ element = $(element);
1463
+ if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
1464
+ var nextSiblings = element.nextSiblings();
1465
+ return expression ? Selector.findElement(nextSiblings, expression, index) :
1466
+ nextSiblings[index || 0];
1467
+ },
1468
+
1469
+ getElementsBySelector: function() {
1470
+ var args = $A(arguments), element = $(args.shift());
1471
+ return Selector.findChildElements(element, args);
1472
+ },
1473
+
1474
+ getElementsByClassName: function(element, className) {
1475
+ return document.getElementsByClassName(className, element);
1476
+ },
1477
+
1478
+ readAttribute: function(element, name) {
1479
+ element = $(element);
1480
+ if (Prototype.Browser.IE) {
1481
+ if (!element.attributes) return null;
1482
+ var t = Element._attributeTranslations;
1483
+ if (t.values[name]) return t.values[name](element, name);
1484
+ if (t.names[name]) name = t.names[name];
1485
+ var attribute = element.attributes[name];
1486
+ return attribute ? attribute.nodeValue : null;
1487
+ }
1488
+ return element.getAttribute(name);
1489
+ },
1490
+
1491
+ getHeight: function(element) {
1492
+ return $(element).getDimensions().height;
1493
+ },
1494
+
1495
+ getWidth: function(element) {
1496
+ return $(element).getDimensions().width;
1497
+ },
1498
+
1499
+ classNames: function(element) {
1500
+ return new Element.ClassNames(element);
1501
+ },
1502
+
1503
+ hasClassName: function(element, className) {
1504
+ if (!(element = $(element))) return;
1505
+ var elementClassName = element.className;
1506
+ if (elementClassName.length == 0) return false;
1507
+ if (elementClassName == className ||
1508
+ elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
1509
+ return true;
1510
+ return false;
1511
+ },
1512
+
1513
+ addClassName: function(element, className) {
1514
+ if (!(element = $(element))) return;
1515
+ Element.classNames(element).add(className);
1516
+ return element;
1517
+ },
1518
+
1519
+ removeClassName: function(element, className) {
1520
+ if (!(element = $(element))) return;
1521
+ Element.classNames(element).remove(className);
1522
+ return element;
1523
+ },
1524
+
1525
+ toggleClassName: function(element, className) {
1526
+ if (!(element = $(element))) return;
1527
+ Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
1528
+ return element;
1529
+ },
1530
+
1531
+ observe: function() {
1532
+ Event.observe.apply(Event, arguments);
1533
+ return $A(arguments).first();
1534
+ },
1535
+
1536
+ stopObserving: function() {
1537
+ Event.stopObserving.apply(Event, arguments);
1538
+ return $A(arguments).first();
1539
+ },
1540
+
1541
+ // removes whitespace-only text node children
1542
+ cleanWhitespace: function(element) {
1543
+ element = $(element);
1544
+ var node = element.firstChild;
1545
+ while (node) {
1546
+ var nextNode = node.nextSibling;
1547
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
1548
+ element.removeChild(node);
1549
+ node = nextNode;
1550
+ }
1551
+ return element;
1552
+ },
1553
+
1554
+ empty: function(element) {
1555
+ return $(element).innerHTML.blank();
1556
+ },
1557
+
1558
+ descendantOf: function(element, ancestor) {
1559
+ element = $(element), ancestor = $(ancestor);
1560
+ while (element = element.parentNode)
1561
+ if (element == ancestor) return true;
1562
+ return false;
1563
+ },
1564
+
1565
+ scrollTo: function(element) {
1566
+ element = $(element);
1567
+ var pos = Position.cumulativeOffset(element);
1568
+ window.scrollTo(pos[0], pos[1]);
1569
+ return element;
1570
+ },
1571
+
1572
+ getStyle: function(element, style) {
1573
+ element = $(element);
1574
+ style = style == 'float' ? 'cssFloat' : style.camelize();
1575
+ var value = element.style[style];
1576
+ if (!value) {
1577
+ var css = document.defaultView.getComputedStyle(element, null);
1578
+ value = css ? css[style] : null;
1579
+ }
1580
+ if (style == 'opacity') return value ? parseFloat(value) : 1.0;
1581
+ return value == 'auto' ? null : value;
1582
+ },
1583
+
1584
+ getOpacity: function(element) {
1585
+ return $(element).getStyle('opacity');
1586
+ },
1587
+
1588
+ setStyle: function(element, styles, camelized) {
1589
+ element = $(element);
1590
+ var elementStyle = element.style;
1591
+
1592
+ for (var property in styles)
1593
+ if (property == 'opacity') element.setOpacity(styles[property])
1594
+ else
1595
+ elementStyle[(property == 'float' || property == 'cssFloat') ?
1596
+ (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
1597
+ (camelized ? property : property.camelize())] = styles[property];
1598
+
1599
+ return element;
1600
+ },
1601
+
1602
+ setOpacity: function(element, value) {
1603
+ element = $(element);
1604
+ element.style.opacity = (value == 1 || value === '') ? '' :
1605
+ (value < 0.00001) ? 0 : value;
1606
+ return element;
1607
+ },
1608
+
1609
+ getDimensions: function(element) {
1610
+ element = $(element);
1611
+ var display = $(element).getStyle('display');
1612
+ if (display != 'none' && display != null) // Safari bug
1613
+ return {width: element.offsetWidth, height: element.offsetHeight};
1614
+
1615
+ // All *Width and *Height properties give 0 on elements with display none,
1616
+ // so enable the element temporarily
1617
+ var els = element.style;
1618
+ var originalVisibility = els.visibility;
1619
+ var originalPosition = els.position;
1620
+ var originalDisplay = els.display;
1621
+ els.visibility = 'hidden';
1622
+ els.position = 'absolute';
1623
+ els.display = 'block';
1624
+ var originalWidth = element.clientWidth;
1625
+ var originalHeight = element.clientHeight;
1626
+ els.display = originalDisplay;
1627
+ els.position = originalPosition;
1628
+ els.visibility = originalVisibility;
1629
+ return {width: originalWidth, height: originalHeight};
1630
+ },
1631
+
1632
+ makePositioned: function(element) {
1633
+ element = $(element);
1634
+ var pos = Element.getStyle(element, 'position');
1635
+ if (pos == 'static' || !pos) {
1636
+ element._madePositioned = true;
1637
+ element.style.position = 'relative';
1638
+ // Opera returns the offset relative to the positioning context, when an
1639
+ // element is position relative but top and left have not been defined
1640
+ if (window.opera) {
1641
+ element.style.top = 0;
1642
+ element.style.left = 0;
1643
+ }
1644
+ }
1645
+ return element;
1646
+ },
1647
+
1648
+ undoPositioned: function(element) {
1649
+ element = $(element);
1650
+ if (element._madePositioned) {
1651
+ element._madePositioned = undefined;
1652
+ element.style.position =
1653
+ element.style.top =
1654
+ element.style.left =
1655
+ element.style.bottom =
1656
+ element.style.right = '';
1657
+ }
1658
+ return element;
1659
+ },
1660
+
1661
+ makeClipping: function(element) {
1662
+ element = $(element);
1663
+ if (element._overflow) return element;
1664
+ element._overflow = element.style.overflow || 'auto';
1665
+ if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
1666
+ element.style.overflow = 'hidden';
1667
+ return element;
1668
+ },
1669
+
1670
+ undoClipping: function(element) {
1671
+ element = $(element);
1672
+ if (!element._overflow) return element;
1673
+ element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
1674
+ element._overflow = null;
1675
+ return element;
1676
+ }
1677
+ };
1678
+
1679
+ Object.extend(Element.Methods, {
1680
+ childOf: Element.Methods.descendantOf,
1681
+ childElements: Element.Methods.immediateDescendants
1682
+ });
1683
+
1684
+ if (Prototype.Browser.Opera) {
1685
+ Element.Methods._getStyle = Element.Methods.getStyle;
1686
+ Element.Methods.getStyle = function(element, style) {
1687
+ switch(style) {
1688
+ case 'left':
1689
+ case 'top':
1690
+ case 'right':
1691
+ case 'bottom':
1692
+ if (Element._getStyle(element, 'position') == 'static') return null;
1693
+ default: return Element._getStyle(element, style);
1694
+ }
1695
+ };
1696
+ }
1697
+ else if (Prototype.Browser.IE) {
1698
+ Element.Methods.getStyle = function(element, style) {
1699
+ element = $(element);
1700
+ style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
1701
+ var value = element.style[style];
1702
+ if (!value && element.currentStyle) value = element.currentStyle[style];
1703
+
1704
+ if (style == 'opacity') {
1705
+ if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
1706
+ if (value[1]) return parseFloat(value[1]) / 100;
1707
+ return 1.0;
1708
+ }
1709
+
1710
+ if (value == 'auto') {
1711
+ if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
1712
+ return element['offset'+style.capitalize()] + 'px';
1713
+ return null;
1714
+ }
1715
+ return value;
1716
+ };
1717
+
1718
+ Element.Methods.setOpacity = function(element, value) {
1719
+ element = $(element);
1720
+ var filter = element.getStyle('filter'), style = element.style;
1721
+ if (value == 1 || value === '') {
1722
+ style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
1723
+ return element;
1724
+ } else if (value < 0.00001) value = 0;
1725
+ style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
1726
+ 'alpha(opacity=' + (value * 100) + ')';
1727
+ return element;
1728
+ };
1729
+
1730
+ // IE is missing .innerHTML support for TABLE-related elements
1731
+ Element.Methods.update = function(element, html) {
1732
+ element = $(element);
1733
+ html = typeof html == 'undefined' ? '' : html.toString();
1734
+ var tagName = element.tagName.toUpperCase();
1735
+ if (['THEAD','TBODY','TR','TD'].include(tagName)) {
1736
+ var div = document.createElement('div');
1737
+ switch (tagName) {
1738
+ case 'THEAD':
1739
+ case 'TBODY':
1740
+ div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
1741
+ depth = 2;
1742
+ break;
1743
+ case 'TR':
1744
+ div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
1745
+ depth = 3;
1746
+ break;
1747
+ case 'TD':
1748
+ div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
1749
+ depth = 4;
1750
+ }
1751
+ $A(element.childNodes).each(function(node) { element.removeChild(node) });
1752
+ depth.times(function() { div = div.firstChild });
1753
+ $A(div.childNodes).each(function(node) { element.appendChild(node) });
1754
+ } else {
1755
+ element.innerHTML = html.stripScripts();
1756
+ }
1757
+ setTimeout(function() { html.evalScripts() }, 10);
1758
+ return element;
1759
+ }
1760
+ }
1761
+ else if (Prototype.Browser.Gecko) {
1762
+ Element.Methods.setOpacity = function(element, value) {
1763
+ element = $(element);
1764
+ element.style.opacity = (value == 1) ? 0.999999 :
1765
+ (value === '') ? '' : (value < 0.00001) ? 0 : value;
1766
+ return element;
1767
+ };
1768
+ }
1769
+
1770
+ Element._attributeTranslations = {
1771
+ names: {
1772
+ colspan: "colSpan",
1773
+ rowspan: "rowSpan",
1774
+ valign: "vAlign",
1775
+ datetime: "dateTime",
1776
+ accesskey: "accessKey",
1777
+ tabindex: "tabIndex",
1778
+ enctype: "encType",
1779
+ maxlength: "maxLength",
1780
+ readonly: "readOnly",
1781
+ longdesc: "longDesc"
1782
+ },
1783
+ values: {
1784
+ _getAttr: function(element, attribute) {
1785
+ return element.getAttribute(attribute, 2);
1786
+ },
1787
+ _flag: function(element, attribute) {
1788
+ return $(element).hasAttribute(attribute) ? attribute : null;
1789
+ },
1790
+ style: function(element) {
1791
+ return element.style.cssText.toLowerCase();
1792
+ },
1793
+ title: function(element) {
1794
+ var node = element.getAttributeNode('title');
1795
+ return node.specified ? node.nodeValue : null;
1796
+ }
1797
+ }
1798
+ };
1799
+
1800
+ (function() {
1801
+ Object.extend(this, {
1802
+ href: this._getAttr,
1803
+ src: this._getAttr,
1804
+ type: this._getAttr,
1805
+ disabled: this._flag,
1806
+ checked: this._flag,
1807
+ readonly: this._flag,
1808
+ multiple: this._flag
1809
+ });
1810
+ }).call(Element._attributeTranslations.values);
1811
+
1812
+ Element.Methods.Simulated = {
1813
+ hasAttribute: function(element, attribute) {
1814
+ var t = Element._attributeTranslations, node;
1815
+ attribute = t.names[attribute] || attribute;
1816
+ node = $(element).getAttributeNode(attribute);
1817
+ return node && node.specified;
1818
+ }
1819
+ };
1820
+
1821
+ Element.Methods.ByTag = {};
1822
+
1823
+ Object.extend(Element, Element.Methods);
1824
+
1825
+ if (!Prototype.BrowserFeatures.ElementExtensions &&
1826
+ document.createElement('div').__proto__) {
1827
+ window.HTMLElement = {};
1828
+ window.HTMLElement.prototype = document.createElement('div').__proto__;
1829
+ Prototype.BrowserFeatures.ElementExtensions = true;
1830
+ }
1831
+
1832
+ Element.hasAttribute = function(element, attribute) {
1833
+ if (element.hasAttribute) return element.hasAttribute(attribute);
1834
+ return Element.Methods.Simulated.hasAttribute(element, attribute);
1835
+ };
1836
+
1837
+ Element.addMethods = function(methods) {
1838
+ var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
1839
+
1840
+ if (!methods) {
1841
+ Object.extend(Form, Form.Methods);
1842
+ Object.extend(Form.Element, Form.Element.Methods);
1843
+ Object.extend(Element.Methods.ByTag, {
1844
+ "FORM": Object.clone(Form.Methods),
1845
+ "INPUT": Object.clone(Form.Element.Methods),
1846
+ "SELECT": Object.clone(Form.Element.Methods),
1847
+ "TEXTAREA": Object.clone(Form.Element.Methods)
1848
+ });
1849
+ }
1850
+
1851
+ if (arguments.length == 2) {
1852
+ var tagName = methods;
1853
+ methods = arguments[1];
1854
+ }
1855
+
1856
+ if (!tagName) Object.extend(Element.Methods, methods || {});
1857
+ else {
1858
+ if (tagName.constructor == Array) tagName.each(extend);
1859
+ else extend(tagName);
1860
+ }
1861
+
1862
+ function extend(tagName) {
1863
+ tagName = tagName.toUpperCase();
1864
+ if (!Element.Methods.ByTag[tagName])
1865
+ Element.Methods.ByTag[tagName] = {};
1866
+ Object.extend(Element.Methods.ByTag[tagName], methods);
1867
+ }
1868
+
1869
+ function copy(methods, destination, onlyIfAbsent) {
1870
+ onlyIfAbsent = onlyIfAbsent || false;
1871
+ var cache = Element.extend.cache;
1872
+ for (var property in methods) {
1873
+ var value = methods[property];
1874
+ if (!onlyIfAbsent || !(property in destination))
1875
+ destination[property] = cache.findOrStore(value);
1876
+ }
1877
+ }
1878
+
1879
+ function findDOMClass(tagName) {
1880
+ var klass;
1881
+ var trans = {
1882
+ "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
1883
+ "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
1884
+ "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
1885
+ "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
1886
+ "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
1887
+ "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
1888
+ "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
1889
+ "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
1890
+ "FrameSet", "IFRAME": "IFrame"
1891
+ };
1892
+ if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
1893
+ if (window[klass]) return window[klass];
1894
+ klass = 'HTML' + tagName + 'Element';
1895
+ if (window[klass]) return window[klass];
1896
+ klass = 'HTML' + tagName.capitalize() + 'Element';
1897
+ if (window[klass]) return window[klass];
1898
+
1899
+ window[klass] = {};
1900
+ window[klass].prototype = document.createElement(tagName).__proto__;
1901
+ return window[klass];
1902
+ }
1903
+
1904
+ if (F.ElementExtensions) {
1905
+ copy(Element.Methods, HTMLElement.prototype);
1906
+ copy(Element.Methods.Simulated, HTMLElement.prototype, true);
1907
+ }
1908
+
1909
+ if (F.SpecificElementExtensions) {
1910
+ for (var tag in Element.Methods.ByTag) {
1911
+ var klass = findDOMClass(tag);
1912
+ if (typeof klass == "undefined") continue;
1913
+ copy(T[tag], klass.prototype);
1914
+ }
1915
+ }
1916
+
1917
+ Object.extend(Element, Element.Methods);
1918
+ delete Element.ByTag;
1919
+ };
1920
+
1921
+ var Toggle = { display: Element.toggle };
1922
+
1923
+ /*--------------------------------------------------------------------------*/
1924
+
1925
+ Abstract.Insertion = function(adjacency) {
1926
+ this.adjacency = adjacency;
1927
+ }
1928
+
1929
+ Abstract.Insertion.prototype = {
1930
+ initialize: function(element, content) {
1931
+ this.element = $(element);
1932
+ this.content = content.stripScripts();
1933
+
1934
+ if (this.adjacency && this.element.insertAdjacentHTML) {
1935
+ try {
1936
+ this.element.insertAdjacentHTML(this.adjacency, this.content);
1937
+ } catch (e) {
1938
+ var tagName = this.element.tagName.toUpperCase();
1939
+ if (['TBODY', 'TR'].include(tagName)) {
1940
+ this.insertContent(this.contentFromAnonymousTable());
1941
+ } else {
1942
+ throw e;
1943
+ }
1944
+ }
1945
+ } else {
1946
+ this.range = this.element.ownerDocument.createRange();
1947
+ if (this.initializeRange) this.initializeRange();
1948
+ this.insertContent([this.range.createContextualFragment(this.content)]);
1949
+ }
1950
+
1951
+ setTimeout(function() {content.evalScripts()}, 10);
1952
+ },
1953
+
1954
+ contentFromAnonymousTable: function() {
1955
+ var div = document.createElement('div');
1956
+ div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
1957
+ return $A(div.childNodes[0].childNodes[0].childNodes);
1958
+ }
1959
+ }
1960
+
1961
+ var Insertion = new Object();
1962
+
1963
+ Insertion.Before = Class.create();
1964
+ Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
1965
+ initializeRange: function() {
1966
+ this.range.setStartBefore(this.element);
1967
+ },
1968
+
1969
+ insertContent: function(fragments) {
1970
+ fragments.each((function(fragment) {
1971
+ this.element.parentNode.insertBefore(fragment, this.element);
1972
+ }).bind(this));
1973
+ }
1974
+ });
1975
+
1976
+ Insertion.Top = Class.create();
1977
+ Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
1978
+ initializeRange: function() {
1979
+ this.range.selectNodeContents(this.element);
1980
+ this.range.collapse(true);
1981
+ },
1982
+
1983
+ insertContent: function(fragments) {
1984
+ fragments.reverse(false).each((function(fragment) {
1985
+ this.element.insertBefore(fragment, this.element.firstChild);
1986
+ }).bind(this));
1987
+ }
1988
+ });
1989
+
1990
+ Insertion.Bottom = Class.create();
1991
+ Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
1992
+ initializeRange: function() {
1993
+ this.range.selectNodeContents(this.element);
1994
+ this.range.collapse(this.element);
1995
+ },
1996
+
1997
+ insertContent: function(fragments) {
1998
+ fragments.each((function(fragment) {
1999
+ this.element.appendChild(fragment);
2000
+ }).bind(this));
2001
+ }
2002
+ });
2003
+
2004
+ Insertion.After = Class.create();
2005
+ Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
2006
+ initializeRange: function() {
2007
+ this.range.setStartAfter(this.element);
2008
+ },
2009
+
2010
+ insertContent: function(fragments) {
2011
+ fragments.each((function(fragment) {
2012
+ this.element.parentNode.insertBefore(fragment,
2013
+ this.element.nextSibling);
2014
+ }).bind(this));
2015
+ }
2016
+ });
2017
+
2018
+ /*--------------------------------------------------------------------------*/
2019
+
2020
+ Element.ClassNames = Class.create();
2021
+ Element.ClassNames.prototype = {
2022
+ initialize: function(element) {
2023
+ this.element = $(element);
2024
+ },
2025
+
2026
+ _each: function(iterator) {
2027
+ this.element.className.split(/\s+/).select(function(name) {
2028
+ return name.length > 0;
2029
+ })._each(iterator);
2030
+ },
2031
+
2032
+ set: function(className) {
2033
+ this.element.className = className;
2034
+ },
2035
+
2036
+ add: function(classNameToAdd) {
2037
+ if (this.include(classNameToAdd)) return;
2038
+ this.set($A(this).concat(classNameToAdd).join(' '));
2039
+ },
2040
+
2041
+ remove: function(classNameToRemove) {
2042
+ if (!this.include(classNameToRemove)) return;
2043
+ this.set($A(this).without(classNameToRemove).join(' '));
2044
+ },
2045
+
2046
+ toString: function() {
2047
+ return $A(this).join(' ');
2048
+ }
2049
+ };
2050
+
2051
+ Object.extend(Element.ClassNames.prototype, Enumerable);
2052
+ /* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
2053
+ * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
2054
+ * license. Please see http://www.yui-ext.com/ for more information. */
2055
+
2056
+ var Selector = Class.create();
2057
+
2058
+ Selector.prototype = {
2059
+ initialize: function(expression) {
2060
+ this.expression = expression.strip();
2061
+ this.compileMatcher();
2062
+ },
2063
+
2064
+ compileMatcher: function() {
2065
+ // Selectors with namespaced attributes can't use the XPath version
2066
+ if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
2067
+ return this.compileXPathMatcher();
2068
+
2069
+ var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
2070
+ c = Selector.criteria, le, p, m;
2071
+
2072
+ if (Selector._cache[e]) {
2073
+ this.matcher = Selector._cache[e]; return;
2074
+ }
2075
+ this.matcher = ["this.matcher = function(root) {",
2076
+ "var r = root, h = Selector.handlers, c = false, n;"];
2077
+
2078
+ while (e && le != e && (/\S/).test(e)) {
2079
+ le = e;
2080
+ for (var i in ps) {
2081
+ p = ps[i];
2082
+ if (m = e.match(p)) {
2083
+ this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
2084
+ new Template(c[i]).evaluate(m));
2085
+ e = e.replace(m[0], '');
2086
+ break;
2087
+ }
2088
+ }
2089
+ }
2090
+
2091
+ this.matcher.push("return h.unique(n);\n}");
2092
+ eval(this.matcher.join('\n'));
2093
+ Selector._cache[this.expression] = this.matcher;
2094
+ },
2095
+
2096
+ compileXPathMatcher: function() {
2097
+ var e = this.expression, ps = Selector.patterns,
2098
+ x = Selector.xpath, le, m;
2099
+
2100
+ if (Selector._cache[e]) {
2101
+ this.xpath = Selector._cache[e]; return;
2102
+ }
2103
+
2104
+ this.matcher = ['.//*'];
2105
+ while (e && le != e && (/\S/).test(e)) {
2106
+ le = e;
2107
+ for (var i in ps) {
2108
+ if (m = e.match(ps[i])) {
2109
+ this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
2110
+ new Template(x[i]).evaluate(m));
2111
+ e = e.replace(m[0], '');
2112
+ break;
2113
+ }
2114
+ }
2115
+ }
2116
+
2117
+ this.xpath = this.matcher.join('');
2118
+ Selector._cache[this.expression] = this.xpath;
2119
+ },
2120
+
2121
+ findElements: function(root) {
2122
+ root = root || document;
2123
+ if (this.xpath) return document._getElementsByXPath(this.xpath, root);
2124
+ return this.matcher(root);
2125
+ },
2126
+
2127
+ match: function(element) {
2128
+ return this.findElements(document).include(element);
2129
+ },
2130
+
2131
+ toString: function() {
2132
+ return this.expression;
2133
+ },
2134
+
2135
+ inspect: function() {
2136
+ return "#<Selector:" + this.expression.inspect() + ">";
2137
+ }
2138
+ };
2139
+
2140
+ Object.extend(Selector, {
2141
+ _cache: {},
2142
+
2143
+ xpath: {
2144
+ descendant: "//*",
2145
+ child: "/*",
2146
+ adjacent: "/following-sibling::*[1]",
2147
+ laterSibling: '/following-sibling::*',
2148
+ tagName: function(m) {
2149
+ if (m[1] == '*') return '';
2150
+ return "[local-name()='" + m[1].toLowerCase() +
2151
+ "' or local-name()='" + m[1].toUpperCase() + "']";
2152
+ },
2153
+ className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
2154
+ id: "[@id='#{1}']",
2155
+ attrPresence: "[@#{1}]",
2156
+ attr: function(m) {
2157
+ m[3] = m[5] || m[6];
2158
+ return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
2159
+ },
2160
+ pseudo: function(m) {
2161
+ var h = Selector.xpath.pseudos[m[1]];
2162
+ if (!h) return '';
2163
+ if (typeof h === 'function') return h(m);
2164
+ return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
2165
+ },
2166
+ operators: {
2167
+ '=': "[@#{1}='#{3}']",
2168
+ '!=': "[@#{1}!='#{3}']",
2169
+ '^=': "[starts-with(@#{1}, '#{3}')]",
2170
+ '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
2171
+ '*=': "[contains(@#{1}, '#{3}')]",
2172
+ '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
2173
+ '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
2174
+ },
2175
+ pseudos: {
2176
+ 'first-child': '[not(preceding-sibling::*)]',
2177
+ 'last-child': '[not(following-sibling::*)]',
2178
+ 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
2179
+ 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
2180
+ 'checked': "[@checked]",
2181
+ 'disabled': "[@disabled]",
2182
+ 'enabled': "[not(@disabled)]",
2183
+ 'not': function(m) {
2184
+ var e = m[6], p = Selector.patterns,
2185
+ x = Selector.xpath, le, m, v;
2186
+
2187
+ var exclusion = [];
2188
+ while (e && le != e && (/\S/).test(e)) {
2189
+ le = e;
2190
+ for (var i in p) {
2191
+ if (m = e.match(p[i])) {
2192
+ v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m);
2193
+ exclusion.push("(" + v.substring(1, v.length - 1) + ")");
2194
+ e = e.replace(m[0], '');
2195
+ break;
2196
+ }
2197
+ }
2198
+ }
2199
+ return "[not(" + exclusion.join(" and ") + ")]";
2200
+ },
2201
+ 'nth-child': function(m) {
2202
+ return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
2203
+ },
2204
+ 'nth-last-child': function(m) {
2205
+ return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
2206
+ },
2207
+ 'nth-of-type': function(m) {
2208
+ return Selector.xpath.pseudos.nth("position() ", m);
2209
+ },
2210
+ 'nth-last-of-type': function(m) {
2211
+ return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
2212
+ },
2213
+ 'first-of-type': function(m) {
2214
+ m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
2215
+ },
2216
+ 'last-of-type': function(m) {
2217
+ m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
2218
+ },
2219
+ 'only-of-type': function(m) {
2220
+ var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
2221
+ },
2222
+ nth: function(fragment, m) {
2223
+ var mm, formula = m[6], predicate;
2224
+ if (formula == 'even') formula = '2n+0';
2225
+ if (formula == 'odd') formula = '2n+1';
2226
+ if (mm = formula.match(/^(\d+)$/)) // digit only
2227
+ return '[' + fragment + "= " + mm[1] + ']';
2228
+ if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
2229
+ if (mm[1] == "-") mm[1] = -1;
2230
+ var a = mm[1] ? Number(mm[1]) : 1;
2231
+ var b = mm[2] ? Number(mm[2]) : 0;
2232
+ predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
2233
+ "((#{fragment} - #{b}) div #{a} >= 0)]";
2234
+ return new Template(predicate).evaluate({
2235
+ fragment: fragment, a: a, b: b });
2236
+ }
2237
+ }
2238
+ }
2239
+ },
2240
+
2241
+ criteria: {
2242
+ tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
2243
+ className: 'n = h.className(n, r, "#{1}", c); c = false;',
2244
+ id: 'n = h.id(n, r, "#{1}", c); c = false;',
2245
+ attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
2246
+ attr: function(m) {
2247
+ m[3] = (m[5] || m[6]);
2248
+ return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
2249
+ },
2250
+ pseudo: function(m) {
2251
+ if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
2252
+ return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
2253
+ },
2254
+ descendant: 'c = "descendant";',
2255
+ child: 'c = "child";',
2256
+ adjacent: 'c = "adjacent";',
2257
+ laterSibling: 'c = "laterSibling";'
2258
+ },
2259
+
2260
+ patterns: {
2261
+ // combinators must be listed first
2262
+ // (and descendant needs to be last combinator)
2263
+ laterSibling: /^\s*~\s*/,
2264
+ child: /^\s*>\s*/,
2265
+ adjacent: /^\s*\+\s*/,
2266
+ descendant: /^\s/,
2267
+
2268
+ // selectors follow
2269
+ tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
2270
+ id: /^#([\w\-\*]+)(\b|$)/,
2271
+ className: /^\.([\w\-\*]+)(\b|$)/,
2272
+ pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/,
2273
+ attrPresence: /^\[([\w]+)\]/,
2274
+ attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
2275
+ },
2276
+
2277
+ handlers: {
2278
+ // UTILITY FUNCTIONS
2279
+ // joins two collections
2280
+ concat: function(a, b) {
2281
+ for (var i = 0, node; node = b[i]; i++)
2282
+ a.push(node);
2283
+ return a;
2284
+ },
2285
+
2286
+ // marks an array of nodes for counting
2287
+ mark: function(nodes) {
2288
+ for (var i = 0, node; node = nodes[i]; i++)
2289
+ node._counted = true;
2290
+ return nodes;
2291
+ },
2292
+
2293
+ unmark: function(nodes) {
2294
+ for (var i = 0, node; node = nodes[i]; i++)
2295
+ node._counted = undefined;
2296
+ return nodes;
2297
+ },
2298
+
2299
+ // mark each child node with its position (for nth calls)
2300
+ // "ofType" flag indicates whether we're indexing for nth-of-type
2301
+ // rather than nth-child
2302
+ index: function(parentNode, reverse, ofType) {
2303
+ parentNode._counted = true;
2304
+ if (reverse) {
2305
+ for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
2306
+ node = nodes[i];
2307
+ if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
2308
+ }
2309
+ } else {
2310
+ for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
2311
+ if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
2312
+ }
2313
+ },
2314
+
2315
+ // filters out duplicates and extends all nodes
2316
+ unique: function(nodes) {
2317
+ if (nodes.length == 0) return nodes;
2318
+ var results = [], n;
2319
+ for (var i = 0, l = nodes.length; i < l; i++)
2320
+ if (!(n = nodes[i])._counted) {
2321
+ n._counted = true;
2322
+ results.push(Element.extend(n));
2323
+ }
2324
+ return Selector.handlers.unmark(results);
2325
+ },
2326
+
2327
+ // COMBINATOR FUNCTIONS
2328
+ descendant: function(nodes) {
2329
+ var h = Selector.handlers;
2330
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
2331
+ h.concat(results, node.getElementsByTagName('*'));
2332
+ return results;
2333
+ },
2334
+
2335
+ child: function(nodes) {
2336
+ var h = Selector.handlers;
2337
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
2338
+ for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
2339
+ if (child.nodeType == 1 && child.tagName != '!') results.push(child);
2340
+ }
2341
+ return results;
2342
+ },
2343
+
2344
+ adjacent: function(nodes) {
2345
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
2346
+ var next = this.nextElementSibling(node);
2347
+ if (next) results.push(next);
2348
+ }
2349
+ return results;
2350
+ },
2351
+
2352
+ laterSibling: function(nodes) {
2353
+ var h = Selector.handlers;
2354
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
2355
+ h.concat(results, Element.nextSiblings(node));
2356
+ return results;
2357
+ },
2358
+
2359
+ nextElementSibling: function(node) {
2360
+ while (node = node.nextSibling)
2361
+ if (node.nodeType == 1) return node;
2362
+ return null;
2363
+ },
2364
+
2365
+ previousElementSibling: function(node) {
2366
+ while (node = node.previousSibling)
2367
+ if (node.nodeType == 1) return node;
2368
+ return null;
2369
+ },
2370
+
2371
+ // TOKEN FUNCTIONS
2372
+ tagName: function(nodes, root, tagName, combinator) {
2373
+ tagName = tagName.toUpperCase();
2374
+ var results = [], h = Selector.handlers;
2375
+ if (nodes) {
2376
+ if (combinator) {
2377
+ // fastlane for ordinary descendant combinators
2378
+ if (combinator == "descendant") {
2379
+ for (var i = 0, node; node = nodes[i]; i++)
2380
+ h.concat(results, node.getElementsByTagName(tagName));
2381
+ return results;
2382
+ } else nodes = this[combinator](nodes);
2383
+ if (tagName == "*") return nodes;
2384
+ }
2385
+ for (var i = 0, node; node = nodes[i]; i++)
2386
+ if (node.tagName.toUpperCase() == tagName) results.push(node);
2387
+ return results;
2388
+ } else return root.getElementsByTagName(tagName);
2389
+ },
2390
+
2391
+ id: function(nodes, root, id, combinator) {
2392
+ var targetNode = $(id), h = Selector.handlers;
2393
+ if (!nodes && root == document) return targetNode ? [targetNode] : [];
2394
+ if (nodes) {
2395
+ if (combinator) {
2396
+ if (combinator == 'child') {
2397
+ for (var i = 0, node; node = nodes[i]; i++)
2398
+ if (targetNode.parentNode == node) return [targetNode];
2399
+ } else if (combinator == 'descendant') {
2400
+ for (var i = 0, node; node = nodes[i]; i++)
2401
+ if (Element.descendantOf(targetNode, node)) return [targetNode];
2402
+ } else if (combinator == 'adjacent') {
2403
+ for (var i = 0, node; node = nodes[i]; i++)
2404
+ if (Selector.handlers.previousElementSibling(targetNode) == node)
2405
+ return [targetNode];
2406
+ } else nodes = h[combinator](nodes);
2407
+ }
2408
+ for (var i = 0, node; node = nodes[i]; i++)
2409
+ if (node == targetNode) return [targetNode];
2410
+ return [];
2411
+ }
2412
+ return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
2413
+ },
2414
+
2415
+ className: function(nodes, root, className, combinator) {
2416
+ if (nodes && combinator) nodes = this[combinator](nodes);
2417
+ return Selector.handlers.byClassName(nodes, root, className);
2418
+ },
2419
+
2420
+ byClassName: function(nodes, root, className) {
2421
+ if (!nodes) nodes = Selector.handlers.descendant([root]);
2422
+ var needle = ' ' + className + ' ';
2423
+ for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
2424
+ nodeClassName = node.className;
2425
+ if (nodeClassName.length == 0) continue;
2426
+ if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
2427
+ results.push(node);
2428
+ }
2429
+ return results;
2430
+ },
2431
+
2432
+ attrPresence: function(nodes, root, attr) {
2433
+ var results = [];
2434
+ for (var i = 0, node; node = nodes[i]; i++)
2435
+ if (Element.hasAttribute(node, attr)) results.push(node);
2436
+ return results;
2437
+ },
2438
+
2439
+ attr: function(nodes, root, attr, value, operator) {
2440
+ if (!nodes) nodes = root.getElementsByTagName("*");
2441
+ var handler = Selector.operators[operator], results = [];
2442
+ for (var i = 0, node; node = nodes[i]; i++) {
2443
+ var nodeValue = Element.readAttribute(node, attr);
2444
+ if (nodeValue === null) continue;
2445
+ if (handler(nodeValue, value)) results.push(node);
2446
+ }
2447
+ return results;
2448
+ },
2449
+
2450
+ pseudo: function(nodes, name, value, root, combinator) {
2451
+ if (nodes && combinator) nodes = this[combinator](nodes);
2452
+ if (!nodes) nodes = root.getElementsByTagName("*");
2453
+ return Selector.pseudos[name](nodes, value, root);
2454
+ }
2455
+ },
2456
+
2457
+ pseudos: {
2458
+ 'first-child': function(nodes, value, root) {
2459
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
2460
+ if (Selector.handlers.previousElementSibling(node)) continue;
2461
+ results.push(node);
2462
+ }
2463
+ return results;
2464
+ },
2465
+ 'last-child': function(nodes, value, root) {
2466
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
2467
+ if (Selector.handlers.nextElementSibling(node)) continue;
2468
+ results.push(node);
2469
+ }
2470
+ return results;
2471
+ },
2472
+ 'only-child': function(nodes, value, root) {
2473
+ var h = Selector.handlers;
2474
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
2475
+ if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
2476
+ results.push(node);
2477
+ return results;
2478
+ },
2479
+ 'nth-child': function(nodes, formula, root) {
2480
+ return Selector.pseudos.nth(nodes, formula, root);
2481
+ },
2482
+ 'nth-last-child': function(nodes, formula, root) {
2483
+ return Selector.pseudos.nth(nodes, formula, root, true);
2484
+ },
2485
+ 'nth-of-type': function(nodes, formula, root) {
2486
+ return Selector.pseudos.nth(nodes, formula, root, false, true);
2487
+ },
2488
+ 'nth-last-of-type': function(nodes, formula, root) {
2489
+ return Selector.pseudos.nth(nodes, formula, root, true, true);
2490
+ },
2491
+ 'first-of-type': function(nodes, formula, root) {
2492
+ return Selector.pseudos.nth(nodes, "1", root, false, true);
2493
+ },
2494
+ 'last-of-type': function(nodes, formula, root) {
2495
+ return Selector.pseudos.nth(nodes, "1", root, true, true);
2496
+ },
2497
+ 'only-of-type': function(nodes, formula, root) {
2498
+ var p = Selector.pseudos;
2499
+ return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
2500
+ },
2501
+
2502
+ // handles the an+b logic
2503
+ getIndices: function(a, b, total) {
2504
+ if (a == 0) return b > 0 ? [b] : [];
2505
+ return $R(1, total).inject([], function(memo, i) {
2506
+ if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
2507
+ return memo;
2508
+ });
2509
+ },
2510
+
2511
+ // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
2512
+ nth: function(nodes, formula, root, reverse, ofType) {
2513
+ if (nodes.length == 0) return [];
2514
+ if (formula == 'even') formula = '2n+0';
2515
+ if (formula == 'odd') formula = '2n+1';
2516
+ var h = Selector.handlers, results = [], indexed = [], m;
2517
+ h.mark(nodes);
2518
+ for (var i = 0, node; node = nodes[i]; i++) {
2519
+ if (!node.parentNode._counted) {
2520
+ h.index(node.parentNode, reverse, ofType);
2521
+ indexed.push(node.parentNode);
2522
+ }
2523
+ }
2524
+ if (formula.match(/^\d+$/)) { // just a number
2525
+ formula = Number(formula);
2526
+ for (var i = 0, node; node = nodes[i]; i++)
2527
+ if (node.nodeIndex == formula) results.push(node);
2528
+ } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
2529
+ if (m[1] == "-") m[1] = -1;
2530
+ var a = m[1] ? Number(m[1]) : 1;
2531
+ var b = m[2] ? Number(m[2]) : 0;
2532
+ var indices = Selector.pseudos.getIndices(a, b, nodes.length);
2533
+ for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
2534
+ for (var j = 0; j < l; j++)
2535
+ if (node.nodeIndex == indices[j]) results.push(node);
2536
+ }
2537
+ }
2538
+ h.unmark(nodes);
2539
+ h.unmark(indexed);
2540
+ return results;
2541
+ },
2542
+
2543
+ 'empty': function(nodes, value, root) {
2544
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
2545
+ // IE treats comments as element nodes
2546
+ if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
2547
+ results.push(node);
2548
+ }
2549
+ return results;
2550
+ },
2551
+
2552
+ 'not': function(nodes, selector, root) {
2553
+ var h = Selector.handlers, selectorType, m;
2554
+ var exclusions = new Selector(selector).findElements(root);
2555
+ h.mark(exclusions);
2556
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
2557
+ if (!node._counted) results.push(node);
2558
+ h.unmark(exclusions);
2559
+ return results;
2560
+ },
2561
+
2562
+ 'enabled': function(nodes, value, root) {
2563
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
2564
+ if (!node.disabled) results.push(node);
2565
+ return results;
2566
+ },
2567
+
2568
+ 'disabled': function(nodes, value, root) {
2569
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
2570
+ if (node.disabled) results.push(node);
2571
+ return results;
2572
+ },
2573
+
2574
+ 'checked': function(nodes, value, root) {
2575
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
2576
+ if (node.checked) results.push(node);
2577
+ return results;
2578
+ }
2579
+ },
2580
+
2581
+ operators: {
2582
+ '=': function(nv, v) { return nv == v; },
2583
+ '!=': function(nv, v) { return nv != v; },
2584
+ '^=': function(nv, v) { return nv.startsWith(v); },
2585
+ '$=': function(nv, v) { return nv.endsWith(v); },
2586
+ '*=': function(nv, v) { return nv.include(v); },
2587
+ '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
2588
+ '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
2589
+ },
2590
+
2591
+ matchElements: function(elements, expression) {
2592
+ var matches = new Selector(expression).findElements(), h = Selector.handlers;
2593
+ h.mark(matches);
2594
+ for (var i = 0, results = [], element; element = elements[i]; i++)
2595
+ if (element._counted) results.push(element);
2596
+ h.unmark(matches);
2597
+ return results;
2598
+ },
2599
+
2600
+ findElement: function(elements, expression, index) {
2601
+ if (typeof expression == 'number') {
2602
+ index = expression; expression = false;
2603
+ }
2604
+ return Selector.matchElements(elements, expression || '*')[index || 0];
2605
+ },
2606
+
2607
+ findChildElements: function(element, expressions) {
2608
+ var exprs = expressions.join(','), expressions = [];
2609
+ exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
2610
+ expressions.push(m[1].strip());
2611
+ });
2612
+ var results = [], h = Selector.handlers;
2613
+ for (var i = 0, l = expressions.length, selector; i < l; i++) {
2614
+ selector = new Selector(expressions[i].strip());
2615
+ h.concat(results, selector.findElements(element));
2616
+ }
2617
+ return (l > 1) ? h.unique(results) : results;
2618
+ }
2619
+ });
2620
+
2621
+ function $$() {
2622
+ return Selector.findChildElements(document, $A(arguments));
2623
+ }
2624
+ var Form = {
2625
+ reset: function(form) {
2626
+ $(form).reset();
2627
+ return form;
2628
+ },
2629
+
2630
+ serializeElements: function(elements, getHash) {
2631
+ var data = elements.inject({}, function(result, element) {
2632
+ if (!element.disabled && element.name) {
2633
+ var key = element.name, value = $(element).getValue();
2634
+ if (value != null) {
2635
+ if (key in result) {
2636
+ if (result[key].constructor != Array) result[key] = [result[key]];
2637
+ result[key].push(value);
2638
+ }
2639
+ else result[key] = value;
2640
+ }
2641
+ }
2642
+ return result;
2643
+ });
2644
+
2645
+ return getHash ? data : Hash.toQueryString(data);
2646
+ }
2647
+ };
2648
+
2649
+ Form.Methods = {
2650
+ serialize: function(form, getHash) {
2651
+ return Form.serializeElements(Form.getElements(form), getHash);
2652
+ },
2653
+
2654
+ getElements: function(form) {
2655
+ return $A($(form).getElementsByTagName('*')).inject([],
2656
+ function(elements, child) {
2657
+ if (Form.Element.Serializers[child.tagName.toLowerCase()])
2658
+ elements.push(Element.extend(child));
2659
+ return elements;
2660
+ }
2661
+ );
2662
+ },
2663
+
2664
+ getInputs: function(form, typeName, name) {
2665
+ form = $(form);
2666
+ var inputs = form.getElementsByTagName('input');
2667
+
2668
+ if (!typeName && !name) return $A(inputs).map(Element.extend);
2669
+
2670
+ for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
2671
+ var input = inputs[i];
2672
+ if ((typeName && input.type != typeName) || (name && input.name != name))
2673
+ continue;
2674
+ matchingInputs.push(Element.extend(input));
2675
+ }
2676
+
2677
+ return matchingInputs;
2678
+ },
2679
+
2680
+ disable: function(form) {
2681
+ form = $(form);
2682
+ Form.getElements(form).invoke('disable');
2683
+ return form;
2684
+ },
2685
+
2686
+ enable: function(form) {
2687
+ form = $(form);
2688
+ Form.getElements(form).invoke('enable');
2689
+ return form;
2690
+ },
2691
+
2692
+ findFirstElement: function(form) {
2693
+ return $(form).getElements().find(function(element) {
2694
+ return element.type != 'hidden' && !element.disabled &&
2695
+ ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
2696
+ });
2697
+ },
2698
+
2699
+ focusFirstElement: function(form) {
2700
+ form = $(form);
2701
+ form.findFirstElement().activate();
2702
+ return form;
2703
+ },
2704
+
2705
+ request: function(form, options) {
2706
+ form = $(form), options = Object.clone(options || {});
2707
+
2708
+ var params = options.parameters;
2709
+ options.parameters = form.serialize(true);
2710
+
2711
+ if (params) {
2712
+ if (typeof params == 'string') params = params.toQueryParams();
2713
+ Object.extend(options.parameters, params);
2714
+ }
2715
+
2716
+ if (form.hasAttribute('method') && !options.method)
2717
+ options.method = form.method;
2718
+
2719
+ return new Ajax.Request(form.readAttribute('action'), options);
2720
+ }
2721
+ }
2722
+
2723
+ /*--------------------------------------------------------------------------*/
2724
+
2725
+ Form.Element = {
2726
+ focus: function(element) {
2727
+ $(element).focus();
2728
+ return element;
2729
+ },
2730
+
2731
+ select: function(element) {
2732
+ $(element).select();
2733
+ return element;
2734
+ }
2735
+ }
2736
+
2737
+ Form.Element.Methods = {
2738
+ serialize: function(element) {
2739
+ element = $(element);
2740
+ if (!element.disabled && element.name) {
2741
+ var value = element.getValue();
2742
+ if (value != undefined) {
2743
+ var pair = {};
2744
+ pair[element.name] = value;
2745
+ return Hash.toQueryString(pair);
2746
+ }
2747
+ }
2748
+ return '';
2749
+ },
2750
+
2751
+ getValue: function(element) {
2752
+ element = $(element);
2753
+ var method = element.tagName.toLowerCase();
2754
+ return Form.Element.Serializers[method](element);
2755
+ },
2756
+
2757
+ clear: function(element) {
2758
+ $(element).value = '';
2759
+ return element;
2760
+ },
2761
+
2762
+ present: function(element) {
2763
+ return $(element).value != '';
2764
+ },
2765
+
2766
+ activate: function(element) {
2767
+ element = $(element);
2768
+ try {
2769
+ element.focus();
2770
+ if (element.select && (element.tagName.toLowerCase() != 'input' ||
2771
+ !['button', 'reset', 'submit'].include(element.type)))
2772
+ element.select();
2773
+ } catch (e) {}
2774
+ return element;
2775
+ },
2776
+
2777
+ disable: function(element) {
2778
+ element = $(element);
2779
+ element.blur();
2780
+ element.disabled = true;
2781
+ return element;
2782
+ },
2783
+
2784
+ enable: function(element) {
2785
+ element = $(element);
2786
+ element.disabled = false;
2787
+ return element;
2788
+ }
2789
+ }
2790
+
2791
+ /*--------------------------------------------------------------------------*/
2792
+
2793
+ var Field = Form.Element;
2794
+ var $F = Form.Element.Methods.getValue;
2795
+
2796
+ /*--------------------------------------------------------------------------*/
2797
+
2798
+ Form.Element.Serializers = {
2799
+ input: function(element) {
2800
+ switch (element.type.toLowerCase()) {
2801
+ case 'checkbox':
2802
+ case 'radio':
2803
+ return Form.Element.Serializers.inputSelector(element);
2804
+ default:
2805
+ return Form.Element.Serializers.textarea(element);
2806
+ }
2807
+ },
2808
+
2809
+ inputSelector: function(element) {
2810
+ return element.checked ? element.value : null;
2811
+ },
2812
+
2813
+ textarea: function(element) {
2814
+ return element.value;
2815
+ },
2816
+
2817
+ select: function(element) {
2818
+ return this[element.type == 'select-one' ?
2819
+ 'selectOne' : 'selectMany'](element);
2820
+ },
2821
+
2822
+ selectOne: function(element) {
2823
+ var index = element.selectedIndex;
2824
+ return index >= 0 ? this.optionValue(element.options[index]) : null;
2825
+ },
2826
+
2827
+ selectMany: function(element) {
2828
+ var values, length = element.length;
2829
+ if (!length) return null;
2830
+
2831
+ for (var i = 0, values = []; i < length; i++) {
2832
+ var opt = element.options[i];
2833
+ if (opt.selected) values.push(this.optionValue(opt));
2834
+ }
2835
+ return values;
2836
+ },
2837
+
2838
+ optionValue: function(opt) {
2839
+ // extend element because hasAttribute may not be native
2840
+ return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
2841
+ }
2842
+ }
2843
+
2844
+ /*--------------------------------------------------------------------------*/
2845
+
2846
+ Abstract.TimedObserver = function() {}
2847
+ Abstract.TimedObserver.prototype = {
2848
+ initialize: function(element, frequency, callback) {
2849
+ this.frequency = frequency;
2850
+ this.element = $(element);
2851
+ this.callback = callback;
2852
+
2853
+ this.lastValue = this.getValue();
2854
+ this.registerCallback();
2855
+ },
2856
+
2857
+ registerCallback: function() {
2858
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
2859
+ },
2860
+
2861
+ onTimerEvent: function() {
2862
+ var value = this.getValue();
2863
+ var changed = ('string' == typeof this.lastValue && 'string' == typeof value
2864
+ ? this.lastValue != value : String(this.lastValue) != String(value));
2865
+ if (changed) {
2866
+ this.callback(this.element, value);
2867
+ this.lastValue = value;
2868
+ }
2869
+ }
2870
+ }
2871
+
2872
+ Form.Element.Observer = Class.create();
2873
+ Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
2874
+ getValue: function() {
2875
+ return Form.Element.getValue(this.element);
2876
+ }
2877
+ });
2878
+
2879
+ Form.Observer = Class.create();
2880
+ Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
2881
+ getValue: function() {
2882
+ return Form.serialize(this.element);
2883
+ }
2884
+ });
2885
+
2886
+ /*--------------------------------------------------------------------------*/
2887
+
2888
+ Abstract.EventObserver = function() {}
2889
+ Abstract.EventObserver.prototype = {
2890
+ initialize: function(element, callback) {
2891
+ this.element = $(element);
2892
+ this.callback = callback;
2893
+
2894
+ this.lastValue = this.getValue();
2895
+ if (this.element.tagName.toLowerCase() == 'form')
2896
+ this.registerFormCallbacks();
2897
+ else
2898
+ this.registerCallback(this.element);
2899
+ },
2900
+
2901
+ onElementEvent: function() {
2902
+ var value = this.getValue();
2903
+ if (this.lastValue != value) {
2904
+ this.callback(this.element, value);
2905
+ this.lastValue = value;
2906
+ }
2907
+ },
2908
+
2909
+ registerFormCallbacks: function() {
2910
+ Form.getElements(this.element).each(this.registerCallback.bind(this));
2911
+ },
2912
+
2913
+ registerCallback: function(element) {
2914
+ if (element.type) {
2915
+ switch (element.type.toLowerCase()) {
2916
+ case 'checkbox':
2917
+ case 'radio':
2918
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
2919
+ break;
2920
+ default:
2921
+ Event.observe(element, 'change', this.onElementEvent.bind(this));
2922
+ break;
2923
+ }
2924
+ }
2925
+ }
2926
+ }
2927
+
2928
+ Form.Element.EventObserver = Class.create();
2929
+ Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
2930
+ getValue: function() {
2931
+ return Form.Element.getValue(this.element);
2932
+ }
2933
+ });
2934
+
2935
+ Form.EventObserver = Class.create();
2936
+ Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
2937
+ getValue: function() {
2938
+ return Form.serialize(this.element);
2939
+ }
2940
+ });
2941
+ if (!window.Event) {
2942
+ var Event = new Object();
2943
+ }
2944
+
2945
+ Object.extend(Event, {
2946
+ KEY_BACKSPACE: 8,
2947
+ KEY_TAB: 9,
2948
+ KEY_RETURN: 13,
2949
+ KEY_ESC: 27,
2950
+ KEY_LEFT: 37,
2951
+ KEY_UP: 38,
2952
+ KEY_RIGHT: 39,
2953
+ KEY_DOWN: 40,
2954
+ KEY_DELETE: 46,
2955
+ KEY_HOME: 36,
2956
+ KEY_END: 35,
2957
+ KEY_PAGEUP: 33,
2958
+ KEY_PAGEDOWN: 34,
2959
+
2960
+ element: function(event) {
2961
+ return $(event.target || event.srcElement);
2962
+ },
2963
+
2964
+ isLeftClick: function(event) {
2965
+ return (((event.which) && (event.which == 1)) ||
2966
+ ((event.button) && (event.button == 1)));
2967
+ },
2968
+
2969
+ pointerX: function(event) {
2970
+ return event.pageX || (event.clientX +
2971
+ (document.documentElement.scrollLeft || document.body.scrollLeft));
2972
+ },
2973
+
2974
+ pointerY: function(event) {
2975
+ return event.pageY || (event.clientY +
2976
+ (document.documentElement.scrollTop || document.body.scrollTop));
2977
+ },
2978
+
2979
+ stop: function(event) {
2980
+ if (event.preventDefault) {
2981
+ event.preventDefault();
2982
+ event.stopPropagation();
2983
+ } else {
2984
+ event.returnValue = false;
2985
+ event.cancelBubble = true;
2986
+ }
2987
+ },
2988
+
2989
+ // find the first node with the given tagName, starting from the
2990
+ // node the event was triggered on; traverses the DOM upwards
2991
+ findElement: function(event, tagName) {
2992
+ var element = Event.element(event);
2993
+ while (element.parentNode && (!element.tagName ||
2994
+ (element.tagName.toUpperCase() != tagName.toUpperCase())))
2995
+ element = element.parentNode;
2996
+ return element;
2997
+ },
2998
+
2999
+ observers: false,
3000
+
3001
+ _observeAndCache: function(element, name, observer, useCapture) {
3002
+ if (!this.observers) this.observers = [];
3003
+ if (element.addEventListener) {
3004
+ this.observers.push([element, name, observer, useCapture]);
3005
+ element.addEventListener(name, observer, useCapture);
3006
+ } else if (element.attachEvent) {
3007
+ this.observers.push([element, name, observer, useCapture]);
3008
+ element.attachEvent('on' + name, observer);
3009
+ }
3010
+ },
3011
+
3012
+ unloadCache: function() {
3013
+ if (!Event.observers) return;
3014
+ for (var i = 0, length = Event.observers.length; i < length; i++) {
3015
+ Event.stopObserving.apply(this, Event.observers[i]);
3016
+ Event.observers[i][0] = null;
3017
+ }
3018
+ Event.observers = false;
3019
+ },
3020
+
3021
+ observe: function(element, name, observer, useCapture) {
3022
+ element = $(element);
3023
+ useCapture = useCapture || false;
3024
+
3025
+ if (name == 'keypress' &&
3026
+ (Prototype.Browser.WebKit || element.attachEvent))
3027
+ name = 'keydown';
3028
+
3029
+ Event._observeAndCache(element, name, observer, useCapture);
3030
+ },
3031
+
3032
+ stopObserving: function(element, name, observer, useCapture) {
3033
+ element = $(element);
3034
+ useCapture = useCapture || false;
3035
+
3036
+ if (name == 'keypress' &&
3037
+ (Prototype.Browser.WebKit || element.attachEvent))
3038
+ name = 'keydown';
3039
+
3040
+ if (element.removeEventListener) {
3041
+ element.removeEventListener(name, observer, useCapture);
3042
+ } else if (element.detachEvent) {
3043
+ try {
3044
+ element.detachEvent('on' + name, observer);
3045
+ } catch (e) {}
3046
+ }
3047
+ }
3048
+ });
3049
+
3050
+ /* prevent memory leaks in IE */
3051
+ if (Prototype.Browser.IE)
3052
+ Event.observe(window, 'unload', Event.unloadCache, false);
3053
+ var Position = {
3054
+ // set to true if needed, warning: firefox performance problems
3055
+ // NOT neeeded for page scrolling, only if draggable contained in
3056
+ // scrollable elements
3057
+ includeScrollOffsets: false,
3058
+
3059
+ // must be called before calling withinIncludingScrolloffset, every time the
3060
+ // page is scrolled
3061
+ prepare: function() {
3062
+ this.deltaX = window.pageXOffset
3063
+ || document.documentElement.scrollLeft
3064
+ || document.body.scrollLeft
3065
+ || 0;
3066
+ this.deltaY = window.pageYOffset
3067
+ || document.documentElement.scrollTop
3068
+ || document.body.scrollTop
3069
+ || 0;
3070
+ },
3071
+
3072
+ realOffset: function(element) {
3073
+ var valueT = 0, valueL = 0;
3074
+ do {
3075
+ valueT += element.scrollTop || 0;
3076
+ valueL += element.scrollLeft || 0;
3077
+ element = element.parentNode;
3078
+ } while (element);
3079
+ return [valueL, valueT];
3080
+ },
3081
+
3082
+ cumulativeOffset: function(element) {
3083
+ var valueT = 0, valueL = 0;
3084
+ do {
3085
+ valueT += element.offsetTop || 0;
3086
+ valueL += element.offsetLeft || 0;
3087
+ element = element.offsetParent;
3088
+ } while (element);
3089
+ return [valueL, valueT];
3090
+ },
3091
+
3092
+ positionedOffset: function(element) {
3093
+ var valueT = 0, valueL = 0;
3094
+ do {
3095
+ valueT += element.offsetTop || 0;
3096
+ valueL += element.offsetLeft || 0;
3097
+ element = element.offsetParent;
3098
+ if (element) {
3099
+ if(element.tagName=='BODY') break;
3100
+ var p = Element.getStyle(element, 'position');
3101
+ if (p == 'relative' || p == 'absolute') break;
3102
+ }
3103
+ } while (element);
3104
+ return [valueL, valueT];
3105
+ },
3106
+
3107
+ offsetParent: function(element) {
3108
+ if (element.offsetParent) return element.offsetParent;
3109
+ if (element == document.body) return element;
3110
+
3111
+ while ((element = element.parentNode) && element != document.body)
3112
+ if (Element.getStyle(element, 'position') != 'static')
3113
+ return element;
3114
+
3115
+ return document.body;
3116
+ },
3117
+
3118
+ // caches x/y coordinate pair to use with overlap
3119
+ within: function(element, x, y) {
3120
+ if (this.includeScrollOffsets)
3121
+ return this.withinIncludingScrolloffsets(element, x, y);
3122
+ this.xcomp = x;
3123
+ this.ycomp = y;
3124
+ this.offset = this.cumulativeOffset(element);
3125
+
3126
+ return (y >= this.offset[1] &&
3127
+ y < this.offset[1] + element.offsetHeight &&
3128
+ x >= this.offset[0] &&
3129
+ x < this.offset[0] + element.offsetWidth);
3130
+ },
3131
+
3132
+ withinIncludingScrolloffsets: function(element, x, y) {
3133
+ var offsetcache = this.realOffset(element);
3134
+
3135
+ this.xcomp = x + offsetcache[0] - this.deltaX;
3136
+ this.ycomp = y + offsetcache[1] - this.deltaY;
3137
+ this.offset = this.cumulativeOffset(element);
3138
+
3139
+ return (this.ycomp >= this.offset[1] &&
3140
+ this.ycomp < this.offset[1] + element.offsetHeight &&
3141
+ this.xcomp >= this.offset[0] &&
3142
+ this.xcomp < this.offset[0] + element.offsetWidth);
3143
+ },
3144
+
3145
+ // within must be called directly before
3146
+ overlap: function(mode, element) {
3147
+ if (!mode) return 0;
3148
+ if (mode == 'vertical')
3149
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
3150
+ element.offsetHeight;
3151
+ if (mode == 'horizontal')
3152
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
3153
+ element.offsetWidth;
3154
+ },
3155
+
3156
+ page: function(forElement) {
3157
+ var valueT = 0, valueL = 0;
3158
+
3159
+ var element = forElement;
3160
+ do {
3161
+ valueT += element.offsetTop || 0;
3162
+ valueL += element.offsetLeft || 0;
3163
+
3164
+ // Safari fix
3165
+ if (element.offsetParent == document.body)
3166
+ if (Element.getStyle(element,'position')=='absolute') break;
3167
+
3168
+ } while (element = element.offsetParent);
3169
+
3170
+ element = forElement;
3171
+ do {
3172
+ if (!window.opera || element.tagName=='BODY') {
3173
+ valueT -= element.scrollTop || 0;
3174
+ valueL -= element.scrollLeft || 0;
3175
+ }
3176
+ } while (element = element.parentNode);
3177
+
3178
+ return [valueL, valueT];
3179
+ },
3180
+
3181
+ clone: function(source, target) {
3182
+ var options = Object.extend({
3183
+ setLeft: true,
3184
+ setTop: true,
3185
+ setWidth: true,
3186
+ setHeight: true,
3187
+ offsetTop: 0,
3188
+ offsetLeft: 0
3189
+ }, arguments[2] || {})
3190
+
3191
+ // find page position of source
3192
+ source = $(source);
3193
+ var p = Position.page(source);
3194
+
3195
+ // find coordinate system to use
3196
+ target = $(target);
3197
+ var delta = [0, 0];
3198
+ var parent = null;
3199
+ // delta [0,0] will do fine with position: fixed elements,
3200
+ // position:absolute needs offsetParent deltas
3201
+ if (Element.getStyle(target,'position') == 'absolute') {
3202
+ parent = Position.offsetParent(target);
3203
+ delta = Position.page(parent);
3204
+ }
3205
+
3206
+ // correct by body offsets (fixes Safari)
3207
+ if (parent == document.body) {
3208
+ delta[0] -= document.body.offsetLeft;
3209
+ delta[1] -= document.body.offsetTop;
3210
+ }
3211
+
3212
+ // set position
3213
+ if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
3214
+ if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
3215
+ if(options.setWidth) target.style.width = source.offsetWidth + 'px';
3216
+ if(options.setHeight) target.style.height = source.offsetHeight + 'px';
3217
+ },
3218
+
3219
+ absolutize: function(element) {
3220
+ element = $(element);
3221
+ if (element.style.position == 'absolute') return;
3222
+ Position.prepare();
3223
+
3224
+ var offsets = Position.positionedOffset(element);
3225
+ var top = offsets[1];
3226
+ var left = offsets[0];
3227
+ var width = element.clientWidth;
3228
+ var height = element.clientHeight;
3229
+
3230
+ element._originalLeft = left - parseFloat(element.style.left || 0);
3231
+ element._originalTop = top - parseFloat(element.style.top || 0);
3232
+ element._originalWidth = element.style.width;
3233
+ element._originalHeight = element.style.height;
3234
+
3235
+ element.style.position = 'absolute';
3236
+ element.style.top = top + 'px';
3237
+ element.style.left = left + 'px';
3238
+ element.style.width = width + 'px';
3239
+ element.style.height = height + 'px';
3240
+ },
3241
+
3242
+ relativize: function(element) {
3243
+ element = $(element);
3244
+ if (element.style.position == 'relative') return;
3245
+ Position.prepare();
3246
+
3247
+ element.style.position = 'relative';
3248
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
3249
+ var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
3250
+
3251
+ element.style.top = top + 'px';
3252
+ element.style.left = left + 'px';
3253
+ element.style.height = element._originalHeight;
3254
+ element.style.width = element._originalWidth;
3255
+ }
3256
+ }
3257
+
3258
+ // Safari returns margins on body which is incorrect if the child is absolutely
3259
+ // positioned. For performance reasons, redefine Position.cumulativeOffset for
3260
+ // KHTML/WebKit only.
3261
+ if (Prototype.Browser.WebKit) {
3262
+ Position.cumulativeOffset = function(element) {
3263
+ var valueT = 0, valueL = 0;
3264
+ do {
3265
+ valueT += element.offsetTop || 0;
3266
+ valueL += element.offsetLeft || 0;
3267
+ if (element.offsetParent == document.body)
3268
+ if (Element.getStyle(element, 'position') == 'absolute') break;
3269
+
3270
+ element = element.offsetParent;
3271
+ } while (element);
3272
+
3273
+ return [valueL, valueT];
3274
+ }
3275
+ }
3276
+
3277
+ Element.addMethods();
app/code/local/Mss/downloader/lib/.htaccess ADDED
@@ -0,0 +1,2 @@
 
 
1
+ Order deny,allow
2
+ Deny from all
app/code/local/Mss/downloader/lib/Mage/Archive.php ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Archive
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive
35
+ {
36
+
37
+ /**
38
+ * Archiver is used for compress.
39
+ */
40
+ const DEFAULT_ARCHIVER = 'gz';
41
+
42
+ /**
43
+ * Default packer for directory.
44
+ */
45
+ const TAPE_ARCHIVER = 'tar';
46
+
47
+ /**
48
+ * Current archiver is used for compress.
49
+ *
50
+ * @var Mage_Archiver_Tar|Mage_Archiver_Gz|Mage_Archiver_Bz
51
+ */
52
+ protected $_archiver=null;
53
+
54
+ /**
55
+ * Accessible formats for compress.
56
+ *
57
+ * @var array
58
+ */
59
+ protected $_formats = array(
60
+ 'tar' => 'tar',
61
+ 'gz' => 'gz',
62
+ 'gzip' => 'gz',
63
+ 'tgz' => 'tar.gz',
64
+ 'tgzip' => 'tar.gz',
65
+ 'bz' => 'bz',
66
+ 'bzip' => 'bz',
67
+ 'bzip2' => 'bz',
68
+ 'bz2' => 'bz',
69
+ 'tbz' => 'tar.bz',
70
+ 'tbzip' => 'tar.bz',
71
+ 'tbz2' => 'tar.bz',
72
+ 'tbzip2' => 'tar.bz');
73
+
74
+ /**
75
+ * Create object of current archiver by $extension.
76
+ *
77
+ * @param string $extension
78
+ * @return Mage_Archiver_Tar|Mage_Archiver_Gz|Mage_Archiver_Bz
79
+ */
80
+ protected function _getArchiver($extension)
81
+ {
82
+ if(array_key_exists(strtolower($extension), $this->_formats)) {
83
+ $format = $this->_formats[$extension];
84
+ } else {
85
+ $format = self::DEFAULT_ARCHIVER;
86
+ }
87
+ $class = 'Mage_Archive_' . ucfirst($format);
88
+ $this->_archiver = new $class();
89
+ return $this->_archiver;
90
+ }
91
+
92
+ /**
93
+ * Split current format to list of archivers.
94
+ *
95
+ * @param string $source
96
+ * @return array
97
+ */
98
+ protected function _getArchivers($source)
99
+ {
100
+ $ext = pathinfo($source, PATHINFO_EXTENSION);
101
+ if(!isset($this->_formats[$ext])) {
102
+ return array();
103
+ }
104
+ $format = $this->_formats[$ext];
105
+ if ($format) {
106
+ $archivers = explode('.', $format);
107
+ return $archivers;
108
+ }
109
+ return array();
110
+ }
111
+
112
+ /**
113
+ * Pack file or directory to archivers are parsed from extension.
114
+ *
115
+ * @param string $source
116
+ * @param string $destination
117
+ * @param boolean $skipRoot skip first level parent
118
+ * @return string Path to file
119
+ */
120
+ public function pack($source, $destination='packed.tgz', $skipRoot=false)
121
+ {
122
+ $archivers = $this->_getArchivers($destination);
123
+ $interimSource = '';
124
+ for ($i=0; $i<count($archivers); $i++ ) {
125
+ if ($i == (count($archivers) - 1)) {
126
+ $packed = $destination;
127
+ } else {
128
+ $packed = dirname($destination) . DS . '~tmp-'. microtime(true) . $archivers[$i] . '.' . $archivers[$i];
129
+ }
130
+ $source = $this->_getArchiver($archivers[$i])->pack($source, $packed, $skipRoot);
131
+ if ($interimSource && $i < count($archivers)) {
132
+ unlink($interimSource);
133
+ }
134
+ $interimSource = $source;
135
+ }
136
+ return $source;
137
+ }
138
+
139
+ /**
140
+ * Unpack file from archivers are parsed from extension.
141
+ * If $tillTar == true unpack file from archivers till
142
+ * meet TAR archiver.
143
+ *
144
+ * @param string $source
145
+ * @param string $destination
146
+ * @param boolean $tillTar
147
+ * @return string Path to file
148
+ */
149
+ public function unpack($source, $destination='.', $tillTar=false, $clearInterm = true)
150
+ {
151
+ $archivers = $this->_getArchivers($source);
152
+ $interimSource = '';
153
+ for ($i=count($archivers)-1; $i>=0; $i--) {
154
+ if ($tillTar && $archivers[$i] == self::TAPE_ARCHIVER) {
155
+ break;
156
+ }
157
+ if ($i == 0) {
158
+ $packed = rtrim($destination, DS) . DS;
159
+ } else {
160
+ $packed = rtrim($destination, DS) . DS . '~tmp-'. microtime(true) . $archivers[$i-1] . '.'
161
+ . $archivers[$i-1];
162
+ }
163
+ $source = $this->_getArchiver($archivers[$i])->unpack($source, $packed);
164
+
165
+ //var_dump($packed, $source);
166
+
167
+ if ($clearInterm && $interimSource && $i >= 0) {
168
+ unlink($interimSource);
169
+ }
170
+ $interimSource = $source;
171
+ }
172
+ return $source;
173
+ }
174
+
175
+ /**
176
+ * Extract one file from TAR (Tape Archiver).
177
+ *
178
+ * @param string $file
179
+ * @param string $source
180
+ * @param string $destination
181
+ * @return string Path to file
182
+ */
183
+ public function extract($file, $source, $destination='.')
184
+ {
185
+ $tarFile = $this->unpack($source, $destination, true);
186
+ $resFile = $this->_getArchiver(self::TAPE_ARCHIVER)->extract($file, $tarFile, $destination);
187
+ if (!$this->isTar($source)) {
188
+ unlink($tarFile);
189
+ }
190
+ return $resFile;
191
+ }
192
+
193
+ /**
194
+ * Check file is archive.
195
+ *
196
+ * @param string $file
197
+ * @return boolean
198
+ */
199
+ public function isArchive($file)
200
+ {
201
+ $archivers = $this->_getArchivers($file);
202
+ if (count($archivers)) {
203
+ return true;
204
+ }
205
+ return false;
206
+ }
207
+
208
+ /**
209
+ * Check file is TAR.
210
+ *
211
+ * @param mixed $file
212
+ * @return boolean
213
+ */
214
+ public function isTar($file)
215
+ {
216
+ $archivers = $this->_getArchivers($file);
217
+ if (count($archivers)==1 && $archivers[0] == self::TAPE_ARCHIVER) {
218
+ return true;
219
+ }
220
+ return false;
221
+ }
222
+ }
app/code/local/Mss/downloader/lib/Mage/Archive/Abstract.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Archive
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Abstract
35
+ {
36
+ /**
37
+ * Write data to file. If file can't be opened - throw exception
38
+ *
39
+ * @param string $destination
40
+ * @param string $data
41
+ * @return boolean
42
+ * @throws Mage_Exception
43
+ */
44
+ protected function _writeFile($destination, $data)
45
+ {
46
+ $destination = trim($destination);
47
+ if(false === file_put_contents($destination, $data)) {
48
+ throw new Mage_Exception("Can't write to file: " . $destination);
49
+ }
50
+ return true;
51
+ }
52
+
53
+ /**
54
+ * Read data from file. If file can't be opened, throw to exception.
55
+ *
56
+ * @param string $source
57
+ * @return string
58
+ * @throws Mage_Exception
59
+ */
60
+ protected function _readFile($source)
61
+ {
62
+ $data = '';
63
+ if (is_file($source) && is_readable($source)) {
64
+ $data = @file_get_contents($source);
65
+ if ($data === false) {
66
+ throw new Mage_Exception("Can't get contents from: " . $source);
67
+ }
68
+ }
69
+ return $data;
70
+ }
71
+
72
+ /**
73
+ * Get file name from source (URI) without last extension.
74
+ *
75
+ * @param string $source
76
+ * @param bool $withExtension
77
+ * @return mixed|string
78
+ */
79
+ public function getFilename($source, $withExtension=false)
80
+ {
81
+ $file = str_replace(dirname($source) . DS, '', $source);
82
+ if (!$withExtension) {
83
+ $file = substr($file, 0, strrpos($file, '.'));
84
+ }
85
+ return $file;
86
+ }
87
+ }
app/code/local/Mss/downloader/lib/Mage/Archive/Bz.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Archive
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with bzip2 archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Bz extends Mage_Archive_Abstract implements Mage_Archive_Interface
35
+ {
36
+
37
+ /**
38
+ * Pack file by BZIP2 compressor.
39
+ *
40
+ * @param string $source
41
+ * @param string $destination
42
+ * @return string
43
+ */
44
+ public function pack($source, $destination)
45
+ {
46
+ $fileReader = new Mage_Archive_Helper_File($source);
47
+ $fileReader->open('r');
48
+
49
+ $archiveWriter = new Mage_Archive_Helper_File_Bz($destination);
50
+ $archiveWriter->open('w');
51
+
52
+ while (!$fileReader->eof()) {
53
+ $archiveWriter->write($fileReader->read());
54
+ }
55
+
56
+ $fileReader->close();
57
+ $archiveWriter->close();
58
+
59
+ return $destination;
60
+ }
61
+
62
+ /**
63
+ * Unpack file by BZIP2 compressor.
64
+ *
65
+ * @param string $source
66
+ * @param string $destination
67
+ * @return string
68
+ */
69
+ public function unpack($source, $destination)
70
+ {
71
+ if (is_dir($destination)) {
72
+ $file = $this->getFilename($source);
73
+ $destination = $destination . $file;
74
+ }
75
+
76
+ $archiveReader = new Mage_Archive_Helper_File_Bz($source);
77
+ $archiveReader->open('r');
78
+
79
+ $fileWriter = new Mage_Archive_Helper_File($destination);
80
+ $fileWriter->open('w');
81
+
82
+ while (!$archiveReader->eof()) {
83
+ $fileWriter->write($archiveReader->read());
84
+ }
85
+
86
+ return $destination;
87
+ }
88
+
89
+ }
app/code/local/Mss/downloader/lib/Mage/Archive/Gz.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Archive
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with gz archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Gz extends Mage_Archive_Abstract implements Mage_Archive_Interface
35
+ {
36
+ /**
37
+ * Pack file by GZ compressor.
38
+ *
39
+ * @param string $source
40
+ * @param string $destination
41
+ * @return string
42
+ */
43
+ public function pack($source, $destination)
44
+ {
45
+ $fileReader = new Mage_Archive_Helper_File($source);
46
+ $fileReader->open('r');
47
+
48
+ $archiveWriter = new Mage_Archive_Helper_File_Gz($destination);
49
+ $archiveWriter->open('wb9');
50
+
51
+ while (!$fileReader->eof()) {
52
+ $archiveWriter->write($fileReader->read());
53
+ }
54
+
55
+ $fileReader->close();
56
+ $archiveWriter->close();
57
+
58
+ return $destination;
59
+ }
60
+
61
+ /**
62
+ * Unpack file by GZ compressor.
63
+ *
64
+ * @param string $source
65
+ * @param string $destination
66
+ * @return string
67
+ */
68
+ public function unpack($source, $destination)
69
+ {
70
+ if (is_dir($destination)) {
71
+ $file = $this->getFilename($source);
72
+ $destination = $destination . $file;
73
+ }
74
+
75
+ $archiveReader = new Mage_Archive_Helper_File_Gz($source);
76
+ $archiveReader->open('r');
77
+
78
+ $fileWriter = new Mage_Archive_Helper_File($destination);
79
+ $fileWriter->open('w');
80
+
81
+ while (!$archiveReader->eof()) {
82
+ $fileWriter->write($archiveReader->read());
83
+ }
84
+
85
+ return $destination;
86
+ }
87
+ }
app/code/local/Mss/downloader/lib/Mage/Archive/Helper/File.php ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Archive
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Helper class that simplifies files stream reading and writing
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Helper_File
35
+ {
36
+ /**
37
+ * Full path to directory where file located
38
+ *
39
+ * @var string
40
+ */
41
+ protected $_fileLocation;
42
+
43
+ /**
44
+ * File name
45
+ *
46
+ * @var string
47
+ */
48
+ protected $_fileName;
49
+
50
+ /**
51
+ * Full path (directory + filename) to file
52
+ *
53
+ * @var string
54
+ */
55
+ protected $_filePath;
56
+
57
+ /**
58
+ * File permissions that will be set if file opened in write mode
59
+ *
60
+ * @var int
61
+ */
62
+ protected $_chmod;
63
+
64
+ /**
65
+ * File handler
66
+ *
67
+ * @var pointer
68
+ */
69
+ protected $_fileHandler;
70
+
71
+ /**
72
+ * Set file path via constructor
73
+ *
74
+ * @param string $filePath
75
+ */
76
+ public function __construct($filePath)
77
+ {
78
+ $pathInfo = pathinfo($filePath);
79
+
80
+ $this->_filePath = $filePath;
81
+ $this->_fileLocation = isset($pathInfo['dirname']) ? $pathInfo['dirname'] : '';
82
+ $this->_fileName = isset($pathInfo['basename']) ? $pathInfo['basename'] : '';
83
+ }
84
+
85
+ /**
86
+ * Close file if it's not closed before object destruction
87
+ */
88
+ public function __destruct()
89
+ {
90
+ if ($this->_fileHandler) {
91
+ $this->_close();
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Open file
97
+ *
98
+ * @param string $mode
99
+ * @param int $chmod
100
+ * @throws Mage_Exception
101
+ */
102
+ public function open($mode = 'w+', $chmod = 0666)
103
+ {
104
+ if ($this->_isWritableMode($mode)) {
105
+ if (!is_writable($this->_fileLocation)) {
106
+ throw new Mage_Exception('Permission denied to write to ' . $this->_fileLocation);
107
+ }
108
+
109
+ if (is_file($this->_filePath) && !is_writable($this->_filePath)) {
110
+ throw new Mage_Exception("Can't open file " . $this->_fileName . " for writing. Permission denied.");
111
+ }
112
+ }
113
+
114
+ if ($this->_isReadableMode($mode) && (!is_file($this->_filePath) || !is_readable($this->_filePath))) {
115
+ if (!is_file($this->_filePath)) {
116
+ throw new Mage_Exception('File ' . $this->_filePath . ' does not exist');
117
+ }
118
+
119
+ if (!is_readable($this->_filePath)) {
120
+ throw new Mage_Exception('Permission denied to read file ' . $this->_filePath);
121
+ }
122
+ }
123
+
124
+ $this->_open($mode);
125
+
126
+ $this->_chmod = $chmod;
127
+ }
128
+
129
+ /**
130
+ * Write data to file
131
+ *
132
+ * @param string $data
133
+ */
134
+ public function write($data)
135
+ {
136
+ $this->_checkFileOpened();
137
+ $this->_write($data);
138
+ }
139
+
140
+ /**
141
+ * Read data from file
142
+ *
143
+ * @param int $length
144
+ * @return string|boolean
145
+ */
146
+ public function read($length = 4096)
147
+ {
148
+ $data = false;
149
+ $this->_checkFileOpened();
150
+ if ($length > 0) {
151
+ $data = $this->_read($length);
152
+ }
153
+
154
+ return $data;
155
+ }
156
+
157
+ /**
158
+ * Check whether end of file reached
159
+ *
160
+ * @return boolean
161
+ */
162
+ public function eof()
163
+ {
164
+ $this->_checkFileOpened();
165
+ return $this->_eof();
166
+ }
167
+
168
+ /**
169
+ * Close file
170
+ */
171
+ public function close()
172
+ {
173
+ $this->_checkFileOpened();
174
+ $this->_close();
175
+ $this->_fileHandler = false;
176
+ @chmod($this->_filePath, $this->_chmod);
177
+ }
178
+
179
+ /**
180
+ * Implementation of file opening
181
+ *
182
+ * @param string $mode
183
+ * @throws Mage_Exception
184
+ */
185
+ protected function _open($mode)
186
+ {
187
+ $this->_fileHandler = @fopen($this->_filePath, $mode);
188
+
189
+ if (false === $this->_fileHandler) {
190
+ throw new Mage_Exception('Failed to open file ' . $this->_filePath);
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Implementation of writing data to file
196
+ *
197
+ * @param string $data
198
+ * @throws Mage_Exception
199
+ */
200
+ protected function _write($data)
201
+ {
202
+ $result = @fwrite($this->_fileHandler, $data);
203
+
204
+ if (false === $result) {
205
+ throw new Mage_Exception('Failed to write data to ' . $this->_filePath);
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Implementation of file reading
211
+ *
212
+ * @param int $length
213
+ * @throws Mage_Exception
214
+ */
215
+ protected function _read($length)
216
+ {
217
+ $result = fread($this->_fileHandler, $length);
218
+
219
+ if (false === $result) {
220
+ throw new Mage_Exception('Failed to read data from ' . $this->_filePath);
221
+ }
222
+
223
+ return $result;
224
+ }
225
+
226
+ /**
227
+ * Implementation of EOF indicator
228
+ *
229
+ * @return boolean
230
+ */
231
+ protected function _eof()
232
+ {
233
+ return feof($this->_fileHandler);
234
+ }
235
+
236
+ /**
237
+ * Implementation of file closing
238
+ */
239
+ protected function _close()
240
+ {
241
+ fclose($this->_fileHandler);
242
+ }
243
+
244
+ /**
245
+ * Check whether requested mode is writable mode
246
+ *
247
+ * @param string $mode
248
+ */
249
+ protected function _isWritableMode($mode)
250
+ {
251
+ return preg_match('/(^[waxc])|(\+$)/', $mode);
252
+ }
253
+
254
+ /**
255
+ * Check whether requested mode is readable mode
256
+ *
257
+ * @param string $mode
258
+ */
259
+ protected function _isReadableMode($mode) {
260
+ return !$this->_isWritableMode($mode);
261
+ }
262
+
263
+ /**
264
+ * Check whether file is opened
265
+ *
266
+ * @throws Mage_Exception
267
+ */
268
+ protected function _checkFileOpened()
269
+ {
270
+ if (!$this->_fileHandler) {
271
+ throw new Mage_Exception('File not opened');
272
+ }
273
+ }
274
+ }
app/code/local/Mss/downloader/lib/Mage/Archive/Helper/File/Bz.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Archive
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Helper class that simplifies bz2 files stream reading and writing
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Helper_File_Bz extends Mage_Archive_Helper_File
35
+ {
36
+ /**
37
+ * Open bz archive file
38
+ *
39
+ * @throws Mage_Exception
40
+ * @param string $mode
41
+ */
42
+ protected function _open($mode)
43
+ {
44
+ $this->_fileHandler = @bzopen($this->_filePath, $mode);
45
+
46
+ if (false === $this->_fileHandler) {
47
+ throw new Mage_Exception('Failed to open file ' . $this->_filePath);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Write data to bz archive
53
+ *
54
+ * @throws Mage_Exception
55
+ * @param $data
56
+ */
57
+ protected function _write($data)
58
+ {
59
+ $result = @bzwrite($this->_fileHandler, $data);
60
+
61
+ if (false === $result) {
62
+ throw new Mage_Exception('Failed to write data to ' . $this->_filePath);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Read data from bz archive
68
+ *
69
+ * @throws Mage_Exception
70
+ * @param int $length
71
+ * @return string
72
+ */
73
+ protected function _read($length)
74
+ {
75
+ $data = bzread($this->_fileHandler, $length);
76
+
77
+ if (false === $data) {
78
+ throw new Mage_Exception('Failed to read data from ' . $this->_filePath);
79
+ }
80
+
81
+ return $data;
82
+ }
83
+
84
+ /**
85
+ * Close bz archive
86
+ */
87
+ protected function _close()
88
+ {
89
+ bzclose($this->_fileHandler);
90
+ }
91
+ }
92
+
app/code/local/Mss/downloader/lib/Mage/Archive/Helper/File/Gz.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Archive
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Helper class that simplifies gz files stream reading and writing
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Helper_File_Gz extends Mage_Archive_Helper_File
35
+ {
36
+
37
+ /**
38
+ * Overwritten Mage_Archive_Helper_File constructor with zlib extension check
39
+ * @param string $filePath
40
+ * @throws Mage_Exception
41
+ */
42
+ public function __construct($filePath)
43
+ {
44
+ if (!function_exists('gzopen')) {
45
+ throw new Mage_Exception('PHP Extensions "zlib" must be loaded.');
46
+ }
47
+
48
+ parent::__construct($filePath);
49
+ }
50
+
51
+ /**
52
+ * @see Mage_Archive_Helper_File::_open()
53
+ */
54
+ protected function _open($mode)
55
+ {
56
+ $this->_fileHandler = @gzopen($this->_filePath, $mode);
57
+
58
+ if (false === $this->_fileHandler) {
59
+ throw new Mage_Exception('Failed to open file ' . $this->_filePath);
60
+ }
61
+ }
62
+
63
+ /**
64
+ * @see Mage_Archive_Helper_File::_write()
65
+ */
66
+ protected function _write($data)
67
+ {
68
+ $result = @gzwrite($this->_fileHandler, $data);
69
+
70
+ if (empty($result) && !empty($data)) {
71
+ throw new Mage_Exception('Failed to write data to ' . $this->_filePath);
72
+ }
73
+ }
74
+
75
+ /**
76
+ * @see Mage_Archive_Helper_File::_read()
77
+ */
78
+ protected function _read($length)
79
+ {
80
+ return gzread($this->_fileHandler, $length);
81
+ }
82
+
83
+ /**
84
+ * @see Mage_Archive_Helper_File::_eof()
85
+ */
86
+ protected function _eof()
87
+ {
88
+ return gzeof($this->_fileHandler);
89
+ }
90
+
91
+ /**
92
+ * @see Mage_Archive_Helper_File::_close()
93
+ */
94
+ protected function _close()
95
+ {
96
+ gzclose($this->_fileHandler);
97
+ }
98
+ }
app/code/local/Mss/downloader/lib/Mage/Archive/Interface.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Archive
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Interface for work with archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ interface Mage_Archive_Interface
35
+ {
36
+ /**
37
+ * Pack file or directory.
38
+ *
39
+ * @param string $source
40
+ * @param string $destination
41
+ * @return string
42
+ */
43
+ public function pack($source, $destination);
44
+
45
+ /**
46
+ * Unpack file or directory.
47
+ *
48
+ * @param string $source
49
+ * @param string $destination
50
+ * @return string
51
+ */
52
+ public function unpack($source, $destination);
53
+ }
app/code/local/Mss/downloader/lib/Mage/Archive/Tar.php ADDED
@@ -0,0 +1,690 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Archive
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with tar archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Archive
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Archive_Tar extends Mage_Archive_Abstract implements Mage_Archive_Interface
35
+ {
36
+ /**
37
+ * Tar block size
38
+ *
39
+ * @const int
40
+ */
41
+ const TAR_BLOCK_SIZE = 512;
42
+
43
+ /**
44
+ * Keep file or directory for packing.
45
+ *
46
+ * @var string
47
+ */
48
+ protected $_currentFile;
49
+
50
+ /**
51
+ * Keep path to file or directory for packing.
52
+ *
53
+ * @var mixed
54
+ */
55
+ protected $_currentPath;
56
+
57
+ /**
58
+ * Skip first level parent directory. Example:
59
+ * use test/fip.php instead test/test/fip.php;
60
+ *
61
+ * @var mixed
62
+ */
63
+ protected $_skipRoot;
64
+
65
+ /**
66
+ * Tarball data writer
67
+ *
68
+ * @var Mage_Archive_Helper_File
69
+ */
70
+ protected $_writer;
71
+
72
+ /**
73
+ * Tarball data reader
74
+ *
75
+ * @var Mage_Archive_Helper_File
76
+ */
77
+ protected $_reader;
78
+
79
+ /**
80
+ * Path to file where tarball should be placed
81
+ *
82
+ * @var string
83
+ */
84
+ protected $_destinationFilePath;
85
+
86
+ /**
87
+ * Initialize tarball writer
88
+ *
89
+ * @return Mage_Archive_Tar
90
+ */
91
+ protected function _initWriter()
92
+ {
93
+ $this->_writer = new Mage_Archive_Helper_File($this->_destinationFilePath);
94
+ $this->_writer->open('w');
95
+
96
+ return $this;
97
+ }
98
+
99
+ /**
100
+ * Returns string that is used for tar's header parsing
101
+ *
102
+ * Format codes were changed in 5.5.0 version. See http://php.net/manual/en/function.unpack.php
103
+ *
104
+ * @return string
105
+ */
106
+ protected static final function _getFormatParseHeader()
107
+ {
108
+ if (version_compare(phpversion(), '5.5.0', '<') === true) {
109
+ return 'a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2version/'
110
+ . 'a32uname/a32gname/a8devmajor/a8devminor/a155prefix/a12closer';
111
+ }
112
+ return 'Z100name/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/Z8checksum/Z1type/Z100symlink/Z6magic/Z2version/'
113
+ . 'Z32uname/Z32gname/Z8devmajor/Z8devminor/Z155prefix/Z12closer';
114
+ }
115
+
116
+ /**
117
+ * Destroy tarball writer
118
+ *
119
+ * @return Mage_Archive_Tar
120
+ */
121
+ protected function _destroyWriter()
122
+ {
123
+ if ($this->_writer instanceof Mage_Archive_Helper_File) {
124
+ $this->_writer->close();
125
+ $this->_writer = null;
126
+ }
127
+
128
+ return $this;
129
+ }
130
+
131
+ /**
132
+ * Get tarball writer
133
+ *
134
+ * @return Mage_Archive_Helper_File
135
+ */
136
+ protected function _getWriter()
137
+ {
138
+ if (!$this->_writer) {
139
+ $this->_initWriter();
140
+ }
141
+
142
+ return $this->_writer;
143
+ }
144
+
145
+ /**
146
+ * Initialize tarball reader
147
+ *
148
+ * @return Mage_Archive_Tar
149
+ */
150
+ protected function _initReader()
151
+ {
152
+ $this->_reader = new Mage_Archive_Helper_File($this->_getCurrentFile());
153
+ $this->_reader->open('r');
154
+
155
+ return $this;
156
+ }
157
+
158
+ /**
159
+ * Destroy tarball reader
160
+ *
161
+ * @return Mage_Archive_Tar
162
+ */
163
+ protected function _destroyReader()
164
+ {
165
+ if ($this->_reader instanceof Mage_Archive_Helper_File) {
166
+ $this->_reader->close();
167
+ $this->_reader = null;
168
+ }
169
+
170
+ return $this;
171
+ }
172
+
173
+ /**
174
+ * Get tarball reader
175
+ *
176
+ * @return Mage_Archive_Helper_File
177
+ */
178
+ protected function _getReader()
179
+ {
180
+ if (!$this->_reader) {
181
+ $this->_initReader();
182
+ }
183
+
184
+ return $this->_reader;
185
+ }
186
+
187
+ /**
188
+ * Set option that define ability skip first catalog level.
189
+ *
190
+ * @param mixed $skipRoot
191
+ * @return Mage_Archive_Tar
192
+ */
193
+ protected function _setSkipRoot($skipRoot)
194
+ {
195
+ $this->_skipRoot = $skipRoot;
196
+ return $this;
197
+ }
198
+
199
+ /**
200
+ * Set file which is packing.
201
+ *
202
+ * @param string $file
203
+ * @return Mage_Archive_Tar
204
+ */
205
+ protected function _setCurrentFile($file)
206
+ {
207
+ $this->_currentFile = $file .((!is_link($file) && is_dir($file) && substr($file, -1) != DS) ? DS : '');
208
+ return $this;
209
+ }
210
+
211
+ /**
212
+ * Set path to file where tarball should be placed
213
+ *
214
+ * @param string $destinationFilePath
215
+ * @return Mage_Archive_Tar
216
+ */
217
+ protected function _setDestinationFilePath($destinationFilePath)
218
+ {
219
+ $this->_destinationFilePath = $destinationFilePath;
220
+ return $this;
221
+ }
222
+
223
+ /**
224
+ * Retrieve file which is packing.
225
+ *
226
+ * @return string
227
+ */
228
+ protected function _getCurrentFile()
229
+ {
230
+ return $this->_currentFile;
231
+ }
232
+
233
+ /**
234
+ * Set path to file which is packing.
235
+ *
236
+ * @param string $path
237
+ * @return Mage_Archive_Tar
238
+ */
239
+ protected function _setCurrentPath($path)
240
+ {
241
+ if ($this->_skipRoot && is_dir($path)) {
242
+ $this->_currentPath = $path.(substr($path, -1)!=DS?DS:'');
243
+ } else {
244
+ $this->_currentPath = dirname($path) . DS;
245
+ }
246
+ return $this;
247
+ }
248
+
249
+ /**
250
+ * Retrieve path to file which is packing.
251
+ *
252
+ * @return string
253
+ */
254
+ protected function _getCurrentPath()
255
+ {
256
+ return $this->_currentPath;
257
+ }
258
+
259
+ /**
260
+ * Walk through directory and add to tar file or directory.
261
+ * Result is packed string on TAR format.
262
+ *
263
+ * @deprecated after 1.7.0.0
264
+ * @param boolean $skipRoot
265
+ * @return string
266
+ */
267
+ protected function _packToTar($skipRoot=false)
268
+ {
269
+ $file = $this->_getCurrentFile();
270
+ $header = '';
271
+ $data = '';
272
+ if (!$skipRoot) {
273
+ $header = $this->_composeHeader();
274
+ $data = $this->_readFile($file);
275
+ $data = str_pad($data, floor(((is_dir($file) ? 0 : filesize($file)) + 512 - 1) / 512) * 512, "\0");
276
+ }
277
+ $sub = '';
278
+ if (is_dir($file)) {
279
+ $treeDir = scandir($file);
280
+ if (empty($treeDir)) {
281
+ throw new Mage_Exception('Can\'t scan dir: ' . $file);
282
+ }
283
+ array_shift($treeDir); /* remove './'*/
284
+ array_shift($treeDir); /* remove '../'*/
285
+ foreach ($treeDir as $item) {
286
+ $sub .= $this->_setCurrentFile($file.$item)->_packToTar(false);
287
+ }
288
+ }
289
+ $tarData = $header . $data . $sub;
290
+ $tarData = str_pad($tarData, floor((strlen($tarData) - 1) / 1536) * 1536, "\0");
291
+ return $tarData;
292
+ }
293
+
294
+ /**
295
+ * Recursively walk through file tree and create tarball
296
+ *
297
+ * @param boolean $skipRoot
298
+ * @param boolean $finalize
299
+ * @throws Mage_Exception
300
+ */
301
+ protected function _createTar($skipRoot = false, $finalize = false)
302
+ {
303
+ if (!$skipRoot) {
304
+ $this->_packAndWriteCurrentFile();
305
+ }
306
+
307
+ $file = $this->_getCurrentFile();
308
+
309
+ if (is_dir($file)) {
310
+ $dirFiles = scandir($file);
311
+
312
+ if (false === $dirFiles) {
313
+ throw new Mage_Exception('Can\'t scan dir: ' . $file);
314
+ }
315
+
316
+ array_shift($dirFiles); /* remove './'*/
317
+ array_shift($dirFiles); /* remove '../'*/
318
+
319
+ foreach ($dirFiles as $item) {
320
+ $this->_setCurrentFile($file . $item)->_createTar();
321
+ }
322
+ }
323
+
324
+ if ($finalize) {
325
+ $this->_getWriter()->write(str_repeat("\0", self::TAR_BLOCK_SIZE * 12));
326
+ }
327
+ }
328
+
329
+ /**
330
+ * Write current file to tarball
331
+ */
332
+ protected function _packAndWriteCurrentFile()
333
+ {
334
+ $archiveWriter = $this->_getWriter();
335
+ $archiveWriter->write($this->_composeHeader());
336
+
337
+ $currentFile = $this->_getCurrentFile();
338
+
339
+ $fileSize = 0;
340
+
341
+ if (is_file($currentFile) && !is_link($currentFile)) {
342
+ $fileReader = new Mage_Archive_Helper_File($currentFile);
343
+ $fileReader->open('r');
344
+
345
+ while (!$fileReader->eof()) {
346
+ $archiveWriter->write($fileReader->read());
347
+ }
348
+
349
+ $fileReader->close();
350
+
351
+ $fileSize = filesize($currentFile);
352
+ }
353
+
354
+ $appendZerosCount = (self::TAR_BLOCK_SIZE - $fileSize % self::TAR_BLOCK_SIZE) % self::TAR_BLOCK_SIZE;
355
+ $archiveWriter->write(str_repeat("\0", $appendZerosCount));
356
+ }
357
+
358
+ /**
359
+ * Compose header for current file in TAR format.
360
+ * If length of file's name greater 100 characters,
361
+ * method breaks header into two pieces. First contains
362
+ * header and data with long name. Second contain only header.
363
+ *
364
+ * @param boolean $long
365
+ * @return string
366
+ */
367
+ protected function _composeHeader($long = false)
368
+ {
369
+ $file = $this->_getCurrentFile();
370
+ $path = $this->_getCurrentPath();
371
+ $infoFile = stat($file);
372
+ $nameFile = str_replace($path, '', $file);
373
+ $nameFile = str_replace('\\', '/', $nameFile);
374
+ $packedHeader = '';
375
+ $longHeader = '';
376
+ if (!$long && strlen($nameFile)>100) {
377
+ $longHeader = $this->_composeHeader(true);
378
+ $longHeader .= str_pad($nameFile, floor((strlen($nameFile) + 512 - 1) / 512) * 512, "\0");
379
+ }
380
+ $header = array();
381
+ $header['100-name'] = $long?'././@LongLink':substr($nameFile, 0, 100);
382
+ $header['8-mode'] = $long ? ' '
383
+ : str_pad(substr(sprintf("%07o", $infoFile['mode']),-4), 6, '0', STR_PAD_LEFT);
384
+ $header['8-uid'] = $long || $infoFile['uid']==0?"\0\0\0\0\0\0\0":sprintf("%07o", $infoFile['uid']);
385
+ $header['8-gid'] = $long || $infoFile['gid']==0?"\0\0\0\0\0\0\0":sprintf("%07o", $infoFile['gid']);
386
+ $header['12-size'] = $long ? sprintf("%011o", strlen($nameFile)) : sprintf("%011o", is_dir($file)
387
+ ? 0 : filesize($file));
388
+ $header['12-mtime'] = $long?'00000000000':sprintf("%011o", $infoFile['mtime']);
389
+ $header['8-check'] = sprintf('% 8s', '');
390
+ $header['1-type'] = $long ? 'L' : (is_link($file) ? 2 : (is_dir($file) ? 5 : 0));
391
+ $header['100-symlink'] = is_link($file) ? readlink($file) : '';
392
+ $header['6-magic'] = 'ustar ';
393
+ $header['2-version'] = ' ';
394
+ $a=function_exists('posix_getpwuid')?posix_getpwuid (fileowner($file)):array('name'=>'');
395
+ $header['32-uname'] = $a['name'];
396
+ $a=function_exists('posix_getgrgid')?posix_getgrgid (filegroup($file)):array('name'=>'');
397
+ $header['32-gname'] = $a['name'];
398
+ $header['8-devmajor'] = '';
399
+ $header['8-devminor'] = '';
400
+ $header['155-prefix'] = '';
401
+ $header['12-closer'] = '';
402
+
403
+ $packedHeader = '';
404
+ foreach ($header as $key=>$element) {
405
+ $length = explode('-', $key);
406
+ $packedHeader .= pack('a' . $length[0], $element);
407
+ }
408
+
409
+ $checksum = 0;
410
+ for ($i = 0; $i < 512; $i++) {
411
+ $checksum += ord(substr($packedHeader, $i, 1));
412
+ }
413
+ $packedHeader = substr_replace($packedHeader, sprintf("%07o", $checksum)."\0", 148, 8);
414
+
415
+ return $longHeader . $packedHeader;
416
+ }
417
+
418
+ /**
419
+ * Read TAR string from file, and unpacked it.
420
+ * Create files and directories information about discribed
421
+ * in the string.
422
+ *
423
+ * @param string $destination path to file is unpacked
424
+ * @return array list of files
425
+ * @throws Mage_Exception
426
+ */
427
+ protected function _unpackCurrentTar($destination)
428
+ {
429
+ $archiveReader = $this->_getReader();
430
+ $list = array();
431
+
432
+ while (!$archiveReader->eof()) {
433
+ $header = $this->_extractFileHeader();
434
+
435
+ if (!$header) {
436
+ continue;
437
+ }
438
+
439
+ $currentFile = $destination . $header['name'];
440
+ $dirname = dirname($currentFile);
441
+
442
+ if (in_array($header['type'], array("0",chr(0), ''))) {
443
+
444
+ if(!file_exists($dirname)) {
445
+ $mkdirResult = @mkdir($dirname, 0777, true);
446
+
447
+ if (false === $mkdirResult) {
448
+ throw new Mage_Exception('Failed to create directory ' . $dirname);
449
+ }
450
+ }
451
+
452
+ $this->_extractAndWriteFile($header, $currentFile);
453
+ $list[] = $currentFile;
454
+
455
+ } elseif ($header['type'] == '5') {
456
+
457
+ if(!file_exists($dirname)) {
458
+ $mkdirResult = @mkdir($currentFile, $header['mode'], true);
459
+
460
+ if (false === $mkdirResult) {
461
+ throw new Mage_Exception('Failed to create directory ' . $currentFile);
462
+ }
463
+ }
464
+ $list[] = $currentFile . DS;
465
+ } elseif ($header['type'] == '2') {
466
+
467
+ //we do not interrupt unpack process if symlink creation failed as symlinks are not so important
468
+ @symlink($header['symlink'], $currentFile);
469
+ }
470
+ }
471
+
472
+ return $list;
473
+ }
474
+
475
+ /**
476
+ * Get header from TAR string and unpacked it by format.
477
+ *
478
+ * @deprecated after 1.7.0.0
479
+ * @param resource $pointer
480
+ * @return string
481
+ */
482
+ protected function _parseHeader(&$pointer)
483
+ {
484
+ $firstLine = fread($pointer, 512);
485
+
486
+ if (strlen($firstLine)<512){
487
+ return false;
488
+ }
489
+
490
+ $fmt = self::_getFormatParseHeader();
491
+ $header = unpack ($fmt, $firstLine);
492
+
493
+ $header['mode']=$header['mode']+0;
494
+ $header['uid']=octdec($header['uid']);
495
+ $header['gid']=octdec($header['gid']);
496
+ $header['size']=octdec($header['size']);
497
+ $header['mtime']=octdec($header['mtime']);
498
+ $header['checksum']=octdec($header['checksum']);
499
+
500
+ if ($header['type'] == "5") {
501
+ $header['size'] = 0;
502
+ }
503
+
504
+ $checksum = 0;
505
+ $firstLine = substr_replace($firstLine, ' ', 148, 8);
506
+ for ($i = 0; $i < 512; $i++) {
507
+ $checksum += ord(substr($firstLine, $i, 1));
508
+ }
509
+
510
+ $isUstar = 'ustar' == strtolower(substr($header['magic'], 0, 5));
511
+
512
+ $checksumOk = $header['checksum'] == $checksum;
513
+ if (isset($header['name']) && $checksumOk) {
514
+ if ($header['name'] == '././@LongLink' && $header['type'] == 'L') {
515
+ $realName = substr(fread($pointer, floor(($header['size'] + 512 - 1) / 512) * 512), 0, $header['size']);
516
+ $headerMain = $this->_parseHeader($pointer);
517
+ $headerMain['name'] = $realName;
518
+ return $headerMain;
519
+ } else {
520
+ if ($header['size']>0) {
521
+ $header['data'] = substr(fread($pointer, floor(($header['size'] + 512 - 1) / 512) * 512), 0, $header['size']);
522
+ } else {
523
+ $header['data'] = '';
524
+ }
525
+ return $header;
526
+ }
527
+ }
528
+ return false;
529
+ }
530
+
531
+ /**
532
+ * Read and decode file header information from tarball
533
+ *
534
+ * @return array|boolean
535
+ */
536
+ protected function _extractFileHeader()
537
+ {
538
+ $archiveReader = $this->_getReader();
539
+
540
+ $headerBlock = $archiveReader->read(self::TAR_BLOCK_SIZE);
541
+
542
+ if (strlen($headerBlock) < self::TAR_BLOCK_SIZE) {
543
+ return false;
544
+ }
545
+
546
+ $header = unpack(self::_getFormatParseHeader(), $headerBlock);
547
+
548
+ $header['mode'] = octdec($header['mode']);
549
+ $header['uid'] = octdec($header['uid']);
550
+ $header['gid'] = octdec($header['gid']);
551
+ $header['size'] = octdec($header['size']);
552
+ $header['mtime'] = octdec($header['mtime']);
553
+ $header['checksum'] = octdec($header['checksum']);
554
+
555
+ if ($header['type'] == "5") {
556
+ $header['size'] = 0;
557
+ }
558
+
559
+ $checksum = 0;
560
+ $headerBlock = substr_replace($headerBlock, ' ', 148, 8);
561
+
562
+ for ($i = 0; $i < 512; $i++) {
563
+ $checksum += ord(substr($headerBlock, $i, 1));
564
+ }
565
+
566
+ $checksumOk = $header['checksum'] == $checksum;
567
+ if (isset($header['name']) && $checksumOk) {
568
+
569
+ if (!($header['name'] == '././@LongLink' && $header['type'] == 'L')) {
570
+ $header['name'] = trim($header['name']);
571
+ return $header;
572
+ }
573
+
574
+ $realNameBlockSize = floor(($header['size'] + self::TAR_BLOCK_SIZE - 1) / self::TAR_BLOCK_SIZE)
575
+ * self::TAR_BLOCK_SIZE;
576
+ $realNameBlock = $archiveReader->read($realNameBlockSize);
577
+ $realName = substr($realNameBlock, 0, $header['size']);
578
+
579
+ $headerMain = $this->_extractFileHeader();
580
+ $headerMain['name'] = trim($realName);
581
+ return $headerMain;
582
+ }
583
+
584
+ return false;
585
+ }
586
+
587
+ /**
588
+ * Extract next file from tarball by its $header information and save it to $destination
589
+ *
590
+ * @param array $fileHeader
591
+ * @param string $destination
592
+ */
593
+ protected function _extractAndWriteFile($fileHeader, $destination)
594
+ {
595
+ $fileWriter = new Mage_Archive_Helper_File($destination);
596
+ $fileWriter->open('w', $fileHeader['mode']);
597
+
598
+ $archiveReader = $this->_getReader();
599
+
600
+ $filesize = $fileHeader['size'];
601
+ $bytesExtracted = 0;
602
+
603
+ while ($filesize > $bytesExtracted && !$archiveReader->eof()) {
604
+ $block = $archiveReader->read(self::TAR_BLOCK_SIZE);
605
+ $nonExtractedBytesCount = $filesize - $bytesExtracted;
606
+
607
+ $data = substr($block, 0, $nonExtractedBytesCount);
608
+ $fileWriter->write($data);
609
+
610
+ $bytesExtracted += strlen($block);
611
+ }
612
+ }
613
+
614
+ /**
615
+ * Pack file to TAR (Tape Archiver).
616
+ *
617
+ * @param string $source
618
+ * @param string $destination
619
+ * @param boolean $skipRoot
620
+ * @return string
621
+ */
622
+ public function pack($source, $destination, $skipRoot = false)
623
+ {
624
+ $this->_setSkipRoot($skipRoot);
625
+ $source = realpath($source);
626
+ $tarData = $this->_setCurrentPath($source)
627
+ ->_setDestinationFilePath($destination)
628
+ ->_setCurrentFile($source);
629
+
630
+ $this->_initWriter();
631
+ $this->_createTar($skipRoot, true);
632
+ $this->_destroyWriter();
633
+
634
+ return $destination;
635
+ }
636
+
637
+ /**
638
+ * Unpack file from TAR (Tape Archiver).
639
+ *
640
+ * @param string $source
641
+ * @param string $destination
642
+ * @return string
643
+ */
644
+ public function unpack($source, $destination)
645
+ {
646
+ $this->_setCurrentFile($source)
647
+ ->_setCurrentPath($source);
648
+
649
+ $this->_initReader();
650
+ $this->_unpackCurrentTar($destination);
651
+ $this->_destroyReader();
652
+
653
+ return $destination;
654
+ }
655
+
656
+ /**
657
+ * Extract one file from TAR (Tape Archiver).
658
+ *
659
+ * @param string $file
660
+ * @param string $source
661
+ * @param string $destination
662
+ * @return string
663
+ */
664
+ public function extract($file, $source, $destination)
665
+ {
666
+ $this->_setCurrentFile($source);
667
+ $this->_initReader();
668
+
669
+ $archiveReader = $this->_getReader();
670
+ $extractedFile = '';
671
+
672
+ while (!$archiveReader->eof()) {
673
+ $header = $this->_extractFileHeader();
674
+ if ($header['name'] == $file) {
675
+ $extractedFile = $destination . basename($header['name']);
676
+ $this->_extractAndWriteFile($header, $extractedFile);
677
+ break;
678
+ }
679
+
680
+ if ($header['type'] != 5){
681
+ $skipBytes = floor(($header['size'] + self::TAR_BLOCK_SIZE - 1) / self::TAR_BLOCK_SIZE)
682
+ * self::TAR_BLOCK_SIZE;
683
+ $archiveReader->read($skipBytes);
684
+ }
685
+ }
686
+
687
+ $this->_destroyReader();
688
+ return $extractedFile;
689
+ }
690
+ }
app/code/local/Mss/downloader/lib/Mage/Autoload/Simple.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Autoload
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ class Mage_Autoload_Simple
28
+ {
29
+ private static $_instance;
30
+
31
+ public static function instance()
32
+ {
33
+ if (!self::$_instance) {
34
+ $class = __CLASS__;
35
+ self::$_instance = new $class();
36
+ }
37
+ return self::$_instance;
38
+ }
39
+
40
+ public static function register()
41
+ {
42
+ spl_autoload_register(array(self::instance(), 'autoload'));
43
+ }
44
+
45
+ public function autoload($class)
46
+ {
47
+ $classFile = str_replace(' ', DIRECTORY_SEPARATOR, ucwords(str_replace('_', ' ', $class)));
48
+ $classFile.= '.php';
49
+ include_once($classFile);
50
+ }
51
+
52
+ }
app/code/local/Mss/downloader/lib/Mage/Backup.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup
35
+ {
36
+ /**
37
+ * List of supported a backup types
38
+ *
39
+ * @var array
40
+ */
41
+ static protected $_allowedBackupTypes = array('db', 'snapshot', 'filesystem', 'media', 'nomedia');
42
+
43
+ /**
44
+ * get Backup Instance By File Name
45
+ *
46
+ * @param string $type
47
+ * @return Mage_Backup_Interface
48
+ */
49
+ static public function getBackupInstance($type)
50
+ {
51
+ $class = 'Mage_Backup_' . ucfirst($type);
52
+
53
+ if (!in_array($type, self::$_allowedBackupTypes) || !class_exists($class, true)){
54
+ throw new Mage_Exception('Current implementation not supported this type (' . $type . ') of backup.');
55
+ }
56
+
57
+ return new $class();
58
+ }
59
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Abstract.php ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ abstract class Mage_Backup_Abstract implements Mage_Backup_Interface
35
+ {
36
+ /**
37
+ * Backup name
38
+ *
39
+ * @var string
40
+ */
41
+ protected $_name;
42
+
43
+ /**
44
+ * Backup creation date
45
+ *
46
+ * @var int
47
+ */
48
+ protected $_time;
49
+
50
+ /**
51
+ * Backup file extension
52
+ *
53
+ * @var string
54
+ */
55
+ protected $_backupExtension;
56
+
57
+ /**
58
+ * Resource model
59
+ *
60
+ * @var object
61
+ */
62
+ protected $_resourceModel;
63
+
64
+ /**
65
+ * Magento's root directory
66
+ *
67
+ * @var string
68
+ */
69
+ protected $_rootDir;
70
+
71
+ /**
72
+ * Path to directory where backups stored
73
+ *
74
+ * @var string
75
+ */
76
+ protected $_backupsDir;
77
+
78
+ /**
79
+ * Is last operation completed successfully
80
+ *
81
+ * @var bool
82
+ */
83
+ protected $_lastOperationSucceed = false;
84
+
85
+ /**
86
+ * Last failed operation error message
87
+ *
88
+ * @var string
89
+ */
90
+ protected $_lastErrorMessage;
91
+
92
+
93
+ /**
94
+ * Set Backup Extension
95
+ *
96
+ * @param string $backupExtension
97
+ * @return Mage_Backup_Interface
98
+ */
99
+ public function setBackupExtension($backupExtension)
100
+ {
101
+ $this->_backupExtension = $backupExtension;
102
+ return $this;
103
+ }
104
+
105
+ /**
106
+ * Get Backup Extension
107
+ *
108
+ * @return string
109
+ */
110
+ public function getBackupExtension()
111
+ {
112
+ return $this->_backupExtension;
113
+ }
114
+
115
+ /**
116
+ * Set Resource Model
117
+ *
118
+ * @param object $resourceModel
119
+ * @return Mage_Backup_Interface
120
+ */
121
+ public function setResourceModel($resourceModel)
122
+ {
123
+ $this->_resourceModel = $resourceModel;
124
+ return $this;
125
+ }
126
+
127
+ /**
128
+ * Get Resource Model
129
+ *
130
+ * @return object
131
+ */
132
+ public function getResourceModel()
133
+ {
134
+ return $this->_resourceModel;
135
+ }
136
+
137
+ /**
138
+ * Set Time
139
+ *
140
+ * @param int $time
141
+ * @return Mage_Backup_Interface
142
+ */
143
+ public function setTime($time)
144
+ {
145
+ $this->_time = $time;
146
+ return $this;
147
+ }
148
+
149
+ /**
150
+ * Get Time
151
+ *
152
+ * @return int
153
+ */
154
+ public function getTime()
155
+ {
156
+ return $this->_time;
157
+ }
158
+
159
+ /**
160
+ * Set root directory of Magento installation
161
+ *
162
+ * @param string $rootDir
163
+ * @throws Mage_Exception
164
+ * @return Mage_Backup_Interface
165
+ */
166
+ public function setRootDir($rootDir)
167
+ {
168
+ if (!is_dir($rootDir)) {
169
+ throw new Mage_Exception('Bad root directory');
170
+ }
171
+
172
+ $this->_rootDir = $rootDir;
173
+ return $this;
174
+ }
175
+
176
+ /**
177
+ * Get Magento's root directory
178
+ * @return string
179
+ */
180
+ public function getRootDir()
181
+ {
182
+ return $this->_rootDir;
183
+ }
184
+
185
+ /**
186
+ * Set path to directory where backups stored
187
+ *
188
+ * @param string $backupsDir
189
+ * @return Mage_Backup_Interface
190
+ */
191
+ public function setBackupsDir($backupsDir)
192
+ {
193
+ $this->_backupsDir = $backupsDir;
194
+ return $this;
195
+ }
196
+
197
+ /**
198
+ * Get path to directory where backups stored
199
+ *
200
+ * @return string
201
+ */
202
+ public function getBackupsDir()
203
+ {
204
+ return $this->_backupsDir;
205
+ }
206
+
207
+ /**
208
+ * Get path to backup
209
+ *
210
+ * @return string
211
+ */
212
+ public function getBackupPath()
213
+ {
214
+ return $this->getBackupsDir() . DS . $this->getBackupFilename();
215
+ }
216
+
217
+ /**
218
+ * Get backup file name
219
+ *
220
+ * @return string
221
+ */
222
+ public function getBackupFilename()
223
+ {
224
+ $filename = $this->getTime() . '_' . $this->getType();
225
+
226
+ $name = $this->getName();
227
+
228
+ if (!empty($name)) {
229
+ $filename .= '_' . $name;
230
+ }
231
+
232
+ $filename .= '.' . $this->getBackupExtension();
233
+
234
+ return $filename;
235
+ }
236
+
237
+ /**
238
+ * Check whether last operation completed successfully
239
+ *
240
+ * @return bool
241
+ */
242
+ public function getIsSuccess()
243
+ {
244
+ return $this->_lastOperationSucceed;
245
+ }
246
+
247
+ /**
248
+ * Get last error message
249
+ *
250
+ * @return string
251
+ */
252
+ public function getErrorMessage()
253
+ {
254
+ return $this->_lastErrorMessage;
255
+ }
256
+
257
+ /**
258
+ * Set error message
259
+ *
260
+ * @param string $errorMessage
261
+ * @return string
262
+ */
263
+ public function setErrorMessage($errorMessage)
264
+ {
265
+ $this->_lastErrorMessage = $errorMessage;
266
+ }
267
+
268
+ /**
269
+ * Set backup name
270
+ *
271
+ * @param string $name
272
+ * @param bool $applyFilter
273
+ * @return Mage_Backup_Interface
274
+ */
275
+ public function setName($name, $applyFilter = true)
276
+ {
277
+ if ($applyFilter) {
278
+ $name = $this->_filterName($name);
279
+ }
280
+ $this->_name = $name;
281
+ return $this;
282
+ }
283
+
284
+ /**
285
+ * Get backup name
286
+ *
287
+ * @return string
288
+ */
289
+ public function getName()
290
+ {
291
+ return $this->_name;
292
+ }
293
+
294
+ /**
295
+ * Get backup display name
296
+ *
297
+ * @return string
298
+ */
299
+ public function getDisplayName()
300
+ {
301
+ return str_replace('_', ' ', $this->_name);
302
+ }
303
+
304
+ /**
305
+ * Removes disallowed characters and replaces spaces with underscores
306
+ *
307
+ * @param string $name
308
+ * @return string
309
+ */
310
+ protected function _filterName($name)
311
+ {
312
+ $name = trim(preg_replace('/[^\da-zA-Z ]/', '', $name));
313
+ $name = preg_replace('/\s{2,}/', ' ', $name);
314
+ $name = str_replace(' ', '_', $name);
315
+
316
+ return $name;
317
+ }
318
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Archive/Tar.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Extended version of Mage_Archive_Tar that supports filtering
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Archive_Tar extends Mage_Archive_Tar
35
+ {
36
+ /**
37
+ * Filenames or filename parts that are used for filtering files
38
+ *
39
+ * @var array()
40
+ */
41
+ protected $_skipFiles = array();
42
+
43
+ /**
44
+ * Overridden Mage_Archive_Tar::_createTar method that does the same actions as it's parent but filters
45
+ * files using Mage_Backup_Filesystem_Iterator_Filter
46
+ *
47
+ * @see Mage_Archive_Tar::_createTar()
48
+ * @param bool $skipRoot
49
+ * @param bool $finalize
50
+ */
51
+ protected function _createTar($skipRoot = false, $finalize = false)
52
+ {
53
+ $path = $this->_getCurrentFile();
54
+
55
+ $filesystemIterator = new RecursiveIteratorIterator(
56
+ new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST
57
+ );
58
+
59
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $this->_skipFiles);
60
+
61
+ foreach ($iterator as $item) {
62
+ $this->_setCurrentFile($item->getPathname());
63
+ $this->_packAndWriteCurrentFile();
64
+ }
65
+
66
+ if ($finalize) {
67
+ $this->_getWriter()->write(str_repeat("\0", self::TAR_BLOCK_SIZE * 12));
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Set files that shouldn't be added to tarball
73
+ *
74
+ * @param array $skipFiles
75
+ * @return Mage_Backup_Archive_Tar
76
+ */
77
+ public function setSkipFiles(array $skipFiles)
78
+ {
79
+ $this->_skipFiles = $skipFiles;
80
+ return $this;
81
+ }
82
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Db.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with database backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Db extends Mage_Backup_Abstract
35
+ {
36
+ /**
37
+ * Implements Rollback functionality for Db
38
+ *
39
+ * @return bool
40
+ */
41
+ public function rollback()
42
+ {
43
+ set_time_limit(0);
44
+ ignore_user_abort(true);
45
+
46
+ $this->_lastOperationSucceed = false;
47
+
48
+ $archiveManager = new Mage_Archive();
49
+ $source = $archiveManager->unpack($this->getBackupPath(), $this->getBackupsDir());
50
+
51
+ $file = new Mage_Backup_Filesystem_Iterator_File($source);
52
+ foreach ($file as $statement) {
53
+ $this->getResourceModel()->runCommand($statement);
54
+ }
55
+ @unlink($source);
56
+
57
+ $this->_lastOperationSucceed = true;
58
+
59
+ return true;
60
+ }
61
+
62
+ /**
63
+ * Checks whether the line is last in sql command
64
+ *
65
+ * @param $line
66
+ * @return bool
67
+ */
68
+ protected function _isLineLastInCommand($line)
69
+ {
70
+ $cleanLine = trim($line);
71
+ $lineLength = strlen($cleanLine);
72
+
73
+ $returnResult = false;
74
+ if ($lineLength > 0){
75
+ $lastSymbolIndex = $lineLength-1;
76
+ if ($cleanLine[$lastSymbolIndex] == ';'){
77
+ $returnResult = true;
78
+ }
79
+ }
80
+
81
+ return $returnResult;
82
+ }
83
+
84
+ /**
85
+ * Implements Create Backup functionality for Db
86
+ *
87
+ * @return bool
88
+ */
89
+ public function create()
90
+ {
91
+ set_time_limit(0);
92
+ ignore_user_abort(true);
93
+
94
+ $this->_lastOperationSucceed = false;
95
+
96
+ $backup = Mage::getModel('backup/backup')
97
+ ->setTime($this->getTime())
98
+ ->setType($this->getType())
99
+ ->setPath($this->getBackupsDir())
100
+ ->setName($this->getName());
101
+
102
+ $backupDb = Mage::getModel('backup/db');
103
+ $backupDb->createBackup($backup);
104
+
105
+ $this->_lastOperationSucceed = true;
106
+
107
+ return true;
108
+ }
109
+
110
+ /**
111
+ * Get Backup Type
112
+ *
113
+ * @return string
114
+ */
115
+ public function getType()
116
+ {
117
+ return 'db';
118
+ }
119
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Exception.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception extends Mage_Exception
35
+ {
36
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Exception/CantLoadSnapshot.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_CantLoadSnapshot extends Mage_Backup_Exception
35
+ {
36
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Exception/FtpConnectionFailed.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_FtpConnectionFailed extends Mage_Backup_Exception
35
+ {
36
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Exception/FtpValidationFailed.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_FtpValidationFailed extends Mage_Backup_Exception
35
+ {
36
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Exception/NotEnoughFreeSpace.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_NotEnoughFreeSpace extends Mage_Backup_Exception
35
+ {
36
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Exception/NotEnoughPermissions.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Exception_NotEnoughPermissions extends Mage_Backup_Exception
35
+ {
36
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem.php ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with filesystem backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem extends Mage_Backup_Abstract
35
+ {
36
+ /**
37
+ * Paths that ignored when creating or rolling back snapshot
38
+ *
39
+ * @var array
40
+ */
41
+ protected $_ignorePaths = array();
42
+
43
+ /**
44
+ * Whether use ftp account for rollback procedure
45
+ *
46
+ * @var bool
47
+ */
48
+ protected $_useFtp = false;
49
+
50
+ /**
51
+ * Ftp host
52
+ *
53
+ * @var string
54
+ */
55
+ protected $_ftpHost;
56
+
57
+ /**
58
+ * Ftp username
59
+ *
60
+ * @var string
61
+ */
62
+ protected $_ftpUser;
63
+
64
+ /**
65
+ * Password to ftp account
66
+ *
67
+ * @var string
68
+ */
69
+ protected $_ftpPass;
70
+
71
+ /**
72
+ * Ftp path to Magento installation
73
+ *
74
+ * @var string
75
+ */
76
+ protected $_ftpPath;
77
+
78
+ /**
79
+ * Implementation Rollback functionality for Filesystem
80
+ *
81
+ * @throws Mage_Exception
82
+ * @return bool
83
+ */
84
+ public function rollback()
85
+ {
86
+ $this->_lastOperationSucceed = false;
87
+
88
+ set_time_limit(0);
89
+ ignore_user_abort(true);
90
+
91
+ $rollbackWorker = $this->_useFtp ? new Mage_Backup_Filesystem_Rollback_Ftp($this)
92
+ : new Mage_Backup_Filesystem_Rollback_Fs($this);
93
+ $rollbackWorker->run();
94
+
95
+ $this->_lastOperationSucceed = true;
96
+ }
97
+
98
+ /**
99
+ * Implementation Create Backup functionality for Filesystem
100
+ *
101
+ * @throws Mage_Exception
102
+ * @return boolean
103
+ */
104
+ public function create()
105
+ {
106
+ set_time_limit(0);
107
+ ignore_user_abort(true);
108
+
109
+ $this->_lastOperationSucceed = false;
110
+
111
+ $this->_checkBackupsDir();
112
+
113
+ $fsHelper = new Mage_Backup_Filesystem_Helper();
114
+
115
+ $filesInfo = $fsHelper->getInfo(
116
+ $this->getRootDir(),
117
+ Mage_Backup_Filesystem_Helper::INFO_READABLE | Mage_Backup_Filesystem_Helper::INFO_SIZE,
118
+ $this->getIgnorePaths()
119
+ );
120
+
121
+ if (!$filesInfo['readable']) {
122
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Not enough permissions to read files for backup');
123
+ }
124
+
125
+ $freeSpace = disk_free_space($this->getBackupsDir());
126
+
127
+ if (2 * $filesInfo['size'] > $freeSpace) {
128
+ throw new Mage_Backup_Exception_NotEnoughFreeSpace('Not enough free space to create backup');
129
+ }
130
+
131
+ $tarTmpPath = $this->_getTarTmpPath();
132
+
133
+ $tarPacker = new Mage_Backup_Archive_Tar();
134
+ $tarPacker->setSkipFiles($this->getIgnorePaths())
135
+ ->pack($this->getRootDir(), $tarTmpPath, true);
136
+
137
+ if (!is_file($tarTmpPath) || filesize($tarTmpPath) == 0) {
138
+ throw new Mage_Exception('Failed to create backup');
139
+ }
140
+
141
+ $backupPath = $this->getBackupPath();
142
+
143
+ $gzPacker = new Mage_Archive_Gz();
144
+ $gzPacker->pack($tarTmpPath, $backupPath);
145
+
146
+ if (!is_file($backupPath) || filesize($backupPath) == 0) {
147
+ throw new Mage_Exception('Failed to create backup');
148
+ }
149
+
150
+ @unlink($tarTmpPath);
151
+
152
+ $this->_lastOperationSucceed = true;
153
+ }
154
+
155
+ /**
156
+ * Force class to use ftp for rollback procedure
157
+ *
158
+ * @param string $host
159
+ * @param string $username
160
+ * @param string $password
161
+ * @param string $path
162
+ * @return Mage_Backup_Filesystem
163
+ */
164
+ public function setUseFtp($host, $username, $password, $path)
165
+ {
166
+ $this->_useFtp = true;
167
+ $this->_ftpHost = $host;
168
+ $this->_ftpUser = $username;
169
+ $this->_ftpPass = $password;
170
+ $this->_ftpPath = $path;
171
+ return $this;
172
+ }
173
+
174
+ /**
175
+ * Get backup type
176
+ *
177
+ * @see Mage_Backup_Interface::getType()
178
+ * @return string
179
+ */
180
+ public function getType()
181
+ {
182
+ return 'filesystem';
183
+ }
184
+
185
+ /**
186
+ * Add path that should be ignoring when creating or rolling back backup
187
+ *
188
+ * @param string|array $paths
189
+ * @return Mage_Backup_Filesystem
190
+ */
191
+ public function addIgnorePaths($paths)
192
+ {
193
+ if (is_string($paths)) {
194
+ if (!in_array($paths, $this->_ignorePaths)) {
195
+ $this->_ignorePaths[] = $paths;
196
+ }
197
+ }
198
+ else if (is_array($paths)) {
199
+ foreach ($paths as $path) {
200
+ $this->addIgnorePaths($path);
201
+ }
202
+ }
203
+
204
+ return $this;
205
+ }
206
+
207
+ /**
208
+ * Get paths that should be ignored while creating or rolling back backup procedure
209
+ *
210
+ * @return array
211
+ */
212
+ public function getIgnorePaths()
213
+ {
214
+ return $this->_ignorePaths;
215
+ }
216
+
217
+ /**
218
+ * Set directory where backups saved and add it to ignore paths
219
+ *
220
+ * @see Mage_Backup_Abstract::setBackupsDir()
221
+ * @param string $backupsDir
222
+ * @return Mage_Backup_Filesystem
223
+ */
224
+ public function setBackupsDir($backupsDir)
225
+ {
226
+ parent::setBackupsDir($backupsDir);
227
+ $this->addIgnorePaths($backupsDir);
228
+ return $this;
229
+ }
230
+
231
+ /**
232
+ * getter for $_ftpPath variable
233
+ *
234
+ * @return string
235
+ */
236
+ public function getFtpPath()
237
+ {
238
+ return $this->_ftpPath;
239
+ }
240
+
241
+ /**
242
+ * Get ftp connection string
243
+ *
244
+ * @return string
245
+ */
246
+ public function getFtpConnectString()
247
+ {
248
+ return 'ftp://' . $this->_ftpUser . ':' . $this->_ftpPass . '@' . $this->_ftpHost . $this->_ftpPath;
249
+ }
250
+
251
+ /**
252
+ * Check backups directory existance and whether it's writeable
253
+ *
254
+ * @throws Mage_Exception
255
+ */
256
+ protected function _checkBackupsDir()
257
+ {
258
+ $backupsDir = $this->getBackupsDir();
259
+
260
+ if (!is_dir($backupsDir)) {
261
+ $backupsDirParentDirectory = basename($backupsDir);
262
+
263
+ if (!is_writeable($backupsDirParentDirectory)) {
264
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Cant create backups directory');
265
+ }
266
+
267
+ mkdir($backupsDir);
268
+ chmod($backupsDir, 0777);
269
+ }
270
+
271
+ if (!is_writable($backupsDir)) {
272
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Backups directory is not writeable');
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Generate tmp name for tarball
278
+ */
279
+ protected function _getTarTmpPath()
280
+ {
281
+ $tmpName = '~tmp-'. microtime(true) . '.tar';
282
+ return $this->getBackupsDir() . DS . $tmpName;
283
+ }
284
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Helper.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Filesystem helper for Mage_Backup library
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem_Helper
35
+ {
36
+ /**
37
+ * Constant can be used in getInfo() function as second parameter.
38
+ * Check whether directory and all files/sub directories are writable
39
+ *
40
+ * @const int
41
+ */
42
+ const INFO_WRITABLE = 1;
43
+
44
+ /**
45
+ * Constant can be used in getInfo() function as second parameter.
46
+ * Check whether directory and all files/sub directories are readable
47
+ *
48
+ * @const int
49
+ */
50
+ const INFO_READABLE = 2;
51
+
52
+ /**
53
+ * Constant can be used in getInfo() function as second parameter.
54
+ * Get directory size
55
+ *
56
+ * @const int
57
+ */
58
+ const INFO_SIZE = 4;
59
+
60
+ /**
61
+ * Constant can be used in getInfo() function as second parameter.
62
+ * Combination of INFO_WRITABLE, INFO_READABLE, INFO_SIZE
63
+ *
64
+ * @const int
65
+ */
66
+ const INFO_ALL = 7;
67
+
68
+ /**
69
+ * Recursively delete $path
70
+ *
71
+ * @param string $path
72
+ * @param array $skipPaths
73
+ * @param bool $removeRoot
74
+ * @throws Mage_Exception
75
+ */
76
+ public function rm($path, $skipPaths = array(), $removeRoot = false)
77
+ {
78
+ $filesystemIterator = new RecursiveIteratorIterator(
79
+ new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::CHILD_FIRST
80
+ );
81
+
82
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $skipPaths);
83
+
84
+ foreach ($iterator as $item) {
85
+ $item->isDir() ? @rmdir($item->__toString()) : @unlink($item->__toString());
86
+ }
87
+
88
+ if ($removeRoot && is_dir($path)) {
89
+ @rmdir($path);
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Get information (readable, writable, size) about $path
95
+ *
96
+ * @param string $path
97
+ * @param int $infoOptions
98
+ * @param array $skipFiles
99
+ */
100
+ public function getInfo($path, $infoOptions = self::INFO_ALL, $skipFiles = array())
101
+ {
102
+ $info = array();
103
+ if ($infoOptions & self::INFO_READABLE) {
104
+ $info['readable'] = true;
105
+ }
106
+
107
+ if ($infoOptions & self::INFO_WRITABLE) {
108
+ $info['writable'] = true;
109
+ }
110
+
111
+ if ($infoOptions & self::INFO_SIZE) {
112
+ $info['size'] = 0;
113
+ }
114
+
115
+ $filesystemIterator = new RecursiveIteratorIterator(
116
+ new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::CHILD_FIRST
117
+ );
118
+
119
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $skipFiles);
120
+
121
+ foreach ($iterator as $item) {
122
+ if (($infoOptions & self::INFO_WRITABLE) && !$item->isWritable()) {
123
+ $info['writable'] = false;
124
+ }
125
+
126
+ if (($infoOptions & self::INFO_READABLE) && !$item->isReadable()) {
127
+ $info['readable'] = false;
128
+ }
129
+
130
+ if ($infoOptions & self::INFO_SIZE && !$item->isDir()) {
131
+ $info['size'] += $item->getSize();
132
+ }
133
+ }
134
+
135
+ return $info;
136
+ }
137
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Iterator/File.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ /**
29
+ * File lines iterator
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Backup
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class Mage_Backup_Filesystem_Iterator_File extends SplFileObject
36
+ {
37
+ /**
38
+ * The statement that was last read during iteration
39
+ *
40
+ * @var string
41
+ */
42
+ protected $_currentStatement = '';
43
+
44
+ /**
45
+ * Return current sql statement
46
+ *
47
+ * @return string
48
+ */
49
+ public function current()
50
+ {
51
+ return $this->_currentStatement;
52
+ }
53
+
54
+ /**
55
+ * Iterate to next sql statement in file
56
+ */
57
+ public function next()
58
+ {
59
+ $this->_currentStatement = '';
60
+ while (!$this->eof()) {
61
+ $line = $this->fgets();
62
+ if (strlen(trim($line))) {
63
+ $this->_currentStatement .= $line;
64
+ if ($this->_isLineLastInCommand($line)) {
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Return to first statement
73
+ */
74
+ public function rewind()
75
+ {
76
+ parent::rewind();
77
+ $this->next();
78
+ }
79
+
80
+ /**
81
+ * Check whether provided string is comment
82
+ *
83
+ * @param string $line
84
+ * @return bool
85
+ */
86
+ protected function _isComment($line)
87
+ {
88
+ return $line[0] == '#' || substr($line, 0, 2) == '--';
89
+ }
90
+
91
+ /**
92
+ * Check is line a last in sql command
93
+ *
94
+ * @param string $line
95
+ * @return bool
96
+ */
97
+ protected function _isLineLastInCommand($line)
98
+ {
99
+ $cleanLine = trim($line);
100
+ $lineLength = strlen($cleanLine);
101
+
102
+ $returnResult = false;
103
+ if ($lineLength > 0) {
104
+ $lastSymbolIndex = $lineLength - 1;
105
+ if ($cleanLine[$lastSymbolIndex] == ';') {
106
+ $returnResult = true;
107
+ }
108
+ }
109
+
110
+ return $returnResult;
111
+ }
112
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Iterator/Filter.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Filter Iterator
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem_Iterator_Filter extends FilterIterator
35
+ {
36
+ /**
37
+ * Array that is used for filtering
38
+ *
39
+ * @var array
40
+ */
41
+ protected $_filters;
42
+
43
+ /**
44
+ * Constructor
45
+ *
46
+ * @param Iterator $iterator
47
+ * @param array $filters list of files to skip
48
+ */
49
+ public function __construct(Iterator $iterator, array $filters)
50
+ {
51
+ parent::__construct($iterator);
52
+ $this->_filters = $filters;
53
+ }
54
+
55
+ /**
56
+ * Check whether the current element of the iterator is acceptable
57
+ *
58
+ * @return bool
59
+ */
60
+ public function accept()
61
+ {
62
+ $current = $this->current()->__toString();
63
+ $currentFilename = $this->current()->getFilename();
64
+
65
+ if ($currentFilename == '.' || $currentFilename == '..') {
66
+ return false;
67
+ }
68
+
69
+ foreach ($this->_filters as $filter) {
70
+ if (false !== strpos($current, $filter)) {
71
+ return false;
72
+ }
73
+ }
74
+
75
+ return true;
76
+ }
77
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Rollback/Abstract.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Filesystem rollback workers abstract class
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ abstract class Mage_Backup_Filesystem_Rollback_Abstract
35
+ {
36
+ /**
37
+ * Snapshot object
38
+ *
39
+ * @var Mage_Backup_Filesystem
40
+ */
41
+ protected $_snapshot;
42
+
43
+ /**
44
+ * Default worker constructor
45
+ *
46
+ * @param Mage_Backup_Filesystem $snapshotObject
47
+ */
48
+ public function __construct(Mage_Backup_Filesystem $snapshotObject)
49
+ {
50
+ $this->_snapshot = $snapshotObject;
51
+ }
52
+
53
+ /**
54
+ * Main worker's function that makes files rollback
55
+ */
56
+ abstract public function run();
57
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Rollback/Fs.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Rollback worker for rolling back via local filesystem
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem_Rollback_Fs extends Mage_Backup_Filesystem_Rollback_Abstract
35
+ {
36
+ /**
37
+ * Files rollback implementation via local filesystem
38
+ *
39
+ * @see Mage_Backup_Filesystem_Rollback_Abstract::run()
40
+ * @throws Mage_Exception
41
+ */
42
+ public function run()
43
+ {
44
+ $snapshotPath = $this->_snapshot->getBackupPath();
45
+
46
+ if (!is_file($snapshotPath) || !is_readable($snapshotPath)) {
47
+ throw new Mage_Backup_Exception_CantLoadSnapshot('Cant load snapshot archive');
48
+ }
49
+
50
+ $fsHelper = new Mage_Backup_Filesystem_Helper();
51
+
52
+ $filesInfo = $fsHelper->getInfo(
53
+ $this->_snapshot->getRootDir(),
54
+ Mage_Backup_Filesystem_Helper::INFO_WRITABLE,
55
+ $this->_snapshot->getIgnorePaths()
56
+ );
57
+
58
+ if (!$filesInfo['writable']) {
59
+ throw new Mage_Backup_Exception_NotEnoughPermissions(
60
+ 'Unable to make rollback because not all files are writable'
61
+ );
62
+ }
63
+
64
+ $archiver = new Mage_Archive();
65
+
66
+ /**
67
+ * we need these fake initializations because all magento's files in filesystem will be deleted and autoloader
68
+ * wont be able to load classes that we need for unpacking
69
+ */
70
+ new Mage_Archive_Tar();
71
+ new Mage_Archive_Gz();
72
+ new Mage_Archive_Helper_File('');
73
+ new Mage_Archive_Helper_File_Gz('');
74
+
75
+ $fsHelper->rm($this->_snapshot->getRootDir(), $this->_snapshot->getIgnorePaths());
76
+ $archiver->unpack($snapshotPath, $this->_snapshot->getRootDir());
77
+ }
78
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Filesystem/Rollback/Ftp.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Rollback worker for rolling back via ftp
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Filesystem_Rollback_Ftp extends Mage_Backup_Filesystem_Rollback_Abstract
35
+ {
36
+ /**
37
+ * Ftp client
38
+ *
39
+ * @var Mage_System_Ftp
40
+ */
41
+ protected $_ftpClient;
42
+
43
+ /**
44
+ * Files rollback implementation via ftp
45
+ *
46
+ * @see Mage_Backup_Filesystem_Rollback_Abstract::run()
47
+ * @throws Mage_Exception
48
+ */
49
+ public function run()
50
+ {
51
+ $snapshotPath = $this->_snapshot->getBackupPath();
52
+
53
+ if (!is_file($snapshotPath) || !is_readable($snapshotPath)) {
54
+ throw new Mage_Backup_Exception_CantLoadSnapshot('Cant load snapshot archive');
55
+ }
56
+
57
+ $this->_initFtpClient();
58
+ $this->_validateFtp();
59
+
60
+ $tmpDir = $this->_createTmpDir();
61
+ $this->_unpackSnapshot($tmpDir);
62
+
63
+ $fsHelper = new Mage_Backup_Filesystem_Helper();
64
+
65
+ $this->_cleanupFtp();
66
+ $this->_uploadBackupToFtp($tmpDir);
67
+
68
+ $fsHelper->rm($tmpDir, array(), true);
69
+ }
70
+
71
+ /**
72
+ * Initialize ftp client and connect to ftp
73
+ *
74
+ * @throws Mage_Backup_Exception_FtpConnectionFailed
75
+ */
76
+ protected function _initFtpClient()
77
+ {
78
+ try {
79
+ $this->_ftpClient = new Mage_System_Ftp();
80
+ $this->_ftpClient->connect($this->_snapshot->getFtpConnectString());
81
+ } catch (Exception $e) {
82
+ throw new Mage_Backup_Exception_FtpConnectionFailed($e->getMessage());
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Perform ftp validation. Check whether ftp account provided points to current magento installation
88
+ *
89
+ * @throws Mage_Exception
90
+ */
91
+ protected function _validateFtp()
92
+ {
93
+ $validationFilename = '~validation-' . microtime(true) . '.tmp';
94
+ $validationFilePath = $this->_snapshot->getBackupsDir() . DS . $validationFilename;
95
+
96
+ $fh = @fopen($validationFilePath, 'w');
97
+ @fclose($fh);
98
+
99
+ if (!is_file($validationFilePath)) {
100
+ throw new Mage_Exception('Unable to validate ftp account');
101
+ }
102
+
103
+ $rootDir = $this->_snapshot->getRootDir();
104
+ $ftpPath = $this->_snapshot->getFtpPath() . DS . str_replace($rootDir, '', $validationFilePath);
105
+
106
+ $fileExistsOnFtp = $this->_ftpClient->fileExists($ftpPath);
107
+ @unlink($validationFilePath);
108
+
109
+ if (!$fileExistsOnFtp) {
110
+ throw new Mage_Backup_Exception_FtpValidationFailed('Failed to validate ftp account');
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Unpack snapshot
116
+ *
117
+ * @param string $tmpDir
118
+ */
119
+ protected function _unpackSnapshot($tmpDir)
120
+ {
121
+ $snapshotPath = $this->_snapshot->getBackupPath();
122
+
123
+ $archiver = new Mage_Archive();
124
+ $archiver->unpack($snapshotPath, $tmpDir);
125
+ }
126
+
127
+ /**
128
+ * @throws Mage_Exception
129
+ * @return string
130
+ */
131
+ protected function _createTmpDir()
132
+ {
133
+ $tmpDir = $this->_snapshot->getBackupsDir() . DS . '~tmp-' . microtime(true);
134
+
135
+ $result = @mkdir($tmpDir);
136
+
137
+ if (false === $result) {
138
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Failed to create directory ' . $tmpDir);
139
+ }
140
+
141
+ return $tmpDir;
142
+ }
143
+
144
+ /**
145
+ * Delete magento and all files from ftp
146
+ */
147
+ protected function _cleanupFtp()
148
+ {
149
+ $rootDir = $this->_snapshot->getRootDir();
150
+
151
+ $filesystemIterator = new RecursiveIteratorIterator(
152
+ new RecursiveDirectoryIterator($rootDir), RecursiveIteratorIterator::CHILD_FIRST
153
+ );
154
+
155
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $this->_snapshot->getIgnorePaths());
156
+
157
+ foreach ($iterator as $item) {
158
+ $ftpPath = $this->_snapshot->getFtpPath() . DS . str_replace($rootDir, '', $item->__toString());
159
+ $ftpPath = str_replace(DS, '/', $ftpPath);
160
+
161
+ $this->_ftpClient->delete($ftpPath);
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Perform files rollback
167
+ *
168
+ * @param string $tmpDir
169
+ * @throws Mage_Exception
170
+ */
171
+ protected function _uploadBackupToFtp($tmpDir)
172
+ {
173
+ $filesystemIterator = new RecursiveIteratorIterator(
174
+ new RecursiveDirectoryIterator($tmpDir), RecursiveIteratorIterator::SELF_FIRST
175
+ );
176
+
177
+ $iterator = new Mage_Backup_Filesystem_Iterator_Filter($filesystemIterator, $this->_snapshot->getIgnorePaths());
178
+
179
+ foreach ($filesystemIterator as $item) {
180
+ $ftpPath = $this->_snapshot->getFtpPath() . DS . str_replace($tmpDir, '', $item->__toString());
181
+ $ftpPath = str_replace(DS, '/', $ftpPath);
182
+
183
+ if ($item->isDir()) {
184
+ $this->_ftpClient->mkdirRecursive($ftpPath);
185
+ } else {
186
+ $result = $this->_ftpClient->put($ftpPath, $item->__toString());
187
+ if (false === $result) {
188
+ throw new Mage_Backup_Exception_NotEnoughPermissions('Failed to upload file '
189
+ . $item->__toString() . ' to ftp');
190
+ }
191
+ }
192
+ }
193
+ }
194
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Interface.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Interface for work with archives
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ interface Mage_Backup_Interface
35
+ {
36
+ /**
37
+ * Create Backup
38
+ *
39
+ * @return boolean
40
+ */
41
+ public function create();
42
+
43
+ /**
44
+ * Rollback Backup
45
+ *
46
+ * @return boolean
47
+ */
48
+ public function rollback();
49
+
50
+ /**
51
+ * Set Backup Extension
52
+ *
53
+ * @param string $backupExtension
54
+ * @return Mage_Backup_Interface
55
+ */
56
+ public function setBackupExtension($backupExtension);
57
+
58
+ /**
59
+ * Set Resource Model
60
+ *
61
+ * @param object $resourceModel
62
+ * @return Mage_Backup_Interface
63
+ */
64
+ public function setResourceModel($resourceModel);
65
+
66
+ /**
67
+ * Set Time
68
+ *
69
+ * @param int $time
70
+ * @return Mage_Backup_Interface
71
+ */
72
+ public function setTime($time);
73
+
74
+ /**
75
+ * Get Backup Type
76
+ *
77
+ * @return string
78
+ */
79
+ public function getType();
80
+
81
+ /**
82
+ * Set path to directory where backups stored
83
+ *
84
+ * @param string $backupsDir
85
+ * @return Mage_Backup_Interface
86
+ */
87
+ public function setBackupsDir($backupsDir);
88
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Media.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work media folder and database backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Media extends Mage_Backup_Snapshot
35
+ {
36
+ /**
37
+ * Implementation Rollback functionality for Snapshot
38
+ *
39
+ * @throws Mage_Exception
40
+ * @return bool
41
+ */
42
+ public function rollback()
43
+ {
44
+ $this->_prepareIgnoreList();
45
+ return parent::rollback();
46
+ }
47
+
48
+ /**
49
+ * Implementation Create Backup functionality for Snapshot
50
+ *
51
+ * @throws Mage_Exception
52
+ * @return bool
53
+ */
54
+ public function create()
55
+ {
56
+ $this->_prepareIgnoreList();
57
+ return parent::create();
58
+ }
59
+
60
+ /**
61
+ * Overlap getType
62
+ *
63
+ * @return string
64
+ * @see Mage_Backup_Interface::getType()
65
+ */
66
+ public function getType()
67
+ {
68
+ return 'media';
69
+ }
70
+
71
+ /**
72
+ * Add all folders and files except media and db backup to ignore list
73
+ *
74
+ * @return Mage_Backup_Media
75
+ */
76
+ protected function _prepareIgnoreList()
77
+ {
78
+ $iterator = new DirectoryIterator($this->getRootDir());
79
+
80
+ foreach ($iterator as $item) {
81
+ $filename = $item->getFilename();
82
+ if (!in_array($filename, array('media', 'var'))) {
83
+ $this->addIgnorePaths($item->getPathname());
84
+ }
85
+ }
86
+
87
+ $iterator = new DirectoryIterator($this->getRootDir() . DS . 'var');
88
+ $dbBackupFilename = $this->_getDbBackupManager()->getBackupFilename();
89
+
90
+ foreach ($iterator as $item) {
91
+ $filename = $item->getFilename();
92
+ if ($filename != $dbBackupFilename) {
93
+ $this->addIgnorePaths($item->getPathname());
94
+ }
95
+ }
96
+
97
+ return $this;
98
+ }
99
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Nomedia.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work system backup that excludes media folder
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Nomedia extends Mage_Backup_Snapshot
35
+ {
36
+ /**
37
+ * Implementation Rollback functionality for Snapshot
38
+ *
39
+ * @throws Mage_Exception
40
+ * @return bool
41
+ */
42
+ public function rollback()
43
+ {
44
+ $this->_prepareIgnoreList();
45
+ return parent::rollback();
46
+ }
47
+
48
+ /**
49
+ * Implementation Create Backup functionality for Snapshot
50
+ *
51
+ * @throws Mage_Exception
52
+ * @return bool
53
+ */
54
+ public function create()
55
+ {
56
+ $this->_prepareIgnoreList();
57
+ return parent::create();
58
+ }
59
+
60
+ /**
61
+ * Overlap getType
62
+ *
63
+ * @return string
64
+ * @see Mage_Backup_Interface::getType()
65
+ */
66
+ public function getType()
67
+ {
68
+ return 'nomedia';
69
+ }
70
+
71
+ /**
72
+ * Add media folder to ignore list
73
+ *
74
+ * @return Mage_Backup_Media
75
+ */
76
+ protected function _prepareIgnoreList()
77
+ {
78
+ $this->addIgnorePaths($this->getRootDir() . DS . 'media');
79
+
80
+ return $this;
81
+ }
82
+ }
app/code/local/Mss/downloader/lib/Mage/Backup/Snapshot.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Backup
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with full filesystem and database backups
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Backup
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Backup_Snapshot extends Mage_Backup_Filesystem
35
+ {
36
+ /**
37
+ * Database backup manager
38
+ *
39
+ * @var Mage_Backup_Db
40
+ */
41
+ protected $_dbBackupManager;
42
+
43
+ /**
44
+ * Implementation Rollback functionality for Snapshot
45
+ *
46
+ * @throws Mage_Exception
47
+ * @return bool
48
+ */
49
+ public function rollback()
50
+ {
51
+ $result = parent::rollback();
52
+
53
+ $this->_lastOperationSucceed = false;
54
+
55
+ try {
56
+ $this->_getDbBackupManager()->rollback();
57
+ } catch (Exception $e) {
58
+ $this->_removeDbBackup();
59
+ throw $e;
60
+ }
61
+
62
+ $this->_removeDbBackup();
63
+ $this->_lastOperationSucceed = true;
64
+
65
+ return $result;
66
+ }
67
+
68
+ /**
69
+ * Implementation Create Backup functionality for Snapshot
70
+ *
71
+ * @throws Mage_Exception
72
+ * @return bool
73
+ */
74
+ public function create()
75
+ {
76
+ $this->_getDbBackupManager()->create();
77
+
78
+ try {
79
+ $result = parent::create();
80
+ } catch (Exception $e) {
81
+ $this->_removeDbBackup();
82
+ throw $e;
83
+ }
84
+
85
+ $this->_lastOperationSucceed = false;
86
+ $this->_removeDbBackup();
87
+ $this->_lastOperationSucceed = true;
88
+
89
+ return $result;
90
+ }
91
+
92
+ /**
93
+ * Overlap getType
94
+ *
95
+ * @return string
96
+ * @see Mage_Backup_Interface::getType()
97
+ */
98
+ public function getType()
99
+ {
100
+ return 'snapshot';
101
+ }
102
+
103
+ /**
104
+ * Create Db Instance
105
+ *
106
+ * @return Mage_Backup_Interface
107
+ */
108
+ protected function _createDbBackupInstance()
109
+ {
110
+ return Mage_Backup::getBackupInstance(Mage_Backup_Helper_Data::TYPE_DB)
111
+ ->setBackupExtension(Mage::helper('backup')->getExtensionByType(Mage_Backup_Helper_Data::TYPE_DB))
112
+ ->setTime($this->getTime())
113
+ ->setBackupsDir(Mage::getBaseDir("var"))
114
+ ->setResourceModel($this->getResourceModel());
115
+ }
116
+
117
+ /**
118
+ * Get database backup manager
119
+ *
120
+ * @return Mage_Backup_Db
121
+ */
122
+ protected function _getDbBackupManager()
123
+ {
124
+ if (is_null($this->_dbBackupManager)) {
125
+ $this->_dbBackupManager = $this->_createDbBackupInstance();
126
+ }
127
+
128
+ return $this->_dbBackupManager;
129
+ }
130
+
131
+ /**
132
+ * Remove Db backup after added it to the snapshot
133
+ *
134
+ * @return Mage_Backup_Snapshot
135
+ */
136
+ protected function _removeDbBackup(){
137
+ @unlink($this->_getDbBackupManager()->getBackupPath());
138
+ return $this;
139
+ }
140
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Backup.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to backup files before extension installation
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Backup
35
+ {
36
+ /**
37
+ * Prefix for backuped files
38
+ *
39
+ * @var string
40
+ */
41
+ protected $_prefix = '_backup_';
42
+
43
+ /**
44
+ * Array of available to overwrite type of files
45
+ *
46
+ * @var array
47
+ */
48
+ protected $_fileTypes = array();
49
+
50
+ /**
51
+ * List of files to backup files
52
+ *
53
+ * @var array
54
+ */
55
+ protected $_fileList = array();
56
+
57
+ /**
58
+ * Get available file types for backup
59
+ *
60
+ * @return array
61
+ */
62
+ public function getFileTypes()
63
+ {
64
+ return $this->_fileTypes;
65
+ }
66
+
67
+ /**
68
+ * Set available file types for backup
69
+ *
70
+ * @param array $types
71
+ */
72
+ public function setFileTypes(array $types)
73
+ {
74
+ foreach ($types as $type) {
75
+ $this->_fileTypes[] = $type;
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Add file to files list for backup
81
+ *
82
+ * @param string $file
83
+ * @param string $rootPath
84
+ * @return void
85
+ */
86
+ public function addFile($file, $rootPath)
87
+ {
88
+ $dest = $rootPath . DS . $file;
89
+ $type = $this->getFileType($file);
90
+ if (file_exists($dest) && in_array($type, $this->getFileTypes())) {
91
+ $this->_fileList[] = $file;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Get count of files
97
+ *
98
+ * @return int
99
+ */
100
+ public function getFilesCount()
101
+ {
102
+ return count($this->_fileList);
103
+ }
104
+
105
+ /**
106
+ * Clear list of files
107
+ *
108
+ * @return void
109
+ */
110
+ public function unsetAllFiles()
111
+ {
112
+ $this->_fileList = array();
113
+ }
114
+
115
+ /**
116
+ * Get list of files
117
+ *
118
+ * @return array
119
+ */
120
+ public function getAllFiles()
121
+ {
122
+ return $this->_fileList;
123
+ }
124
+
125
+ /**
126
+ * Run backup process
127
+ *
128
+ * @param boolean $cleanUpQueue
129
+ * @return void
130
+ */
131
+ public function run($cleanUpQueue = false)
132
+ {
133
+ if ($this->getFilesCount() > 0) {
134
+ $fileList = $this->getAllFiles();
135
+ foreach($fileList as $file) {
136
+ $this->_backupFile($file);
137
+ }
138
+ if ($cleanUpQueue) {
139
+ $this->unsetAllFiles();
140
+ }
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Get File type
146
+ *
147
+ * @param string $file
148
+ * @return string
149
+ */
150
+ public function getFileType($file)
151
+ {
152
+ return pathinfo($file, PATHINFO_EXTENSION);
153
+ }
154
+
155
+ /**
156
+ * Backup file
157
+ *
158
+ * @param string $file
159
+ * @return void
160
+ */
161
+ private function _backupFile($file)
162
+ {
163
+ $type = $this->getFileType($file);
164
+ if ($type && $type != '') {
165
+ $newName = $this->_prefix . time() . '.' . $type;
166
+ @rename($file, str_replace('.' . $type, $newName, $file));
167
+ }
168
+ }
169
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Channel/Generator.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ class Mage_Connect_Channel_Generator extends Mage_Xml_Generator
28
+ {
29
+ protected $_file = 'channel.xml';
30
+ protected $_generator = null;
31
+
32
+ public function __construct($file='')
33
+ {
34
+ if ($file) {
35
+ $this->_file = $file;
36
+ }
37
+ return $this;
38
+ }
39
+
40
+ public function getFile()
41
+ {
42
+ return $this->_file;
43
+ }
44
+
45
+ public function getGenerator()
46
+ {
47
+ if (is_null($this->_generator)) {
48
+ $this->_generator = new Mage_Xml_Generator();
49
+ }
50
+ return $this->_generator;
51
+ }
52
+
53
+ /**
54
+ * @param array $content
55
+ */
56
+ public function save($content)
57
+ {
58
+ $xmlContent = $this->getGenerator()
59
+ ->arrayToXml($content)
60
+ ->save($this->getFile());
61
+ return $this;
62
+ }
63
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Channel/Parser.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Channel/VO.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ class Mage_Connect_Channel_VO implements Iterator
29
+ {
30
+
31
+ private $_validator = null;
32
+
33
+ protected $properties = array(
34
+ 'name' => '',
35
+ 'uri' => '',
36
+ 'summary' => '',
37
+ );
38
+
39
+ public function rewind() {
40
+ reset($this->properties);
41
+ }
42
+
43
+ public function valid() {
44
+ return current($this->properties) !== false;
45
+ }
46
+
47
+ public function key() {
48
+ return key($this->properties);
49
+ }
50
+
51
+ public function current() {
52
+ return current($this->properties);
53
+ }
54
+
55
+ public function next() {
56
+ next($this->properties);
57
+ }
58
+
59
+ public function __get($var)
60
+ {
61
+ if (isset($this->properties[$var])) {
62
+ return $this->properties[$var];
63
+ }
64
+ return null;
65
+ }
66
+
67
+ public function __set($var, $value)
68
+ {
69
+ if (is_string($value)) {
70
+ $value = trim($value);
71
+ }
72
+ if (isset($this->properties[$var])) {
73
+ if ($value === null) {
74
+ $value = '';
75
+ }
76
+ $this->properties[$var] = $value;
77
+ }
78
+ }
79
+
80
+ public function toArray()
81
+ {
82
+ return array('channel' => $this->properties);
83
+ }
84
+
85
+ public function fromArray(array $arr)
86
+ {
87
+ foreach($arr as $k=>$v) {
88
+ $this->$k = $v;
89
+ }
90
+ }
91
+
92
+
93
+ private function validator()
94
+ {
95
+ if(is_null($this->_validator)) {
96
+ $this->_validator = new Mage_Connect_Validator();
97
+ }
98
+ return $this->_validator;
99
+ }
100
+
101
+ /**
102
+ Stub for validation result
103
+ */
104
+ public function validate()
105
+ {
106
+ $v = $this->validator();
107
+ if(!$v->validatePackageName($this->name)) {
108
+ return false;
109
+ }
110
+ return true;
111
+ }
112
+
113
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Command.php ADDED
@@ -0,0 +1,463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Connect Command abstract class. It cannot instantiate directly
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Command
35
+ {
36
+ /**
37
+ * All commands list
38
+ * @var array
39
+ */
40
+ protected static $_commandsAll = array();
41
+
42
+ /**
43
+ * Commands list hash (key=class)
44
+ * @var array
45
+ */
46
+ protected static $_commandsByClass = array();
47
+
48
+ /**
49
+ * Frontend object
50
+ * @var Mage_Connect_Fro
51
+ */
52
+ protected static $_frontend = null;
53
+
54
+ /**
55
+ * Connect Config instance
56
+ * @var Mage_Connect_Config
57
+ */
58
+ protected static $_config = null;
59
+ /**
60
+ * Validator instance
61
+ *
62
+ * @var Mage_Connect_Validator
63
+ */
64
+ protected static $_validator = null;
65
+
66
+ /**
67
+ * Backup instance
68
+ *
69
+ * @var Mage_Connect_Backup
70
+ */
71
+ protected static $_backup = null;
72
+
73
+ /**
74
+ * Rest instance
75
+ *
76
+ * @var Mage_Connect_Rest
77
+ */
78
+ protected static $_rest = null;
79
+
80
+ /**
81
+ * Cache config instance
82
+ *
83
+ * @var Mage_Connect_Singleconfig
84
+ */
85
+ protected static $_sconfig = null;
86
+
87
+ /**
88
+ * Called class name
89
+ *
90
+ * @var string
91
+ */
92
+ protected $_class;
93
+
94
+ /**
95
+ * Packager instance
96
+ *
97
+ * @var Mage_Connect_Packager
98
+ */
99
+ protected static $_packager = null;
100
+
101
+ protected static $_return = array();
102
+
103
+ /**
104
+ * Constructor
105
+ */
106
+ public function __construct()
107
+ {
108
+ $class = $this->_class = get_class($this);
109
+ if(__CLASS__ == $class) {
110
+ throw new Exception("You shouldn't instantiate {$class} directly!");
111
+ }
112
+ $this->commandsInfo = self::$_commandsByClass[$class];
113
+ }
114
+
115
+ /**
116
+ * Get command info (static)
117
+ *
118
+ * @param string $name command name
119
+ * @return array|boolean
120
+ */
121
+ public static function commandInfo($name)
122
+ {
123
+ $name = strtolower($name);
124
+ if(!isset(self::$_commandsAll[$name])) {
125
+ return false;
126
+ }
127
+ return self::$_commandsAll[$name];
128
+ }
129
+
130
+ /**
131
+ * Get command info for current command object
132
+ *
133
+ * @param string $name
134
+ * @return array|boolean
135
+ */
136
+ public function getCommandInfo($name)
137
+ {
138
+ if(!isset(self::$_commandsByClass[$this->_class][$name])) {
139
+ return false;
140
+ }
141
+ return self::$_commandsByClass[$this->_class][$name];
142
+ }
143
+
144
+ /**
145
+ * Run command
146
+ *
147
+ * @param string $command
148
+ * @param string $options
149
+ * @param string $params
150
+ * @throws Exception if there's no needed method
151
+ * @return mixed
152
+ */
153
+ public function run($command, $options, $params)
154
+ {
155
+ $data = $this->getCommandInfo($command);
156
+ $method = $data['function'];
157
+ if(! method_exists($this, $method)) {
158
+ throw new Exception("$method does't exist in class ".$this->_class);
159
+ }
160
+ return $this->$method($command, $options, $params);
161
+ }
162
+
163
+ /**
164
+ * Static functions
165
+ */
166
+
167
+ /**
168
+ * Static
169
+ * @param $commandName
170
+ * @return unknown_type
171
+ */
172
+ public static function getInstance($commandName)
173
+ {
174
+ if(!isset(self::$_commandsAll[$commandName])) {
175
+ throw new UnexpectedValueException("Cannot find command $commandName");
176
+ }
177
+ $currentCommand = self::$_commandsAll[$commandName];
178
+ return new $currentCommand['class']();
179
+ }
180
+
181
+ /**
182
+ * Cache config setter
183
+ *
184
+ * @static
185
+ * @param Mage_Connect_Singleconfig $obj
186
+ * @return null
187
+ */
188
+ public static function setSconfig($obj)
189
+ {
190
+ self::$_sconfig = $obj;
191
+ }
192
+
193
+ /**
194
+ * Cache config getter
195
+ *
196
+ * @return Mage_Connect_Singleconfig
197
+ */
198
+ public function getSconfig()
199
+ {
200
+ return self::$_sconfig;
201
+ }
202
+
203
+ /**
204
+ * Sets frontend object for all commands
205
+ *
206
+ * @param Mage_Connect_Frontend $obj
207
+ * @return null
208
+ */
209
+ public static function setFrontendObject($obj)
210
+ {
211
+ self::$_frontend = $obj;
212
+ }
213
+
214
+ /**
215
+ * Set config object for all commands
216
+ *
217
+ * @param Mage_Connect_Config $obj
218
+ * @return null
219
+ */
220
+ public static function setConfigObject($obj)
221
+ {
222
+ self::$_config = $obj;
223
+ }
224
+
225
+ /**
226
+ * Non-static getter for config
227
+ *
228
+ * @return Mage_Connect_Config
229
+ */
230
+ public function config()
231
+ {
232
+ return self::$_config;
233
+ }
234
+
235
+ /**
236
+ * Non-static getter for UI
237
+ *
238
+ * @return Mage_Connect_Frontend
239
+ */
240
+ public function ui()
241
+ {
242
+ return self::$_frontend;
243
+ }
244
+
245
+ /**
246
+ * Get validator object
247
+ *
248
+ * @return Mage_Connect_Validator
249
+ */
250
+ public function validator()
251
+ {
252
+ if(is_null(self::$_validator)) {
253
+ self::$_validator = new Mage_Connect_Validator();
254
+ }
255
+ return self::$_validator;
256
+ }
257
+
258
+ /**
259
+ * Get backup object
260
+ *
261
+ * @return Mage_Connect_Backup
262
+ */
263
+ public function backup()
264
+ {
265
+ if(is_null(self::$_backup)) {
266
+ self::$_backup = new Mage_Connect_Backup();
267
+ }
268
+ return self::$_backup;
269
+ }
270
+
271
+ /**
272
+ * Get rest object
273
+ *
274
+ * @return Mage_Connect_Rest
275
+ */
276
+ public function rest()
277
+ {
278
+ if(is_null(self::$_rest)) {
279
+ self::$_rest = Mage_Connect_Rest_Builder::getAdapter(self::config()->protocol);
280
+ }
281
+ return self::$_rest;
282
+ }
283
+
284
+ /**
285
+ * Get commands list sorted
286
+ *
287
+ * @return array
288
+ */
289
+ public static function getCommands()
290
+ {
291
+ if(!count(self::$_commandsAll)) {
292
+ self::registerCommands();
293
+ }
294
+ ksort(self::$_commandsAll);
295
+ return self::$_commandsAll;
296
+ }
297
+
298
+ /**
299
+ * Get Getopt args from command definitions
300
+ * and parse them
301
+ *
302
+ * @param $command
303
+ * @return array
304
+ */
305
+ public static function getGetoptArgs($command)
306
+ {
307
+ $commandInfo = self::commandInfo($command);
308
+ $short_args = '';
309
+ $long_args = array();
310
+ if (empty($commandInfo) || empty($commandInfo['options'])) {
311
+ return;
312
+ }
313
+ reset($commandInfo['options']);
314
+ while (list($option, $info) = each($commandInfo['options'])) {
315
+ $larg = $sarg = '';
316
+ if (isset($info['arg'])) {
317
+ if ($info['arg']{0} == '(') {
318
+ $larg = '==';
319
+ $sarg = '::';
320
+ } else {
321
+ $larg = '=';
322
+ $sarg = ':';
323
+ }
324
+ }
325
+ if (isset($info['shortopt'])) {
326
+ $short_args .= $info['shortopt'] . $sarg;
327
+ }
328
+ $long_args[] = $option . $larg;
329
+ }
330
+ return array($short_args, $long_args);
331
+ }
332
+
333
+ /**
334
+ * Try to register commands automatically
335
+ *
336
+ * @return null
337
+ */
338
+ public static function registerCommands()
339
+ {
340
+ $pathCommands = dirname(__FILE__).DIRECTORY_SEPARATOR.basename(__FILE__, ".php");
341
+ $f = new DirectoryIterator($pathCommands);
342
+ foreach($f as $file) {
343
+ /** @var $file DirectoryIterator */
344
+ if (! $file->isFile()) {
345
+ continue;
346
+ }
347
+ $pattern = preg_match("/(.*)_Header\.php/imsu", $file->getFilename(), $matches);
348
+ if(! $pattern) {
349
+ continue;
350
+ }
351
+ include($file->getPathname());
352
+ if(! isset($commands)) {
353
+ continue;
354
+ }
355
+ $class = __CLASS__."_".$matches[1];
356
+ foreach ($commands as $k=>$v) {
357
+ $commands[$k]['class'] = $class;
358
+ self::$_commandsAll[$k] = $commands[$k];
359
+ }
360
+ self::$_commandsByClass[$class] = $commands;
361
+ }
362
+ }
363
+
364
+ /**
365
+ * Add Error message
366
+ *
367
+ * @param string $command
368
+ * @param string $message
369
+ * @return null
370
+ */
371
+ public function doError($command, $message)
372
+ {
373
+ return $this->ui()->doError($command, $message);
374
+ }
375
+
376
+ /**
377
+ * Set command return
378
+ *
379
+ * @param string $key
380
+ * @param mixed $val
381
+ * @return null
382
+ */
383
+ public static function setReturn($key, $val)
384
+ {
385
+ self::$_return[$key] = $val;
386
+ }
387
+
388
+ /**
389
+ * Get command return
390
+ *
391
+ * @param $key
392
+ * @param $clear
393
+ * @return mixed
394
+ */
395
+ public static function getReturn($key, $clear = true)
396
+ {
397
+ if(isset(self::$_return[$key])) {
398
+ $out = self::$_return[$key];
399
+ if($clear) {
400
+ unset(self::$_return[$key]);
401
+ }
402
+ return $out;
403
+ }
404
+ return null;
405
+ }
406
+
407
+ /**
408
+ * Cleanup command params from empty strings
409
+ *
410
+ * @param array $params by reference
411
+ */
412
+ public function cleanupParams(array & $params)
413
+ {
414
+ $newParams = array();
415
+ if(!count($params)) {
416
+ return;
417
+ }
418
+ foreach($params as $v) {
419
+ if(is_string($v)) {
420
+ $v = trim($v);
421
+ if(!strlen($v)) {
422
+ continue;
423
+ }
424
+ }
425
+ $newParams[] = $v;
426
+ }
427
+ $params = $newParams;
428
+ }
429
+
430
+ /**
431
+ * Splits first command argument: channel/package
432
+ * to two arguments if found in top of array
433
+ *
434
+ * @param array $params
435
+ */
436
+ public function splitPackageArgs(array & $params)
437
+ {
438
+ if(!count($params) || !isset($params[0])) {
439
+ return;
440
+ }
441
+ if($this->validator()->validateUrl($params[0])) {
442
+ return;
443
+ }
444
+ if(preg_match("@([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)@ims", $params[0], $subs)) {
445
+ $params[0] = $subs[2];
446
+ array_unshift($params, $subs[1]);
447
+ }
448
+ }
449
+
450
+
451
+ /**
452
+ * Get packager instance
453
+ *
454
+ * @return Mage_Connect_Packager
455
+ */
456
+ public function getPackager()
457
+ {
458
+ if(!self::$_packager) {
459
+ self::$_packager = new Mage_Connect_Packager();
460
+ }
461
+ return self::$_packager;
462
+ }
463
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Channels.php ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ final class Mage_Connect_Command_Channels
28
+ extends Mage_Connect_Command
29
+ {
30
+
31
+ /**
32
+ * List available channels
33
+ * @param $command
34
+ * @param $params
35
+ * @param $options
36
+ */
37
+ public function doList($command, $options, $params)
38
+ {
39
+
40
+ try {
41
+ $title = "Available channels:";
42
+ $aliasT = "Available aliases:";
43
+ $packager = $this->getPackager();
44
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
45
+ if($ftp) {
46
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
47
+ $data = $cache->getData();
48
+ @unlink($config->getFilename());
49
+ @unlink($cache->getFilename());
50
+ } else {
51
+ $cache = $this->getSconfig();
52
+ $config = $this->config();
53
+ $data = $cache->getData();
54
+ }
55
+ $out = array($command => array('data'=>$data, 'title'=>$title, 'title_aliases'=>$aliasT));
56
+ $this->ui()->output($out);
57
+ } catch (Exception $e) {
58
+ $this->doError($command, $e->getMessage());
59
+ }
60
+ }
61
+
62
+ /**
63
+ * channel-delete callback method
64
+ * @param string $command
65
+ * @param array $options
66
+ * @param array $params
67
+ */
68
+ public function doDelete($command, $options, $params)
69
+ {
70
+ $this->cleanupParams($params);
71
+ try {
72
+ if(count($params) != 1) {
73
+ throw new Exception("Parameters count should be equal to 1");
74
+ }
75
+ $packager = $this->getPackager();
76
+
77
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
78
+ if($ftp) {
79
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
80
+ $cache->deleteChannel($params[0]);
81
+ $packager->writeToRemoteCache($cache, $ftpObj);
82
+ @unlink($config->getFilename());
83
+ } else {
84
+ $config = $this->config();
85
+ $cache = $this->getSconfig();
86
+ $cache->deleteChannel($params[0]);
87
+ }
88
+ $this->ui()->output("Successfully deleted");
89
+
90
+ } catch (Exception $e) {
91
+ $this->doError($command, $e->getMessage());
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Channel-add callback
97
+ * @param string $command
98
+ * @param array $options
99
+ * @param array $params
100
+ */
101
+ public function doAdd($command, $options, $params)
102
+ {
103
+ $this->cleanupParams($params);
104
+ try {
105
+ if(count($params) != 1) {
106
+ throw new Exception("Parameters count should be equal to 1");
107
+ }
108
+ $url = $params[0];
109
+ $rest = $this->rest();
110
+ $rest->setChannel($url);
111
+ $data = $rest->getChannelInfo();
112
+ $data->url = $url;
113
+
114
+ $packager = $this->getPackager();
115
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
116
+ if($ftp) {
117
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
118
+ $cache->addChannel($data->name, $url);
119
+ $packager->writeToRemoteCache($cache, $ftpObj);
120
+ @unlink($config->getFilename());
121
+ } else {
122
+ $cache = $this->getSconfig();
123
+ $config = $this->config();
124
+ $cache->addChannel($data->name, $url);
125
+ }
126
+
127
+ $this->ui()->output("Successfully added: ".$url);
128
+ } catch (Exception $e) {
129
+ $this->doError($command, $e->getMessage());
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Get information about given channel callback
135
+ * @param string $command
136
+ * @param array $options
137
+ * @param array $params
138
+ */
139
+ public function doInfo($command, $options, $params)
140
+ {
141
+
142
+ }
143
+
144
+ /**
145
+ * channel-alias
146
+ * @param $command
147
+ * @param $options
148
+ * @param $params
149
+ * @return unknown_type
150
+ */
151
+ public function doAlias($command, $options, $params)
152
+ {
153
+ $this->cleanupParams($params);
154
+ try {
155
+ if(count($params) != 2) {
156
+ throw new Exception("Parameters count should be equal to 2");
157
+ }
158
+
159
+ $packager = $this->getPackager();
160
+ $chanUrl = $params[0];
161
+ $alias = $params[1];
162
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
163
+ if($ftp) {
164
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
165
+ $cache->addChannelAlias($chanUrl, $alias);
166
+ $packager->writeToRemoteCache($cache, $ftpObj);
167
+ @unlink($config->getFilename());
168
+ } else {
169
+ $cache = $this->getSconfig();
170
+ $config = $this->config();
171
+ $cache->addChannelAlias($chanUrl, $alias);
172
+ }
173
+ $this->ui()->output("Successfully added: ".$alias);
174
+ } catch (Exception $e) {
175
+ $this->doError($command, $e->getMessage());
176
+ }
177
+ }
178
+
179
+ public function doLogin($command, $options, $params)
180
+ {
181
+
182
+ }
183
+
184
+ public function doLogout($command, $options, $params)
185
+ {
186
+
187
+ }
188
+
189
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Channels_Header.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ $commands = array(
28
+ 'list-channels' => array(
29
+ 'summary' => 'List Available Channels',
30
+ 'function' => 'doList',
31
+ 'shortcut' => 'lc',
32
+ 'options' => array(),
33
+ 'doc' => '
34
+ List all available channels for installation.
35
+ ',
36
+ ),
37
+ 'channel-delete' => array(
38
+ 'summary' => 'Remove a Channel From the List',
39
+ 'function' => 'doDelete',
40
+ 'shortcut' => 'cde',
41
+ 'options' => array(),
42
+ 'doc' => '<channel name>
43
+ Delete a channel from the registry. You may not
44
+ remove any channel that has installed packages.
45
+ '
46
+ ),
47
+ 'channel-add' => array(
48
+ 'summary' => 'Add a Channel',
49
+ 'function' => 'doAdd',
50
+ 'shortcut' => 'ca',
51
+ 'options' => array(),
52
+ 'doc' => '<channel.xml>
53
+ Add a private channel to the channel list. Note that all
54
+ public channels should be synced using "update-channels".
55
+ Parameter may be either a local file or remote URL to a
56
+ channel.xml.
57
+ '
58
+ ),
59
+ 'channel-info' => array(
60
+ 'summary' => 'Retrieve Information on a Channel',
61
+ 'function' => 'doInfo',
62
+ 'shortcut' => 'ci',
63
+ 'options' => array(),
64
+ 'doc' => '<package>
65
+ List the files in an installed package.
66
+ '
67
+ ),
68
+ 'channel-alias' => array(
69
+ 'summary' => 'Specify an alias to a channel name',
70
+ 'function' => 'doAlias',
71
+ 'shortcut' => 'cha',
72
+ 'options' => array(),
73
+ 'doc' => '<channel> <alias>
74
+ Specify a specific alias to use for a channel name.
75
+ The alias may not be an existing channel name or
76
+ alias.
77
+ '
78
+ ),
79
+ 'channel-login' => array(
80
+ 'summary' => 'Connects and authenticates to remote channel server',
81
+ 'shortcut' => 'cli',
82
+ 'function' => 'doLogin',
83
+ 'options' => array(),
84
+ 'doc' => '<channel name>
85
+ Log in to a remote channel server. If <channel name> is not supplied,
86
+ the default channel is used. To use remote functions in the installer
87
+ that require any kind of privileges, you need to log in first. The
88
+ username and password you enter here will be stored in your per-user
89
+ PEAR configuration (~/.pearrc on Unix-like systems). After logging
90
+ in, your username and password will be sent along in subsequent
91
+ operations on the remote server.',
92
+ ),
93
+ 'channel-logout' => array(
94
+ 'summary' => 'Logs out from the remote channel server',
95
+ 'shortcut' => 'clo',
96
+ 'function' => 'doLogout',
97
+ 'options' => array(),
98
+ 'doc' => '<channel name>
99
+ Logs out from a remote channel server. If <channel name> is not supplied,
100
+ the default channel is used. This command does not actually connect to the
101
+ remote server, it only deletes the stored username and password from your user
102
+ configuration.',
103
+ ),
104
+ );
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Config.php ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Configuration command callbacks
29
+ *
30
+ * @throws Exception
31
+ * @category Mage
32
+ * @package Mage_Connect
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class Mage_Connect_Command_Config extends Mage_Connect_Command
36
+ {
37
+ /**
38
+ * Parameters constants
39
+ */
40
+ const PARAM_KEY = 0;
41
+ const PARAM_VAL = 1;
42
+
43
+ /**
44
+ * Show config variable
45
+ * @param string $command
46
+ * @param array $options
47
+ * @param array $params
48
+ * @return void
49
+ */
50
+ public function doConfigShow($command, $options, $params)
51
+ {
52
+ $this->cleanupParams($params);
53
+
54
+ try {
55
+ $values = array();
56
+
57
+ $packager = $this->getPackager();
58
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
59
+ if($ftp) {
60
+ list($config, $ftpObj) = $packager->getRemoteConfig($ftp);
61
+ } else {
62
+ $config = $this->config();
63
+ }
64
+ foreach( $config as $k=>$v ) {
65
+ $values[$k] = $v;
66
+ }
67
+ if($ftp) {
68
+ @unlink($config->getFilename());
69
+ }
70
+ $data = array($command => array('data'=>$values));
71
+ $this->ui()->output($data);
72
+ } catch (Exception $e) {
73
+ if($ftp) {
74
+ @unlink($config->getFilename());
75
+ }
76
+ return $this->doError($command, $e->getMessage());
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Set config variable
82
+ * @param string $command
83
+ * @param array $options
84
+ * @param array $params
85
+ * @return void
86
+ */
87
+ public function doConfigSet($command, $options, $params)
88
+ {
89
+ $this->cleanupParams($params);
90
+
91
+ try {
92
+ if(count($params) < 2) {
93
+ throw new Exception("Parameters count should be >= 2");
94
+ }
95
+ $key = strtolower($params[self::PARAM_KEY]);
96
+ $val = strval($params[self::PARAM_VAL]);
97
+ $packager = $this->getPackager();
98
+
99
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
100
+ if(!$ftp) {
101
+ $config = $this->config();
102
+ $ftp=$config->remote_config;
103
+ }
104
+ if($ftp) {
105
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
106
+ }
107
+
108
+ if(!$config->hasKey($key)) {
109
+ throw new Exception ("No such config variable: {$key}!");
110
+ }
111
+ if(!$config->validate($key, $val)) {
112
+ $possible = $this->config()->possible($key);
113
+ $type = $this->config()->type($key);
114
+ $errString = "Invalid value specified for $key!";
115
+ throw new Exception($errString);
116
+ }
117
+ if($ftp) {
118
+ $packager->writeToRemoteConfig($config, $ftpObj);
119
+ }
120
+ $this->config()->$key = $val;
121
+ $this->ui()->output('Success');
122
+ } catch (Exception $e) {
123
+ if($ftp) {
124
+ @unlink($config->getFilename());
125
+ }
126
+ return $this->doError($command, $e->getMessage());
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Get config var
132
+ * @param string $command
133
+ * @param array $options
134
+ * @param array $params
135
+ * @return void
136
+ */
137
+ public function doConfigGet($command, $options, $params)
138
+ {
139
+ $this->cleanupParams($params);
140
+
141
+ try {
142
+ if(count($params) < 1) {
143
+ throw new Exception("Parameters count should be >= 1");
144
+ }
145
+ $packager = $this->getPackager();
146
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
147
+ if($ftp) {
148
+ list($config, $ftpObj) = $packager->getRemoteConfig($ftp);
149
+ } else {
150
+ $config = $this->config();
151
+ }
152
+ $key = strtolower($params[self::PARAM_KEY]);
153
+ if(!$config->hasKey($key)) {
154
+ throw new Exception("No such config variable '{$key}'!");
155
+ }
156
+ if($ftp) {
157
+ @unlink($config->getFilename());
158
+ }
159
+ $this->ui()->output($config->$key);
160
+ } catch (Exception $e) {
161
+ if($ftp) {
162
+ @unlink($config->getFilename());
163
+ }
164
+ return $this->doError($command, $e->getMessage());
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Config help
170
+ * @param string $command
171
+ * @param array $options
172
+ * @param array $params
173
+ * @return void
174
+ */
175
+ public function doConfigHelp($command, $options, $params)
176
+ {
177
+ try {
178
+ $this->cleanupParams($params);
179
+ if(count($params) < 1) {
180
+ throw new Exception( "Parameters count should be >= 1");
181
+ }
182
+ $packager = $this->getPackager();
183
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
184
+ if($ftp) {
185
+ list($config, $ftpObj) = $packager->getRemoteConfig($ftp);
186
+ } else {
187
+ $config = $this->config();
188
+ }
189
+
190
+ $key = strtolower($params[self::PARAM_KEY]);
191
+ if(!$this->config()->hasKey($key)) {
192
+ throw new Exception("No such config variable '{$key}'!");
193
+ }
194
+
195
+ $possible = $config->possible($key);
196
+ $type = $config->type($key);
197
+ $doc = $config->doc($key);
198
+ if($ftp) {
199
+ @unlink($config->getFilename());
200
+ }
201
+ $data = array();
202
+ $data[$command]['data'] = array(
203
+ 'name' => array('Variable name', $key),
204
+ 'type' => array('Value type', $type),
205
+ 'possible' => array('Possible values', $possible),
206
+ 'doc' => $doc,
207
+ );
208
+ $this->ui()->output($data);
209
+ } catch (Exception $e) {
210
+ if($ftp) {
211
+ @unlink($config->getFilename());
212
+ }
213
+ return $this->doError($command, $e->getMessage());
214
+ }
215
+ }
216
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Config_Header.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ $commands = array(
28
+ 'config-show' => array(
29
+ 'summary' => 'Show All Settings',
30
+ 'function' => 'doConfigShow',
31
+ 'shortcut' => 'csh',
32
+ 'options' => array(
33
+ 'channel' => array(
34
+ 'shortopt' => 'c',
35
+ 'doc' => 'show configuration variables for another channel',
36
+ 'arg' => 'CHAN',
37
+ ),
38
+ ),
39
+ 'doc' => '[layer]
40
+ Displays all configuration values. An optional argument
41
+ may be used to tell which configuration layer to display. Valid
42
+ configuration layers are "user", "system" and "default". To display
43
+ configurations for different channels, set the default_channel
44
+ configuration variable and run config-show again.
45
+ ',
46
+ ),
47
+ 'config-get' => array(
48
+ 'summary' => 'Show One Setting',
49
+ 'function' => 'doConfigGet',
50
+ 'shortcut' => 'cg',
51
+ 'options' => array(
52
+ 'channel' => array(
53
+ 'shortopt' => 'c',
54
+ 'doc' => 'show configuration variables for another channel',
55
+ 'arg' => 'CHAN',
56
+ ),
57
+ ),
58
+ 'doc' => '<parameter> [layer]
59
+ Displays the value of one configuration parameter. The
60
+ first argument is the name of the parameter, an optional second argument
61
+ may be used to tell which configuration layer to look in. Valid configuration
62
+ layers are "user", "system" and "default". If no layer is specified, a value
63
+ will be picked from the first layer that defines the parameter, in the order
64
+ just specified. The configuration value will be retrieved for the channel
65
+ specified by the default_channel configuration variable.
66
+ ',
67
+ ),
68
+ 'config-set' => array(
69
+ 'summary' => 'Change Setting',
70
+ 'function' => 'doConfigSet',
71
+ 'shortcut' => 'cs',
72
+ 'options' => array(
73
+ 'channel' => array(
74
+ 'shortopt' => 'c',
75
+ 'doc' => 'show configuration variables for another channel',
76
+ 'arg' => 'CHAN',
77
+ ),
78
+ ),
79
+ 'doc' => '<parameter> <value> [layer]
80
+ Sets the value of one configuration parameter. The first argument is
81
+ the name of the parameter, the second argument is the new value. Some
82
+ parameters are subject to validation, and the command will fail with
83
+ an error message if the new value does not make sense. An optional
84
+ third argument may be used to specify in which layer to set the
85
+ configuration parameter. The default layer is "user". The
86
+ configuration value will be set for the current channel, which
87
+ is controlled by the default_channel configuration variable.
88
+ ',
89
+ ),
90
+ 'config-help' => array(
91
+ 'summary' => 'Show Information About Setting',
92
+ 'function' => 'doConfigHelp',
93
+ 'shortcut' => 'ch',
94
+ 'options' => array(),
95
+ 'doc' => '[parameter]
96
+ Displays help for a configuration parameter. Without arguments it
97
+ displays help for all configuration parameters.
98
+ ',
99
+ ),
100
+ );
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Install.php ADDED
@@ -0,0 +1,568 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+ final class Mage_Connect_Command_Install extends Mage_Connect_Command
27
+ {
28
+ /**
29
+ * Install action callback
30
+ *
31
+ * @throws Exception
32
+ * @param string $command
33
+ * @param array $options
34
+ * @param array $params
35
+ * @param array $objects
36
+ * @return array|null
37
+ */
38
+ public function doInstall($command, $options, $params, $objects = array())
39
+ {
40
+ $this->cleanupParams($params);
41
+
42
+ $installFileMode = $command === 'install-file';
43
+
44
+ /** @var $ftpObj Mage_Connect_Ftp */
45
+ $ftpObj=null;
46
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
47
+ /** @var $packager Mage_Connect_Packager */
48
+ $packager = $this->getPackager();
49
+ /** @var $cache Mage_Connect_Singleconfig */
50
+ /** @var $config Mage_Connect_Config */
51
+ if ($ftp) {
52
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
53
+ } else {
54
+ $cache = $this->getSconfig();
55
+ $config = $this->config();
56
+ }
57
+
58
+ try {
59
+ $forceMode = isset($options['force']);
60
+ $upgradeAllMode = $command == 'upgrade-all';
61
+ $upgradeMode = $command == 'upgrade' || $command == 'upgrade-all';
62
+ $noFilesInstall = isset($options['nofiles']);
63
+ $withDepsMode = !isset($options['nodeps']);
64
+ $ignoreModifiedMode = true || !isset($options['ignorelocalmodification']);
65
+ $clearInstallMode = $command == 'install' && !$forceMode;
66
+ $installAll = isset($options['install_all']);
67
+ $channelAuth = isset($options['auth'])?$options['auth']:array();
68
+
69
+ $rest = $this->rest();
70
+ if (empty($config->magento_root)) {
71
+ $config->magento_root=dirname(dirname($_SERVER['SCRIPT_FILENAME']));
72
+ }
73
+ chdir($config->magento_root);
74
+ $dirCache = DIRECTORY_SEPARATOR . $config->downloader_path . DIRECTORY_SEPARATOR
75
+ . Mage_Connect_Config::DEFAULT_CACHE_PATH;
76
+ $dirTmp = DIRECTORY_SEPARATOR . Mage_Connect_Package_Reader::PATH_TO_TEMPORARY_DIRECTORY;
77
+ $dirMedia = DIRECTORY_SEPARATOR . 'media';
78
+ $isWritable = true;
79
+ if ($ftp) {
80
+ $cwd=$ftpObj->getcwd();
81
+ $ftpObj->mkdirRecursive($cwd . $dirCache,0777);
82
+ $ftpObj->chdir($cwd);
83
+ $ftpObj->mkdirRecursive($cwd . $dirTmp,0777);
84
+ $ftpObj->chdir($cwd);
85
+ $ftpObj->mkdirRecursive($cwd . $dirMedia,0777);
86
+ $ftpObj->chdir($cwd);
87
+ $err = "Please check for sufficient ftp write file permissions.";
88
+ } else {
89
+ @mkdir($config->magento_root . $dirCache,0777,true);
90
+ @mkdir($config->magento_root . $dirTmp,0777,true);
91
+ @mkdir($config->magento_root . $dirMedia,0777,true);
92
+ $isWritable = is_writable($config->magento_root)
93
+ && is_writable($config->magento_root . DIRECTORY_SEPARATOR . $config->downloader_path)
94
+ && is_writable($config->magento_root . $dirCache)
95
+ && is_writable($config->magento_root . $dirTmp)
96
+ && is_writable($config->magento_root . $dirMedia);
97
+ $err = "Please check for sufficient write file permissions.";
98
+ }
99
+ $isWritable = $isWritable && is_writable($config->magento_root . $dirMedia)
100
+ && is_writable($config->magento_root . $dirCache)
101
+ && is_writable($config->magento_root . $dirTmp);
102
+ if (!$isWritable) {
103
+ $this->doError($command, $err);
104
+ throw new Exception(
105
+ 'Your Magento folder does not have sufficient write permissions, which downloader requires.'
106
+ );
107
+ }
108
+ if (!empty($channelAuth)) {
109
+ $rest->getLoader()->setCredentials($channelAuth['username'], $channelAuth['password']);
110
+ }
111
+
112
+ if ($installFileMode) {
113
+ if (count($params) < 1) {
114
+ throw new Exception("Argument should be: filename");
115
+ }
116
+ $filename = $params[0];
117
+ if (!@file_exists($filename)) {
118
+ throw new Exception("File '{$filename}' not found");
119
+ }
120
+ if (!@is_readable($filename)) {
121
+ throw new Exception("File '{$filename}' is not readable");
122
+ }
123
+
124
+ $package = new Mage_Connect_Package($filename);
125
+ $package->setConfig($config);
126
+ $package->validate();
127
+ $errors = $package->getErrors();
128
+ if (count($errors)) {
129
+ throw new Exception("Package file is invalid\n" . implode("\n", $errors));
130
+ }
131
+
132
+ $pChan = $package->getChannel();
133
+ $pName = $package->getName();
134
+ $pVer = $package->getVersion();
135
+
136
+ if (!($cache->isChannelName($pChan) || $cache->isChannelAlias($pChan))) {
137
+ throw new Exception("The '{$pChan}' channel is not installed. Please use the MAGE shell "
138
+ . "script to install the '{$pChan}' channel.");
139
+ }
140
+
141
+ $conflicts = $cache->hasConflicts($pChan, $pName, $pVer);
142
+
143
+ if (false !== $conflicts) {
144
+ $conflicts = implode(", ",$conflicts);
145
+ if ($forceMode) {
146
+ $this->doError($command, "Package {$pChan}/{$pName} {$pVer} conflicts with: " . $conflicts);
147
+ } else {
148
+ throw new Exception("Package {$pChan}/{$pName} {$pVer} conflicts with: " . $conflicts);
149
+ }
150
+ }
151
+
152
+ $conflicts = $package->checkPhpDependencies();
153
+ if (true !== $conflicts) {
154
+ $conflicts = implode(",",$conflicts);
155
+ $err = "Package {$pChan}/{$pName} {$pVer} depends on PHP extensions: " . $conflicts;
156
+ if ($forceMode) {
157
+ $this->doError($command, $err);
158
+ } else {
159
+ throw new Exception($err);
160
+ }
161
+ }
162
+
163
+ $conflicts = $package->checkPhpVersion();
164
+ if (true !== $conflicts) {
165
+ $err = "Package {$pChan}/{$pName} {$pVer}: " . $conflicts;
166
+ if ($forceMode) {
167
+ $this->doError($command, $err);
168
+ } else {
169
+ throw new Exception($err);
170
+ }
171
+ }
172
+
173
+ if (!$noFilesInstall) {
174
+ if ($ftp) {
175
+ $packager->processInstallPackageFtp($package, $filename, $config, $ftpObj);
176
+ } else {
177
+ $packager->processInstallPackage($package, $filename, $config);
178
+ }
179
+ }
180
+ $cache->addPackage($package);
181
+ $installedDeps = array();
182
+ $installedDepsAssoc = array();
183
+ $installedDepsAssoc[] = array('channel'=>$pChan, 'name'=>$pName, 'version'=>$pVer);
184
+ $installedDeps[] = array($pChan, $pName, $pVer);
185
+
186
+ $title = isset($options['title']) ? $options['title'] : "Package installed: ";
187
+ $out = array($command => array('data'=>$installedDeps, 'assoc'=>$installedDepsAssoc, 'title'=>$title));
188
+
189
+ if ($ftp) {
190
+ $packager->writeToRemoteCache($cache, $ftpObj);
191
+ @unlink($config->getFilename());
192
+ }
193
+
194
+ $this->ui()->output($out);
195
+ return $out[$command]['data'];
196
+ }
197
+
198
+ if (!$upgradeAllMode) {
199
+ if (count($params) < 2) {
200
+ throw new Exception("Argument should be: channelName packageName");
201
+ }
202
+ $channel = $params[0];
203
+ $package = $params[1];
204
+ $argVersionMax = isset($params[2]) ? $params[2]: false;
205
+ $argVersionMin = isset($params[3]) ? $params[3]: false;
206
+
207
+ $cache->checkChannel($channel, $config, $rest);
208
+ $channelName = $cache->chanName($channel);
209
+ $this->ui()->output("Checking dependencies of packages");
210
+ $packagesToInstall = $packager->getDependenciesList($channelName, $package, $cache, $config,
211
+ $argVersionMax, $argVersionMin, $withDepsMode, false, $rest
212
+ );
213
+ /*
214
+ * process 'failed' results
215
+ */
216
+ if (count($packagesToInstall['failed'])) {
217
+ $showError=!count($packagesToInstall['result']);
218
+ foreach ($packagesToInstall['failed'] as $failed) {
219
+ $msg="Package {$failed['channel']}/{$failed['name']} failed: " . $failed['reason'];
220
+ if ($showError) {
221
+ $this->doError($command, $msg);
222
+ } else {
223
+ $this->ui()->output($msg);
224
+ }
225
+ }
226
+ }
227
+ $packagesToInstall = $packagesToInstall['result'];
228
+ } else {
229
+ if (empty($params[0])) {
230
+ $channels = $cache->getChannelNames();
231
+ } else {
232
+ $channel = $params[0];
233
+ if (!$cache->isChannel($channel)) {
234
+ throw new Exception("'{$channel}' is not existant channel name / valid uri");
235
+ }
236
+ $channels = $cache->chanName($channel);
237
+ }
238
+ $packagesToInstall = array();
239
+ $neededToUpgrade = $packager->getUpgradesList($channels, $cache, $config, $rest);
240
+ foreach ($neededToUpgrade as $chan=>$packages) {
241
+ foreach ($packages as $name=>$data) {
242
+ $versionTo = $data['to'];
243
+ $tmp = $packager->getDependenciesList($chan, $name, $cache, $config, $versionTo, $versionTo,
244
+ $withDepsMode, false, $rest
245
+ );
246
+ if (count($tmp['result'])) {
247
+ $packagesToInstall = array_merge($packagesToInstall, $tmp['result']);
248
+ }
249
+ }
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Make installation
255
+ */
256
+ $installedDeps = array();
257
+ $installedDepsAssoc = array();
258
+
259
+ foreach ($packagesToInstall as $package) {
260
+ try {
261
+ $pName = $package['name'];
262
+ $pChan = $package['channel'];
263
+ $pVer = $package['downloaded_version'];
264
+ $pInstallState = $package['install_state'];
265
+ $rest->setChannel($cache->chanUrl($pChan));
266
+
267
+ /**
268
+ * Skip existing packages
269
+ */
270
+ if ($upgradeMode && $cache->hasPackage($pChan, $pName, $pVer, $pVer)
271
+ || ('already_installed' == $pInstallState && !$forceMode)
272
+ ) {
273
+ $this->ui()->output("Already installed: {$pChan}/{$pName} {$pVer}, skipping");
274
+ continue;
275
+ }
276
+
277
+ if ('incompartible' == $pInstallState) {
278
+ $this->ui()->output(
279
+ "Package incompartible with installed Magento: {$pChan}/{$pName} {$pVer}, skipping"
280
+ );
281
+ continue;
282
+ }
283
+
284
+ $conflicts = $cache->hasConflicts($pChan, $pName, $pVer);
285
+
286
+ if (false !== $conflicts) {
287
+ $conflicts = implode(", ",$conflicts);
288
+ if ($forceMode) {
289
+ $this->doError($command, "Package {$pChan}/{$pName} {$pVer} conflicts with: " . $conflicts);
290
+ } else {
291
+ throw new Exception("Package {$pChan}/{$pName} {$pVer} conflicts with: " . $conflicts);
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Modifications
297
+ */
298
+ if (($upgradeMode || ($pInstallState == 'upgrade')) && !$ignoreModifiedMode) {
299
+ if ($ftp) {
300
+ $modifications = $packager->getRemoteModifiedFiles($pChan, $pName, $cache, $config, $ftp);
301
+ } else {
302
+ $modifications = $packager->getLocalModifiedFiles($pChan, $pName, $cache, $config);
303
+ }
304
+ if (count($modifications) > 0) {
305
+ $this->ui()->output('Changed locally: ');
306
+ foreach ($modifications as $row) {
307
+ if (!$ftp) {
308
+ $this->ui()->output($config->magento_root . DS . $row);
309
+ } else {
310
+ $this->ui()->output($row);
311
+ }
312
+ }
313
+ }
314
+ }
315
+
316
+ if ($ftp) {
317
+ $cwd=$ftpObj->getcwd();
318
+ $dir=$cwd . DIRECTORY_SEPARATOR .$config->downloader_path . DIRECTORY_SEPARATOR
319
+ . Mage_Connect_Config::DEFAULT_CACHE_PATH . DIRECTORY_SEPARATOR . trim( $pChan, "\\/");
320
+ $ftpObj->mkdirRecursive($dir,0777);
321
+ $ftpObj->chdir($cwd);
322
+ } else {
323
+ $dir = $config->getChannelCacheDir($pChan);
324
+ @mkdir($dir, 0777, true);
325
+ }
326
+ $dir = $config->getChannelCacheDir($pChan);
327
+ $packageFileName = $pName . "-" . $pVer . ".tgz";
328
+ $file = $dir . DIRECTORY_SEPARATOR . $packageFileName;
329
+ if (!@file_exists($file)) {
330
+ $this->ui()->output("Starting to download $packageFileName ...");
331
+ $rest->downloadPackageFileOfRelease($pName, $pVer, $file);
332
+ $this->ui()->output(sprintf("...done: %s bytes", number_format(filesize($file))));
333
+ }
334
+
335
+ /**
336
+ * Remove old version package before install new
337
+ */
338
+ if ($cache->hasPackage($pChan, $pName)) {
339
+ if ($ftp) {
340
+ $packager->processUninstallPackageFtp($pChan, $pName, $cache, $ftpObj);
341
+ } else {
342
+ $packager->processUninstallPackage($pChan, $pName, $cache, $config);
343
+ }
344
+ $cache->deletePackage($pChan, $pName);
345
+ }
346
+
347
+ $package = new Mage_Connect_Package($file);
348
+ if ($clearInstallMode && $pInstallState != 'upgrade' && !$installAll) {
349
+ $contents = $package->getContents();
350
+ $this->backup()->setFileTypes(array('csv', 'html'));
351
+ $typesToBackup = $this->backup()->getFileTypes();
352
+ $this->validator()->validateContents($contents, $config, $typesToBackup);
353
+ $errors = $this->validator()->getErrors();
354
+ if (count($errors)) {
355
+ throw new Exception("Package '{$pName}' is invalid\n" . implode("\n", $errors));
356
+ }
357
+
358
+ $targetPath = rtrim($config->magento_root, "\\/");
359
+ foreach ($contents as $filePath) {
360
+ $this->backup()->addFile($filePath, $targetPath);
361
+ }
362
+
363
+ if ($this->backup()->getFilesCount() > 0) {
364
+ $this->ui()->output('<br/>');
365
+ $this->ui()->output('Backup of following files will be created :');
366
+ $this->ui()->output('<br/>');
367
+ $this->backup()->run();
368
+ $this->ui()->output(implode('<br/>', $this->backup()->getAllFiles()));
369
+ $this->ui()->output('<br/>');
370
+ $this->ui()->output(
371
+ $this->backup()->getFilesCount() . ' files was overwritten by installed extension.'
372
+ );
373
+ $this->ui()->output('<br/>');
374
+ $this->backup()->unsetAllFiles();
375
+ }
376
+ }
377
+
378
+ $conflicts = $package->checkPhpDependencies();
379
+ if (true !== $conflicts) {
380
+ $conflicts = implode(",",$conflicts);
381
+ $err = "Package {$pChan}/{$pName} {$pVer} depends on PHP extensions: " . $conflicts;
382
+ if ($forceMode) {
383
+ $this->doError($command, $err);
384
+ } else {
385
+ throw new Exception($err);
386
+ }
387
+ }
388
+
389
+ $conflicts = $package->checkPhpVersion();
390
+ if (true !== $conflicts) {
391
+ $err = "Package {$pChan}/{$pName} {$pVer}: " . $conflicts;
392
+ if ($forceMode) {
393
+ $this->doError($command, $err);
394
+ } else {
395
+ throw new Exception($err);
396
+ }
397
+ }
398
+
399
+ if (!$noFilesInstall) {
400
+ $this->ui()->output("Installing package {$pChan}/{$pName} {$pVer}");
401
+ if ($ftp) {
402
+ $packager->processInstallPackageFtp($package, $file, $config, $ftpObj);
403
+ } else {
404
+ $packager->processInstallPackage($package, $file, $config);
405
+ }
406
+ $this->ui()->output("Package {$pChan}/{$pName} {$pVer} installed successfully");
407
+ }
408
+ $cache->addPackage($package);
409
+
410
+ $installedDepsAssoc[] = array('channel'=>$pChan, 'name'=>$pName, 'version'=>$pVer);
411
+ $installedDeps[] = array($pChan, $pName, $pVer);
412
+
413
+ } catch(Exception $e) {
414
+ $this->doError($command, $e->getMessage());
415
+ }
416
+ }
417
+
418
+ $title = isset($options['title']) ? $options['title'] : "Package installed: ";
419
+ $out = array($command => array('data'=>$installedDeps, 'assoc'=>$installedDepsAssoc, 'title'=>$title));
420
+
421
+ if ($ftp) {
422
+ $packager->writeToRemoteCache($cache, $ftpObj);
423
+ @unlink($config->getFilename());
424
+ }
425
+
426
+ $this->ui()->output($out);
427
+ return $out[$command]['data'];
428
+ } catch (Exception $e) {
429
+ if ($ftp) {
430
+ $packager->writeToRemoteCache($cache, $ftpObj);
431
+ @unlink($config->getFilename());
432
+ }
433
+ return $this->doError($command, $e->getMessage());
434
+ }
435
+ }
436
+
437
+ /**
438
+ * Upgrade action callback
439
+ *
440
+ * @param string $command
441
+ * @param array $options
442
+ * @param array $params
443
+ * @return array|null
444
+ */
445
+ public function doUpgrade($command, $options, $params)
446
+ {
447
+ $options['title'] = "Package upgraded: ";
448
+ return $this->doInstall($command, $options, $params);
449
+ }
450
+
451
+ /**
452
+ * Updgrade action callback
453
+ *
454
+ * @param string $command
455
+ * @param array $options
456
+ * @param array $params
457
+ * @return array|null
458
+ */
459
+ public function doUpgradeAll($command, $options, $params)
460
+ {
461
+ $options['title'] = "Package upgraded: ";
462
+ return $this->doInstall($command, $options, $params);
463
+ }
464
+
465
+ /**
466
+ * Uninstall package callback
467
+ *
468
+ * @param string $command
469
+ * @param array $options
470
+ * @param array $params
471
+ * @return array|null
472
+ */
473
+ public function doUninstall($command, $options, $params)
474
+ {
475
+ $this->cleanupParams($params);
476
+
477
+ try {
478
+ if (count($params) != 2) {
479
+ throw new Exception("Argument count should be = 2");
480
+ }
481
+
482
+ $channel = $params[0];
483
+ $package = $params[1];
484
+ /** @var $packager Mage_Connect_Packager */
485
+ $packager = $this->getPackager();
486
+ $withDepsMode = !isset($options['nodeps'])? false : (boolean)$options['nodeps'];
487
+ $forceMode = isset($options['force']);
488
+
489
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
490
+ /** @var $cache Mage_Connect_Singleconfig */
491
+ /** @var $config Mage_Connect_Config */
492
+ /** @var $ftpObj Mage_Connect_Ftp */
493
+ if ($ftp) {
494
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
495
+ } else {
496
+ $cache = $this->getSconfig();
497
+ $config = $this->config();
498
+ }
499
+
500
+ $channel = $cache->chanName($channel);
501
+ if (!$cache->hasPackage($channel, $package)) {
502
+ throw new Exception("Package is not installed");
503
+ }
504
+
505
+ $deletedPackages = array();
506
+ $list = $packager->getUninstallList($channel, $package, $cache, $config, $withDepsMode);
507
+ foreach ($list['list'] as $packageData) {
508
+ try {
509
+ $reqd = $cache->requiredByOtherPackages(
510
+ $packageData['channel'],
511
+ $packageData['name'],
512
+ $list['list']
513
+ );
514
+ if (count($reqd)) {
515
+ $errMessage = "{$packageData['channel']}/{$packageData['name']} "
516
+ . "{$packageData['version']} is required by: ";
517
+ $t = array();
518
+ foreach ($reqd as $r) {
519
+ $t[] = $r['channel'] . "/" . $r['name'] . " " . $r['version'];
520
+ }
521
+ $errMessage .= implode(", ", $t);
522
+ if ($forceMode) {
523
+ $this->ui()->output("Warning: " . $errMessage);
524
+ } else {
525
+ throw new Exception($errMessage);
526
+ }
527
+ }
528
+ } catch(Exception $e) {
529
+ if ($forceMode) {
530
+ $this->doError($command, $e->getMessage());
531
+ } else {
532
+ throw new Exception($e->getMessage());
533
+ }
534
+ }
535
+ }
536
+ foreach ($list['list'] as $packageData) {
537
+ try {
538
+ list($chan, $pack) = array($packageData['channel'], $packageData['name']);
539
+ $packageName = $packageData['channel'] . "/" . $packageData['name'];
540
+ $this->ui()->output("Starting to uninstall $packageName ");
541
+ if ($ftp) {
542
+ $packager->processUninstallPackageFtp($chan, $pack, $cache, $ftpObj);
543
+ } else {
544
+ $packager->processUninstallPackage($chan, $pack, $cache, $config);
545
+ }
546
+ $cache->deletePackage($chan, $pack);
547
+ $deletedPackages[] = array($chan, $pack);
548
+ $this->ui()->output("Package {$packageName} uninstalled");
549
+ } catch(Exception $e) {
550
+ if ($forceMode) {
551
+ $this->doError($command, $e->getMessage());
552
+ } else {
553
+ throw new Exception($e->getMessage());
554
+ }
555
+ }
556
+ }
557
+ if ($ftp) {
558
+ $packager->writeToRemoteCache($cache, $ftpObj);
559
+ @unlink($config->getFilename());
560
+ }
561
+ $out = array($command=>array('data'=>$deletedPackages, 'title'=>'Package deleted: '));
562
+ $this->ui()->output($out);
563
+ return $out[$command]['data'];
564
+ } catch (Exception $e) {
565
+ return $this->doError($command, $e->getMessage());
566
+ }
567
+ }
568
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Install_Header.php ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ $commands = array(
28
+
29
+ 'install-file' => array(
30
+ 'summary' => 'Install Package Archive File',
31
+ 'function' => 'doInstall',
32
+ 'shortcut' => 'if',
33
+ 'options' => array(),
34
+ 'doc' => '',
35
+ ),
36
+ 'install' => array(
37
+ 'summary' => 'Install Package',
38
+ 'function' => 'doInstall',
39
+ 'shortcut' => 'i',
40
+ 'options' => array(
41
+ 'force' => array(
42
+ 'shortopt' => 'f',
43
+ 'doc' => 'will overwrite newer installed packages',
44
+ ),
45
+ 'loose' => array(
46
+ 'shortopt' => 'l',
47
+ 'doc' => 'do not check for recommended dependency version',
48
+ ),
49
+ 'nodeps' => array(
50
+ 'shortopt' => 'n',
51
+ 'doc' => 'ignore dependencies, install anyway',
52
+ ),
53
+ 'ignore-errors' => array(
54
+ 'doc' => 'force install even if there were errors',
55
+ ),
56
+ 'alldeps' => array(
57
+ 'shortopt' => 'a',
58
+ 'doc' => 'install all required and optional dependencies',
59
+ ),
60
+ 'pretend' => array(
61
+ 'shortopt' => 'p',
62
+ 'doc' => 'Only list the packages that would be downloaded',
63
+ ),
64
+ 'ftp=' => array(
65
+ 'shortopt' => 'r=',
66
+ 'doc' => 'Remote side FTP connect string',
67
+ ),
68
+ ),
69
+ 'doc' => '[channel/]<package> ...
70
+ Installs one or more PEAR packages. You can specify a package to
71
+ install in four ways:
72
+
73
+ "Package-1.0.tgz" : installs from a local file
74
+
75
+ "http://example.com/Package-1.0.tgz" : installs from
76
+ anywhere on the net.
77
+
78
+ "package.xml" : installs the package described in
79
+ package.xml. Useful for testing, or for wrapping a PEAR package in
80
+ another package manager such as RPM.
81
+
82
+ "Package[-version/state][.tar]" : queries your default channel\'s server
83
+ ({config master_server}) and downloads the newest package with
84
+ the preferred quality/state ({config preferred_state}).
85
+
86
+ To retrieve Package version 1.1, use "Package-1.1," to retrieve
87
+ Package state beta, use "Package-beta." To retrieve an uncompressed
88
+ file, append .tar (make sure there is no file by the same name first)
89
+
90
+ To download a package from another channel, prefix with the channel name like
91
+ "channel/Package"
92
+
93
+ More than one package may be specified at once. It is ok to mix these
94
+ four ways of specifying packages.
95
+ '),
96
+ 'upgrade' => array(
97
+ 'summary' => 'Upgrade Package',
98
+ 'function' => 'doUpgrade',
99
+ 'shortcut' => 'up',
100
+ 'options' => array(
101
+ 'channel' => array(
102
+ 'shortopt' => 'c',
103
+ 'doc' => 'upgrade packages from a specific channel',
104
+ 'arg' => 'CHAN',
105
+ ),
106
+ 'force' => array(
107
+ 'shortopt' => 'f',
108
+ 'doc' => 'overwrite newer installed packages',
109
+ ),
110
+ 'loose' => array(
111
+ 'shortopt' => 'l',
112
+ 'doc' => 'do not check for recommended dependency version',
113
+ ),
114
+ 'nodeps' => array(
115
+ 'shortopt' => 'n',
116
+ 'doc' => 'ignore dependencies, upgrade anyway',
117
+ ),
118
+ 'register-only' => array(
119
+ 'shortopt' => 'r',
120
+ 'doc' => 'do not install files, only register the package as upgraded',
121
+ ),
122
+ 'nobuild' => array(
123
+ 'shortopt' => 'B',
124
+ 'doc' => 'don\'t build C extensions',
125
+ ),
126
+ 'nocompress' => array(
127
+ 'shortopt' => 'Z',
128
+ 'doc' => 'request uncompressed files when downloading',
129
+ ),
130
+ 'installroot' => array(
131
+ 'shortopt' => 'R',
132
+ 'arg' => 'DIR',
133
+ 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)',
134
+ ),
135
+ 'ignore-errors' => array(
136
+ 'doc' => 'force install even if there were errors',
137
+ ),
138
+ 'alldeps' => array(
139
+ 'shortopt' => 'a',
140
+ 'doc' => 'install all required and optional dependencies',
141
+ ),
142
+ 'onlyreqdeps' => array(
143
+ 'shortopt' => 'o',
144
+ 'doc' => 'install all required dependencies',
145
+ ),
146
+ 'offline' => array(
147
+ 'shortopt' => 'O',
148
+ 'doc' => 'do not attempt to download any urls or contact channels',
149
+ ),
150
+ 'pretend' => array(
151
+ 'shortopt' => 'p',
152
+ 'doc' => 'Only list the packages that would be downloaded',
153
+ ),
154
+ ),
155
+ 'doc' => '<package> ...
156
+ Upgrades one or more PEAR packages. See documentation for the
157
+ "install" command for ways to specify a package.
158
+
159
+ When upgrading, your package will be updated if the provided new
160
+ package has a higher version number (use the -f option if you need to
161
+ upgrade anyway).
162
+
163
+ More than one package may be specified at once.
164
+ '),
165
+ 'upgrade-all' => array(
166
+ 'summary' => 'Upgrade All Packages',
167
+ 'function' => 'doUpgradeAll',
168
+ 'shortcut' => 'ua',
169
+ 'options' => array(
170
+ 'channel' => array(
171
+ 'shortopt' => 'c',
172
+ 'doc' => 'upgrade packages from a specific channel',
173
+ 'arg' => 'CHAN',
174
+ ),
175
+ 'nodeps' => array(
176
+ 'shortopt' => 'n',
177
+ 'doc' => 'ignore dependencies, upgrade anyway',
178
+ ),
179
+ 'register-only' => array(
180
+ 'shortopt' => 'r',
181
+ 'doc' => 'do not install files, only register the package as upgraded',
182
+ ),
183
+ 'nobuild' => array(
184
+ 'shortopt' => 'B',
185
+ 'doc' => 'don\'t build C extensions',
186
+ ),
187
+ 'nocompress' => array(
188
+ 'shortopt' => 'Z',
189
+ 'doc' => 'request uncompressed files when downloading',
190
+ ),
191
+ 'installroot' => array(
192
+ 'shortopt' => 'R',
193
+ 'arg' => 'DIR',
194
+ 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
195
+ ),
196
+ 'ignore-errors' => array(
197
+ 'doc' => 'force install even if there were errors',
198
+ ),
199
+ 'loose' => array(
200
+ 'doc' => 'do not check for recommended dependency version',
201
+ ),
202
+ ),
203
+ 'doc' => '
204
+ WARNING: This function is deprecated in favor of using the upgrade command with no params
205
+
206
+ Upgrades all packages that have a newer release available. Upgrades are
207
+ done only if there is a release available of the state specified in
208
+ "preferred_state" (currently {config preferred_state}), or a state considered
209
+ more stable.
210
+ '),
211
+ 'uninstall' => array(
212
+ 'summary' => 'Un-install Package',
213
+ 'function' => 'doUninstall',
214
+ 'shortcut' => 'un',
215
+ 'options' => array(
216
+ 'nodeps' => array(
217
+ 'shortopt' => 'n',
218
+ 'doc' => 'ignore dependencies, uninstall anyway',
219
+ ),
220
+ 'register-only' => array(
221
+ 'shortopt' => 'r',
222
+ 'doc' => 'do not remove files, only register the packages as not installed',
223
+ ),
224
+ 'ignore-errors' => array(
225
+ 'doc' => 'force install even if there were errors',
226
+ ),
227
+ 'offline' => array(
228
+ 'shortopt' => 'O',
229
+ 'doc' => 'do not attempt to uninstall remotely',
230
+ ),
231
+ ),
232
+ 'doc' => '[channel/]<package> ...
233
+ Uninstalls one or more PEAR packages. More than one package may be
234
+ specified at once. Prefix with channel name to uninstall from a
235
+ channel not in your default channel ({config default_channel})
236
+ '),
237
+ );
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Package.php ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ final class Mage_Connect_Command_Package
28
+ extends Mage_Connect_Command
29
+ {
30
+ /**
31
+ * Dependencies list
32
+ * @var array
33
+ */
34
+ private $_depsList = array();
35
+
36
+ /**
37
+ * Releases list
38
+ * @var array
39
+ */
40
+ private $_releasesList = array();
41
+
42
+ /**
43
+ * Package command callback
44
+ * @param string $command
45
+ * @param array $options
46
+ * @param array $params
47
+ * @return void
48
+ */
49
+ public function doPackage($command, $options, $params)
50
+ {
51
+ $this->cleanupParams($params);
52
+
53
+ if(count($params) < 1) {
54
+ return $this->doError($command, "Parameters count should be >= 1");
55
+ }
56
+
57
+ $file = strtolower($params[0]);
58
+ $file = realpath($file);
59
+
60
+ if(!file_exists($file)) {
61
+ return $this->doError($command, "File {$params[0]} doesn't exist");
62
+ }
63
+
64
+ try {
65
+ $packager = new Mage_Connect_Package($file);
66
+ $res = $packager->validate();
67
+ if(!$res) {
68
+ $this->doError($command, implode("\n", $packager->getErrors()));
69
+ return;
70
+ }
71
+ $packager->save(dirname($file));
72
+ $this->ui()->output('Done building package');
73
+ } catch (Exception $e) {
74
+ $this->doError( $command, $e->getMessage() );
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Display/get installation information for package
80
+ * @param string $command
81
+ * @param array $options
82
+ * @param array $params
83
+ * @return void/array
84
+ */
85
+ public function doPackagePrepare($command, $options, $params)
86
+ {
87
+ $this->cleanupParams($params);
88
+ $channelAuth = array();
89
+ if (isset($options['auth'])) {
90
+ $channelAuth = $options['auth'];
91
+ $options['auth'] = null;
92
+ }
93
+ try {
94
+
95
+ if(count($params) < 2) {
96
+ return $this->doError($command, "Argument count should be >= 2");
97
+ }
98
+
99
+ $channel = $params[0];
100
+ $package = $params[1];
101
+
102
+ $argVersionMin = isset($params[3]) ? $params[3] : false;
103
+ $argVersionMax = isset($params[2]) ? $params[2] : false;
104
+
105
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
106
+ $packager = $this->getPackager();
107
+ if ($ftp) {
108
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
109
+ } else {
110
+ $cache = $this->getSconfig();
111
+ $config = $this->config();
112
+ }
113
+
114
+ $rest = Mage_Connect_Rest_Builder::getAdapter($config->protocol);
115
+ if(!empty($channelAuth)){
116
+ $rest->getLoader()->setCredentials($channelAuth['username'], $channelAuth['password']);
117
+ }
118
+
119
+ $cache->checkChannel($channel, $config, $rest);
120
+
121
+ $data = $packager->getDependenciesList($channel, $package, $cache, $config,
122
+ $argVersionMax, $argVersionMin, true, false, $rest
123
+ );
124
+
125
+ $result = array();
126
+ foreach ($data['result'] as $_package) {
127
+ $_result['channel'] = $_package['channel'];
128
+ $_result['name'] = $_package['name'];
129
+ $_result['version'] = $_package['downloaded_version'];
130
+ $_result['stability'] = $_package['stability'];
131
+ $_result['install_state'] = $_package['install_state'];
132
+ $_result['message'] = $_package['message'];
133
+ $result[] = $_result;
134
+ }
135
+ if (!count($data['result']) && isset($data['failed']) && !empty($data['failed'])) {
136
+ foreach ($data['failed'] as $_package) {
137
+ $reason = $_package['channel'] . '/' . $_package['name'] . ': ' . $_package['reason'];
138
+ $this->doError($command, $reason);
139
+ }
140
+ }
141
+
142
+ $this->ui()->output(
143
+ array(
144
+ $command=> array(
145
+ 'data'=>$result,
146
+ 'title'=>"Package installation information for {$params[1]}: "
147
+ )
148
+ )
149
+ );
150
+
151
+ } catch (Exception $e) {
152
+ $this->doError($command, $e->getMessage());
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Display/get dependencies
158
+ * @param string $command
159
+ * @param array $options
160
+ * @param array $params
161
+ * @return void/array
162
+ */
163
+ public function doPackageDependencies($command, $options, $params)
164
+ {
165
+ $this->cleanupParams($params);
166
+ try {
167
+ if(count($params) < 2) {
168
+ return $this->doError($command, "Argument count should be >= 2");
169
+ }
170
+
171
+ $channel = $params[0];
172
+ $package = $params[1];
173
+
174
+ $argVersionMin = isset($params[3]) ? $params[3] : false;
175
+ $argVersionMax = isset($params[2]) ? $params[2] : false;
176
+
177
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
178
+ $packager = $this->getPackager();
179
+ if($ftp) {
180
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
181
+ } else {
182
+ $cache = $this->getSconfig();
183
+ $config = $this->config();
184
+ }
185
+ $data = $packager->getDependenciesList(
186
+ $channel,
187
+ $package,
188
+ $cache,
189
+ $config,
190
+ $argVersionMax,
191
+ $argVersionMin
192
+ );
193
+ $this->ui()->output(
194
+ array(
195
+ $command=> array(
196
+ 'data'=>$data['deps'],
197
+ 'title'=>"Package deps for {$params[1]}: "
198
+ )
199
+ )
200
+ );
201
+
202
+ } catch (Exception $e) {
203
+ $this->doError($command, $e->getMessage());
204
+ }
205
+ }
206
+
207
+ public function doConvert($command, $options, $params)
208
+ {
209
+ $this->cleanupParams($params);
210
+ try {
211
+ if (count($params) < 1) {
212
+ throw new Exception("Arguments should be: source.tgz [target.tgz]");
213
+ }
214
+ $sourceFile = $params[0];
215
+ $converter = new Mage_Connect_Converter();
216
+ $targetFile = isset($params[1]) ? $params[1] : false;
217
+ $result = $converter->convertPearToMage($sourceFile, $targetFile);
218
+ $this->ui()->output("Saved to: ".$result);
219
+ } catch (Exception $e) {
220
+ $this->doError($command, $e->getMessage());
221
+ }
222
+
223
+ }
224
+
225
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Package_Header.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ $commands = array(
28
+ 'package' => array(
29
+ 'summary' => 'Build Package',
30
+ 'function' => 'doPackage',
31
+ 'shortcut' => 'p',
32
+ 'options' => array(
33
+ 'nocompress' => array(
34
+ 'shortopt' => 'Z',
35
+ 'doc' => 'Do not gzip the package file'
36
+ ),
37
+ 'showname' => array(
38
+ 'shortopt' => 'n',
39
+ 'doc' => 'Print the name of the packaged file.',
40
+ ),
41
+ ),
42
+ 'doc' => '[descfile] [descfile2]
43
+ Creates a PEAR package from its description file (usually called
44
+ package.xml). If a second packagefile is passed in, then
45
+ the packager will check to make sure that one is a package.xml
46
+ version 1.0, and the other is a package.xml version 2.0. The
47
+ package.xml version 1.0 will be saved as "package.xml" in the archive,
48
+ and the other as "package2.xml" in the archive"
49
+ '
50
+ ),
51
+ 'package-dependencies' => array(
52
+ 'summary' => 'Show package dependencies',
53
+ 'function' => 'doPackageDependencies',
54
+ 'shortcut' => 'pd',
55
+ 'options' => array(),
56
+ 'doc' => '<package-file> or <package.xml> or <install-package-name>
57
+ List all dependencies the package has.
58
+ Can take a tgz / tar file, package.xml or a package name of an installed package.'
59
+ ),
60
+ 'package-prepare' => array(
61
+ 'summary' => 'Show installation information of package',
62
+ 'function' => 'doPackagePrepare',
63
+ 'shortcut' => 'pp',
64
+ 'options' => array(),
65
+ 'doc' => '<package-file> or <package.xml> or <install-package-name>
66
+ List all dependencies the package has.
67
+ Can take a tgz / tar file, package.xml or a package name of an installed package.'
68
+ ),
69
+ 'convert' => array(
70
+ 'summary' => 'Convert old magento PEAR package to new format',
71
+ 'function' => 'doConvert',
72
+ 'shortcut' => 'conv',
73
+ 'options' => array(),
74
+ 'doc' => ''
75
+ ),
76
+ );
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Registry.php ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ final class Mage_Connect_Command_Registry
28
+ extends Mage_Connect_Command
29
+ {
30
+ const PACKAGE_PEAR_DIR = 'pearlib/php/.registry';
31
+
32
+ /**
33
+ * List-installed callback
34
+ * @param string $command
35
+ * @param array $options
36
+ * @param array $params
37
+ * @return void
38
+ */
39
+ public function doList($command, $options, $params)
40
+ {
41
+ $this->cleanupParams($params);
42
+ try {
43
+ $packager = $this->getPackager();
44
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
45
+ if($ftp) {
46
+ list($cache, $ftpObj) = $packager->getRemoteCache($ftp);
47
+ } else {
48
+ $cache = $this->getSconfig();
49
+ }
50
+ if(!empty($params[0])) {
51
+ $chanName = $conf->chanName($params[0]);
52
+ $data = $cache->getInstalledPackages($chanName);
53
+ } else {
54
+ $data = $cache->getInstalledPackages();
55
+ }
56
+ if($ftp) {
57
+ @unlink($cache->getFilename());
58
+ }
59
+ $this->ui()->output(array($command=>array('data'=>$data, 'channel-title'=>"Installed package for channel '%s' :")));
60
+ } catch (Exception $e) {
61
+ if($ftp) {
62
+ @unlink($cache->getFilename());
63
+ }
64
+ $this->doError($command, $e->getMessage());
65
+ }
66
+
67
+ }
68
+
69
+ /**
70
+ * list-files callback
71
+ * @param string $command
72
+ * @param array $options
73
+ * @param array $params
74
+ * @return void
75
+ */
76
+ public function doFileList($command, $options, $params)
77
+ {
78
+ $this->cleanupParams($params);
79
+ //$this->splitPackageArgs($params);
80
+ try {
81
+ $channel = false;
82
+ if(count($params) < 2) {
83
+ throw new Exception("Argument count should be = 2");
84
+ }
85
+ $channel = $params[0];
86
+ $package = $params[1];
87
+
88
+ $packager = $this->getPackager();
89
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
90
+ if($ftp) {
91
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
92
+ } else {
93
+ $cache = $this->getSconfig();
94
+ $confif = $this->config();
95
+ }
96
+ if(!$cache->hasPackage($channel, $package)) {
97
+ return $this->ui()->output("No package found: {$channel}/{$package}");
98
+ }
99
+
100
+ $p = $cache->getPackageObject($channel, $package);
101
+ $contents = $p->getContents();
102
+ if($ftp) {
103
+ $ftpObj->close();
104
+ }
105
+ if(!count($contents)) {
106
+ return $this->ui()->output("No contents for package {$package}");
107
+ }
108
+ $title = ("Contents of '{$package}': ");
109
+ if($ftp) {
110
+ @unlink($config->getFilename());
111
+ @unlink($cache->getFilename());
112
+ }
113
+
114
+ $this->ui()->output(array($command=>array('data'=>$contents, 'title'=>$title)));
115
+
116
+ } catch (Exception $e) {
117
+ if($ftp) {
118
+ @unlink($config->getFilename());
119
+ @unlink($cache->getFilename());
120
+ }
121
+ $this->doError($command, $e->getMessage());
122
+ }
123
+
124
+ }
125
+
126
+ /**
127
+ * Installed package info
128
+ * info command callback
129
+ * @param string $command
130
+ * @param array $options
131
+ * @param array $params
132
+ * @return
133
+ */
134
+ public function doInfo($command, $options, $params)
135
+ {
136
+ $this->cleanupParams($params);
137
+ //$this->splitPackageArgs($params);
138
+
139
+ $cache = null;
140
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
141
+ try {
142
+ $channel = false;
143
+ if(count($params) < 2) {
144
+ throw new Exception("Argument count should be = 2");
145
+ }
146
+ $channel = $params[0];
147
+ $package = $params[1];
148
+ $packager = $this->getPackager();
149
+ if($ftp) {
150
+ list($cache, $ftpObj) = $packager->getRemoteCache($ftp);
151
+ } else {
152
+ $cache = $this->getSconfig();
153
+ }
154
+
155
+ if(!$cache->isChannel($channel)) {
156
+ throw new Exception("'{$channel}' is not a valid installed channel name/uri");
157
+ }
158
+ $channelUri = $cache->chanUrl($channel);
159
+ $rest = $this->rest();
160
+ $rest->setChannel($channelUri);
161
+ $releases = $rest->getReleases($package);
162
+ if(false === $releases) {
163
+ throw new Exception("No information found about {$channel}/{$package}");
164
+ }
165
+ $data = array($command => array('releases'=>$releases));
166
+ if($ftp) {
167
+ @unlink($cache->getFilename());
168
+ }
169
+ $this->ui()->output($data);
170
+ } catch (Exception $e) {
171
+ if ($ftp && isset($cache)) {
172
+ @unlink($cache->getFilename());
173
+ }
174
+ $this->doError($command, $e->getMessage());
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Synchronize manually installed package info with local cache
180
+ *
181
+ * @param string $command
182
+ * @param array $options
183
+ * @param array $params
184
+ */
185
+ public function doSync($command, $options, $params)
186
+ {
187
+ $this->cleanupParams($params);
188
+ try {
189
+ $packager = $this->getPackager();
190
+ $cache = null;
191
+ $config = null;
192
+ $ftpObj = null;
193
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
194
+ if($ftp) {
195
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
196
+ } else {
197
+ $config = $this->config();
198
+ $cache = $this->getSconfig();
199
+ }
200
+ if ($this->_checkPearData($config)) {
201
+ $this->doSyncPear($command, $options, $params);
202
+ }
203
+
204
+ $packageDir = $config->magento_root . DS . Mage_Connect_Package::PACKAGE_XML_DIR;
205
+ if (is_dir($packageDir)) {
206
+ $entries = scandir($packageDir);
207
+ foreach ((array)$entries as $entry) {
208
+ $path = $packageDir. DS .$entry;
209
+ $info = pathinfo($path);
210
+ if ($entry == '.' || $entry == '..' || is_dir($path) || $info['extension'] != 'xml') {
211
+ continue;
212
+ }
213
+
214
+ if (is_readable($path)) {
215
+ $data = file_get_contents($path);
216
+ if ($data === false) {
217
+ continue;
218
+ }
219
+
220
+ $package = new Mage_Connect_Package($data);
221
+ $name = $package->getName();
222
+ $channel = $package->getChannel();
223
+ $version = $package->getVersion();
224
+ if (!$cache->isChannel($channel) && $channel == $config->root_channel) {
225
+ $cache->addChannel($channel, $config->root_channel_uri);
226
+ }
227
+ if (!$cache->hasPackage($channel, $name, $version, $version)) {
228
+ $cache->addPackage($package);
229
+ $this->ui()->output("Successfully added: {$channel}/{$name}-{$version}");
230
+ }
231
+ }
232
+ }
233
+ if ($ftp) {
234
+ $packager->writeToRemoteCache($cache, $ftpObj);
235
+ }
236
+ }
237
+ } catch (Exception $e) {
238
+ $this->doError($command, $e->getMessage());
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Synchronize packages installed earlier (by pear installer) with local cache
244
+ *
245
+ * @param string $command
246
+ * @param array $options
247
+ * @param array $params
248
+ */
249
+ public function doSyncPear($command, $options, $params)
250
+ {
251
+ $this->cleanupParams($params);
252
+ try {
253
+ $packager = $this->getPackager();
254
+ $cache = null;
255
+ $config = null;
256
+ $ftpObj = null;
257
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
258
+ if($ftp) {
259
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
260
+ } else {
261
+ $config = $this->config();
262
+ $cache = $this->getSconfig();
263
+ }
264
+
265
+ $pkglist = array();
266
+ if (!$this->_checkPearData($config)) {
267
+ return $pkglist;
268
+ }
269
+
270
+ $pearStorage = $config->magento_root . DS . $config->downloader_path . DS . self::PACKAGE_PEAR_DIR;
271
+ $channels = array(
272
+ '.channel.connect.magentocommerce.com_community',
273
+ '.channel.connect.magentocommerce.com_core'
274
+ );
275
+ foreach ($channels as $channel) {
276
+ $channelDirectory = $pearStorage . DS . $channel;
277
+ if (!file_exists($channelDirectory) || !is_dir($channelDirectory)) {
278
+ continue;
279
+ }
280
+
281
+ $dp = opendir($channelDirectory);
282
+ if (!$dp) {
283
+ continue;
284
+ }
285
+
286
+ while ($ent = readdir($dp)) {
287
+ if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
288
+ continue;
289
+ }
290
+ $pkglist[] = array('file'=>$ent, 'channel'=>$channel);
291
+ }
292
+ closedir($dp);
293
+ }
294
+
295
+ $package = new Mage_Connect_Package();
296
+ foreach ($pkglist as $pkg) {
297
+ $pkgFilename = $pearStorage . DS . $pkg['channel'] . DS . $pkg['file'];
298
+ if (!file_exists($pkgFilename)) {
299
+ continue;
300
+ }
301
+ $data = file_get_contents($pkgFilename);
302
+ $data = unserialize($data);
303
+
304
+ $package->importDataV1x($data);
305
+ $name = $package->getName();
306
+ $channel = $package->getChannel();
307
+ $version = $package->getVersion();
308
+ if (!$cache->isChannel($channel) && $channel == $config->root_channel) {
309
+ $cache->addChannel($channel, $config->root_channel_uri);
310
+ }
311
+ if (!$cache->hasPackage($channel, $name, $version, $version)) {
312
+ $cache->addPackage($package);
313
+
314
+ if($ftp) {
315
+ $localXml = tempnam(sys_get_temp_dir(),'package');
316
+ @file_put_contents($localXml, $package->getPackageXml());
317
+
318
+ if (is_file($localXml)) {
319
+ $ftpDir = $ftpObj->getcwd();
320
+ $remoteXmlPath = $ftpDir . '/' . Mage_Connect_Package::PACKAGE_XML_DIR;
321
+ $remoteXml = $package->getReleaseFilename() . '.xml';
322
+ $ftpObj->mkdirRecursive($remoteXmlPath);
323
+ $ftpObj->upload($remoteXml, $localXml, 0777, 0666);
324
+ $ftpObj->chdir($ftpDir);
325
+ }
326
+ } else {
327
+ $destDir = rtrim($config->magento_root, "\\/") . DS . Mage_Connect_Package::PACKAGE_XML_DIR;
328
+ $destFile = $package->getReleaseFilename() . '.xml';
329
+ $dest = $destDir . DS . $destFile;
330
+
331
+ @mkdir($destDir, 0777, true);
332
+ @file_put_contents($dest, $package->getPackageXml());
333
+ @chmod($dest, 0666);
334
+ }
335
+
336
+ $this->ui()->output("Successfully added: {$channel}/{$name}-{$version}");
337
+ }
338
+
339
+ }
340
+
341
+ $config->sync_pear = true;
342
+ if($ftp) {
343
+ $packager->writeToRemoteCache($cache, $ftpObj);
344
+ @unlink($config->getFilename());
345
+ }
346
+ } catch (Exception $e) {
347
+ $this->doError($command, $e->getMessage());
348
+ }
349
+
350
+ return true;
351
+ }
352
+
353
+ /**
354
+ * Check is need to sync old pear data
355
+ *
356
+ * @param Mage_Connect_Config $config
357
+ * @return boolean
358
+ */
359
+ protected function _checkPearData($config) {
360
+ $pearStorage = $config->magento_root . DS . $config->downloader_path . DS . self::PACKAGE_PEAR_DIR;
361
+ return (!$config->sync_pear) && file_exists($pearStorage) && is_dir($pearStorage);
362
+ }
363
+
364
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Registry_Header.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ $commands = array(
28
+ 'list-installed' => array(
29
+ 'summary' => 'List Installed Packages In The Default Channel',
30
+ 'function' => 'doList',
31
+ 'shortcut' => 'l',
32
+ 'options' => array(
33
+ 'channel' => array(
34
+ 'shortopt' => 'c',
35
+ 'doc' => 'list installed packages from this channel',
36
+ 'arg' => 'CHAN',
37
+ ),
38
+ 'allchannels' => array(
39
+ 'shortopt' => 'a',
40
+ 'doc' => 'list installed packages from all channels',
41
+ ),
42
+ ),
43
+ 'doc' => '<package>
44
+ If invoked without parameters, this command lists the PEAR packages
45
+ installed in your php_dir ({config php_dir}). With a parameter, it
46
+ lists the files in a package.
47
+ ',
48
+ ),
49
+ 'list-files' => array(
50
+ 'summary' => 'List Files In Installed Package',
51
+ 'function' => 'doFileList',
52
+ 'shortcut' => 'fl',
53
+ 'options' => array(),
54
+ 'doc' => '<package>
55
+ List the files in an installed package.
56
+ '
57
+ ),
58
+ 'info' => array(
59
+ 'summary' => 'Display information about a package',
60
+ 'function' => 'doInfo',
61
+ 'shortcut' => 'in',
62
+ 'options' => array(),
63
+ 'doc' => '<package>
64
+ Displays information about a package. The package argument may be a
65
+ local package file, an URL to a package file, or the name of an
66
+ installed package.'
67
+ ),
68
+ 'sync' => array(
69
+ 'summary' => 'Synchronize Manually Installed Packages',
70
+ 'function' => 'doSync',
71
+ 'shortcut' => 'snc',
72
+ 'options' => array(),
73
+ 'doc' => '<package>
74
+ Synchronize manually installed package info with local cache.'
75
+ ),
76
+ 'sync-pear' => array(
77
+ 'summary' => 'Synchronize already Installed Packages by pear',
78
+ 'function' => 'doSyncPear',
79
+ 'shortcut' => 'sncp',
80
+ 'options' => array(),
81
+ 'doc' => '<package>
82
+ Synchronize already Installed Packages by pear.'
83
+ )
84
+ );
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Remote.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ final class Mage_Connect_Command_Remote
28
+ extends Mage_Connect_Command
29
+ {
30
+
31
+ /**
32
+ * List-upgrades callback
33
+ * @param srting $command
34
+ * @param array $options
35
+ * @param array $params
36
+ * @return void
37
+ */
38
+ public function doListUpgrades($command, $options, $params)
39
+ {
40
+
41
+ $this->cleanupParams($params);
42
+ try {
43
+ $packager = new Mage_Connect_Packager();
44
+ $channelAuth = isset($options['auth'])?$options['auth']:array();
45
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
46
+ if($ftp) {
47
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
48
+ } else {
49
+ $cache = $this->getSconfig();
50
+ $config = $this->config();
51
+ }
52
+
53
+ if(!empty($params[0])) {
54
+ $channels = $params[0];
55
+ $cache->getChannel($channels);
56
+ } else {
57
+ $channels = $cache->getChannelNames();
58
+ }
59
+ $rest = $this->rest();
60
+ if(!empty($channelAuth)){
61
+ $rest->getLoader()->setCredentials($channelAuth['username'], $channelAuth['password']);
62
+ }
63
+ $ups = $packager->getUpgradesList($channels, $cache, $config, $rest);
64
+
65
+ if(count($ups)) {
66
+ $data = array($command => array('data'=>$ups));
67
+ } else {
68
+ $data = "No upgrades available";
69
+ }
70
+ $this->ui()->output($data);
71
+ } catch(Exception $e) {
72
+ $this->doError($command, $e->getMessage());
73
+ }
74
+ }
75
+
76
+
77
+ /**
78
+ * List available
79
+ * @param $command
80
+ * @param $options
81
+ * @param $params
82
+ * @return unknown_type
83
+ */
84
+
85
+ public function doListAvailable($command, $options, $params)
86
+ {
87
+ $this->cleanupParams($params);
88
+
89
+ try {
90
+ $packager = new Mage_Connect_Packager();
91
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
92
+ if($ftp) {
93
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
94
+ } else {
95
+ $cache = $this->getSconfig();
96
+ $config = $this->config();
97
+ }
98
+
99
+ if(!empty($params[0])) {
100
+ $channels = array($params[0]);
101
+ $cache->getChannel($channels[0]);
102
+ } else {
103
+ $channels = $cache->getChannelNames();
104
+ }
105
+
106
+
107
+
108
+ $packs = array();
109
+ foreach ($channels as $channel) {
110
+ try {
111
+ $chan = $cache->getChannel($channel);
112
+ $uri = $cache->chanUrl($channel);
113
+
114
+ $rest = $this->rest();
115
+ $rest->setChannel($uri);
116
+
117
+ $packages = $rest->getPackages();
118
+ if(!count($packages)) {
119
+ $this->ui()->output("Channel '{$channel}' has no packages");
120
+ continue;
121
+ }
122
+ $packs[$channel]['title'] = "Packages for channel '".$channel."':";
123
+ foreach($packages as $p) {
124
+ $packageName = $p['n'];
125
+ $releases = array();
126
+ foreach($p['r'] as $k=>$r) {
127
+ $releases[$r] = $rest->shortStateToLong($k);
128
+ }
129
+ $packs[$channel]['packages'][$packageName]['releases'] = $releases;
130
+ }
131
+ } catch (Exception $e) {
132
+ $this->doError($command, $e->getMessage());
133
+ }
134
+ }
135
+ $dataOut = array();
136
+ $dataOut[$command]= array('data'=>$packs);
137
+ $this->ui()->output($dataOut);
138
+
139
+ } catch(Exception $e) {
140
+ $this->doError($command, $e->getMessage());
141
+ }
142
+
143
+ }
144
+
145
+ /**
146
+ * Download command callback
147
+ *
148
+ * @param string $command
149
+ * @param array $options
150
+ * @param array $params
151
+ * @return void
152
+ */
153
+ public function doDownload($command, $options, $params)
154
+ {
155
+ $this->cleanupParams($params);
156
+ //$this->splitPackageArgs($params);
157
+ try {
158
+ if(count($params) < 2) {
159
+ throw new Exception("Arguments should be: channel Package");
160
+ }
161
+
162
+ $channel = $params[0];
163
+ $package = $params[1];
164
+
165
+ $packager = $this->getPackager();
166
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
167
+ if($ftp) {
168
+ list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
169
+ } else {
170
+ $cache = $this->getSconfig();
171
+ $config = $this->config();
172
+ }
173
+
174
+ $chan = $cache->getChannel($channel);
175
+ $uri = $cache->chanUrl($channel);
176
+
177
+ $rest = $this->rest();
178
+ $rest->setChannel($uri);
179
+ $c = $rest->getReleases($package);
180
+ if(!count($c)) {
181
+ throw new Exception("No releases found for package");
182
+ }
183
+ $version = $cache->detectVersionFromRestArray($c);
184
+ $dir = $config->getChannelCacheDir($channel);
185
+ $file = $dir.DIRECTORY_SEPARATOR.$package."-".$version.".tgz";
186
+ $rest->downloadPackageFileOfRelease($package, $version, $file);
187
+ if($ftp) {
188
+ @unlink($config->getFilename());
189
+ @unlink($cache->getFilename());
190
+ }
191
+ $this->ui()->output("Saved to: ". $file);
192
+ } catch (Exception $e) {
193
+ if($ftp) {
194
+ @unlink($config->getFilename());
195
+ @unlink($cache->getFilename());
196
+ }
197
+ $this->doError($command, $e->getMessage());
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Clear cache command callback
203
+ * @param string $command
204
+ * @param array $options
205
+ * @param array $params
206
+ * @return void
207
+ */
208
+ public function doClearCache($command, $options, $params)
209
+ {
210
+ $this->cleanupParams($params);
211
+ try {
212
+ $packager = new Mage_Connect_Packager();
213
+ $ftp = empty($options['ftp']) ? false : $options['ftp'];
214
+ if($ftp) {
215
+ list($cache, $ftpObj) = $packager->getRemoteCache($ftp);
216
+ $cache->clear();
217
+ $packager->writeToRemoteCache($cache, $ftpObj);
218
+ } else {
219
+ $cache = $this->getSconfig();
220
+ $cache->clear();
221
+ }
222
+ } catch (Exception $e) {
223
+ $this->doError($command, $e->getMessage());
224
+ }
225
+ }
226
+
227
+
228
+
229
+
230
+
231
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Command/Remote_Header.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ $commands = array(
28
+ 'list-upgrades' => array(
29
+ 'summary' => 'List Available Upgrades',
30
+ 'function' => 'doListUpgrades',
31
+ 'shortcut' => 'lu',
32
+ 'options' => array(
33
+ 'channelinfo' => array(
34
+ 'shortopt' => 'i',
35
+ 'doc' => 'output fully channel-aware data, even on failure',
36
+ ),
37
+ ),
38
+ 'doc' => '[preferred_state]
39
+ List releases on the server of packages you have installed where
40
+ a newer version is available with the same release state (stable etc.)
41
+ or the state passed as the second parameter.'
42
+ ),
43
+ 'list-available' => array(
44
+ 'summary' => 'List Available Packages',
45
+ 'function' => 'doListAvailable',
46
+ 'shortcut' => 'la',
47
+ 'options' => array(
48
+ 'channel' =>
49
+ array(
50
+ 'shortopt' => 'c',
51
+ 'doc' => 'specify a channel other than the default channel',
52
+ 'arg' => 'CHAN',
53
+ ),
54
+ 'channelinfo' => array(
55
+ 'shortopt' => 'i',
56
+ 'doc' => 'output fully channel-aware data, even on failure',
57
+ ),
58
+ ),
59
+ 'doc' => '
60
+ Lists the packages available on the configured server along with the
61
+ latest stable release of each package.',
62
+ ),
63
+ 'download' => array(
64
+ 'summary' => 'Download Package',
65
+ 'function' => 'doDownload',
66
+ 'shortcut' => 'd',
67
+ 'options' => array(
68
+ 'nocompress' => array(
69
+ 'shortopt' => 'Z',
70
+ 'doc' => 'download an uncompressed (.tar) file',
71
+ ),
72
+ ),
73
+ 'doc' => '<package>...
74
+ Download package tarballs. The files will be named as suggested by the
75
+ server, for example if you download the DB package and the latest stable
76
+ version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.',
77
+ ),
78
+ 'clear-cache' => array(
79
+ 'summary' => 'Clear Web Services Cache',
80
+ 'function' => 'doClearCache',
81
+ 'shortcut' => 'cc',
82
+ 'options' => array(),
83
+ 'doc' => '
84
+ Clear the XML-RPC/REST cache. See also the cache_ttl configuration
85
+ parameter.
86
+ ',
87
+ ),
88
+ );
app/code/local/Mss/downloader/lib/Mage/Connect/Config.php ADDED
@@ -0,0 +1,617 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Magento Connect Config
29
+ *
30
+ * @property string php_ini
31
+ * @property string protocol
32
+ * @property string preferred_state
33
+ * @property string use_custom_permissions_mode
34
+ * @property string global_dir_mode
35
+ * @property string global_file_mode
36
+ * @property string downloader_path
37
+ * @property string magento_root
38
+ * @property string root_channel_uri
39
+ * @property string root_channel
40
+ * @property string remote_config
41
+ * @property string sync_pear
42
+ *
43
+ * @category Mage
44
+ * @package Mage_Connect
45
+ * @author Magento Core Team <core@magentocommerce.com>
46
+ */
47
+ class Mage_Connect_Config implements Iterator
48
+ {
49
+ /**
50
+ * Config file name
51
+ *
52
+ * @var string
53
+ */
54
+ protected $_configFile;
55
+
56
+ /**
57
+ * Config loaded from file
58
+ *
59
+ * @var bool
60
+ */
61
+ protected $_configLoaded;
62
+
63
+ /**
64
+ * Save file even if it not modified
65
+ *
66
+ * @var bool
67
+ */
68
+ protected $_forceSave = false;
69
+
70
+ /**
71
+ * Stores last error message
72
+ *
73
+ * @var string
74
+ */
75
+ protected $_configError = '';
76
+
77
+ /**
78
+ * Header string
79
+ */
80
+ const HEADER = "::ConnectConfig::v::1.0::";
81
+
82
+ /**
83
+ * Default paths
84
+ */
85
+ const DEFAULT_DOWNLOADER_PATH = "downloader";
86
+ const DEFAULT_CACHE_PATH = ".cache";
87
+
88
+ /**
89
+ * Array of default properties
90
+ * @var array
91
+ */
92
+ protected $defaultProperties = array();
93
+
94
+ /**
95
+ * Array of properties
96
+ *
97
+ * @var array
98
+ */
99
+ protected $properties = array();
100
+
101
+ /**
102
+ * Constructor loads the data from config file
103
+ * @param string $configFile
104
+ */
105
+ public function __construct($configFile = "connect.cfg")
106
+ {
107
+ $this->initProperties();
108
+ $this->_configFile = $configFile;
109
+ $this->load();
110
+ }
111
+
112
+ /**
113
+ * Initialise Properties and Default Properties
114
+ *
115
+ * @return void
116
+ */
117
+ protected function initProperties()
118
+ {
119
+ $this->defaultProperties = array (
120
+ 'php_ini' => array(
121
+ 'type' => 'file',
122
+ 'value' => '',
123
+ 'prompt' => 'location of php.ini',
124
+ 'doc' => "It's a location of PHP.ini to use blah",
125
+ 'possible' => '/path/php.ini',
126
+ ),
127
+ 'protocol' => array(
128
+ 'type' => 'set',
129
+ 'value' => 'https',
130
+ 'prompt' => 'preffered protocol',
131
+ 'doc' => 'preffered protocol',
132
+ 'rules' => array('http', 'ftp')
133
+ ),
134
+ 'preferred_state' => array(
135
+ 'type' => 'set',
136
+ 'value' => 'stable',
137
+ 'prompt' => 'preferred package state',
138
+ 'doc' => 'preferred package state',
139
+ 'rules' => array('beta','alpha','stable','devel')
140
+ ),
141
+ 'use_custom_permissions_mode' => array (
142
+ 'type' => 'bool',
143
+ 'value' => false,
144
+ 'prompt' => 'Use custom permissions for directory and file creation',
145
+ 'doc' => 'Use custom permissions for directory and file creation',
146
+ 'possible' => 'true, false',
147
+ ),
148
+ 'global_dir_mode' => array (
149
+ 'type' => 'octal',
150
+ 'value' => 0777,
151
+ 'prompt' => 'directory creation mode',
152
+ 'doc' => 'directory creation mode',
153
+ 'possible' => '0777, 0666 etc.',
154
+ ),
155
+ 'global_file_mode' => array (
156
+ 'type' => 'octal',
157
+ 'value' => 0666,
158
+ 'prompt' => 'file creation mode',
159
+ 'doc' => 'file creation mode',
160
+ 'possible' => '0777, 0666 etc.',
161
+ ),
162
+ 'downloader_path' => array(
163
+ 'type' => 'dir',
164
+ 'value' => 'downloader',
165
+ 'prompt' => 'relative path, location of magento downloader',
166
+ 'doc' => "relative path, location of magento downloader",
167
+ 'possible' => 'path',
168
+ ),
169
+ 'magento_root' => array(
170
+ 'type' => 'dir',
171
+ 'value' => '',
172
+ 'prompt' => 'location of magento root dir',
173
+ 'doc' => "Location of magento",
174
+ 'possible' => '/path',
175
+ ),
176
+ 'root_channel_uri' => array(
177
+ 'type' => 'string',
178
+ 'value' => 'connect20.magentocommerce.com/community',
179
+ 'prompt' => '',
180
+ 'doc' => "",
181
+ 'possible' => '',
182
+ ),
183
+ 'root_channel' => array(
184
+ 'type' => 'string',
185
+ 'value' => 'community',
186
+ 'prompt' => '',
187
+ 'doc' => "",
188
+ 'possible' => '',
189
+ ),
190
+ 'remote_config' => array(
191
+ 'type' => 'string',
192
+ 'value' => '',
193
+ 'prompt' => '',
194
+ 'doc' => "",
195
+ 'possible' => 'ftp://name:password@host.com:port/path/to/folder/',
196
+ ),
197
+ 'sync_pear' => array(
198
+ 'type' => 'boolean',
199
+ 'value' => false,
200
+ 'prompt' => '',
201
+ 'doc' => "",
202
+ 'possible' => '',
203
+ )
204
+ );
205
+ $this->properties = $this->defaultProperties;
206
+ }
207
+
208
+ /**
209
+ * Retrieve Downloader Path
210
+ *
211
+ * @return string
212
+ */
213
+ public function getDownloaderPath()
214
+ {
215
+ return $this->magento_root . DIRECTORY_SEPARATOR . $this->downloader_path;
216
+ }
217
+
218
+ /**
219
+ * Retrieve Packages Cache Directory
220
+ *
221
+ * @return string
222
+ */
223
+ public function getPackagesCacheDir()
224
+ {
225
+ return $this->getDownloaderPath() . DIRECTORY_SEPARATOR . self::DEFAULT_CACHE_PATH;
226
+ }
227
+
228
+ /**
229
+ * Retrieve Channel Cache Directory
230
+ *
231
+ * @param string $channel
232
+ * @return string
233
+ */
234
+ public function getChannelCacheDir($channel)
235
+ {
236
+ $channel = trim( $channel, "\\/");
237
+ return $this->getPackagesCacheDir(). DIRECTORY_SEPARATOR . $channel;
238
+ }
239
+
240
+ /**
241
+ * Get Config file name
242
+ *
243
+ * @return string
244
+ */
245
+ public function getFilename()
246
+ {
247
+ return $this->_configFile;
248
+ }
249
+
250
+ /**
251
+ * Load data from config file
252
+ *
253
+ * @return bool
254
+ */
255
+ public function load()
256
+ {
257
+ $this->_configLoaded=false;
258
+ if (!is_file($this->_configFile)) {
259
+ if (!$this->save()) {
260
+ $this->_configError = 'Config file does not exists please save Settings';
261
+ } else {
262
+ $this->_configLoaded=true;
263
+ return true;
264
+ }
265
+ return false;
266
+ }
267
+
268
+ try {
269
+ $f = fopen($this->_configFile, "r");
270
+ fseek($f, 0, SEEK_SET);
271
+ } catch (Exception $e) {
272
+ $this->_configError = "Cannot open config file {$this->_configFile} please check file permission";
273
+ return false;
274
+ }
275
+
276
+ clearstatcache();
277
+ $size = filesize($this->_configFile);
278
+ if (!$size) {
279
+ $this->_configError = "Wrong config file size {$this->_configFile} please save Settings again";
280
+ return false;
281
+ }
282
+
283
+ $headerLen = strlen(self::HEADER);
284
+ try {
285
+ $contents = fread($f, $headerLen);
286
+ if (self::HEADER != $contents) {
287
+ $this->_configError = "Wrong configuration file {$this->_configFile} please save Settings again";
288
+ return false;
289
+ }
290
+
291
+ $size -= $headerLen;
292
+ $contents = fread($f, $size);
293
+ } catch (Exception $e) {
294
+ $this->_configError = "Configuration file {$this->_configFile} read error '{$e->getMessage()}'"
295
+ . " please save Settings again";
296
+ return false;
297
+ }
298
+ $data = @unserialize($contents);
299
+ if ($data === false) {
300
+ $this->_configError = "Wrong configuration file {$this->_configFile} please save Settings again";
301
+ return false;
302
+ }
303
+ foreach($data as $k=>$v) {
304
+ $this->$k = $v;
305
+ }
306
+ @fclose($f);
307
+ $this->_configLoaded=true;
308
+ return true;
309
+ }
310
+
311
+ /**
312
+ * Save config file on the disk or over ftp
313
+ *
314
+ * @return bool
315
+ */
316
+ public function store()
317
+ {
318
+ $result = false;
319
+ if ($this->_forceSave || $this->_configLoaded || strlen($this->remote_config)>0) {
320
+ $data = serialize($this->toArray());
321
+ if (strlen($this->remote_config)>0) {
322
+ //save config over ftp
323
+ $confFile = $this->downloader_path . DIRECTORY_SEPARATOR . "connect.cfg";
324
+ try {
325
+ $ftpObj = new Mage_Connect_Ftp();
326
+ $ftpObj->connect($this->remote_config);
327
+ } catch (Exception $e) {
328
+ $this->_configError = 'Cannot access to deployment FTP path. '
329
+ . 'Check deployment FTP Installation path settings.';
330
+ return $result;
331
+ }
332
+ try {
333
+ $tempFile = tempnam(sys_get_temp_dir(),'config');
334
+ $f = fopen($tempFile, "w+");
335
+ fwrite($f, self::HEADER);
336
+ fwrite($f, $data);
337
+ fclose($f);
338
+ } catch (Exception $e) {
339
+ $this->_configError = 'Cannot access to temporary file storage to save Settings.'
340
+ . 'Contact your system administrator.';
341
+ return $result;
342
+ }
343
+ try {
344
+ $result = $ftpObj->upload($confFile, $tempFile);
345
+ $ftpObj->close();
346
+ } catch (Exception $e) {
347
+ $this->_configError = 'Cannot write file over FTP. '
348
+ . 'Check deployment FTP Installation path settings.';
349
+ return $result;
350
+ }
351
+ if (!$result) {
352
+ $this->_configError = '';
353
+ }
354
+ } elseif (is_file($this->_configFile) && is_writable($this->_configFile) || is_writable(getcwd())) {
355
+ try {
356
+ $f = fopen($this->_configFile, "w+");
357
+ fwrite($f, self::HEADER);
358
+ fwrite($f, $data);
359
+ fclose($f);
360
+ $result = true;
361
+ } catch (Exception $e) {
362
+ $result = false;
363
+ }
364
+ }
365
+ }
366
+ return $result;
367
+ }
368
+
369
+ /**
370
+ * Validate value for configuration key
371
+ *
372
+ * @param string $key
373
+ * @param mixed $val
374
+ * @return bool
375
+ */
376
+ public function validate($key, $val)
377
+ {
378
+ $rules = $this->extractField($key, 'rules');
379
+ if (null === $rules) {
380
+ return true;
381
+ } elseif ( is_array($rules) ) {
382
+ return in_array($val, $rules);
383
+ }
384
+ return false;
385
+ }
386
+
387
+ /**
388
+ * Get possible values for configuration key
389
+ *
390
+ * @param string $key
391
+ * @return null|string
392
+ */
393
+ public function possible($key)
394
+ {
395
+ $data = $this->getKey($key);
396
+ if (! $data) {
397
+ return null;
398
+ }
399
+ if ('set' == $data['type']) {
400
+ return implode("|", $data['rules']);
401
+ }
402
+ if (!empty($data['possible'])) {
403
+ return $data['possible'];
404
+ }
405
+ return "<" . $data['type'] . ">";
406
+ }
407
+
408
+ /**
409
+ * Get type of key
410
+ *
411
+ * @param string $key
412
+ * @return mixed|null
413
+ */
414
+ public function type($key)
415
+ {
416
+ return $this->extractField($key, 'type');
417
+ }
418
+
419
+ /**
420
+ * Get documentation information
421
+ *
422
+ * @param string $key
423
+ * @return mixed|null
424
+ */
425
+ public function doc($key)
426
+ {
427
+ return $this->extractField($key, 'doc');
428
+ }
429
+
430
+ /**
431
+ * Get property of key
432
+ *
433
+ * @param $key
434
+ * @param $field
435
+ * @return mixed|null
436
+ */
437
+ public function extractField($key, $field)
438
+ {
439
+ if (!isset($this->properties[$key][$field])) {
440
+ return null;
441
+ }
442
+ return $this->properties[$key][$field];
443
+ }
444
+
445
+ /**
446
+ * Check Key exists in properties array
447
+ *
448
+ * @param string $fld
449
+ * @return bool
450
+ */
451
+ public function hasKey($fld)
452
+ {
453
+ return isset($this->properties[$fld]);
454
+ }
455
+
456
+ /**
457
+ * Get all Key properties
458
+ *
459
+ * @param $fld
460
+ * @return null
461
+ */
462
+ public function getKey($fld)
463
+ {
464
+ if ($this->hasKey($fld)) {
465
+ return $this->properties[$fld];
466
+ }
467
+ return null;
468
+ }
469
+
470
+ /**
471
+ * Set the internal pointer of the Properties array to its first element
472
+ *
473
+ * @return void
474
+ */
475
+ public function rewind() {
476
+ reset($this->properties);
477
+ }
478
+
479
+ /**
480
+ * Validate current property
481
+ *
482
+ * @return bool
483
+ */
484
+ public function valid() {
485
+ return current($this->properties) !== false;
486
+ }
487
+
488
+ /**
489
+ * Get Key of current property
490
+ *
491
+ * @return mixed
492
+ */
493
+ public function key() {
494
+ return key($this->properties);
495
+ }
496
+
497
+ /**
498
+ * Get current Property
499
+ *
500
+ * @return mixed
501
+ */
502
+ public function current() {
503
+ return current($this->properties);
504
+ }
505
+
506
+ /**
507
+ * Advance the internal array pointer of the Properties array
508
+ *
509
+ * @return void
510
+ */
511
+ public function next() {
512
+ next($this->properties);
513
+ }
514
+
515
+ /**
516
+ * Retrieve value of property
517
+ *
518
+ * @param string $var
519
+ * @return null
520
+ */
521
+ public function __get($var)
522
+ {
523
+ if (isset($this->properties[$var]['value'])) {
524
+ return $this->properties[$var]['value'];
525
+ }
526
+ return null;
527
+ }
528
+
529
+ /**
530
+ * Set value of property
531
+ *
532
+ * @param string $var
533
+ * @param mixed $value
534
+ * @return void
535
+ */
536
+ public function __set($var, $value)
537
+ {
538
+ if (is_string($value)) {
539
+ $value = trim($value);
540
+ }
541
+ if (isset($this->properties[$var])) {
542
+ if ($value === null) {
543
+ $value = '';
544
+ }
545
+ if ($this->properties[$var]['value'] !== $value) {
546
+ $this->properties[$var]['value'] = $value;
547
+ $this->store();
548
+ }
549
+ }
550
+ }
551
+
552
+ /**
553
+ * Prepare Array of class properties
554
+ *
555
+ * @param bool $withRules
556
+ * @return array
557
+ */
558
+ public function toArray($withRules = false)
559
+ {
560
+ $out = array();
561
+ foreach ($this as $k=>$v) {
562
+ $out[$k] = $withRules ? $v : $v['value'];
563
+ }
564
+ return $out;
565
+ }
566
+
567
+ /**
568
+ * Return default config value by key
569
+ *
570
+ * @param string $key
571
+ * @return mixed
572
+ */
573
+ public function getDefaultValue($key)
574
+ {
575
+ if (isset($this->defaultProperties[$key]['value'])) {
576
+ return $this->defaultProperties[$key]['value'];
577
+ }
578
+ return false;
579
+ }
580
+
581
+ /**
582
+ * Check is config loaded
583
+ *
584
+ * @return string
585
+ */
586
+ public function isLoaded()
587
+ {
588
+ return $this->_configLoaded;
589
+ }
590
+
591
+ /**
592
+ * Retrieve error message
593
+ *
594
+ * @return string
595
+ */
596
+ public function getError()
597
+ {
598
+ return $this->_configError;
599
+ }
600
+
601
+ /**
602
+ * Save config
603
+ *
604
+ * @return string
605
+ */
606
+ public function save()
607
+ {
608
+ $forceSave = $this->_forceSave;
609
+ $this->_forceSave = true;
610
+
611
+ $result = $this->store();
612
+
613
+ $this->_forceSave = $forceSave;
614
+
615
+ return $result;
616
+ }
617
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Converter.php ADDED
@@ -0,0 +1,336 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class for convertiong old magento PEAR packages to new one
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+
35
+ final class Mage_Connect_Converter
36
+ {
37
+ protected $_archiver;
38
+
39
+ /**
40
+ *
41
+ * @return Mage_Archive
42
+ */
43
+ public function arc()
44
+ {
45
+ if(!$this->_archiver) {
46
+ $this->_archiver = new Mage_Archive();
47
+ }
48
+ return $this->_archiver;
49
+ }
50
+
51
+ public function newPackage()
52
+ {
53
+ return new Mage_Connect_Package();
54
+ }
55
+
56
+ /**
57
+ *
58
+ * @return Pear_Package_Parser_v2
59
+ */
60
+ public function oldPackageReader()
61
+ {
62
+ return new Pear_Package_Parser_v2();
63
+ }
64
+
65
+
66
+ public function __construct()
67
+ {
68
+
69
+ }
70
+
71
+
72
+ public function convertChannelName($channel)
73
+ {
74
+ return str_replace("connect.magentocommerce.com/", "", $channel);
75
+ }
76
+
77
+ /**
78
+ * Convert package dependencies - urls - by ref
79
+ * @param array $deps ref to array
80
+ * @return void
81
+ */
82
+ public function convertPackageDependencies($oldDeps)
83
+ {
84
+ $out = array();
85
+ if(empty($oldDeps['required']['package'])) {
86
+ return $out;
87
+ }
88
+ $deps = $oldDeps['required']['package'];
89
+ if(!isset($deps[0])) {
90
+ $deps = array($deps);
91
+ }
92
+ for($i=0, $c=count($deps); $i<$c; $i++) {
93
+ $deps[$i]['min_version'] = isset($deps[$i]['min']) ? $deps[$i]['min'] : false;
94
+ $deps[$i]['max_version'] = isset($deps[$i]['max']) ? $deps[$i]['max'] : false;
95
+ $deps[$i]['channel'] = $this->convertChannelName($deps[$i]['channel']);
96
+ $out[] = $deps[$i];
97
+ }
98
+
99
+ return $out;
100
+ }
101
+
102
+ public function convertLicense($oldLicense)
103
+ {
104
+ if(is_scalar($oldLicense)) {
105
+ return $oldLicense;
106
+ }
107
+ return array($oldLicense['_content'], $oldLicense['attribs']['uri']);
108
+ }
109
+
110
+ public function convertMaintainers($maintainers)
111
+ {
112
+ if(!is_array($maintainers) || !count($maintainers)) {
113
+ return array();
114
+ }
115
+ $out = array();
116
+ foreach($maintainers as $row) {
117
+ $out[] = array('name'=>$row['name'], 'email'=>$row['email'], 'user'=>'auto-converted');
118
+ }
119
+ return $out;
120
+ }
121
+
122
+ protected $fileMap = array();
123
+
124
+
125
+ /**
126
+ * Conver pear package object to magento object
127
+ * @param Pear_Package_V2 $pearObject
128
+ * @return Mage_Connect_Package
129
+ */
130
+
131
+ public function convertPackageObject($pearObject)
132
+ {
133
+ $data = array();
134
+ $mageObject = $this->newPackage();
135
+
136
+
137
+
138
+ $map = array (
139
+ 'name' => null,
140
+ 'version' => array('getterArgs' => array('release')
141
+ ),
142
+ 'package_deps' => array( 'getter'=>'getDependencies',
143
+ 'converter'=>'convertPackageDependencies',
144
+ 'setter'=>'setDependencyPackages',
145
+ ),
146
+ 'stability' => array( 'getter'=>'getState',
147
+ 'getterArgs' => array('release'),
148
+ ),
149
+ 'license' => array( 'getterArgs' => array(true),
150
+ 'converter' => 'convertLicense',
151
+ 'noArrayWrap' => true,
152
+ ),
153
+ 'summary' => null,
154
+ 'description' => null,
155
+ 'notes' => null,
156
+ 'date' => null,
157
+ 'time' => null,
158
+ 'authors' => array( 'converter' => 'convertMaintainers',
159
+ 'getter' => 'getMaintainers',
160
+ ),
161
+ 'channel' => array( 'converter' => 'convertChannelName',
162
+
163
+ ),
164
+
165
+ );
166
+ foreach($map as $field=>$rules) {
167
+
168
+ if(empty($rules)) {
169
+ $rules = array('setter'=> '', 'getter'=> '');
170
+ }
171
+
172
+ if(empty($rules['getter'])) {
173
+ $rules['getter'] = 'get'. ucfirst($field);
174
+ }
175
+
176
+ $useSetter = empty($rules['noSetter']);
177
+ $useGetter = empty($rules['noGetter']);
178
+
179
+
180
+ if(empty($rules['setter'])) {
181
+ $rules['setter'] = 'set'. ucfirst($field);
182
+ }
183
+ if(empty($rules['getterArgs'])) {
184
+ $rules['getterArgs'] = array();
185
+ } elseif(!is_array($rules['getterArgs'])) {
186
+ throw new Exception("Invalid 'getterArgs' for '{$field}', should be array");
187
+ }
188
+
189
+ if($useGetter && !method_exists($pearObject, $rules['getter'])) {
190
+ $mName = get_class($pearObject)."::".$rules['getter'];
191
+ throw new Exception('No getter method exists: '.$mName);
192
+ }
193
+
194
+ if($useSetter && !method_exists($mageObject, $rules['setter'])) {
195
+ $mName = get_class($mageObject)."::".$rules['setter'];
196
+ throw new Exception('No setter method exists: '.$mName);
197
+ }
198
+
199
+ $useConverter = !empty($rules['converter']);
200
+
201
+ if($useConverter && false === method_exists($this, $rules['converter'])) {
202
+ $mName = get_class($this)."::".$rules['converter'];
203
+ throw new Exception('No converter method exists: '.$mName);
204
+ }
205
+
206
+ if($useGetter) {
207
+ $getData = call_user_func_array(array($pearObject, $rules['getter']), $rules['getterArgs']);
208
+ } else {
209
+ $getData = array();
210
+ }
211
+
212
+ if($useConverter) {
213
+ $args = array();
214
+ if(!$useGetter && !$useSetter) {
215
+ $args = array($pearObject, $mageObject);
216
+ } elseif(!$useSetter) {
217
+ $args = array($mageObject, $getData);
218
+ } else {
219
+ $args = array($getData);
220
+ }
221
+ $getData = call_user_func_array(array($this, $rules['converter']), $args);
222
+ }
223
+
224
+ $noWrap = !empty($rules['noArrayWrap']);
225
+ if($useSetter) {
226
+ $setData = call_user_func_array(array($mageObject, $rules['setter']), $noWrap ? $getData : array($getData));
227
+ }
228
+ }
229
+ return $mageObject;
230
+ }
231
+
232
+ /**
233
+ * Convert PEAR package to Magento package
234
+ * @param string $sourceFile path to PEAR .tgz
235
+ * @param string|false $destFile path to newly-created Magento .tgz, false to specify auto
236
+ * @return bool
237
+ */
238
+ public function convertPearToMage($sourceFile, $destFile = false)
239
+ {
240
+ try {
241
+ if(!file_exists($sourceFile)) {
242
+ throw new Exception("File doesn't exist: {$sourceFile}");
243
+ }
244
+ $arc = $this->arc();
245
+ $tempDir = "tmp-".basename($sourceFile).uniqid();
246
+ $outDir = "out-".basename($sourceFile).uniqid();
247
+ $outDir = rtrim($outDir, "\\/");
248
+ Mage_System_Dirs::mkdirStrict($outDir);
249
+ Mage_System_Dirs::mkdirStrict($tempDir);
250
+
251
+ $result = $arc->unpack($sourceFile, $tempDir);
252
+ if(!$result) {
253
+ throw new Exception("'{$sourceFile}' was not unpacked");
254
+ }
255
+
256
+ $result = rtrim($result, "\\/");
257
+ $packageXml = $result . DS . "package.xml";
258
+ if(!file_exists($packageXml)) {
259
+ throw new Exception("No package.xml found inside '{$sourceFile}'");
260
+ }
261
+
262
+ $reader = $this->oldPackageReader();
263
+ $data = file_get_contents($packageXml);
264
+
265
+ $pearObject = $reader->parsePackage($data, $packageXml);
266
+ $mageObject = $this->convertPackageObject($pearObject);
267
+ if(!$mageObject->validate()) {
268
+ throw new Exception("Package validation failed.\n". implode("\n", $mageObject->getErrors()));
269
+ }
270
+
271
+ /**
272
+ * Calculate destination file if false
273
+ */
274
+ if(false === $destFile) {
275
+ $pathinfo = pathinfo($sourceFile);
276
+ $destFile = $pathinfo['dirname'] . DS .$pathinfo['filename'].'-converted';
277
+ if(isset($pathinfo['extension'])) {
278
+ $destFile .= ".".$pathinfo['extension'];
279
+ }
280
+ }
281
+
282
+ $target = new Mage_Connect_Package_Target("target.xml");
283
+ $targets = $target->getTargets();
284
+ $mageObject->setTarget($target);
285
+ $validRoles = array_keys($targets);
286
+ $data = $pearObject->getFilelist();
287
+ $pathSource = dirname($pearObject->getPackageFile()).DS.$pearObject->getName()."-".$pearObject->getVersion();
288
+
289
+ $filesToDo = array();
290
+ foreach($data as $file =>$row) {
291
+ $name = $row['name'];
292
+ $role = $row['role'];
293
+ if(!in_array($role, $validRoles)) {
294
+ $role = 'mage';
295
+ }
296
+ $baseName = ltrim($targets[$role], "\\/.");
297
+ $baseName = rtrim($baseName, "\\/");
298
+ $sourceFile = $pathSource.DS.$name;
299
+ $targetFile = $outDir . DS . $baseName . DS. $name;
300
+ if(file_exists($sourceFile)) {
301
+ Mage_System_Dirs::mkdirStrict(dirname($targetFile));
302
+ $copy = @copy($sourceFile, $targetFile);
303
+ if(false === $copy) {
304
+ throw new Exception("Cannot copy '{$sourceFile}' to '{$targetFile}'");
305
+ }
306
+ }
307
+ $filesToDo[] = array ('name'=> $name, 'role'=>$role);
308
+ }
309
+ $cwd = getcwd();
310
+ @chdir($outDir);
311
+ foreach($filesToDo as $fileToDo) {
312
+ $mageObject->addContent($fileToDo['name'], $fileToDo['role']);
313
+ }
314
+ $mageObject->save(getcwd());
315
+ @chdir($cwd);
316
+ $filename = $outDir. DS . $mageObject->getReleaseFilename().".tgz";
317
+ if(@file_exists($targetArchive)) {
318
+ @unlink($targetArchive);
319
+ }
320
+ Mage_System_Dirs::mkdirStrict(dirname($destFile));
321
+ $copy = @copy($filename, $destFile);
322
+ if(false === $copy) {
323
+ throw new Exception("Cannot copy '{$filename}' to '{$targetArchive}'");
324
+ }
325
+ Mage_System_Dirs::rm($tempDir);
326
+ Mage_System_Dirs::rm($outDir);
327
+
328
+ } catch (Exception $e) {
329
+ throw $e;
330
+ }
331
+ return $destFile;
332
+ }
333
+
334
+
335
+
336
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Frontend.php ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+ class Mage_Connect_Frontend
27
+ {
28
+ /**
29
+ * Silent flag. If set no output is produced to view.
30
+ * Should be used in derived classes.
31
+ *
32
+ * @var boolean
33
+ */
34
+ protected $_silent = false;
35
+
36
+ /**
37
+ * Capture mode. If set command output should be collected
38
+ * by derived class impplementation
39
+ *
40
+ * @var boolean
41
+ */
42
+ protected $_capture = false;
43
+
44
+ /**
45
+ * push/pop variable for capture
46
+ *
47
+ * @var array
48
+ */
49
+ protected $_captureSaved = array();
50
+
51
+ /**
52
+ * push/pop variable for silent
53
+ *
54
+ * @var array
55
+ */
56
+ protected $_silentSaved = array();
57
+
58
+ /**
59
+ * Errors list
60
+ *
61
+ * @var array
62
+ */
63
+ protected $_errors = array();
64
+
65
+ /**
66
+ * Add error to errors list
67
+ *
68
+ * @param mixed $data
69
+ * @return null
70
+ */
71
+ public function addError($data)
72
+ {
73
+ $this->_errors[] = $data;
74
+ }
75
+
76
+ /**
77
+ * Get errors, clear errors list with first param
78
+ *
79
+ * @param boolean $clear
80
+ * @return array
81
+ */
82
+ public function getErrors($clear = true)
83
+ {
84
+ if(!$clear) {
85
+ return $this->_errors;
86
+ }
87
+ $out = $this->_errors;
88
+ $this->clearErrors();
89
+ return $out;
90
+ }
91
+
92
+ /**
93
+ * Clear errors array
94
+ *
95
+ * @return null
96
+ */
97
+ public function clearErrors()
98
+ {
99
+ $this->_errors = array();
100
+ }
101
+
102
+ /**
103
+ * Are there any errros?
104
+ *
105
+ * @return boolean
106
+ */
107
+ public function hasErrors()
108
+ {
109
+ return count($this->_errors) != 0;
110
+ }
111
+
112
+ /**
113
+ * Error processing
114
+ * @param string $command
115
+ * @param string $message
116
+ * @return null
117
+ */
118
+ public function doError($command, $message)
119
+ {
120
+ $this->addError(array($command, $message));
121
+ }
122
+
123
+ /**
124
+ * Save capture state
125
+ *
126
+ * @return Mage_Connect_Frontend
127
+ */
128
+ public function pushCapture()
129
+ {
130
+ array_push($this->_captureSaved, $this->_capture);
131
+ return $this;
132
+ }
133
+
134
+ /**
135
+ * Restore capture state
136
+ *
137
+ * @return Mage_Connect_Frontend
138
+ */
139
+ public function popCapture()
140
+ {
141
+ $this->_capture = array_pop($this->_captureSaved);
142
+ return $this;
143
+ }
144
+
145
+ /**
146
+ * Set capture mode
147
+ *
148
+ * @param boolean $arg true by default
149
+ * @return Mage_Connect_Frontend
150
+ */
151
+ public function setCapture($arg = true)
152
+ {
153
+ $this->_capture = $arg;
154
+ return $this;
155
+ }
156
+
157
+ /**
158
+ * Getter for capture mode
159
+ *
160
+ * @return boolean
161
+ */
162
+ public function isCapture()
163
+ {
164
+ return $this->_capture;
165
+ }
166
+
167
+ /**
168
+ * Log stub
169
+ *
170
+ * @param $msg
171
+ * @return
172
+ */
173
+ public function log($msg)
174
+ {
175
+
176
+ }
177
+
178
+ /**
179
+ * Ouptut method
180
+ *
181
+ * @param array $data
182
+ * @return null
183
+ */
184
+ public function output($data)
185
+ {
186
+
187
+ }
188
+
189
+ /**
190
+ * Get instance of derived class
191
+ *
192
+ * @param $class CLI for example will produce Mage_Connect_Frontend_CLI
193
+ * @return object
194
+ */
195
+ public static function getInstance($class)
196
+ {
197
+ $class = __CLASS__."_".$class;
198
+ return new $class();
199
+ }
200
+
201
+ /**
202
+ * Get output if capture mode set
203
+ * Clear prevoius if needed
204
+ *
205
+ * @param boolean $clearPrevious
206
+ * @return mixed
207
+ */
208
+ public function getOutput($clearPrevious = true)
209
+ {
210
+
211
+ }
212
+
213
+ /**
214
+ * Save silent mode
215
+ *
216
+ * @return Mage_Connect_Frontend
217
+ */
218
+ public function pushSilent()
219
+ {
220
+ array_push($this->_silentSaved, $this->_silent);
221
+ return $this;
222
+ }
223
+
224
+ /**
225
+ * Restore silent mode
226
+ *
227
+ * @return Mage_Connect_Frontend
228
+ */
229
+ public function popSilent()
230
+ {
231
+ $this->_silent = array_pop($this->_silentSaved);
232
+ return $this;
233
+ }
234
+
235
+ /**
236
+ * Set silent mode
237
+ *
238
+ * @param boolean $value
239
+ * @return Mage_Connect_Frontend
240
+ */
241
+ public function setSilent($value = true)
242
+ {
243
+ $this->_silent = (boolean) $value;
244
+ return $this;
245
+ }
246
+
247
+ /**
248
+ * Is silent mode?
249
+ *
250
+ * @return boolean
251
+ */
252
+ public function isSilent()
253
+ {
254
+ return (boolean) $this->_silent;
255
+ }
256
+
257
+ /**
258
+ * Method for ask client about rewrite all files.
259
+ *
260
+ * @param $string
261
+ */
262
+ public function confirm($string)
263
+ {
264
+
265
+ }
266
+ }
267
+
app/code/local/Mss/downloader/lib/Mage/Connect/Frontend/CLI.php ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * CLI Frontend implementation
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+
35
+ class Mage_Connect_Frontend_CLI
36
+ extends Mage_Connect_Frontend
37
+ {
38
+
39
+ /**
40
+ * Collected output
41
+ * @var array
42
+ */
43
+ protected $_output = array();
44
+
45
+ /**
46
+ * Output error
47
+ * @param string $command
48
+ * @param string $message
49
+ * @return void
50
+ */
51
+ public function doError($command, $message)
52
+ {
53
+ parent::doError($command, $message);
54
+ $this->writeln("Error: ");
55
+ $this->writeln("$command: $message");
56
+ }
57
+
58
+
59
+ /**
60
+ * Output config help
61
+ * @param array $data
62
+ * @return void
63
+ */
64
+ public function outputConfigHelp($data)
65
+ {
66
+ foreach($data['data'] as $k=>$v) {
67
+ if(is_scalar($v)) {
68
+ $this->writeln($v);
69
+ } elseif(is_array($v)) {
70
+ $this->writeln(implode(": ", $v));
71
+ }
72
+ }
73
+ }
74
+
75
+
76
+ /**
77
+ * Output info
78
+ * @param array $data
79
+ * @return void
80
+ */
81
+ public function outputRemoteInfo($data)
82
+ {
83
+ if(!is_array($data['releases'])) {
84
+ return;
85
+ }
86
+ foreach ($data['releases'] as $r) {
87
+ $this->writeln(implode(" ", $r));
88
+ }
89
+ }
90
+
91
+
92
+ public function detectMethodByType($type)
93
+ {
94
+ $defaultMethod = "output";
95
+ $methodMap = array(
96
+ 'list-upgrades'=> 'outputUpgrades',
97
+ 'list-available' => 'outputChannelsPackages',
98
+ 'list-installed' => 'writeInstalledList',
99
+ 'package-dependencies' => 'outputPackageDeps',
100
+ 'package-prepare' => 'outputPackagePrepare',
101
+ 'list-files' => 'outputPackageContents',
102
+ 'config-help' => 'outputConfigHelp',
103
+ 'info' => 'outputRemoteInfo',
104
+ 'config-show' => 'outputConfig',
105
+ 'install' => 'outputInstallResult',
106
+ 'install-file' => 'outputInstallResult',
107
+ 'upgrade' => 'outputInstallResult',
108
+ 'upgrade-all' => 'outputInstallResult',
109
+ 'uninstall' => 'outputDeleted',
110
+ 'list-channels' => 'outputListChannels',
111
+ );
112
+ if(isset($methodMap[$type])) {
113
+ return $methodMap[$type];
114
+ }
115
+ return $defaultMethod;
116
+ }
117
+
118
+
119
+ public function outputDeleted($data)
120
+ {
121
+ if(!count($data['data'])) {
122
+ return;
123
+ }
124
+ $this->writeln($data['title']);
125
+ foreach($data['data'] as $row) {
126
+ $this->writeln("$row[0]/$row[1]");
127
+ }
128
+ }
129
+
130
+ public function outputListChannels($data)
131
+ {
132
+ $this->writeln($data['title']);
133
+
134
+ $channels =& $data['data'][Mage_Connect_Singleconfig::K_CHAN];
135
+ foreach($channels as $name => $v) {
136
+ $this->writeln("$name: {$v[Mage_Connect_Singleconfig::K_URI]}");
137
+ }
138
+ $aliases =& $data['data'][Mage_Connect_Singleconfig::K_CHAN_ALIAS];
139
+ if(count($aliases)) {
140
+ $this->writeln();
141
+ $this->writeln($data['title_aliases']);
142
+ foreach($aliases as $k=>$v) {
143
+ $this->writeln("$k => $v");
144
+ }
145
+ }
146
+
147
+ }
148
+
149
+ /**
150
+ * Output install result
151
+ * @param array $data
152
+ * @return void
153
+ */
154
+ public function outputInstallResult($data)
155
+ {
156
+ if(isset($data['title'])) {
157
+ $title = trim($data['title'])." ";
158
+ } else {
159
+ $title = '';
160
+ }
161
+ foreach($data['assoc'] as $row) {
162
+ $this->printf("%s%s/%s %s\n", $title, $row['channel'], $row['name'], $row['version']);
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Ouptut package contents
168
+ * @param array $data
169
+ * @return void
170
+ */
171
+ public function outputPackageContents($data)
172
+ {
173
+ $this->writeln($data['title']);
174
+ foreach($data['data'] as $file) {
175
+ $this->writeln($file);
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Output package dependencies
181
+ * @param $data
182
+ * @return void
183
+ */
184
+ public function outputPackageDeps($data)
185
+ {
186
+ $title = $data['title'];
187
+ $this->writeln($title);
188
+ foreach($data['data'] as $package) {
189
+ $this->printf("%-20s %-20s %-20s %-20s\n", $package['channel'], $package['name'], $package['min'], $package['max']);
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Output package prepare
195
+ * @param $data
196
+ * @return void
197
+ */
198
+ public function outputPackagePrepare($data)
199
+ {
200
+ $title = $data['title'];
201
+ $this->writeln($title);
202
+ foreach($data['data'] as $package) {
203
+ $this->printf("%-20s %-20s %-20s %-20s\n", $package['channel'], $package['name'], $package['version'], $package['install_state']);
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Ouptut channel packages
209
+ * @param $data
210
+ * @return unknown_type
211
+ */
212
+ public function outputChannelsPackages($data)
213
+ {
214
+ foreach($data['data'] as $channelInfo) {
215
+ $title =& $channelInfo['title'];
216
+ $packages =& $channelInfo['packages'];
217
+ $this->writeln($title);
218
+ foreach($packages as $name=>$package) {
219
+ $releases =& $package['releases'];
220
+ $tmp = array();
221
+ foreach($releases as $ver=>$state) {
222
+ $tmp[] = "$ver $state";
223
+ }
224
+ $tmp = implode(',',$tmp);
225
+ $this->writeln($name.": ".$tmp);
226
+ }
227
+ }
228
+ }
229
+
230
+
231
+ /**
232
+ * Make output
233
+ *
234
+ * @param array $data
235
+ * @return void
236
+ */
237
+
238
+ public function output($data)
239
+ {
240
+ $capture = $this->isCapture();
241
+ if($capture) {
242
+ $this->_output[] = $data;
243
+ return;
244
+ }
245
+
246
+ if(is_array($data)) {
247
+ foreach($data as $type=>$params) {
248
+ $method = $this->detectMethodByType($type);
249
+ if($method) {
250
+ $this->$method($params);
251
+ } else {
252
+ $this->writeln(__METHOD__." handler not found for {$type}");
253
+ }
254
+ }
255
+ } else {
256
+ $this->writeln($data);
257
+ }
258
+ }
259
+
260
+
261
+ /**
262
+ * Detailed package info
263
+ * @param Mage_Connect_Package $package
264
+ * @return void
265
+ */
266
+ public function outputPackage($package)
267
+ {
268
+ $fields = array(
269
+ 'Name'=>'name',
270
+ 'Version'=>'version',
271
+ 'Stability'=>'stability',
272
+ 'Description' => 'description',
273
+ 'Date' => 'date',
274
+ 'Authors' => 'authors',
275
+ );
276
+
277
+ foreach($fields as $title => $fld) {
278
+ $method = "get".ucfirst($fld);
279
+ $data = $package->$method();
280
+ if(empty($data)) {
281
+ continue;
282
+ }
283
+ $this->write($title.": ");
284
+ if(is_array($data)) {
285
+ $this->write(print_r($data,true));
286
+ } else {
287
+ $this->write($data);
288
+ }
289
+ $this->writeln('');
290
+ }
291
+ }
292
+
293
+
294
+ /**
295
+ * Write channels list
296
+ * @param array $data
297
+ * @return void
298
+ */
299
+ public function writeChannelsList($data)
300
+ {
301
+ $this->writeln("Channels available: ");
302
+ $this->writeln("===================");
303
+ $out = $data['byName'];
304
+ ksort($out);
305
+ foreach($out as $k=>$v) {
306
+ $this->printf ("%-20s %-20s\n", $k, $v);
307
+ }
308
+ }
309
+
310
+ /**
311
+ * Write installed list
312
+ * @param array $data
313
+ * @return void
314
+ */
315
+ public function writeInstalledList($data)
316
+ {
317
+ $totalCount = 0;
318
+ foreach($data['data'] as $channel=>$packages) {
319
+ $title = sprintf($data['channel-title'], $channel);
320
+ $c = count($packages);
321
+ $totalCount += $c;
322
+ if(!$c) {
323
+ continue;
324
+ }
325
+ $this->writeln($title);
326
+ foreach($packages as $name=>$row) {
327
+ $this->printf("%-20s %-20s\n", $name, $row['version']." ".$row['stability']);
328
+ }
329
+ }
330
+ if($totalCount === 0) {
331
+ $this->writeln("No installed packages");
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Output commands list
337
+ * @param array $data
338
+ * @return void
339
+ */
340
+ public function outputCommandList($data)
341
+ {
342
+ $this->writeln("Connect commands available:");
343
+ $this->writeln("===========================");
344
+ foreach ($data as $k=>$v) {
345
+ $this->printf ("%-20s %-20s\n", $k, $v['summary']);
346
+ }
347
+ }
348
+
349
+ /**
350
+ * Output config
351
+ * @param array $data
352
+ * @return void
353
+ */
354
+ public function outputConfig($data)
355
+ {
356
+ foreach($data['data'] as $name=>$row) {
357
+ $value = $row['value'] === '' ? "<not set>" : strval($row['value']);
358
+ $this->printf("%-30s %-20s %-20s\n", $row['prompt'], $name, $value);
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Output config variable
364
+ * @param string $key
365
+ * @param string $value
366
+ * @return void
367
+ */
368
+ public function outputConfigVariable($key, $value)
369
+ {
370
+ if($value === '') {
371
+ $value = '<not set>';
372
+ }
373
+ $this->writeln("Config variable '{$key}': {$value}");
374
+ }
375
+
376
+ /**
377
+ * Write data and "\n" afterwards
378
+ * @param string $data
379
+ * @return void
380
+ */
381
+ public function writeln($data = '')
382
+ {
383
+ $this->write($data."\n");
384
+ }
385
+
386
+
387
+ /**
388
+ * get output, clear if needed
389
+ *
390
+ * @param bool $clearPrevoius optional, true by default
391
+ * @return array
392
+ */
393
+ public function getOutput($clearPrevious = true)
394
+ {
395
+ $out = $this->_output;
396
+ if($clearPrevious) {
397
+ $this->_output = array();
398
+ }
399
+ return $out;
400
+ }
401
+
402
+ /**
403
+ * Write data to console
404
+ * @param string $data
405
+ * @return void
406
+ */
407
+ public function write($data)
408
+ {
409
+ if($this->isSilent()) {
410
+ return;
411
+ }
412
+ print $data;
413
+ }
414
+
415
+ /**
416
+ * Output printf-stlye formatted string and args
417
+ * @return void
418
+ */
419
+ public function printf()
420
+ {
421
+ $args = func_get_args();
422
+ $this->write(call_user_func_array('sprintf', $args));
423
+ }
424
+
425
+ /**
426
+ * Readline from console
427
+ * @return string
428
+ */
429
+ public function readln()
430
+ {
431
+ $out = "";
432
+ $key = fgetc(STDIN);
433
+ while ($key!="\n") {
434
+ $out.= $key;
435
+ $key = fread(STDIN, 1);
436
+ }
437
+ return $out;
438
+ }
439
+
440
+ /**
441
+ * Output upgrades
442
+ * @param array $data
443
+ * @return void
444
+ */
445
+ public function outputUpgrades($data)
446
+ {
447
+ foreach($data['data'] as $chan => $packages) {
448
+ $this->writeln("Updates for ".$chan.": ");
449
+ foreach($packages as $name => $data) {
450
+ $this->writeln(" $name: {$data['from']} => {$data['to']}");
451
+ }
452
+ }
453
+ }
454
+
455
+ }
456
+
app/code/local/Mss/downloader/lib/Mage/Connect/Ftp.php ADDED
@@ -0,0 +1,533 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with remote FTP server
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Ftp
35
+ {
36
+ /**
37
+ * Connection object
38
+ *
39
+ * @var resource
40
+ */
41
+ protected $_conn = false;
42
+
43
+ /**
44
+ * Check connected, throw exception if not
45
+ *
46
+ * @throws Exception
47
+ * @return null
48
+ */
49
+ protected function checkConnected()
50
+ {
51
+ if(!$this->_conn) {
52
+ throw new Exception(__CLASS__." - no connection established with server");
53
+ }
54
+ }
55
+
56
+ /**
57
+ * ftp_mkdir wrapper
58
+ *
59
+ * @param string $name
60
+ * @return string
61
+ */
62
+ public function mdkir($name)
63
+ {
64
+ $this->checkConnected();
65
+ return @ftp_mkdir($this->_conn, $name);
66
+ }
67
+
68
+ /**
69
+ * Make dir recursive
70
+ *
71
+ * @param string $path
72
+ * @param int $mode
73
+ */
74
+ public function mkdirRecursive($path, $mode = 0777)
75
+ {
76
+ $this->checkConnected();
77
+ $dir = explode('/', $path);
78
+ $path= "";
79
+ $ret = true;
80
+ for ($i=0; $i < count($dir); $i++) {
81
+ $path .= "/" .$dir[$i];
82
+ if(!@ftp_chdir($this->_conn, $path)) {
83
+ @ftp_chdir($this->_conn,"/");
84
+ if(!@ftp_mkdir($this->_conn,$path)) {
85
+ $ret=false;
86
+ break;
87
+ } else {
88
+ @ftp_chmod($this->_conn, $mode, $path);
89
+ }
90
+ }
91
+ }
92
+ return $ret;
93
+ }
94
+
95
+ /**
96
+ * Try to login to server
97
+ *
98
+ * @param string $login
99
+ * @param string $password
100
+ * @throws Exception on invalid login credentials
101
+ * @return boolean
102
+ */
103
+ public function login($login = "anonymous", $password = "test@gmail.com")
104
+ {
105
+ $this->checkConnected();
106
+ $res = @ftp_login($this->_conn, $login, $password);
107
+ if(!$res) {
108
+ throw new Exception("Invalid login credentials");
109
+ }
110
+ return $res;
111
+ }
112
+
113
+ /**
114
+ * Validate connection string
115
+ *
116
+ * @param string $string
117
+ * @throws Exception
118
+ * @return string
119
+ */
120
+ public function validateConnectionString($string)
121
+ {
122
+ if (empty($string)) {
123
+ throw new Exception("Connection string is empty");
124
+ }
125
+ $data = @parse_url($string);
126
+ if(false === $data) {
127
+ throw new Exception("Connection string invalid: '{$string}'");
128
+ }
129
+ if($data['scheme'] != 'ftp') {
130
+ throw new Exception("Support for scheme '{$data['scheme']}' unsupported");
131
+ }
132
+ return $data;
133
+ }
134
+
135
+ /**
136
+ * Connect to server using connect string
137
+ * Connection string: ftp://user:pass@server:port/path
138
+ * user,pass,port,path are optional parts
139
+ *
140
+ * @param string $string
141
+ * @param int $timeout
142
+ * @return null
143
+ */
144
+ public function connect($string, $timeout = 90)
145
+ {
146
+ $params = $this->validateConnectionString($string);
147
+ $port = isset($params['port']) ? intval($params['port']) : 21;
148
+
149
+ $this->_conn = @ftp_connect($params['host'], $port, $timeout);
150
+
151
+ if(!$this->_conn) {
152
+ throw new Exception("Cannot connect to host: {$params['host']}");
153
+ }
154
+ ftp_pasv($this->_conn, true);
155
+ if(isset($params['user']) && isset($params['pass'])) {
156
+ $this->login($params['user'], $params['pass']);
157
+ } else {
158
+ $this->login();
159
+ }
160
+ if(isset($params['path'])) {
161
+ if(!$this->chdir($params['path'])) {
162
+ throw new Exception ("Cannot chdir after login to: {$params['path']}");
163
+ }
164
+ }
165
+ }
166
+
167
+ /**
168
+ * ftp_fput wrapper
169
+ *
170
+ * @param string $remoteFile
171
+ * @param resource $handle
172
+ * @param int $mode FTP_BINARY | FTP_ASCII
173
+ * @param int $startPos
174
+ * @return boolean
175
+ */
176
+ public function fput($remoteFile, $handle, $mode = FTP_BINARY, $startPos = 0)
177
+ {
178
+ $this->checkConnected();
179
+ return @ftp_fput($this->_conn, $remoteFile, $handle, $mode, $startPos);
180
+ }
181
+
182
+ /**
183
+ * ftp_put wrapper
184
+ *
185
+ * @param string $remoteFile
186
+ * @param string $localFile
187
+ * @param int $mode FTP_BINARY | FTP_ASCII
188
+ * @param int $startPos
189
+ * @return boolean
190
+ */
191
+ public function put($remoteFile, $localFile, $mode = FTP_BINARY, $startPos = 0)
192
+ {
193
+ $this->checkConnected();
194
+ return @ftp_put($this->_conn, $remoteFile, $localFile, $mode, $startPos);
195
+ }
196
+
197
+ /**
198
+ * Get current working directory
199
+ *
200
+ * @return string
201
+ */
202
+ public function getcwd()
203
+ {
204
+ $d = $this->raw("pwd");
205
+ $data = explode(" ", $d[0], 3);
206
+ if(empty($data[1])) {
207
+ return false;
208
+ }
209
+ if(intval($data[0]) != 257) {
210
+ return false;
211
+ }
212
+ $out = trim($data[1], '"');
213
+ if($out !== "/") {
214
+ $out = rtrim($out, "/");
215
+ }
216
+ return $out;
217
+ }
218
+
219
+ /**
220
+ * ftp_raw wrapper
221
+ *
222
+ * @param string $cmd
223
+ * @return array
224
+ */
225
+ public function raw($cmd)
226
+ {
227
+ $this->checkConnected();
228
+ return @ftp_raw($this->_conn, $cmd);
229
+ }
230
+
231
+ /**
232
+ * Upload local file to remote server.
233
+ * Can be used for relative and absoulte remote paths
234
+ * Relative: use chdir before calling this
235
+ *
236
+ * @param string $remote
237
+ * @param string $local
238
+ * @param int $dirMode
239
+ * @param int $fileMode
240
+ * @return boolean
241
+ */
242
+ public function upload($remote, $local, $dirMode = 0777, $fileMode=0)
243
+ {
244
+ $this->checkConnected();
245
+
246
+ if(!file_exists($local)) {
247
+ throw new Exception("Local file doesn't exist: {$local}");
248
+ }
249
+ if(!is_readable($local)) {
250
+ throw new Exception("Local file is not readable: {$local}");
251
+ }
252
+ if(is_dir($local)) {
253
+ throw new Exception("Directory given instead of file: {$local}");
254
+ }
255
+
256
+ $globalPathMode = substr($remote, 0, 1) == "/";
257
+ $dirname = dirname($remote);
258
+ $cwd = $this->getcwd();
259
+ if(false === $cwd) {
260
+ throw new Exception("Server returns something awful on PWD command");
261
+ }
262
+
263
+ if(!$globalPathMode) {
264
+ $dirname = $cwd."/".$dirname;
265
+ $remote = $cwd."/".$remote;
266
+ }
267
+ $res = $this->mkdirRecursive($dirname, $dirMode);
268
+ $this->chdir($cwd);
269
+
270
+ if(!$res) {
271
+ return false;
272
+ }
273
+ $res = $this->put($remote, $local);
274
+
275
+ if(!$res) {
276
+ return false;
277
+ }
278
+
279
+ if($fileMode){
280
+ $res=$this->chmod($fileMode, $remote);
281
+ }
282
+ return (boolean)$res;
283
+ }
284
+
285
+ /**
286
+ * Download remote file to local machine
287
+ *
288
+ * @param string $remote
289
+ * @param string $local
290
+ * @param int $ftpMode FTP_BINARY|FTP_ASCII
291
+ * @return boolean
292
+ */
293
+ public function download($remote, $local, $ftpMode = FTP_BINARY)
294
+ {
295
+ $this->checkConnected();
296
+ return $this->get($local, $remote, $ftpMode);
297
+ }
298
+
299
+ /**
300
+ * ftp_pasv wrapper
301
+ *
302
+ * @param boolean $pasv
303
+ * @return boolean
304
+ */
305
+ public function pasv($pasv)
306
+ {
307
+ $this->checkConnected();
308
+ return @ftp_pasv($this->_conn, (boolean) $pasv);
309
+ }
310
+
311
+ /**
312
+ * Close FTP connection
313
+ *
314
+ * @return null
315
+ */
316
+ public function close()
317
+ {
318
+ if($this->_conn) {
319
+ @ftp_close($this->_conn);
320
+ }
321
+ }
322
+
323
+ /**
324
+ * ftp_chmod wrapper
325
+ *
326
+ * @param $mode
327
+ * @param $remoteFile
328
+ * @return boolean
329
+ */
330
+ public function chmod($mode, $remoteFile)
331
+ {
332
+ $this->checkConnected();
333
+ return @ftp_chmod($this->_conn, $mode, $remoteFile);
334
+ }
335
+
336
+ /**
337
+ * ftp_chdir wrapper
338
+ *
339
+ * @param string $dir
340
+ * @return boolean
341
+ */
342
+ public function chdir($dir)
343
+ {
344
+ $this->checkConnected();
345
+ return @ftp_chdir($this->_conn, $dir);
346
+ }
347
+
348
+ /**
349
+ * ftp_cdup wrapper
350
+ *
351
+ * @return boolean
352
+ */
353
+ public function cdup()
354
+ {
355
+ $this->checkConnected();
356
+ return @ftp_cdup($this->_conn);
357
+ }
358
+
359
+ /**
360
+ * ftp_get wrapper
361
+ *
362
+ * @param string $localFile
363
+ * @param string $remoteFile
364
+ * @param int $fileMode FTP_BINARY | FTP_ASCII
365
+ * @param int $resumeOffset
366
+ * @return boolean
367
+ */
368
+ public function get($localFile, $remoteFile, $fileMode = FTP_BINARY, $resumeOffset = 0)
369
+ {
370
+ $remoteFile = $this->correctFilePath($remoteFile);
371
+ $this->checkConnected();
372
+ return @ftp_get($this->_conn, $localFile, $remoteFile, $fileMode, $resumeOffset);
373
+ }
374
+
375
+ /**
376
+ * ftp_nlist wrapper
377
+ *
378
+ * @param string $dir
379
+ * @return boolean
380
+ */
381
+ public function nlist($dir = "/")
382
+ {
383
+ $this->checkConnected();
384
+ $dir = $this->correctFilePath($dir);
385
+ return @ftp_nlist($this->_conn, $dir);
386
+ }
387
+
388
+ /**
389
+ * ftp_rawlist wrapper
390
+ *
391
+ * @param string $dir
392
+ * @param boolean $recursive
393
+ * @return array
394
+ */
395
+ public function rawlist( $dir = "/", $recursive = false )
396
+ {
397
+ $this->checkConnected();
398
+ $dir = $this->correctFilePath($dir);
399
+ return @ftp_rawlist($this->_conn, $dir, $recursive);
400
+ }
401
+
402
+ /**
403
+ * Convert byte count to float KB/MB format
404
+ *
405
+ * @param int $bytes
406
+ * @return string
407
+ */
408
+ public static function byteconvert($bytes)
409
+ {
410
+ $symbol = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
411
+ $exp = floor( log($bytes) / log(1024) );
412
+ return sprintf( '%.2f ' . $symbol[ $exp ], ($bytes / pow(1024, floor($exp))) );
413
+ }
414
+
415
+ /**
416
+ * Chmod string "-rwxrwxrwx" to "777" converter
417
+ *
418
+ * @param string $chmod
419
+ * @return string
420
+ */
421
+ public static function chmodnum($chmod)
422
+ {
423
+ $trans = array('-' => '0', 'r' => '4', 'w' => '2', 'x' => '1');
424
+ $chmod = substr(strtr($chmod, $trans), 1);
425
+ $array = str_split($chmod, 3);
426
+ return array_sum(str_split($array[0])) . array_sum(str_split($array[1])) . array_sum(str_split($array[2]));
427
+ }
428
+
429
+ /**
430
+ * Checks file exists
431
+ *
432
+ * @param string $path
433
+ * @param boolean $excludeIfIsDir
434
+ * @return boolean
435
+ */
436
+ public function fileExists($path, $excludeIfIsDir = true)
437
+ {
438
+ $path = $this->correctFilePath($path);
439
+ $globalPathMode = substr($path, 0, 1) == "/";
440
+
441
+ $file = basename($path);
442
+ $dir = $globalPathMode ? dirname($path) : $this->getcwd()."/".($path==basename($path)?'':$path);
443
+ $data = $this->ls($dir);
444
+ foreach($data as $row) {
445
+ if($file == basename($row['name'])) {
446
+ if($excludeIfIsDir && $row['dir']) {
447
+ continue;
448
+ }
449
+ return true;
450
+ }
451
+ }
452
+ return false;
453
+ }
454
+
455
+ /**
456
+ * Get directory contents in PHP array
457
+ *
458
+ * @param string $dir
459
+ * @param boolean $recursive
460
+ * @return array
461
+ */
462
+ public function ls($dir = "/", $recursive = false)
463
+ {
464
+ $dir= $this->correctFilePath($dir);
465
+ $rawfiles = (array) $this->rawlist($dir, $recursive);
466
+ $structure = array();
467
+ $arraypointer = &$structure;
468
+ foreach ($rawfiles as $rawfile) {
469
+ if ($rawfile[0] == '/') {
470
+ $paths = array_slice(explode('/', str_replace(':', '', $rawfile)), 1);
471
+ $arraypointer = &$structure;
472
+ foreach ($paths as $path) {
473
+ foreach ($arraypointer as $i => $file) {
474
+ if ($file['name'] == $path) {
475
+ $arraypointer = &$arraypointer[ $i ]['children'];
476
+ break;
477
+ }
478
+ }
479
+ }
480
+ } elseif(!empty($rawfile)) {
481
+ $info = preg_split("/[\s]+/", $rawfile, 9);
482
+ $arraypointer[] = array(
483
+ 'name' => $info[8],
484
+ 'dir' => $info[0]{0} == 'd',
485
+ 'size' => (int) $info[4],
486
+ 'chmod' => self::chmodnum($info[0]),
487
+ 'rawdata' => $info,
488
+ 'raw' => $rawfile
489
+ );
490
+ }
491
+ }
492
+ return $structure;
493
+ }
494
+
495
+ /**
496
+ * Correct file path
497
+ *
498
+ * @param $str
499
+ * @return string
500
+ */
501
+ public function correctFilePath($str)
502
+ {
503
+ $str = str_replace("\\", "/", $str);
504
+ $str = preg_replace("/^.\//", "", $str);
505
+ return $str;
506
+ }
507
+
508
+ /**
509
+ * Delete file
510
+ *
511
+ * @param string $file
512
+ * @return boolean
513
+ */
514
+ public function delete($file)
515
+ {
516
+ $this->checkConnected();
517
+ $file = $this->correctFilePath($file);
518
+ return @ftp_delete($this->_conn, $file);
519
+ }
520
+
521
+ /**
522
+ * Remove directory
523
+ *
524
+ * @param string $dir
525
+ * @return boolean
526
+ */
527
+ public function rmdir($dir)
528
+ {
529
+ $this->checkConnected();
530
+ $dir = $this->correctFilePath($dir);
531
+ return @ftp_rmdir($this->_conn, $dir);
532
+ }
533
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Loader.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class for loader which using in the Rest
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Loader
35
+ {
36
+ /**
37
+ * Factory for HTTP client
38
+ *
39
+ * @param string|false $protocol 'curl'/'socket' or false for auto-detect
40
+ * @return Mage_HTTP_IClient|Mage_Connect_Loader_Ftp
41
+ */
42
+ public static function getInstance($protocol='')
43
+ {
44
+ if ($protocol == 'ftp') {
45
+ return new Mage_Connect_Loader_Ftp();
46
+ } else {
47
+ return Mage_HTTP_Client::getInstance();
48
+ }
49
+ }
50
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Loader/Ftp.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class for ftp loader which using in the Rest
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Loader_Ftp
35
+ {
36
+
37
+ const TEMPORARY_DIR = '../var/package/tmp';
38
+
39
+ const FTP_USER = 'anonymous';
40
+
41
+ const FTP_PASS = 'test@gmail.com';
42
+
43
+ /**
44
+ * Object of Ftp
45
+ *
46
+ * @var Mage_Connect_Ftp
47
+ */
48
+ protected $_ftp = null;
49
+
50
+ /**
51
+ * User name
52
+ * @var string
53
+ */
54
+ protected $_ftpUser = '';
55
+
56
+ /**
57
+ * User password
58
+ * @var string
59
+ */
60
+ protected $_ftpPassword = '';
61
+
62
+ /**
63
+ * Response body
64
+ * @var string
65
+ */
66
+ protected $_responseBody = '';
67
+
68
+ /**
69
+ * Response status
70
+ * @var int
71
+ */
72
+ protected $_responseStatus = 0;
73
+
74
+ /**
75
+ * Constructor
76
+ */
77
+ public function __construct()
78
+ {
79
+ $this->_ftp = new Mage_Connect_Ftp();
80
+ $this->_ftpUser = self::FTP_USER;
81
+ $this->_ftpPassword = self::FTP_PASS;
82
+ }
83
+
84
+ public function getFtp()
85
+ {
86
+ return $this->_ftp;
87
+ }
88
+
89
+ /**
90
+ * Retrieve file from URI
91
+ *
92
+ * @param mixed $uri
93
+ * @return bool
94
+ */
95
+ public function get($uri)
96
+ {
97
+ $remoteFile = basename($uri);
98
+ $uri = dirname($uri);
99
+ $uri = str_replace('http://', '', $uri);
100
+ $uri = str_replace('https://', '', $uri);
101
+ $uri = str_replace('ftp://', '', $uri);
102
+ $uri = $this->_ftpUser.":".$this->_ftpPassword."@".$uri;
103
+ $this->getFtp()->connect("ftp://".$uri);
104
+ $this->getFtp()->pasv(true);
105
+ $tmpDir = self::TEMPORARY_DIR . DS;
106
+ if (!is_dir($tmpDir)) {
107
+ $tmpDir = sys_get_temp_dir();
108
+ }
109
+ if (substr($tmpDir, -1) != DS) {
110
+ $tmpDir .= DS;
111
+ }
112
+ $localFile = $tmpDir . time() . ".xml";
113
+
114
+ if ($this->getFtp()->get($localFile, $remoteFile)) {
115
+ $this->_responseBody = file_get_contents($localFile);
116
+ $this->_responseStatus = 200;
117
+ }
118
+ @unlink($localFile);
119
+ $this->getFtp()->close();
120
+ return $this;
121
+ }
122
+
123
+ /**
124
+ * Get response status code
125
+ *
126
+ * @return string
127
+ */
128
+ public function getStatus()
129
+ {
130
+ return $this->_responseStatus;
131
+ }
132
+
133
+ /**
134
+ * put your comment there...
135
+ *
136
+ * @return string
137
+ */
138
+ public function getBody()
139
+ {
140
+ return $this->_responseBody;
141
+ }
142
+
143
+ /**
144
+ * Set login credentials for ftp auth.
145
+ * @param string $ftpLogin Ftp User account name
146
+ * @param string $ftpPassword User password
147
+ * @return string
148
+ */
149
+ public function setCredentials($ftpLogin, $ftpPassword)
150
+ {
151
+ $this->_ftpUser = $ftpLogin;
152
+ $this->_ftpPassword = $ftpPassword;
153
+ }
154
+
155
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Package.php ADDED
@@ -0,0 +1,1499 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with Magento Connect packages
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Package
35
+ {
36
+
37
+ const PACKAGE_XML_DIR = 'var/package';
38
+
39
+ /**
40
+ * Contain SimpleXMLElement for composing document.
41
+ *
42
+ * @var SimpleXMLElement
43
+ */
44
+ protected $_packageXml;
45
+
46
+ /**
47
+ * Internal cache
48
+ *
49
+ * @var array
50
+ */
51
+ protected $_authors;
52
+
53
+ /**
54
+ * Internal cache
55
+ *
56
+ * @var array
57
+ */
58
+ protected $_contents;
59
+
60
+ /**
61
+ * Internal cache
62
+ *
63
+ * @var array
64
+ */
65
+ protected $_hashContents;
66
+
67
+ /**
68
+ * Internal cache
69
+ *
70
+ * @var array
71
+ */
72
+ protected $_compatible;
73
+
74
+ /**
75
+ * Internal cache
76
+ *
77
+ * @var array
78
+ */
79
+ protected $_dependencyPhpExtensions;
80
+
81
+ /**
82
+ * Internal cache
83
+ *
84
+ * @var array
85
+ */
86
+ protected $_dependencyPackages;
87
+
88
+ /**
89
+ * A helper object that can read from a package archive
90
+ *
91
+ * @var Mage_Connect_Package_Reader
92
+ */
93
+ protected $_reader;
94
+
95
+ /**
96
+ * A helper object that can create and write to a package archive
97
+ *
98
+ * @var Mage_Connect_Package_Writer
99
+ */
100
+ protected $_writer;
101
+
102
+ /**
103
+ * Validator object
104
+ *
105
+ * @var Mage_Connect_Validator
106
+ */
107
+ protected $_validator = null;
108
+
109
+ /**
110
+ * Validation errors
111
+ *
112
+ * @var array
113
+ */
114
+ protected $_validationErrors = array();
115
+
116
+ /**
117
+ * Object with target
118
+ *
119
+ * @var Mage_Connect_Package_Target
120
+ */
121
+ protected $_target = null;
122
+
123
+ /**
124
+ * Config object
125
+ *
126
+ * @var Mage_Connect_Config
127
+ */
128
+ protected $_config = null;
129
+
130
+ /**
131
+ * Creates a package object (empty, or from existing archive, or from package definition xml)
132
+ *
133
+ * @param null|string|resource $source
134
+ */
135
+ public function __construct($source=null)
136
+ {
137
+ libxml_use_internal_errors(true);
138
+
139
+ if (is_string($source)) {
140
+ // check what's in the string (a package definition or a package filename)
141
+ if (0 === strpos($source, "<?xml")) {
142
+ // package definition xml
143
+ $this->_init($source);
144
+ } elseif (is_file($source) && is_readable($source)) {
145
+ // package archive filename
146
+ $this->_loadFile($source);
147
+ } else {
148
+ throw new Mage_Exception('Invalid package source');
149
+ }
150
+ } elseif (is_resource($source)) {
151
+ $this->_loadResource($source);
152
+ } elseif (is_null($source)) {
153
+ $this->_init();
154
+ } else {
155
+ throw new Mage_Exception('Invalid package source');
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Initializes an empty package object
161
+ *
162
+ * @param null|string $definition optional package definition xml
163
+ * @return Mage_Connect_Package
164
+ */
165
+ protected function _init($definition=null)
166
+ {
167
+
168
+ if (!is_null($definition)) {
169
+ $this->_packageXml = simplexml_load_string($definition);
170
+ } else {
171
+ $packageXmlStub = <<<END
172
+ <?xml version="1.0"?>
173
+ <package>
174
+ <name />
175
+ <version />
176
+ <stability />
177
+ <license />
178
+ <channel />
179
+ <extends />
180
+ <summary />
181
+ <description />
182
+ <notes />
183
+ <authors />
184
+ <date />
185
+ <time />
186
+ <contents />
187
+ <compatible />
188
+ <dependencies />
189
+ </package>
190
+ END;
191
+ $this->_packageXml = simplexml_load_string($packageXmlStub);
192
+ }
193
+ return $this;
194
+ }
195
+
196
+ /**
197
+ * Loads a package from specified file
198
+ *
199
+ * @param string $filename
200
+ * @return Mage_Connect_Package
201
+ */
202
+ protected function _loadFile($filename='')
203
+ {
204
+ if (is_null($this->_reader)) {
205
+ $this->_reader = new Mage_Connect_Package_Reader($filename);
206
+ }
207
+ $content = $this->_reader->load();
208
+ $this->_packageXml = simplexml_load_string($content);
209
+ return $this;
210
+ }
211
+
212
+ /**
213
+ * Creates a package and saves it
214
+ *
215
+ * @param string $path
216
+ * @return Mage_Connect_Package
217
+ */
218
+ public function save($path)
219
+ {
220
+ $this->validate();
221
+ $path = rtrim($path, "\\/") . DS;
222
+ $this->_savePackage($path);
223
+ return $this;
224
+ }
225
+
226
+ /**
227
+ * Creates a package archive and saves it to specified path
228
+ *
229
+ * @param string $path
230
+ * @return Mage_Connect_Package
231
+ */
232
+ protected function _savePackage($path)
233
+ {
234
+ $fileName = $this->getReleaseFilename();
235
+ if (is_null($this->_writer)) {
236
+ $this->_writer = new Mage_Connect_Package_Writer($this->getContents(), $path.$fileName);
237
+ }
238
+ $this->_writer
239
+ ->composePackage()
240
+ ->addPackageXml($this->getPackageXml())
241
+ ->archivePackage();
242
+ return $this;
243
+ }
244
+
245
+ /**
246
+ * Retrieve Target object
247
+ *
248
+ * @return Mage_Connect_Package_Target
249
+ */
250
+ protected function getTarget()
251
+ {
252
+ if (!$this->_target instanceof Mage_Connect_Package_Target) {
253
+ $this->_target = new Mage_Connect_Package_Target();
254
+ }
255
+ return $this->_target;
256
+ }
257
+
258
+ public function setTarget($arg)
259
+ {
260
+ if ($arg instanceof Mage_Connect_Package_Target) {
261
+ $this->_target = $arg;
262
+ }
263
+ }
264
+
265
+ /* Mutators */
266
+
267
+ /**
268
+ * Puts value to name
269
+ *
270
+ * @param string $name
271
+ * @return Mage_Connect_Package
272
+ */
273
+ public function setName($name)
274
+ {
275
+ $this->_packageXml->name = $name;
276
+ return $this;
277
+ }
278
+
279
+ /**
280
+ * Puts value to <channel />
281
+ *
282
+ * @param string $channel
283
+ * @return Mage_Connect_Package
284
+ */
285
+ public function setChannel($channel)
286
+ {
287
+ $this->_packageXml->channel = $channel;
288
+ return $this;
289
+ }
290
+
291
+ /**
292
+ * Puts value to <summary />
293
+ *
294
+ * @param string $summary
295
+ * @return Mage_Connect_Package
296
+ */
297
+ public function setSummary($summary)
298
+ {
299
+ $this->_packageXml->summary = $summary;
300
+ return $this;
301
+ }
302
+
303
+ /**
304
+ * Puts value to <description />
305
+ *
306
+ * @param string $description
307
+ * @return Mage_Connect_Package
308
+ */
309
+ public function setDescription($description)
310
+ {
311
+ $this->_packageXml->description = $description;
312
+ return $this;
313
+ }
314
+
315
+ /**
316
+ * Puts value to <authors />
317
+ *
318
+ * array(
319
+ * array('name'=>'Name1', 'user'=>'User1', 'email'=>'email1@email.com'),
320
+ * array('name'=>'Name2', 'user'=>'User2', 'email'=>'email2@email.com'),
321
+ * );
322
+ *
323
+ * @param array $authors
324
+ * @return Mage_Connect_Package
325
+ */
326
+ public function setAuthors($authors)
327
+ {
328
+ $this->_authors = $authors;
329
+ foreach ($authors as $_author) {
330
+ $this->addAuthor($_author['name'], $_author['user'], $_author['email']);
331
+ }
332
+ return $this;
333
+ }
334
+
335
+ /**
336
+ * Add author to <authors/>
337
+ *
338
+ * @param string $name
339
+ * @param string $user
340
+ * @param string $email
341
+ * @return Mage_Connect_Package
342
+ */
343
+ public function addAuthor($name=null, $user=null, $email=null)
344
+ {
345
+ $this->_authors[] = array(
346
+ 'name' =>$name,
347
+ 'user' =>$user,
348
+ 'email'=>$email
349
+ );
350
+ $author = $this->_packageXml->authors->addChild('author');
351
+ $author->addChild('name', $name);
352
+ $author->addChild('user', $user);
353
+ $author->addChild('email', $email);
354
+ return $this;
355
+ }
356
+
357
+ /**
358
+ * Puts value to <date/>. Format should be Y-M-D.
359
+ *
360
+ * @param string $date
361
+ * @return Mage_Connect_Package
362
+ */
363
+ public function setDate($date)
364
+ {
365
+ $this->_packageXml->date = $date;
366
+ return $this;
367
+ }
368
+
369
+ /**
370
+ * Puts value to <time />. Format should be H:i:s.
371
+ *
372
+ * @param string $time
373
+ * @return Mage_Connect_Package
374
+ */
375
+ public function setTime($time)
376
+ {
377
+ $this->_packageXml->time = $time;
378
+ return $this;
379
+ }
380
+
381
+ /**
382
+ * Puts value to <version/>. Format should be X.Y.Z.
383
+ *
384
+ * @param string $version
385
+ * @return Mage_Connect_Package
386
+ */
387
+ public function setVersion($version)
388
+ {
389
+ $this->_packageXml->version = $version;
390
+ return $this;
391
+ }
392
+
393
+ /**
394
+ * Puts value to <stability/>. It can be alpha, beta, devel and stable.
395
+ *
396
+ * @param string $stability
397
+ * @return Mage_Connect_Package
398
+ */
399
+ public function setStability($stability)
400
+ {
401
+ $this->_packageXml->stability = $stability;
402
+ return $this;
403
+ }
404
+
405
+ /**
406
+ * Puts value to <license/>, also method can used for set attribute URI.
407
+ *
408
+ * @param string $license
409
+ * @param string $uri
410
+ * @return Mage_Connect_Package
411
+ */
412
+ public function setLicense($license, $uri=null)
413
+ {
414
+ $this->_packageXml->license = $license;
415
+ if ($uri) {
416
+ $this->_packageXml->license['uri'] = $uri;
417
+ }
418
+ return $this;
419
+ }
420
+
421
+ /**
422
+ * Puts value to <notes/>.
423
+ *
424
+ * @param string $notes
425
+ * @return Mage_Connect_Package
426
+ */
427
+ public function setNotes($notes)
428
+ {
429
+ $this->_packageXml->notes = $notes;
430
+ return $this;
431
+ }
432
+
433
+ /**
434
+ * Retrieve SimpleXMLElement node by xpath. If it absent, create new.
435
+ * For comparing nodes method uses attribute "name" in each nodes.
436
+ * If attribute "name" is same for both nodes, nodes are same.
437
+ *
438
+ * @param string $tag
439
+ * @param SimpleXMLElement $parent
440
+ * @param string $name
441
+ * @return SimpleXMLElement
442
+ */
443
+ protected function _getNode($tag, $parent, $name='')
444
+ {
445
+ $found = false;
446
+ foreach ($parent->xpath($tag) as $_node) {
447
+ if ($_node['name'] == $name) {
448
+ $node = $_node;
449
+ $found = true;
450
+ break;
451
+ }
452
+ }
453
+ if (!$found) {
454
+ $node = $parent->addChild($tag);
455
+ if ($name) {
456
+ $node->addAttribute('name', $name);
457
+ }
458
+ }
459
+ return $node;
460
+ }
461
+
462
+ /**
463
+ * Add directory or file to <contents />.
464
+ *
465
+ * @param string $path Path to directory or file
466
+ * @param string $targetName Target name.
467
+ * @param string $hash MD5 hash of the file
468
+ * @return Mage_Connect_Package
469
+ */
470
+ public function addContent($path, $targetName)
471
+ {
472
+ $found = false;
473
+ $parent = $this->_getNode('target', $this->_packageXml->contents, $targetName);
474
+ $source = str_replace('\\', '/', $path);
475
+ $directories = explode('/', dirname($source));
476
+ foreach ($directories as $directory) {
477
+ $parent = $this->_getNode('dir', $parent, $directory);
478
+ }
479
+ $fileName = basename($source);
480
+ if ($fileName!='') {
481
+ $fileNode = $parent->addChild('file');
482
+ $fileNode->addAttribute('name', $fileName);
483
+ $targetDir = $this->getTarget()->getTargetUri($targetName);
484
+ $hash = md5_file($targetDir.DS.$path);
485
+ $fileNode->addAttribute('hash', $hash);
486
+ }
487
+ return $this;
488
+ }
489
+
490
+ /**
491
+ * Add directory recursively (with subdirectory and file).
492
+ * Exclude and Include can be add using Regular Expression.
493
+ *
494
+ * @param string $targetName Target name
495
+ * @param string $targetDir Path for target name
496
+ * @param string $path Path to directory
497
+ * @param string $exclude Exclude
498
+ * @param string $include Include
499
+ * @return Mage_Connect_Package
500
+ */
501
+ public function addContentDir($targetName, $path, $exclude=null, $include=null)
502
+ {
503
+ $targetDir = $this->getTarget()->getTargetUri($targetName);
504
+ $targetDirLen = strlen($targetDir . DS);
505
+ //get all subdirectories and files.
506
+ $entries = @glob($targetDir. DS . $path . DS . "{,.}*", GLOB_BRACE);
507
+ if (!empty($entries)) {
508
+ foreach ($entries as $entry) {
509
+ $filePath = substr($entry, $targetDirLen);
510
+ if (!empty($include) && !preg_match($include, $filePath)) {
511
+ continue;
512
+ }
513
+ if (!empty($exclude) && preg_match($exclude, $filePath)) {
514
+ continue;
515
+ }
516
+ if (is_dir($entry)) {
517
+ $baseName = basename($entry);
518
+ if ('.'===$baseName || '..'===$baseName) {
519
+ continue;
520
+ }
521
+ //for subdirectory call method recursively
522
+ $this->addContentDir($targetName, $filePath, $exclude, $include);
523
+ } elseif (is_file($entry)) {
524
+ $this->addContent($filePath, $targetName);
525
+ }
526
+ }
527
+ }
528
+ return $this;
529
+ }
530
+
531
+ /**
532
+ * Add value to <compatible />.
533
+ *
534
+ * @param string $packageName
535
+ * @param string $channel
536
+ * @param string $minVersion
537
+ * @param string $maxVersion
538
+ * @return Mage_Connect_Package
539
+ */
540
+ public function addCompatible($packageName, $channel, $minVersion, $maxVersion)
541
+ {
542
+ $package = $this->_packageXml->compatible->addChild('package');
543
+ $package->addChild('name', $packageName);
544
+ $package->addChild('channel', $channel);
545
+ $package->addChild('min', $minVersion);
546
+ $package->addChild('max', $maxVersion);
547
+ return $this;
548
+ }
549
+
550
+ /**
551
+ * Set dependency from php version.
552
+ *
553
+ * @param string $minVersion
554
+ * @param string $maxVersion
555
+ * @return Mage_Connect_Package
556
+ */
557
+ public function setDependencyPhpVersion($minVersion, $maxVersion)
558
+ {
559
+ $parent = $this->_packageXml->dependencies;
560
+ $parent = $this->_getNode('required', $parent);
561
+ $parent = $this->_getNode('php', $parent);
562
+ $parent->addChild('min', $minVersion);
563
+ $parent->addChild('max', $maxVersion);
564
+ return $this;
565
+ }
566
+
567
+
568
+ /**
569
+ * Check PHP version restriction
570
+ * @param $phpVersion PHP_VERSION by default
571
+ * @return true | string
572
+ */
573
+ public function checkPhpVersion()
574
+ {
575
+ $min = $this->getDependencyPhpVersionMin();
576
+ $max = $this->getDependencyPhpVersionMax();
577
+
578
+ $minOk = $min? version_compare(PHP_VERSION, $min, ">=") : true;
579
+ $maxOk = $max? version_compare(PHP_VERSION, $max, "<=") : true;
580
+
581
+ if(!$minOk || !$maxOk) {
582
+ $err = "requires PHP version ";
583
+ if($min && $max) {
584
+ $err .= " >= $min and <= $max ";
585
+ } elseif($min) {
586
+ $err .= " >= $min ";
587
+ } elseif($max) {
588
+ $err .= " <= $max ";
589
+ }
590
+ $err .= " current is: ".PHP_VERSION;
591
+ return $err;
592
+ }
593
+ return true;
594
+ }
595
+
596
+
597
+ /**
598
+ * Check PHP extensions availability
599
+ * @throws Exceptiom on failure
600
+ * @return true | array
601
+ */
602
+ public function checkPhpDependencies()
603
+ {
604
+ $errors = array();
605
+ foreach($this->getDependencyPhpExtensions() as $dep)
606
+ {
607
+ if(!extension_loaded($dep['name'])) {
608
+ $errors[] = $dep;
609
+ }
610
+ }
611
+ if(count($errors)) {
612
+ return $errors;
613
+ }
614
+ return true;
615
+ }
616
+
617
+
618
+ /**
619
+ * Set dependency from php extensions.
620
+ *
621
+ * $extension has next view:
622
+ * array('curl', 'mysql')
623
+ *
624
+ * @param array|string $extensions
625
+ * @return Mage_Connect_Package
626
+ */
627
+ public function setDependencyPhpExtensions($extensions)
628
+ {
629
+ foreach($extensions as $_extension) {
630
+ $this->addDependencyExtension(
631
+ $_extension['name'],
632
+ $_extension['min_version'],
633
+ $_extension['max_version']
634
+ );
635
+ }
636
+ return $this;
637
+ }
638
+
639
+ /**
640
+ * Set dependency from another packages.
641
+ *
642
+ * $packages should contain:
643
+ * array(
644
+ * array('name'=>'test1', 'channel'=>'test1', 'min_version'=>'0.0.1', 'max_version'=>'0.1.0'),
645
+ * array('name'=>'test2', 'channel'=>'test2', 'min_version'=>'0.0.1', 'max_version'=>'0.1.0'),
646
+ * )
647
+ *
648
+ * @param array $packages
649
+ * @param bool $clear
650
+ * @return Mage_Connect_Package
651
+ */
652
+ public function setDependencyPackages($packages, $clear = false)
653
+ {
654
+ if($clear) {
655
+ unset($this->_packageXml->dependencies->required->package);
656
+ }
657
+
658
+ foreach($packages as $_package) {
659
+
660
+ $filesArrayCondition = isset($_package['files']) && is_array($_package['files']);
661
+ $filesArray = $filesArrayCondition ? $_package['files'] : array();
662
+
663
+ $this->addDependencyPackage(
664
+ $_package['name'],
665
+ $_package['channel'],
666
+ $_package['min_version'],
667
+ $_package['max_version'],
668
+ $filesArray
669
+ );
670
+ }
671
+ return $this;
672
+ }
673
+
674
+
675
+
676
+ /**
677
+ * Add package to dependency packages.
678
+ *
679
+ * @param string $package
680
+ * @param string $channel
681
+ * @param string $minVersion
682
+ * @param string $maxVersion
683
+ * @return Mage_Connect_Package
684
+ */
685
+ public function addDependencyPackage($name, $channel, $minVersion, $maxVersion, $files = array())
686
+ {
687
+ $parent = $this->_packageXml->dependencies;
688
+ $parent = $this->_getNode('required', $parent);
689
+ $parent = $parent->addChild('package');
690
+ $parent->addChild('name', $name);
691
+ $parent->addChild('channel', $channel);
692
+ $parent->addChild('min', $minVersion);
693
+ $parent->addChild('max', $maxVersion);
694
+ if(count($files)) {
695
+ $parent = $parent->addChild('files');
696
+ foreach($files as $row) {
697
+ if(!empty($row['target']) && !empty($row['path'])) {
698
+ $node = $parent->addChild("file");
699
+ $node["target"] = $row['target'];
700
+ $node["path"] = $row['path'];
701
+
702
+ }
703
+ }
704
+ }
705
+ return $this;
706
+ }
707
+
708
+
709
+
710
+ /**
711
+ * Add package to dependency extension.
712
+ *
713
+ * @param string $package
714
+ * @param string $minVersion
715
+ * @param string $maxVersion
716
+ * @return Mage_Connect_Package
717
+ */
718
+ public function addDependencyExtension($name, $minVersion, $maxVersion)
719
+ {
720
+ $parent = $this->_packageXml->dependencies;
721
+ $parent = $this->_getNode('required', $parent);
722
+ $parent = $parent->addChild('extension');
723
+ $parent->addChild('name', $name);
724
+ $parent->addChild('min', $minVersion);
725
+ $parent->addChild('max', $maxVersion);
726
+ return $this;
727
+ }
728
+
729
+ /* Accessors */
730
+
731
+ /**
732
+ * Getter
733
+ *
734
+ * @return string
735
+ */
736
+ public function getName()
737
+ {
738
+ return (string)$this->_packageXml->name;
739
+ }
740
+
741
+ /**
742
+ * Getter
743
+ *
744
+ * @return string
745
+ */
746
+ public function getChannel()
747
+ {
748
+ return (string)$this->_packageXml->channel;
749
+ }
750
+
751
+ /**
752
+ * Getter
753
+ *
754
+ * @return string
755
+ */
756
+ public function getSummary()
757
+ {
758
+ return (string)$this->_packageXml->summary;
759
+ }
760
+
761
+ /**
762
+ * Getter
763
+ *
764
+ * @return string
765
+ */
766
+ public function getDescription()
767
+ {
768
+ return (string)$this->_packageXml->description;
769
+ }
770
+
771
+ /**
772
+ * Get list of authors in associative array.
773
+ *
774
+ * @return array
775
+ */
776
+ public function getAuthors()
777
+ {
778
+ if (is_array($this->_authors)) return $this->_authors;
779
+ $this->_authors = array();
780
+ if(!isset($this->_packageXml->authors->author)) {
781
+ return array();
782
+ }
783
+ foreach ($this->_packageXml->authors->author as $_author) {
784
+ $this->_authors[] = array(
785
+ 'name' => (string)$_author->name,
786
+ 'user' => (string)$_author->user,
787
+ 'email'=> (string)$_author->email
788
+ );
789
+ }
790
+ return $this->_authors;
791
+ }
792
+
793
+ /**
794
+ * Getter
795
+ *
796
+ * @return string
797
+ */
798
+ public function getDate()
799
+ {
800
+ return (string)$this->_packageXml->date;
801
+ }
802
+
803
+ /**
804
+ * Getter
805
+ *
806
+ * @return string
807
+ */
808
+ public function getTime()
809
+ {
810
+ return (string)$this->_packageXml->time;
811
+ }
812
+
813
+ /**
814
+ * Getter
815
+ *
816
+ * @return string
817
+ */
818
+ public function getVersion()
819
+ {
820
+ return (string)$this->_packageXml->version;
821
+ }
822
+
823
+ /**
824
+ * Getter
825
+ *
826
+ * @return string
827
+ */
828
+ public function getStability()
829
+ {
830
+ return (string)$this->_packageXml->stability;
831
+ }
832
+
833
+ /**
834
+ * Getter
835
+ *
836
+ * @return string
837
+ */
838
+ public function getLicense()
839
+ {
840
+ return (string)$this->_packageXml->license;
841
+ }
842
+
843
+ /**
844
+ * Getter
845
+ *
846
+ * @return string
847
+ */
848
+ public function getLicenseUri()
849
+ {
850
+ return (string)$this->_packageXml->license['uri'];
851
+ }
852
+
853
+ /**
854
+ * Getter
855
+ *
856
+ * @return string
857
+ */
858
+ public function getNotes()
859
+ {
860
+ return (string)$this->_packageXml->notes;
861
+ }
862
+
863
+ /**
864
+ * Create list of all files from package.xml
865
+ *
866
+ * @return array
867
+ */
868
+ public function getContents()
869
+ {
870
+ if (is_array($this->_contents)) return $this->_contents;
871
+ $this->_contents = array();
872
+ if(!isset($this->_packageXml->contents->target)) {
873
+ return $this->_contents;
874
+ }
875
+ foreach($this->_packageXml->contents->target as $target) {
876
+ $targetUri = $this->getTarget()->getTargetUri($target['name']);
877
+ $this->_getList($target, $targetUri);
878
+ }
879
+ return $this->_contents;
880
+ }
881
+
882
+ /**
883
+ * Helper for getContents(). Create recursively list.
884
+ *
885
+ * @param SimpleXMLElement $parent
886
+ * @param string $path
887
+ */
888
+ protected function _getList($parent, $path)
889
+ {
890
+ if (count($parent) == 0) {
891
+ $this->_contents[] = $path;
892
+ } else {
893
+ foreach($parent as $_content) {
894
+ $this->_getList($_content, ($path ? $path . DS : '') . $_content['name']);
895
+ }
896
+ }
897
+ }
898
+
899
+ /**
900
+ * Create list of all files from package.xml with hash
901
+ *
902
+ * @return array
903
+ */
904
+ public function getHashContents()
905
+ {
906
+ if (is_array($this->_hashContents)) return $this->_hashContents;
907
+ $this->_hashContents = array();
908
+ if(!isset($this->_packageXml->contents->target)) {
909
+ return $this->_hashContents;
910
+ }
911
+ foreach($this->_packageXml->contents->target as $target) {
912
+ $targetUri = $this->getTarget()->getTargetUri($target['name']);
913
+ $this->_getHashList($target, $targetUri);
914
+ }
915
+ return $this->_hashContents;
916
+ }
917
+
918
+ /**
919
+ * Helper for getHashContents(). Create recursively list.
920
+ *
921
+ * @param SimpleXMLElement $parent
922
+ * @param string $path
923
+ */
924
+ protected function _getHashList($parent, $path, $hash='')
925
+ {
926
+ if (count($parent) == 0) {
927
+ $this->_hashContents[$path] = $hash;
928
+ } else {
929
+ foreach($parent as $_content) {
930
+ $contentHash = '';
931
+ if (isset($_content['hash'])) {
932
+ $contentHash = (string)$_content['hash'];
933
+ }
934
+ $this->_getHashList($_content, ($path ? $path . DS : '') . $_content['name'], $contentHash);
935
+ }
936
+ }
937
+ }
938
+
939
+ /**
940
+ * Get compatible packages.
941
+ *
942
+ * @return array
943
+ */
944
+ public function getCompatible()
945
+ {
946
+ if (is_array($this->_compatible)) return $this->_compatible;
947
+ $this->_compatible = array();
948
+ if(!isset($this->_packageXml->compatible->package)) {
949
+ return array();
950
+ }
951
+ foreach ($this->_packageXml->compatible->package as $_package) {
952
+ $this->_compatible[] = array(
953
+ 'name' => (string)$_package->name,
954
+ 'channel' => (string)$_package->channel,
955
+ 'min' => (string)$_package->min,
956
+ 'max' => (string)$_package->max
957
+ );
958
+ }
959
+ return $this->_compatible;
960
+ }
961
+
962
+ /**
963
+ * Getter
964
+ *
965
+ * @return string
966
+ */
967
+ public function getDependencyPhpVersionMin()
968
+ {
969
+ if(!isset($this->_packageXml->dependencies->required->php->min)) {
970
+ return false;
971
+ }
972
+ return (string)$this->_packageXml->dependencies->required->php->min;
973
+ }
974
+
975
+ /**
976
+ * Getter
977
+ *
978
+ * @return string
979
+ */
980
+ public function getDependencyPhpVersionMax()
981
+ {
982
+ if(!isset($this->_packageXml->dependencies->required->php->max)) {
983
+ return false;
984
+ }
985
+ return (string)$this->_packageXml->dependencies->required->php->max;
986
+ }
987
+
988
+ /**
989
+ * Get list of php extensions.
990
+ *
991
+ * @return array
992
+ */
993
+ public function getDependencyPhpExtensions()
994
+ {
995
+ if (is_array($this->_dependencyPhpExtensions)) return $this->_dependencyPhpExtensions;
996
+ $this->_dependencyPhpExtensions = array();
997
+ if (!isset($this->_packageXml->dependencies->required->extension)) {
998
+ return $this->_dependencyPhpExtensions;
999
+ }
1000
+ foreach($this->_packageXml->dependencies->required->extension as $_package) {
1001
+ $this->_dependencyPhpExtensions[] = array(
1002
+ 'name' => (string)$_package->name,
1003
+ 'min' => (string)$_package->min,
1004
+ 'max' => (string)$_package->max,
1005
+ );
1006
+ }
1007
+ return $this->_dependencyPhpExtensions;
1008
+ }
1009
+
1010
+ /**
1011
+ * Get list of dependency packages.
1012
+ *
1013
+ * @return array
1014
+ */
1015
+ public function getDependencyPackages()
1016
+ {
1017
+ $this->_dependencyPackages = array();
1018
+ if (!isset($this->_packageXml->dependencies->required->package)) {
1019
+ return $this->_dependencyPackages;
1020
+ }
1021
+ foreach($this->_packageXml->dependencies->required->package as $_package) {
1022
+ $add = array(
1023
+ 'name' => (string)$_package->name,
1024
+ 'channel' => (string)$_package->channel,
1025
+ 'min' => (string)$_package->min,
1026
+ 'max' => (string)$_package->max,
1027
+ );
1028
+ if(isset($_package->files)) {
1029
+ $add['files'] = array();
1030
+ foreach($_package->files as $node) {
1031
+ if(isset($node->file)) {
1032
+
1033
+ $add['files'][] = array('target' => (string) $node->file['target'], 'path'=> (string) $node->file['path']);
1034
+ }
1035
+ }
1036
+ }
1037
+ $this->_dependencyPackages[] = $add;
1038
+ }
1039
+ return $this->_dependencyPackages;
1040
+ }
1041
+
1042
+
1043
+
1044
+
1045
+ /**
1046
+ * Get string with XML content.
1047
+ *
1048
+ * @return string
1049
+ */
1050
+ public function getPackageXml()
1051
+ {
1052
+ return $this->_packageXml->asXml();
1053
+ }
1054
+
1055
+
1056
+ /**
1057
+ * Validator instance (single)
1058
+ *
1059
+ * @return Mage_Connect_Validator
1060
+ */
1061
+ protected function validator()
1062
+ {
1063
+ if(is_null($this->_validator)) {
1064
+ $this->_validator = new Mage_Connect_Validator();
1065
+ }
1066
+ return $this->_validator;
1067
+ }
1068
+
1069
+ /**
1070
+ * Get validation error strings
1071
+ *
1072
+ * @return array
1073
+ */
1074
+ public function getErrors()
1075
+ {
1076
+ return $this->_validationErrors;
1077
+ }
1078
+
1079
+ /**
1080
+ * Setter for validation errors
1081
+ *
1082
+ * @param array $errors
1083
+ * @return
1084
+ */
1085
+ protected function setErrors(array $errors)
1086
+ {
1087
+ $this->_validationErrors = $errors;
1088
+ }
1089
+
1090
+ /**
1091
+ * Check validation result.
1092
+ * Returns true if package data is invalid.
1093
+ *
1094
+ * @return bool
1095
+ */
1096
+ public function hasErrors()
1097
+ {
1098
+ return count($this->_validationErrors) != 0;
1099
+ }
1100
+
1101
+ /**
1102
+ * Validate package. Errors can be
1103
+ * retreived by calling getErrors();
1104
+ *
1105
+ * @return bool
1106
+ */
1107
+ public function validate()
1108
+ {
1109
+ $v = $this->validator();
1110
+
1111
+ /**
1112
+ * Validation map
1113
+ *
1114
+ * Format:
1115
+ *
1116
+ * 'key' => array(
1117
+ * 'method' => this class method name to call, string, required
1118
+ * 'method_args' => optional args for 'method' call, array, optional
1119
+ * 'v_method' => validator method to call, string, required
1120
+ * 'error' => custom error string when validation fails, optional
1121
+ * if not set, error string fprmatted as "Invalid '$key' specified"
1122
+ * 'v_error_method' => validator method - when called returned error string
1123
+ * prepared by validator, optional,
1124
+ * if not set => see 'error'
1125
+ * 'optional' => optional value, if it's empty validation result ignored
1126
+ *
1127
+ */
1128
+ $validateMap = array(
1129
+ 'name' => array('method' => 'getName',
1130
+ 'v_method' => 'validatePackageName',
1131
+ 'error'=>"Invalid package name, allowed: [a-zA-Z0-9_-] chars"),
1132
+ 'version' => array('method' => 'getVersion',
1133
+ 'v_method' => 'validateVersion',
1134
+ 'error'=>"Invalid version, should be like: x.x.x"),
1135
+ 'stability' => array('method' => 'getStability',
1136
+ 'v_method' => 'validateStability',
1137
+ 'error'=>"Invalid stability"),
1138
+ 'date' => array('method' => 'getDate',
1139
+ 'v_method' => 'validateDate',
1140
+ 'error'=>"Invalid date, should be YYYY-DD-MM"),
1141
+ 'license_uri' => array('method' => 'getLicenseUri',
1142
+ 'v_method' => 'validateLicenseUrl',
1143
+ 'error'=>"Invalid license URL"),
1144
+ 'channel' => array('method' => 'getChannel',
1145
+ 'v_method' => 'validateChannelNameOrUri',
1146
+ 'error'=>"Invalid channel URL"),
1147
+ 'authors' => array('method' => 'getAuthors',
1148
+ 'v_method' => 'validateAuthors',
1149
+ 'v_error_method' => 'getErrors'),
1150
+ 'php_min' => array('method' => 'getDependencyPhpVersionMin',
1151
+ 'v_method' => 'validateVersion',
1152
+ 'error' => 'PHP minimum version invalid',
1153
+ 'optional' => true ),
1154
+ 'php_max' => array('method' => 'getDependencyPhpVersionMax',
1155
+ 'v_method' => 'validateVersion',
1156
+ 'error' => 'PHP maximum version invalid',
1157
+ 'optional' => true ),
1158
+ 'compatible' => array('method' => 'getCompatible',
1159
+ 'v_method' => 'validateCompatible',
1160
+ 'v_error_method' => 'getErrors'),
1161
+ 'content' => array('method' => 'getContents',
1162
+ 'v_method' => 'validateContents',
1163
+ 'v_args' => array('config' => $this->getConfig()),
1164
+ 'v_error_method' => 'getErrors'),
1165
+ );
1166
+
1167
+ $errors = array();
1168
+ /**
1169
+ * Iterate validation map
1170
+ */
1171
+ foreach($validateMap as $name=>$data) {
1172
+
1173
+ /**
1174
+ * Check mandatory rules fields
1175
+ */
1176
+ if(!isset($data['method'], $data['v_method'])) {
1177
+ throw new Mage_Exception("Invalid rules specified!");
1178
+ }
1179
+
1180
+ $method = $data['method'];
1181
+ $validatorMethod = $data['v_method'];
1182
+
1183
+ /**
1184
+ * If $optional === false, value is mandatory
1185
+ */
1186
+ $optional = isset($data['optional']) ? (bool) $data['optional'] : false;
1187
+
1188
+ /**
1189
+ * Check for method availability, package
1190
+ */
1191
+ if(!method_exists($this, $method)) {
1192
+ throw new Mage_Exception("Invalid method specified for Package : $method");
1193
+ }
1194
+
1195
+ /**
1196
+ * Check for method availability, validator
1197
+ */
1198
+ if(!method_exists($v, $validatorMethod)) {
1199
+ throw new Mage_Exception("Invalid method specified for Validator : $validatorMethod");
1200
+ }
1201
+
1202
+ /**
1203
+ * If $data['error'] => get error string from $data['error']
1204
+ * Else concatenate "Invalid '{$name}' specified"
1205
+ */
1206
+ $errorString = isset($data['error']) ? $data['error'] : "Invalid '{$name}' specified";
1207
+
1208
+ /**
1209
+ * Additional method args check
1210
+ * array() by default
1211
+ */
1212
+ $methodArgs = isset($data['method_args']) ? $data['method_args'] : array();
1213
+
1214
+ /**
1215
+ * Call package method
1216
+ */
1217
+ $out = @call_user_func_array(array($this, $method), $methodArgs);
1218
+
1219
+ /**
1220
+ * Skip if result is empty and value is optional
1221
+ */
1222
+ if(empty($out) && $optional) {
1223
+ continue;
1224
+ }
1225
+
1226
+ /**
1227
+ * Additional validator arguments, merged with array($out)
1228
+ */
1229
+ $validatorArgs = isset($data['v_args']) ? array_merge(array($out), $data['v_args']) : array($out);
1230
+
1231
+ /**
1232
+ * Get validation result
1233
+ */
1234
+ $result = call_user_func_array(array($v, $validatorMethod), $validatorArgs);
1235
+
1236
+ /**
1237
+ * Skip if validation success
1238
+ */
1239
+ if($result) {
1240
+ continue;
1241
+ }
1242
+
1243
+ /**
1244
+ * From where to get error string?
1245
+ * If validator callback method specified, call it to get errors array
1246
+ * Else get it from $errorString - local error string
1247
+ */
1248
+ $validatorFetchErrorsMethod = isset($data['v_error_method']) ? $data['v_error_method'] : false;
1249
+ if (false !== $validatorFetchErrorsMethod) {
1250
+ $errorString = call_user_func_array(array($v, $validatorFetchErrorsMethod), array());
1251
+ }
1252
+
1253
+ /**
1254
+ * If errors is array => merge
1255
+ * Else append
1256
+ */
1257
+ if(is_array($errorString)) {
1258
+ $errors = array_merge($errors, $errorString);
1259
+ } else {
1260
+ $errors[] = $errorString;
1261
+ }
1262
+ }
1263
+ /**
1264
+ * Set local errors
1265
+ */
1266
+ $this->setErrors($errors);
1267
+ /**
1268
+ * Return true if there's no errors :)
1269
+ */
1270
+ return ! $this->hasErrors();
1271
+ }
1272
+
1273
+ /**
1274
+ * Return package release filename w/o extension
1275
+ * @return string
1276
+ */
1277
+ public function getReleaseFilename()
1278
+ {
1279
+ return $this->getName()."-".$this->getVersion();
1280
+ }
1281
+
1282
+ /**
1283
+ * Return release filepath w/o extension
1284
+ * @return string
1285
+ */
1286
+ public function getRelaseDirFilename()
1287
+ {
1288
+ return $this->getName() . DS . $this->getVersion() . DS . $this->getReleaseFilename();
1289
+ }
1290
+
1291
+ /**
1292
+ * Clear dependencies
1293
+ *
1294
+ * @return Mage_Connect_Package
1295
+ */
1296
+ public function clearDependencies()
1297
+ {
1298
+ $this->_packageXml->dependencies = null;
1299
+ return $this;
1300
+ }
1301
+
1302
+ /**
1303
+ * Clear contents
1304
+ *
1305
+ * @return Mage_Connect_Package
1306
+ */
1307
+ public function clearContents()
1308
+ {
1309
+ $this->_packageXml->contents = null;
1310
+ return $this;
1311
+ }
1312
+
1313
+ /**
1314
+ * Get config
1315
+ *
1316
+ * @return Mage_Connect_Config
1317
+ */
1318
+ public function getConfig()
1319
+ {
1320
+ return $this->_config;
1321
+ }
1322
+
1323
+ /**
1324
+ * Set config
1325
+ *
1326
+ * @param Mage_Connect_Config $config
1327
+ */
1328
+ public function setConfig($config)
1329
+ {
1330
+ $this->_config = $config;
1331
+ }
1332
+
1333
+ /**
1334
+ * Import package information from previous version of Magento Connect Manager
1335
+ *
1336
+ * @param array $data
1337
+ *
1338
+ * @return Mage_Connect_Package
1339
+ */
1340
+ public function importDataV1x(array $data)
1341
+ {
1342
+ $this->_packageXml = null;
1343
+ $this->_init();
1344
+ // Import simple data
1345
+ if (isset($data['name'])) {
1346
+ $this->setName($data['name']);
1347
+ }
1348
+ if (isset($data['summary'])) {
1349
+ $this->setSummary($data['summary']);
1350
+ }
1351
+ if (isset($data['description'])) {
1352
+ $this->setDescription($data['description']);
1353
+ }
1354
+ if (isset($data['channel'])) {
1355
+ $this->setChannel($this->convertChannelFromV1x($data['channel']));
1356
+ }
1357
+ if (isset($data['license'])) {
1358
+ if (is_array($data['license'])) {
1359
+ $this->setLicense($data['license']['_content'], $data['license']['attribs']['uri']);
1360
+ } else {
1361
+ $this->setLicense($data['license']);
1362
+ }
1363
+ }
1364
+ if (isset($data['version'])) {
1365
+ $this->setVersion($data['version']['release']);
1366
+ }
1367
+ if (isset($data['stability'])) {
1368
+ $this->setStability($data['stability']['release']);
1369
+ }
1370
+ if (isset($data['notes'])) {
1371
+ $this->setNotes($data['notes']);
1372
+ }
1373
+ if (isset($data['date'])) {
1374
+ $this->setDate($data['date']);
1375
+ }
1376
+ if (isset($data['time'])) {
1377
+ $this->setTime($data['time']);
1378
+ }
1379
+
1380
+ // Import authors
1381
+ $authors = array();
1382
+ $authorRoles = array('lead', 'developer', 'contributor', 'helper');
1383
+ foreach ($authorRoles as $authorRole) {
1384
+ if (isset($data[$authorRole])) {
1385
+ $authorList = $data[$authorRole];
1386
+ if (!is_array($authorList) || isset($authorList['name'])) {
1387
+ $authorList = array($authorList);
1388
+ }
1389
+ foreach ($authorList as $authorRawData) {
1390
+ $author = array();
1391
+ $author['name'] = $authorRawData['name'];
1392
+ $author['user'] = $authorRawData['user'];
1393
+ $author['email'] = $authorRawData['email'];
1394
+ array_push($authors, $author);
1395
+ }
1396
+ }
1397
+ }
1398
+ $this->setAuthors($authors);
1399
+
1400
+ // Import dependencies
1401
+ $packages = array();
1402
+ $extensions = array();
1403
+ if (isset($data['dependencies']) && is_array($data['dependencies'])) {
1404
+ $dependencySections = array('required', 'optional');
1405
+ $elementTypes = array('package', 'extension');
1406
+ foreach ($dependencySections as $dependencySection) {
1407
+ if (isset($data['dependencies'][$dependencySection])) {
1408
+ // Handle required PHP version
1409
+ if ($dependencySection == 'required' && isset($data['dependencies']['required']['php'])) {
1410
+ $this->setDependencyPhpVersion($data['dependencies']['required']['php']['min'], $data['dependencies']['required']['php']['max']);
1411
+ }
1412
+ // Handle extensions
1413
+ if (isset($data['dependencies'][$dependencySection]['extension'])) {
1414
+ $extensionList = $data['dependencies'][$dependencySection]['extension'];
1415
+ if (!is_array($extensionList) || isset($extensionList['name'])) {
1416
+ $extensionList = array($extensionList);
1417
+ }
1418
+ foreach ($extensionList as $extensionRawData) {
1419
+ $extension = array();
1420
+ $extension['name'] = $extensionRawData['name'];
1421
+ $extension['min_version'] = isset($extensionRawData['min']) ? $extensionRawData['min'] : null;
1422
+ $extension['max_version'] = isset($extensionRawData['max']) ? $extensionRawData['max'] : null;
1423
+ array_push($extensions, $extension);
1424
+ }
1425
+ }
1426
+ // Handle packages
1427
+ if (isset($data['dependencies'][$dependencySection]['package'])) {
1428
+ $packageList = $data['dependencies'][$dependencySection]['package'];
1429
+ if (!is_array($packageList) || isset($packageList['name'])) {
1430
+ $packageList = array($packageList);
1431
+ }
1432
+ foreach ($packageList as $packageRawData) {
1433
+ $package = array();
1434
+ $package['name'] = $packageRawData['name'];
1435
+ $package['channel'] = $this->convertChannelFromV1x($packageRawData['channel']);
1436
+ $package['min_version'] = isset($packageRawData['min']) ? $packageRawData['min'] : null;
1437
+ $package['max_version'] = isset($packageRawData['max']) ? $packageRawData['max'] : null;
1438
+ array_push($packages, $package);
1439
+ }
1440
+ }
1441
+ }
1442
+ }
1443
+ }
1444
+ $this->setDependencyPackages($packages);
1445
+ $this->setDependencyPhpExtensions($extensions);
1446
+
1447
+ // Import contents
1448
+ if (isset($data['contents']) && is_array($data['contents']) && is_array($data['contents']['dir'])) {
1449
+ // Handle files
1450
+ $root = $data['contents']['dir'];
1451
+ if (isset($data['contents']['dir']['file'])) {
1452
+ $fileList = $data['contents']['dir']['file'];
1453
+ if (!is_array($fileList) || isset($fileList['attribs'])) {
1454
+ $fileList = array($fileList);
1455
+ }
1456
+ foreach ($fileList as $fileRawData) {
1457
+ $targetName = $fileRawData['attribs']['role'];
1458
+ $parentTargetNode = $this->_getNode('target', $this->_packageXml->contents, $targetName);
1459
+ $filePath = $fileRawData['attribs']['name'];
1460
+ $filePathParts = explode('/', $filePath);
1461
+ $fileName = array_pop($filePathParts);
1462
+ $parentDirNode = null;
1463
+ if (!empty($filePathParts)) {
1464
+ $parentDirNode = $parentTargetNode;
1465
+ foreach ($filePathParts as $directoryName) {
1466
+ $parentDirNode = $this->_getNode('dir', $parentDirNode, $directoryName);
1467
+ }
1468
+ } else {
1469
+ $parentDirNode = $this->_getNode('dir', $parentTargetNode, '.');
1470
+ }
1471
+ $fileNode = $parentDirNode->addChild('file');
1472
+ $fileNode->addAttribute('name', $fileName);
1473
+ $fileNode->addAttribute('hash', $fileRawData['attribs']['md5sum']);
1474
+ }
1475
+ }
1476
+ }
1477
+
1478
+ return $this;
1479
+ }
1480
+
1481
+ /**
1482
+ * Convert package channel in order for it to be compatible with current version of Magento Connect Manager
1483
+ *
1484
+ * @param string $channel
1485
+ *
1486
+ * @return string
1487
+ */
1488
+ public function convertChannelFromV1x($channel)
1489
+ {
1490
+ $channelMap = array(
1491
+ 'connect.magentocommerce.com/community' => 'community',
1492
+ 'connect.magentocommerce.com/core' => 'community'
1493
+ );
1494
+ if (!empty($channel) && isset($channelMap[$channel])) {
1495
+ $channel = $channelMap[$channel];
1496
+ }
1497
+ return $channel;
1498
+ }
1499
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Package/Extension.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Package/Hotfix.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with Magento Connect Hotfix
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+
35
+ class Mage_Connect_Package_Hotfix extends Mage_Connect_Package
36
+ {
37
+
38
+ /**
39
+ * Initializes an empty package object
40
+ *
41
+ * @param null|string $definition optional package definition xml
42
+ * @return Mage_Connect_Package
43
+ */
44
+ protected function _init($definition=null)
45
+ {
46
+
47
+ if (!is_null($definition)) {
48
+ $this->_packageXml = simplexml_load_string($definition);
49
+ } else {
50
+ $packageXmlStub = <<<END
51
+ <?xml version="1.0"?>
52
+ <package>
53
+ <name />
54
+ <version />
55
+ <stability />
56
+ <license />
57
+ <channel />
58
+ <extends />
59
+ <summary />
60
+ <description />
61
+ <notes />
62
+ <authors />
63
+ <date />
64
+ <time />
65
+ <replace />
66
+ <compatible />
67
+ <dependencies />
68
+ </package>
69
+ END;
70
+ $this->_packageXml = simplexml_load_string($packageXmlStub);
71
+ }
72
+ return $this;
73
+ }
74
+
75
+ /**
76
+ * Add content to node <replace/>
77
+ *
78
+ * @return Mage_Connect_Package_Hotfix
79
+ */
80
+ public function addReplace($path, $targetName)
81
+ {
82
+ $found = false;
83
+ $parent = $this->_getNode('target', $this->_packageXml->replace, $targetName);
84
+ $path = str_replace('\\', '/', $path);
85
+ $directories = explode('/', dirname($path));
86
+ foreach ($directories as $directory) {
87
+ $parent = $this->_getNode('dir', $parent, $directory);
88
+ }
89
+ $fileName = basename($path);
90
+ if ($fileName!='') {
91
+ $fileNode = $parent->addChild('file');
92
+ $fileNode->addAttribute('name', $fileName);
93
+ }
94
+ return $this;
95
+ }
96
+
97
+ /**
98
+ * Add directory recursively (with subdirectory and file).
99
+ * Exclude and Include can be add using Regular Expression.
100
+ *
101
+ * @param string $targetName Target name
102
+ * @param string $targetDir Path for target name
103
+ * @param string $path Path to directory
104
+ * @param string $exclude Exclude
105
+ * @param string $include Include
106
+ * @return Mage_Connect_Package
107
+ */
108
+ public function addReplaceDir($targetName, $targetDir, $path, $exclude=null, $include=null)
109
+ {
110
+ $targetDirLen = strlen($targetDir);
111
+ //get all subdirectories and files.
112
+ $entries = @glob($targetDir.$path.DS."*");
113
+ if (!empty($entries)) {
114
+ foreach ($entries as $entry) {
115
+ $filePath = substr($entry, $targetDirLen);
116
+ if (!empty($include) && !preg_match($include, $filePath)) {
117
+ continue;
118
+ }
119
+ if (!empty($ignore) && preg_match($exclude, $filePath)) {
120
+ continue;
121
+ }
122
+ if (is_dir($entry)) {
123
+ $baseName = basename($entry);
124
+ if ('.'===$baseName || '..'===$baseName) {
125
+ continue;
126
+ }
127
+ //for subdirectory call method recursively
128
+ $this->addReplaceDir($targetName, $targetDir, $filePath, $exclude, $include);
129
+ } elseif (is_file($entry)) {
130
+ $this->addReplace($filePath, $targetName);
131
+ }
132
+ }
133
+ }
134
+ return $this;
135
+ }
136
+
137
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Package/Maintainer.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Package/Reader.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to get package.xml from different places.
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Package_Reader
35
+ {
36
+
37
+ /**
38
+ * Name of package file
39
+ */
40
+ const DEFAULT_NAME_PACKAGE = 'package.xml';
41
+
42
+ /**
43
+ * Temporary dir for extract DEFAULT_NAME_PACKAGE.
44
+ */
45
+ const PATH_TO_TEMPORARY_DIRECTORY = 'var/package/tmp/';
46
+
47
+ /**
48
+ * Current path to file.
49
+ *
50
+ * @var string
51
+ */
52
+ protected $_file = '';
53
+
54
+ /**
55
+ * Archivator is used for extract DEFAULT_NAME_PACKAGE.
56
+ *
57
+ * @var Mage_Archive
58
+ */
59
+ protected $_archivator = null;
60
+
61
+ /**
62
+ * Constructor initializes $_file.
63
+ *
64
+ * @param string $file
65
+ * @return Mage_Connect_Package_Reader
66
+ */
67
+ public function __construct($file='')
68
+ {
69
+ if ($file) {
70
+ $this->_file = $file;
71
+ } else {
72
+ $this->_file = self::DEFAULT_NAME_PACKAGE;
73
+ }
74
+ return $this;
75
+ }
76
+
77
+ /**
78
+ * Retrieve archivator.
79
+ *
80
+ * @return Mage_Archive
81
+ */
82
+ protected function _getArchivator()
83
+ {
84
+ if (is_null($this->_archivator)) {
85
+ $this->_archivator = new Mage_Archive();
86
+ }
87
+ return $this->_archivator;
88
+ }
89
+
90
+ /**
91
+ * Open file directly or from archive and return his content.
92
+ *
93
+ * @return string Content of file $file
94
+ */
95
+ public function load()
96
+ {
97
+ if (!is_file($this->_file) || !is_readable($this->_file)) {
98
+ throw new Exception('Invalid package file specified.');
99
+ }
100
+ if ($this->_getArchivator()->isArchive($this->_file)) {
101
+ @mkdir(self::PATH_TO_TEMPORARY_DIRECTORY, 0777, true);
102
+ $this->_file = $this->_getArchivator()->extract(
103
+ self::DEFAULT_NAME_PACKAGE,
104
+ $this->_file,
105
+ self::PATH_TO_TEMPORARY_DIRECTORY
106
+ );
107
+ }
108
+ $xmlContent = $this->_readFile();
109
+ return $xmlContent;
110
+ }
111
+
112
+ /**
113
+ * Read content file.
114
+ *
115
+ * @return string Content of file $file
116
+ */
117
+ protected function _readFile()
118
+ {
119
+ $handle = fopen($this->_file, 'r');
120
+ try {
121
+ $data = $this->_loadResource($handle);
122
+ } catch (Mage_Exception $e) {
123
+ fclose($handle);
124
+ throw $e;
125
+ }
126
+ fclose($handle);
127
+ return $data;
128
+ }
129
+
130
+ /**
131
+ * Loads a package from specified resource
132
+ *
133
+ * @param resource $resource only file resources are supported at the moment
134
+ * @return Mage_Connect_Package
135
+ */
136
+ protected function _loadResource(&$resource)
137
+ {
138
+ $data = '';
139
+ //var_dump("====", $res, get_resource_type($resource));
140
+ if ('stream' === get_resource_type($resource)) {
141
+ while (!feof($resource)) {
142
+ $data .= fread($resource, 10240);
143
+ }
144
+ } else {
145
+ throw new Mage_Exception('Unsupported resource type');
146
+ }
147
+ return $data;
148
+ }
149
+
150
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Package/Target.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to get targets and their basepath from target.xml.
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+
35
+ class Mage_Connect_Package_Target
36
+ {
37
+
38
+ /**
39
+ * Object contains all contents from target.xml.
40
+ *
41
+ * @var array
42
+ */
43
+ protected $_targetMap=null;
44
+
45
+ /**
46
+ * Cache for targets.
47
+ *
48
+ * @var array
49
+ */
50
+ protected $_targets;
51
+
52
+ /**
53
+ * Retrieve content from target.xml.
54
+ *
55
+ * @return SimpleXMLElement
56
+ */
57
+ protected function _getTargetMap()
58
+ {
59
+ if (is_null($this->_targetMap)) {
60
+ $this->_targetMap = array();
61
+ $this->_targetMap[] = array('name'=>"magelocal" ,'label'=>"Magento Local module file" , 'uri'=>"./app/code/local");
62
+ $this->_targetMap[] = array('name'=>"magecommunity" ,'label'=>"Magento Community module file" , 'uri'=>"./app/code/community");
63
+ $this->_targetMap[] = array('name'=>"magecore" ,'label'=>"Magento Core team module file" , 'uri'=>"./app/code/core");
64
+ $this->_targetMap[] = array('name'=>"magedesign" ,'label'=>"Magento User Interface (layouts, templates)" , 'uri'=>"./app/design");
65
+ $this->_targetMap[] = array('name'=>"mageetc" ,'label'=>"Magento Global Configuration" , 'uri'=>"./app/etc");
66
+ $this->_targetMap[] = array('name'=>"magelib" ,'label'=>"Magento PHP Library file" , 'uri'=>"./lib");
67
+ $this->_targetMap[] = array('name'=>"magelocale" ,'label'=>"Magento Locale language file" , 'uri'=>"./app/locale");
68
+ $this->_targetMap[] = array('name'=>"magemedia" ,'label'=>"Magento Media library" , 'uri'=>"./media");
69
+ $this->_targetMap[] = array('name'=>"mageskin" ,'label'=>"Magento Theme Skin (Images, CSS, JS)" , 'uri'=>"./skin");
70
+ $this->_targetMap[] = array('name'=>"mageweb" ,'label'=>"Magento Other web accessible file" , 'uri'=>".");
71
+ $this->_targetMap[] = array('name'=>"magetest" ,'label'=>"Magento PHPUnit test" , 'uri'=>"./tests");
72
+ $this->_targetMap[] = array('name'=>"mage" ,'label'=>"Magento other" , 'uri'=>".");
73
+ }
74
+ return $this->_targetMap;
75
+ }
76
+
77
+ /**
78
+ * Retrieve targets as associative array from target.xml.
79
+ *
80
+ * @return array
81
+ */
82
+ public function getTargets()
83
+ {
84
+ if (!is_array($this->_targets)) {
85
+ $this->_targets = array();
86
+ if($this->_getTargetMap()) {
87
+ foreach ($this->_getTargetMap() as $_target) {
88
+ $this->_targets[$_target['name']] = (string)$_target['uri'];
89
+ }
90
+ }
91
+ }
92
+ return $this->_targets;
93
+ }
94
+
95
+ /**
96
+ * Retrieve tragets with label for select options.
97
+ *
98
+ * @return array
99
+ */
100
+ public function getLabelTargets()
101
+ {
102
+ $targets = array();
103
+ foreach ($this->_getTargetMap() as $_target) {
104
+ $targets[$_target['name']] = $_target['label'];
105
+ }
106
+ return $targets;
107
+ }
108
+
109
+ /**
110
+ * Get uri by target's name.
111
+ *
112
+ * @param string $name
113
+ * @return string
114
+ */
115
+ public function getTargetUri($name)
116
+ {
117
+ foreach ($this->getTargets() as $_name=>$_uri) {
118
+ if ($name == $_name) {
119
+ return $_uri;
120
+ }
121
+ }
122
+ return '';
123
+ }
124
+
125
+
126
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Package/VO.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ class Mage_Connect_Package_VO implements Iterator
28
+ {
29
+ protected $properties = array(
30
+ 'name' => '',
31
+ 'package_type_vesrion' => '',
32
+ 'cahnnel' => '',
33
+ 'extends' => '',
34
+ 'summary' => '',
35
+ 'description' => '',
36
+ 'authors' => '',
37
+ 'date' => '',
38
+ 'time' => '',
39
+ 'version' => '',
40
+ 'stability' => 'dev',
41
+ 'license' => '',
42
+ 'license_uri' => '',
43
+ 'contents' => '',
44
+ 'compatible' => '',
45
+ 'hotfix' => ''
46
+ );
47
+
48
+ public function rewind() {
49
+ reset($this->properties);
50
+ }
51
+
52
+ public function valid() {
53
+ return current($this->properties) !== false;
54
+ }
55
+
56
+ public function key() {
57
+ return key($this->properties);
58
+ }
59
+
60
+ public function current() {
61
+ return current($this->properties);
62
+ }
63
+
64
+ public function next() {
65
+ next($this->properties);
66
+ }
67
+
68
+ public function __get($var)
69
+ {
70
+ if (isset($this->properties[$var])) {
71
+ return $this->properties[$var];
72
+ }
73
+ return null;
74
+ }
75
+
76
+ public function __set($var, $value)
77
+ {
78
+ if (is_string($value)) {
79
+ $value = trim($value);
80
+ }
81
+ if (isset($this->properties[$var])) {
82
+ if ($value === null) {
83
+ $value = '';
84
+ }
85
+ $this->properties[$var] = $value;
86
+ }
87
+ }
88
+
89
+ public function toArray()
90
+ {
91
+ return $this->properties;
92
+ }
93
+
94
+ }
95
+
96
+
app/code/local/Mss/downloader/lib/Mage/Connect/Package/Writer.php ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to create archive.
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Package_Writer
35
+ {
36
+
37
+ /**
38
+ * Name of package configuration file
39
+ */
40
+ const DEFAULT_NAME_PACKAGE_CONFIG = 'package.xml';
41
+
42
+ /**
43
+ * Temporary dir for extract DEFAULT_NAME_PACKAGE.
44
+ */
45
+ const PATH_TO_TEMPORARY_DIRECTORY = 'var/package/tmp/';
46
+
47
+ /**
48
+ * Files are used in package.
49
+ *
50
+ * @var array
51
+ */
52
+ protected $_files = array();
53
+
54
+ /**
55
+ * Archivator is used for extract DEFAULT_NAME_PACKAGE.
56
+ *
57
+ * @var Mage_Archive
58
+ */
59
+ protected $_archivator = null;
60
+
61
+ /**
62
+ * Name of package with extension. Extension should be only one.
63
+ * "package.tar.gz" is not ability, only "package.tgz".
64
+ *
65
+ * @var string
66
+ */
67
+ protected $_namePackage = 'package';
68
+
69
+ /**
70
+ * Temporary directory where package is situated.
71
+ *
72
+ * @var string
73
+ */
74
+ protected $_temporaryPackageDir = '';
75
+
76
+ /**
77
+ * Path to archive with package.
78
+ *
79
+ * @var mixed
80
+ */
81
+ protected $_pathToArchive = '';
82
+
83
+ /**
84
+ * Constructor initializes $_file.
85
+ *
86
+ * @param array $files
87
+ * @param string $namePackage
88
+ * @return Mage_Connect_Package_Reader
89
+ */
90
+ public function __construct($files, $namePackage='')
91
+ {
92
+ $this->_files = $files;
93
+ $this->_namePackage = $namePackage;
94
+ return $this;
95
+ }
96
+
97
+ /**
98
+ * Retrieve archivator.
99
+ *
100
+ * @return Mage_Archive
101
+ */
102
+ protected function _getArchivator()
103
+ {
104
+ if (is_null($this->_archivator)) {
105
+ $this->_archivator = new Mage_Archive();
106
+ }
107
+ return $this->_archivator;
108
+ }
109
+
110
+ /**
111
+ * Create dir in PATH_TO_TEMPORARY_DIRECTORY and move all files
112
+ * to this dir.
113
+ *
114
+ * @return Mage_Connect_Package_Writer
115
+ */
116
+ public function composePackage()
117
+ {
118
+ @mkdir(self::PATH_TO_TEMPORARY_DIRECTORY, 0777, true);
119
+ $root = self::PATH_TO_TEMPORARY_DIRECTORY . basename($this->_namePackage);
120
+ @mkdir($root, 0777, true);
121
+ foreach ($this->_files as $file) {
122
+
123
+ if (is_dir($file) || is_file($file)) {
124
+ $fileName = basename($file);
125
+ $filePath = dirname($file);
126
+ @mkdir($root . DS . $filePath, 0777, true);
127
+ if (is_file($file)) {
128
+ copy($file, $root . DS . $filePath . DS . $fileName);
129
+ } else {
130
+ @mkdir($root . DS . $filePath . $fileName, 0777);
131
+ }
132
+ }
133
+ }
134
+ $this->_temporaryPackageDir = $root;
135
+ return $this;
136
+ }
137
+
138
+ /**
139
+ * Add package.xml to temporary package directory.
140
+ *
141
+ * @param $content
142
+ * @return Mage_Connect_Package_Writer
143
+ */
144
+ public function addPackageXml($content)
145
+ {
146
+ file_put_contents($this->_temporaryPackageDir . DS . self::DEFAULT_NAME_PACKAGE_CONFIG, $content);
147
+ return $this;
148
+ }
149
+
150
+ /**
151
+ * Archives package.
152
+ *
153
+ * @return Mage_Connect_Package_Writer
154
+ */
155
+ public function archivePackage()
156
+ {
157
+ $this->_pathToArchive = $this->_getArchivator()->pack(
158
+ $this->_temporaryPackageDir,
159
+ $this->_namePackage.'.tgz',
160
+ true);
161
+
162
+ //delete temporary dir
163
+ Mage_System_Dirs::rm(array("-r", $this->_temporaryPackageDir));
164
+ return $this;
165
+ }
166
+
167
+ /**
168
+ * Getter for pathToArchive
169
+ *
170
+ * @return string
171
+ */
172
+ public function getPathToArchive()
173
+ {
174
+ return $this->_pathToArchive;
175
+ }
176
+
177
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Packager.php ADDED
@@ -0,0 +1,1052 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to manipulate with packages
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Packager
35
+ {
36
+ /**
37
+ * Default Config File name
38
+ */
39
+ const CONFIG_FILE_NAME = 'downloader/connect.cfg';
40
+ /**
41
+ * Default Cache Config File name
42
+ */
43
+ const CACHE_FILE_NAME = 'downloader/cache.cfg';
44
+
45
+ /**
46
+ * Install states of package
47
+ */
48
+ const INSTALL_STATE_INSTALL = 'install';
49
+ const INSTALL_STATE_UPGRADE = 'upgrade';
50
+ const INSTALL_STATE_WRONG_VERSION = 'wrong_version';
51
+ const INSTALL_STATE_ALREADY_INSTALLED = 'already_installed';
52
+ const INSTALL_STATE_INCOMPATIBLE = 'incompatible';
53
+
54
+ /**
55
+ * Install states messages
56
+ *
57
+ * @var array
58
+ */
59
+ protected $installStates = array(
60
+ self::INSTALL_STATE_INSTALL => 'Ready to install',
61
+ self::INSTALL_STATE_UPGRADE => 'Ready to upgrade',
62
+ self::INSTALL_STATE_ALREADY_INSTALLED => 'Already installed',
63
+ self::INSTALL_STATE_WRONG_VERSION => 'Wrong version',
64
+ );
65
+
66
+ /**
67
+ * Archiver object
68
+ * @var Mage_Archive
69
+ */
70
+ protected $_archiver = null;
71
+
72
+ /**
73
+ * HTTP Client (Curl/Socket etc)
74
+ * @var Mage_HTTP_IClient
75
+ */
76
+ protected $_http = null;
77
+
78
+ /**
79
+ * Get Archiver object
80
+ *
81
+ * @return Mage_Archive
82
+ */
83
+ public function getArchiver()
84
+ {
85
+ if(is_null($this->_archiver)) {
86
+ $this->_archiver = new Mage_Archive();
87
+ }
88
+ return $this->_archiver;
89
+ }
90
+
91
+ /**
92
+ * Returns HTTP Client
93
+ * @return Mage_HTTP_IClient|null
94
+ */
95
+ public function getDownloader()
96
+ {
97
+ if(is_null($this->_http)) {
98
+ $this->_http = Mage_HTTP_Client::getInstance();
99
+ }
100
+ return $this->_http;
101
+ }
102
+
103
+ /**
104
+ * Get config data and cache config data remotely
105
+ *
106
+ * @param string $ftpString
107
+ * @return array
108
+ */
109
+ public function getRemoteConf($ftpString)
110
+ {
111
+ $ftpObj = new Mage_Connect_Ftp();
112
+ $ftpObj->connect($ftpString);
113
+ $cfgFile = self::CONFIG_FILE_NAME;
114
+ $cacheFile = self::CACHE_FILE_NAME;
115
+
116
+ $wd = $ftpObj->getcwd();
117
+
118
+ $remoteConfigExists = $ftpObj->fileExists($cfgFile);
119
+ $tempConfigFile = tempnam(sys_get_temp_dir(),'conf');
120
+ if(!$remoteConfigExists) {
121
+ $remoteCfg = new Mage_Connect_Config($tempConfigFile);
122
+ $remoteCfg->store();
123
+ $ftpObj->upload($cfgFile, $tempConfigFile);
124
+ } else {
125
+ $ftpObj->get($tempConfigFile, $cfgFile);
126
+ $remoteCfg = new Mage_Connect_Config($tempConfigFile);
127
+ }
128
+
129
+ $ftpObj->chdir($wd);
130
+
131
+ $remoteCacheExists = $ftpObj->fileExists($cacheFile);
132
+ $tempCacheFile = tempnam(sys_get_temp_dir(),'cache');
133
+
134
+ if(!$remoteCacheExists) {
135
+ $remoteCache = new Mage_Connect_Singleconfig($tempCacheFile);
136
+ $remoteCache->clear();
137
+ $ftpObj->upload($cacheFile, $tempCacheFile);
138
+ } else {
139
+ $ftpObj->get($tempCacheFile, $cacheFile);
140
+ $remoteCache = new Mage_Connect_Singleconfig($tempCacheFile);
141
+ }
142
+ $ftpObj->chdir($wd);
143
+ return array($remoteCache, $remoteCfg, $ftpObj);
144
+ }
145
+
146
+ /**
147
+ * Get Cache config data remotely
148
+ *
149
+ * @param string $ftpString
150
+ * @return array
151
+ */
152
+ public function getRemoteCache($ftpString)
153
+ {
154
+
155
+ $ftpObj = new Mage_Connect_Ftp();
156
+ $ftpObj->connect($ftpString);
157
+ $remoteConfigExists = $ftpObj->fileExists(self::CACHE_FILE_NAME);
158
+ if(!$remoteConfigExists) {
159
+ $configFile=tempnam(sys_get_temp_dir(),'conf');
160
+ $remoteCfg = new Mage_Connect_Singleconfig($configFile);
161
+ $remoteCfg->clear();
162
+ $ftpObj->upload(self::CACHE_FILE_NAME, $configFile);
163
+ } else {
164
+ $configFile=tempnam(sys_get_temp_dir(),'conf');
165
+ $ftpObj->get($configFile, self::CACHE_FILE_NAME);
166
+ $remoteCfg = new Mage_Connect_Singleconfig($configFile);
167
+ }
168
+ return array($remoteCfg, $ftpObj);
169
+ }
170
+
171
+ /**
172
+ * Get config data remotely
173
+ *
174
+ * @param string $ftpString
175
+ * @return array
176
+ */
177
+ public function getRemoteConfig($ftpString)
178
+ {
179
+ $ftpObj = new Mage_Connect_Ftp();
180
+ $ftpObj->connect($ftpString);
181
+ $cfgFile = self::CONFIG_FILE_NAME;
182
+
183
+ $wd = $ftpObj->getcwd();
184
+ $remoteConfigExists = $ftpObj->fileExists($cfgFile);
185
+ $tempConfigFile = tempnam(sys_get_temp_dir(),'conf_');
186
+ if(!$remoteConfigExists) {
187
+ $remoteCfg = new Mage_Connect_Config($tempConfigFile);
188
+ $remoteCfg->store();
189
+ $ftpObj->upload($cfgFile, $tempConfigFile);
190
+ } else {
191
+ $ftpObj->get($tempConfigFile, $cfgFile);
192
+ $remoteCfg = new Mage_Connect_Config($tempConfigFile);
193
+ }
194
+ $ftpObj->chdir($wd);
195
+ return array($remoteCfg, $ftpObj);
196
+ }
197
+
198
+ /**
199
+ * Write Cache config remotely
200
+ *
201
+ * @param Mage_Connect_Singleconfig $cache
202
+ * @param Mage_Connect_Ftp $ftpObj
203
+ * @return void
204
+ */
205
+ public function writeToRemoteCache($cache, $ftpObj)
206
+ {
207
+ $wd = $ftpObj->getcwd();
208
+ $ftpObj->upload(self::CACHE_FILE_NAME, $cache->getFilename());
209
+ @unlink($cache->getFilename());
210
+ $ftpObj->chdir($wd);
211
+ }
212
+
213
+ /**
214
+ * Write config remotely
215
+ *
216
+ * @param Mage_Connect_Config $cache
217
+ * @param Mage_Connect_Ftp $ftpObj
218
+ * @throws RuntimeException
219
+ */
220
+ public function writeToRemoteConfig($cache, $ftpObj)
221
+ {
222
+ $wd = $ftpObj->getcwd();
223
+ $ftpObj->upload(self::CONFIG_FILE_NAME, $cache->getFilename());
224
+ @unlink($cache->getFilename());
225
+ $ftpObj->chdir($wd);
226
+ }
227
+
228
+ /**
229
+ * Remove empty directories recursively up
230
+ *
231
+ * @param string $dir
232
+ * @param Mage_Connect_Ftp $ftp
233
+ */
234
+ protected function removeEmptyDirectory($dir, $ftp = null)
235
+ {
236
+ if ($ftp) {
237
+ if (count($ftp->nlist($dir))==0) {
238
+ if ($ftp->rmdir($dir)) {
239
+ $this->removeEmptyDirectory(dirname($dir), $ftp);
240
+ }
241
+ }
242
+ } else {
243
+ $content = scandir($dir);
244
+ if ($content === false) return;
245
+
246
+ if (count(array_diff($content, array('.', '..'))) == 0) {
247
+ if (@rmdir($dir)) {
248
+ $this->removeEmptyDirectory(dirname($dir), $ftp);
249
+ } else {
250
+ throw new RuntimeException('Failed to delete dir ' . $dir . "\r\n Check permissions");
251
+ }
252
+ }
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Uninstall Package
258
+ *
259
+ * @param string $chanName
260
+ * @param string $package
261
+ * @param Mage_Connect_Singleconfig $cacheObj
262
+ * @param Mage_Connect_Config $configObj
263
+ * @throws RuntimeException
264
+ */
265
+ public function processUninstallPackage($chanName, $package, $cacheObj, $configObj)
266
+ {
267
+ $package = $cacheObj->getPackageObject($chanName, $package);
268
+ $contents = $package->getContents();
269
+
270
+ $targetPath = rtrim($configObj->magento_root, "\\/");
271
+ $failedFiles = array();
272
+ foreach ($contents as $file) {
273
+ $fileName = basename($file);
274
+ $filePath = dirname($file);
275
+ $dest = $targetPath . DIRECTORY_SEPARATOR . $filePath . DIRECTORY_SEPARATOR . $fileName;
276
+ if(@file_exists($dest)) {
277
+ if (!@unlink($dest)) {
278
+ $failedFiles[] = $dest;
279
+ }
280
+ }
281
+ $this->removeEmptyDirectory(dirname($dest));
282
+ }
283
+ if (!empty($failedFiles)) {
284
+ $msg = sprintf("Failed to delete files: %s \r\n Check permissions", implode("\r\n", $failedFiles));
285
+ throw new RuntimeException($msg);
286
+ }
287
+
288
+ $destDir = $targetPath . DS . Mage_Connect_Package::PACKAGE_XML_DIR;
289
+ $destFile = $package->getReleaseFilename() . '.xml';
290
+ @unlink($destDir . DS . $destFile);
291
+ }
292
+
293
+ /**
294
+ * Uninstall Package over FTP
295
+ *
296
+ * @param $chanName
297
+ * @param $package
298
+ * @param Mage_Connect_Singleconfig $cacheObj
299
+ * @param Mage_Connect_Ftp $ftp
300
+ * @throws RuntimeException
301
+ */
302
+ public function processUninstallPackageFtp($chanName, $package, $cacheObj, $ftp)
303
+ {
304
+ $ftpDir = $ftp->getcwd();
305
+ $package = $cacheObj->getPackageObject($chanName, $package);
306
+ $contents = $package->getContents();
307
+ $failedFiles = array();
308
+ foreach ($contents as $file) {
309
+ $ftp->delete($file);
310
+ if ($ftp->fileExists($file)) {
311
+ $failedFiles[] = $file;
312
+ continue;
313
+ }
314
+ $this->removeEmptyDirectory(dirname($file), $ftp);
315
+ }
316
+ if (!empty($failedFiles)) {
317
+ $msg = sprintf("Failed to delete files: %s \r\n Check permissions", implode("\r\n", $failedFiles));
318
+ throw new RuntimeException($msg);
319
+ }
320
+ $remoteXml = Mage_Connect_Package::PACKAGE_XML_DIR . DS . $package->getReleaseFilename() . '.xml';
321
+ $ftp->delete($remoteXml);
322
+ $ftp->chdir($ftpDir);
323
+ }
324
+
325
+ /**
326
+ * Validation of mode permissions
327
+ *
328
+ * @param int $mode
329
+ * @return int
330
+ */
331
+ protected function validPermMode($mode)
332
+ {
333
+ $mode = intval($mode);
334
+ if ($mode < 73 || $mode > 511) {
335
+ return false;
336
+ }
337
+ return true;
338
+ }
339
+
340
+ /**
341
+ * Return correct global dir mode in octal representation
342
+ *
343
+ * @param Mage_Connect_Config $config
344
+ * @return int
345
+ */
346
+ protected function _getDirMode($config)
347
+ {
348
+ if ($this->validPermMode($config->global_dir_mode)) {
349
+ return $config->global_dir_mode;
350
+ } else {
351
+ return $config->getDefaultValue('global_dir_mode');
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Return global file mode in octal representation
357
+ *
358
+ * @param Mage_Connect_Config $config
359
+ * @return int
360
+ */
361
+ protected function _getFileMode($config)
362
+ {
363
+ if ($this->validPermMode($config->global_file_mode)) {
364
+ return $config->global_file_mode;
365
+ } else {
366
+ return $config->getDefaultValue('global_file_mode');
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Convert FTP path
372
+ *
373
+ * @param string $str
374
+ * @return string
375
+ */
376
+ protected function convertFtpPath($str)
377
+ {
378
+ return str_replace("\\", "/", $str);
379
+ }
380
+
381
+ /**
382
+ * Install package over FTP
383
+ *
384
+ * @param Mage_Connect_Package $package
385
+ * @param string $file
386
+ * @param Mage_Connect_Config $configObj
387
+ * @param Mage_Connect_Ftp $ftp
388
+ * @throws RuntimeException
389
+ */
390
+ public function processInstallPackageFtp($package, $file, $configObj, $ftp)
391
+ {
392
+ $ftpDir = $ftp->getcwd();
393
+ $contents = $package->getContents();
394
+ $arc = $this->getArchiver();
395
+ $target = dirname($file) . DS . $package->getReleaseFilename();
396
+ if (!@mkdir($target, 0777, true)) {
397
+ throw new RuntimeException("Can't create directory ". $target);
398
+ }
399
+ $tar = $arc->unpack($file, $target);
400
+ $modeFile = $this->_getFileMode($configObj);
401
+ $modeDir = $this->_getDirMode($configObj);
402
+ $failedFiles = array();
403
+ foreach ($contents as $file) {
404
+ $source = $tar . DS . $file;
405
+ if (file_exists($source) && is_file($source)) {
406
+ $args = array(ltrim($file,"/"), $source);
407
+ if($modeDir||$modeFile) {
408
+ $args[] = $modeDir;
409
+ $args[] = $modeFile;
410
+ }
411
+ if (call_user_func_array(array($ftp,'upload'), $args) === false) {
412
+ $failedFiles[] = $source;
413
+ }
414
+ }
415
+ }
416
+
417
+ if (!empty($failedFiles)) {
418
+ $msg = sprintf("Failed to upload files: %s \r\n Check permissions", implode("\r\n", $failedFiles));
419
+ throw new RuntimeException($msg);
420
+ }
421
+
422
+ $localXml = $tar . Mage_Connect_Package_Reader::DEFAULT_NAME_PACKAGE;
423
+ if (is_file($localXml)) {
424
+ $remoteXml = Mage_Connect_Package::PACKAGE_XML_DIR . DS . $package->getReleaseFilename() . '.xml';
425
+ $ftp->upload($remoteXml, $localXml, $modeDir, $modeFile);
426
+ }
427
+
428
+ $ftp->chdir($ftpDir);
429
+ Mage_System_Dirs::rm(array("-r",$target));
430
+ }
431
+
432
+ /**
433
+ * Package installation to FS
434
+ *
435
+ * @param Mage_Connect_Package $package
436
+ * @param string $file
437
+ * @param Mage_Connect_Config $configObj
438
+ * @return void
439
+ */
440
+ public function processInstallPackage($package, $file, $configObj)
441
+ {
442
+ $contents = $package->getContents();
443
+ $arc = $this->getArchiver();
444
+ $target = dirname($file) . DS . $package->getReleaseFilename();
445
+ @mkdir($target, 0777, true);
446
+ $tar = $arc->unpack($file, $target);
447
+ $modeFile = $this->_getFileMode($configObj);
448
+ $modeDir = $this->_getDirMode($configObj);
449
+ $targetPath = rtrim($configObj->magento_root, "\\/");
450
+ $packageXmlDir = $targetPath . DS . Mage_Connect_Package::PACKAGE_XML_DIR;
451
+ if (!$this->isDirWritable($packageXmlDir)) {
452
+ throw new RuntimeException('Directory ' . $packageXmlDir . ' is not writable. Check permission');
453
+ }
454
+ $this->_makeDirectories($contents, $targetPath, $modeDir);
455
+ foreach ($contents as $file) {
456
+ $fileName = basename($file);
457
+ $filePath = dirname($file);
458
+ $source = $tar . DS . $file;
459
+ $dest = $targetPath . DS . $filePath . DS . $fileName;
460
+ if (is_file($source)) {
461
+ @copy($source, $dest);
462
+ if($modeFile) {
463
+ @chmod($dest, $modeFile);
464
+ }
465
+ } else {
466
+ @mkdir($dest, $modeDir);
467
+ }
468
+ }
469
+
470
+ $packageXml = $tar . Mage_Connect_Package_Reader::DEFAULT_NAME_PACKAGE;
471
+ if (is_file($packageXml)) {
472
+ $destDir = $targetPath . DS . Mage_Connect_Package::PACKAGE_XML_DIR;
473
+ $destFile = $package->getReleaseFilename() . '.xml';
474
+ $dest = $destDir . DS . $destFile;
475
+
476
+ @copy($packageXml, $dest);
477
+ @chmod($dest, $modeFile);
478
+ }
479
+
480
+ Mage_System_Dirs::rm(array("-r",$target));
481
+ }
482
+
483
+ /**
484
+ * Make directories
485
+ *
486
+ * @param array $content
487
+ * @param string $targetPath
488
+ * @param int $modeDir
489
+ * @throws RuntimeException
490
+ */
491
+ protected function _makeDirectories($content, $targetPath, $modeDir)
492
+ {
493
+ $failedDirs = array();
494
+ $createdDirs = array();
495
+ foreach ($content as $file) {
496
+ $dirPath = dirname($file);
497
+ if (is_dir($dirPath) && $this->isDirWritable($dirPath)) {
498
+ continue;
499
+ }
500
+ if (!mkdir($targetPath . DS . $dirPath, $modeDir, true)) {
501
+ $failedDirs[] = $targetPath . DS . $dirPath;
502
+ } else {
503
+ $createdDirs[] = $targetPath . DS . $dirPath;
504
+ }
505
+ }
506
+ if (!empty($failedDirs)) {
507
+ foreach ($createdDirs as $createdDir) {
508
+ $this->removeEmptyDirectory($createdDir);
509
+ }
510
+ $msg = sprintf("Failed to create directory:\r\n%s\r\n Check permissions", implode("\r\n", $failedDirs));
511
+ throw new RuntimeException($msg);
512
+ }
513
+ }
514
+
515
+ /**
516
+ * Get local modified files
517
+ *
518
+ * @param string $chanName
519
+ * @param string $package
520
+ * @param Mage_Connect_Singleconfig $cacheObj
521
+ * @param Mage_Connect_Config $configObj
522
+ * @return array
523
+ */
524
+ public function getLocalModifiedFiles($chanName, $package, $cacheObj, $configObj)
525
+ {
526
+ $p = $cacheObj->getPackageObject($chanName, $package);
527
+ $hashContents = $p->getHashContents();
528
+ $listModified = array();
529
+ foreach ($hashContents as $file=>$hash) {
530
+ if (md5_file($configObj->magento_root . DS . $file)!==$hash) {
531
+ $listModified[] = $file;
532
+ }
533
+ }
534
+ return $listModified;
535
+ }
536
+
537
+ /**
538
+ * Get remote modified files
539
+ *
540
+ * @param string $chanName
541
+ * @param string $package
542
+ * @param Mage_Connect_Singleconfig $cacheObj
543
+ * @param Mage_Connect_Ftp $ftp
544
+ * @return array
545
+ */
546
+ public function getRemoteModifiedFiles($chanName, $package, $cacheObj, $ftp)
547
+ {
548
+ $p = $cacheObj->getPackageObject($chanName, $package);
549
+ $hashContents = $p->getHashContents();
550
+ $listModified = array();
551
+ foreach ($hashContents as $file=>$hash) {
552
+ $localFile = uniqid("temp_remote_");
553
+ if(!$ftp->fileExists($file)) {
554
+ continue;
555
+ }
556
+ $ftp->get($localFile, $file);
557
+ if (file_exists($localFile) && md5_file($localFile)!==$hash) {
558
+ $listModified[] = $file;
559
+ }
560
+ @unlink($localFile);
561
+ }
562
+ return $listModified;
563
+ }
564
+
565
+ /**
566
+ * Get upgrades list
567
+ *
568
+ * @param string|array $channels
569
+ * @param Mage_Connect_Singleconfig $cacheObject
570
+ * @param Mage_Connect_Config $configObj
571
+ * @param Mage_Connect_Rest $restObj optional
572
+ * @param bool $checkConflicts
573
+ * @return array
574
+ */
575
+ public function getUpgradesList($channels, $cacheObject, $configObj, $restObj = null, $checkConflicts = false)
576
+ {
577
+ if(is_scalar($channels)) {
578
+ $channels = array($channels);
579
+ }
580
+
581
+ if(!$restObj) {
582
+ $restObj = Mage_Connect_Rest_Builder::getAdapter($configObj->protocol);
583
+ }
584
+
585
+ $updates = array();
586
+ foreach ($channels as $chan) {
587
+
588
+ if(!$cacheObject->isChannel($chan)) {
589
+ continue;
590
+ }
591
+ $chanName = $cacheObject->chanName($chan);
592
+ $localPackages = $cacheObject->getInstalledPackages($chanName);
593
+ $localPackages = $localPackages[$chanName];
594
+
595
+ if(!count($localPackages)) {
596
+ continue;
597
+ }
598
+
599
+ $channel = $cacheObject->getChannel($chan);
600
+ $uri = $channel[Mage_Connect_Singleconfig::K_URI];
601
+ $restObj->setChannel($uri);
602
+ $remotePackages = $restObj->getPackagesHashed();
603
+
604
+ /**
605
+ * Iterate packages of channel $chan
606
+ */
607
+ $state = $configObj->preferred_state ? $configObj->preferred_state : "stable";
608
+
609
+ foreach ($localPackages as $localName=>$localData) {
610
+ if(!isset($remotePackages[$localName])) {
611
+ continue;
612
+ }
613
+ $package = $remotePackages[$localName];
614
+ $neededToUpgrade = false;
615
+ $remoteVersion = $localVersion = trim($localData[Mage_Connect_Singleconfig::K_VER]);
616
+ foreach ($package as $version => $s) {
617
+
618
+ if($cacheObject->compareStabilities($s, $state) < 0) {
619
+ continue;
620
+ }
621
+
622
+ if(version_compare($version, $localVersion, ">")) {
623
+ $neededToUpgrade = true;
624
+ $remoteVersion = $version;
625
+ }
626
+
627
+ if($checkConflicts) {
628
+ $conflicts = $cacheObject->hasConflicts($chanName, $localName, $remoteVersion);
629
+ if(false !== $conflicts) {
630
+ $neededToUpgrade = false;
631
+ }
632
+ }
633
+ }
634
+ if(!$neededToUpgrade) {
635
+ continue;
636
+ }
637
+ if(!isset($updates[$chanName])) {
638
+ $updates[$chanName] = array();
639
+ }
640
+ $updates[$chanName][$localName] = array("from"=>$localVersion, "to"=>$remoteVersion);
641
+ }
642
+ }
643
+ return $updates;
644
+ }
645
+
646
+ /**
647
+ * Get uninstall list
648
+ *
649
+ * @param string $chanName
650
+ * @param string $package
651
+ * @param Mage_Connect_Singleconfig $cache
652
+ * @param Mage_Connect_Config $config
653
+ * @param bool $withDepsRecursive
654
+ * @return array|null
655
+ */
656
+ public function getUninstallList($chanName, $package, $cache, $config, $withDepsRecursive = true)
657
+ {
658
+ static $level = 0;
659
+ static $hash = array();
660
+
661
+ $chanName = $cache->chanName($chanName);
662
+ $level++;
663
+
664
+ try {
665
+ $chanName = $cache->chanName($chanName);
666
+ if(!$cache->hasPackage($chanName, $package)) {
667
+ $level--;
668
+ if($level == 0) {
669
+ $hash = array();
670
+ return array('list'=>array());
671
+ }
672
+ return null;
673
+ }
674
+ $dependencies = $cache->getPackageDependencies($chanName, $package);
675
+ $data = $cache->getPackage($chanName, $package);
676
+ $version = $data['version'];
677
+
678
+ $hash[$chanName . "/" . $package] = array (
679
+ 'name' => $package,
680
+ 'channel' => $chanName,
681
+ 'version' => $version,
682
+ 'packages' => $dependencies,
683
+ );
684
+
685
+ if($withDepsRecursive) {
686
+ $fields = array('name','channel','min','max');
687
+ foreach ($dependencies as $row) {
688
+ /**
689
+ * Converts an array to variables
690
+ * @var $pChannel string Channel Name
691
+ * @var $pName string Package Name
692
+ */
693
+ foreach ($fields as $key) {
694
+ $varName = "p" . ucfirst($key);
695
+ $$varName = $row[$key];
696
+ }
697
+ $method = __FUNCTION__;
698
+ $keyInner = $pChannel . "/" . $pName;
699
+ if(!isset($hash[$keyInner])) {
700
+ $this->$method($pChannel, $pName, $cache, $config,
701
+ $withDepsRecursive, false);
702
+ }
703
+ }
704
+ }
705
+
706
+ } catch (Exception $e) {
707
+ }
708
+
709
+ $level--;
710
+ if(0 === $level) {
711
+ $out = $this->processDepsHash($hash);
712
+ $hash = array();
713
+ return array('list'=>$out);
714
+ }
715
+
716
+ return null;
717
+ }
718
+
719
+ /**
720
+ * Add data to package dependencies hash array
721
+ *
722
+ * @param array $hash Package dependencies hash array
723
+ * @param string $name Package name
724
+ * @param string $channel Package chaannel
725
+ * @param string $downloaded_version Package downloaded version
726
+ * @param string $stability Package stability
727
+ * @param string $versionMin Required package minimum version
728
+ * @param string $versionMax Required package maximum version
729
+ * @param string $installState Package install state
730
+ * @param string $message Package install message
731
+ * @param array|string $dependencies Package dependencies
732
+ * @return bool
733
+ */
734
+ private function addHashData(&$hash, $name, $channel, $downloaded_version = '', $stability = '', $versionMin = '',
735
+ $versionMax = '', $installState = '', $message = '', $dependencies = '')
736
+ {
737
+ /**
738
+ * When we are building dependencies tree we should base this calculations not on full key as on a
739
+ * unique value but check it by parts. First part which should be checked is EXTENSION_NAME also this
740
+ * part should be unique globally not per channel.
741
+ */
742
+ $key = $name;
743
+ $hash[$key] = array (
744
+ 'name' => $name,
745
+ 'channel' => $channel,
746
+ 'downloaded_version' => $downloaded_version,
747
+ 'stability' => $stability,
748
+ 'min' => $versionMin,
749
+ 'max' => $versionMax,
750
+ 'install_state' => $installState,
751
+ 'message' => (isset($this->installStates[$installState]) ?
752
+ $this->installStates[$installState] : '') . $message,
753
+ 'packages' => $dependencies,
754
+ );
755
+ return true;
756
+ }
757
+
758
+ /**
759
+ * Get dependencies list/install order info
760
+ *
761
+ * @param string $chanName
762
+ * @param string $package
763
+ * @param Mage_Connect_Singleconfig $cache
764
+ * @param Mage_Connect_Config $config
765
+ * @param mixed $versionMax
766
+ * @param mixed $versionMin
767
+ * @param boolean $withDepsRecursive
768
+ * @param boolean $forceRemote
769
+ * @param Mage_Connect_Rest $rest
770
+ * @return mixed
771
+ */
772
+ public function getDependenciesList( $chanName, $package, $cache, $config, $versionMax = false, $versionMin = false,
773
+ $withDepsRecursive = true, $forceRemote = false, $rest = null)
774
+ {
775
+ static $level = 0;
776
+ static $_depsHash = array();
777
+ static $_deps = array();
778
+ static $_failed = array();
779
+ $install_state = self::INSTALL_STATE_INSTALL;
780
+ $version = '';
781
+ $message = '';
782
+
783
+ $level++;
784
+
785
+ try {
786
+ $chanName = $cache->chanName($chanName);
787
+
788
+ if (!$rest) {
789
+ $rest = Mage_Connect_Rest_Builder::getAdapter($config->protocol);
790
+ }
791
+ $rest->setChannel($cache->chanUrl($chanName));
792
+ $releases = $rest->getReleases($package);
793
+ if (!$releases || !count($releases)) {
794
+ throw new Exception("No releases for '{$package}', skipping");
795
+ }
796
+ $state = $config->preferred_state ? $config->preferred_state : 'stable';
797
+ /**
798
+ * Check current package version first
799
+ */
800
+ $installedPackage = $cache->getPackage($chanName, $package);
801
+ if ($installedPackage && is_array($installedPackage)) {
802
+ $installedRelease = array(array(
803
+ 'v' => $installedPackage['version'],
804
+ 's' => $installedPackage['stability'],
805
+ ));
806
+ $version = $cache->detectVersionFromRestArray($installedRelease, $versionMin, $versionMax, $state);
807
+ }
808
+ if (!$version) {
809
+ $version = $cache->detectVersionFromRestArray($releases, $versionMin, $versionMax, $state);
810
+ }
811
+ if (!$version) {
812
+ $versionState = $cache->detectVersionFromRestArray($releases, $versionMin, $versionMax);
813
+ if ($versionState) {
814
+ /** @var $packageInfo Mage_Connect_Package */
815
+ $packageInfo = $rest->getPackageReleaseInfo($package, $versionState);
816
+ if (false !== $packageInfo) {
817
+ $stability = $packageInfo->getStability();
818
+ throw new Exception("Extension is '{$stability}' please check(or change) stability settings".
819
+ " on Magento Connect Manager");
820
+ }
821
+ }
822
+ throw new Exception("Version for '{$package}' was not detected");
823
+ }
824
+ $packageInfo = $rest->getPackageReleaseInfo($package, $version);
825
+ if (false === $packageInfo) {
826
+ throw new Exception("Package release '{$package}' not found on server");
827
+ }
828
+ $stability = $packageInfo->getStability();
829
+
830
+ /**
831
+ * check is package already installed
832
+ */
833
+ if ($installedPackage = $cache->isPackageInstalled($package)) {
834
+ if ($chanName == $installedPackage['channel']) {
835
+ /**
836
+ * check versions
837
+ */
838
+ if (version_compare($version, $installedPackage['version'], '>')) {
839
+ $install_state = self::INSTALL_STATE_UPGRADE;
840
+ } elseif (version_compare($version, $installedPackage['version'], '<')) {
841
+ $version = $installedPackage['version'];
842
+ $stability = $installedPackage['stability'];
843
+ $install_state = self::INSTALL_STATE_WRONG_VERSION;
844
+ } else {
845
+ $install_state = self::INSTALL_STATE_ALREADY_INSTALLED;
846
+ }
847
+ } else {
848
+ $install_state = self::INSTALL_STATE_INCOMPATIBLE;
849
+ }
850
+ }
851
+
852
+ $deps_tmp = $packageInfo->getDependencyPackages();
853
+
854
+ /**
855
+ * Select distinct packages grouped by name
856
+ */
857
+ $dependencies = array();
858
+ foreach ($deps_tmp as $row) {
859
+ if (isset($dependencies[$row['name']])) {
860
+ if ($installedPackageDep = $cache->isPackageInstalled($row['name'])) {
861
+ if ($installedPackageDep['channel'] == $row['channel']) {
862
+ $dependencies[$row['name']]=$row;
863
+ }
864
+ } elseif ($config->root_channel == $row['channel']) {
865
+ $dependencies[$row['name']] = $row;
866
+ }
867
+ } else {
868
+ $dependencies[$row['name']] = $row;
869
+ }
870
+ }
871
+
872
+ /**
873
+ * When we are building dependencies tree we should base this calculations not on full key as on a
874
+ * unique value but check it by parts. First part which should be checked is EXTENSION_NAME also this part
875
+ * should be unique globally not per channel.
876
+ */
877
+ if (self::INSTALL_STATE_INCOMPATIBLE != $install_state) {
878
+ $this->addHashData($_depsHash, $package, $chanName, $version, $stability, $versionMin,
879
+ $versionMax, $install_state, $message, $dependencies);
880
+ }
881
+
882
+ if ($withDepsRecursive && self::INSTALL_STATE_INCOMPATIBLE != $install_state) {
883
+ $flds = array('name','channel','min','max');
884
+ foreach ($dependencies as $row) {
885
+ /**
886
+ * Converts an array to variables
887
+ * @var $pChannel string Channel Name
888
+ * @var $pName string Package Name
889
+ * @var $pMax string Maximum version number
890
+ * @var $pMin string Minimum version number
891
+ */
892
+ foreach ($flds as $key) {
893
+ $varName = "p" . ucfirst($key);
894
+ $$varName = $row[$key];
895
+ }
896
+ $method = __FUNCTION__;
897
+ /**
898
+ * When we are building dependencies tree we should base this calculations not on full key as
899
+ * on a unique value but check it by parts. First part which should be checked is EXTENSION_NAME
900
+ * also this part should be unique globally not per channel.
901
+ */
902
+ $keyInner = $pName;
903
+ if(!isset($_depsHash[$keyInner])) {
904
+ $_deps[] = $row;
905
+ $this->$method($pChannel, $pName, $cache, $config,
906
+ $pMax, $pMin, $withDepsRecursive, $forceRemote, $rest);
907
+ } else {
908
+ $downloaded = $_depsHash[$keyInner]['downloaded_version'];
909
+ $hasMin = $_depsHash[$keyInner]['min'];
910
+ $hasMax = $_depsHash[$keyInner]['max'];
911
+ if($pMin === $hasMin && $pMax === $hasMax) {
912
+ continue;
913
+ }
914
+
915
+ if($cache->versionInRange($downloaded, $pMin, $pMax)) {
916
+ continue;
917
+ }
918
+
919
+ $names = array("pMin","pMax","hasMin","hasMax");
920
+ for ($i=0, $c=count($names); $i<$c; $i++) {
921
+ if(!isset($$names[$i])) {
922
+ continue;
923
+ }
924
+ if(false !== $$names[$i]) {
925
+ continue;
926
+ }
927
+ $$names[$i] = $i % 2 == 0 ? "0" : "999999999";
928
+ }
929
+
930
+ if(!$cache->hasVersionRangeIntersect($pMin,$pMax, $hasMin, $hasMax)) {
931
+ $reason = "Detected {$pName} conflict of versions: {$hasMin}-{$hasMax} and {$pMin}-{$pMax}";
932
+ unset($_depsHash[$keyInner]);
933
+ $_failed[] = array(
934
+ 'name'=>$pName,
935
+ 'channel'=>$pChannel,
936
+ 'max'=>$pMax,
937
+ 'min'=>$pMin,
938
+ 'reason'=>$reason
939
+ );
940
+ continue;
941
+ }
942
+ $newMaxIsLess = version_compare($pMax, $hasMax, "<");
943
+ $newMinIsGreater = version_compare($pMin, $hasMin, ">");
944
+ $forceMax = $newMaxIsLess ? $pMax : $hasMax;
945
+ $forceMin = $newMinIsGreater ? $pMin : $hasMin;
946
+ $this->$method($pChannel, $pName, $cache, $config,
947
+ $forceMax, $forceMin, $withDepsRecursive, $forceRemote, $rest);
948
+ }
949
+ }
950
+ }
951
+ unset($rest);
952
+ } catch (Exception $e) {
953
+ $_failed[] = array(
954
+ 'name'=>$package,
955
+ 'channel'=>$chanName,
956
+ 'max'=>$versionMax,
957
+ 'min'=>$versionMin,
958
+ 'reason'=>$e->getMessage()
959
+ );
960
+ }
961
+
962
+ $level--;
963
+ if($level == 0) {
964
+ $out = $this->processDepsHash($_depsHash, false);
965
+ $deps = $_deps;
966
+ $failed = $_failed;
967
+ $_depsHash = array();
968
+ $_deps = array();
969
+ $_failed = array();
970
+ return array('deps' => $deps, 'result' => $out, 'failed'=> $failed);
971
+ }
972
+
973
+ return null;
974
+ }
975
+
976
+ /**
977
+ * Process dependencies hash. Makes topological sorting and gives operation order list
978
+ *
979
+ * @param array $depsHash
980
+ * @param bool $sortReverse
981
+ * @return array
982
+ */
983
+ protected function processDepsHash(&$depsHash, $sortReverse = true)
984
+ {
985
+ $nodes = array();
986
+ $graph = new Mage_Connect_Structures_Graph();
987
+
988
+ foreach ($depsHash as $key=>$data) {
989
+ $node = new Mage_Connect_Structures_Node();
990
+ $nodes[$key] =& $node;
991
+ unset($data['packages']);
992
+ $node->setData($data);
993
+ $graph->addNode($node);
994
+ unset($node);
995
+ }
996
+
997
+ if (count($nodes) > 1) {
998
+ foreach ($depsHash as $key=>$data) {
999
+ $packages = $data['packages'];
1000
+ foreach ($packages as $pdata) {
1001
+ $pName = $pdata['name'];
1002
+ if (isset($nodes[$key], $nodes[$pName])) {
1003
+ $nodes[$key]->connectTo($nodes[$pName]);
1004
+ }
1005
+ }
1006
+ }
1007
+ }
1008
+
1009
+ if (!$graph->isAcyclic()) {
1010
+ throw new Exception("Dependency references are cyclic");
1011
+ }
1012
+
1013
+ $result = $graph->topologicalSort();
1014
+ $sortReverse ? krsort($result) : ksort($result);
1015
+ $out = array();
1016
+ foreach ($result as $nodes) {
1017
+ foreach ($nodes as $n) {
1018
+ /** @var $n Mage_Connect_Structures_Node */
1019
+ $out[] = $n->getData();
1020
+ }
1021
+ }
1022
+ unset($graph, $nodes);
1023
+ return $out;
1024
+ }
1025
+
1026
+ /**
1027
+ * Check if directory writable
1028
+ *
1029
+ * @param string $dir
1030
+ * @return boolean
1031
+ */
1032
+ protected function isDirWritable($dir)
1033
+ {
1034
+ if (is_dir($dir) && is_writable($dir)) {
1035
+ if (stripos(PHP_OS, 'win') === 0) {
1036
+ $dir = ltrim($dir, DIRECTORY_SEPARATOR);
1037
+ $file = $dir . DIRECTORY_SEPARATOR . uniqid(mt_rand()).'.tmp';
1038
+ $exist = file_exists($file);
1039
+ $fp = @fopen($file, 'a');
1040
+ if ($fp === false) {
1041
+ return false;
1042
+ }
1043
+ fclose($fp);
1044
+ if (!$exist) {
1045
+ unlink($file);
1046
+ }
1047
+ }
1048
+ return true;
1049
+ }
1050
+ return false;
1051
+ }
1052
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Repository.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Abstract.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel/Abstract.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel/Commercial.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel/Community.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Channel/Core.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Repository/Local.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
app/code/local/Mss/downloader/lib/Mage/Connect/Rest.php ADDED
@@ -0,0 +1,387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with remote REST interface
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Rest
35
+ {
36
+ /**
37
+ * Paths for xml config files
38
+ */
39
+ const CHANNELS_XML = "channels.xml";
40
+ const CHANNEL_XML = "channel.xml";
41
+ const PACKAGES_XML = "packages.xml";
42
+ const RELEASES_XML = "releases.xml";
43
+ const PACKAGE_XML = "package.xml";
44
+ const EXT = "tgz";
45
+
46
+ /**
47
+ * HTTP Loader
48
+ * @var Mage_HTTP_IClient
49
+ */
50
+ protected $_loader = null;
51
+
52
+ /**
53
+ * XML parser
54
+ *
55
+ * @var Mage_Xml_Parser
56
+ */
57
+ protected $_parser = null;
58
+
59
+ /**
60
+ * Channel URI
61
+ *
62
+ * @var string
63
+ */
64
+ protected $_chanUri = '';
65
+
66
+ /**
67
+ * Protocol HTTP or FTP
68
+ *
69
+ * @var string http or ftp
70
+ */
71
+ protected $_protocol = '';
72
+
73
+ /**
74
+ * States interpretation
75
+ *
76
+ * @var array
77
+ */
78
+ protected $states = array('b'=>'beta', 'd'=>'dev', 's'=>'stable', 'a'=>'alpha');
79
+
80
+ /**
81
+ * Constructor sets default protocol
82
+ *
83
+ * @param string $protocol
84
+ */
85
+ public function __construct($protocol="https")
86
+ {
87
+ switch ($protocol) {
88
+ case 'http':
89
+ $this->_protocol = 'http';
90
+ break;
91
+ default:
92
+ $this->_protocol = 'https';
93
+ break;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Set channel URI
99
+ *
100
+ * @param string $uri
101
+ * @return void
102
+ */
103
+ public function setChannel($uri)
104
+ {
105
+ $this->_chanUri = $uri;
106
+ }
107
+
108
+ /**
109
+ * Get HTTP loader
110
+ *
111
+ * @return Mage_HTTP_IClient|Mage_Connect_Loader_Ftp
112
+ */
113
+ public function getLoader()
114
+ {
115
+ if (is_null($this->_loader)) {
116
+ $this->_loader = Mage_Connect_Loader::getInstance($this->_protocol);
117
+ }
118
+ return $this->_loader;
119
+ }
120
+
121
+ /**
122
+ * Get parser
123
+ *
124
+ * @return Mage_Xml_Parser
125
+ */
126
+ protected function getParser()
127
+ {
128
+ if (is_null($this->_parser)) {
129
+ $this->_parser = new Mage_Xml_Parser();
130
+ }
131
+ return $this->_parser;
132
+ }
133
+
134
+ /**
135
+ * Load URI response
136
+ *
137
+ * @param string $uriSuffix
138
+ * @return bool|string
139
+ */
140
+ protected function loadChannelUri($uriSuffix)
141
+ {
142
+ $url = $this->_chanUri . "/" . $uriSuffix;
143
+ $this->getLoader()->get($url);
144
+ $statusCode = $this->getLoader()->getStatus();
145
+ if ($statusCode != 200) {
146
+ return false;
147
+ }
148
+ return $this->getLoader()->getBody();
149
+ }
150
+
151
+ /**
152
+ * Get channels list of URI
153
+ *
154
+ * @return array
155
+ */
156
+ public function getChannelInfo()
157
+ {
158
+ $out = $this->loadChannelUri(self::CHANNEL_XML);
159
+ $statusCode = $this->getLoader()->getStatus();
160
+ if ($statusCode != 200) {
161
+ throw new Exception("Invalid server response for {$this->_chanUri}");
162
+ }
163
+ $parser = $this->getParser();
164
+ $out = $parser->loadXML($out)->xmlToArray();
165
+
166
+ $vo = new Mage_Connect_Channel_VO();
167
+ $vo->fromArray($out['channel']);
168
+ if (!$vo->validate()) {
169
+ throw new Exception("Invalid channel.xml file");
170
+ }
171
+ return $vo;
172
+ }
173
+
174
+ /**
175
+ * Get packages list of channel
176
+ *
177
+ * @return array
178
+ */
179
+ public function getPackages()
180
+ {
181
+ $out = $this->loadChannelUri(self::PACKAGES_XML);
182
+ $statusCode = $this->getLoader()->getStatus();
183
+ if ($statusCode != 200) {
184
+ return false;
185
+ }
186
+ $parser = $this->getParser();
187
+ $out = $parser->loadXML($out)->xmlToArray();
188
+
189
+ if (!isset($out['data']['p'])) {
190
+ return array();
191
+ }
192
+ if (isset($out['data']['p'][0])) {
193
+ return $out['data']['p'];
194
+ }
195
+ if (is_array($out['data']['p'])) {
196
+ return array($out['data']['p']);
197
+ }
198
+ return array();
199
+ }
200
+
201
+ /**
202
+ * Return Channel Packages loaded from Channel Server
203
+ *
204
+ * @return array|bool|string
205
+ */
206
+ public function getPackagesHashed()
207
+ {
208
+ $out = $this->loadChannelUri(self::PACKAGES_XML);
209
+ $statusCode = $this->getLoader()->getStatus();
210
+ if ($statusCode != 200) {
211
+ return false;
212
+ }
213
+ $parser = $this->getParser();
214
+ $out = $parser->loadXML($out)->xmlToArray();
215
+
216
+ $return = array();
217
+ if (!isset($out['data']['p'])) {
218
+ return $return;
219
+ }
220
+ if (isset($out['data']['p'][0])) {
221
+ $return = $out['data']['p'];
222
+ } elseif (is_array($out['data']['p'])) {
223
+ $return = array($out['data']['p']);
224
+ }
225
+ $c = count($return);
226
+ if ($c) {
227
+ $output = array();
228
+ for ($i=0; $i<$c; $i++) {
229
+ $element = $return[$i];
230
+ $output[$element['n']] = $element['r'];
231
+ }
232
+ $return = $output;
233
+ }
234
+
235
+ $out = array();
236
+ foreach ($return as $name=>$package) {
237
+ $stabilities = array_map(array($this, 'shortStateToLong'), array_keys($package));
238
+ $versions = array_map('trim', array_values($package));
239
+ $package = array_combine($versions, $stabilities);
240
+ ksort($package);
241
+ $out[$name] = $package;
242
+ }
243
+ return $out;
244
+ }
245
+
246
+ /**
247
+ * Stub
248
+ *
249
+ * @param $n
250
+ * @return unknown_type
251
+ */
252
+ public function escapePackageName($n)
253
+ {
254
+ return $n;
255
+ }
256
+
257
+ /**
258
+ * Get releases list of package on current channel
259
+ *
260
+ * @param string $package package name
261
+ * @return array|bool
262
+ */
263
+ public function getReleases($package)
264
+ {
265
+ $out = $this->loadChannelUri($this->escapePackageName($package) . "/" . self::RELEASES_XML);
266
+ $statusCode = $this->getLoader()->getStatus();
267
+ if ($statusCode != 200) {
268
+ return false;
269
+ }
270
+ $parser = $this->getParser();
271
+ $out = $parser->loadXML($out)->xmlToArray();
272
+ if (!isset($out['releases']['r'])) {
273
+ return array();
274
+ }
275
+ $src = $out['releases']['r'];
276
+ if (!array_key_exists(0, $src)) {
277
+ return array($src);
278
+ }
279
+ $this->sortReleases($src);
280
+ return $src;
281
+ }
282
+
283
+ /**
284
+ * Sort releases
285
+ *
286
+ * @param array $releases
287
+ * @return void
288
+ */
289
+ public function sortReleases(array &$releases)
290
+ {
291
+ usort($releases, array($this, 'sortReleasesCallback'));
292
+ $releases = array_reverse($releases);
293
+ }
294
+
295
+ /**
296
+ * Sort releases callback
297
+ *
298
+ * @param string $a
299
+ * @param srting $b
300
+ * @return int
301
+ */
302
+ protected function sortReleasesCallback($a, $b)
303
+ {
304
+ return version_compare($a['v'],$b['v']);
305
+ }
306
+
307
+ /**
308
+ * Get package info (package.xml)
309
+ *
310
+ * @param $package
311
+ * @return unknown_type
312
+ */
313
+ public function getPackageInfo($package)
314
+ {
315
+ $out = $this->loadChannelUri($this->escapePackageName($package) . "/" . self::PACKAGE_XML);
316
+ if (false === $out) {
317
+ return false;
318
+ }
319
+ return new Mage_Connect_Package($out);
320
+ }
321
+
322
+ /**
323
+ * Retrieve information on Package Release from the Channel Server
324
+ *
325
+ * @param $package
326
+ * @param $version
327
+ * @return Mage_Connect_Package|bool
328
+ */
329
+ public function getPackageReleaseInfo($package, $version)
330
+ {
331
+ $out = $this->loadChannelUri($this->escapePackageName($package) . "/" . $version . "/" . self::PACKAGE_XML);
332
+ if (false === $out) {
333
+ return false;
334
+ }
335
+ return new Mage_Connect_Package($out);
336
+ }
337
+
338
+ /**
339
+ * Get package archive file of release
340
+ *
341
+ * @throws Exception
342
+ * @param string $package package name
343
+ * @param string $version package version
344
+ * @param string $targetFile
345
+ * @return bool
346
+ */
347
+ public function downloadPackageFileOfRelease($package, $version, $targetFile)
348
+ {
349
+ $package = $this->escapePackageName($package);
350
+ $version = $this->escapePackageName($version);
351
+
352
+ if (file_exists($targetFile)) {
353
+ $chksum = $this->loadChannelUri($package . "/" . $version . "/checksum");
354
+ $statusCode = $this->getLoader()->getStatus();
355
+ if ($statusCode == 200) {
356
+ if (md5_file($targetFile) == $chksum) {
357
+ return true;
358
+ }
359
+ }
360
+ }
361
+
362
+ $out = $this->loadChannelUri($package . "/" . $version . "/" . $package . "-" . $version . "." . self::EXT);
363
+
364
+ $statusCode = $this->getLoader()->getStatus();
365
+ if ($statusCode != 200) {
366
+ throw new Exception("Package not found: {$package} {$version}");
367
+ }
368
+ $dir = dirname($targetFile);
369
+ @mkdir($dir, 0777, true);
370
+ $result = @file_put_contents($targetFile, $out);
371
+ if (false === $result) {
372
+ throw new Exception("Cannot write to file {$targetFile}");
373
+ }
374
+ return true;
375
+ }
376
+
377
+ /**
378
+ * Decode state
379
+ *
380
+ * @param string $s
381
+ * @return string
382
+ */
383
+ public function shortStateToLong($s)
384
+ {
385
+ return isset($this->states[$s]) ? $this->states[$s] : 'dev';
386
+ }
387
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Rest/Builder.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class for retrieve adapter to work with remote REST interface
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Rest_Builder
35
+ {
36
+ /**
37
+ * Rest adapter factory
38
+ *
39
+ * @var Mage_Connect_Rest_Factory
40
+ */
41
+ protected static $_adapterFactory;
42
+
43
+ /**
44
+ * Retrieve adapter factory
45
+ *
46
+ * @return Mage_Connect_Rest_Factory
47
+ */
48
+ protected static function _getAdapterFactory()
49
+ {
50
+ if (self::$_adapterFactory === null) {
51
+ self::$_adapterFactory = new Mage_Connect_Rest_Factory();
52
+ }
53
+ return self::$_adapterFactory;
54
+ }
55
+
56
+ /**
57
+ * Define rest adapter factory
58
+ *
59
+ * @param Mage_Connect_Rest_Factory $adapterFactory
60
+ */
61
+ public static function setAdapterFactory(Mage_Connect_Rest_Factory $adapterFactory)
62
+ {
63
+ self::$_adapterFactory = $adapterFactory;
64
+ }
65
+
66
+ /**
67
+ * Retrieve rest adapter
68
+ *
69
+ * @param string $protocol
70
+ * @return Mage_Connect_Rest
71
+ */
72
+ public static function getAdapter($protocol = "https")
73
+ {
74
+ return self::_getAdapterFactory()->getAdapter($protocol);
75
+ }
76
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Rest/Factory.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+ /**
27
+ * Factory for rest adapter
28
+ */
29
+ class Mage_Connect_Rest_Factory
30
+ {
31
+ /**
32
+ * Create new adapter instance
33
+ *
34
+ * @param string $protocol
35
+ * @return Mage_Connect_Rest
36
+ */
37
+ public function getAdapter($protocol = "https")
38
+ {
39
+ return new Mage_Connect_Rest($protocol);
40
+ }
41
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Singleconfig.php ADDED
@@ -0,0 +1,1060 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to manipulate with channel/package cache file
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Singleconfig
35
+ {
36
+ /**
37
+ * Default single config filename
38
+ *
39
+ * 'cache.cfg'
40
+ */
41
+ const DEFAULT_SCONFIG_FILENAME = 'cache.cfg';
42
+
43
+ /**
44
+ * Cache data
45
+ *
46
+ * @var array
47
+ */
48
+ protected $_data = array();
49
+
50
+ /**
51
+ * Filename
52
+ *
53
+ * @var string
54
+ */
55
+ protected $_readFilename = false;
56
+
57
+ /**
58
+ * Debug flag
59
+ *
60
+ * @var boolean
61
+ */
62
+ protected $_debug = false;
63
+
64
+ /**
65
+ * Validator instance
66
+ *
67
+ * @var Mage_Connect_Validator
68
+ */
69
+ protected $_validator;
70
+
71
+ /**
72
+ * Internal keys constants
73
+ */
74
+ const K_CHAN = 'channels_by_name';
75
+ const K_CHAN_URI = 'channels_by_uri';
76
+ const K_CHAN_ALIAS = 'channel_aliases';
77
+ const K_PACK = 'packages';
78
+ const K_URI = 'uri';
79
+ const K_CHAN_DATA = 'channel_data';
80
+ const K_NAME = 'name';
81
+ const K_VER = 'version';
82
+ const K_STATE = 'stability';
83
+ const K_XML = 'xml';
84
+ const K_DEPS = 'deps';
85
+ const K_PACK_DEPS = 'pack_deps';
86
+ const K_CONFIG = 'config';
87
+
88
+ /**
89
+ * Constructor
90
+ *
91
+ * @param string $file
92
+ * @return null
93
+ */
94
+ public function __construct($file = self::DEFAULT_SCONFIG_FILENAME)
95
+ {
96
+ $this->setEmptyConfig();
97
+ if($file) {
98
+ $this->_readFilename = $file;
99
+ $this->load();
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Parse and return valid URL
105
+ *
106
+ * @param string $str
107
+ * @return string|boolean
108
+ */
109
+ public function getValidUri($str)
110
+ {
111
+ $data = @parse_url($str);
112
+ if(isset($data['path'])) {
113
+ return $data['path'];
114
+ }
115
+ return false;
116
+ }
117
+
118
+ /**
119
+ * Return config file name
120
+ *
121
+ * @return string
122
+ */
123
+ public function getFilename()
124
+ {
125
+ return $this->_readFilename;
126
+ }
127
+
128
+ /**
129
+ * Return formatted part of URI
130
+ *
131
+ * @param $uri
132
+ * @return string
133
+ */
134
+ public function formatUri($uri)
135
+ {
136
+ $uri = rtrim($uri, "/");
137
+ $uri = str_replace("http://", '', $uri);
138
+ $uri = str_replace("https://", '', $uri);
139
+ return $uri;
140
+ }
141
+
142
+ /**
143
+ * Get data
144
+ *
145
+ * @return array
146
+ */
147
+ public function getData()
148
+ {
149
+ return $this->_data;
150
+ }
151
+
152
+ /**
153
+ * Load cache from file
154
+ *
155
+ * @param string $file
156
+ * @return null
157
+ */
158
+ public function load($file = false)
159
+ {
160
+ if(false === $file) {
161
+ $file = $this->_readFilename;
162
+ }
163
+ if(false === $file) {
164
+ return;
165
+ }
166
+
167
+ if(!file_exists($file)||filesize($file)==0) {
168
+ $this->save($file);
169
+ return;
170
+ }
171
+
172
+ if(!is_readable($file)) {
173
+ return $this->doError("File is not readable: '{$file}'");
174
+ }
175
+
176
+ $this->_readFilename = $file;
177
+
178
+ $data = @file_get_contents($file);
179
+ if(false === $data) {
180
+ return $this->doError("Cannot get file contents: '{$file}'");
181
+ }
182
+
183
+ if(!$this->_debug) {
184
+ $data = @gzuncompress($data);
185
+ if(false === $data) {
186
+ return $this->doError("Cannot unpack gzipped data in file contents: '{$file}'");
187
+ }
188
+ }
189
+ $data = @unserialize($data);
190
+ if(unserialize(false) === $data) {
191
+ return $this->doError("Cannot unserialize data in file contents: '{$file}'");
192
+ }
193
+
194
+ $validData = true;
195
+ foreach(array_keys($this->_data) as $k) {
196
+ if(!isset($data[$k])) {
197
+ $validData = false;
198
+ } else {
199
+ $this->_data[$k] = $data[$k];
200
+ }
201
+ }
202
+ if($validData) {
203
+ $this->_data = $data;
204
+ } else {
205
+ $this->save();
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Save contents
211
+ *
212
+ * @param string $file
213
+ * @return null
214
+ */
215
+ public function save($file = false)
216
+ {
217
+ if(false === $file) {
218
+ $file = $this->_readFilename;
219
+ }
220
+ if(false === $file) {
221
+ return;
222
+ }
223
+ $data = @serialize($this->_data);
224
+ if(!$this->_debug) {
225
+ $data = @gzcompress($data);
226
+ }
227
+ $res=true;
228
+ if((!file_exists($file)&&is_writable(dirname($file)))||(file_exists($file)&&is_writable($file))){
229
+ $res = @file_put_contents($file, $data);
230
+ }
231
+ if(!$res) {
232
+ $this->doError("Cannot save: '{$file}'");
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Set empty config skeleton
238
+ *
239
+ * @return null
240
+ */
241
+ public function setEmptyConfig()
242
+ {
243
+ $this->_data = array(
244
+ self::K_CHAN => array (),
245
+ self::K_CHAN_URI => array (),
246
+ self::K_CHAN_ALIAS => array (),
247
+ );
248
+ }
249
+
250
+ /**
251
+ * Check channel, add if valid name and not exist
252
+ *
253
+ * @param string $chanName
254
+ * @param Mage_Connect_Config $config
255
+ * @param Mage_Connect_Rest $rest
256
+ * @return boolean
257
+ */
258
+ public function checkChannel($chanName, $config, $rest = null)
259
+ {
260
+ if ($this->isChannel($chanName)) {
261
+ return true;
262
+ }
263
+
264
+ $_validator = new Mage_Connect_Validator();
265
+ if ($this->isChannelName($chanName)) {
266
+ $uri = $this->chanUrl($chanName);
267
+ } elseif ($_validator->validateUrl($chanName)) {
268
+ $uri = $chanName;
269
+ } elseif($chanName) {
270
+ $uri = $config->protocol.'://'.$chanName;
271
+ } else {
272
+ throw new Exception("'{$chanName}' is not existant channel name / valid uri");
273
+ }
274
+
275
+ if ($uri && !$this->isChannel($uri)) {
276
+ if (!isset($rest)) {
277
+ $rest = Mage_Connect_Rest_Builder::getAdapter($config->protocol);
278
+ }
279
+ $rest->setChannel($uri);
280
+ $data = $rest->getChannelInfo();
281
+ $data->uri = $uri;
282
+ $this->addChannel($data->name, $uri);
283
+ }
284
+
285
+ return $this->isChannel($uri);
286
+ }
287
+
288
+ /**
289
+ * Check Channel name
290
+ *
291
+ * @param $chanName
292
+ * @return boolean
293
+ */
294
+ public function isChannel($chanName)
295
+ {
296
+ if($this->isChannelName($chanName)) {
297
+ return true;
298
+ }
299
+ if($this->isChannelUri($chanName)) {
300
+ return true;
301
+ }
302
+ if($this->isChannelAlias($chanName)) {
303
+ return true;
304
+ }
305
+ return false;
306
+ }
307
+
308
+ /**
309
+ * Get channel
310
+ *
311
+ * @param string $chanName
312
+ * @return array
313
+ */
314
+ public function getChannel($chanName)
315
+ {
316
+ if($this->isChannelAlias($chanName)) {
317
+ $chanName = $this->getChannelNameByAlias($chanName);
318
+ } elseif($this->isChannelUri($chanName)) {
319
+ $chanName = $this->getChannelUriRecord($chanName);
320
+ }
321
+ if($this->isChannelName($chanName)) {
322
+ return $this->_data[self::K_CHAN][$chanName];
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Is channel name?
328
+ *
329
+ * @param $chanName
330
+ * @return boolean
331
+ */
332
+ public function isChannelName($chanName)
333
+ {
334
+ return isset($this->_data[self::K_CHAN][$chanName]);
335
+ }
336
+
337
+ /**
338
+ * Is channel alias?
339
+ *
340
+ * @param string $chanName
341
+ * @return boolean
342
+ */
343
+ public function isChannelAlias($chanName)
344
+ {
345
+ return isset($this->_data[self::K_CHAN_ALIAS][$chanName]);
346
+ }
347
+
348
+ /**
349
+ * Is channel uri?
350
+ *
351
+ * @param $uri
352
+ * @return boolean
353
+ */
354
+ public function isChannelUri($uri)
355
+ {
356
+ $uri = $this->formatUri($uri);
357
+ return isset($this->_data[self::K_CHAN_URI][$uri]);
358
+ }
359
+
360
+ /**
361
+ * Unset channel uri record
362
+ *
363
+ * @param string $uri
364
+ * @return null
365
+ */
366
+ protected function unsetChannelUriRecord($uri)
367
+ {
368
+ $uri = $this->formatUri($uri);
369
+ unset($this->_data[self::K_CHAN_URI][$uri]);
370
+ }
371
+
372
+ /**
373
+ * Set channel uri record: uri maps to channel record
374
+ *
375
+ * @param string $chanName
376
+ * @param string $uri
377
+ * @return null
378
+ */
379
+ protected function setChannelUriRecord($chanName, $uri)
380
+ {
381
+ $uri = $this->formatUri($uri);
382
+ $this->_data[self::K_CHAN_URI][$uri] = $chanName;
383
+ }
384
+
385
+ /**
386
+ * Get channel name by uri record
387
+ *
388
+ * @param string $uri
389
+ * @return string
390
+ */
391
+ protected function getChannelUriRecord($uri)
392
+ {
393
+ $uri = $this->formatUri($uri);
394
+ return $this->_data[self::K_CHAN_URI][$uri];
395
+ }
396
+
397
+ /**
398
+ * Unset channel record
399
+ *
400
+ * @param string $chanName
401
+ * @return null
402
+ */
403
+ protected function unsetChannelRecord($chanName)
404
+ {
405
+ unset($this->_data[self::K_CHAN][$chanName]);
406
+ }
407
+
408
+ /**
409
+ * Get channel record
410
+ *
411
+ * @param string $chanName
412
+ * @return array
413
+ */
414
+ protected function getChannelRecord($chanName)
415
+ {
416
+ return $this->_data[self::K_CHAN][$chanName];
417
+ }
418
+
419
+ /**
420
+ * Set channel record
421
+ *
422
+ * @param string $chanName
423
+ * @param string $uri
424
+ * @param mixed $data
425
+ * @param array $packages
426
+ * @return null
427
+ */
428
+ protected function setChannelRecord($chanName, $uri, $data, $packages = array())
429
+ {
430
+ $this->_data[self::K_CHAN][$chanName] = array(
431
+ self::K_NAME=>$chanName,
432
+ self::K_URI=>$uri,
433
+ self::K_CHAN_DATA=>$data,
434
+ self::K_PACK=>$packages
435
+ );
436
+ }
437
+
438
+ /**
439
+ * Set package record
440
+ *
441
+ * @param string $chanName
442
+ * @param string $packageName
443
+ * @param mixed $data
444
+ * @return null
445
+ */
446
+ protected function setPackageRecord($chanName, $packageName, $data, $oneField = null)
447
+ {
448
+ if(null === $oneField) {
449
+ $this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName] = $data;
450
+ } else {
451
+ $this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName][$oneField] = $data;
452
+ }
453
+ }
454
+
455
+
456
+
457
+ /**
458
+ * Unset package record
459
+ *
460
+ * @param string $chanName
461
+ * @param string $packageName
462
+ * @return null
463
+ */
464
+ protected function unsetPackageRecord($chanName, $packageName)
465
+ {
466
+ unset($this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName]);
467
+ }
468
+
469
+ /**
470
+ * Get package record
471
+ *
472
+ * @param string $chanName
473
+ * @param string $packageName
474
+ * @return array
475
+ */
476
+ protected function fetchPackage($chanName, $packageName, $field = null)
477
+ {
478
+ if(null === $field) {
479
+ return $this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName];
480
+ } else {
481
+ return $this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName][$field];
482
+ }
483
+ }
484
+
485
+ /**
486
+ * Has package record
487
+ *
488
+ * @param string $chanName
489
+ * @param string $packageName
490
+ * @return boolean
491
+ */
492
+ protected function hasPackageRecord($chanName, $packageName)
493
+ {
494
+ return isset($this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName]);
495
+ }
496
+
497
+ /**
498
+ * Get channel name by alias
499
+ * @param string $alias
500
+ * @return array
501
+ */
502
+ protected function getChannelNameByAlias($alias)
503
+ {
504
+ return $this->_data[self::K_CHAN_ALIAS][$alias];
505
+ }
506
+
507
+ /**
508
+ * Set channel alias
509
+ *
510
+ * @param string $alias
511
+ * @param string $chanName
512
+ * @return null
513
+ */
514
+ protected function setChannelAlias($alias, $chanName)
515
+ {
516
+ $this->_data[self::K_CHAN_ALIAS][$alias] = $chanName;
517
+ }
518
+
519
+ /**
520
+ * Unset channel alias
521
+ *
522
+ * @param string $alias
523
+ * @return null
524
+ */
525
+ protected function unsetChannelAlias($alias)
526
+ {
527
+ unset($this->_data[self::K_CHAN_ALIAS][$alias]);
528
+ }
529
+
530
+ /**
531
+ * Clear all aliases of channel
532
+ *
533
+ * @param string $chanName channel name
534
+ * @return null
535
+ */
536
+ protected function clearAliases($chanName)
537
+ {
538
+ $keys = array_keys($this->_data[self::K_CHAN_ALIAS]);
539
+ foreach ($keys as $key) {
540
+ if($this->_data[self::K_CHAN_ALIAS][$key] == $chanName) {
541
+ unset($this->_data[self::K_CHAN_ALIAS][$key]);
542
+ }
543
+ }
544
+ }
545
+
546
+ /**
547
+ * Add channel alias
548
+ *
549
+ * @param string $chanName
550
+ * @param string $alias
551
+ * @return null
552
+ */
553
+ public function addChannelAlias($chanName, $alias)
554
+ {
555
+ if($this->isChannelName($alias)) {
556
+ return $this->doError("Alias '{$alias}' is existant channel name!");
557
+ }
558
+
559
+ if(!$this->isChannelName($chanName)) {
560
+ return $this->doError("Channel '{$chanName}' doesn't exist");
561
+ }
562
+ $this->setChannelAlias($alias, $chanName);
563
+ $this->save();
564
+ }
565
+
566
+ /**
567
+ * Add channel
568
+ *
569
+ * @param string $chanName
570
+ * @param string $uri
571
+ * @param array $data
572
+ * @return null
573
+ */
574
+ public function addChannel($chanName, $uri, $data = array())
575
+ {
576
+ if($this->isChannelName($chanName)) {
577
+ return $this->doError("Channel '{$chanName}' already exist!");
578
+ }
579
+ if($this->isChannelUri($uri)) {
580
+ return $this->doError("Channel with uri= '{$uri}' already exist!");
581
+ }
582
+ if($this->isChannelAlias($chanName)) {
583
+ $this->unsetChannelAlias($chanName);
584
+ }
585
+ $uri = $this->formatUri($uri);
586
+ $this->setChannelRecord($chanName, $uri, $data);
587
+ $this->setChannelUriRecord($chanName, $uri);
588
+ $this->save();
589
+ }
590
+
591
+ /**
592
+ * Delete channel
593
+ *
594
+ * @param string $chanName
595
+ * @return null
596
+ */
597
+ public function deleteChannel($chanName)
598
+ {
599
+ if($this->isChannelName($chanName)) {
600
+ $record = $this->getChannelRecord($chanName);
601
+ $this->unsetChannelUriRecord($record[self::K_URI]);
602
+ $this->unsetChannelRecord($chanName);
603
+ $this->clearAliases($chanName);
604
+ } elseif($this->isChannelUri($chanName)) {
605
+ $uri = $chanName;
606
+ $chanName = $this->getChannelUriRecord($uri);
607
+ $this->unsetChannelUriRecord($uri);
608
+ $this->unsetChannelRecord($chanName);
609
+ $this->clearAliases($chanName);
610
+ } elseif($this->isChannelAlias($chanName)) {
611
+ $this->unsetChannelAlias($chanName);
612
+ } else {
613
+ return $this->doError("'{$chanName}' was not found in aliases, channel names, channel uris");
614
+ }
615
+ $this->save();
616
+ }
617
+
618
+ /**
619
+ * Converts channel name, url or alias to channel name
620
+ * throws exception if not found
621
+ *
622
+ * @param string $chanName
623
+ * @return string
624
+ */
625
+ public function chanName($chanName)
626
+ {
627
+ $channelData = $this->getChannel($chanName);
628
+ if(!$channelData) {
629
+ return $this->doError("Channel '{$chanName}' doesn't exist");
630
+ }
631
+ return $channelData[self::K_NAME];
632
+ }
633
+
634
+ /**
635
+ * Return Channel URI
636
+ *
637
+ * @param string $chan
638
+ * @return null
639
+ */
640
+ public function chanUrl($chan)
641
+ {
642
+ $channelData = $this->getChannel($chan);
643
+ if(!$channelData) {
644
+ return $this->doError("Channel '{$chan}' doesn't exist");
645
+ }
646
+ return $channelData[self::K_URI];
647
+ }
648
+
649
+ /**
650
+ * Add package
651
+ *
652
+ * @param Mage_Connect_Package $package
653
+ * @return null
654
+ */
655
+ public function addPackage($package)
656
+ {
657
+ $channel = $this->chanName($package->getChannel());
658
+ $name = $package->getName();
659
+ $record = array (
660
+ self::K_VER => $package->getVersion(),
661
+ self::K_STATE => $package->getStability(),
662
+ self::K_XML => $package->getPackageXml(),
663
+ self::K_NAME => $name,
664
+ self::K_DEPS => array(),
665
+ self::K_PACK_DEPS => array(),
666
+ );
667
+ $this->setPackageRecord($channel, $name, $record);
668
+ $this->setPackageDependencies($channel, $name, $package->getDependencyPackages());
669
+ $this->save();
670
+ }
671
+
672
+ /**
673
+ * Delete package
674
+ *
675
+ * @param string $chanName
676
+ * @param string $package
677
+ * @return null
678
+ */
679
+ public function deletePackage($chanName, $package)
680
+ {
681
+ $chanName = $this->chanName($chanName);
682
+ $this->unsetPackageRecord($chanName, $package);
683
+ $this->save();
684
+ }
685
+
686
+ /**
687
+ * Get package
688
+ *
689
+ * @param string $chanName
690
+ * @param string $package
691
+ * @return null
692
+ */
693
+ public function getPackage($chanName, $package)
694
+ {
695
+ $chanName = $this->chanName($chanName);
696
+ if($this->hasPackageRecord($chanName, $package)) {
697
+ return $this->fetchPackage($chanName, $package);
698
+ }
699
+ return null;
700
+ }
701
+
702
+ /**
703
+ * Retrieve Package object
704
+ *
705
+ * @throws Exception
706
+ * @param string $chanName
707
+ * @param string $package
708
+ * @return Mage_Connect_Package
709
+ */
710
+ public function getPackageObject($chanName, $package)
711
+ {
712
+ $chanName = $this->chanName($chanName);
713
+ if($this->hasPackageRecord($chanName, $package)) {
714
+ $data = $this->fetchPackage($chanName, $package);
715
+ return new Mage_Connect_Package($data[self::K_XML]);
716
+ }
717
+ throw new Exception("Cannot get package: '{$package}'");
718
+ }
719
+
720
+ /**
721
+ * Checks the presence of the package in the channel
722
+ *
723
+ * @param string $chanName
724
+ * @param string $package
725
+ * @param string $versionMin
726
+ * @param string $versionMax
727
+ * @return boolean
728
+ */
729
+ public function hasPackage($chanName, $package, $versionMin = false, $versionMax = false)
730
+ {
731
+ $chanName = $this->chanName($chanName);
732
+ $data = $this->getPackage($chanName, $package);
733
+ if(null === $data) {
734
+ return false;
735
+ }
736
+ $installedVersion = $data[self::K_VER];
737
+ return $this->versionInRange($installedVersion, $versionMin, $versionMax);
738
+ }
739
+
740
+ /**
741
+ * Check whether package installed or not. Return package if it installed
742
+ *
743
+ * @param string $package package name
744
+ * @return array|boolean
745
+ */
746
+ public function isPackageInstalled($package)
747
+ {
748
+ $channels = $this->getChannelNames();
749
+ foreach ($channels as $channel) {
750
+ if ($installedPackage = $this->getPackage($channel, $package)) {
751
+ return array_merge(array('channel'=>$channel), $installedPackage);
752
+ }
753
+
754
+ }
755
+ return false;
756
+ }
757
+
758
+ /**
759
+ * Checks whether the version in in the specified range of versionMin to versionMax
760
+ *
761
+ * @param string $version
762
+ * @param string $versionMin
763
+ * @param string $versionMax
764
+ * @return boolean
765
+ */
766
+ public function versionInRange($version, $versionMin = false, $versionMax = false)
767
+ {
768
+ if(false === $versionMin || empty($versionMin)) {
769
+ $minOk = true;
770
+ } else {
771
+ $minOk = version_compare($version, $versionMin, ">=");
772
+ }
773
+ if(false === $versionMax || empty($versionMax)) {
774
+ $maxOk = true;
775
+ } else {
776
+ $maxOk = version_compare($version, $versionMax, "<=");
777
+ }
778
+ return $minOk && $maxOk;
779
+ }
780
+
781
+ public function hasVersionRangeIntersect($min1, $max1, $min2, $max2)
782
+ {
783
+ if(version_compare($min1, $min2, ">") && version_compare($max1, $max2, ">")) {
784
+ return false;
785
+ } elseif(version_compare($min1, $min2, "<") && version_compare($max1, $max2, "<")) {
786
+ return false;
787
+ } elseif(version_compare($min1, $min2, ">=") && version_compare($max1, $max2, "<=")) {
788
+ return true;
789
+ } elseif(version_compare($min1, $min2, "<=") && version_compare($max1, $max2, ">=")) {
790
+ return true;
791
+ }
792
+ return false;
793
+ }
794
+
795
+ /**
796
+ * Clear contents to defaults and save
797
+ *
798
+ * @return null
799
+ */
800
+ public function clear()
801
+ {
802
+ $this->setEmptyConfig();
803
+ $this->save();
804
+ }
805
+
806
+ /**
807
+ * Output error - throw exception
808
+ *
809
+ * @param $message
810
+ * @throws Exception
811
+ * @return null
812
+ */
813
+ protected function doError($message)
814
+ {
815
+ throw new Exception($message);
816
+ }
817
+
818
+ /**
819
+ * Compare Stability
820
+ *
821
+ * @param string $s1
822
+ * @param string $s2
823
+ * @return int
824
+ */
825
+ public function compareStabilities($s1, $s2)
826
+ {
827
+ if(!$this->_validator) {
828
+ $this->_validator = new Mage_Connect_Validator();
829
+ }
830
+ return $this->_validator->compareStabilities($s1, $s2);
831
+ }
832
+
833
+ /**
834
+ * Retrieve Release Version from Rest Data
835
+ *
836
+ * @param $restData
837
+ * @param string|boolean $argVersionMin
838
+ * @param string|boolean $argVersionMax
839
+ * @param string $preferredStability
840
+ * @return boolean|string
841
+ */
842
+ public function detectVersionFromRestArray($restData, $argVersionMin = false, $argVersionMax = false,
843
+ $preferredStability = 'devel')
844
+ {
845
+ if(!is_array($restData)) {
846
+ return false;
847
+ }
848
+
849
+ foreach($restData as $vData) {
850
+ $stability = trim($vData['s']);
851
+ $version = trim($vData['v']);
852
+ $goodStability = $this->compareStabilities($stability, $preferredStability) >= 0;
853
+ if($goodStability && $this->versionInRange($version, $argVersionMin, $argVersionMax)) {
854
+ return $version;
855
+ }
856
+ }
857
+ return false;
858
+ }
859
+
860
+ /**
861
+ * Set Package dependencies
862
+ *
863
+ * @param string $chanName
864
+ * @param string $package
865
+ * @param mixed $data
866
+ * @return boolean
867
+ */
868
+ public function setPackageDependencies($chanName, $package, $data)
869
+ {
870
+ $chanName = $this->chanName($chanName);
871
+ if($this->hasPackageRecord($chanName, $package)) {
872
+ $this->setPackageRecord($chanName, $package, $data, self::K_PACK_DEPS);
873
+ $this->save();
874
+ return true;
875
+ }
876
+ return false;
877
+ }
878
+
879
+ /**
880
+ * Retrieve Package Dependencies
881
+ *
882
+ * @param string $chanName
883
+ * @param string $package
884
+ * @return array|boolean
885
+ */
886
+ public function getPackageDependencies($chanName, $package)
887
+ {
888
+ $chanName = $this->chanName($chanName);
889
+ if($this->hasPackageRecord($chanName, $package)) {
890
+ return $this->fetchPackage($chanName, $package, self::K_PACK_DEPS);
891
+ }
892
+ return false;
893
+ }
894
+
895
+ /**
896
+ * Set Dependency information into package
897
+ *
898
+ * @param string $chanName
899
+ * @param string $package
900
+ * @param mixed $data
901
+ * @return boolean
902
+ */
903
+ public function setDependencyInfo($chanName, $package, $data)
904
+ {
905
+ $chanName = $this->chanName($chanName);
906
+ if($this->hasPackageRecord($chanName, $package)) {
907
+ $this->setPackageRecord($chanName, $package, $data, self::K_DEPS);
908
+ $this->save();
909
+ return true;
910
+ }
911
+ return false;
912
+ }
913
+
914
+ /**
915
+ * Get Dependency information from package
916
+ *
917
+ * @param $chanName
918
+ * @param $package
919
+ * @return array|boolean
920
+ */
921
+ public function getDependencyInfo($chanName, $package)
922
+ {
923
+ $chanName = $this->chanName($chanName);
924
+ if($this->hasPackageRecord($chanName, $package)) {
925
+ return $this->fetchPackage($chanName, $package, self::K_DEPS);
926
+ }
927
+ return false;
928
+ }
929
+
930
+ /**
931
+ * Retrieve chanel names
932
+ *
933
+ * @return array
934
+ */
935
+ public function getChannelNames()
936
+ {
937
+ return array_keys($this->_data[self::K_CHAN]);
938
+ }
939
+
940
+ /**
941
+ * Retrieve Packages array
942
+ *
943
+ * @param string|boolean $channel
944
+ * @return array
945
+ */
946
+ public function getPackagesData($channel = false)
947
+ {
948
+ if(false == $channel) {
949
+ return $this->_data[self::K_CHAN];
950
+ }
951
+
952
+ if(!$this->isChannel($channel)) {
953
+ return array();
954
+ }
955
+ return $this->getChannel($channel);
956
+ }
957
+
958
+ /**
959
+ * Check whether Package exists in dependency list
960
+ *
961
+ * @param array $deps
962
+ * @param string $chanName
963
+ * @param string $packageName
964
+ * @return boolean
965
+ */
966
+ public function specifiedInDependencyList($deps, $chanName, $packageName)
967
+ {
968
+ foreach($deps as $dep) {
969
+ if($chanName == $dep['channel'] && $packageName == $dep['name']) {
970
+ return true;
971
+ }
972
+ }
973
+ return false;
974
+ }
975
+
976
+ /**
977
+ * Checks is package required by other
978
+ *
979
+ * @param string $chanName
980
+ * @param string $packageName
981
+ * @param array $excludeList
982
+ * @return array
983
+ */
984
+ public function requiredByOtherPackages($chanName, $packageName, $excludeList = array())
985
+ {
986
+ $out = array();
987
+ foreach($this->_data[self::K_CHAN] as $channel=>$data) {
988
+ foreach($data[self::K_PACK] as $package) {
989
+ if($this->specifiedInDependencyList($excludeList, $channel, $package['name'])) {
990
+ continue;
991
+ }
992
+ $deps = $package[self::K_PACK_DEPS];
993
+ if($this->specifiedInDependencyList($deps, $chanName, $packageName)) {
994
+ $out[] = array('channel'=>$channel, 'name' =>$package['name'], 'version'=>$package['version']);
995
+ }
996
+ }
997
+ }
998
+ return $out;
999
+ }
1000
+
1001
+ /**
1002
+ * Get Installed packages array
1003
+ *
1004
+ * @param string $chanName
1005
+ * @return array
1006
+ */
1007
+ public function getInstalledPackages($chanName = false)
1008
+ {
1009
+ $data = null;
1010
+ if(false == $chanName) {
1011
+ $data = $this->getChannelNames();
1012
+ } elseif($this->isChannel($chanName)) {
1013
+ $tmp = $this->getChannel($chanName);
1014
+ $data = array($tmp[self::K_NAME]);
1015
+ }
1016
+ $out = array();
1017
+ foreach($data as $chanName) {
1018
+ $channel = $this->getChannel($chanName);
1019
+ $out[$chanName] = array();
1020
+ foreach($channel[self::K_PACK] as $package=>$data) {
1021
+ $out[$chanName][$package] = array();
1022
+ foreach(array(self::K_VER, self::K_STATE) as $k) {
1023
+ $out[$chanName][$package][$k] = $data[$k];
1024
+ }
1025
+ }
1026
+ }
1027
+ return $out;
1028
+ }
1029
+
1030
+ /**
1031
+ * Check if package conflicts with installed packages
1032
+ * Returns:
1033
+ * array with conflicts
1034
+ * false if no conflicts
1035
+ *
1036
+ * @param string $chanName
1037
+ * @param string $packageName
1038
+ * @param string $version
1039
+ * @return array|boolean
1040
+ */
1041
+ public function hasConflicts($chanName, $packageName, $version)
1042
+ {
1043
+ $conflicts = array();
1044
+ foreach($this->_data[self::K_CHAN] as $channel=>$data) {
1045
+ foreach($data[self::K_PACK] as $package) {
1046
+ $deps = $package[self::K_PACK_DEPS];
1047
+ foreach($deps as $dep) {
1048
+ if($dep['name'] != $packageName) {
1049
+ continue;
1050
+ }
1051
+
1052
+ if(!$this->versionInRange($version, $dep['min'], $dep['max'])) {
1053
+ $conflicts[] = $channel . "/". $package['name'] ." ". $package['version'];
1054
+ }
1055
+ }
1056
+ }
1057
+ }
1058
+ return count($conflicts) ? $conflicts : false;
1059
+ }
1060
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Structures/Graph.php ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ class Mage_Connect_Structures_Graph
28
+ {
29
+ protected $_nodes = array();
30
+ protected $_directed = false;
31
+ protected $_nodeClassName = 'Mage_Connect_Structures_Node';
32
+
33
+ const ACYCLIC_VISITED_KEY = 'acyclic-test-visited';
34
+ const SORT_VISITED_KEY = 'topological-sort-visited';
35
+ const SORT_LEVEL_KEY = 'topological-sort-level';
36
+
37
+ /**
38
+ * Constructor
39
+ * @param bool $directed directed graph?
40
+ * @return void
41
+ */
42
+ public function __construct($directed = true)
43
+ {
44
+ $this->_directed = $directed;
45
+ }
46
+
47
+
48
+ /**
49
+ * Is graph directed?
50
+ *
51
+ * @return bool
52
+ */
53
+ public function isDirected()
54
+ {
55
+ return (boolean) $this->_directed;
56
+ }
57
+
58
+ /**
59
+ * Add node to list
60
+ *
61
+ * @param Mage_Connect_Structures_Graph_Node $newNode
62
+ * @return void
63
+ */
64
+ public function addNode(&$newNode)
65
+ {
66
+ if(!$newNode instanceof $this->_nodeClassName) {
67
+ throw new Exception(__METHOD__." : invalid node class, should be instance of: ".$this->_nodeClassName);
68
+ }
69
+ foreach($this->_nodes as $key => $node) {
70
+ if($newNode === $node) {
71
+ throw new Exception(__METHOD__." : received duplicate object");
72
+ }
73
+ }
74
+ $this->_nodes[] =& $newNode;
75
+ $newNode->setGraph($this);
76
+ }
77
+
78
+ /**
79
+ * Remove a Node from the Graph
80
+ * @param Mage_Connect_Structures_Graph_Node $node
81
+ */
82
+ public function removeNode(&$node)
83
+ {
84
+
85
+ }
86
+
87
+ /**
88
+ * Return set of nodes
89
+ * @return array
90
+ */
91
+ public function &getNodes()
92
+ {
93
+ return $this->_nodes;
94
+ }
95
+
96
+ /**
97
+ * Is asyclic
98
+ * @return unknown_type
99
+ */
100
+ public function isAcyclic()
101
+ {
102
+ if (!$this->isDirected()) {
103
+ return false;
104
+ }
105
+ return self::_isAcyclic($this);
106
+ }
107
+
108
+ /**
109
+ *
110
+ * This is a variant of Graph::inDegree which does
111
+ * not count nodes marked as visited.
112
+ *
113
+ * @return integer
114
+ */
115
+ protected static function _nonVisitedInDegree(&$node, $metadataKey)
116
+ {
117
+ $result = 0;
118
+ $graphNodes =& $node->getGraph()->getNodes();
119
+ foreach (array_keys($graphNodes) as $key) {
120
+ if ((!$graphNodes[$key]->getMetadata($metadataKey)) && $graphNodes[$key]->connectsTo($node)) {
121
+ $result++;
122
+ }
123
+ }
124
+ return $result;
125
+ }
126
+
127
+ /**
128
+ * Is graph acyclic?
129
+ * @param $graph
130
+ * @return bool
131
+ */
132
+ protected static function _isAcyclic(&$graph)
133
+ {
134
+ // Mark every node as not visited
135
+ $nodes =& $graph->getNodes();
136
+ $nodeKeys = array_keys($nodes);
137
+ $refGenerator = array();
138
+ foreach($nodeKeys as $key) {
139
+ $refGenerator[] = false;
140
+ $nodes[$key]->setMetadata(self::ACYCLIC_VISITED_KEY, $refGenerator[sizeof($refGenerator) - 1]);
141
+ }
142
+
143
+ // Iteratively peel off leaf nodes
144
+ do {
145
+ // Find out which nodes are leafs (excluding visited nodes)
146
+ $leafNodes = array();
147
+ foreach($nodeKeys as $key) {
148
+ if ((!$nodes[$key]->getMetadata(self::ACYCLIC_VISITED_KEY)) &&
149
+ self::_nonVisitedInDegree($nodes[$key], self::ACYCLIC_VISITED_KEY) == 0) {
150
+ $leafNodes[] =& $nodes[$key];
151
+ }
152
+ }
153
+ // Mark leafs as visited
154
+ for ($i=sizeof($leafNodes) - 1; $i>=0; $i--) {
155
+ $visited =& $leafNodes[$i]->getMetadata(self::ACYCLIC_VISITED_KEY);
156
+ $visited = true;
157
+ $leafNodes[$i]->setMetadata(self::ACYCLIC_VISITED_KEY, $visited);
158
+ }
159
+ } while (sizeof($leafNodes) > 0);
160
+
161
+
162
+ // If graph is a DAG, there should be no non-visited nodes.
163
+ // Let's try to prove otherwise
164
+ $result = true;
165
+ foreach($nodeKeys as $key) {
166
+ if (!$nodes[$key]->getMetadata(self::ACYCLIC_VISITED_KEY)) {
167
+ $result = false;
168
+ break;
169
+ }
170
+ }
171
+
172
+ // Cleanup visited marks
173
+ foreach($nodeKeys as $key) {
174
+ $nodes[$key]->unsetMetadata(self::ACYCLIC_VISITED_KEY);
175
+ }
176
+
177
+ return $result;
178
+ }
179
+
180
+ /**
181
+ *
182
+ * sort returns the graph's nodes, sorted by topological order.
183
+ *
184
+ * The result is an array with
185
+ * as many entries as topological levels.
186
+ *
187
+ * Each entry in this array is an array of nodes within
188
+ * the given topological level.
189
+ *
190
+ * @return array
191
+ */
192
+ public function topologicalSort()
193
+ {
194
+ // We only sort graphs
195
+ self::_topologicalSort($this);
196
+ $result = array();
197
+ // Fill out result array
198
+ $nodes =& $this->getNodes();
199
+ $nodeKeys = array_keys($nodes);
200
+ foreach($nodeKeys as $key) {
201
+ $k = $nodes[$key]->getMetadata(self::SORT_LEVEL_KEY);
202
+ if (!array_key_exists($k, $result)) {
203
+ $result[$k] = array();
204
+ }
205
+ $result[$k][] =& $nodes[$key];
206
+ $nodes[$key]->unsetMetadata(self::SORT_LEVEL_KEY);
207
+ }
208
+ return $result;
209
+ }
210
+
211
+ protected static function _topologicalSort(&$graph)
212
+ {
213
+ // Mark every node as not visited
214
+ $nodes =& $graph->getNodes();
215
+ $nodeKeys = array_keys($nodes);
216
+ $refGenerator = array();
217
+ foreach($nodeKeys as $key) {
218
+ $refGenerator[] = false;
219
+ $nodes[$key]->setMetadata(self::SORT_VISITED_KEY, $refGenerator[sizeof($refGenerator) - 1]);
220
+ }
221
+
222
+ // Iteratively peel off leaf nodes
223
+ $topologicalLevel = 0;
224
+ do {
225
+ // Find out which nodes are leafs (excluding visited nodes)
226
+ $leafNodes = array();
227
+ foreach($nodeKeys as $key) {
228
+ if ((!$nodes[$key]->getMetadata(self::SORT_VISITED_KEY)) && self::_nonVisitedInDegree($nodes[$key], self::SORT_VISITED_KEY) == 0) {
229
+ $leafNodes[] =& $nodes[$key];
230
+ }
231
+ }
232
+ // Mark leafs as visited
233
+ $refGenerator[] = $topologicalLevel;
234
+ for ($i=sizeof($leafNodes) - 1; $i>=0; $i--) {
235
+ $visited =& $leafNodes[$i]->getMetadata(self::SORT_VISITED_KEY);
236
+ $visited = true;
237
+ $leafNodes[$i]->setMetadata(self::SORT_VISITED_KEY, $visited);
238
+ $leafNodes[$i]->setMetadata(self::SORT_LEVEL_KEY, $refGenerator[sizeof($refGenerator) - 1]);
239
+ }
240
+ $topologicalLevel++;
241
+ } while (sizeof($leafNodes) > 0);
242
+
243
+ foreach($nodeKeys as $key) {
244
+ $nodes[$key]->unsetMetadata(self::SORT_VISITED_KEY);
245
+ }
246
+ }
247
+
248
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Structures/Node.php ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ class Mage_Connect_Structures_Node
28
+ {
29
+
30
+ protected $_data = null;
31
+ protected $_metadata = array();
32
+ protected $_arcs = array();
33
+ protected $_graph = null;
34
+
35
+ /**
36
+ * Node graph getter
37
+ *
38
+ * @return Mage_Connect_Structures_Graph
39
+ */
40
+ public function &getGraph()
41
+ {
42
+ return $this->_graph;
43
+ }
44
+
45
+ /**
46
+ *
47
+ * Node graph setter.
48
+ * This method should not be called directly.
49
+ * Use Graph::addNode instead.
50
+ *
51
+ * @param $graph
52
+ */
53
+ public function setGraph(&$graph)
54
+ {
55
+ $this->_graph =& $graph;
56
+ }
57
+
58
+ /**
59
+ *
60
+ * Node data getter.
61
+ *
62
+ * Each graph node can contain a reference to one variable. This is the getter for that reference.
63
+ *
64
+ * @return mixed Data stored in node
65
+ * @access public
66
+ */
67
+ public function &getData()
68
+ {
69
+ return $this->_data;
70
+ }
71
+
72
+ /**
73
+ * Node data setter
74
+ *
75
+ * Each graph node can contain a reference to one variable. This is the setter for that reference.
76
+ *
77
+ * @return mixed Data to store in node
78
+ */
79
+ public function setData($data)
80
+ {
81
+ $this->_data =& $data;
82
+ }
83
+
84
+ /**
85
+ *
86
+ * Test for existence of metadata under a given key.
87
+ *
88
+ * @param string Key to test
89
+ * @return boolean
90
+ * @access public
91
+ */
92
+ public function metadataKeyExists($key)
93
+ {
94
+ return array_key_exists($key, $this->_metadata);
95
+ }
96
+
97
+ /**
98
+ *
99
+ * Get node metadata
100
+ *
101
+ * @param string $key
102
+ * @param boolean $nullIfNonexistent (defaults to false).
103
+ * @return mixed
104
+ */
105
+ public function & getMetadata($key, $nullIfNonexistent = false)
106
+ {
107
+ if (array_key_exists($key, $this->_metadata)) {
108
+ return $this->_metadata[$key];
109
+ } elseif ($nullIfNonexistent) {
110
+ $a = null;
111
+ return $a;
112
+ } else {
113
+ throw new Exception(__METHOD__." : requested key doesn't exist: {$key}");
114
+ }
115
+ }
116
+
117
+ /**
118
+ *
119
+ * Delete metadata by key
120
+ *
121
+ * @param string Key
122
+ */
123
+ public function unsetMetadata($key)
124
+ {
125
+ if (array_key_exists($key, $this->_metadata)) {
126
+ unset($this->_metadata[$key]);
127
+ }
128
+
129
+ }
130
+
131
+ /**
132
+ *
133
+ * Node metadata setter
134
+ *
135
+ * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an
136
+ * associative array or in a dictionary. This method stores data under the given key. If the key already exists,
137
+ * previously stored data is discarded.
138
+ *
139
+ * @param string $key
140
+ * @param mixed $data
141
+ */
142
+ public function setMetadata($key, $data)
143
+ {
144
+ $this->_metadata[$key] =& $data;
145
+ }
146
+
147
+ protected function _connectTo(&$destinationNode)
148
+ {
149
+ $this->_arcs[] =& $destinationNode;
150
+ }
151
+
152
+ /**
153
+ * Connect this node to another one.
154
+ * If the graph is not directed, the reverse arc, connecting $destinationNode to $this is also created.
155
+ * @param Structures_Graph Node to connect to
156
+ */
157
+ public function connectTo(&$destinationNode)
158
+ {
159
+ $class = get_class($this);
160
+ if(!$destinationNode instanceof $class) {
161
+ throw new Exception(__METHOD__." : argument should be instance of {$class}");
162
+ }
163
+
164
+ // Nodes must already be in graphs to be connected
165
+ if ($this->_graph == null) {
166
+ throw new Exception(__METHOD__." : tried to connect to null graph");
167
+ }
168
+
169
+ if ($destinationNode->getGraph() == null) {
170
+ throw new Exception(__METHOD__." : tried to connect to node that is not connected to any graph");
171
+ }
172
+
173
+ // Connect here
174
+ $this->_connectTo($destinationNode);
175
+ // If graph is undirected, connect back
176
+ if (!$this->_graph->isDirected()) {
177
+ $destinationNode->_connectTo($this);
178
+ }
179
+ }
180
+
181
+
182
+ /**
183
+ * Return nodes connected to this one.
184
+ * @return array
185
+ */
186
+ public function getNeighbours()
187
+ {
188
+ return $this->_arcs;
189
+ }
190
+
191
+ /**
192
+ * Test wether this node has an arc to the target node
193
+ * Returns true if the two nodes are connected
194
+ * @return boolean
195
+ */
196
+ public function connectsTo(&$target)
197
+ {
198
+ $arcKeys = array_keys($this->_arcs);
199
+ foreach($arcKeys as $key) {
200
+ $arc =& $this->_arcs[$key];
201
+ if ($target === $arc) {
202
+ return true;
203
+ }
204
+ }
205
+ return false;
206
+ }
207
+
208
+ /**
209
+ * Calculate the in degree of the node.
210
+ *
211
+ * The indegree for a node is the number of arcs
212
+ * entering the node.
213
+ *
214
+ * For non directed graphs:
215
+ * always outdegree = indegree.
216
+ *
217
+ * @return int
218
+ */
219
+ public function inDegree()
220
+ {
221
+ $result = 0;
222
+
223
+ if ($this->_graph == null) {
224
+ return $result;
225
+ }
226
+ if (!$this->_graph->isDirected()) {
227
+ return $this->outDegree();
228
+ }
229
+
230
+ $graphNodes =& $this->_graph->getNodes();
231
+ foreach (array_keys($graphNodes) as $key) {
232
+ if ($graphNodes[$key]->connectsTo($this)) {
233
+ $result++;
234
+ }
235
+ }
236
+ return $result;
237
+
238
+ }
239
+
240
+ /**
241
+ * Calculate the out degree of the node.
242
+ *
243
+ * The outdegree for a node is the number of arcs exiting the node.
244
+ * For non directed graphs:
245
+ * always outdegree = indegree.
246
+ *
247
+ * @return int
248
+ */
249
+ public function outDegree()
250
+ {
251
+ if ($this->_graph == null) {
252
+ return 0;
253
+ }
254
+ return count($this->_arcs);
255
+ }
256
+
257
+ }
app/code/local/Mss/downloader/lib/Mage/Connect/Validator.php ADDED
@@ -0,0 +1,483 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to validate string resources
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Connect_Validator
35
+ {
36
+ /**
37
+ * Array of stability variants
38
+ *
39
+ * @var array
40
+ */
41
+ protected static $_stability = array(0=>'devel',1=>'alpha',2=>'beta',3=>'stable');
42
+
43
+ /**
44
+ * Get array of Stability variants
45
+ *
46
+ * @static
47
+ * @return array
48
+ */
49
+ public static function getStabilities()
50
+ {
51
+ return self::$_stability;
52
+ }
53
+
54
+ /**
55
+ * Compare stabilities. Returns:
56
+ *
57
+ * -1 if the first stability is lower than the second
58
+ * 0 if they are equal
59
+ * 1 if the second is lower.
60
+ *
61
+ * @param int|string $s1
62
+ * @param int|string $s2
63
+ * @return int|null
64
+ */
65
+ public function compareStabilities($s1, $s2)
66
+ {
67
+ $list = $this->getStabilities();
68
+ $tmp = array_combine(array_values($list),array_keys($list));
69
+
70
+ if (!isset($tmp[$s1], $tmp[$s2])) {
71
+ throw new Exception("Invalid stability in compareStabilities argument");
72
+ }
73
+
74
+ $s1 = $tmp[$s1];
75
+ $s2 = $tmp[$s2];
76
+ if ($s1 === $s2) {
77
+ return 0;
78
+ } elseif ($s1 > $s2) {
79
+ return 1;
80
+ } elseif ($s1 < $s2) {
81
+ return -1;
82
+ }
83
+ return null;
84
+ }
85
+
86
+ /**
87
+ * Constructor
88
+ */
89
+ public function __construct()
90
+ {
91
+
92
+ }
93
+
94
+ /**
95
+ * Validate max len of string
96
+ *
97
+ * @param string $str
98
+ * @param int $maxLen
99
+ * @return bool
100
+ */
101
+ public function validateMaxLen($str, $maxLen)
102
+ {
103
+ return strlen((string) $str) <= (int) $maxLen;
104
+ }
105
+
106
+ /**
107
+ * Validate channel name and url
108
+ *
109
+ * @param mixed $str
110
+ * @return bool
111
+ */
112
+ public function validateChannelNameOrUri($str)
113
+ {
114
+ return ( $this->validateUrl($str) || $this->validatePackageName($str));
115
+ }
116
+
117
+ /**
118
+ * Validate License url
119
+ *
120
+ * @param mixed $str
121
+ * @return boolean
122
+ */
123
+ public function validateLicenseUrl($str)
124
+ {
125
+ if ($str) {
126
+ return ( $this->validateUrl($str) || $this->validatePackageName($str));
127
+ }
128
+ return true;
129
+ }
130
+
131
+ /**
132
+ * Validate compatible data
133
+ *
134
+ * @param array $data
135
+ * @return bool
136
+ */
137
+ public function validateCompatible(array $data)
138
+ {
139
+ if (!count($data)) {
140
+ /**
141
+ * Allow empty
142
+ */
143
+ return true;
144
+ }
145
+ $count = 0;
146
+ foreach ($data as $v) {
147
+ /**
148
+ * Converts an array to variables
149
+ * @var $channel string Channel Name
150
+ * @var $name string Package Name
151
+ * @var $max string Maximum version number
152
+ * @var $min string Minimum version number
153
+ */
154
+ foreach (array('name','channel','min','max') as $fld) {
155
+ $$fld = trim($v[$fld]);
156
+ }
157
+ $count++;
158
+
159
+ $res = $this->validateUrl($channel) && strlen($channel);
160
+ if (!$res) {
161
+ $this->addError("Invalid or empty channel in compatibility #{$count}");
162
+ }
163
+
164
+ $res = $this->validatePackageName($name) && strlen($name);
165
+ if (!$res) {
166
+ $this->addError("Invalid or empty name in compatibility #{$count}");
167
+ }
168
+ $res1 = $this->validateVersion($min);
169
+ if (!$res1) {
170
+ $this->addError("Invalid or empty minVersion in compatibility #{$count}");
171
+ }
172
+ $res2 = $this->validateVersion($max);
173
+ if (!$res2) {
174
+ $this->addError("Invalid or empty maxVersion in compatibility #{$count}");
175
+ }
176
+ if ($res1 && $res2 && $this->versionLower($max, $min)) {
177
+ $this->addError("Max version is lower than min in compatibility #{$count}");
178
+ }
179
+ }
180
+ return !$this->hasErrors();
181
+ }
182
+
183
+ /**
184
+ * Validate authors of package
185
+ *
186
+ * @param array $authors
187
+ * @return bool
188
+ */
189
+ public function validateAuthors(array $authors)
190
+ {
191
+ if (!count($authors)) {
192
+ $this->addError('Empty authors section');
193
+ return false;
194
+ }
195
+ $count = 0;
196
+ foreach ($authors as $v) {
197
+ $count++;
198
+ array_map('trim', $v);
199
+ $name = $v['name'];
200
+ $login = $v['user'];
201
+ $email = $v['email'];
202
+ $res = $this->validateMaxLen($name, 256) && strlen($name);
203
+ if (!$res) {
204
+ $this->addError("Invalid or empty name for author #{$count}");
205
+ }
206
+ $res = $this->validateAuthorName($login) && strlen($login);
207
+ if (!$res) {
208
+ $this->addError("Invalid or empty login for author #{$count}");
209
+ }
210
+ $res = $this->validateEmail($email);
211
+ if (!$res) {
212
+ $this->addError("Invalid or empty email for author #{$count}");
213
+ }
214
+ }
215
+ return !$this->hasErrors();
216
+ }
217
+
218
+ /**
219
+ * Validator errors
220
+ *
221
+ * @var array
222
+ */
223
+ private $_errors = array();
224
+
225
+ /**
226
+ * Add error
227
+ *
228
+ * @param string $err
229
+ * @return void
230
+ */
231
+ private function addError($err)
232
+ {
233
+ $this->_errors[] = $err;
234
+ }
235
+
236
+ /**
237
+ * Set validator errors
238
+ *
239
+ * @param array $err
240
+ * @return void
241
+ */
242
+ private function setErrors(array $err)
243
+ {
244
+ $this->_errors = $err;
245
+ }
246
+
247
+ /**
248
+ * Clear validator errors
249
+ *
250
+ * @return void
251
+ */
252
+ private function clearErrors()
253
+ {
254
+ $this->_errors = array();
255
+ }
256
+
257
+ /**
258
+ * Check if there are validator errors set
259
+ *
260
+ * @return int
261
+ */
262
+ public function hasErrors()
263
+ {
264
+ return count($this->_errors) != 0;
265
+ }
266
+
267
+ /**
268
+ * Get errors
269
+ *
270
+ * @param bool $clear if true after this call erros will be cleared
271
+ * @return array
272
+ */
273
+ public function getErrors($clear = true)
274
+ {
275
+ $out = $this->_errors;
276
+ if ($clear) {
277
+ $this->clearErrors();
278
+ }
279
+ return $out;
280
+ }
281
+
282
+ /**
283
+ * Validate URL
284
+ *
285
+ * @param string $str
286
+ * @return bool
287
+ */
288
+ public function validateUrl($str)
289
+ {
290
+ $regex = "@([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|"
291
+ ."(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)"
292
+ ."[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+)(:[0-9]*)?@i";
293
+ return preg_match($regex, $str);
294
+ }
295
+
296
+ /**
297
+ * Validates package stability
298
+ *
299
+ * @param string $str
300
+ * @return bool
301
+ */
302
+ public function validateStability($str)
303
+ {
304
+ return in_array(strval($str), self::$_stability);
305
+ }
306
+
307
+ /**
308
+ * Validate date format
309
+ *
310
+ * @param $date
311
+ * @return bool
312
+ */
313
+ public function validateDate($date)
314
+ {
315
+ $subs = null;
316
+ $check1 = preg_match("/^([\d]{4})-([\d]{2})-([\d]{2})$/i", $date, $subs);
317
+ if (!$check1) {
318
+ return false;
319
+ }
320
+ return checkdate($subs[2], $subs[3], $subs[1]);
321
+ }
322
+
323
+ /**
324
+ * Validate email
325
+ * @param string $email
326
+ * @return bool
327
+ */
328
+ public function validateEmail($email)
329
+ {
330
+ return preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $email);
331
+ }
332
+
333
+ /**
334
+ * Validate package name
335
+ * @param $name
336
+ * @return bool
337
+ */
338
+ public function validatePackageName($name)
339
+ {
340
+ return preg_match("/^[a-zA-Z0-9_]+$/i", $name);
341
+ }
342
+
343
+ /**
344
+ * Validate author name
345
+ *
346
+ * @param string $name
347
+ * @return bool
348
+ */
349
+ public function validateAuthorName($name)
350
+ {
351
+ return preg_match("/^[a-zA-Z0-9_-]+$/i", $name);
352
+ }
353
+
354
+ /**
355
+ * Validate version number
356
+ *
357
+ * @param string $version
358
+ * @return bool
359
+ */
360
+ public function validateVersion($version)
361
+ {
362
+ return preg_match("/^[\d]+\.[\d]+\.[\d]+([[:alnum:]\.\-\_]+)?$/i", $version);
363
+ }
364
+
365
+ /**
366
+ * Check versions are equal
367
+ *
368
+ * @param string $v1
369
+ * @param string $v2
370
+ * @return bool
371
+ */
372
+ public function versionEqual($v1, $v2)
373
+ {
374
+ return version_compare($v1, $v2, "==");
375
+ }
376
+
377
+ /**
378
+ * Check version $v1 <= $v2
379
+ *
380
+ * @param string $v1
381
+ * @param string $v2
382
+ * @return bool
383
+ */
384
+ public function versionLowerEqual($v1, $v2)
385
+ {
386
+ return version_compare($v1, $v2, "le");
387
+ }
388
+
389
+ /**
390
+ * Check if version $v1 lower than $v2
391
+ *
392
+ * @param string $v1
393
+ * @param string $v2
394
+ * @return bool
395
+ */
396
+ public function versionLower($v1, $v2)
397
+ {
398
+ return version_compare($v1, $v2, "<");
399
+ }
400
+
401
+ /**
402
+ * Check version $v1 >= $v2
403
+ *
404
+ * @param string $v1
405
+ * @param string $v2
406
+ * @return bool
407
+ */
408
+ public function versionGreaterEqual($v1, $v2)
409
+ {
410
+ return version_compare($v1, $v2, "ge");
411
+ }
412
+
413
+ /**
414
+ * Generic regex validation
415
+ *
416
+ * @param string $str
417
+ * @param string $regex
418
+ * @return bool
419
+ */
420
+ public function validateRegex($str, $regex)
421
+ {
422
+ return preg_match($regex, $str);
423
+ }
424
+
425
+ /**
426
+ * Check if PHP extension loaded
427
+ *
428
+ * @param string $name Extension name
429
+ * @return bool
430
+ */
431
+ public function validatePhpExtension($name)
432
+ {
433
+ return extension_loaded($name);
434
+ }
435
+
436
+ /**
437
+ * Validate PHP version
438
+ *
439
+ * @param string $min
440
+ * @param string $max
441
+ * @param string $ver
442
+ * @return bool
443
+ */
444
+ public function validatePHPVersion($min, $max, $ver = PHP_VERSION)
445
+ {
446
+ $minAccepted = true;
447
+ if ($min) {
448
+ $minAccepted = version_compare($ver, $min, ">=");
449
+ }
450
+ $maxAccepted = true;
451
+ if ($max) {
452
+ $maxAccepted = version_compare($ver, $max, "<=");
453
+ }
454
+ return (bool) $minAccepted && $maxAccepted;
455
+ }
456
+
457
+ /**
458
+ * Validate contents of package
459
+ *
460
+ * @param array $contents
461
+ * @param Mage_Connect_Config $config
462
+ * @param array $typesToBackup
463
+ * @return bool
464
+ */
465
+ public function validateContents(array $contents, $config, $typesToBackup = array())
466
+ {
467
+ if (!count($contents)) {
468
+ $this->addError('Empty package contents section');
469
+ return false;
470
+ }
471
+
472
+ $targetPath = rtrim($config->magento_root, "\\/");
473
+ foreach ($contents as $file) {
474
+ $dest = $targetPath . DS . $file;
475
+ $type = pathinfo($file, PATHINFO_EXTENSION);
476
+ if (file_exists($dest) && !in_array($type, $typesToBackup)) {
477
+ $this->addError("'{$file}' already exists");
478
+ return false;
479
+ }
480
+ }
481
+ return true;
482
+ }
483
+ }
app/code/local/Mss/downloader/lib/Mage/DB/Exception.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_DB
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * TODO
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_DB_Exception extends Exception {
35
+
36
+ }
app/code/local/Mss/downloader/lib/Mage/DB/Mysqli.php ADDED
@@ -0,0 +1,532 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_DB
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Mysqli database connector
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_DB_Mysqli
35
+ {
36
+ /**
37
+ * Default port
38
+ * @var int
39
+ */
40
+ const DEFAULT_PORT = 3306;
41
+
42
+ /**
43
+ * Table name escaper
44
+ * @var string
45
+ */
46
+ const TABLE_ESCAPER = '`';
47
+
48
+ /**
49
+ * Value escaper
50
+ * @var unknown_type
51
+ */
52
+ const VALUE_ESCAPER = '"';
53
+
54
+ /**
55
+ * Connection
56
+ * @var mysqli
57
+ */
58
+ protected $conn;
59
+ /**
60
+ * Fetch mode
61
+ * @var unknown_type
62
+ */
63
+ private $fetch_mode = MYSQLI_ASSOC;
64
+
65
+
66
+ /**
67
+ * Constructor
68
+ */
69
+ public function __construct()
70
+ {
71
+ $this->conn = new mysqli();
72
+ }
73
+
74
+ /**
75
+ * Connect
76
+ * @param string $host
77
+ * @param string $user
78
+ * @param string $paswd
79
+ * @param string $db
80
+ * @param int $port
81
+ * @return mixed
82
+ */
83
+ public function connect($host, $user, $paswd, $db, $port = self::DEFAULT_PORT)
84
+ {
85
+ $port = (int) $port;
86
+ $res = @$this->conn->connect($host, $user, $paswd, $db, $port);
87
+ if(0 !== mysqli_connect_errno($this->conn)) {
88
+ throw new Mage_DB_Exception(mysqli_connect_error($this->conn));
89
+ }
90
+ return $res;
91
+ }
92
+
93
+ /**
94
+ * Select database
95
+ * @param $db db name
96
+ * @return mixed
97
+ */
98
+ public function selectDb($db)
99
+ {
100
+ $res = mysqli_select_db($this->conn, $db);
101
+ return $res;
102
+ }
103
+
104
+ /**
105
+ * Escape string
106
+ * @param string $str
107
+ * @return string
108
+ */
109
+ public function escapeString($str)
110
+ {
111
+ return mysqli_real_escape_string($this->conn, $str);
112
+ }
113
+
114
+ /**
115
+ * Escape table name
116
+ * @param string $table
117
+ * @return string
118
+ */
119
+ public function escapeTableName($table)
120
+ {
121
+ return self::TABLE_ESCAPER.$this->escapeString($table).self::TABLE_ESCAPER;
122
+ }
123
+
124
+ /**
125
+ * Escape field name
126
+ * @param stirng $fld
127
+ * @return string
128
+ */
129
+ public function escapeFieldName($fld)
130
+ {
131
+ return self::TABLE_ESCAPER.$this->escapeString($fld).self::TABLE_ESCAPER;
132
+ }
133
+
134
+ /**
135
+ * Escape field value
136
+ * @param $data
137
+ * @return string
138
+ */
139
+ public function escapeFieldValue($data)
140
+ {
141
+ return self::VALUE_ESCAPER.$this->escapeString($data).self::VALUE_ESCAPER;
142
+ }
143
+
144
+ /**
145
+ * Fetch all rows
146
+ * @param $sql
147
+ * @return array
148
+ */
149
+ public function fetchAll($sql)
150
+ {
151
+ $res = $this->query($sql);
152
+ for($out = array(); $row = $res->fetch_array($this->fetch_mode); $out[] = $row);
153
+ return $out;
154
+ }
155
+
156
+ /**
157
+ * Fetch one row
158
+ * @param $sql
159
+ * @return array
160
+ */
161
+ public function fetchOne($sql)
162
+ {
163
+ $res = $this->query($sql);
164
+ return $res->fetch_array($this->fetch_mode);
165
+ }
166
+
167
+ /**
168
+ * Fetch rows grouped by key
169
+ * @param $sql
170
+ * @param $key
171
+ * @param $arrayMode force Array mode
172
+ * @return array
173
+ */
174
+ public function fetchGroupedArrayByKey($sql, $key, $arrayMode = true)
175
+ {
176
+ $res = $this->query($sql);
177
+ $out = array();
178
+ while($row = $res->fetch_array(MYSQLI_ASSOC)) {
179
+ if($arrayMode) {
180
+ if(!isset($out[$row[$key]])) {
181
+ $out[$row[$key]] = array();
182
+ }
183
+ $out[$row[$key]][] = $row;
184
+ } else {
185
+ $out[$row[$key]] = $row;
186
+ }
187
+ }
188
+ return $out;
189
+ }
190
+
191
+ /**
192
+ * Fetch one field from all rows and place to list
193
+ * @param string $sql
194
+ * @param string $fld
195
+ * @return array
196
+ */
197
+ public function fetchOneFieldAll($sql, $fld)
198
+ {
199
+ $res = $this->query($sql);
200
+ for($out = array(); $row = $res->fetch_array($this->fetch_mode); $out[] = $row[$fld]);
201
+ return $out;
202
+ }
203
+
204
+ /**
205
+ * List one item
206
+ * @param $table
207
+ * @param $condition
208
+ * @return array
209
+ */
210
+ public function listOne($table, $condition)
211
+ {
212
+ $table = $this->escapeTableName($table);
213
+ $sql = "SELECT * FROM {$table} WHERE {$condition}";
214
+ return $this->fetchOne($sql);
215
+ }
216
+
217
+ /**
218
+ * List items in table by condition
219
+ * @param string $table table name
220
+ * @param string $condition optional, if empty 1=1 is used
221
+ * @return array
222
+ */
223
+ public function listAll($table, $condition = '1=1')
224
+ {
225
+ $table = $this->escapeTableName($table);
226
+ $sql = "SELECT * FROM {$table} WHERE {$condition}";
227
+ return $this->fetchAll($sql);
228
+ }
229
+
230
+ /**
231
+ * List by key single entry
232
+ * @param string $table table name
233
+ * @param string $value field value
234
+ * @param string $key field name
235
+ * @return array
236
+ */
237
+ public function listByKeyOne($table, $value, $key = 'id')
238
+ {
239
+ $table = $this->escapeTableName($table);
240
+ $key = $this->escapeFieldName($key);
241
+ $value = $this->escapeFieldValue($value);
242
+ $sql = "SELECT * FROM {$table} WHERE {$key} = {$value}";
243
+ return $this->fetchOne($sql);
244
+ }
245
+
246
+ /**
247
+ * List by key all rows in table
248
+ * @param string $table table name
249
+ * @param string $value value of key field
250
+ * @param string $key key field name
251
+ * @param string $add additional conditions
252
+ * @return array
253
+ */
254
+ public function listByKeyAll($table, $value, $key = 'id', $add = '')
255
+ {
256
+ $table = $this->escapeTableName($table);
257
+ $key = $this->escapeFieldName($key);
258
+ $value = $this->escapeFieldValue($value);
259
+ $sql = "SELECT * FROM {$table} WHERE {$key} = {$value} {$add}";
260
+ return $this->fetchAll($sql);
261
+ }
262
+
263
+ /**
264
+ * List by key grouped
265
+ * @param string $table
266
+ * @param string $key
267
+ * @param bool $forcedArrayMode
268
+ * @return array
269
+ */
270
+ public function listByKeyGrouped($table, $key = 'id', $forcedArrayMode = false)
271
+ {
272
+ $table = $this->escapeTableName($table);
273
+ $sql = "SELECT * FROM {$table}";
274
+ return $this->fetchGroupedArrayByKey($sql, $key, $forcedArrayMode);
275
+ }
276
+
277
+
278
+ /**
279
+ * Escape field names
280
+ * @param array $arrNames
281
+ * @return array
282
+ */
283
+ public function escapeFieldNames(array $arrNames)
284
+ {
285
+ $out = array();
286
+ for ($i=0, $c = count($arrNames) ; $i<$c; $i++) {
287
+ $out[] = $this->escapeFieldName($arrNames[$i]);
288
+ }
289
+ return $out;
290
+ }
291
+
292
+ /**
293
+ * Escape field values
294
+ * @param array $arrNames
295
+ * @return array
296
+ */
297
+ public function escapeFieldValues(array $arrNames)
298
+ {
299
+ $out = array();
300
+ for ($i=0, $c = count($arrNames) ; $i<$c; $i++) {
301
+ if($arrNames[$i] !== 'LAST_INSERT_ID()') {
302
+ $out[] = $this->escapeFieldValue($arrNames[$i]);
303
+ } else {
304
+ $out[] = $arrNames[$i];
305
+ }
306
+ }
307
+ return $out;
308
+ }
309
+
310
+
311
+ /**
312
+ * Throw connect exception
313
+ * @throws Mage_DB_Exception
314
+ * @return void
315
+ */
316
+ protected function throwConnectException()
317
+ {
318
+ throw new Mage_DB_Exception($this->conn->connect_error);
319
+ }
320
+
321
+ /**
322
+ * Query - perform with throwing exception on error
323
+ * @param sting $sql query
324
+ * @throws Mage_DB_Exception
325
+ * @return mixed
326
+ */
327
+ public function query($sql)
328
+ {
329
+ $res = $this->unsafeQuery($sql);
330
+ if(!$res) {
331
+ throw new Mage_DB_Exception($this->conn->error);
332
+ }
333
+ return $res;
334
+ }
335
+
336
+ /**
337
+ * Unsafe query - perform without error checking
338
+ * @param string $sql query
339
+ * @return mixed
340
+ */
341
+ public function unsafeQuery($sql)
342
+ {
343
+ return $this->conn->query($sql);
344
+ }
345
+
346
+ /**
347
+ * Insert assoc array to table
348
+ * @param string $table
349
+ * @param array $data
350
+ * @param bool $replace
351
+ * @return mixed
352
+ */
353
+ public function insertAssocOne($table, array $data, $replace = false) {
354
+ $keys = $this->escapeFieldNames(array_keys($data));
355
+ $keys = "(" . implode (",", $keys) . ")";
356
+ $table = $this->escapeTableName($table);
357
+ $sql = $replace ? "REPLACE INTO {$table} " : "INSERT INTO {$table} ";
358
+ $values = $this->escapeFieldValues(array_values($data));
359
+ $values = " VALUES (" . implode (",", $values) . ")";
360
+ $sql .= $keys . $values;
361
+ return $this->query($sql);
362
+ }
363
+
364
+ /**
365
+ * Insert several records to table
366
+ * @param string $table
367
+ * @param array $data
368
+ * @param bool $replace use REPLACE INTO instead of INSERT INTO
369
+ * @return array
370
+ */
371
+ public function insertAssocMultiple($table, array $data, $replace = false, $excludeFields = array())
372
+ {
373
+ $table = $this->escapeTableName($table);
374
+ $sql = $replace ? "REPLACE INTO {$table} " : "INSERT INTO {$table} ";
375
+ $keys = array_keys($data[0]);
376
+ $excluded = array();
377
+ for($i = 0, $c = count($excludeFields); $i < $c; $i++) {
378
+ $k = $excludeFields[$i];
379
+ if(isset($keys[$k])) {
380
+ $excluded [] = $k;
381
+ unset($keys[$k]);
382
+ }
383
+ }
384
+
385
+ $keys = $this->escapeFieldNames($keys);
386
+ $sql .= " ( ";
387
+ for($i = 0, $c = count($keys); $i<$c; $i++) {
388
+ $sql .= $keys[$i];
389
+ if($i!=$c-1) {
390
+ $sql .= ",";
391
+ }
392
+ }
393
+ $sql .= " ) VALUES ";
394
+ for($i = 0, $c = count($data); $i<$c; $i++) {
395
+ $row = $data[$i];
396
+ for ($j = 0, $jc = count($excluded); $j<$jc; $j++) {
397
+ unset($data[$excluded[$j]]);
398
+ }
399
+ $values = $this->escapeFieldValues(array_values($row));
400
+ $sql .= "( ";
401
+ for ($j = 0, $jc = count($values); $j < $jc; $j++) {
402
+ $sql .= $values[$j];
403
+ if($j != $jc-1) {
404
+ $sql .= ",";
405
+ }
406
+ }
407
+ $sql .= " )";
408
+ if($i!=$c-1) {
409
+ $sql .= ",";
410
+ }
411
+ }
412
+ return $this->query($sql);
413
+ }
414
+
415
+
416
+ /**
417
+ * Set table data by condition
418
+ * @param $table
419
+ * @param $data
420
+ * @param $condition
421
+ * @return mixed
422
+ */
423
+ public function updateAssoc($table, array $data, $condition = '1=1')
424
+ {
425
+ $table = $this->escapeTableName($table);
426
+ $set = array();
427
+ foreach($data as $k=>$v) {
428
+ $k = $this->escapeFieldName($k);
429
+ $v = $this->escapeFieldValue($v);
430
+ $set[] = $k . " = " . $v;
431
+ }
432
+ $set = implode(",", $set);
433
+ $sql = "UPDATE {$table} SET {$set} WHERE {$condition}";
434
+ return $this->query($sql);
435
+ }
436
+
437
+
438
+ /**
439
+ * Update entry by pk
440
+ * @param string $table
441
+ * @param array $data
442
+ * @param string $value
443
+ * @param string $key
444
+ * @return mixed
445
+ */
446
+ public function updateAssocByKey($table, array $data, $value, $key = 'id')
447
+ {
448
+ $table = $this->escapeTableName($table);
449
+ $key = $this->escapeFieldName($key);
450
+ $value = $this->escapeFieldValue($value);
451
+ $set = array();
452
+ foreach($data as $k=>$v) {
453
+ $k = $this->escapeFieldName($k);
454
+ $v = $this->escapeFieldValue($v);
455
+ $set[] = $k . " = " . $v;
456
+ }
457
+ $set = implode(",", $set);
458
+ $sql = "UPDATE {$table} SET {$set} WHERE {$key} = {$value}";
459
+ return $this->query($sql);
460
+ }
461
+
462
+
463
+ /**
464
+ * Convert ids to string
465
+ * @param array|string $ids
466
+ * @return string
467
+ */
468
+ public function idsToString($ids)
469
+ {
470
+ if(is_scalar($ids)) {
471
+ return $this->escapeFieldValue(strval($ids));
472
+ }
473
+ $out = array();
474
+ foreach ($values as $id) {
475
+ $out .= $this->escapeFieldValue($id);
476
+ }
477
+ return implode(",", $out);
478
+ }
479
+
480
+ /**
481
+ * Ids equality condition
482
+ * @param mixed $ids array or string
483
+ * @return string
484
+ */
485
+ public function idsEqualCondition($ids)
486
+ {
487
+ $vals = $this->idsToString($ids);
488
+ $condition = is_scalar($ids) ? " = {$vals} " : " IN ({$vals}) ";
489
+ return $condition;
490
+ }
491
+
492
+
493
+ /**
494
+ * Delete items by id
495
+ * @param string $table
496
+ * @param mixed $ids array or string
497
+ * @param string $key key field
498
+ * @return mixed
499
+ */
500
+ public function deleteById($table, $ids, $key = 'id')
501
+ {
502
+ $key = $this->escapeFieldName($key);
503
+ $cond = $this->idsEqualCondition($ids);
504
+ $table = $this->escapeTableName($table);
505
+ $sql = "DELETE FROM {$table} WHERE {$key} {$cond}";
506
+ return $this->query($sql);
507
+ }
508
+
509
+ /**
510
+ * Count items in table by condition
511
+ * @param string $table
512
+ * @param string $condition ex: "a>0"
513
+ * @return int
514
+ */
515
+ public function simpleCount($table, $condition) {
516
+ $sql = "SELECT count(*) AS `cnt` WHERE {$condition}";
517
+ $data = $this->fetchOne($sql);
518
+ if(empty($data['cnt'])) {
519
+ return 0;
520
+ }
521
+ return intval($data['cnt']);
522
+
523
+ }
524
+
525
+ public function lastInsertId()
526
+ {
527
+ $sql = "SELECT LAST_INSERT_ID() as `id`";
528
+ $data = $this->fetchOne($sql);
529
+ return $data['id'];
530
+ }
531
+
532
+ }
app/code/local/Mss/downloader/lib/Mage/Exception.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Exception
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class for Exception
29
+ *
30
+ * @category Mage
31
+ * @package Mage
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_Exception extends Exception
35
+ {}
app/code/local/Mss/downloader/lib/Mage/HTTP/Client.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_HTTP
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Factory for HTTP client classes
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_HTTP_Client
35
+ {
36
+ /**
37
+ * Disallow to instantiate - pvt constructor
38
+ */
39
+ private function __construct()
40
+ {
41
+
42
+ }
43
+
44
+ /**
45
+ * Factory for HTTP client
46
+ *
47
+ * @static
48
+ * @throws Exception
49
+ * @param string|bool $frontend 'curl'/'socket' or false for auto-detect
50
+ * @return Mage_HTTP_IClient
51
+ */
52
+ public static function getInstance($frontend = false)
53
+ {
54
+ if (false === $frontend) {
55
+ $frontend = self::detectFrontend();
56
+ }
57
+ if (false === $frontend) {
58
+ throw new Exception("Cannot find frontend automatically, set it manually");
59
+ }
60
+
61
+ $class = __CLASS__ . "_" . str_replace(' ', DIRECTORY_SEPARATOR, ucwords(str_replace('_', ' ', $frontend)));
62
+ $obj = new $class();
63
+ return $obj;
64
+ }
65
+
66
+ /**
67
+ * Detects frontend type.
68
+ * Priority is given to CURL
69
+ *
70
+ * @return string/bool
71
+ */
72
+ protected static function detectFrontend()
73
+ {
74
+ if (function_exists("curl_init")) {
75
+ return "curl";
76
+ }
77
+ if (function_exists("fsockopen")) {
78
+ return "socket";
79
+ }
80
+ return false;
81
+ }
82
+ }
app/code/local/Mss/downloader/lib/Mage/HTTP/Client/Curl.php ADDED
@@ -0,0 +1,576 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_HTTP
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with HTTP protocol using curl library
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_HTTP_Client_Curl
35
+ implements Mage_HTTP_IClient
36
+ {
37
+ /**
38
+ * Session Cookie storage, magento_root/var directory used
39
+ * @var string
40
+ */
41
+ const COOKIE_FILE = 'var/cookie';
42
+
43
+ /**
44
+ * Hostname
45
+ * @var string
46
+ */
47
+ protected $_host = 'localhost';
48
+
49
+ /**
50
+ * Port
51
+ * @var int
52
+ */
53
+ protected $_port = 80;
54
+
55
+ /**
56
+ * Stream resource
57
+ * @var object
58
+ */
59
+ protected $_sock = null;
60
+
61
+ /**
62
+ * Request headers
63
+ * @var array
64
+ */
65
+ protected $_headers = array();
66
+
67
+
68
+ /**
69
+ * Fields for POST method - hash
70
+ * @var array
71
+ */
72
+ protected $_postFields = array();
73
+
74
+ /**
75
+ * Request cookies
76
+ * @var array
77
+ */
78
+ protected $_cookies = array();
79
+
80
+ /**
81
+ * Response headers
82
+ * @var array
83
+ */
84
+ protected $_responseHeaders = array();
85
+
86
+ /**
87
+ * Response body
88
+ * @var string
89
+ */
90
+ protected $_responseBody = '';
91
+
92
+ /**
93
+ * Response status
94
+ * @var int
95
+ */
96
+ protected $_responseStatus = 0;
97
+
98
+
99
+ /**
100
+ * Request timeout
101
+ * @var intunknown_type
102
+ */
103
+ protected $_timeout = 300;
104
+
105
+ /**
106
+ * TODO
107
+ * @var int
108
+ */
109
+ protected $_redirectCount = 0;
110
+
111
+ /**
112
+ * Curl
113
+ * @var object
114
+ */
115
+ protected $_ch;
116
+
117
+
118
+ /**
119
+ * User ovverides options hash
120
+ * Are applied before curl_exec
121
+ *
122
+ * @var array();
123
+ */
124
+ protected $_curlUserOptions = array();
125
+
126
+ /**
127
+ * User credentials
128
+ *
129
+ * @var array();
130
+ */
131
+ protected $_auth = array();
132
+
133
+ /**
134
+ * Set request timeout, msec
135
+ *
136
+ * @param int $value
137
+ */
138
+ public function setTimeout($value)
139
+ {
140
+ $this->_timeout = (int) $value;
141
+ }
142
+
143
+ /**
144
+ * Constructor
145
+ */
146
+ public function __construct()
147
+ {
148
+
149
+ }
150
+
151
+ /**
152
+ * Destructor
153
+ * Removes temporary environment
154
+ */
155
+ public function __destruct()
156
+ {
157
+ if (is_file(self::COOKIE_FILE)) {
158
+ @unlink(self::COOKIE_FILE);
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Set headers from hash
164
+
165
+ * @param array $headers
166
+ */
167
+ public function setHeaders($headers)
168
+ {
169
+ $this->_headers = $headers;
170
+
171
+ }
172
+
173
+ /**
174
+ * Add header
175
+ *
176
+ * @param $name name, ex. "Location"
177
+ * @param $value value ex. "http://google.com"
178
+ */
179
+ public function addHeader($name, $value)
180
+ {
181
+ $this->_headers[$name] = $value;
182
+ }
183
+
184
+ /**
185
+ * Remove specified header
186
+ *
187
+ * @param string $name
188
+ */
189
+ public function removeHeader($name)
190
+ {
191
+ unset($this->_headers[$name]);
192
+
193
+ }
194
+
195
+ /**
196
+ * Authorization: Basic header
197
+ * Login credentials support
198
+ *
199
+ * @param string $login username
200
+ * @param string $pass password
201
+ */
202
+ public function setCredentials($login, $pass)
203
+ {
204
+ $this->_auth['login'] = $login;
205
+ $this->_auth['password'] = $pass;
206
+ //$val= base64_encode( "$login:$pass" );
207
+ //$this->addHeader( "Authorization", "Basic $val" );
208
+ }
209
+
210
+ /**
211
+ * Add cookie
212
+ *
213
+ * @param string $name
214
+ * @param string $value
215
+ */
216
+ public function addCookie($name, $value)
217
+ {
218
+ $this->_cookies[$name] = $value;
219
+ }
220
+
221
+ /**
222
+ * Remove cookie
223
+ *
224
+ * @param string $name
225
+ */
226
+ public function removeCookie($name)
227
+ {
228
+ unset($this->_cookies[$name]);
229
+ }
230
+
231
+ /**
232
+ * Set cookies array
233
+ *
234
+ * @param array $cookies
235
+ */
236
+ public function setCookies($cookies)
237
+ {
238
+ $this->_cookies = $cookies;
239
+ }
240
+
241
+ /**
242
+ * Clear cookies
243
+ */
244
+ public function removeCookies()
245
+ {
246
+ $this->setCookies(array());
247
+ }
248
+
249
+
250
+ /**
251
+ * Make GET request
252
+ *
253
+ * @param string $uri uri relative to host, ex. "/index.php"
254
+ */
255
+ public function get($uri)
256
+ {
257
+ $this->makeRequest("GET", $uri);
258
+ }
259
+
260
+ /**
261
+ * Make POST request
262
+ * @see lib/Mage/HTTP/Mage_HTTP_Client#post($uri, $params)
263
+ */
264
+ public function post($uri, $params)
265
+ {
266
+ $this->makeRequest("POST", $uri, $params);
267
+ }
268
+
269
+
270
+ /**
271
+ * Get response headers
272
+ *
273
+ * @return array
274
+ */
275
+ public function getHeaders()
276
+ {
277
+ return $this->_responseHeaders;
278
+ }
279
+
280
+
281
+ /**
282
+ * Get response body
283
+ *
284
+ * @return string
285
+ */
286
+ public function getBody()
287
+ {
288
+ return $this->_responseBody;
289
+ }
290
+
291
+ /**
292
+ * Get cookies response hash
293
+ *
294
+ * @return array
295
+ */
296
+ public function getCookies()
297
+ {
298
+ if(empty($this->_responseHeaders['Set-Cookie'])) {
299
+ return array();
300
+ }
301
+ $out = array();
302
+ foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
303
+ $values = explode("; ", $row);
304
+ $c = count($values);
305
+ if(!$c) {
306
+ continue;
307
+ }
308
+ list($key, $val) = explode("=", $values[0]);
309
+ if(is_null($val)) {
310
+ continue;
311
+ }
312
+ $out[trim($key)] = trim($val);
313
+ }
314
+ return $out;
315
+ }
316
+
317
+
318
+ /**
319
+ * Get cookies array with details
320
+ * (domain, expire time etc)
321
+ * @return array
322
+ */
323
+ public function getCookiesFull()
324
+ {
325
+ if(empty($this->_responseHeaders['Set-Cookie'])) {
326
+ return array();
327
+ }
328
+ $out = array();
329
+ foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
330
+ $values = explode("; ", $row);
331
+ $c = count($values);
332
+ if(!$c) {
333
+ continue;
334
+ }
335
+ list($key, $val) = explode("=", $values[0]);
336
+ if(is_null($val)) {
337
+ continue;
338
+ }
339
+ $out[trim($key)] = array('value'=>trim($val));
340
+ array_shift($values);
341
+ $c--;
342
+ if(!$c) {
343
+ continue;
344
+ }
345
+ for($i = 0; $i<$c; $i++) {
346
+ list($subkey, $val) = explode("=", $values[$i]);
347
+ $out[trim($key)][trim($subkey)] = trim($val);
348
+ }
349
+ }
350
+ return $out;
351
+ }
352
+
353
+ /**
354
+ * Get response status code
355
+ * @see lib/Mage/HTTP/Mage_HTTP_Client#getStatus()
356
+ */
357
+ public function getStatus()
358
+ {
359
+ return $this->_responseStatus;
360
+ }
361
+
362
+ /**
363
+ * Make request
364
+ *
365
+ * @param string $method
366
+ * @param string $uri
367
+ * @param array $params
368
+ * @param boolean $isAuthorizationRequired
369
+ * @param boolean $https
370
+ */
371
+ protected function makeRequest($method, $uri, $params = array(), $isAuthorizationRequired = false, $https = true)
372
+ {
373
+ $uriModified = $this->getModifiedUri($uri, $https);
374
+ $this->_ch = curl_init();
375
+ $this->curlOption(CURLOPT_URL, $uriModified);
376
+ $this->curlOption(CURLOPT_SSL_VERIFYPEER, false);
377
+ $this->curlOption(CURLOPT_SSL_CIPHER_LIST, 'TLSv1');
378
+ $this->getCurlMethodSettings($method, $params, $isAuthorizationRequired);
379
+
380
+ if(count($this->_headers)) {
381
+ $heads = array();
382
+ foreach($this->_headers as $k=>$v) {
383
+ $heads[] = $k.': '.$v;
384
+ }
385
+ $this->curlOption(CURLOPT_HTTPHEADER, $heads);
386
+ }
387
+
388
+ if(count($this->_cookies)) {
389
+ $cookies = array();
390
+ foreach($this->_cookies as $k=>$v) {
391
+ $cookies[] = "$k=$v";
392
+ }
393
+ $this->curlOption(CURLOPT_COOKIE, implode(";", $cookies));
394
+ }
395
+
396
+ if($this->_timeout) {
397
+ $this->curlOption(CURLOPT_TIMEOUT, $this->_timeout);
398
+ }
399
+
400
+ if($this->_port != 80) {
401
+ $this->curlOption(CURLOPT_PORT, $this->_port);
402
+ }
403
+
404
+ $this->curlOption(CURLOPT_RETURNTRANSFER, 1);
405
+ $this->curlOption(CURLOPT_FOLLOWLOCATION, 1);
406
+ $this->curlOption(CURLOPT_HEADERFUNCTION, array($this,'parseHeaders'));
407
+
408
+ if(count($this->_curlUserOptions)) {
409
+ foreach($this->_curlUserOptions as $k=>$v) {
410
+ $this->curlOption($k, $v);
411
+ }
412
+ }
413
+
414
+ $this->_responseHeaders = array();
415
+ $this->_responseBody = curl_exec($this->_ch);
416
+ $err = curl_errno($this->_ch);
417
+ if($err) {
418
+ $this->doError(curl_error($this->_ch));
419
+ }
420
+ if(!$this->getStatus()) {
421
+ $this->doError("Invalid response headers returned from server.");
422
+ return;
423
+ }
424
+
425
+ curl_close($this->_ch);
426
+
427
+ if (403 == $this->getStatus()) {
428
+ if (!$isAuthorizationRequired && $https) {
429
+ $this->makeRequest('POST', $uri, $params, true, false);
430
+ } else if ($isAuthorizationRequired && !$https) {
431
+ $this->makeRequest('POST', $uri, $params, true, true);
432
+ } else {
433
+ $this->doError(sprintf('Access denied for %s@%s', $_SESSION['auth']['login'], $uriModified));
434
+ return;
435
+ }
436
+ } elseif (405 == $this->getStatus()) {
437
+ $this->doError("HTTP Error 405 Method not allowed");
438
+ return;
439
+ }
440
+ }
441
+
442
+ /**
443
+ * @throws Exception
444
+ */
445
+ public function isAuthorizationRequired()
446
+ {
447
+ if (isset($_SESSION['auth']['username']) && isset($_SESSION['auth']['password'])
448
+ && !empty($_SESSION['auth']['username']))
449
+ {
450
+ return true;
451
+ }
452
+ return false;
453
+ }
454
+
455
+ /**
456
+ * Throw error excpetion
457
+ * @param $string
458
+ * @throws Exception
459
+ */
460
+ public function doError($string)
461
+ {
462
+ throw new Exception($string);
463
+ }
464
+
465
+
466
+ /**
467
+ * Parse headers - CURL callback functin
468
+ *
469
+ * @param resource $ch curl handle, not needed
470
+ * @param string $data
471
+ * @return int
472
+ */
473
+ protected function parseHeaders($ch, $data)
474
+ {
475
+ if(preg_match('/^HTTP\/[\d\.x]+ (\d+)/', $data, $m)) {
476
+ if (isset($m[1])) {
477
+ $this->_responseStatus = (int)$m[1];
478
+ }
479
+ } else {
480
+ $name = $value = '';
481
+ $out = explode(": ", trim($data), 2);
482
+ if(count($out) == 2) {
483
+ $name = $out[0];
484
+ $value = $out[1];
485
+ }
486
+
487
+ if(strlen($name)) {
488
+ if("Set-Cookie" == $name) {
489
+ if(!isset($this->_responseHeaders[$name])) {
490
+ $this->_responseHeaders[$name] = array();
491
+ }
492
+ $this->_responseHeaders[$name][] = $value;
493
+ } else {
494
+ $this->_responseHeaders[$name] = $value;
495
+ }
496
+ }
497
+ }
498
+
499
+ return strlen($data);
500
+ }
501
+
502
+ /**
503
+ * Set curl option directly
504
+ *
505
+ * @param string $name
506
+ * @param string $value
507
+ */
508
+ protected function curlOption($name, $value)
509
+ {
510
+ curl_setopt($this->_ch, $name, $value);
511
+ }
512
+
513
+ /**
514
+ * Set curl options array directly
515
+ * @param array $array
516
+ */
517
+ protected function curlOptions($array)
518
+ {
519
+ curl_setopt_array($this->_ch, $arr);
520
+ }
521
+
522
+ /**
523
+ * Set CURL options ovverides array
524
+ */
525
+ public function setOptions($arr)
526
+ {
527
+ $this->_curlUserOptions = $arr;
528
+ }
529
+
530
+ /**
531
+ * Set curl option
532
+ */
533
+ public function setOption($name, $value)
534
+ {
535
+ $this->_curlUserOptions[$name] = $value;
536
+ }
537
+
538
+ /**
539
+ * Build secure url
540
+ *
541
+ * @param string $uri
542
+ * @param boolean $https
543
+ * @return string
544
+ */
545
+ protected function getModifiedUri($uri, $https = true)
546
+ {
547
+ if ($https && strpos($uri, 'https://') !== 0) {
548
+ $uri = str_replace('http://', '', $uri);
549
+ $uri = 'https://' . $uri;
550
+ }
551
+ return $uri;
552
+ }
553
+
554
+ /**
555
+ * @param $method
556
+ * @param $params
557
+ * @param $isAuthorizationRequired
558
+ */
559
+ protected function getCurlMethodSettings($method, $params, $isAuthorizationRequired)
560
+ {
561
+ if ($method == 'POST' || $isAuthorizationRequired) {
562
+ $this->curlOption(CURLOPT_POST, 1);
563
+ $postFields = is_array($params) ? $params : array();
564
+ if ($isAuthorizationRequired) {
565
+ $this->curlOption(CURLOPT_COOKIEJAR, self::COOKIE_FILE);
566
+ $this->curlOption(CURLOPT_COOKIEFILE, self::COOKIE_FILE);
567
+ $postFields = array_merge($postFields, $this->_auth);
568
+ }
569
+ $this->curlOption(CURLOPT_POSTFIELDS, $postFields);
570
+ } elseif ($method == "GET") {
571
+ $this->curlOption(CURLOPT_HTTPGET, 1);
572
+ } else {
573
+ $this->curlOption(CURLOPT_CUSTOMREQUEST, $method);
574
+ }
575
+ }
576
+ }
app/code/local/Mss/downloader/lib/Mage/HTTP/Client/Socket.php ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_HTTP
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with HTTP protocol using sockets
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_HTTP_Client_Socket
35
+ implements Mage_HTTP_IClient
36
+ {
37
+ /**
38
+ * Hostname
39
+ * @var string
40
+ */
41
+ private $_host = 'localhost';
42
+
43
+ /**
44
+ * Port
45
+ * @var int
46
+ */
47
+ private $_port = 80;
48
+
49
+ /**
50
+ * Stream resource
51
+ * @var object
52
+ */
53
+ private $_sock = null;
54
+
55
+ /**
56
+ * Request headers
57
+ * @var array
58
+ */
59
+ private $_headers = array();
60
+
61
+
62
+ /**
63
+ * Fields for POST method - hash
64
+ * @var array
65
+ */
66
+ private $_postFields = array();
67
+
68
+ /**
69
+ * Request cookies
70
+ * @var array
71
+ */
72
+ private $_cookies = array();
73
+
74
+ /**
75
+ * Response headers
76
+ * @var array
77
+ */
78
+ private $_responseHeaders = array();
79
+
80
+ /**
81
+ * Response body
82
+ * @var string
83
+ */
84
+ private $_responseBody = '';
85
+
86
+ /**
87
+ * Response status
88
+ * @var int
89
+ */
90
+ private $_responseStatus = 0;
91
+
92
+
93
+ /**
94
+ * Request timeout
95
+ * @var int
96
+ */
97
+ private $_timeout = 300;
98
+
99
+ /**
100
+ * TODO
101
+ * @var int
102
+ */
103
+ private $_redirectCount = 0;
104
+
105
+
106
+ /**
107
+ * Set request timeout, msec
108
+ *
109
+ * @param int $value
110
+ */
111
+ public function setTimeout($value)
112
+ {
113
+ $this->_timeout = (int) $value;
114
+ }
115
+
116
+ /**
117
+ * Constructor
118
+ * @param string $host
119
+ * @param int $port
120
+ */
121
+ public function __construct($host = null, $port = 80)
122
+ {
123
+ if($host) {
124
+ $this->connect($host, (int) $port);
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Set connection params
130
+ *
131
+ * @param string $host
132
+ * @param int $port
133
+ */
134
+ public function connect($host, $port = 80)
135
+ {
136
+ $this->_host = $host;
137
+ $this->_port = (int) $port;
138
+
139
+ }
140
+
141
+ /**
142
+ * Disconnect
143
+ */
144
+ public function disconnect()
145
+ {
146
+ @fclose($this->_sock);
147
+ }
148
+
149
+ /**
150
+ * Set headers from hash
151
+
152
+ * @param array $headers
153
+ */
154
+ public function setHeaders($headers)
155
+ {
156
+ $this->_headers = $headers;
157
+
158
+ }
159
+
160
+ /**
161
+ * Add header
162
+ *
163
+ * @param $name name, ex. "Location"
164
+ * @param $value value ex. "http://google.com"
165
+ */
166
+ public function addHeader($name, $value)
167
+ {
168
+ $this->_headers[$name] = $value;
169
+
170
+ }
171
+
172
+ /**
173
+ * Remove specified header
174
+ *
175
+ * @param string $name
176
+ */
177
+ public function removeHeader($name)
178
+ {
179
+ unset($this->_headers[$name]);
180
+
181
+ }
182
+
183
+ /**
184
+ * Authorization: Basic header
185
+ * Login credentials support
186
+ *
187
+ * @param string $login username
188
+ * @param string $pass password
189
+ */
190
+ public function setCredentials($login, $pass)
191
+ {
192
+ $val= base64_encode( "$login:$pass" );
193
+ $this->addHeader( "Authorization", "Basic $val" );
194
+ }
195
+
196
+ /**
197
+ * Add cookie
198
+ *
199
+ * @param string $name
200
+ * @param string $value
201
+ */
202
+ public function addCookie($name, $value)
203
+ {
204
+ $this->_cookies[$name] = $value;
205
+ }
206
+
207
+ /**
208
+ * Remove cookie
209
+ *
210
+ * @param string $name
211
+ */
212
+ public function removeCookie($name)
213
+ {
214
+ unset($this->_cookies[$name]);
215
+ }
216
+
217
+ /**
218
+ * Set cookies array
219
+ *
220
+ * @param array $cookies
221
+ */
222
+ public function setCookies($cookies)
223
+ {
224
+ $this->_cookies = $cookies;
225
+ }
226
+
227
+ /**
228
+ * Clear cookies
229
+ */
230
+ public function removeCookies()
231
+ {
232
+ $this->setCookies(array());
233
+ }
234
+
235
+
236
+ /**
237
+ * Make GET request
238
+ *
239
+ * @param string $uri full uri path
240
+ */
241
+ public function get($uri)
242
+ {
243
+ $this->makeRequest("GET",$this->parseUrl($uri));
244
+ }
245
+
246
+ /**
247
+ * Set host, port from full url
248
+ * and return relative url
249
+ *
250
+ * @param string $uri ex. http://google.com/index.php?a=b
251
+ * @return string ex. /index.php?a=b
252
+ */
253
+ protected function parseUrl($uri)
254
+ {
255
+ $parts = parse_url($uri);
256
+ if(!empty($parts['user']) && !empty($parts['pass'])) {
257
+ $this->setCredentials($parts['user'], $parts['pass']);
258
+ }
259
+ if(!empty($parts['port'])) {
260
+ $this->_port = (int) $parts['port'];
261
+ }
262
+
263
+ if(!empty($parts['host'])) {
264
+ $this->_host = $parts['host'];
265
+ } else {
266
+ throw new InvalidArgumentException("Uri doesn't contain host part");
267
+ }
268
+
269
+
270
+ if(!empty($parts['path'])) {
271
+ $requestUri = $parts['path'];
272
+ } else {
273
+ throw new InvalidArgumentException("Uri doesn't contain path part");
274
+ }
275
+ if(!empty($parts['query'])) {
276
+ $requestUri .= "?".$parts['query'];
277
+ }
278
+ return $requestUri;
279
+ }
280
+
281
+ /**
282
+ * Make POST request
283
+ */
284
+ public function post($uri, $params)
285
+ {
286
+ $this->makeRequest("POST", $this->parseUrl($uri), $params);
287
+ }
288
+
289
+
290
+ /**
291
+ * Get response headers
292
+ *
293
+ * @return array
294
+ */
295
+ public function getHeaders()
296
+ {
297
+ return $this->_responseHeaders;
298
+ }
299
+
300
+
301
+ /**
302
+ * Get response body
303
+ *
304
+ * @return string
305
+ */
306
+ public function getBody()
307
+ {
308
+ return $this->_responseBody;
309
+ }
310
+
311
+ /**
312
+ * Get cookies response hash
313
+ *
314
+ * @return array
315
+ */
316
+ public function getCookies()
317
+ {
318
+ if(empty($this->_responseHeaders['Set-Cookie'])) {
319
+ return array();
320
+ }
321
+ $out = array();
322
+ foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
323
+ $values = explode("; ", $row);
324
+ $c = count($values);
325
+ if(!$c) {
326
+ continue;
327
+ }
328
+ list($key, $val) = explode("=", $values[0]);
329
+ if(is_null($val)) {
330
+ continue;
331
+ }
332
+ $out[trim($key)] = trim($val);
333
+ }
334
+ return $out;
335
+ }
336
+
337
+
338
+ /**
339
+ * Get cookies array with details
340
+ * (domain, expire time etc)
341
+ * @return array
342
+ */
343
+ public function getCookiesFull()
344
+ {
345
+ if(empty($this->_responseHeaders['Set-Cookie'])) {
346
+ return array();
347
+ }
348
+ $out = array();
349
+ foreach( $this->_responseHeaders['Set-Cookie'] as $row) {
350
+ $values = explode("; ", $row);
351
+ $c = count($values);
352
+ if(!$c) {
353
+ continue;
354
+ }
355
+ list($key, $val) = explode("=", $values[0]);
356
+ if(is_null($val)) {
357
+ continue;
358
+ }
359
+ $out[trim($key)] = array('value'=>trim($val));
360
+ array_shift($values);
361
+ $c--;
362
+ if(!$c) {
363
+ continue;
364
+ }
365
+ for($i = 0; $i<$c; $i++) {
366
+ list($subkey, $val) = explode("=", $values[$i]);
367
+ $out[trim($key)][trim($subkey)] = trim($val);
368
+ }
369
+ }
370
+ return $out;
371
+ }
372
+
373
+ /**
374
+ * Process response headers
375
+ */
376
+ protected function processResponseHeaders()
377
+ {
378
+ $crlf = "\r\n";
379
+ $this->_responseHeaders = array();
380
+ while (!feof($this->_sock)) {
381
+ $line = fgets($this->_sock, 1024);
382
+ if($line === $crlf) {
383
+ return;
384
+ }
385
+ $name = $value = '';
386
+ $out = explode(": ", trim($line), 2);
387
+ if(count($out) == 2) {
388
+ $name = $out[0];
389
+ $value = $out[1];
390
+ }
391
+ if(!empty($value)) {
392
+ if($name == "Set-Cookie") {
393
+ if(!isset($this->_responseHeaders[$name])) {
394
+ $this->_responseHeaders[$name] = array();
395
+ }
396
+ $this->_responseHeaders[$name][] = $value;
397
+ } else {
398
+ $this->_responseHeaders[$name] = $value;
399
+ }
400
+ }
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Process response body
406
+ */
407
+ protected function processResponseBody()
408
+ {
409
+ $this->_responseBody = '';
410
+
411
+ while (!feof($this->_sock)) {
412
+ $this->_responseBody .= @fread($this->_sock, 1024);
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Process response
418
+ */
419
+ protected function processResponse()
420
+ {
421
+ $response = '';
422
+ $responseLine = trim(fgets($this->_sock, 1024));
423
+
424
+ $line = explode(" ", $responseLine, 3);
425
+ if(count($line) != 3) {
426
+ return $this->doError("Invalid response line returned from server: ".$responseLine);
427
+ }
428
+ $this->_responseStatus = intval($line[1]);
429
+ $this->processResponseHeaders();
430
+
431
+ $this->processRedirect();
432
+
433
+ $this->processResponseBody();
434
+ }
435
+
436
+
437
+ /**
438
+ * Process redirect
439
+ */
440
+ protected function processRedirect()
441
+ {
442
+ // TODO: implement redircets support
443
+ }
444
+
445
+
446
+ /**
447
+ * Get response status code
448
+ * @see lib/Mage/HTTP/Mage_HTTP_Client#getStatus()
449
+ */
450
+ public function getStatus()
451
+ {
452
+ return $this->_responseStatus;
453
+ }
454
+
455
+ /**
456
+ * Make request
457
+ * @param string $method
458
+ * @param string $uri
459
+ * @param array $params
460
+ * @return null
461
+ */
462
+ protected function makeRequest($method, $uri, $params = array())
463
+ {
464
+ $errno = $errstr = '';
465
+ $this->_sock = @fsockopen($this->_host, $this->_port, $errno, $errstr, $this->_timeout);
466
+ if(!$this->_sock) {
467
+ return $this->doError(sprintf("[errno: %d] %s", $errno, $errstr));
468
+ }
469
+
470
+ $crlf = "\r\n";
471
+ $isPost = $method == "POST";
472
+
473
+ $appendHeaders = array();
474
+ $paramsStr = false;
475
+ if($isPost && count($params)) {
476
+ $paramsStr = http_build_query($params);
477
+ $appendHeaders['Content-type'] = 'application/x-www-form-urlencoded';
478
+ $appendHeaders['Content-length'] = strlen($paramsStr);
479
+ }
480
+
481
+ $out = "{$method} {$uri} HTTP/1.1{$crlf}";
482
+ $out .= $this->headersToString($appendHeaders);
483
+ $out .= $crlf;
484
+ if($paramsStr) {
485
+ $out .= $paramsStr.$crlf;
486
+ }
487
+
488
+ fwrite($this->_sock, $out);
489
+ $this->processResponse();
490
+ }
491
+
492
+ /**
493
+ * Throw error excpetion
494
+ * @param $string
495
+ * @throws Exception
496
+ */
497
+ public function doError($string)
498
+ {
499
+ throw new Exception($string);
500
+ }
501
+
502
+ /**
503
+ * Convert headers hash to string
504
+ * @param $delimiter
505
+ * @param $append
506
+ * @return string
507
+ */
508
+ protected function headersToString($append = array())
509
+ {
510
+ $headers = array();
511
+ $headers["Host"] = $this->_host;
512
+ $headers['Connection'] = "close";
513
+ $headers = array_merge($headers, $this->_headers, $append);
514
+ $str = array();
515
+ foreach ($headers as $k=>$v) {
516
+ $str []= "$k: $v\r\n";
517
+ }
518
+ return implode($str);
519
+ }
520
+
521
+ /**
522
+ * TODO
523
+ */
524
+ public function setOptions($arr)
525
+ {
526
+ // Stub
527
+ }
528
+
529
+ /**
530
+ * TODO
531
+ */
532
+ public function setOption($name, $value)
533
+ {
534
+ // Stub
535
+ }
536
+
537
+ }
app/code/local/Mss/downloader/lib/Mage/HTTP/IClient.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_HTTP
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Interface for different HTTP clients
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Connect
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ interface Mage_HTTP_IClient
35
+ {
36
+ /**
37
+ * Set request timeout
38
+ * @param int $value
39
+ */
40
+ function setTimeout($value);
41
+
42
+
43
+ /**
44
+ * Set request headers from hash
45
+ * @param array $headers
46
+ */
47
+ function setHeaders($headers);
48
+
49
+ /**
50
+ * Add header to request
51
+ * @param string $name
52
+ * @param string $value
53
+ */
54
+ function addHeader($name, $value);
55
+
56
+
57
+ /**
58
+ * Remove header from request
59
+ * @param string $name
60
+ */
61
+ function removeHeader($name);
62
+
63
+
64
+ /**
65
+ * Set login credentials
66
+ * for basic auth.
67
+ * @param string $login
68
+ * @param string $pass
69
+ */
70
+ function setCredentials($login, $pass);
71
+
72
+ /**
73
+ * Add cookie to request
74
+ * @param string $name
75
+ * @param string $value
76
+ */
77
+ function addCookie($name, $value);
78
+
79
+ /**
80
+ * Remove cookie from request
81
+ * @param string $name
82
+ */
83
+ function removeCookie($name);
84
+
85
+ /**
86
+ * Set request cookies from hash
87
+ * @param array $cookies
88
+ */
89
+ function setCookies($cookies);
90
+
91
+ /**
92
+ * Remove cookies from request
93
+ */
94
+ function removeCookies();
95
+
96
+ /**
97
+ * Make GET request
98
+ * @param string full uri
99
+ */
100
+ function get($uri);
101
+
102
+ /**
103
+ * Make POST request
104
+ * @param string $uri full uri
105
+ * @param array $params POST fields array
106
+ */
107
+ function post($uri, $params);
108
+
109
+ /**
110
+ * Get response headers
111
+ * @return array
112
+ */
113
+ function getHeaders();
114
+
115
+ /**
116
+ * Get response body
117
+ * @return string
118
+ */
119
+ function getBody();
120
+
121
+ /**
122
+ * Get response status code
123
+ * @return int
124
+ */
125
+ function getStatus();
126
+
127
+ /**
128
+ * Get response cookies (k=>v)
129
+ * @return array
130
+ */
131
+ function getCookies();
132
+
133
+ /**
134
+ * Set additional option
135
+ * @param string $key
136
+ * @param string $value
137
+ */
138
+ function setOption($key, $value);
139
+
140
+ /**
141
+ * Set additional options
142
+ * @param array $arr
143
+ */
144
+ function setOptions($arr);
145
+ }
app/code/local/Mss/downloader/lib/Mage/System/Args.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_System
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Command-line options parsing class.
29
+ */
30
+ class Mage_System_Args
31
+ {
32
+ public $flags;
33
+ public $filtered;
34
+
35
+ /**
36
+ * Get flags/named options
37
+ * @return array
38
+ */
39
+ public function getFlags()
40
+ {
41
+ return $this->flags;
42
+ }
43
+
44
+ /**
45
+ * Get filtered args
46
+ * @return array
47
+ */
48
+ public function getFiltered()
49
+ {
50
+ return $this->filtered;
51
+ }
52
+
53
+ /**
54
+ * Constructor
55
+ * @param array $argv, if false $GLOBALS['argv'] is taken
56
+ * @return void
57
+ */
58
+ public function __construct($source = false)
59
+ {
60
+ $this->flags = array();
61
+ $this->filtered = array();
62
+
63
+ if(false === $source) {
64
+ $argv = $GLOBALS['argv'];
65
+ array_shift($argv);
66
+ }
67
+
68
+ for($i = 0, $iCount = count($argv); $i < $iCount; $i++)
69
+ {
70
+ $str = $argv[$i];
71
+
72
+ // --foo
73
+ if(strlen($str) > 2 && substr($str, 0, 2) == '--')
74
+ {
75
+ $str = substr($str, 2);
76
+ $parts = explode('=', $str);
77
+ $this->flags[$parts[0]] = true;
78
+
79
+ // Does not have an =, so choose the next arg as its value
80
+ if(count($parts) == 1 && isset($argv[$i + 1]) && preg_match('/^--?.+/', $argv[$i + 1]) == 0)
81
+ {
82
+ $this->flags[$parts[0]] = $argv[$i + 1];
83
+ $argv[$i + 1] = null;
84
+ }
85
+ elseif(count($parts) == 2) // Has a =, so pick the second piece
86
+ {
87
+ $this->flags[$parts[0]] = $parts[1];
88
+ }
89
+ }
90
+ elseif(strlen($str) == 2 && $str[0] == '-') // -a
91
+ {
92
+ $this->flags[$str[1]] = true;
93
+ if(isset($argv[$i + 1]) && preg_match('/^--?.+/', $argv[$i + 1]) == 0) {
94
+ $this->flags[$str[1]] = $argv[$i + 1];
95
+ $argv[$i + 1] = null;
96
+ }
97
+ } else if(!is_null($str)) {
98
+ $this->filtered[] = $str;
99
+ }
100
+ }
101
+ }
102
+ }
app/code/local/Mss/downloader/lib/Mage/System/Dirs.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_System
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+ class Mage_System_Dirs
27
+ {
28
+
29
+ public static function rm($dirname)
30
+ {
31
+ if(is_array($dirname)) {
32
+ $dirname = $dirname[1];
33
+ }
34
+ // Sanity check
35
+ if (!@file_exists($dirname)) {
36
+ return false;
37
+ }
38
+
39
+ // Simple delete for a file
40
+ if (@is_file($dirname) || @is_link($dirname)) {
41
+ return unlink($dirname);
42
+ }
43
+
44
+ // Create and iterate stack
45
+ $stack = array($dirname);
46
+ while ($entry = array_pop($stack)) {
47
+ // Watch for symlinks
48
+ if (@is_link($entry)) {
49
+ @unlink($entry);
50
+ continue;
51
+ }
52
+
53
+ // Attempt to remove the directory
54
+ if (@rmdir($entry)) {
55
+ continue;
56
+ }
57
+
58
+ // Otherwise add it to the stack
59
+ $stack[] = $entry;
60
+ $dh = opendir($entry);
61
+ while (false !== $child = readdir($dh)) {
62
+ // Ignore pointers
63
+ if ($child === '.' || $child === '..') {
64
+ continue;
65
+ }
66
+ // Unlink files and add directories to stack
67
+ $child = $entry . DIRECTORY_SEPARATOR . $child;
68
+ if (is_dir($child) && !is_link($child)) {
69
+ $stack[] = $child;
70
+ } else {
71
+ @unlink($child);
72
+ }
73
+ }
74
+ @closedir($dh);
75
+ }
76
+ return true;
77
+ }
78
+
79
+
80
+ public static function mkdirStrict($path, $recursive = true, $mode = 0777)
81
+ {
82
+ $exists = file_exists($path);
83
+ if($exists && is_dir($path)) {
84
+ return true;
85
+ }
86
+ if($exists && !is_dir($path)) {
87
+ throw new Exception("'{$path}' already exists, should be a dir, not a file!");
88
+ }
89
+ $out = @mkdir($path, $mode, $recursive);
90
+ if(false === $out) {
91
+ throw new Exception("Can't create dir: '{$path}'");
92
+ }
93
+ return true;
94
+ }
95
+
96
+ public static function copyFileStrict($source, $dest)
97
+ {
98
+ $exists = file_exists($source);
99
+ if(!$exists) {
100
+ throw new Exception('No file exists: '.$exists);
101
+ }
102
+
103
+ }
104
+ }
app/code/local/Mss/downloader/lib/Mage/System/Ftp.php ADDED
@@ -0,0 +1,509 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_System
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Class to work with remote FTP server
29
+ *
30
+ * @category Mage
31
+ * @package Mage_System
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_System_Ftp
35
+ {
36
+
37
+ /**
38
+ * Connection object
39
+ *
40
+ * @var resource
41
+ */
42
+ protected $_conn = false;
43
+
44
+ /**
45
+ * Check connected, throw exception if not
46
+ *
47
+ * @throws Exception
48
+ * @return void
49
+ */
50
+ protected function checkConnected()
51
+ {
52
+ if(!$this->_conn) {
53
+ throw new Exception(__CLASS__." - no connection established with server");
54
+ }
55
+ }
56
+
57
+ /**
58
+ * ftp_mkdir wrapper
59
+ *
60
+ * @param sting $name
61
+ * @return unknown_type
62
+ */
63
+ public function mdkir($name)
64
+ {
65
+ $this->checkConnected();
66
+ return @ftp_mkdir($this->_conn, $name);
67
+ }
68
+
69
+ /**
70
+ * Make dir recursive
71
+ *
72
+ * @param string $path
73
+ * @param int $mode
74
+ * @return bool
75
+ */
76
+ public function mkdirRecursive($path, $mode = 0777)
77
+ {
78
+ $this->checkConnected();
79
+ $dir = explode("/", $path);
80
+ $path= "";
81
+ $ret = true;
82
+ for ($i=0; $i < count($dir); $i++) {
83
+ $path .= "/" .$dir[$i];
84
+ if(!@ftp_chdir($this->_conn, $path)) {
85
+ @ftp_chdir($this->_conn,"/");
86
+ if(!@ftp_mkdir($this->_conn,$path)) {
87
+ $ret=false;
88
+ break;
89
+ } else {
90
+ @ftp_chmod($this->_conn, $mode, $path);
91
+ }
92
+ }
93
+ }
94
+ return $ret;
95
+ }
96
+
97
+ /**
98
+ * Try to login to server
99
+ *
100
+ * @param string $login
101
+ * @param string $password
102
+ * @throws Exception on invalid login credentials
103
+ * @return bool
104
+ */
105
+ public function login($login = "anonymous", $password = "")
106
+ {
107
+ $this->checkConnected();
108
+ $res = @ftp_login($this->_conn, $login, $password);
109
+ if(!$res) {
110
+ throw new Exception("Invalid login credentials");
111
+ }
112
+ return $res;
113
+ }
114
+
115
+ /**
116
+ * Validate connection string
117
+ *
118
+ * @param string $string
119
+ * @throws Exception
120
+ * @return string
121
+ */
122
+ public function validateConnectionString($string)
123
+ {
124
+ $data = @parse_url($string);
125
+ if(false === $data) {
126
+ throw new Exception("Connection string invalid: '{$string}'");
127
+ }
128
+ if($data['scheme'] != 'ftp') {
129
+ throw new Exception("Support for scheme unsupported: '{$data['scheme']}'");
130
+ }
131
+ return $data;
132
+ }
133
+
134
+ /**
135
+ * Connect to server using connect string
136
+ * Connection string: ftp://user:pass@server:port/path
137
+ * user,pass,port,path are optional parts
138
+ *
139
+ * @param string $string
140
+ * @param int $timeout
141
+ */
142
+ public function connect($string, $timeout = 900)
143
+ {
144
+ $params = $this->validateConnectionString($string);
145
+ $port = isset($params['port']) ? intval($params['port']) : 21;
146
+
147
+ $this->_conn = ftp_connect($params['host'], $port, $timeout);
148
+
149
+ if(!$this->_conn) {
150
+ throw new Exception("Cannot connect to host: {$params['host']}");
151
+ }
152
+ if(isset($params['user']) && isset($params['pass'])) {
153
+ $this->login($params['user'], $params['pass']);
154
+ } else {
155
+ $this->login();
156
+ }
157
+ if(isset($params['path'])) {
158
+ if(!$this->chdir($params['path'])) {
159
+ throw new Exception ("Cannot chdir after login to: {$params['path']}");
160
+ }
161
+ }
162
+ }
163
+
164
+ /**
165
+ * ftp_fput wrapper
166
+ *
167
+ * @param string $remoteFile
168
+ * @param resource $handle
169
+ * @param int $mode FTP_BINARY | FTP_ASCII
170
+ * @param int $startPos
171
+ * @return bool
172
+ */
173
+ public function fput($remoteFile, $handle, $mode = FTP_BINARY, $startPos = 0)
174
+ {
175
+ $this->checkConnected();
176
+ return @ftp_fput($this->_conn, $remoteFile, $handle, $mode, $startPos);
177
+ }
178
+
179
+ /**
180
+ * ftp_put wrapper
181
+ *
182
+ * @param string $remoteFile
183
+ * @param string $localFile
184
+ * @param int $mode FTP_BINARY | FTP_ASCII
185
+ * @param int $startPos
186
+ * @return bool
187
+ */
188
+ public function put($remoteFile, $localFile, $mode = FTP_BINARY, $startPos = 0)
189
+ {
190
+ $this->checkConnected();
191
+ return ftp_put($this->_conn, $remoteFile, $localFile, $mode, $startPos);
192
+ }
193
+
194
+ /**
195
+ * Get current working directory
196
+ *
197
+ * @return mixed
198
+ */
199
+ public function getcwd()
200
+ {
201
+ $d = $this->raw("pwd");
202
+ $data = explode(" ", $d[0], 3);
203
+ if(empty($data[1])) {
204
+ return false;
205
+ }
206
+ if(intval($data[0]) != 257) {
207
+ return false;
208
+ }
209
+ $out = trim($data[1], '"');
210
+ if($out !== "/") {
211
+ $out = rtrim($out, "/");
212
+ }
213
+ return $out;
214
+ }
215
+
216
+ /**
217
+ * ftp_raw wrapper
218
+ *
219
+ * @param string $cmd
220
+ * @return mixed
221
+ */
222
+ public function raw($cmd)
223
+ {
224
+ $this->checkConnected();
225
+ return @ftp_raw($this->_conn, $cmd);
226
+ }
227
+
228
+ /**
229
+ * Upload local file to remote
230
+ *
231
+ * Can be used for relative and absoulte remote paths
232
+ * Relative: use chdir before calling this
233
+ *
234
+ * @param srting $remote
235
+ * @param string $local
236
+ * @param int $dirMode
237
+ * @param int $ftpMode
238
+ * @return unknown_type
239
+ */
240
+ public function upload($remote, $local, $dirMode = 0777, $ftpMode = FTP_BINARY)
241
+ {
242
+ $this->checkConnected();
243
+
244
+ if(!file_exists($local)) {
245
+ throw new Exception("Local file doesn't exist: {$localFile}");
246
+ }
247
+ if(!is_readable($local)) {
248
+ throw new Exception("Local file is not readable: {$localFile}");
249
+ }
250
+ if(is_dir($local)) {
251
+ throw new Exception("Directory given instead of file: {$localFile}");
252
+ }
253
+
254
+ $globalPathMode = substr($remote, 0, 1) == "/";
255
+ $dirname = dirname($remote);
256
+ $cwd = $this->getcwd();
257
+ if(false === $cwd) {
258
+ throw new Exception("Server returns something awful on PWD command");
259
+ }
260
+
261
+ if(!$globalPathMode) {
262
+ $dirname = $cwd."/".$dirname;
263
+ $remote = $cwd."/".$remote;
264
+ }
265
+ $res = $this->mkdirRecursive($dirname, $dirMode);
266
+ $this->chdir($cwd);
267
+
268
+ if(!$res) {
269
+ return false;
270
+ }
271
+ return $this->put($remote, $local, $ftpMode);
272
+ }
273
+
274
+ /**
275
+ * Download remote file to local machine
276
+ *
277
+ * @param string $remote
278
+ * @param string $local
279
+ * @param int $ftpMode FTP_BINARY|FTP_ASCII
280
+ * @return bool
281
+ */
282
+ public function download($remote, $local, $ftpMode = FTP_BINARY)
283
+ {
284
+ $this->checkConnected();
285
+ return $this->get($local, $remote, $ftpMode);
286
+ }
287
+
288
+ /**
289
+ * ftp_pasv wrapper
290
+ *
291
+ * @param bool $pasv
292
+ * @return bool
293
+ */
294
+ public function pasv($pasv)
295
+ {
296
+ $this->checkConnected();
297
+ return @ftp_pasv($this->_conn, (bool) $pasv);
298
+ }
299
+
300
+ /**
301
+ * Close FTP connection
302
+ *
303
+ * @return void
304
+ */
305
+ public function close()
306
+ {
307
+ if($this->_conn) {
308
+ @ftp_close($this->_conn);
309
+ }
310
+ }
311
+
312
+ /**
313
+ * ftp_chmod wrapper
314
+ *
315
+ * @param $mode
316
+ * @param $remoteFile
317
+ * @return bool
318
+ */
319
+ public function chmod($mode, $remoteFile)
320
+ {
321
+ $this->checkConnected();
322
+ return @ftp_chmod($this->_conn, $mode, $remoteFile);
323
+ }
324
+
325
+ /**
326
+ * ftp_chdir wrapper
327
+ *
328
+ * @param string $dir
329
+ * @return bool
330
+ */
331
+ public function chdir($dir)
332
+ {
333
+ $this->checkConnected();
334
+ return @ftp_chdir($this->_conn, $dir);
335
+ }
336
+
337
+ /**
338
+ * ftp_cdup wrapper
339
+ *
340
+ * @return bool
341
+ */
342
+ public function cdup()
343
+ {
344
+ $this->checkConnected();
345
+ return @ftp_cdup($this->_conn);
346
+ }
347
+
348
+ /**
349
+ * ftp_get wrapper
350
+ *
351
+ * @param string $localFile
352
+ * @param string $remoteFile
353
+ * @param int $fileMode FTP_BINARY | FTP_ASCII
354
+ * @param int $resumeOffset
355
+ * @return bool
356
+ */
357
+ public function get($localFile, $remoteFile, $fileMode = FTP_BINARY, $resumeOffset = 0)
358
+ {
359
+ $remoteFile = $this->correctFilePath($remoteFile);
360
+ $this->checkConnected();
361
+ return @ftp_get($this->_conn, $localFile, $remoteFile, $fileMode, $resumeOffset);
362
+ }
363
+
364
+ /**
365
+ * ftp_nlist wrapper
366
+ *
367
+ * @param string $dir
368
+ * @return bool
369
+ */
370
+ public function nlist($dir = "/")
371
+ {
372
+ $this->checkConnected();
373
+ $dir = $this->correctFilePath($dir);
374
+ return @ftp_nlist($this->_conn, $dir);
375
+ }
376
+
377
+ /**
378
+ * ftp_rawlist wrapper
379
+ *
380
+ * @param string $dir
381
+ * @param bool $recursive
382
+ * @return mixed
383
+ */
384
+ public function rawlist( $dir = "/", $recursive = false )
385
+ {
386
+ $this->checkConnected();
387
+ $dir = $this->correctFilePath($dir);
388
+ return @ftp_rawlist($this->_conn, $dir, $recursive);
389
+ }
390
+
391
+ /**
392
+ * Convert byte count to float KB/MB format
393
+ *
394
+ * @param int $bytes
395
+ * @return string
396
+ */
397
+ public static function byteconvert($bytes)
398
+ {
399
+ $symbol = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
400
+ $exp = floor( log($bytes) / log(1024) );
401
+ return sprintf( '%.2f ' . $symbol[ $exp ], ($bytes / pow(1024, floor($exp))) );
402
+ }
403
+
404
+ /**
405
+ * Chmod string "-rwxrwxrwx" to "777" converter
406
+ *
407
+ * @param string $chmod
408
+ * @return string
409
+ */
410
+ public static function chmodnum($chmod)
411
+ {
412
+ $trans = array('-' => '0', 'r' => '4', 'w' => '2', 'x' => '1');
413
+ $chmod = substr(strtr($chmod, $trans), 1);
414
+ $array = str_split($chmod, 3);
415
+ return array_sum(str_split($array[0])) . array_sum(str_split($array[1])) . array_sum(str_split($array[2]));
416
+ }
417
+
418
+ /**
419
+ * Check whether file exists
420
+ *
421
+ * @param string $path
422
+ * @param bool $excludeIfIsDir
423
+ * @return bool
424
+ */
425
+ public function fileExists($path, $excludeIfIsDir = true)
426
+ {
427
+ $path = $this->correctFilePath($path);
428
+ $globalPathMode = substr($path, 0, 1) == "/";
429
+
430
+ $file = basename($path);
431
+ $dir = $globalPathMode ? dirname($path) : $this->getcwd()."/".$path;
432
+ $data = $this->ls($dir);
433
+ foreach($data as $row) {
434
+ if($file == $row['name']) {
435
+ if($excludeIfIsDir && $row['dir']) {
436
+ continue;
437
+ }
438
+ return true;
439
+ }
440
+ }
441
+ return false;
442
+ }
443
+
444
+ /**
445
+ * Get directory contents in PHP array
446
+ *
447
+ * @param string $dir
448
+ * @param bool $recursive
449
+ * @return array
450
+ */
451
+ public function ls($dir = "/", $recursive = false)
452
+ {
453
+ $dir= $this->correctFilePath($dir);
454
+ $rawfiles = (array) $this->rawlist($dir, $recursive);
455
+ $structure = array();
456
+ $arraypointer = &$structure;
457
+ foreach ($rawfiles as $rawfile) {
458
+ if ($rawfile[0] == '/') {
459
+ $paths = array_slice(explode('/', str_replace(':', '', $rawfile)), 1);
460
+ $arraypointer = &$structure;
461
+ foreach ($paths as $path) {
462
+ foreach ($arraypointer as $i => $file) {
463
+ if ($file['name'] == $path) {
464
+ $arraypointer = &$arraypointer[ $i ]['children'];
465
+ break;
466
+ }
467
+ }
468
+ }
469
+ } elseif(!empty($rawfile)) {
470
+ $info = preg_split("/[\s]+/", $rawfile, 9);
471
+ $arraypointer[] = array(
472
+ 'name' => $info[8],
473
+ 'dir' => $info[0]{0} == 'd',
474
+ 'size' => (int) $info[4],
475
+ 'chmod' => self::chmodnum($info[0]),
476
+ 'rawdata' => $info,
477
+ 'raw' => $rawfile
478
+ );
479
+ }
480
+ }
481
+ return $structure;
482
+ }
483
+
484
+ /**
485
+ * Correct file path
486
+ *
487
+ * @param string $str
488
+ * @return string
489
+ */
490
+ public function correctFilePath($str)
491
+ {
492
+ $str = str_replace("\\", "/", $str);
493
+ $str = preg_replace("/^.\//", "", $str);
494
+ return $str;
495
+ }
496
+
497
+ /**
498
+ * Delete file
499
+ *
500
+ * @param string $file
501
+ * @return bool
502
+ */
503
+ public function delete($file)
504
+ {
505
+ $this->checkConnected();
506
+ $file = $this->correctFilePath($file);
507
+ return @ftp_delete($this->_conn, $file);
508
+ }
509
+ }
app/code/local/Mss/downloader/lib/Mage/Xml/Generator.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Xml
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+ class Mage_Xml_Generator
27
+ {
28
+ protected $_dom = null;
29
+ protected $_currentDom;
30
+
31
+ public function __construct()
32
+ {
33
+ $this->_dom = new DOMDocument('1.0');
34
+ $this->_dom->formatOutput=true;
35
+ $this->_currentDom = $this->_dom;
36
+ return $this;
37
+ }
38
+
39
+ public function getDom()
40
+ {
41
+ return $this->_dom;
42
+ }
43
+
44
+ protected function _getCurrentDom()
45
+ {
46
+ return $this->_currentDom;
47
+ }
48
+
49
+ protected function _setCurrentDom($node)
50
+ {
51
+ $this->_currentDom = $node;
52
+ return $this;
53
+ }
54
+
55
+ /**
56
+ * @param array $content
57
+ */
58
+ public function arrayToXml($content)
59
+ {
60
+ $parentNode = $this->_getCurrentDom();
61
+ if(!$content || !count($content)) {
62
+ return $this;
63
+ }
64
+ foreach ($content as $_key=>$_item) {
65
+ try{
66
+ $node = $this->getDom()->createElement($_key);
67
+ } catch (DOMException $e) {
68
+ // echo $e->getMessage();
69
+ var_dump($_item);
70
+ die;
71
+ }
72
+ $parentNode->appendChild($node);
73
+ if (is_array($_item) && isset($_item['_attribute'])) {
74
+ if (is_array($_item['_value'])) {
75
+ if (isset($_item['_value'][0])) {
76
+ foreach($_item['_value'] as $_k=>$_v) {
77
+ $this->_setCurrentDom($node)->arrayToXml($_v);
78
+ }
79
+ } else {
80
+ $this->_setCurrentDom($node)->arrayToXml($_item['_value']);
81
+ }
82
+ } else {
83
+ $child = $this->getDom()->createTextNode($_item['_value']);
84
+ $node->appendChild($child);
85
+ }
86
+ foreach($_item['_attribute'] as $_attributeKey=>$_attributeValue) {
87
+ $node->setAttribute($_attributeKey, $_attributeValue);
88
+ }
89
+ } elseif (is_string($_item)) {
90
+ $text = $this->getDom()->createTextNode($_item);
91
+ $node->appendChild($text);
92
+ } elseif (is_array($_item) && !isset($_item[0])) {
93
+ $this->_setCurrentDom($node)->arrayToXml($_item);
94
+ } elseif (is_array($_item) && isset($_item[0])) {
95
+ foreach($_item as $k=>$v) {
96
+ $this->_setCurrentDom($node)->arrayToXml($v);
97
+ }
98
+ }
99
+ }
100
+ return $this;
101
+ }
102
+
103
+ public function __toString()
104
+ {
105
+ return $this->getDom()->saveXML();
106
+ }
107
+
108
+ public function save($file)
109
+ {
110
+ $this->getDom()->save($file);
111
+ return $this;
112
+ }
113
+
114
+ }
app/code/local/Mss/downloader/lib/Mage/Xml/Parser.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Xml
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+ class Mage_Xml_Parser
27
+ {
28
+ protected $_dom = null;
29
+ protected $_currentDom;
30
+ protected $_content = array();
31
+
32
+ public function __construct()
33
+ {
34
+ $this->_dom = new DOMDocument;
35
+ $this->_currentDom = $this->_dom;
36
+ return $this;
37
+ }
38
+
39
+ public function getDom()
40
+ {
41
+ return $this->_dom;
42
+ }
43
+
44
+ protected function _getCurrentDom()
45
+ {
46
+ return $this->_currentDom;
47
+ }
48
+
49
+ protected function _setCurrentDom($node)
50
+ {
51
+ $this->_currentDom = $node;
52
+ return $this;
53
+ }
54
+
55
+ public function xmlToArray()
56
+ {
57
+ $this->_content = $this->_xmlToArray();
58
+ return $this->_content;
59
+ }
60
+
61
+ protected function _xmlToArray($currentNode=false)
62
+ {
63
+ if (!$currentNode) {
64
+ $currentNode = $this->getDom();
65
+ }
66
+ $content = array();
67
+ foreach ($currentNode->childNodes as $node) {
68
+ switch ($node->nodeType) {
69
+ case XML_ELEMENT_NODE:
70
+
71
+ $value = null;
72
+ if ($node->hasChildNodes()) {
73
+ $value = $this->_xmlToArray($node);
74
+ }
75
+ $attributes = array();
76
+ if ($node->hasAttributes()) {
77
+ foreach($node->attributes as $attribute) {
78
+ $attributes += array($attribute->name=>$attribute->value);
79
+ }
80
+ $value = array('_value'=>$value, '_attribute'=>$attributes);
81
+ }
82
+ if (isset($content[$node->nodeName])) {
83
+ if (!isset($content[$node->nodeName][0]) || !is_array($content[$node->nodeName][0])) {
84
+ $oldValue = $content[$node->nodeName];
85
+ $content[$node->nodeName] = array();
86
+ $content[$node->nodeName][] = $oldValue;
87
+ }
88
+ $content[$node->nodeName][] = $value;
89
+ } else {
90
+ $content[$node->nodeName] = $value;
91
+ }
92
+ break;
93
+ case XML_TEXT_NODE:
94
+ if (trim($node->nodeValue)) {
95
+ $content = $node->nodeValue;
96
+ }
97
+ break;
98
+ }
99
+ }
100
+ return $content;
101
+ }
102
+
103
+ public function load($file)
104
+ {
105
+ $this->getDom()->load($file);
106
+ return $this;
107
+ }
108
+
109
+ public function loadXML($string)
110
+ {
111
+ $this->getDom()->loadXML($string);
112
+ return $this;
113
+ }
114
+
115
+ }
app/code/local/Mss/downloader/mage.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ define('DS', DIRECTORY_SEPARATOR);
28
+ define('PS', PATH_SEPARATOR);
29
+ define('BP', dirname(dirname(__FILE__)));
30
+ define('MAGENTO_ROOT', dirname(dirname(__FILE__)));
31
+
32
+ class __cli_Mage_Connect
33
+ {
34
+ private static $_instance;
35
+ protected $argv;
36
+ public static function instance()
37
+ {
38
+ if(!self::$_instance) {
39
+ self::$_instance = new self();
40
+ }
41
+ return self::$_instance;
42
+ }
43
+
44
+ public function init($argv)
45
+ {
46
+ $this->argv = $argv;
47
+ $this->setIncludes();
48
+ require_once("Mage/Autoload/Simple.php");
49
+ Mage_Autoload_Simple::register();
50
+ chdir(BP . DS . 'downloader' . DS);
51
+ return $this;
52
+ }
53
+
54
+ public function setIncludes()
55
+ {
56
+ if (defined('DEVELOPMENT_MODE')) {
57
+ $libPath = PS . dirname(BP) . DS . 'lib';
58
+ } else {
59
+ $libPath = PS . BP . DS . 'downloader' . DS . 'lib';
60
+ }
61
+ $includePath = BP . DS . 'app'
62
+ . $libPath
63
+ . PS . get_include_path();
64
+ set_include_path($includePath);
65
+ }
66
+
67
+
68
+
69
+ public function getCommands()
70
+ {
71
+ return Mage_Connect_Command::getCommands();
72
+ }
73
+
74
+ public function getFrontend()
75
+ {
76
+ $frontend = Mage_Connect_Frontend::getInstance('CLI');
77
+ Mage_Connect_Command::setFrontendObject($frontend);
78
+ return $frontend;
79
+ }
80
+
81
+ public function getConfig($fileName = 'connect.cfg')
82
+ {
83
+ if (isset($this->config)) {
84
+ return $this->config;
85
+ }
86
+ $config = new Mage_Connect_Config($fileName);
87
+ if (empty($config->magento_root)) {
88
+ $config->magento_root = dirname(dirname(__FILE__));
89
+ }
90
+ Mage_Connect_Command::setConfigObject($config);
91
+ $this->config = $config;
92
+ return $config;
93
+ }
94
+
95
+ public function detectCommand()
96
+ {
97
+ $argv = $this->argv;
98
+ if(empty($argv[1])) {
99
+ return false;
100
+ }
101
+ if(in_array($argv[1], $this->validCommands)) {
102
+ list($options,$params) = $this->parseCommandArgs($argv);
103
+ return array('name' => strtolower($argv[1]), 'options'=>$options, 'params'=>$params);
104
+ }
105
+ return false;
106
+ }
107
+
108
+ public function parseCommandArgs($argv)
109
+ {
110
+ $a = new Mage_System_Args();
111
+ $args = $a->getFiltered();
112
+ array_shift($args);
113
+ return array($a->getFlags(), $args);
114
+ }
115
+
116
+ public function runCommand($cmd, $options, $params)
117
+ {
118
+ $c = Mage_Connect_Command::getInstance($cmd);
119
+ $c->run($cmd, $options, $params);
120
+ }
121
+
122
+ private $_sconfig;
123
+ public function getSingleConfig()
124
+ {
125
+ if(!$this->_sconfig) {
126
+ $this->_sconfig = new Mage_Connect_Singleconfig(
127
+ $this->getConfig()->magento_root . DS .
128
+ $this->getConfig()->downloader_path . DS .
129
+ Mage_Connect_Singleconfig::DEFAULT_SCONFIG_FILENAME
130
+ );
131
+ }
132
+ Mage_Connect_Command::setSconfig($this->_sconfig);
133
+ return $this->_sconfig;
134
+ }
135
+
136
+ public function run()
137
+ {
138
+ $this->commands = $this->getCommands();
139
+ $this->frontend = $this->getFrontend();
140
+ $this->config = $this->getConfig();
141
+ $this->validCommands = array_keys($this->commands);
142
+ $this->getSingleConfig();
143
+ $cmd = $this->detectCommand();
144
+ if(!$cmd) {
145
+ $this->frontend->outputCommandList($this->commands);
146
+ } else {
147
+ $this->runCommand($cmd['name'], $cmd['options'], $cmd['params']);
148
+ }
149
+
150
+ }
151
+
152
+ }
153
+
154
+ if (defined('STDIN') && defined('STDOUT') && (defined('STDERR'))) {
155
+ __cli_Mage_Connect::instance()->init($argv)->run();
156
+ }
app/code/local/Mss/downloader/skin/boxes.css ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Academic Free License (AFL 3.0)
7
+ * that is bundled with this package in the file LICENSE_AFL.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magento.com so we can send you a copy immediately.
13
+ *
14
+ * DISCLAIMER
15
+ *
16
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
17
+ * versions in the future. If you wish to customize Magento for your
18
+ * needs please refer to http://www.magento.com for more information.
19
+ *
20
+ * @category design
21
+ * @package default
22
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
23
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
24
+ */
25
+ /*
26
+ RESET
27
+ ******************************************************/
28
+ * { margin:0; padding:0; }
29
+ body { background:#f6f6f6; color:#2f2f2f; font:12px/1.55em arial, helvetica; }
30
+ a { color:#ea7601; }
31
+ a:hover { color:#d56b00; }
32
+ p { margin-bottom:1em; }
33
+ th { font-weight:bold; }
34
+ fieldset { border:none; }
35
+ form { display:inline; }
36
+ input, select, button { vertical-align:middle; }
37
+ li { list-style:none; }
38
+
39
+ /* COMMON ELEMENTS
40
+ ******************************************************/
41
+
42
+ /* Messages */
43
+ .msgs ul { margin-bottom:14px; padding:4px 10px 3px 10px; }
44
+ .msgs li {
45
+ list-style:none;
46
+ margin:0 0 3px 0;
47
+ border:0;
48
+ padding:0;
49
+ font-size:.95em;
50
+ font-weight:bold;
51
+ }
52
+ .error-msg { color:#df280a !important; background:#faebe7; }
53
+ .success-msg { color:#3d6611; background:#eff5ea; }
54
+ .notice-msg { background:#fffbf0; color:#3d6611 !important; }
55
+ .warning-msg { background:#e6e6e6; color:#000000 !important; }
56
+
57
+
58
+
59
+ /* Forms */
60
+ .form-list { margin-bottom:10px; }
61
+ .form-list td.label { padding:2px 8px 2px 0; }
62
+ .form-list td.value { padding:2px 0 2px 8px; }
63
+ .form-btn-set { margin-top:10px; text-align:right; }
64
+ button, .form-btn {
65
+ border-width:1px;
66
+ border-style:solid;
67
+ border-color:#ed6502 #a04300 #a04300 #ed6502;
68
+ background:url(images/btn_bg.gif) #ffac47 repeat-x 0 100%;
69
+ padding:0 7px 1px 7px;
70
+ color:#fff;
71
+ font:bold 12px arial, helvetica, sans-serif;
72
+ cursor:pointer;
73
+ white-space:nowrap;
74
+ }
75
+ a.form-btn,
76
+ a.form-btn:hover { color:#fff; padding-top:1px; padding-bottom:2px; text-decoration:none; }
77
+
78
+
79
+ /* Heading */
80
+ .bar-head { margin-bottom:12px; background:#6f8992; padding:2px 8px; }
81
+ .bar-head h4 { float:left; margin:0; color:#fff; font-size:1em; }
82
+ .bar-head
83
+ .bar-head-btn { margin-right:-6px; position:relative; }
84
+
85
+
86
+ /* Lists */
87
+ .bare-list li { margin-bottom:8px; }
88
+ .disc { margin-bottom:12px; }
89
+ .disc li { margin-left:22px; list-style-type:disc; }
90
+ .divider { height:1px; margin:15px 0; background:#bbb; overflow:hidden; font-size:1px; line-height:0em; }
91
+
92
+
93
+ /*
94
+ BOXES
95
+ ******************************************************/
96
+
97
+ /* Base structure */
98
+ .container { width:750px; margin:35px auto 0 auto; }
99
+ .header-top { background:url(images/header_bg.gif) repeat-x #415d65; padding:25px 25px 10px 25px; }
100
+ .main {
101
+ min-height:400px;
102
+ border-width:0 1px 2px 1px;
103
+ border-color:#aeaeae #aeaeae #6a6a6a #aeaeae;
104
+ border-style:solid;
105
+ background:#fff;
106
+ }
107
+ .content { padding:10px 25px 35px 25px; }
108
+ .footer { width:710px; margin:0 auto 35px auto; padding:10px 20px; text-align:center; }
109
+
110
+
111
+ /* Header */
112
+ #logo {
113
+ width:329px;
114
+ height:31px;
115
+ background:url(images/logo.gif) no-repeat;
116
+ text-indent:-6000px;
117
+ }
118
+ .nav {
119
+ margin-bottom:20px;
120
+ padding:8px 15px 0 20px;
121
+ background:url(images/nav_bg.gif) repeat-x 0 100% #f6f6f6;
122
+ }
123
+ .nav li { list-style:none; float:left; }
124
+ .nav li a, .nav .nav li a:hover {
125
+ float:left;
126
+ margin-right:4px;
127
+ border:1px solid #ccc;
128
+ border-right-color:#999;
129
+ border-bottom:none;
130
+ background:#ccc;
131
+ padding:2px 11px;
132
+ color:#222;
133
+ text-decoration:none;
134
+ }
135
+ .nav li a.active, .nav li a.active:hover {
136
+ background:#fff;
137
+ color:#2f2f2f;
138
+ font-weight:bold;
139
+ text-decoration:none;
140
+ cursor:default;
141
+ }
142
+ .page-head { margin-bottom:14px; font-size:1.7em; font-weight:normal; }
143
+
144
+
145
+ /* Footer */
146
+ .footer .copyright { font-size:.95em; color:#444; }
147
+
148
+
149
+
150
+
151
+ /* SECTION-SPECIFIC
152
+ ******************************************************/
153
+
154
+ /* Connect Package */
155
+ .connect-packages table { table-layout:fixed; margin:6px 0; }
156
+ .connect-packages td,.connect-packages th {
157
+ padding:3px 5px;
158
+ border-right:solid 1px #ccc;
159
+ border-bottom:solid 1px #ccc;
160
+ background:#f6f6f6;
161
+ vertical-align:top;
162
+ word-wrap:break-word;
163
+ }
164
+ .connect-packages th { border-top:solid 1px #bbb; background:#ccc; text-align:left; }
165
+ .connect-packages td.first { border-left:solid 1px #bbb; }
166
+ .connect-packages td.last { border-right:solid 1px #bbb; }
167
+ .connect-packages tr.installed-latest td { background:#dbf1d7; }
168
+ .connect-packages tr.upgrade-available td { background:#fcfbbb; }
169
+ .connect-packages tr.stand-alone td { background:#cbe8fb; }
170
+ .connect-packages td .select { word-wrap:normal; width:100%; }
171
+ .step-count { background:#f77312; color:#fff; font-weight:bold; padding:0 4px; }
172
+
173
+
174
+
175
+
176
+ /* MISC
177
+ ******************************************************/
178
+
179
+ /* Clearing */
180
+ .bar-head:after,
181
+ .form-btn-set:after,
182
+ .nav:after,
183
+ .clear:after {
184
+ clear:both;
185
+ content:".";
186
+ display:block;
187
+ height:0;
188
+ font-size:0;
189
+ line-height:0;
190
+ visibility:hidden;
191
+ }
192
+
193
+
194
+ /* Directional and spacial */
195
+ .f-left { float:left; }
196
+ .f-right { float:right; }
197
+ .v-top { vertical-align:top; }
198
+ .v-middle { vertical-align:middle; }
199
+ .v-bottom { vertical-align:bottom; }
200
+ .a-left { text-align:left; }
201
+ .a-center { text-align:center !important; }
202
+ .a-right { text-align:right; }
203
+ .nm { margin:0 !important; }
204
+ .np { padding:0 !important; }
205
+ .no-display { display:none; }
206
+ .no-show { display:none; }
207
+ .no-br { white-space:nowrap; }
208
+ .no-float { float:none !important; }
209
+ .big { font-size:1.2em !important; }
210
+
211
+ .loading-mask { color:#d85909; font-size:1.1em; font-weight:bold; text-align:center; opacity:0.80; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; z-index:500; }
212
+ .loading-mask .loader { position:absolute; /* position:absolute; top:143px; */ left:50%; width:120px; margin-left:-120px; padding:15px 60px; background:#fff4e9; border:2px solid #f1af73; color:#d85909; font-weight:bold; text-align:center; z-index:1000; }
213
+
214
+ /* Settings Page */
215
+ .settings-page .form-list td { width:200px; }
216
+ .settings-page .form-list select { width:254px; }
217
+ .settings-page .form-list .input-text { width:250px; }
app/code/local/Mss/downloader/skin/ie7boxes.css ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Academic Free License (AFL 3.0)
7
+ * that is bundled with this package in the file LICENSE_AFL.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magento.com so we can send you a copy immediately.
13
+ *
14
+ * DISCLAIMER
15
+ *
16
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
17
+ * versions in the future. If you wish to customize Magento for your
18
+ * needs please refer to http://www.magento.com for more information.
19
+ *
20
+ * @category design
21
+ * @package default
22
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
23
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
24
+ */
25
+ .main { height:auto !important; }
26
+ button, .form-button { filter:chroma(color=#000000); }
27
+ .connect-packages td .select { margin:0 0 2px; width:100%; }
app/code/local/Mss/downloader/skin/ieboxes.css ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Academic Free License (AFL 3.0)
7
+ * that is bundled with this package in the file LICENSE_AFL.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magento.com so we can send you a copy immediately.
13
+ *
14
+ * DISCLAIMER
15
+ *
16
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
17
+ * versions in the future. If you wish to customize Magento for your
18
+ * needs please refer to http://www.magento.com for more information.
19
+ *
20
+ * @category design
21
+ * @package default
22
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
23
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
24
+ */
25
+ button, .form-button { filter:chroma(color=#000000); overflow:visible; width:auto; }
26
+ .main { height:400px; }
27
+ .nav, .form-btn-set, .header-top, .bar-head { zoom:1; }
28
+ .clear { clear:both; height:0; font-size:0; line-height:0; overflow:hidden; }
29
+ .connect-packages td .select { margin:0 0 2px; }
app/code/local/Mss/downloader/skin/images/Magento_Connect.jpg ADDED
Binary file
app/code/local/Mss/downloader/skin/images/ajax-loader-tr.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/images/btn_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/images/header_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/images/logo.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/images/nav_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/images/nav_separator.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/boxes.css ADDED
@@ -0,0 +1,414 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Academic Free License (AFL 3.0)
7
+ * that is bundled with this package in the file LICENSE_AFL.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magento.com so we can send you a copy immediately.
13
+ *
14
+ * DISCLAIMER
15
+ *
16
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
17
+ * versions in the future. If you wish to customize Magento for your
18
+ * needs please refer to http://www.magento.com for more information.
19
+ *
20
+ * @category design
21
+ * @package default
22
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
23
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
24
+ */
25
+
26
+ /****************************************************/
27
+ /***********[ Mage_CSS_B Common Elements ]***********/
28
+ /****************************************************/
29
+
30
+
31
+ /********************** Columns */
32
+
33
+ /* All */
34
+ .col2-set, .col3-set, .col4-set, .col5-set { clear:both; }
35
+
36
+ /* Col2 */
37
+ .col2-set .col-1, .col2-set .col-2 { width:48.5%; }
38
+ .col2-set .col-1 { float:left; }
39
+ .col2-set .col-2 { float:right;}
40
+
41
+ /* Col2-alt */
42
+ .col2-alt-set .col-1 { width:32%; }
43
+ .col2-alt-set .col-2 { width:65%; }
44
+ .col2-alt-set .col-1 { float:left; }
45
+ .col2-alt-set .col-2 { float:right;}
46
+
47
+ /* Col3 */
48
+ .col3-set .col-1, .col3-set .col-2, .col3-set .col-3 { float:left; width:31.3%; }
49
+ .col3-set .col-1, .col3-set .col-2 { margin-right:3%; }
50
+
51
+ /* Col4 */
52
+ .col4-set .col-1, .col4-set .col-2, .col4-set .col-3, .col4-set .col-4 { float:left; width:22%; }
53
+ .col4-set .col-1, .col4-set .col-2, .col4-set .col-3 { margin-right:4%; }
54
+
55
+ /* Table Columns */
56
+ table .col-1, table .col-2, table .col-3, table .col-4 { float:none !important; margin:0 !important; }
57
+ .col3-set td.spacer { width:3%; }
58
+ .col4-set td.spacer { width:4%; }
59
+
60
+
61
+
62
+ /********************** Form */
63
+
64
+ /* Form Elements */
65
+ input.input-text, select, textarea { border:1px solid #b6b6b6; font:12px arial, helvetica, sans-serif; }
66
+ option, optgroup { font:12px arial, helvetica, sans-serif; }
67
+ optgroup { font-weight:bold; }
68
+ input.input-text, textarea { padding:2px; }
69
+ input.form-radio { margin-right:3px;}
70
+ .qty { width:2.5em; }
71
+ .group-select label, .form-list label, .payment-methods label { font-weight:bold;}
72
+ .button-set { /* Container for form buttons*/
73
+ clear:both;
74
+ margin-top:4em;
75
+ border-top:1px solid #e4e4e4;
76
+ padding-top:8px;
77
+ text-align:right;
78
+ }
79
+ .form-button, .form-button-alt {
80
+ overflow:visible;
81
+ width:auto;
82
+ background-color:transparent;
83
+ border:0;
84
+ padding:1px 8px;
85
+ background:#f18200;
86
+ color:#fff;
87
+ border:1px solid #de5400;
88
+ font:bold 12px arial, sans-serif !important;
89
+ cursor:pointer;
90
+ text-align:center;
91
+ vertical-align:middle;
92
+ }
93
+ .form-button span, .form-button-alt span {
94
+ white-space:nowrap;
95
+ }
96
+ .form-button-alt {
97
+ border:1px solid #406a83;
98
+ background-color:#618499;
99
+ }
100
+
101
+ .fieldset-download .form-button { margin:0.8em 0 0; }
102
+
103
+
104
+ /* Form lists */
105
+ .form-list li { margin-bottom:6px; }
106
+ .form-list li .input-box .input-text, .form-list li .input-box textarea { width:250px; }
107
+ .form-list li .input-box select { width:256px;}
108
+
109
+ table.form-list td { padding:2px 5px 2px 0; width:225px; }
110
+ table.form-list input { width:248px; }
111
+ table.form-list select { width:254px; }
112
+
113
+ .group-select {
114
+ margin:28px 0;
115
+ border:1px solid #bbafa0;
116
+ padding:22px 25px 12px 25px;
117
+ background:#fbfaf6;
118
+ }
119
+ .group-select .legend {
120
+ margin-top:-33px;
121
+ float:left;
122
+ border:1px solid #f19900;
123
+ background:#F9F3E3;
124
+ padding:0 8px;
125
+ color:#E76200;
126
+ font-weight:bold;
127
+ font-size:1.1em;
128
+ }
129
+ .group-select li { padding:4px 8px !important; }
130
+ .group-select li .input-box { float:left; width:275px; }
131
+ .group-select li .input-text, .group-select li select, .group-select li textarea { width:525px; }
132
+ .group-select li .input-box .input-text, .group-select li .input-box textarea { width:250px; }
133
+ .group-select li .input-box select { width:256px;}
134
+
135
+
136
+ /* Form Messages */
137
+ .validation-advice, .required { color:#EB340A; }
138
+ .validation-advice {
139
+ clear:both;
140
+ min-height:15px;
141
+ margin-top:3px;
142
+ background:url(images/validation_advice_bg.gif) no-repeat 2px 1px;
143
+ padding-left:17px;
144
+ font-size:.95em;
145
+ font-weight:bold;
146
+ line-height:1.25em;
147
+ }
148
+ .validation-failed {
149
+ border:1px dashed #EB340A !important;
150
+ background:#faebe7 !important;
151
+ }
152
+ label.required {
153
+ font-weight:bold;
154
+ }
155
+ p.required {
156
+ font-size:.95em;
157
+ text-align:right;
158
+ }
159
+
160
+
161
+
162
+ /********************** Messages */
163
+ .success { color:#3d6611; }
164
+ .error { color:#df280a; }
165
+ .success, .error { font-weight:bold; }
166
+ .error-msg, .success-msg, .notice-msg, .note-msg {
167
+ min-height:23px !important;
168
+ margin-bottom:1em !important;
169
+ border-style:solid !important;
170
+ border-width:1px !important;
171
+ background-repeat:no-repeat !important;
172
+ background-position:10px 10px !important;
173
+ padding:8px 8px 8px 32px !important;
174
+ font-size:.95em !important;
175
+ font-weight:bold !important;
176
+ }
177
+ .error-msg li, .success-msg li, .notice-msg li {margin-bottom:.2em; }
178
+ .error-msg {
179
+ border-color:#f16048;
180
+ color:#df280a;
181
+ background-color:#faebe7;
182
+ background-image:url(images/error_msg_icon.gif);
183
+ }
184
+ .success-msg {
185
+ border-color:#446423;
186
+ color:#3d6611;
187
+ background-color:#eff5ea;
188
+ background-image:url(images/success_msg_icon.gif);
189
+ }
190
+ .notice-msg, .note-msg {
191
+ border-color:#fcd344;
192
+ color:#3d6611;
193
+ background-color:#fafaec;
194
+ background-image:url(images/note_msg_icon.gif);
195
+ }
196
+
197
+
198
+
199
+ /********************** Headings */
200
+
201
+ .head, .inner-head { line-height:1.25em; text-align:right; }
202
+ .head h1,.head h2, .head h3, .head h4, .head h5,
203
+ .inner-head h1,.inner-head h2, .inner-head h3, .inner-head h4, .inner-head h5{ margin:0; float:left; }
204
+
205
+
206
+ /* Page heading */
207
+ .page-head { margin:0 0 25px 0; border-bottom:1px solid #ccc; }
208
+ .page-head-alt { margin:0 0 12px 0; }
209
+ .page-head, .page-head-alt { text-align:right; }
210
+ .page-head h3, .page-head-alt h3 {
211
+ margin:0;
212
+ font-size:1.7em !important;
213
+ font-weight:normal !important;
214
+ text-transform:none !important;
215
+ text-align:left;
216
+ }
217
+ .button-level h3 { /* heading level with buttons */
218
+ float:left;
219
+ width:60%;
220
+ }
221
+
222
+
223
+ /* Category list heading */
224
+ .category-head {
225
+ margin-bottom:7px;
226
+ }
227
+ .category-head h2 {
228
+ margin:0;
229
+ padding:3px 0;
230
+ color:#0a263c;
231
+ font-size:1.6em;
232
+ line-height:1.3em;
233
+ font-weight:normal;
234
+ }
235
+
236
+
237
+
238
+
239
+ /********************** Lists */
240
+ .disc { margin-bottom:10px; }
241
+ .disc li { margin-left:20px; list-style:disc; }
242
+
243
+
244
+ /* Bare List */ /* Unstyled list */
245
+ .bare-list { margin:5px 0; }
246
+ .bare-list li { margin:3px 0; }
247
+
248
+
249
+
250
+ /********************** Space Creators */
251
+
252
+ .no-show { display:none; }
253
+ .no-wrap { white-space:nowrap; }
254
+ .content-box { min-height:250px; } /* Set minimum height for visual presentation */
255
+ .content { padding:12px 12px 12px 15px; } /* Sets default padding */
256
+ .actions { line-height:1.3em; }
257
+ .separator { padding:0 5px;}
258
+ .pipe { padding:0 4px; font-size:.95em; }
259
+ .divider {
260
+ margin:10px 0;
261
+ height:1px;
262
+ background:url(images/dotted_divider.gif) repeat-x;
263
+ font-size:1px;
264
+ line-height:1em;
265
+ overflow:hidden;
266
+ }
267
+
268
+
269
+
270
+
271
+ /************************************************************/
272
+ /********************[ Mage_CSS_C Layout]********************/
273
+ /************************************************************/
274
+
275
+
276
+ /********************** Base Layout */
277
+
278
+ /* Structure */
279
+ .header {
280
+ z-index:999;
281
+ text-align:left;
282
+ }
283
+ .header-top {
284
+ position:relative;
285
+ width:930px;
286
+ margin:0 auto;
287
+ }
288
+ .header-nav {
289
+ width:950px;
290
+ margin:0 auto;
291
+ }
292
+ .middle {
293
+ min-height:400px;
294
+ width:900px;
295
+ margin:0 auto;
296
+ text-align:left;
297
+ position:relative;
298
+ }
299
+ .side-col { width:195px; }
300
+ .col-left { float:left; }
301
+ .col-main { float:left; }
302
+ .col-right { float:right; }
303
+ .col-1-layout .col-main { float:none; margin:0; }
304
+ .col-2-right-layout .col-main { float:left; width:685px; }
305
+ .col-2-left-layout .col-main { float:right; width:685px; }
306
+ .col-3-layout .col-main { width:475px; margin-left:17px; }
307
+
308
+ /* Style */
309
+ .header { border-top:5px solid #0d2131; }
310
+ .header-top-container { border-bottom:1px solid #415966; background:url(images/header_top_container_bg.jpg) repeat-x 50% 0; }
311
+ .header-top { padding:10px; }
312
+ .header-nav-container { background:url(images/nav_bg.jpg) repeat-y 50% 0 #0a263d; }
313
+ .middle-container { background:url(images/main_container_bg.gif) no-repeat 50% 0 #fbfaf6; }
314
+ .middle { background:url(images/main_bg.gif) no-repeat #fffffe; padding:25px 25px 80px 25px; }
315
+
316
+
317
+
318
+ /********************** Header */
319
+
320
+ /* Logo */
321
+ h1#logo {
322
+ float:left;
323
+ width:202px;
324
+ margin:3px 0 10px 12px;
325
+ }
326
+ .page-popup h1#logo { display:none; }
327
+
328
+
329
+ /* Quick Access*/
330
+ .quick-access {
331
+ width:390px;
332
+ float:right;
333
+ margin-top:28px;
334
+ text-align:right;
335
+ padding:0 10px;
336
+ color:#fff;
337
+ }
338
+ .quick-access p { margin-bottom:4px; }
339
+ .quick-access li {
340
+ display:inline;
341
+ background:url(images/shop_access_pipe.gif) no-repeat 100% .35em;
342
+ padding-right:7px;
343
+ padding-left:3px;
344
+ }
345
+ .quick-access li.first { padding-left:0;}
346
+ .quick-access li.last { padding-right:0; background:none;}
347
+ .account-access p, .account-access ul, .account-access li { display:inline; color:#fff; }
348
+ .account-access a, .account-access a:hover { color:#e1f1fb; }
349
+ .account-access ul { padding-left:10px; font-size:.95em; }
350
+ .shop-access a, .shop-access a:hover { color:#ebbc58; font-size:.95em; }
351
+
352
+
353
+ /* Breadcrumbs */
354
+ .breadcrumbs { margin-bottom:13px; font-size:.95em; line-height:1.25em; }
355
+ .breadcrumbs li { display:inline; }
356
+
357
+
358
+
359
+ /********************** Footer */
360
+ .footer-container { border-top:15px solid #B6D1E2; }
361
+ .footer {
362
+ width:930px;
363
+ margin:0 auto;
364
+ padding:1em 1em 4em 1em;
365
+ position:relative;
366
+ }
367
+ .footer .store-switcher { display:inline; padding:0 10px 0 0; vertical-align:middle; }
368
+ .footer .informational label { color:#fff; font-weight:bold; padding-right:3px; }
369
+ .footer .informational ul {
370
+ display:inline;
371
+ }
372
+ .footer .informational li {
373
+ display:inline;
374
+ background:url(images/footer_info_separator.gif) no-repeat 100% 50%;
375
+ padding-right:8px;
376
+ padding-left:4px;
377
+ }
378
+ .footer .informational li.last { background:none; padding-right:0; }
379
+ .footer .informational a, .footer .informational a:hover { color:#fff; }
380
+ .footer .informational a { text-decoration:none; }
381
+ .footer .legality {
382
+ padding:13px 0;
383
+ color:#ecf3f6;
384
+ text-align:center;
385
+ }
386
+ .footer .legality a, .footer .legality a:hover { color:#ecf3f6; }
387
+
388
+
389
+ /************************************************************/
390
+ /******************[ Mage_CSS_F Overrides]*******************/
391
+ /************************************************************/
392
+
393
+
394
+ /* Alignment */
395
+ .v-top { vertical-align:top; }
396
+ .v-middle { vertical-align:middle; }
397
+ .v-bottom { vertical-align:bottom; }
398
+ .a-left { text-align:left; }
399
+ .a-center { text-align:center; }
400
+ .a-right { text-align:right; }
401
+ .left { float:left; }
402
+ .right { float:right !important; }
403
+
404
+ .normal-weight { font-weight:normal; }
405
+ .auto-width { width:auto;}
406
+
407
+ /* Link highlights */
408
+ .link-cart { color:#DC6809 !important; font-weight:bold !important;}
409
+ .link-remove { color:#646464 !important;}
410
+ .link-print { background:url(images/icon_printer.gif) no-repeat 0 2px; padding-left:23px; }
411
+
412
+
413
+ /* For Demo store only */
414
+ .demo-notice { margin:0; background:#d75f07; padding:5px 10px 6px 10px; color:#fff; line-height:1em; text-align:center; }
app/code/local/Mss/downloader/skin/install/clears.css ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Academic Free License (AFL 3.0)
7
+ * that is bundled with this package in the file LICENSE_AFL.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magento.com so we can send you a copy immediately.
13
+ *
14
+ * DISCLAIMER
15
+ *
16
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
17
+ * versions in the future. If you wish to customize Magento for your
18
+ * needs please refer to http://www.magento.com for more information.
19
+ *
20
+ * @category design
21
+ * @package default
22
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
23
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
24
+ */
25
+
26
+ /****************************************************/
27
+ /****************[ Mage_CSS_B Clears ]***************/
28
+ /****************************************************/
29
+
30
+ .page-head:after,
31
+ .page-head-alt:after,
32
+ .clear:after,
33
+ .col2-set:after,
34
+ .col3-set:after,
35
+ .col4-set:after,
36
+ .col2-alt-set:after,
37
+ .head:after,
38
+ .inner-head:after,
39
+ .header-top:after,
40
+ .quick-access:after,
41
+ .header-nav:after,
42
+ #nav:after,
43
+ .middle:after,
44
+ .product-essential:after,
45
+ .button-set:after,
46
+ .actions:after,
47
+ .legend:after,
48
+ .form-list li:after,
49
+ .button-container:after,
50
+ .ratings:after,
51
+ .page-head:after,
52
+ .page-head-alt:after,
53
+ .group-select li:after,
54
+ .search-autocomplete li:after,
55
+ .side-col li:after,
56
+ .account-box li:after,
57
+ .address-list li:after,
58
+ .generic-product-list li:after,
59
+ .listing-type-list .listing-item:after,
60
+ .listing-type-list .product-info .product-reviews:after,
61
+ .my-review-detail:after {
62
+ content:".";
63
+ display:block;
64
+ clear:both;
65
+ height:0;
66
+ font-size:0;
67
+ line-height:0em;
68
+ visibility:hidden;
69
+ overflow:hidden;
70
+ }
app/code/local/Mss/downloader/skin/install/ie7minus.css ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Academic Free License (AFL 3.0)
7
+ * that is bundled with this package in the file LICENSE_AFL.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magento.com so we can send you a copy immediately.
13
+ *
14
+ * DISCLAIMER
15
+ *
16
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
17
+ * versions in the future. If you wish to customize Magento for your
18
+ * needs please refer to http://www.magento.com for more information.
19
+ *
20
+ * @category design
21
+ * @package default
22
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
23
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
24
+ */
25
+
26
+ #nav li.parent { margin-bottom:-3px; }
27
+ .one-page-checkout { position:relative; }
28
+ .group-select .legend { position:relative; zoom:1; }
29
+
30
+ /* Min-height for IE */
31
+ .login-box .content { height:180px; }
32
+ .content-box { height:250px; }
33
+ #main { height:400px; }
34
+
35
+ .validation-advice { height:15px; }
36
+ .error-msg, .success-msg, .note-msg { height:23px; }
37
+ .currency-switcher h4 { height:21px; }
38
+ .base-mini .head h4, .shopping-cart-collaterals h4 { height:16px; }
39
+ .login-box h4 { height:16px; }
40
+ .login-box .content { height:230px; }
app/code/local/Mss/downloader/skin/install/iestyles.css ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Academic Free License (AFL 3.0)
7
+ * that is bundled with this package in the file LICENSE_AFL.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magento.com so we can send you a copy immediately.
13
+ *
14
+ * DISCLAIMER
15
+ *
16
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
17
+ * versions in the future. If you wish to customize Magento for your
18
+ * needs please refer to http://www.magento.com for more information.
19
+ *
20
+ * @category design
21
+ * @package default
22
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
23
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
24
+ */
25
+ .col2-set,
26
+ .col3-set,
27
+ .col4-set,
28
+ .col2-alt-set,
29
+ .head,
30
+ .page-head,
31
+ .page-head-alt,
32
+ .header-top-container,
33
+ .header-top,
34
+ .header-nav-container,
35
+ .header-nav,
36
+ .quick-access,
37
+ #nav,
38
+ #nav li,
39
+ #nav a,
40
+ .middle,
41
+ .product-essential,
42
+ .button-set,
43
+ .actions,
44
+ .form-list li,
45
+ .button-container,
46
+ .ratings,
47
+ .page-head,
48
+ .page-head-alt,
49
+ .group-select li,
50
+ .search-autocomplete li,
51
+ .side-col li,
52
+ .account-box li,
53
+ .address-list li,
54
+ .listing-type-list .listing-item,
55
+ .listing-type-list .product-info .product-reviews,
56
+ .account-nav a,
57
+ .account-box,
58
+ .my-review-detail,
59
+ .generic-product-list li { zoom:1; }
60
+
61
+ .clear {
62
+ display:block;
63
+ clear:both;
64
+ height:0;
65
+ font-size:0;
66
+ line-height:0;
67
+ }
68
+ .multi-address-checkout-box .box { zoom:1; }
69
+ .multi-address-checkout-box .legend { zoom:1; position:relative; margin-left:8px;}
70
+ .quick-access li { padding-right:4px; padding-left:6px;}
71
+ .search-autocomplete { left:39px !important; }
72
+ .mini-search { padding-top:-1px; line-height:1em;}
73
+ .home-spot { display:inline; }
74
+ .mini-related-items .product-details { margin-left:76px; }
75
+ .mini-related-items .product-images input { float:left; margin:-4px 2px 0 -4px; }
76
+ .mini-related-items .product-images img { float:left; }
77
+ .header-top-container { position:relative; }
78
+ #nav ul li.parent { margin-bottom:-3px;}
app/code/local/Mss/downloader/skin/install/images/error_msg_icon.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/footer_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/footer_container_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/footer_info_separator.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/footer_informational_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/footer_left.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/footer_legality_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/footer_right.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/header_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/header_nav_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/header_top_bg.jpg ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/header_top_container_bg.jpg ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/logo.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/main_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/main_container_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/note_msg_icon.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/success_msg_icon.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/images/validation_advice_bg.gif ADDED
Binary file
app/code/local/Mss/downloader/skin/install/reset.css ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Academic Free License (AFL 3.0)
7
+ * that is bundled with this package in the file LICENSE_AFL.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magento.com so we can send you a copy immediately.
13
+ *
14
+ * DISCLAIMER
15
+ *
16
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
17
+ * versions in the future. If you wish to customize Magento for your
18
+ * needs please refer to http://www.magento.com for more information.
19
+ *
20
+ * @category design
21
+ * @package default
22
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
23
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
24
+ */
25
+ /******************************************/
26
+ /***********[ Mage_CSS_A Reset ]***********/
27
+ /******************************************/
28
+
29
+ * { margin:0; padding:0; }
30
+
31
+ body {
32
+ background-color: #496778;
33
+ color:#2f2f2f;
34
+ font:12px/1.55em arial, helvetica, sans-serif;
35
+ text-align:center;
36
+ }
37
+
38
+ a { color:#1e7ec8; text-decoration:underline; }
39
+ a:hover { color:#1e7ec8; text-decoration:underline; }
40
+ a img { border:0;}
41
+
42
+ /* Heading */
43
+ h1, h2, h3, h4, h5, h6, .head {
44
+ margin-bottom:.4em;
45
+ line-height:1.3em;
46
+ color:#0A263C;
47
+ }
48
+ h2 { font-size:1.5em; }
49
+ h3 { font-size:1.35em; }
50
+ h4 { font-size:1.05em; }
51
+ h5 { font-size:1.05em; }
52
+ h6 { font-size:.95em; }
53
+
54
+ /* Table */
55
+ th { padding:0; text-align:left; vertical-align:top; }
56
+ td {padding:0;vertical-align:top;}
57
+
58
+ /* Paragraph */
59
+ p { margin-bottom:.8em; }
60
+ address { margin-bottom:.4em; }
61
+ address { font-style:normal; line-height:1.4em;}
62
+ cite { font-style:normal; font-size:10px;}
63
+ q:before, q:after{content:'';}
64
+
65
+ /* Form */
66
+ form { display:inline;}
67
+ fieldset { border:none; }
68
+ legend {display:none;}
69
+ label { color:#666; /*font-size:.95em;*/ font-weight:bold; }
70
+ input, select, button { vertical-align:middle; }
71
+
72
+ /* Lists */
73
+ dt { display:block; font-weight:bold; }
74
+ li { list-style:none; }
75
+
76
+ /* Size */
77
+ small { font-size:.9em; }
78
+ big { font-size:1.1em; }
79
+
80
+ hr { height:0; margin:8px 0; overflow:hidden; visibility:hidden; }
81
+ .nowrap { white-space:nowrap; }
82
+ :focus { outline: 0; }
83
+ .bold { font-weight:bold; }
app/code/local/Mss/downloader/target.xml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Magento
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magento.com so we can send you a copy immediately.
15
+ *
16
+ * DISCLAIMER
17
+ *
18
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
19
+ * versions in the future. If you wish to customize Magento for your
20
+ * needs please refer to http://www.magento.com for more information.
21
+ *
22
+ * @category Mage
23
+ * @package Mage_Downloader
24
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ */
27
+ -->
28
+ <targets>
29
+ <target name="magelocal" label="Magento Local module file" uri="./app/code/local" />
30
+ <target name="magecommunity" label="Magento Community module file" uri="./app/code/community" />
31
+ <target name="magecore" label="Magento Core team module file" uri="./app/code/core" />
32
+ <target name="magedesign" label="Magento User Interface (layouts, templates)" uri="./app/design" />
33
+ <target name="mageetc" label="Magento Global Configuration" uri="./app/etc" />
34
+ <target name="magelib" label="Magento PHP Library file" uri="./lib" />
35
+ <target name="magelocale" label="Magento Locale language file" uri="./app/locale" />
36
+ <target name="magemedia" label="Magento Media library" uri="./media" />
37
+ <target name="mageskin" label="Magento Theme Skin (Images, CSS, JS)" uri="./skin" />
38
+ <target name="mageweb" label="Magento Other web accessible file" uri="." />
39
+ <target name="magetest" label="Magento PHPUnit test" uri="./tests" />
40
+ <target name="mage" label="Magento other" uri="." />
41
+ </targets>
app/code/local/Mss/downloader/template/.htaccess ADDED
@@ -0,0 +1,2 @@
 
 
1
+ Order deny,allow
2
+ Deny from all
app/code/local/Mss/downloader/template/connect/iframe.phtml ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <a name="connect_iframe"></a>
28
+
29
+ <div id="connect_iframe_container" style="display:none;">
30
+ <input id="connect_iframe_scroll" type="checkbox" checked="checked"/> <label for="connect_iframe_scroll">Auto-scroll console contents</label><br/>
31
+ <iframe id="connect_iframe" name="connect_iframe" src="<?php echo $this->url('empty') ?>" style="width:100%; height:300px;" frameborder="no"></iframe>
32
+ </div>
33
+
34
+ <script type="text/javascript">
35
+ function disableInputs(flag)
36
+ {
37
+ top.$$('input, select, button').each(function(el){
38
+ if (el.id!='connect_iframe_scroll') el.disabled = flag;
39
+ });
40
+ if (flag) {
41
+ window.onbeforeunload = confirmExit;
42
+ } else {
43
+ window.onbeforeunload = null;
44
+ }
45
+ }
46
+
47
+ function confirmExit()
48
+ {
49
+ return "There are Connect processes running.\nIf you will close the window or navigate away from the page, installation will be interrupted.";
50
+ }
51
+
52
+ function onSubmit(formObj)
53
+ {
54
+ if(formObj){
55
+ formObj.action = addParamToUrl(formObj.action, 'maintenance', (top.$('maintenance').checked === true ? '1' : '0'));
56
+ formObj.action = addParamToUrl(formObj.action, 'archive_type', top.$('is_backup').checked === true ? top.$('archive_type').value:0);
57
+ formObj.action = addParamToUrl(formObj.action, 'backup_name', top.$('backup_name').value);
58
+ }
59
+ top.$('connect_iframe_success').style.display = 'none';
60
+ top.$('connect_iframe_failure').style.display = 'none';
61
+ top.$('connect_iframe_container').style.display = '';
62
+ top.location.href = '#connect_iframe';
63
+ return true;
64
+ }
65
+
66
+ function onSuccess()
67
+ {
68
+ var div = top.$('connect_iframe_success');
69
+ if (div) {
70
+ top.location.href = top.location.href.replace(/#.*$/, '')+'#connect_iframe_result';
71
+ div.style.display = '';
72
+ }
73
+ }
74
+
75
+ function onFailure()
76
+ {
77
+ var div = top.$('connect_iframe_failure');
78
+ if (div) {
79
+ top.location.href = top.location.href.replace(/#.*$/, '')+'#connect_iframe_result';
80
+ div.style.display = '';
81
+ }
82
+ }
83
+
84
+ function checkForUpdateClick()
85
+ {
86
+ url = addParamToUrl(location.href, 'maintenance', (top.$('maintenance').checked === true ? '1' : '0'));
87
+ url = addParamToUrl(url, 'updates', 'yes');
88
+ location.href = url;
89
+ }
90
+
91
+ function addParamToUrl(url, param, value)
92
+ {
93
+ var anchor = null, params = {};
94
+ var anchorPos = url.search(/#/);
95
+ if (anchorPos != -1) {
96
+ anchor = url.substr(anchorPos + 1);
97
+ url = url.substr(0, anchorPos);
98
+ }
99
+ getPos = url.search(/\?/);
100
+ if (getPos != -1) {
101
+ url.substr(getPos + 1).split('&').each(function(pv){
102
+ if (pv != 'loggedin') {
103
+ pv = pv.split('=');
104
+ params[pv[0]] = pv[1];
105
+ }
106
+ });
107
+ url = url.substr(0, getPos);
108
+ }
109
+
110
+ params[param] = value;
111
+
112
+ if (params) {
113
+ url += '?';
114
+ for (k in params) {
115
+ url += k + '=' + params[k] + '&';
116
+ }
117
+ url = url.substr(0, url.length - 1);
118
+ }
119
+ if (anchor) {
120
+ url = url + '#' + anchor;
121
+ }
122
+
123
+ return url;
124
+ }
125
+ </script>
app/code/local/Mss/downloader/template/connect/packages.phtml ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php echo $this->template('header.phtml') ?>
28
+ <?php if ($this->get('writable_warning')) echo $this->template('writable.phtml');?>
29
+ <div class="bar-head">
30
+ <h4>Settings</h4>
31
+ </div>
32
+ <ul class="bare-list">
33
+ <li>
34
+ <input type="checkbox" id="maintenance" value="1" checked="checked" /> &nbsp;
35
+ <label for="maintenance">Put store on the maintenance mode while installing/upgrading/backup creation</label>
36
+ </li>
37
+ <li>
38
+ <table cellpadding="0" cellspacing="0">
39
+ <tr>
40
+ <td rowspan="2" valign="top">
41
+ <input type="checkbox" id="is_backup" value="1" /> &nbsp;
42
+ </td>
43
+ <td>
44
+ <label for="is_backup">Create Backup</label>
45
+ </td>
46
+ <td>
47
+ &nbsp;<select id="archive_type" style="width: 320px;">
48
+ <option value="1">Database</option>
49
+ <option value="4">Database and Media</option>
50
+ <option value="2">System</option>
51
+ <option value="3">System (excluding Media)</option>
52
+ </select>
53
+ </td>
54
+ </tr>
55
+ <tr id="backup-name-container" style="display: none; margin-top: 5px;">
56
+ <td valign="top">
57
+ <div style="margin: 6px 0 0 5px;">
58
+ <label for="backup_name">Backup Name</label>
59
+ </div>
60
+ </td>
61
+ <td>
62
+ <div style="margin: 6px 0 0 4px;">
63
+ <input type="text" name="backup_name" id="backup_name" style="width: 318px;" maxlength="50"/>
64
+ <div class="notice-msg">Please use only letters (a-z or A-Z), numbers (0-9) or<br/> space in this field. Other characters are not allowed.</div>
65
+ </div>
66
+ </td>
67
+ </tr>
68
+ </table>
69
+ </li>
70
+ </ul>
71
+ <div class="bar-head">
72
+ <h4>Install New Extensions</h4>
73
+ </div>
74
+ <script type="text/javascript">
75
+ <!--
76
+ changeAvailableArchiveStatus = function (){
77
+ $('archive_type').disabled = !$('is_backup').checked;
78
+ $('is_backup').checked ? $('backup-name-container').show() : $('backup-name-container').hide();
79
+ $('backup_name').value = '';
80
+ }
81
+
82
+ Event.observe('is_backup', 'change', changeAvailableArchiveStatus);
83
+ Event.observe(window, 'load', changeAvailableArchiveStatus);
84
+
85
+ function connectPrepare(form) {
86
+ new Ajax.Request(form.action, {
87
+ method:'post',
88
+ parameters: {install_package_id: form.install_package_id.value, form_key: form.form_key.value},
89
+ onCreate: function() {
90
+ $('prepare_package_result').update(
91
+ '<div class="loading-mask" id="loading_mask_loader">'+
92
+ ' <p class="loader">'+
93
+ ' <img src="<?php echo $this->baseUrl()?>/skin/images/ajax-loader-tr.gif" alt="Loading..."/><br/>Please wait...'+
94
+ ' </p>'+
95
+ '</div>'
96
+ );
97
+ $('loading_mask_loader').style.position = 'relative';
98
+ $('loading_mask_loader').top = 0;
99
+ $('prepare_package_result').show();
100
+ },
101
+ onSuccess: function(transport) {
102
+ // @TODO: check transport.status to show errors
103
+ $('prepare_package_result').update(transport.responseText);
104
+ $('prepare_package_result').show();
105
+ },
106
+ onFailure: function() {
107
+ $('prepare_package_result').update(
108
+ '<div id="packages_failure">' +
109
+ ' <ul class="msgs"> ' +
110
+ ' <li>' +
111
+ ' <ul class="error-msg">' +
112
+ ' <li>Connection Error try again later.</li>' +
113
+ ' </ul>' +
114
+ ' </li>' +
115
+ ' </ul>' +
116
+ '</div> '
117
+ );
118
+ }
119
+ });
120
+ return(false);
121
+ }
122
+ //-->
123
+ </script>
124
+ <form action="<?php echo $this->url('connectPreparePackagePost')?>" method="post" onsubmit="return connectPrepare(this)">
125
+ <input name="form_key" type="hidden" value="<?php echo $this->getFormKey() ?>" />
126
+ <ul class="bare-list">
127
+ <li>
128
+ <span class="step-count">1</span> &nbsp; Search for modules via <a href="http://connect.magentocommerce.com/" target="Magento_Connect">Magento Connect</a>.
129
+ </li>
130
+ <li>
131
+ <span class="step-count">2</span> &nbsp;
132
+ <label for="install_package_id">Paste extension key to install:</label> <input type="text" id="install_package_id" name="install_package_id" style="width:300px"/>
133
+ <button type="submit">Install</button>
134
+ </li>
135
+ </ul>
136
+ </form>
137
+
138
+ <br/>
139
+
140
+ <div class="connect-packages" id="prepare_package_result" style="display:none;"></div>
141
+ <br/>
142
+
143
+ <div class="bar-head">
144
+ <h4>Direct package file upload</h4>
145
+ </div>
146
+ <form action="<?php echo $this->url('connectInstallPackageUpload')?>" method="post" target="connect_iframe" onsubmit="onSubmit(this)" enctype="multipart/form-data">
147
+ <input name="form_key" type="hidden" value="<?php echo $this->getFormKey() ?>" />
148
+ <ul class="bare-list">
149
+ <li><span class="step-count">1</span> &nbsp; Download or build package file.</li>
150
+ <li>
151
+ <span class="step-count">2</span> &nbsp; Upload package file:
152
+ <label for="file"></label>
153
+ <input type="file" id="file" name="file"/>
154
+ <button type="submit">Upload</button>
155
+ </li>
156
+ </ul>
157
+ </form>
158
+
159
+ <br/><br/>
160
+ <div class="bar-head">
161
+ <h4>Manage Existing Extensions</h4>
162
+ <?php if (empty($_GET['updates'])): ?>
163
+ <span class="bar-head-btn f-right"><button type="button" class="f-right" onclick="checkForUpdateClick()">Check for Upgrades</button></span>
164
+ <?php endif; ?>
165
+ </div>
166
+ <?php $packages = $this->get('connect')->getAllInstalledPackages(); $i = 0; $cnt = count($packages); ?>
167
+ <?php $channelConfig=$this->get('channel_config');?>
168
+ <script type="text/javascript">
169
+ function formSubmit(id)
170
+ {
171
+ var formObj = $(id);
172
+ if (onSubmit(formObj)) {
173
+ formObj.submit();
174
+ }
175
+ }
176
+ </script>
177
+ <?php foreach ($packages as $channel=>$pkgs): ?>
178
+
179
+ <form id="connect_packages_<?php echo $i ?>" class="connect-packages" action="<?php echo $this->url('connectPackagesPost')?>" method="post" target="connect_iframe">
180
+ <input name="form_key" type="hidden" value="<?php echo $this->getFormKey() ?>" />
181
+ <div class="no-display">
182
+ <input type="hidden" id="ignore_local_modification" name="ignore_local_modification" value=""/>
183
+ <input type="hidden" name="form_id" value="connect_packages_<?php echo $i ?>"/>
184
+ </div>
185
+ <p class="nm"><button type="button" onclick="formSubmit('connect_packages_<?php echo $i ?>')" class="f-right">Commit Changes</button></p>
186
+ <h2 class="page-head">Channel: <?php echo $channelConfig->getChannelLabel($channel); ?></h2>
187
+ <p class="f-right"><label for="clean_sessions">Clear all sessions after successfull install or upgrade: <input type="checkbox" id="clean_sessions"/></label></p>
188
+ <div class="clear"></div>
189
+
190
+ <table cellspacing="0" cellpadding="0" width="100%">
191
+ <?php if (!empty($_GET['updates'])): ?>
192
+ <col width="190" />
193
+ <col width="60" />
194
+ <col width="60" />
195
+ <col width="160" />
196
+ <col width="170" />
197
+ <?php else: ?>
198
+ <col width="200" />
199
+ <col width="100" />
200
+ <col width="70" />
201
+ <col width="180" />
202
+ <?php endif; ?>
203
+ <thead>
204
+ <tr>
205
+ <th class="first">Package Name</th>
206
+ <th class="a-center">Installed</th>
207
+ <?php if (!empty($_GET['updates'])): ?><th class="a-center">Available</th><?php endif; ?>
208
+ <th>Actions</th>
209
+ <th class="last">Summary</th>
210
+ </tr>
211
+ </thead>
212
+ <tbody>
213
+ <?php foreach ($pkgs as $pkgName=>$pkg): ?>
214
+ <tr class="<?php echo $pkg['status']?>">
215
+ <td class="first"><?php echo $pkgName?></td>
216
+ <td class="a-center"><?php echo $pkg['version'].' ('.$pkg['stability'].')'?>&nbsp;</td>
217
+ <?php if (!empty($_GET['updates'])): ?><td class="a-center"><?php echo $pkg['upgrade_latest']?>&nbsp;</td><?php endif; ?>
218
+ <td><select class="select" name="actions[<?php echo $channel.'|'.$pkgName ?>]">
219
+ <option selected="selected"></option>
220
+ <?php if(isset($pkg['actions']) && is_array($pkg['actions'])): ?>
221
+ <?php foreach ($pkg['actions'] as $k=>$v): ?>
222
+ <option value="<?php echo $k ?>"><?php echo $v ?></option>
223
+ <?php endforeach; ?>
224
+ <?php endif; ?>
225
+ </select>
226
+ </td>
227
+ <td class="last"><?php echo $pkg['summary']?></td>
228
+ </tr>
229
+ <?php endforeach; /*channel*/ ?>
230
+ </tbody>
231
+ </table>
232
+ <div class="clear"></div>
233
+
234
+ <div class="form-btn-set">
235
+ <button type="button" onclick="formSubmit('connect_packages_<?php echo $i ?>')" class="f-right">Commit Changes</button>
236
+ <?php if (!empty($_GET['updates'])): ?>
237
+ <p class="f-left a-left">
238
+ <span style="background:#f6f6f6;padding:0 5px;">&nbsp;</span> &nbsp;Installed<br/>
239
+ <span style="background:#fcfbbb;padding:0 5px;">&nbsp;</span> &nbsp;Upgrade Available<br/>
240
+ </p>
241
+ <?php endif; ?>
242
+ </div>
243
+ </form>
244
+ <script type="text/javascript">
245
+ $$('#connect_packages_' + <?php echo $i?> + ' select').each(function(el){el.value=''});
246
+ </script>
247
+ <?php if (++$i != $cnt): ?><div class="divider"></div><?php endif ?>
248
+ <br/>
249
+ <?php endforeach; /*all packages*/ ?>
250
+
251
+
252
+ <?php echo $this->template('connect/iframe.phtml') ?>
253
+
254
+ <a name="connect_iframe_result"></a>
255
+ <div id="connect_iframe_success" style="display:none">
256
+ <?php $this->set('messages', array('success'=>array('Procedure completed. Please check the output frame for useful information and refresh the page to see changes.'))) ?>
257
+ <?php echo $this->template('messages.phtml') ?>
258
+ <button onclick="location.href='<?php echo $this->baseUrl() ?>'">Refresh</button>
259
+ </div>
260
+ <div id="connect_iframe_failure" style="display:none">
261
+ <?php $this->set('messages', array('error'=>array('Please check the output frame for errors and refresh the page to retry changes.'))) ?>
262
+ <?php echo $this->template('messages.phtml') ?>
263
+ <button onclick="location.href='<?php echo $this->baseUrl() ?>'">Refresh</button>
264
+ </div>
265
+
266
+ <?php echo $this->template('footer.phtml') ?>
app/code/local/Mss/downloader/template/connect/packages_prepare.phtml ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php
28
+ $packages = $this->get('packages');
29
+ $errors = $this->get('errors');
30
+ $cnt = count($packages);
31
+ if($cnt):
32
+ ?>
33
+ Extension dependencies
34
+ <form action="<?php
35
+ echo $this->url('connectInstallPackagePost')?>" method="post" target="connect_iframe" onsubmit="onSubmit(this)">
36
+ <input name="form_key" type="hidden" value="<?php echo $this->getFormKey() ?>" />
37
+ <input type="hidden" name="install_package_id" value="<?php echo $this->escapeHtml($this->get('package_id')); ?>">
38
+ <table cellspacing="0" cellpadding="0" width="100%">
39
+ <col width="150" />
40
+ <col width="250" />
41
+ <col width="150" />
42
+ <col width="100" />
43
+ <thead>
44
+ <tr>
45
+ <th class="first">Channel</th>
46
+ <th class="first">Package Name</th>
47
+ <th>Version</th>
48
+ <th class="last">Status</th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ <?php foreach ($packages as $pkg): ?>
53
+ <tr class="<?php echo $pkg['status']?>">
54
+ <td class="first"><?php echo $pkg['channel']?></td>
55
+ <td><?php echo $pkg['name']?></td>
56
+ <td><?php echo $pkg['version'] . (!empty($pkg['stability']) ? ' (' . $pkg['stability'] . ')' : '')?></td>
57
+ <td class="last"><?php echo $pkg['message']?></td>
58
+ </tr>
59
+ <?php endforeach;?>
60
+ </tbody>
61
+ </table>
62
+ <div class="form-btn-set">
63
+ <button class="f-right" type="submit">Proceed</button>
64
+ <button class="f-right" style="margin-right:10px;" onclick="$('prepare_package_result').update();" type="reset">Cancel installation</button>
65
+ </div>
66
+ </form>
67
+ <?php
68
+ endif;
69
+ if (!$cnt || !empty($errors['error'])):
70
+ $_errors = array('error'=>array('Extension key is not valid.'));
71
+ if(!empty($errors) && is_array($errors)) $_errors = $errors;
72
+ $this->set('messages', $_errors)
73
+ ?>
74
+ <div id="packages_failure">
75
+ <?php echo $this->template('messages.phtml') ?>
76
+ </div>
77
+ <?php
78
+ endif;
79
+ ?>
app/code/local/Mss/downloader/template/exception.phtml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php echo $this->template($this->controller()->isInstalled() ? 'header.phtml' : 'install/header.phtml') ?>
28
+
29
+ <h2>Exception caught:</h2>
30
+ <br/>
31
+ <h3><?php echo $this->get('exception')->getMessage() ?></h3>
32
+ <br/>
33
+ <h4>Backtrace:</h4>
34
+ <pre><?php echo $this->get('exception')->getTraceAsString() ?></pre>
35
+
36
+ <?php echo $this->template($this->controller()->isInstalled() ? 'footer.phtml' : 'install/footer.phtml') ?>
app/code/local/Mss/downloader/template/footer.phtml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ <div class="footer">
31
+ <p class="copyright">
32
+ Help Us to Keep Magento Healthy - <a href="http://www.magentocommerce.com/bug-tracking" id="bug_tracking_link"><strong>Report All Bugs</strong></a> (Magento Connect Manager ver. <?php echo Maged_Controller::getVersion();?>)<br/>
33
+ <script type="text/javascript">
34
+ $('bug_tracking_link').target = "varien_external";
35
+ </script>
36
+ Magento is a trademark of Magento, Inc. Copyright &copy; 2016 Magento Inc.
37
+ </p>
38
+ </div>
39
+ </body>
40
+ </html>
app/code/local/Mss/downloader/template/header.phtml ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
28
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
29
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
30
+ <head>
31
+ <title><?php echo $this->__('Magento Downloader') ?></title>
32
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
33
+ <link type="image/x-icon" href="<?php echo $this->baseUrl()?>/favicon.ico" rel="icon"/>
34
+ <link type="image/x-icon" href="<?php echo $this->baseUrl()?>/favicon.ico" rel="shortcut icon"/>
35
+ <script type="text/javascript" src="js/prototype.js"></script>
36
+ <link type="text/css" rel="stylesheet" href="skin/boxes.css"></link>
37
+ <!--[if IE]>
38
+ <link type="text/css" rel="stylesheet" href="skin/ieboxes.css" media="all"></link>
39
+ <![endif]-->
40
+ <!--[if gt IE 6]>
41
+ <link type="text/css" rel="stylesheet" href="skin/ie7boxes.css" media="all"></link>
42
+ <![endif]-->
43
+ </head>
44
+ <body>
45
+ <div class="container">
46
+
47
+ <div class="header-top">
48
+ <h1 id="logo">Magento Downloader</h1>
49
+ </div>
50
+ <div class="main">
51
+ <?php if ($this->controller()->getAction()!='login' && !$this->get('exception')): ?>
52
+ <div class="nav">
53
+ <?php if (true||$this->controller()->isWritable()): ?>
54
+ <?php if ($this->controller()->session()->getUserId()): ?>
55
+ <a href="<?php echo $this->url('logout') ?>" class="f-right" style="margin:0px 10px;">Log Out</a>
56
+ <?php if ($returnUrl = $this->controller()->session()->getReturnUrl()): ?>
57
+ <a href="<?php echo $returnUrl ?>" class="f-right" style="margin:0px 10px;">Return to Admin</a>
58
+ <?php endif; ?>
59
+ <?php endif; ?>
60
+ <ul>
61
+ <li class="first"><a <?php echo $this->getNavLinkParams('connectPackages') ?>>Extensions</a></li>
62
+ <li class="last"><a <?php echo $this->getNavLinkParams('settings') ?>>Settings</a></li>
63
+ </ul>
64
+ <?php else: ?>
65
+ <ul>
66
+ <li class="first last"><a class="active">Check Write Permissions</a></li>
67
+ </ul>
68
+ <?php endif; ?>
69
+ </div>
70
+ <?php endif; ?>
71
+ <div class="content">
72
+ <?php $this->set('messages', $this->controller()->session()->getMessages()) ?>
73
+ <?php echo $this->template('messages.phtml') ?>
app/code/local/Mss/downloader/template/index.phtml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php echo $this->template('header.phtml') ?>
28
+
29
+ <h2 class="page-head">Start Here</h2>
30
+ <p>Here is some explanation about PEAR. Suspendisse sapien urna, facilisis sed, pharetra ut, blandit nec, nulla. Vivamus ac dui. Morbi justo ipsum, bibendum sed, egestas sed, pharetra ut, ligula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer quis sapien vel sem semper luctus. Vestibulum tristique venenatis velit. Ut urna nisl, dignissim vitae, cursus eget, pulvinar scelerisque, lectus. In ac leo id libero consequat dignissim. Sed aliquam est a pede. Phasellus ut turpis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed magna leo, volutpat eget, pretium tristique, varius vitae, tellus. Sed odio ante, sagittis id, euismod eu, bibendum quis, purus. Proin consectetuer elementum nunc. Mauris turpis. In sed eros eu enim sagittis viverra. Integer adipiscing vestibulum tortor. Proin ante. Vivamus euismod, tortor id condimentum condimentum, arcu odio posuere est, eu eleifend nunc nulla sed nibh. Proin pretium sapien vitae erat.<br/><a href="<?php echo $this->url('settings') ?>">Change your PEAR settings</a></p>
31
+
32
+ <p class="a-center"><a href="<?php echo $this->url('pearGlobal') ?>" class="form-btn">Proceed with complete Magento PEAR Download/Upgrade</a></p>
33
+ <p class="a-center"><a href="<?php echo $this->url('pearPackages') ?>" class="form-btn">Proceed to individual PEAR packages management</a></p>
34
+
35
+ <?php echo $this->template('footer.phtml') ?>
36
+
app/code/local/Mss/downloader/template/install/download.phtml ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php echo $this->template('install/header.phtml') ?>
28
+
29
+ <div class="page-head">
30
+ <h3>Welcome to Magento's Installation Wizard!</h3>
31
+ </div>
32
+
33
+ <?php if (!$this->controller()->isDownloaded()): ?>
34
+ <p>You are now ready to continue the installation process by downloading the most up-to-date copy of the Magento software.</p>
35
+ <?php echo($this->get('channel_notice')); ?>
36
+ <form id="install_all" method="post" action="<?php echo $this->url('connectInstallAll') ?>" target="connect_iframe" onsubmit="return installAll()">
37
+ <fieldset class="fieldset-download">
38
+ <?php else: ?>
39
+ <p>There's an indication that Magento files already have been downloaded.</p>
40
+ <p>If you feel that you have arrived to this page by mistake, please continue installation:</p>
41
+ <button class="form-button" type="button" onclick="location.href='<?php echo $this->mageUrl() ?>'"><span>Continue Magento installation</span></button>
42
+ <br/><br/><br/>
43
+ <p>Alternatively, you could proceed with Re-Downloading all packages</p>
44
+ <?php echo($this->get('channel_notice')); ?>
45
+ <form id="reinstall_all" method="post" action="<?php echo $this->url('connectInstallAll') ?>&force=1" target="connect_iframe" onsubmit="return installAll(true)">
46
+ <fieldset class="fieldset-download">
47
+ <?php endif; ?>
48
+
49
+ <table cellspacing="0" class="form-list">
50
+ <tr>
51
+ <td class="label">Magento Connect Channel Protocol:</td>
52
+ <td class="value">
53
+ <select id="protocol" name="protocol">
54
+ <option value="http" <?php if ($this->get('protocol')=='http'):?>selected="selected"<?php endif ?>>Http</option>
55
+ <option value="ftp" <?php if ($this->get('protocol')=='ftp'):?>selected="selected"<?php endif ?>>Ftp</option>
56
+ </select>
57
+ </td>
58
+ </tr>
59
+ <?php echo($this->get('channel_protocol_fields')); ?>
60
+ <tr>
61
+ <td class="label">Magento Version Stability:</td>
62
+ <td class="value">
63
+ <select id="preferred_state" name="preferred_state">
64
+ <option value="stable" <?php if ($this->get('preferred_state') == 'stable'):?>selected="selected"<?php endif ?>>stable</option>
65
+ <option value="beta" <?php if ($this->get('preferred_state') == 'beta'):?>selected="selected"<?php endif ?>>beta</option>
66
+ <option value="alpha" <?php if ($this->get('preferred_state') == 'alpha'):?>selected="selected"<?php endif ?>>alpha</option>
67
+ </select>
68
+ </td>
69
+ </tr>
70
+ <tr>
71
+ <td class="label">Use Custom Permissions:</td>
72
+ <td class="value">
73
+ <select onchange="togglePanel(this)" id="use_custom_permissions_mode" name="use_custom_permissions_mode">
74
+ <option value="1" <?php if ($this->get('use_custom_permissions_mode')=='1'):?>selected="selected"<?php endif ?>>Yes</option>
75
+ <option value="0" <?php if ($this->get('use_custom_permissions_mode')=='0'):?>selected="selected"<?php endif ?>>No</option>
76
+ </select>
77
+ </td>
78
+ </tr>
79
+ </table>
80
+ <table cellspacing="0" cellpadding="0" class="form-list" id="use_custom_permissions_mode_panel" <?php if ($this->get('use_custom_permissions_mode')=='0'):?>style="display:none;"<?php endif ?> >
81
+ <tr>
82
+ <td class="label">Folders:</td>
83
+ <td class="value">
84
+ <input id="mkdir_mode" name="mkdir_mode" value="<?php echo($this->get('mkdir_mode'));?>" type="text" class="input-text"/>
85
+ </td>
86
+ </tr>
87
+ <tr>
88
+ <td class="label">Files:</td>
89
+ <td class="value">
90
+ <input id="chmod_file_mode" name="chmod_file_mode" value="<?php echo($this->get('chmod_file_mode'));?>" type="text" class="input-text"/>
91
+ </td>
92
+ </tr>
93
+ </table>
94
+ <table cellspacing="0" cellpadding="0" class="form-list">
95
+ <tr>
96
+ <td class="label">Deployment Type:</td>
97
+ <td class="value">
98
+ <select id="inst_protocol" onchange="togglePanel(this)" name="inst_protocol">
99
+ <option value="0">Local Filesystem</option>
100
+ <option value="1">FTP Connection</option>
101
+ </select>
102
+ </td>
103
+ </tr>
104
+ </table>
105
+ <table cellspacing="0" cellpadding="0" class="form-list" id="inst_protocol_panel">
106
+ <tr>
107
+ <td class="label">Host:</td>
108
+ <td class="value">
109
+ <input type="text" class="input-text" id="ftp_host" value="" name="ftp_host" />
110
+ </td>
111
+ </tr>
112
+
113
+ <tr>
114
+ <td class="label">User:</td>
115
+ <td class="value">
116
+ <input type="text" class="input-text" id="ftp_login" value="" name="ftp_login" />
117
+ </td>
118
+ </tr>
119
+
120
+ <tr>
121
+ <td class="label">Password:</td>
122
+ <td class="value">
123
+ <input type="password" id="ftp_password" value="" name="ftp_password" class="input-text" />
124
+ </td>
125
+ </tr>
126
+
127
+ <tr>
128
+ <td class="label">Installation Path:</td>
129
+ <td class="value">
130
+ <input id="ftp_path" name="ftp_path" value="" type="text" class="input-text" />
131
+ </td>
132
+ </tr>
133
+ </table>
134
+
135
+ <?php if (!$this->controller()->isDownloaded()): ?>
136
+ <button class="form-button" type="submit">Start the download process</button>
137
+ </fieldset>
138
+ </form>
139
+ <?php else: ?>
140
+ <button class="form-button" type="submit">Re-Download All Magento Core Packages</button>
141
+ </fieldset>
142
+ </form>
143
+ <?php endif; ?>
144
+
145
+ <br/>
146
+ <?php echo $this->template('connect/iframe.phtml') ?>
147
+
148
+ <a name="connect_iframe_result"></a>
149
+ <div id="connect_iframe_success" style="display:none">
150
+ <?php $this->set('messages', array('success'=>array(
151
+ 'Download completed. You can proceed with installation',
152
+ ))) ?>
153
+ <?php echo $this->template('messages.phtml') ?>
154
+
155
+ <button class="form-button" type="button" onclick="location.href='<?php echo $this->mageUrl() ?>'"><span>Continue Magento installation</span></button>
156
+ </div>
157
+
158
+ <div id="connect_iframe_failure" style="display:none">
159
+ <?php $this->set('messages', array('error'=>array('There was a problem during downloading of Magento packages. Please check the output frame for errors information and refresh the page to retry again.'))) ?>
160
+ <?php echo $this->template('messages.phtml') ?>
161
+ <button class="form-button" type="button" onclick="location.reload()"><span>Refresh</span></button>
162
+ </div>
163
+
164
+ <script type="text/javascript">
165
+ function togglePanel (element)
166
+ {
167
+ if (element.value == '1') {
168
+ disabledMode = '';
169
+ } else {
170
+ disabledMode = 'none';
171
+ }
172
+ document.getElementById(element.id+'_panel').style.display = disabledMode;
173
+ }
174
+ togglePanel(document.getElementById('use_custom_permissions_mode'));
175
+ togglePanel(document.getElementById('inst_protocol'));
176
+ </script>
177
+
178
+ <script type="text/javascript">
179
+ function installAll(force)
180
+ {
181
+ if (force) {
182
+ if (!confirm("This will delete all files from core packages.\n\nAre you sure you wish to force re-install all Magento files?")) {
183
+ return false;
184
+ }
185
+ }
186
+ /**
187
+ * @TODO: create validation of directory/file permission fields
188
+ */
189
+
190
+ return onSubmit();
191
+ }
192
+ </script>
193
+
194
+ <?php echo $this->template('install/footer.phtml') ?>
app/code/local/Mss/downloader/template/install/footer.phtml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <!-- [end] content -->
28
+ </div>
29
+ </div>
30
+
31
+ <!-- [end] center -->
32
+ </div>
33
+ <!-- [end] middle -->
34
+
35
+ <!-- [start] footer -->
36
+ <div class="footer-container">
37
+ <div class="footer">
38
+ <p class="legality">
39
+ Help Us to Keep Magento Healthy - <a href="http://www.magentocommerce.com/bug-tracking" id="bug_tracking_link"><strong>Report All Bugs</strong></a> (Downloader ver. <?php echo Maged_Controller::getVersion();?>)<br/>
40
+
41
+ <script type="text/javascript">
42
+ $('bug_tracking_link').target = "varien_external";
43
+ </script>
44
+ Magento is a trademark of Magento, Inc. Copyright &copy; 2016 Magento Inc.</p>
45
+ </div>
46
+ </div>
47
+ <!-- [end] footer -->
48
+ </body>
49
+ </html>
app/code/local/Mss/downloader/template/install/header.phtml ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
28
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
29
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
30
+ <head>
31
+ <title>Magento Installation Wizard</title>
32
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
33
+
34
+ <link type="image/x-icon" href="<?php echo $this->baseUrl()?>/favicon.ico" rel="icon"/>
35
+ <link type="image/x-icon" href="<?php echo $this->baseUrl()?>/favicon.ico" rel="shortcut icon"/>
36
+
37
+ <script type="text/javascript" src="<?php echo $this->baseUrl()?>/js/prototype.js" ></script>
38
+
39
+ <link rel="stylesheet" href="<?php echo $this->baseUrl()?>/skin/install/reset.css" type="text/css" media="all"/>
40
+ <link rel="stylesheet" href="<?php echo $this->baseUrl()?>/skin/install/boxes.css" type="text/css" media="all"/>
41
+ <link rel="stylesheet" href="<?php echo $this->baseUrl()?>/skin/install/clears.css" type="text/css" media="all"/>
42
+
43
+ <!--[if IE]><link rel="stylesheet" href="<?php echo $this->baseUrl()?>/skin/install/iestyles.css" type="text/css" media="all"/><![endif]-->
44
+ <!--[if lt IE 7]><link rel="stylesheet" href="<?php echo $this->baseUrl()?>/skin/install/ie7minus.css" type="text/css" media="all"/><![endif]-->
45
+ </head>
46
+
47
+ <body>
48
+ <!-- [start] header -->
49
+ <div class="header">
50
+ <div class="header-top-container">
51
+ <div class="header-top">
52
+ <h1 id="logo">
53
+ <a href="<?php echo $this->baseUrl()?>"><img src="<?php echo $this->baseUrl()?>/skin/install/images/<?php echo($this->get('channel_logo')); ?>.gif" alt="Magento"/></a>
54
+ </h1>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ <!-- [end] header -->
59
+
60
+ <!-- [start] middle -->
61
+ <div class="middle-container">
62
+ <div class="middle col-2-left-layout">
63
+
64
+
65
+
66
+ <!-- [start] left -->
67
+
68
+ <div class="col-left side-col">
69
+ <div style="border:1px solid #ccc; background:#f6f6f6;">
70
+ <h2 style="margin-bottom:0; border-bottom:1px solid #ccc; padding:4px 10px; color:#3c5974; font-size:1.4em;">Installation</h2>
71
+ <ol style="padding:10px; border-top:1px solid #fff;">
72
+ <li>Welcome</li>
73
+ <li>Validation</li>
74
+ <li>Magento Connect Manager Deployment</li>
75
+ <?php echo($this->get('channel_steps')); ?>
76
+ <li style="color:green; font-weight:bold; ">Download</li>
77
+ <li >License Agreement</li>
78
+ <li >Localization</li>
79
+ <li >Configuration</li>
80
+
81
+ <li >Create Admin Account</li>
82
+ <li >You're All Set!</li>
83
+ </ol>
84
+ </div>
85
+
86
+ <br/>
87
+ <p>
88
+ Having trouble installing Magento? Check out our <a href="http://www.magentocommerce.com/knowledge-base/entry/magento-installation-cheat-sheet" id="installation_guide_link">Installation Guide</a>
89
+ <script type="text/javascript">
90
+ $('installation_guide_link').target = "installation_guide";
91
+ </script>
92
+
93
+ </p>
94
+ &nbsp;
95
+ </div>
96
+ <div id="main" class="col-main">
97
+ <!-- [start] global messages -->
98
+ <!-- [end] global messages -->
99
+ <!-- [start] content -->
app/code/local/Mss/downloader/template/install/writable.phtml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php echo $this->template('install/header.phtml') ?>
28
+ <div class="page-head">
29
+ <h3 style="color:red">Error: Please check for sufficient write file permissions</h3>
30
+ </div>
31
+
32
+ <p>Your Magento folder does not have sufficient write permissions, which this web based downloader requires.</p>
33
+ <p>If you wish to proceed downloading Magento packages online, please set all Magento folders to have writable permission for the web server user (example: apache) and press the "Refresh" button to try again.</p>
34
+
35
+ <button class="form-button" type="button" onclick="location.reload()"><span>Refresh</span></button>
36
+ <br/><br/><br/>
37
+ <p>To learn more about setting write permissions, please visit <a href="http://www.magentocommerce.com/knowledge-base/entry/magento-installation-guide" target="Install_Help">the Magento community site</a> for further details.</p>
38
+ <p>Alternatively, if you are a developer and familiar with SVN, you can follow <a href="http://www.magentocommerce.com/svn" target="Install_Help">these instructions</a> to check out the latest Magento branch.</p>
39
+ <?php echo $this->template('install/footer.phtml') ?>
40
+
app/code/local/Mss/downloader/template/login.phtml ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php echo $this->template('header.phtml') ?>
28
+ <?php if ($returnUrl = $this->controller()->session()->getReturnUrl()): ?>
29
+ <a class="f-right" href="<?php echo htmlentities($returnUrl) ?>">Return to Magento Administration</a>
30
+ <?php endif ?>
31
+ <div style="width:300px; padding:20px; margin:90px auto !important; background:#f6f6f6;">
32
+ <form method="post" action="#">
33
+ <input name="form_key" type="hidden" value="<?php echo $this->getFormKey() ?>" />
34
+ <h2 class="page-head">Log In</h2>
35
+ <p><small>Please re-enter your Magento Adminstration Credentials.<br/>Only administrators with full permissions will be able to log in.</small></p>
36
+ <table class="form-list">
37
+ <tr><td class="label"><label for="username">Username:</label></td><td class="value"><input id="username" name="username" value=""/></td></tr>
38
+ <tr><td class="label"><label for="password">Password:</label></td><td class="value"><input type="password" id="password" name="password"/></td></tr>
39
+ <tr><td></td>
40
+ <td class="value"><button type="submit">Log In</button></td></tr>
41
+ </table>
42
+ </form>
43
+ </div>
44
+ <?php echo $this->template('footer.phtml') ?>
app/code/local/Mss/downloader/template/messages.phtml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php if ($messages = $this->get('messages')): ?>
28
+ <ul class="msgs">
29
+ <?php foreach ($messages as $type=>$msgs): ?>
30
+ <li>
31
+ <ul class="<?php echo $type ?>-msg">
32
+ <?php foreach ($msgs as $msg): ?>
33
+ <li><?php echo $this->escapeHtml($msg) ?></li>
34
+ <?php endforeach; ?>
35
+ </ul>
36
+ </li>
37
+ <?php endforeach; ?>
38
+ </ul>
39
+ <?php endif; ?>
app/code/local/Mss/downloader/template/noroute.phtml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php echo $this->template('header.phtml') ?>
28
+ <h2 class="page-head">404 - Invalid Page</h2>
29
+ <p>Vestibulum tristique venenatis velit. Ut urna nisl, dignissim vitae, cursus eget, pulvinar scelerisque, lectus. In ac leo id libero consequat dignissim. Sed aliquam est a pede. Phasellus ut turpis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed magna leo, volutpat eget, pretium tristique, varius vitae, tellus. Sed odio ante, sagittis id, euismod eu, bibendum quis, purus. Proin consectetuer elementum nunc. Mauris turpis.</p>
30
+ <?php echo $this->template('footer.phtml') ?>
31
+
app/code/local/Mss/downloader/template/settings.phtml ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <?php echo $this->template('header.phtml') ?>
28
+
29
+ <script type="text/javascript">
30
+ function useCustomPermissions (element)
31
+ {
32
+ if (element.value == '1') {
33
+ disabledMode = 'block';
34
+ } else {
35
+ disabledMode = 'none';
36
+ }
37
+ document.getElementById('use_custom_permissions_mode_panel').style.display = disabledMode;
38
+ }
39
+ function changeDeploymentType (element)
40
+ {
41
+ if (element.value == 'ftp') {
42
+ disabledMode = 'block';
43
+ } else {
44
+ disabledMode = 'none';
45
+ }
46
+ document.getElementById('deployment_type_panel').style.display = disabledMode;
47
+ }
48
+ </script>
49
+
50
+ <div class="settings-page">
51
+ <h2 class="page-head">Settings</h2>
52
+ <form action="<?php echo $this->url('settingsPost') ?>" method="post">
53
+ <input name="form_key" type="hidden" value="<?php echo $this->getFormKey() ?>" />
54
+ <fieldset>
55
+ <p>Magento Extensions are available in three different versions.</p>
56
+ <ul class="disc">
57
+ <li><strong>Stable</strong> means the extension can be used in a production environment.</li>
58
+ <li><strong>Beta</strong> means the extension is not recommended for use in a production environment.</li>
59
+ <li><strong>Alpha</strong> means the extension is still in development.</li>
60
+ </ul>
61
+ <p><strong>Please note: extensions are provided as is. Make sure to backup your data before installing new extensions.</strong></p>
62
+ <table cellspacing="0" class="form-list">
63
+ <tr>
64
+ <td class="label">Magento Connect Channel Protocol:</td>
65
+ <td class="value">
66
+ <select id="protocol" name="protocol">
67
+ <option value="https" <?php if ($this->get('protocol')=='https'):?>selected="selected"<?php endif ?>>Https</option>
68
+ <option value="http" <?php if ($this->get('protocol')=='http'):?>selected="selected"<?php endif ?>>Http</option>
69
+ </select>
70
+ </td>
71
+ </tr>
72
+ <?php echo $this->get('channel_protocol_fields'); ?>
73
+ <tr>
74
+ <td class="label">Preferred State:</td>
75
+ <td class="value">
76
+ <select id="preferred_state" name="preferred_state">
77
+ <option value="stable" <?php if ($this->get('preferred_state')=='stable'):?>selected="selected"<?php endif ?>>Stable</option>
78
+ <option value="beta" <?php if ($this->get('preferred_state')=='beta'):?>selected="selected"<?php endif ?>>Beta</option>
79
+ <option value="alpha" <?php if ($this->get('preferred_state')=='alpha'):?>selected="selected"<?php endif ?>>Alpha</option>
80
+ </select>
81
+ </td>
82
+ </tr>
83
+ <!--
84
+ <tr>
85
+ <td class="label">Magento Installation Directory:</td>
86
+ <td class="value"><input name="mage_dir" value="<?php echo htmlentities($this->get('mage_dir'))?>" style="width:250px;"/></td>
87
+ </tr>
88
+ -->
89
+ </table>
90
+ <p><strong>Permission to create new files and folders.</strong></p>
91
+ <table cellspacing="0" class="form-list">
92
+ <tr>
93
+ <td class="label">Use custom permissions:</td>
94
+ <td class="value">
95
+ <select onchange="useCustomPermissions(this)" id="use_custom_permissions_mode" name="use_custom_permissions_mode">
96
+ <option value="1" <?php if ($this->get('use_custom_permissions_mode')=='1'):?>selected="selected"<?php endif ?>>Yes</option>
97
+ <option value="0" <?php if ($this->get('use_custom_permissions_mode')=='0'):?>selected="selected"<?php endif ?>>No</option>
98
+ </select>
99
+ </td>
100
+ </tr>
101
+ </table>
102
+ <table cellspacing="0" class="form-list" id="use_custom_permissions_mode_panel" <?php if ($this->get('use_custom_permissions_mode')=='0'):?>style="display:none;"<?php endif ?>>
103
+ <tr>
104
+ <td class="label">Folders:</td>
105
+ <td class="value">
106
+ <input id="mkdir_mode" name="mkdir_mode" value="<?php echo($this->get('mkdir_mode'));?>" class="input-text" type="text"></input>
107
+ </td>
108
+ </tr>
109
+ <tr>
110
+ <td class="label">Files:</td>
111
+ <td class="value">
112
+ <input id="chmod_file_mode" name="chmod_file_mode" value="<?php echo($this->get('chmod_file_mode'));?>" class="input-text" type="text"></input>
113
+ </td>
114
+ </tr>
115
+ </table>
116
+
117
+ <p><strong>Deployment.</strong></p>
118
+ <table cellspacing="0" class="form-list">
119
+ <tr>
120
+ <td class="label">Deployment Type:</td>
121
+ <td class="value">
122
+ <input value="fs" type="radio" name="deployment_type" id="deployment_fs" onclick="changeDeploymentType(this)" <?php if ($this->get('deployment_type')=='fs'):?>checked="checked"<?php endif ?> <?php if ($this->get('fs_disabled')):?>disabled="disabled"<?php endif ?> />
123
+ <label for="deployment_fs"> <span class="label">Local Filesystem</span> </label>
124
+ </td>
125
+ </tr>
126
+ <tr>
127
+ <td class="label">&nbsp;</td>
128
+ <td class="value">
129
+ <input value="ftp" type="radio" name="deployment_type" id="deployment_ftp" onclick="changeDeploymentType(this)" <?php if ($this->get('deployment_type')=='ftp'):?>checked="checked"<?php endif ?> />
130
+ <label for="deployment_ftp"><span class="label">FTP Connection</span></label>
131
+ </td>
132
+ </tr>
133
+ </table>
134
+ <table cellspacing="0" class="form-list" id="deployment_type_panel" <?php if ($this->get('deployment_type')!='ftp'):?>style="display:none;"<?php endif ?>>
135
+ <tr>
136
+ <td class="label">FTP Host:</td>
137
+ <td class="value">
138
+ <input id="ftp_host" name="ftp_host" value="<?php echo($this->get('ftp_host'));?>" class="input-text" type="text"></input>
139
+ </td>
140
+ </tr>
141
+ <tr>
142
+ <td class="label">FTP Login:</td>
143
+ <td class="value">
144
+ <input id="ftp_login" name="ftp_login" value="<?php echo($this->get('ftp_login'));?>" class="input-text" type="text"></input>
145
+ </td>
146
+ </tr>
147
+ <tr>
148
+ <td class="label">FTP Password:</td>
149
+ <td class="value">
150
+ <input id="ftp_password" name="ftp_password" value="<?php echo($this->get('ftp_password'));?>" class="input-text" type="password"></input>
151
+ </td>
152
+ </tr>
153
+ <tr>
154
+ <td class="label">Installation Path:</td>
155
+ <td class="value">
156
+ <input id="ftp_path" name="ftp_path" value="<?php echo($this->get('ftp_path'));?>" class="input-text" type="text"></input>
157
+ </td>
158
+ </tr>
159
+ </table>
160
+
161
+ <p><button type="submit">Save Settings</button></p>
162
+ </fieldset>
163
+ </form>
164
+ </div>
165
+
166
+ <?php echo $this->template('footer.phtml') ?>
167
+
app/code/local/Mss/downloader/template/writable.phtml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-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 design
22
+ * @package default
23
+ * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <div class="error-msg">
28
+ <h4>Warning: Your Magento folder does not have sufficient write permissions.</h4>
29
+ </div>
30
+
31
+ <p>
32
+ If you wish to proceed downloading Magento packages online, please set all Magento folders to
33
+ have writable permission for the web server user (example: apache) or set up FTP Connection on the
34
+ Magento Connect Manager <a href="<?php echo $this->url('settings')?>">Settings</a> tab.
35
+ </p>
package.xml CHANGED
@@ -1,18 +1,19 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Mss_Connector</name>
4
- <version>2.6.2</version>
5
  <stability>stable</stability>
6
  <license>OSL v1.0</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Mobile Multi store app for Android and Iphone</summary>
10
  <description>Mobile Multistore app for Android and Iphone</description>
11
- <notes>fixed some minor bugs</notes>
 
12
  <authors><author><name>mss</name><user>mss</user><email>mss.yogendra@gmail.com</email></author></authors>
13
- <date>2017-02-01</date>
14
- <time>06:02:40</time>
15
- <contents><target name="magelocal"><dir name="Mss"><dir name="Bannersliderapp"><dir name="Block"><dir name="Adminhtml"><dir name="Bannersliderapp"><dir name="Edit"><file name="Form.php" hash="c55bbba3b00c98a068bec9b9b12c4a40"/><dir name="Tab"><file name="Form.php" hash="337f9ecaa1f491cd779ed018f65316ae"/></dir><file name="Tabs.php" hash="ec6e540fda2b39feedc0a4c1192a3c7d"/></dir><file name="Edit.php" hash="010f4999a1ddc53e411562d83c3ad3f8"/><file name="Grid.php" hash="28c70476bdd3d44aa2cac9dc9f423ebb"/><dir name="Helper"><file name="Image.php" hash="d2ce47b0d7ab6ef5c31d0989fcc05f78"/></dir></dir><file name="Grid.php" hash="9c86bf7a2daa24e9416ff254396b2aa0"/><dir name="Renderer"><file name="Image.php" hash="0a9b4358a9409e7933e96c1eb157717e"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="db48c09c76d16ad7c094d32224329276"/></dir><dir name="Model"><file name="Bannersliderapp.php" hash="61f481ac93c5c494889d5ea7cb306bc0"/><dir name="Mysql4"><dir name="Bannersliderapp"><file name="Collection.php" hash="5d6543bbf3dee4d17b73244dbd0f843f"/></dir><file name="Bannersliderapp.php" hash="e000805a295e083e81f7163df7b92197"/></dir><file name="Observer.php" hash="65004e950e366b77a2cd1cb177d0f1ab"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="BannersliderappController.php" hash="6f9f94fd96e35225ed3bd8fdf7a3dc22"/></dir><file name="BannerController.php" hash="36bd22c81ff14c2f6d04c40916020b6d"/></dir><dir name="etc"><file name="adminhtml.xml" hash="dab3fdde55b6523faadc3fad70702c28"/><file name="config.xml" hash="17c28ecccbd87140087d4e870c3a7f97"/></dir><dir name="sql"><dir name="bannersliderapp_setup"><file name="mysql4-install-0.1.1.php" hash="bbc6f32eb101c83a52cdef67c8b6a806"/><file name="mysql4-upgrade-0.1.1-0.1.2.php" hash="6df036187a26ac6dcea3473d8065f59a"/></dir></dir></dir><dir name="Connector"><dir name="Block"><dir name="Adminhtml"><file name="Notifications.php" hash="6f24014b5a24a4f56410e9754b8aa2d5"/><file name="Support.php" hash="d120e7f8945a01d791d0f3d2c32dcfcf"/></dir><dir name="System"><dir name="Config"><file name="About.php" hash="2e9dc040ee2d42a57d5c9411f0b999e4"/><file name="Authorizenet.php" hash="ed644e9814fef74147bdddf24cfd75c1"/><file name="Banktransfer.php" hash="77f6ebf2074462cdadf4bccbe2f0d19a"/><file name="Checkmo.php" hash="edfc0fc0b233cd349392e563eeac57ed"/><file name="Cod.php" hash="37d1757764340fd02b8be7ac32434967"/><file name="Mpaypal.php" hash="e69d6a2d58618cf741d4cf503ede70ca"/><file name="Payu.php" hash="d0307013bdf58700a29aa7838ee94e51"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="2b2b667df63e7cd32c974d21620c6a91"/></dir><dir name="Model"><file name="Connector.php" hash="e9a927bc0a5974d092ab3af257ee7607"/><dir name="Mysql4"><dir name="Connector"><file name="Collection.php" hash="1f3bb37f160abdf974859f7419a19b65"/></dir><file name="Connector.php" hash="185189264d3275af813349e721ee46fb"/></dir><file name="Observer.php" hash="2c70ee00a83aaae12a05c604f59af29f"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="SupportController.php" hash="0f5afef5730673f0145cd5c8bbf1ed77"/></dir><file name="CartController.php" hash="cf79b0f8c52ee68b5eb0de401a2ca74a"/><file name="CreditController.php" hash="a489dd0ed95914fb2b58491410f6f92f"/><file name="CustomerController.php" hash="1fb524e6c082786bb1210d5b646654e6"/><file name="FeedbackController.php" hash="2b9e092984c0c64397cd25fe1d2266d5"/><file name="IndexController.php" hash="6505b388da82853149fc5682e173d583"/><file name="ItemsController.php" hash="03aeb9fceec3173e1aa678e03582b226"/><file name="ProductsController.php" hash="e864cd359f8079384e9f1ad325b85a77"/><file name="StaticpagesController.php" hash="f49d4cef2d1baf269e5ac19994619037"/><file name="StoreinfoController.php" hash="c7600983d865fe529e020344e485cbed"/><file name="TokenController.php" hash="30e09062bb6f613c2ec3167da27cd571"/><file name="WishlistController.php" hash="082445ed48fde71569305aba02177337"/></dir><dir name="etc"><file name="adminhtml.xml" hash="dace418dcc6eee76831169b5c70176e7"/><file name="config.xml" hash="b8b277ce7f3c287ae465a8d5ba107976"/><file name="system.xml" hash="b5782f2d21d04ba07cf411563fcf98a1"/></dir><dir name="sql"><dir name="connector_setup"><file name="mysql4-install-0.1.0.php" hash="4325ba30b21f9680b11d4b124b9e8181"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="eaa00e880b38ba41580b67785b33ed10"/></dir></dir></dir><dir name="Mpaypal"><dir name="Helper"><file name="Data.php" hash="c3ba57e7cc86210346b1b3f279083c0f"/></dir><dir name="Model"><file name="Mpaypal.php" hash="f49b32aad7d7bed49333534139fd07b7"/><file name="Observer.php" hash="4b92aaf547f0b080d8495cf064574d10"/></dir><dir name="controllers"><file name="IndexController.php" hash="14098d1e6290ba8f8439c564335e1a2a"/></dir><dir name="etc"><file name="config.xml" hash="9ed76ff53b5e0232b4ea442a7e046b14"/><file name="system.xml" hash="2f51ad686858a69e07e8c21baf5d690e"/></dir></dir><dir name="Payu"><dir name="Block"><file name="Index.php" hash="f6a324c1ac4b0c1dcfac775c51c2a34c"/></dir><dir name="Helper"><file name="Data.php" hash="7800e0e58258b78d0f23a7fec482d120"/></dir><dir name="controllers"><file name="IndexController.php" hash="46ec9fef2d62fa7c4e67f937f40685af"/></dir><dir name="etc"><file name="config.xml" hash="c6867fb0cc7efdde39c32a3ecbf62433"/></dir></dir><dir name="Pushnotification"><dir name="Block"><dir name="Adminhtml"><file name="Pushnotificationbackend.php" hash="6b9e143ee7b5fe4fc2642eee977b44bf"/></dir></dir><dir name="Helper"><file name="Data.php" hash="d84a29d3aa0fb6655300cab13a70f0cd"/></dir><dir name="Model"><dir name="Entity"><file name="Resource.php" hash="93b6a261762541433fa601aefb60d0a7"/></dir><dir name="Mysql4"><dir name="Pushnotification"><file name="Collection.php" hash="392612adedcb14ec5dcaaa4ea9858091"/></dir><file name="Pushnotification.php" hash="77f6cadb7682377a1de6b275310c1cf6"/></dir><file name="Pushnotification.php" hash="ad5fe0f74049c61402ff99fc32d8164a"/><dir name="System"><dir name="Config"><dir name="Backend"><file name="File.php" hash="d7c74e49b78bb9da3453bd5f414a445f"/><file name="Image.php" hash="e1d98dbf511fe16581b37a8b7b43f5b4"/><file name="Iosmode.php" hash="ff1794ef4844019b7af64192fbd4e122"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="PushnotificationbackendController.php" hash="ec4ebd0ad1cfee78d2e67a69698a14e5"/></dir></dir><dir name="etc"><file name="config.xml" hash="daafb506dc1ed6bd54d8f8049e2e9595"/><file name="system.xml" hash="23a622dec8250a355bbaed9e83f1f82d"/></dir><dir name="sql"><dir name="pushnotification_setup"><file name="mysql4-install-0.1.0.php" hash="571b53fa424e343507d73689708b0596"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="e5939f147e797d9d8b7a9643f8cda7d8"/></dir></dir></dir><dir name="Sociallogin"><dir name="Helper"><file name="Data.php" hash="8965f0b6a0127d0965d99987aa0a300c"/></dir><dir name="Model"><dir name="Mysql4"><file name="Sociallogin.php" hash="b881bc47c5ee70b1c4c02b59501ffbc5"/></dir><file name="Sociallogin.php" hash="0ba90dadb0f34528c2296704c5cea233"/></dir><dir name="etc"><file name="config.xml" hash="eac1dc2364bc283a9cd5326eb7e852a9"/></dir><dir name="sql"><dir name="sociallogin_setup"><file name="mysql4-install-0.1.0.php" hash="163332cb130dae297af332cbefde58f3"/></dir></dir></dir></dir></target><target name="magedesign"><dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="pushnotification"><file name="pushnotificationbackend.phtml" hash="138add7171fdd7fb326abc4a4f9dbe5a"/></dir><dir name="connector"><file name="landing.phtml" hash="6efda7cca18e7bc62ce40c9f25a9510b"/><file name="notification.phtml" hash="164e5f9e7dcfc5c2d2451f0e77776d77"/><file name="support.phtml" hash="7c799c058795eafbf96239e16e3326ca"/></dir></dir><dir name="layout"><file name="bannersliderapp.xml" hash="f18034448b9f74646c870a23bfc0b6fd"/><file name="pushnotification.xml" hash="f7fd974e63c4c7eb5ffac7b059470946"/><file name="connector.xml" hash="003166428e55a52301f71826a37f8283"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="payu.xml" hash="473595488f536cb588c5588a744915a3"/><file name="mpaypal.xml" hash="7b75c5bed6f3142c8bc9e4c1233bf1e9"/></dir><dir name="template"><dir name="payu"><file name="index.phtml" hash="5f9e2dfb00a991707e31a00b39cfebef"/><file name="test.phtml" hash="da4701ff5b2c64444a49f77571e8a00c"/></dir><dir name="mpaypal"><file name="index.phtml" hash="df077c063b2006b9321c96cd6744b19f"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir><dir name="modules"><file name="Mss_Bannersliderapp.xml" hash="de3e077185056246492c3a2ff01a531f"/><file name="Mss_Connector.xml" hash="ba8a5609c9c8c3636f183c5bfe04d664"/><file name="Mss_Payu.xml" hash="5feac03d698b481473223fbe6a8814b1"/><file name="Mss_Pushnotification.xml" hash="2e8e9bc56a5f0ff8bb42f43fb5a3a3db"/><file name="Mss_Sociallogin.xml" hash="8671199bdad3bdecbfe0c47ce9ff05e6"/><file name="Mss_Mpaypal.xml" hash="4d6a7f8d862de8c449b1366727ef0a6d"/></dir></dir></target><target name="mageskin"><dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="images"><dir name="magentomobileshop"><file name="magento_logo.png" hash="d1800a3c95de49500f158bfb6ca9c70c"/><file name="magentomobileshop_loader.gif" hash="453272c9cacd32efe6465961ea8a61dd"/></dir></dir></dir></dir></dir></dir></target></contents>
16
  <compatible/>
17
- <dependencies><required><php><min>5.3.0</min><max>7.0.5</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Mss_Connector</name>
4
+ <version>2.6.3</version>
5
  <stability>stable</stability>
6
  <license>OSL v1.0</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Mobile Multi store app for Android and Iphone</summary>
10
  <description>Mobile Multistore app for Android and Iphone</description>
11
+ <notes>1.Google Login Functionality Bug Removed.&#xD;
12
+ 2.Product Listing Filter Improved.</notes>
13
  <authors><author><name>mss</name><user>mss</user><email>mss.yogendra@gmail.com</email></author></authors>
14
+ <date>2017-05-19</date>
15
+ <time>07:53:34</time>
16
+ <contents><target name="magelocal"><dir name="Mss"><dir name="Bannersliderapp"><dir name="Block"><dir name="Adminhtml"><dir name="Bannersliderapp"><dir name="Edit"><file name="Form.php" hash="c55bbba3b00c98a068bec9b9b12c4a40"/><dir name="Tab"><file name="Form.php" hash="337f9ecaa1f491cd779ed018f65316ae"/></dir><file name="Tabs.php" hash="ec6e540fda2b39feedc0a4c1192a3c7d"/></dir><file name="Edit.php" hash="010f4999a1ddc53e411562d83c3ad3f8"/><file name="Grid.php" hash="28c70476bdd3d44aa2cac9dc9f423ebb"/><dir name="Helper"><file name="Image.php" hash="d2ce47b0d7ab6ef5c31d0989fcc05f78"/></dir></dir><file name="Grid.php" hash="9c86bf7a2daa24e9416ff254396b2aa0"/><dir name="Renderer"><file name="Image.php" hash="0a9b4358a9409e7933e96c1eb157717e"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="db48c09c76d16ad7c094d32224329276"/></dir><dir name="Model"><file name="Bannersliderapp.php" hash="61f481ac93c5c494889d5ea7cb306bc0"/><dir name="Mysql4"><dir name="Bannersliderapp"><file name="Collection.php" hash="5d6543bbf3dee4d17b73244dbd0f843f"/></dir><file name="Bannersliderapp.php" hash="e000805a295e083e81f7163df7b92197"/></dir><file name="Observer.php" hash="65004e950e366b77a2cd1cb177d0f1ab"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="BannersliderappController.php" hash="6f9f94fd96e35225ed3bd8fdf7a3dc22"/></dir><file name="BannerController.php" hash="36bd22c81ff14c2f6d04c40916020b6d"/></dir><dir name="etc"><file name="adminhtml.xml" hash="dab3fdde55b6523faadc3fad70702c28"/><file name="config.xml" hash="17c28ecccbd87140087d4e870c3a7f97"/></dir><dir name="sql"><dir name="bannersliderapp_setup"><file name="mysql4-install-0.1.1.php" hash="bbc6f32eb101c83a52cdef67c8b6a806"/><file name="mysql4-upgrade-0.1.1-0.1.2.php" hash="6df036187a26ac6dcea3473d8065f59a"/></dir></dir></dir><dir name="Bargain"><dir name="Helper"><file name="Data.php" hash="e587d632ee994985495d613e0b23a196"/></dir><dir name="controllers"><file name="IndexController.php" hash="f63f6c268b8530fe7e398cc234b217d5"/></dir><dir name="etc"><file name="config.xml" hash="d091fef524e7460565b0f534633c8c93"/></dir></dir><dir name="Connector"><dir name="Block"><dir name="Adminhtml"><file name="Notifications.php" hash="6f24014b5a24a4f56410e9754b8aa2d5"/><file name="Support.php" hash="d120e7f8945a01d791d0f3d2c32dcfcf"/></dir><dir name="System"><dir name="Config"><file name="About.php" hash="2e9dc040ee2d42a57d5c9411f0b999e4"/><file name="Authorizenet.php" hash="ed644e9814fef74147bdddf24cfd75c1"/><file name="Banktransfer.php" hash="77f6ebf2074462cdadf4bccbe2f0d19a"/><file name="Checkmo.php" hash="edfc0fc0b233cd349392e563eeac57ed"/><file name="Cod.php" hash="37d1757764340fd02b8be7ac32434967"/><file name="Mpaypal.php" hash="e69d6a2d58618cf741d4cf503ede70ca"/><file name="Payu.php" hash="d0307013bdf58700a29aa7838ee94e51"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="2b2b667df63e7cd32c974d21620c6a91"/></dir><dir name="Model"><file name="Connector.php" hash="e9a927bc0a5974d092ab3af257ee7607"/><dir name="Mysql4"><dir name="Connector"><file name="Collection.php" hash="1f3bb37f160abdf974859f7419a19b65"/></dir><file name="Connector.php" hash="185189264d3275af813349e721ee46fb"/></dir><file name="Observer.php" hash="2c70ee00a83aaae12a05c604f59af29f"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="SupportController.php" hash="0f5afef5730673f0145cd5c8bbf1ed77"/></dir><file name="CartController.php" hash="cf79b0f8c52ee68b5eb0de401a2ca74a"/><file name="CreditController.php" hash="a489dd0ed95914fb2b58491410f6f92f"/><file name="CustomerController.php" hash="983a0acb367054bcb4f80058bb21bf9e"/><file name="FeedbackController.php" hash="2b9e092984c0c64397cd25fe1d2266d5"/><file name="IndexController.php" hash="11f56bffb261a5e4f07062c1b932cfb3"/><file name="ItemsController.php" hash="03aeb9fceec3173e1aa678e03582b226"/><file name="ProductsController.php" hash="e864cd359f8079384e9f1ad325b85a77"/><file name="StaticpagesController.php" hash="565d0cb7ef788975e436f2984bd4a1a7"/><file name="StoreinfoController.php" hash="c7600983d865fe529e020344e485cbed"/><file name="TokenController.php" hash="30e09062bb6f613c2ec3167da27cd571"/><file name="WishlistController.php" hash="082445ed48fde71569305aba02177337"/><file name="index.php" hash="f590b9dd88c9b768c3934f88beb2e917"/></dir><dir name="etc"><file name="adminhtml.xml" hash="dace418dcc6eee76831169b5c70176e7"/><file name="config.xml" hash="8fc24030fb0ae502b7979c7de83ab7ac"/><file name="system.xml" hash="b5782f2d21d04ba07cf411563fcf98a1"/></dir><dir name="sql"><dir name="connector_setup"><file name="mysql4-install-0.1.0.php" hash="4325ba30b21f9680b11d4b124b9e8181"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="eaa00e880b38ba41580b67785b33ed10"/></dir></dir></dir><dir name="Mpaypal"><dir name="Helper"><file name="Data.php" hash="c3ba57e7cc86210346b1b3f279083c0f"/></dir><dir name="Model"><file name="Mpaypal.php" hash="f49b32aad7d7bed49333534139fd07b7"/><file name="Observer.php" hash="4b92aaf547f0b080d8495cf064574d10"/></dir><dir name="controllers"><file name="IndexController.php" hash="14098d1e6290ba8f8439c564335e1a2a"/></dir><dir name="etc"><file name="config.xml" hash="9ed76ff53b5e0232b4ea442a7e046b14"/><file name="system.xml" hash="2f51ad686858a69e07e8c21baf5d690e"/></dir></dir><dir name="Payu"><dir name="Block"><file name="Index.php" hash="f6a324c1ac4b0c1dcfac775c51c2a34c"/></dir><dir name="Helper"><file name="Data.php" hash="7800e0e58258b78d0f23a7fec482d120"/></dir><dir name="controllers"><file name="IndexController.php" hash="46ec9fef2d62fa7c4e67f937f40685af"/></dir><dir name="etc"><file name="config.xml" hash="c6867fb0cc7efdde39c32a3ecbf62433"/></dir></dir><dir name="Popup"><dir name="Block"><file name="Popup.php" hash="f931124728df9d9e62ca1e49a649f1e1"/></dir><dir name="Helper"><file name="Data.php" hash="e6ae4527a51de43bda3afed1153228f8"/></dir><dir name="Model"><dir name="Source"><file name="Page.php" hash="d6ac2e8552aa0a37c9abe4f6a0b61319"/><file name="Truefalse.php" hash="e1b0d5020caeb4990faade97d905bb86"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="1feb00f84959a547af18f76c05726cf3"/><file name="config.xml" hash="5a58d6e400096be30b1720c39d102da4"/></dir></dir><dir name="Pushnotification"><dir name="Block"><dir name="Adminhtml"><file name="Pushnotificationbackend.php" hash="6b9e143ee7b5fe4fc2642eee977b44bf"/></dir></dir><dir name="Helper"><file name="Data.php" hash="d84a29d3aa0fb6655300cab13a70f0cd"/></dir><dir name="Model"><dir name="Entity"><file name="Resource.php" hash="93b6a261762541433fa601aefb60d0a7"/></dir><dir name="Mysql4"><dir name="Pushnotification"><file name="Collection.php" hash="392612adedcb14ec5dcaaa4ea9858091"/></dir><file name="Pushnotification.php" hash="77f6cadb7682377a1de6b275310c1cf6"/></dir><file name="Pushnotification.php" hash="ad5fe0f74049c61402ff99fc32d8164a"/><dir name="System"><dir name="Config"><dir name="Backend"><file name="File.php" hash="d7c74e49b78bb9da3453bd5f414a445f"/><file name="Image.php" hash="e1d98dbf511fe16581b37a8b7b43f5b4"/><file name="Iosmode.php" hash="ff1794ef4844019b7af64192fbd4e122"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="PushnotificationbackendController.php" hash="ec4ebd0ad1cfee78d2e67a69698a14e5"/></dir></dir><dir name="etc"><file name="config.xml" hash="daafb506dc1ed6bd54d8f8049e2e9595"/><file name="system.xml" hash="23a622dec8250a355bbaed9e83f1f82d"/></dir><dir name="sql"><dir name="pushnotification_setup"><file name="mysql4-install-0.1.0.php" hash="571b53fa424e343507d73689708b0596"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="e5939f147e797d9d8b7a9643f8cda7d8"/></dir></dir></dir><dir name="Sociallogin"><dir name="Helper"><file name="Data.php" hash="64c04ff04481307fa2480a27d97fd92a"/></dir><dir name="Model"><dir name="Mysql4"><file name="Sociallogin.php" hash="b881bc47c5ee70b1c4c02b59501ffbc5"/></dir><file name="Sociallogin.php" hash="0ba90dadb0f34528c2296704c5cea233"/></dir><dir name="etc"><file name="config.xml" hash="eac1dc2364bc283a9cd5326eb7e852a9"/></dir><dir name="sql"><dir name="sociallogin_setup"><file name="mysql4-install-0.1.0.php" hash="163332cb130dae297af332cbefde58f3"/></dir></dir></dir><file name="cache.cfg" hash="3c909cc0a4c1e6341dce142fa70e1c19"/><file name="connect.cfg" hash="7cf65d3821fa2e85ba9f7c883a2a8ec1"/><dir name="downloader"><dir name="Maged"><dir name="Connect"><file name="Frontend.php" hash="1fe594862033bdaa75e04ca2bdbbff17"/></dir><file name="Connect.php" hash="c5733623d0aa65c0f139f4871cb7fa4f"/><file name="Controller.php" hash="935bc6849724d39acfdf5a8de12d9268"/><file name="Exception.php" hash="a42db400bc39f8bf3b59f72ba97d977f"/><dir name="Model"><dir name="Config"><file name="Abstract.php" hash="a0cf5733571ff2e6290c21364e3f5c24"/><file name="Community.php" hash="a636eb518434ca1dfe8ca1f01bf379fd"/><file name="Interface.php" hash="4d5fab4370d1d139f066bfebc0feb695"/></dir><file name="Config.php" hash="b97bd285b6de78866c30ee0e7789f916"/><dir name="Connect"><file name="Request.php" hash="00448a099046a24ab66fd5182c963114"/></dir><file name="Connect.php" hash="325bd131537d3b88a3f1c6ce7eec7bf1"/><file name="Dowloader.php" hash="1b11353e50d943a105f2a3de69f58bc4"/><file name="Session.php" hash="7b7cf4f320a9235a3be6ebca96ee5ae2"/></dir><file name="Model.php" hash="6cdf4d7f15043aac54102397fa8969df"/><file name="View.php" hash="fbaf1cf8fc0200f90ee1c02f567b7ee8"/><file name=".htaccess" hash="72617d60821288133a367f70bf39ad93"/></dir><file name="cache.cfg" hash="3c909cc0a4c1e6341dce142fa70e1c19"/><file name="config.ini" hash="a52ba98e71ab19de387b3af1a04c6102"/><file name="connect.cfg" hash="7cf65d3821fa2e85ba9f7c883a2a8ec1"/><file name="favicon.ico" hash="88733ee53676a47fc354a61c32516e82"/><file name="index.php" hash="2d785a16995da61d6ea03aa9eb130c3a"/><dir name="js"><file name="prototype.js" hash="3766aeff5778b54f74f93670322ca0df"/></dir><dir name="lib"><dir name="Mage"><dir name="Archive"><file name="Abstract.php" hash="fe932085a8ee80ced42caa531114f1e0"/><file name="Bz.php" hash="d6426ab0a7999ef9829f8f4ad0ae4f65"/><file name="Gz.php" hash="0825c0e8ac799f5071edc5441935b74b"/><dir name="Helper"><dir name="File"><file name="Bz.php" hash="f9bed06826ecc6d6ad55f303ddaf45c7"/><file name="Gz.php" hash="c839c55d72b3ec5c524113222a650936"/></dir><file name="File.php" hash="5fc72860b28ec0c3a9d075d9ec3899f5"/></dir><file name="Interface.php" hash="141a427b2de40a2425f04a59d84a5ac1"/><file name="Tar.php" hash="6c10e519a593c0414dabc848fdb84baf"/></dir><file name="Archive.php" hash="0644f8db11f1c357b7869945cb5bcd53"/><dir name="Autoload"><file name="Simple.php" hash="286dbec2676d0e7537e5d10d63f03b64"/></dir><dir name="Backup"><file name="Abstract.php" hash="bfe563b766fadff97fd363de8c4df8b1"/><dir name="Archive"><file name="Tar.php" hash="c8fe2ced6e6eec732be365c03cca7a1f"/></dir><file name="Db.php" hash="2ec2fe7b4017b861be4d1440627b3c19"/><dir name="Exception"><file name="CantLoadSnapshot.php" hash="8dda1d8fcb58b38f3a6b34fe14c19738"/><file name="FtpConnectionFailed.php" hash="ac9e832b2502a85d87de7ecd24d0a06e"/><file name="FtpValidationFailed.php" hash="38a4d1b979b7aa23ec285d4ed0cfcbdb"/><file name="NotEnoughFreeSpace.php" hash="18730975d2f1eeb8a7f4e95ea783bbf7"/><file name="NotEnoughPermissions.php" hash="30be06ac99390b6c5a2e697583d967e7"/></dir><file name="Exception.php" hash="e50bd4ee85b423143f408252403938f8"/><dir name="Filesystem"><file name="Helper.php" hash="3a50c7daffcd2a32dfade3b056c6e809"/><dir name="Iterator"><file name="File.php" hash="daac2b8602774cb2ca4dcf2cee275375"/><file name="Filter.php" hash="2f2a5a7b993e5ed9e98b444bf01cfc18"/></dir><dir name="Rollback"><file name="Abstract.php" hash="dbd411d64baeb4255fcd68ea8f4a8657"/><file name="Fs.php" hash="05c8e69bdb6cc499ee6d2e9dfe0df806"/><file name="Ftp.php" hash="e52f99c00cc30c52ce9cf82b39df6cc4"/></dir></dir><file name="Filesystem.php" hash="b94ad4d595d0e4ef7c3255cdad1c7ada"/><file name="Interface.php" hash="1bbad039d29cf54675c59764c0baf381"/><file name="Media.php" hash="267a6da8299593324304af34b9016a88"/><file name="Nomedia.php" hash="f59f14a1dac8f40800a6477341c68df8"/><file name="Snapshot.php" hash="e12f7f3819445d6fce43abc9d6a6d249"/></dir><file name="Backup.php" hash="40a2c5a18460690bfb24474e162f58b2"/><dir name="Connect"><file name="Backup.php" hash="2e4d1e2c1fb8f78bc2033fca475c476f"/><dir name="Channel"><file name="Generator.php" hash="ce1306cd397921a92dabc281215ebcf4"/><file name="Parser.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/><file name="VO.php" hash="e9e715cf8b85960faddaf064f9adcdf0"/></dir><dir name="Command"><file name="Channels.php" hash="3149451cfe1be57bb5cb18b2a9759ec3"/><file name="Channels_Header.php" hash="ad00027c4f5642211ba51d2648931967"/><file name="Config.php" hash="c4aefacf1e0d77b595802700a03b9091"/><file name="Config_Header.php" hash="6308fc5c62ad94c92579e6ba8532764f"/><file name="Install.php" hash="eb7afec2d9b017c40e02561447180cac"/><file name="Install_Header.php" hash="9909984d7cbaedd4433d2638d0c30e55"/><file name="Package.php" hash="19cc7ad69932e84482b87c6c48f8b109"/><file name="Package_Header.php" hash="6783594e2920fcee8c04fdd869ab8dbd"/><file name="Registry.php" hash="623d0f1ab6e7b1c5f8b42bc418db63f8"/><file name="Registry_Header.php" hash="59d72375eac65124fead2e39d65d012e"/><file name="Remote.php" hash="9acf14759e955d7d4bcf5005c59d512f"/><file name="Remote_Header.php" hash="d1e7a277fe5671fb8783100d77bf6517"/></dir><file name="Command.php" hash="6d3eff81db6d7890ed8acf616d0d11a5"/><file name="Config.php" hash="08752165f08baec4736c39c1b2ec6bf7"/><file name="Converter.php" hash="253e0faaf11b3b6ebd4f131b6e194f2b"/><dir name="Frontend"><file name="CLI.php" hash="9640aaca77e3a34934ec543e0bfe8391"/></dir><file name="Frontend.php" hash="1293aa36c6a18cb283a4eee12f7230b5"/><file name="Ftp.php" hash="0323c80694b6acadf93c4a8d0e298a22"/><dir name="Loader"><file name="Ftp.php" hash="2bd56f41f20cbc78725a3ca480f3ecde"/></dir><file name="Loader.php" hash="620b95d854f29f3d7e4d74d192e113a8"/><dir name="Package"><file name="Extension.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/><file name="Hotfix.php" hash="3964d63fe528ff52445afdbef9a3efce"/><file name="Maintainer.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/><file name="Reader.php" hash="f4d55460659a19a38f1e29f08aff71a7"/><file name="Target.php" hash="0674dfd23e69adc5832e330d5fb041d8"/><file name="VO.php" hash="1a37cad472e2d61044321b20ed4ceae4"/><file name="Writer.php" hash="fe7b796442aaf844296baeb9c63715a0"/></dir><file name="Package.php" hash="c301c73d327c386776c196390021f7b5"/><file name="Packager.php" hash="af7af012704cced243becf84fa5baba9"/><dir name="Repository"><file name="Abstract.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/><dir name="Channel"><file name="Abstract.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/><file name="Commercial.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/><file name="Community.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/><file name="Core.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/></dir><file name="Channel.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/><file name="Local.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/></dir><file name="Repository.php" hash="0ff7c4822bbce0b4390e3e1bec6f4d5d"/><dir name="Rest"><file name="Builder.php" hash="1a009de2ca883a6686900e42f28691c3"/><file name="Factory.php" hash="816de1ef0e376e4a610aa0d97600e479"/></dir><file name="Rest.php" hash="3030c97d6128590bea0b7fb704505a99"/><file name="Singleconfig.php" hash="c6572e5c0159a79d12c05b96cd179f90"/><dir name="Structures"><file name="Graph.php" hash="823112810f5ea1c5382079591ebd9282"/><file name="Node.php" hash="089a0a309aedd56f8ef506a613eb92c9"/></dir><file name="Validator.php" hash="085a0fa83fc246d5390fb23b1d330d9e"/></dir><dir name="DB"><file name="Exception.php" hash="df87dc0b525da51748422213e3fdfc34"/><file name="Mysqli.php" hash="c6ff8085cdc797ecd73202a82dc0268d"/></dir><file name="Exception.php" hash="a6044f488f965fa1f35ebe509a1c7cf7"/><dir name="HTTP"><dir name="Client"><file name="Curl.php" hash="3ee84f5f785cf70b17e1ce7853f9654c"/><file name="Socket.php" hash="5183aa4839c4387ff5ea38ffb7fab98c"/></dir><file name="Client.php" hash="a5a702957a0b5a2f45f608dc95bcfdad"/><file name="IClient.php" hash="4412c30e01d49bf54389ecb74afa917e"/></dir><dir name="System"><file name="Args.php" hash="7f596269c4f2c524ba1897c88033186e"/><file name="Dirs.php" hash="3a1c0021175e04a93082e3084e0d1dfb"/><file name="Ftp.php" hash="543f8aa70d392454b6739c3f29396a09"/></dir><dir name="Xml"><file name="Generator.php" hash="dc74586a864fbc9901ae981aec967c99"/><file name="Parser.php" hash="5b6dd20e89f0aa8cda3c24a73df316bb"/></dir></dir><file name=".htaccess" hash="72617d60821288133a367f70bf39ad93"/></dir><file name="mage.php" hash="58571168f6ac531be694577b5c106823"/><dir name="skin"><file name="boxes.css" hash="252cc12205a39279b5c5330e23aad7ac"/><file name="ie7boxes.css" hash="f17d5252a3f67fdbcdb4e9df4f7971fb"/><file name="ieboxes.css" hash="cae83da82fef24e35155fb56b2c4a85f"/><dir name="images"><file name="Magento_Connect.jpg" hash="20e1378c09506fdc5723abc0115d5f57"/><file name="ajax-loader-tr.gif" hash="1ae32bc8232ff2527c627e5b38eb319a"/><file name="btn_bg.gif" hash="37c51a4d48a92da9648dcd3ca011039f"/><file name="header_bg.gif" hash="8440b04c5cb6b1451bb886bfbef260a5"/><file name="logo.gif" hash="5eb089ecea67d82311d7c91898460104"/><file name="nav_bg.gif" hash="1cb1366f03a9efad6b17e4483aef20cf"/><file name="nav_separator.gif" hash="492011a7de2de84a9c7837bfd879ab95"/></dir><dir name="install"><file name="boxes.css" hash="de9a4050805ee8eaee88dc30351170ae"/><file name="clears.css" hash="4d4f27ee5e4fd5d33a9aa192f952d674"/><file name="ie7minus.css" hash="8cc457cdbbe8842902ca91f23a44adf7"/><file name="iestyles.css" hash="f9d8a7f31aa41ce449a2b14eb5e961e9"/><dir name="images"><file name="error_msg_icon.gif" hash="e4f28607f075a105e53fa3113d84bd26"/><file name="footer_bg.gif" hash="d59784af16fd95ea82226e5708a89232"/><file name="footer_container_bg.gif" hash="d468e3943943cbbf711586e69d40ca42"/><file name="footer_info_separator.gif" hash="7da64eefaf4da3855ab6ee76dbced0c2"/><file name="footer_informational_bg.gif" hash="72d37f4b2ea747bf8969c2654ad1d1e0"/><file name="footer_left.gif" hash="2b15a54bea9409a75c142d14a62f0149"/><file name="footer_legality_bg.gif" hash="4eb1602e3369dccd901ffe98ea0fd4b3"/><file name="footer_right.gif" hash="a45eaf35c8797d299bd4d9b936528e8f"/><file name="header_bg.gif" hash="795c6de754d0d49717ed08d5cd8168c8"/><file name="header_nav_bg.gif" hash="80c6a18686eb0243e06d6176506a2502"/><file name="header_top_bg.jpg" hash="143f524392ee62fcc8183f5930d7258b"/><file name="header_top_container_bg.jpg" hash="294c18f3f6b838bba06ae41dd3c3d638"/><file name="logo.gif" hash="073a947a39b967af678455a5c7f66e90"/><file name="main_bg.gif" hash="cf18ba9f7c7e6b058b439cde1a897e9c"/><file name="main_container_bg.gif" hash="a8f5717873dc6cf8f6bd22924b5838fe"/><file name="note_msg_icon.gif" hash="e774ee481a2820789c1a77112377c4e0"/><file name="success_msg_icon.gif" hash="834dfafd5f8b44c4b24a4c00add56fcf"/><file name="validation_advice_bg.gif" hash="b85432906de8985a8b14eeb2dc652d3c"/></dir><file name="reset.css" hash="d10ef7911c66830825b0367b46fc203c"/></dir></dir><file name="target.xml" hash="9037fc86de8dd2aea215ca3c3714e03b"/><dir name="template"><dir name="connect"><file name="iframe.phtml" hash="7184ea4efaefe2e49952e06ebc82b7e4"/><file name="packages.phtml" hash="83fb56d37655a352008a46084f69f29b"/><file name="packages_prepare.phtml" hash="d664da715e3d9e35e51cf51a356d7ad6"/></dir><file name="exception.phtml" hash="446cb7db443dac90fd179e4dc9042208"/><file name="footer.phtml" hash="c19c11172aa91e03e99e387226236ba4"/><file name="header.phtml" hash="cd119717f993edab2532033fd1e7031a"/><file name="index.phtml" hash="af7fd53abba1ceee7931a59727baf1ac"/><dir name="install"><file name="download.phtml" hash="f8cd81dfdad9316ee9cc436a80d034d1"/><file name="footer.phtml" hash="ffd35db4058f3e1612214f2f76b3f445"/><file name="header.phtml" hash="ee4d96860229d06a436457dacbe335b5"/><file name="writable.phtml" hash="1573d8b6e869adf198e7245e2faefdd2"/></dir><file name="login.phtml" hash="f090def42f337e6c0d831606b62d2446"/><file name="messages.phtml" hash="a25f4bd907224f5124b00c166414d2d5"/><file name="noroute.phtml" hash="e3701c3664d76611110209e88d36ea9e"/><file name="settings.phtml" hash="6b2baacc34089a3d0d63bff0132ce261"/><file name="writable.phtml" hash="934410a54bd3fb796c2bfa7e0d011d51"/><file name=".htaccess" hash="72617d60821288133a367f70bf39ad93"/></dir><dir name=".cache"><dir name="community"><file name="Bricks_Chekcout-0.0.1.tgz" hash="cdaba836257874c30e8b4004358c5beb"/><file name="Exit_Screen_Pop_Up-1.0.2.tgz" hash="04019c61ef187617b3652e6898581253"/><file name="Mss_Connector-2.5.0.tgz" hash="52f4967322f6035d4fef5b1d89afe677"/><file name="Mss_Connector-2.5.1.tgz" hash="d060b09198ed1d2bd1101dec06dacf1d"/><file name="Mss_Connector-2.5.2.tgz" hash="b2bbf5b8528f3cf47e6f3edd2ed87051"/><file name="Mss_Connector-2.6.1.tgz" hash="61eda272f7af76fb3868d9505d69a1a8"/><file name="OrganicInternet_SimpleConfigurableProducts-0.7.4.tgz" hash="73ea77357a7ee2e1c5c95033974840ab"/><file name="Owebia_Shipping_2-2.6.0.tgz" hash="a906d9da0df9d53c6e04eded7c9ec2e4"/><file name="toogas_featured_popup_free_version-1.0.6.tgz" hash="4dd1fb36d27f4e32e899973b5543a818"/></dir><dir name="community@"><file name="Auctionmaid_Matrxrate-5.1.1.tgz" hash="437d51defd179a0c517a021e02ca2c08"/><file name="CashOnDelivery-1.0.8.tgz" hash="b1505c5356da8b2140556ae6be52d3b3"/><file name="Craig_Tco-2.4.2.tgz" hash="01e98fe023efd3aeac04b4e2cda6595d"/><file name="Mss_Connector-2.4.9.tgz" hash="ab578134d28e848b14140a01450c7856"/><file name="PayU-India-Basic-1.0.0.tgz" hash="d6f9eb7bc921195171216cbb25317bce"/><file name="Pook_CollectInStore-1.0.5.tgz" hash="39688feef0ff06866def0b64f627ecee"/><file name="Zero1_Customshipprice-1.0.1.tgz" hash="05ca328634599a26a59ef5b3cf4dde9b"/></dir></dir><file name=".htaccess" hash="520cc012c84739584526b8a9ff098e23"/></dir></dir></target><target name="magedesign"><dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="pushnotification"><file name="pushnotificationbackend.phtml" hash="138add7171fdd7fb326abc4a4f9dbe5a"/></dir><dir name="connector"><file name="landing.phtml" hash="6efda7cca18e7bc62ce40c9f25a9510b"/><file name="notification.phtml" hash="164e5f9e7dcfc5c2d2451f0e77776d77"/><file name="support.phtml" hash="7c799c058795eafbf96239e16e3326ca"/><file name="landing.phtml" hash="6efda7cca18e7bc62ce40c9f25a9510b"/><file name="notification.phtml" hash="164e5f9e7dcfc5c2d2451f0e77776d77"/><file name="support.phtml" hash="7c799c058795eafbf96239e16e3326ca"/></dir></dir><dir name="layout"><file name="bannersliderapp.xml" hash="f18034448b9f74646c870a23bfc0b6fd"/><file name="pushnotification.xml" hash="f7fd974e63c4c7eb5ffac7b059470946"/><file name="connector.xml" hash="003166428e55a52301f71826a37f8283"/><file name="connector.xml" hash="003166428e55a52301f71826a37f8283"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="payu.xml" hash="473595488f536cb588c5588a744915a3"/><file name="mpaypal.xml" hash="7b75c5bed6f3142c8bc9e4c1233bf1e9"/></dir><dir name="template"><dir name="payu"><file name="index.phtml" hash="5f9e2dfb00a991707e31a00b39cfebef"/><file name="test.phtml" hash="da4701ff5b2c64444a49f77571e8a00c"/></dir><dir name="mpaypal"><file name="index.phtml" hash="df077c063b2006b9321c96cd6744b19f"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir><dir name="modules"><file name="Mss_Bannersliderapp.xml" hash="de3e077185056246492c3a2ff01a531f"/><file name="Mss_Connector.xml" hash="ba8a5609c9c8c3636f183c5bfe04d664"/><file name="Mss_Payu.xml" hash="5feac03d698b481473223fbe6a8814b1"/><file name="Mss_Pushnotification.xml" hash="2e8e9bc56a5f0ff8bb42f43fb5a3a3db"/><file name="Mss_Sociallogin.xml" hash="8671199bdad3bdecbfe0c47ce9ff05e6"/><file name="Mss_Mpaypal.xml" hash="4d6a7f8d862de8c449b1366727ef0a6d"/></dir></dir></target><target name="mageskin"><dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="images"><dir name="magentomobileshop"><file name="magento_logo.png" hash="d1800a3c95de49500f158bfb6ca9c70c"/><file name="magentomobileshop_loader.gif" hash="453272c9cacd32efe6465961ea8a61dd"/></dir></dir></dir></dir></dir></dir></target></contents>
17
  <compatible/>
18
+ <dependencies><required><php><min>5.3.0</min><max>7.0.17</max></php></required></dependencies>
19
  </package>