Version Notes
1.6.1.0
Download this release
Release Info
Developer | Magento Core Team |
Extension | Mage_Downloader |
Version | 1.6.1.0 |
Comparing to | |
See all releases |
Version 1.6.1.0
- .htaccess +186 -0
- downloader/.htaccess +11 -0
- downloader/Maged/Connect.php +467 -0
- downloader/Maged/Connect/Frontend.php +149 -0
- downloader/Maged/Controller.php +977 -0
- downloader/Maged/Exception.php +37 -0
- downloader/Maged/Model.php +99 -0
- downloader/Maged/Model/Config.php +84 -0
- downloader/Maged/Model/Config/Abstract.php +134 -0
- downloader/Maged/Model/Config/Community.php +112 -0
- downloader/Maged/Model/Config/Interface.php +90 -0
- downloader/Maged/Model/Connect.php +491 -0
- downloader/Maged/Model/Connect/Request.php +43 -0
- downloader/Maged/Model/Dowloader.php +30 -0
- downloader/Maged/Model/Session.php +224 -0
- downloader/Maged/View.php +155 -0
- downloader/config.ini +1 -0
- downloader/index.php +36 -0
- downloader/js/prototype.js +3277 -0
- downloader/lib/Mage/Archive.php +222 -0
- downloader/lib/Mage/Archive/Abstract.php +84 -0
- downloader/lib/Mage/Archive/Bz.php +79 -0
- downloader/lib/Mage/Archive/Gz.php +77 -0
- downloader/lib/Mage/Archive/Interface.php +53 -0
- downloader/lib/Mage/Archive/Tar.php +372 -0
- downloader/lib/Mage/Autoload/Simple.php +52 -0
- downloader/lib/Mage/Connect/Channel/Generator.php +63 -0
- downloader/lib/Mage/Connect/Channel/Parser.php +25 -0
- downloader/lib/Mage/Connect/Channel/VO.php +113 -0
- downloader/lib/Mage/Connect/Command.php +390 -0
- downloader/lib/Mage/Connect/Command/Channels.php +189 -0
- downloader/lib/Mage/Connect/Command/Channels_Header.php +104 -0
- downloader/lib/Mage/Connect/Command/Config.php +213 -0
- downloader/lib/Mage/Connect/Command/Config_Header.php +100 -0
- downloader/lib/Mage/Connect/Command/Install.php +567 -0
- downloader/lib/Mage/Connect/Command/Install_Header.php +237 -0
- downloader/lib/Mage/Connect/Command/Package.php +204 -0
- downloader/lib/Mage/Connect/Command/Package_Header.php +76 -0
- downloader/lib/Mage/Connect/Command/Registry.php +364 -0
- downloader/lib/Mage/Connect/Command/Registry_Header.php +84 -0
- downloader/lib/Mage/Connect/Command/Remote.php +231 -0
- downloader/lib/Mage/Connect/Command/Remote_Header.php +88 -0
- downloader/lib/Mage/Connect/Config.php +464 -0
- downloader/lib/Mage/Connect/Converter.php +336 -0
- downloader/lib/Mage/Connect/Frontend.php +251 -0
- downloader/lib/Mage/Connect/Frontend/CLI.php +456 -0
- downloader/lib/Mage/Connect/Ftp.php +523 -0
- downloader/lib/Mage/Connect/Loader.php +51 -0
- downloader/lib/Mage/Connect/Loader/Ftp.php +155 -0
- downloader/lib/Mage/Connect/Package.php +1499 -0
- downloader/lib/Mage/Connect/Package/Extension.php +1 -0
- downloader/lib/Mage/Connect/Package/Hotfix.php +137 -0
- downloader/lib/Mage/Connect/Package/Maintainer.php +1 -0
- downloader/lib/Mage/Connect/Package/Reader.php +150 -0
- downloader/lib/Mage/Connect/Package/Target.php +126 -0
- downloader/lib/Mage/Connect/Package/VO.php +96 -0
- downloader/lib/Mage/Connect/Package/Writer.php +177 -0
- downloader/lib/Mage/Connect/Packager.php +909 -0
- downloader/lib/Mage/Connect/Repository.php +1 -0
- downloader/lib/Mage/Connect/Repository/Abstract.php +1 -0
- downloader/lib/Mage/Connect/Repository/Channel.php +1 -0
- downloader/lib/Mage/Connect/Repository/Channel/Abstract.php +1 -0
- downloader/lib/Mage/Connect/Repository/Channel/Commercial.php +1 -0
- downloader/lib/Mage/Connect/Repository/Channel/Community.php +1 -0
- downloader/lib/Mage/Connect/Repository/Channel/Core.php +1 -0
- downloader/lib/Mage/Connect/Repository/Local.php +1 -0
- downloader/lib/Mage/Connect/Rest.php +366 -0
- downloader/lib/Mage/Connect/Singleconfig.php +934 -0
- downloader/lib/Mage/Connect/Structures/Graph.php +248 -0
- downloader/lib/Mage/Connect/Structures/Node.php +257 -0
- downloader/lib/Mage/Connect/Validator.php +440 -0
- downloader/lib/Mage/DB/Exception.php +36 -0
- downloader/lib/Mage/DB/Mysqli.php +532 -0
- downloader/lib/Mage/Exception.php +35 -0
- downloader/lib/Mage/HTTP/Client.php +84 -0
- downloader/lib/Mage/HTTP/Client/Curl.php +556 -0
- downloader/lib/Mage/HTTP/Client/Socket.php +537 -0
- downloader/lib/Mage/HTTP/IClient.php +145 -0
- downloader/lib/Mage/System/Args.php +102 -0
- downloader/lib/Mage/System/Dirs.php +104 -0
- downloader/lib/Mage/Xml/Generator.php +114 -0
- downloader/lib/Mage/Xml/Parser.php +115 -0
- downloader/mage.php +156 -0
- downloader/skin/boxes.css +217 -0
- downloader/skin/ie7boxes.css +27 -0
- downloader/skin/ieboxes.css +29 -0
- downloader/skin/images/Magento_Connect.jpg +0 -0
- downloader/skin/images/ajax-loader-tr.gif +0 -0
- downloader/skin/images/btn_bg.gif +0 -0
- downloader/skin/images/header_bg.gif +0 -0
- downloader/skin/images/logo.gif +0 -0
- downloader/skin/images/nav_bg.gif +0 -0
- downloader/skin/images/nav_separator.gif +0 -0
- downloader/skin/install/boxes.css +414 -0
- downloader/skin/install/clears.css +70 -0
- downloader/skin/install/ie7minus.css +40 -0
- downloader/skin/install/iestyles.css +78 -0
- downloader/skin/install/images/error_msg_icon.gif +0 -0
- downloader/skin/install/images/footer_bg.gif +0 -0
- downloader/skin/install/images/footer_container_bg.gif +0 -0
- downloader/skin/install/images/footer_info_separator.gif +0 -0
- downloader/skin/install/images/footer_informational_bg.gif +0 -0
- downloader/skin/install/images/footer_left.gif +0 -0
- downloader/skin/install/images/footer_legality_bg.gif +0 -0
- downloader/skin/install/images/footer_right.gif +0 -0
- downloader/skin/install/images/header_bg.gif +0 -0
- downloader/skin/install/images/header_nav_bg.gif +0 -0
- downloader/skin/install/images/header_top_bg.jpg +0 -0
- downloader/skin/install/images/header_top_container_bg.jpg +0 -0
- downloader/skin/install/images/logo.gif +0 -0
- downloader/skin/install/images/main_bg.gif +0 -0
- downloader/skin/install/images/main_container_bg.gif +0 -0
- downloader/skin/install/images/note_msg_icon.gif +0 -0
- downloader/skin/install/images/success_msg_icon.gif +0 -0
- downloader/skin/install/images/validation_advice_bg.gif +0 -0
- downloader/skin/install/reset.css +83 -0
- downloader/template/.htaccess +2 -0
- downloader/template/connect/iframe.phtml +121 -0
- downloader/template/connect/packages.phtml +221 -0
- downloader/template/connect/packages_prepare.phtml +78 -0
- downloader/template/exception.phtml +36 -0
- downloader/template/footer.phtml +40 -0
- downloader/template/header.phtml +73 -0
- downloader/template/index.phtml +36 -0
- downloader/template/install/download.phtml +184 -0
- downloader/template/install/footer.phtml +49 -0
- downloader/template/install/header.phtml +99 -0
- downloader/template/install/writable.phtml +40 -0
- downloader/template/login.phtml +43 -0
- downloader/template/messages.phtml +39 -0
- downloader/template/noroute.phtml +31 -0
- downloader/template/settings.phtml +166 -0
- downloader/template/writable.phtml +35 -0
- index.php +80 -0
- mage +54 -0
- package.xml +18 -0
.htaccess
ADDED
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
############################################
|
2 |
+
## uncomment these lines for CGI mode
|
3 |
+
## make sure to specify the correct cgi php binary file name
|
4 |
+
## it might be /cgi-bin/php-cgi
|
5 |
+
|
6 |
+
# Action php5-cgi /cgi-bin/php5-cgi
|
7 |
+
# AddHandler php5-cgi .php
|
8 |
+
|
9 |
+
############################################
|
10 |
+
## GoDaddy specific options
|
11 |
+
|
12 |
+
# Options -MultiViews
|
13 |
+
|
14 |
+
## you might also need to add this line to php.ini
|
15 |
+
## cgi.fix_pathinfo = 1
|
16 |
+
## if it still doesn't work, rename php.ini to php5.ini
|
17 |
+
|
18 |
+
############################################
|
19 |
+
## this line is specific for 1and1 hosting
|
20 |
+
|
21 |
+
#AddType x-mapp-php5 .php
|
22 |
+
#AddHandler x-mapp-php5 .php
|
23 |
+
|
24 |
+
############################################
|
25 |
+
## default index file
|
26 |
+
|
27 |
+
DirectoryIndex index.php
|
28 |
+
|
29 |
+
<IfModule mod_php5.c>
|
30 |
+
|
31 |
+
############################################
|
32 |
+
## adjust memory limit
|
33 |
+
|
34 |
+
# php_value memory_limit 64M
|
35 |
+
php_value memory_limit 256M
|
36 |
+
php_value max_execution_time 18000
|
37 |
+
|
38 |
+
############################################
|
39 |
+
## disable magic quotes for php request vars
|
40 |
+
|
41 |
+
php_flag magic_quotes_gpc off
|
42 |
+
|
43 |
+
############################################
|
44 |
+
## disable automatic session start
|
45 |
+
## before autoload was initialized
|
46 |
+
|
47 |
+
php_flag session.auto_start off
|
48 |
+
|
49 |
+
############################################
|
50 |
+
## enable resulting html compression
|
51 |
+
|
52 |
+
#php_flag zlib.output_compression on
|
53 |
+
|
54 |
+
###########################################
|
55 |
+
# disable user agent verification to not break multiple image upload
|
56 |
+
|
57 |
+
php_flag suhosin.session.cryptua off
|
58 |
+
|
59 |
+
###########################################
|
60 |
+
# turn off compatibility with PHP4 when dealing with objects
|
61 |
+
|
62 |
+
php_flag zend.ze1_compatibility_mode Off
|
63 |
+
|
64 |
+
</IfModule>
|
65 |
+
|
66 |
+
<IfModule mod_security.c>
|
67 |
+
###########################################
|
68 |
+
# disable POST processing to not break multiple image upload
|
69 |
+
|
70 |
+
SecFilterEngine Off
|
71 |
+
SecFilterScanPOST Off
|
72 |
+
</IfModule>
|
73 |
+
|
74 |
+
<IfModule mod_deflate.c>
|
75 |
+
|
76 |
+
############################################
|
77 |
+
## enable apache served files compression
|
78 |
+
## http://developer.yahoo.com/performance/rules.html#gzip
|
79 |
+
|
80 |
+
# Insert filter on all content
|
81 |
+
###SetOutputFilter DEFLATE
|
82 |
+
# Insert filter on selected content types only
|
83 |
+
#AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
|
84 |
+
|
85 |
+
# Netscape 4.x has some problems...
|
86 |
+
#BrowserMatch ^Mozilla/4 gzip-only-text/html
|
87 |
+
|
88 |
+
# Netscape 4.06-4.08 have some more problems
|
89 |
+
#BrowserMatch ^Mozilla/4\.0[678] no-gzip
|
90 |
+
|
91 |
+
# MSIE masquerades as Netscape, but it is fine
|
92 |
+
#BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
|
93 |
+
|
94 |
+
# Don't compress images
|
95 |
+
#SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
|
96 |
+
|
97 |
+
# Make sure proxies don't deliver the wrong content
|
98 |
+
#Header append Vary User-Agent env=!dont-vary
|
99 |
+
|
100 |
+
</IfModule>
|
101 |
+
|
102 |
+
<IfModule mod_ssl.c>
|
103 |
+
|
104 |
+
############################################
|
105 |
+
## make HTTPS env vars available for CGI mode
|
106 |
+
|
107 |
+
SSLOptions StdEnvVars
|
108 |
+
|
109 |
+
</IfModule>
|
110 |
+
|
111 |
+
<IfModule mod_rewrite.c>
|
112 |
+
|
113 |
+
############################################
|
114 |
+
## enable rewrites
|
115 |
+
|
116 |
+
Options +FollowSymLinks
|
117 |
+
RewriteEngine on
|
118 |
+
|
119 |
+
############################################
|
120 |
+
## you can put here your magento root folder
|
121 |
+
## path relative to web root
|
122 |
+
|
123 |
+
#RewriteBase /magento/
|
124 |
+
|
125 |
+
############################################
|
126 |
+
## workaround for HTTP authorization
|
127 |
+
## in CGI environment
|
128 |
+
|
129 |
+
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
130 |
+
|
131 |
+
############################################
|
132 |
+
## always send 404 on missing files in these folders
|
133 |
+
|
134 |
+
RewriteCond %{REQUEST_URI} !^/(media|skin|js)/
|
135 |
+
|
136 |
+
############################################
|
137 |
+
## never rewrite for existing files, directories and links
|
138 |
+
|
139 |
+
RewriteCond %{REQUEST_FILENAME} !-f
|
140 |
+
RewriteCond %{REQUEST_FILENAME} !-d
|
141 |
+
RewriteCond %{REQUEST_FILENAME} !-l
|
142 |
+
|
143 |
+
############################################
|
144 |
+
## rewrite everything else to index.php
|
145 |
+
|
146 |
+
RewriteRule .* index.php [L]
|
147 |
+
|
148 |
+
</IfModule>
|
149 |
+
|
150 |
+
|
151 |
+
############################################
|
152 |
+
## Prevent character encoding issues from server overrides
|
153 |
+
## If you still have problems, use the second line instead
|
154 |
+
|
155 |
+
AddDefaultCharset Off
|
156 |
+
#AddDefaultCharset UTF-8
|
157 |
+
|
158 |
+
<IfModule mod_expires.c>
|
159 |
+
|
160 |
+
############################################
|
161 |
+
## Add default Expires header
|
162 |
+
## http://developer.yahoo.com/performance/rules.html#expires
|
163 |
+
|
164 |
+
ExpiresDefault "access plus 1 year"
|
165 |
+
|
166 |
+
</IfModule>
|
167 |
+
|
168 |
+
############################################
|
169 |
+
## By default allow all access
|
170 |
+
|
171 |
+
Order allow,deny
|
172 |
+
Allow from all
|
173 |
+
|
174 |
+
###########################################
|
175 |
+
## Deny access to release notes to prevent disclosure of the installed Magento version
|
176 |
+
|
177 |
+
<Files RELEASE_NOTES.txt>
|
178 |
+
order allow,deny
|
179 |
+
deny from all
|
180 |
+
</Files>
|
181 |
+
|
182 |
+
############################################
|
183 |
+
## If running in cluster environment, uncomment this
|
184 |
+
## http://developer.yahoo.com/performance/rules.html#etags
|
185 |
+
|
186 |
+
#FileETag none
|
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>
|
downloader/Maged/Connect.php
ADDED
@@ -0,0 +1,467 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
* Instance of class
|
87 |
+
*
|
88 |
+
* @var Maged_Connect
|
89 |
+
*/
|
90 |
+
static protected $_instance;
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Constructor
|
94 |
+
*/
|
95 |
+
public function __construct()
|
96 |
+
{
|
97 |
+
$this->getConfig();
|
98 |
+
$this->getSingleConfig();
|
99 |
+
$this->getFrontend();
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Initialize instance
|
104 |
+
*
|
105 |
+
* @return Maged_Connect
|
106 |
+
*/
|
107 |
+
public static function getInstance()
|
108 |
+
{
|
109 |
+
if (!self::$_instance) {
|
110 |
+
self::$_instance = new self;
|
111 |
+
}
|
112 |
+
return self::$_instance;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Retrieve object of config and set it to Mage_Connect_Command
|
117 |
+
*
|
118 |
+
* @return Mage_Connect_Config
|
119 |
+
*/
|
120 |
+
public function getConfig()
|
121 |
+
{
|
122 |
+
if (!$this->_config) {
|
123 |
+
$this->_config = new Mage_Connect_Config();
|
124 |
+
$ftp=$this->_config->__get('remote_config');
|
125 |
+
if(!empty($ftp)){
|
126 |
+
$packager = new Mage_Connect_Packager();
|
127 |
+
list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
|
128 |
+
$this->_config=$config;
|
129 |
+
$this->_sconfig=$cache;
|
130 |
+
}
|
131 |
+
$this->_config->magento_root = dirname(dirname(__FILE__)).DS.'..';
|
132 |
+
Mage_Connect_Command::setConfigObject($this->_config);
|
133 |
+
}
|
134 |
+
return $this->_config;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Retrieve object of single config and set it to Mage_Connect_Command
|
139 |
+
*
|
140 |
+
* @param bool $reload
|
141 |
+
* @return Mage_Connect_Singleconfig
|
142 |
+
*/
|
143 |
+
public function getSingleConfig($reload = false)
|
144 |
+
{
|
145 |
+
if(!$this->_sconfig || $reload) {
|
146 |
+
$this->_sconfig = new Mage_Connect_Singleconfig($this->getConfig()->magento_root . DIRECTORY_SEPARATOR . $this->getConfig()->downloader_path . DIRECTORY_SEPARATOR . Mage_Connect_Singleconfig::DEFAULT_SCONFIG_FILENAME);
|
147 |
+
}
|
148 |
+
Mage_Connect_Command::setSconfig($this->_sconfig);
|
149 |
+
return $this->_sconfig;
|
150 |
+
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Retrieve object of frontend and set it to Mage_Connect_Command
|
155 |
+
*
|
156 |
+
* @return Maged_Connect_Frontend
|
157 |
+
*/
|
158 |
+
public function getFrontend()
|
159 |
+
{
|
160 |
+
if (!$this->_frontend) {
|
161 |
+
$this->_frontend = new Maged_Connect_Frontend();
|
162 |
+
Mage_Connect_Command::setFrontendObject($this->_frontend);
|
163 |
+
}
|
164 |
+
return $this->_frontend;
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Retrieve lof from frontend
|
169 |
+
*
|
170 |
+
* @return array
|
171 |
+
*/
|
172 |
+
public function getLog()
|
173 |
+
{
|
174 |
+
return $this->getFrontend()->getLog();
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Retrieve output from frontend
|
179 |
+
*
|
180 |
+
* @return array
|
181 |
+
*/
|
182 |
+
public function getOutput()
|
183 |
+
{
|
184 |
+
return $this->getFrontend()->getOutput();
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Clean registry
|
189 |
+
*
|
190 |
+
* @return Maged_Connect
|
191 |
+
*/
|
192 |
+
public function cleanSconfig()
|
193 |
+
{
|
194 |
+
$this->getSingleConfig()->clear();
|
195 |
+
return $this;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Delete directory recursively
|
200 |
+
*
|
201 |
+
* @param string $path
|
202 |
+
* @return Maged_Connect
|
203 |
+
*/
|
204 |
+
public function delTree($path) {
|
205 |
+
if (@is_dir($path)) {
|
206 |
+
$entries = @scandir($path);
|
207 |
+
foreach ($entries as $entry) {
|
208 |
+
if ($entry != '.' && $entry != '..') {
|
209 |
+
$this->delTree($path.DS.$entry);
|
210 |
+
}
|
211 |
+
}
|
212 |
+
@rmdir($path);
|
213 |
+
} else {
|
214 |
+
@unlink($path);
|
215 |
+
}
|
216 |
+
return $this;
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Run commands from Mage_Connect_Command
|
221 |
+
*
|
222 |
+
* @param string $command
|
223 |
+
* @param array $options
|
224 |
+
* @param array $params
|
225 |
+
* @return
|
226 |
+
*/
|
227 |
+
public function run($command, $options=array(), $params=array())
|
228 |
+
{
|
229 |
+
@set_time_limit(0);
|
230 |
+
@ini_set('memory_limit', '256M');
|
231 |
+
|
232 |
+
if (empty($this->_cmdCache[$command])) {
|
233 |
+
Mage_Connect_Command::getCommands();
|
234 |
+
/**
|
235 |
+
* @var $cmd Mage_Connect_Command
|
236 |
+
*/
|
237 |
+
$cmd = Mage_Connect_Command::getInstance($command);
|
238 |
+
if ($cmd instanceof Mage_Connect_Error) {
|
239 |
+
return $cmd;
|
240 |
+
}
|
241 |
+
$this->_cmdCache[$command] = $cmd;
|
242 |
+
} else {
|
243 |
+
/**
|
244 |
+
* @var $cmd Mage_Connect_Command
|
245 |
+
*/
|
246 |
+
$cmd = $this->_cmdCache[$command];
|
247 |
+
}
|
248 |
+
$ftp=$this->getConfig()->remote_config;
|
249 |
+
if(strlen($ftp)>0){
|
250 |
+
$options=array_merge($options, array('ftp'=>$ftp));
|
251 |
+
}
|
252 |
+
$cmd->run($command, $options, $params);
|
253 |
+
if ($cmd->ui()->hasErrors()) {
|
254 |
+
return false;
|
255 |
+
} else {
|
256 |
+
return true;
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
public function setRemoteConfig($uri) #$host, $user, $password, $path='', $port=null)
|
261 |
+
{
|
262 |
+
#$uri = 'ftp://' . $user . ':' . $password . '@' . $host . (is_numeric($port) ? ':' . $port : '') . '/' . trim($path, '/') . '/';
|
263 |
+
//$this->run('config-set', array(), array('remote_config', $uri));
|
264 |
+
//$this->run('config-set', array('ftp'=>$uri), array('remote_config', $uri));
|
265 |
+
$this->getConfig()->remote_config=$uri;
|
266 |
+
return $this;
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
*
|
271 |
+
* @param array $errors Error messages
|
272 |
+
* @return Maged_Connect
|
273 |
+
*/
|
274 |
+
public function showConnectErrors($errors)
|
275 |
+
{
|
276 |
+
echo '<script type="text/javascript">';
|
277 |
+
$run = new Maged_Model_Connect_Request();
|
278 |
+
if ($callback = $run->get('failure_callback')) {
|
279 |
+
if (is_array($callback)) {
|
280 |
+
call_user_func_array($callback, array($result));
|
281 |
+
} else {
|
282 |
+
echo $callback;
|
283 |
+
}
|
284 |
+
}
|
285 |
+
echo '</script>';
|
286 |
+
|
287 |
+
return $this;
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Run Mage_Connect_Command with html output console style
|
292 |
+
*
|
293 |
+
* @param array|Maged_Model $runParams command, options, params,
|
294 |
+
* comment, success_callback, failure_callback
|
295 |
+
*/
|
296 |
+
public function runHtmlConsole($runParams)
|
297 |
+
{
|
298 |
+
if (function_exists('apache_setenv')) {
|
299 |
+
apache_setenv('no-gzip', '1');
|
300 |
+
}
|
301 |
+
@ini_set('zlib.output_compression', 0);
|
302 |
+
@ini_set('implicit_flush', 1);
|
303 |
+
for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
|
304 |
+
ob_implicit_flush();
|
305 |
+
|
306 |
+
$fe = $this->getFrontend();
|
307 |
+
$oldLogStream = $fe->getLogStream();
|
308 |
+
$fe->setLogStream('stdout');
|
309 |
+
|
310 |
+
if ($runParams instanceof Maged_Model) {
|
311 |
+
$run = $runParams;
|
312 |
+
} elseif (is_array($runParams)) {
|
313 |
+
$run = new Maged_Model_Connect_Request($runParams);
|
314 |
+
} elseif (is_string($runParams)) {
|
315 |
+
$run = new Maged_Model_Connect_Request(array('comment'=>$runParams));
|
316 |
+
} else {
|
317 |
+
throw Maged_Exception("Invalid run parameters");
|
318 |
+
}
|
319 |
+
|
320 |
+
if (!$run->get('no-header')) {
|
321 |
+
?>
|
322 |
+
<html><head><style type="text/css">
|
323 |
+
body { margin:0px;
|
324 |
+
padding:3px;
|
325 |
+
background:black;
|
326 |
+
color:#2EC029;
|
327 |
+
font:normal 11px Lucida Console, Courier New, serif;
|
328 |
+
}
|
329 |
+
</style></head><body>
|
330 |
+
<script type="text/javascript">
|
331 |
+
if (parent && parent.disableInputs) {
|
332 |
+
parent.disableInputs(true);
|
333 |
+
}
|
334 |
+
if (typeof auto_scroll=='undefined') {
|
335 |
+
var auto_scroll = window.setInterval(console_scroll, 10);
|
336 |
+
}
|
337 |
+
function console_scroll()
|
338 |
+
{
|
339 |
+
if (typeof top.$ != 'function') {
|
340 |
+
return;
|
341 |
+
}
|
342 |
+
if (top.$('connect_iframe_scroll').checked) {
|
343 |
+
document.body.scrollTop+=3;
|
344 |
+
}
|
345 |
+
}
|
346 |
+
function show_message(message, newline)
|
347 |
+
{
|
348 |
+
var bodyElement = document.getElementsByTagName('body')[0];
|
349 |
+
if (typeof newline == 'undefined') {
|
350 |
+
newline = true
|
351 |
+
}
|
352 |
+
if (newline) {
|
353 |
+
bodyElement.innerHTML += '<br/>';
|
354 |
+
}
|
355 |
+
bodyElement.innerHTML += message;
|
356 |
+
}
|
357 |
+
function clear_cache(callbacks)
|
358 |
+
{
|
359 |
+
if (typeof top.Ajax != 'object') {
|
360 |
+
return;
|
361 |
+
}
|
362 |
+
var message = 'Exception during cache and session cleaning';
|
363 |
+
var url = window.location.href.split('?')[0] + '?A=cleanCache';
|
364 |
+
var intervalID = setInterval(function() {show_message('.', false); }, 500);
|
365 |
+
var clean = 0;
|
366 |
+
var maintenance = 0;
|
367 |
+
if (window.location.href.indexOf('clean_sessions') >= 0) {
|
368 |
+
clean = 1;
|
369 |
+
}
|
370 |
+
if (window.location.href.indexOf('maintenance') >= 0) {
|
371 |
+
maintenance = 1;
|
372 |
+
}
|
373 |
+
|
374 |
+
new top.Ajax.Request(url, {
|
375 |
+
method: 'post',
|
376 |
+
parameters: {clean_sessions:clean, maintenance:maintenance},
|
377 |
+
onCreate: function() {
|
378 |
+
show_message('Cleaning cache');
|
379 |
+
show_message('');
|
380 |
+
},
|
381 |
+
onSuccess: function(transport, json) {
|
382 |
+
var result = true;
|
383 |
+
try{
|
384 |
+
var response = eval('(' + transport.responseText + ')');
|
385 |
+
if (typeof response.result != 'undefined') {
|
386 |
+
result = response.result;
|
387 |
+
} else {
|
388 |
+
result = false;
|
389 |
+
}
|
390 |
+
if (typeof response.message != 'undefined') {
|
391 |
+
if (response.message.length > 0) {
|
392 |
+
message = response.message;
|
393 |
+
} else {
|
394 |
+
message = 'Cache cleaned successfully';
|
395 |
+
}
|
396 |
+
}
|
397 |
+
} catch (ex){
|
398 |
+
result = false;
|
399 |
+
}
|
400 |
+
if (result) {
|
401 |
+
callbacks.success();
|
402 |
+
} else {
|
403 |
+
callbacks.fail();
|
404 |
+
}
|
405 |
+
},
|
406 |
+
onFailure: function() {
|
407 |
+
callbacks.fail();
|
408 |
+
},
|
409 |
+
onComplete: function(transport) {
|
410 |
+
clearInterval(intervalID);
|
411 |
+
show_message(message);
|
412 |
+
}
|
413 |
+
});
|
414 |
+
}
|
415 |
+
</script>
|
416 |
+
<?php
|
417 |
+
}
|
418 |
+
echo htmlspecialchars($run->get('comment'));
|
419 |
+
|
420 |
+
if ($command = $run->get('command')) {
|
421 |
+
$result = $this->run($command, $run->get('options'), $run->get('params'));
|
422 |
+
|
423 |
+
if ($this->getFrontend()->hasErrors()) {
|
424 |
+
echo "<br/>CONNECT ERROR: ";
|
425 |
+
foreach ($this->getFrontend()->getErrors(false) as $error) {
|
426 |
+
echo nl2br($error[1]);
|
427 |
+
echo '<br/>';
|
428 |
+
}
|
429 |
+
}
|
430 |
+
echo '<script type="text/javascript">';
|
431 |
+
if ($this->getFrontend()->hasErrors()) {
|
432 |
+
if ($callback = $run->get('failure_callback')) {
|
433 |
+
if (is_array($callback)) {
|
434 |
+
call_user_func_array($callback, array($result));
|
435 |
+
} else {
|
436 |
+
echo $callback;
|
437 |
+
}
|
438 |
+
}
|
439 |
+
} else {
|
440 |
+
if (!$run->get('no-footer')) {
|
441 |
+
if ($callback = $run->get('success_callback')) {
|
442 |
+
if (is_array($callback)) {
|
443 |
+
call_user_func_array($callback, array($result));
|
444 |
+
} else {
|
445 |
+
echo $callback;
|
446 |
+
}
|
447 |
+
}
|
448 |
+
}
|
449 |
+
}
|
450 |
+
echo '</script>';
|
451 |
+
} else {
|
452 |
+
$result = false;
|
453 |
+
}
|
454 |
+
if ($this->getFrontend()->getErrors() || !$run->get('no-footer')) {
|
455 |
+
?>
|
456 |
+
<script type="text/javascript">
|
457 |
+
if (parent && parent.disableInputs) {
|
458 |
+
parent.disableInputs(false);
|
459 |
+
}
|
460 |
+
</script>
|
461 |
+
</body></html>
|
462 |
+
<?php
|
463 |
+
$fe->setLogStream($oldLogStream);
|
464 |
+
}
|
465 |
+
return $result;
|
466 |
+
}
|
467 |
+
}
|
downloader/Maged/Connect/Frontend.php
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 " ".$msg;
|
99 |
+
}
|
100 |
+
echo "<br/>".str_repeat(" ", 256);
|
101 |
+
}
|
102 |
+
} else {
|
103 |
+
echo " ".$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 |
+
* @return array
|
142 |
+
*/
|
143 |
+
public function getOutput()
|
144 |
+
{
|
145 |
+
return $this->_out;
|
146 |
+
}
|
147 |
+
|
148 |
+
}
|
149 |
+
|
downloader/Maged/Controller.php
ADDED
@@ -0,0 +1,977 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
$actions = isset($_POST['actions']) ? $_POST['actions'] : array();
|
324 |
+
if (isset($_POST['ignore_local_modification'])) {
|
325 |
+
$ignoreLocalModification = $_POST['ignore_local_modification'];
|
326 |
+
} else {
|
327 |
+
$ignoreLocalModification = '';
|
328 |
+
}
|
329 |
+
$this->model('connect', true)->applyPackagesActions($actions, $ignoreLocalModification);
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* Prepare package to install, get dependency info.
|
334 |
+
*/
|
335 |
+
public function connectPreparePackagePostAction()
|
336 |
+
{
|
337 |
+
if (!$_POST) {
|
338 |
+
echo "INVALID POST DATA";
|
339 |
+
return;
|
340 |
+
}
|
341 |
+
$prepareResult = $this->model('connect', true)->prepareToInstall($_POST['install_package_id']);
|
342 |
+
|
343 |
+
$packages = isset($prepareResult['data']) ? $prepareResult['data'] : array();
|
344 |
+
$errors = isset($prepareResult['errors']) ? $prepareResult['errors'] : array();
|
345 |
+
|
346 |
+
$this->view()->set('packages', $packages);
|
347 |
+
$this->view()->set('errors', $errors);
|
348 |
+
$this->view()->set('package_id', $_POST['install_package_id']);
|
349 |
+
|
350 |
+
echo $this->view()->template('connect/packages_prepare.phtml');
|
351 |
+
}
|
352 |
+
|
353 |
+
/**
|
354 |
+
* Install package
|
355 |
+
*/
|
356 |
+
public function connectInstallPackagePostAction()
|
357 |
+
{
|
358 |
+
if (!$_POST) {
|
359 |
+
echo "INVALID POST DATA";
|
360 |
+
return;
|
361 |
+
}
|
362 |
+
$this->model('connect', true)->installPackage($_POST['install_package_id']);
|
363 |
+
}
|
364 |
+
|
365 |
+
/**
|
366 |
+
* Install uploaded package
|
367 |
+
*/
|
368 |
+
public function connectInstallPackageUploadAction()
|
369 |
+
{
|
370 |
+
if (!$_FILES) {
|
371 |
+
echo "No file was uploaded";
|
372 |
+
return;
|
373 |
+
}
|
374 |
+
|
375 |
+
if(empty($_FILES['file'])) {
|
376 |
+
echo "No file was uploaded";
|
377 |
+
return;
|
378 |
+
}
|
379 |
+
|
380 |
+
$info =& $_FILES['file'];
|
381 |
+
|
382 |
+
if(0 !== intval($info['error'])) {
|
383 |
+
echo "File upload problem";
|
384 |
+
return;
|
385 |
+
}
|
386 |
+
|
387 |
+
$target = $this->_mageDir . DS . "var/" . uniqid() . $info['name'];
|
388 |
+
$res = move_uploaded_file($info['tmp_name'], $target);
|
389 |
+
if(false === $res) {
|
390 |
+
echo "Error moving uploaded file";
|
391 |
+
return;
|
392 |
+
}
|
393 |
+
|
394 |
+
$this->model('connect', true)->installUploadedPackage($target);
|
395 |
+
@unlink($target);
|
396 |
+
}
|
397 |
+
|
398 |
+
/**
|
399 |
+
* Clean cache on ajax request
|
400 |
+
*/
|
401 |
+
public function cleanCacheAction()
|
402 |
+
{
|
403 |
+
$result = $this->cleanCache();
|
404 |
+
echo json_encode($result);
|
405 |
+
}
|
406 |
+
|
407 |
+
/**
|
408 |
+
* Settings
|
409 |
+
*/
|
410 |
+
public function settingsAction()
|
411 |
+
{
|
412 |
+
$config = $this->config();
|
413 |
+
$this->view()->set('preferred_state', $config->__get('preferred_state'));
|
414 |
+
$this->view()->set('protocol', $config->__get('protocol'));
|
415 |
+
|
416 |
+
$this->view()->set('use_custom_permissions_mode', $config->__get('use_custom_permissions_mode'));
|
417 |
+
$this->view()->set('mkdir_mode', decoct($config->__get('global_dir_mode')));
|
418 |
+
$this->view()->set('chmod_file_mode', decoct($config->__get('global_file_mode')));
|
419 |
+
|
420 |
+
$this->channelConfig()->setSettingsView($this->session(), $this->view());
|
421 |
+
|
422 |
+
$fs_disabled =! $this->isWritable();
|
423 |
+
$ftpParams = $config->__get('remote_config') ? @parse_url($config->__get('remote_config')) : '';
|
424 |
+
|
425 |
+
$this->view()->set('fs_disabled', $fs_disabled);
|
426 |
+
$this->view()->set('deployment_type', ($fs_disabled || !empty($ftpParams) ? 'ftp' : 'fs'));
|
427 |
+
|
428 |
+
if (!empty($ftpParams)) {
|
429 |
+
$this->view()->set('ftp_host', sprintf("%s://%s", $ftpParams['scheme'], $ftpParams['host']));
|
430 |
+
$this->view()->set('ftp_login', $ftpParams['user']);
|
431 |
+
$this->view()->set('ftp_password', $ftpParams['pass']);
|
432 |
+
$this->view()->set('ftp_path', $ftpParams['path']);
|
433 |
+
}
|
434 |
+
echo $this->view()->template('settings.phtml');
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Settings post
|
439 |
+
*/
|
440 |
+
public function settingsPostAction()
|
441 |
+
{
|
442 |
+
if ($_POST) {
|
443 |
+
$ftp = $this->getFtpPost($_POST);
|
444 |
+
|
445 |
+
/* clear startup messages */
|
446 |
+
$this->config();
|
447 |
+
$this->session()->getMessages();
|
448 |
+
|
449 |
+
$errors = $this->model('connect', true)->validateConfigPost($_POST);
|
450 |
+
if ($errors) {
|
451 |
+
foreach ($errors as $err) {
|
452 |
+
$this->session()->addMessage('error', $err);
|
453 |
+
}
|
454 |
+
$this->redirect($this->url('settings'));
|
455 |
+
return;
|
456 |
+
}
|
457 |
+
try {
|
458 |
+
if ('ftp' == $_POST['deployment_type'] && !empty($_POST['ftp_host'])) {
|
459 |
+
$this->model('connect', true)->connect()->setRemoteConfig($ftp);
|
460 |
+
} else {
|
461 |
+
$this->model('connect', true)->connect()->setRemoteConfig('');
|
462 |
+
$_POST['ftp'] = '';
|
463 |
+
}
|
464 |
+
$this->channelConfig()->setPostData($this->config(), $_POST);
|
465 |
+
$this->model('connect', true)->saveConfigPost($_POST);
|
466 |
+
$this->channelConfig()->setSettingsSession($_POST, $this->session());
|
467 |
+
$this->model('connect', true)->connect()->run('sync');
|
468 |
+
} catch (Exception $e) {
|
469 |
+
$this->session()->addMessage('error', "Unable to save settings: " . $e->getMessage());
|
470 |
+
}
|
471 |
+
}
|
472 |
+
$this->redirect($this->url('settings'));
|
473 |
+
}
|
474 |
+
|
475 |
+
//////////////////////////// ABSTRACT
|
476 |
+
|
477 |
+
/**
|
478 |
+
* Constructor
|
479 |
+
*/
|
480 |
+
public function __construct()
|
481 |
+
{
|
482 |
+
$this->_rootDir = dirname(dirname(__FILE__));
|
483 |
+
$this->_mageDir = dirname($this->_rootDir);
|
484 |
+
}
|
485 |
+
|
486 |
+
/**
|
487 |
+
* Run
|
488 |
+
*/
|
489 |
+
public static function run()
|
490 |
+
{
|
491 |
+
try {
|
492 |
+
self::singleton()->dispatch();
|
493 |
+
} catch (Exception $e) {
|
494 |
+
echo $e->getMessage();
|
495 |
+
//echo self::singleton()->view()->set('exception', $e)->template("exception.phtml");
|
496 |
+
}
|
497 |
+
}
|
498 |
+
|
499 |
+
/**
|
500 |
+
* Initialize object of class
|
501 |
+
*
|
502 |
+
* @return Maged_Controller
|
503 |
+
*/
|
504 |
+
public static function singleton()
|
505 |
+
{
|
506 |
+
if (!self::$_instance) {
|
507 |
+
self::$_instance = new self;
|
508 |
+
|
509 |
+
if (self::$_instance->isDownloaded() && self::$_instance->isInstalled()) {
|
510 |
+
Mage::app('', 'store', array('global_ban_use_cache'=>true));
|
511 |
+
Mage::getSingleton('adminhtml/url')->turnOffSecretKey();
|
512 |
+
}
|
513 |
+
}
|
514 |
+
return self::$_instance;
|
515 |
+
}
|
516 |
+
|
517 |
+
/**
|
518 |
+
* Retrieve Downloader root dir
|
519 |
+
*
|
520 |
+
* @return string
|
521 |
+
*/
|
522 |
+
public function getRootDir()
|
523 |
+
{
|
524 |
+
return $this->_rootDir;
|
525 |
+
}
|
526 |
+
|
527 |
+
/**
|
528 |
+
* Retrieve Magento root dir
|
529 |
+
*
|
530 |
+
* @return string
|
531 |
+
*/
|
532 |
+
public function getMageDir()
|
533 |
+
{
|
534 |
+
return $this->_mageDir;
|
535 |
+
}
|
536 |
+
|
537 |
+
/**
|
538 |
+
* Retrieve Mage Class file path
|
539 |
+
*
|
540 |
+
* @return string
|
541 |
+
*/
|
542 |
+
public function getMageFilename()
|
543 |
+
{
|
544 |
+
$ds = DIRECTORY_SEPARATOR;
|
545 |
+
return $this->getMageDir() . $ds . 'app' . $ds . 'Mage.php';
|
546 |
+
}
|
547 |
+
|
548 |
+
/**
|
549 |
+
* Retrieve path for Varien_Profiler
|
550 |
+
*
|
551 |
+
* @return string
|
552 |
+
*/
|
553 |
+
public function getVarFilename()
|
554 |
+
{
|
555 |
+
$ds = DIRECTORY_SEPARATOR;
|
556 |
+
return $this->getMageDir() . $ds . 'lib' . $ds . 'Varien' . $ds . 'Profiler.php';
|
557 |
+
}
|
558 |
+
|
559 |
+
/**
|
560 |
+
* Retrieve downloader file path
|
561 |
+
*
|
562 |
+
* @param string $name
|
563 |
+
* @return string
|
564 |
+
*/
|
565 |
+
public function filepath($name = '')
|
566 |
+
{
|
567 |
+
$ds = DIRECTORY_SEPARATOR;
|
568 |
+
return rtrim($this->getRootDir() . $ds . str_replace('/', $ds, $name), $ds);
|
569 |
+
}
|
570 |
+
|
571 |
+
/**
|
572 |
+
* Retrieve object of view
|
573 |
+
*
|
574 |
+
* @return Maged_View
|
575 |
+
*/
|
576 |
+
public function view()
|
577 |
+
{
|
578 |
+
if (!$this->_view) {
|
579 |
+
$this->_view = new Maged_View;
|
580 |
+
}
|
581 |
+
return $this->_view;
|
582 |
+
}
|
583 |
+
|
584 |
+
/**
|
585 |
+
* Retrieve object of model
|
586 |
+
*
|
587 |
+
* @param string $model
|
588 |
+
* @param boolean $singleton
|
589 |
+
* @return Maged_Model
|
590 |
+
*/
|
591 |
+
public function model($model = null, $singleton = false)
|
592 |
+
{
|
593 |
+
if ($singleton && isset($this->_singletons[$model])) {
|
594 |
+
return $this->_singletons[$model];
|
595 |
+
}
|
596 |
+
|
597 |
+
if (is_null($model)) {
|
598 |
+
$class = 'Maged_Model';
|
599 |
+
} else {
|
600 |
+
$class = 'Maged_Model_'.str_replace(' ', '_', ucwords(str_replace('_', ' ', $model)));
|
601 |
+
if (!class_exists($class, false)) {
|
602 |
+
include_once str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
|
603 |
+
}
|
604 |
+
}
|
605 |
+
|
606 |
+
$object = new $class();
|
607 |
+
|
608 |
+
if ($singleton) {
|
609 |
+
$this->_singletons[$model] = $object;
|
610 |
+
}
|
611 |
+
|
612 |
+
return $object;
|
613 |
+
}
|
614 |
+
|
615 |
+
/**
|
616 |
+
* Retrieve object of config
|
617 |
+
*
|
618 |
+
* @return Mage_Connect_Config
|
619 |
+
*/
|
620 |
+
public function config()
|
621 |
+
{
|
622 |
+
if (!$this->_config) {
|
623 |
+
$this->_config = $this->model('connect', true)->connect()->getConfig();
|
624 |
+
if (!$this->_config->isLoaded()) {
|
625 |
+
$this->session()->addMessage('error', "Settings has not been loaded. Used default settings");
|
626 |
+
if ($this->_config->getError()) {
|
627 |
+
$this->session()->addMessage('error', $this->_config->getError());
|
628 |
+
}
|
629 |
+
}
|
630 |
+
}
|
631 |
+
return $this->_config;
|
632 |
+
}
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Retrieve object of channel config
|
636 |
+
*
|
637 |
+
* @return Maged_Model_Config_Interface
|
638 |
+
*/
|
639 |
+
public function channelConfig()
|
640 |
+
{
|
641 |
+
if (!$this->_localConfig) {
|
642 |
+
$this->_localConfig = $this->model('config', true)->getChannelConfig();
|
643 |
+
}
|
644 |
+
return $this->_localConfig;
|
645 |
+
}
|
646 |
+
|
647 |
+
/**
|
648 |
+
* Retrieve object of session
|
649 |
+
*
|
650 |
+
* @return Maged_Model_Session
|
651 |
+
*/
|
652 |
+
public function session()
|
653 |
+
{
|
654 |
+
if (!$this->_session) {
|
655 |
+
$this->_session = $this->model('session')->start();
|
656 |
+
}
|
657 |
+
return $this->_session;
|
658 |
+
}
|
659 |
+
|
660 |
+
/**
|
661 |
+
* Set Controller action
|
662 |
+
*
|
663 |
+
* @param string $action
|
664 |
+
* @return Maged_Controller
|
665 |
+
*/
|
666 |
+
public function setAction($action=null)
|
667 |
+
{
|
668 |
+
if (is_null($action)) {
|
669 |
+
if (!empty($this->_action)) {
|
670 |
+
return $this;
|
671 |
+
}
|
672 |
+
$action = !empty($_GET[self::ACTION_KEY]) ? $_GET[self::ACTION_KEY] : 'index';
|
673 |
+
}
|
674 |
+
if (empty($action) || !is_string($action) || !method_exists($this, $this->getActionMethod($action))) {
|
675 |
+
//$action = 'noroute';
|
676 |
+
$action = 'index';
|
677 |
+
}
|
678 |
+
$this->_action = $action;
|
679 |
+
return $this;
|
680 |
+
}
|
681 |
+
|
682 |
+
/**
|
683 |
+
* Retrieve Controller action name
|
684 |
+
*
|
685 |
+
* @return string
|
686 |
+
*/
|
687 |
+
public function getAction()
|
688 |
+
{
|
689 |
+
return $this->_action;
|
690 |
+
}
|
691 |
+
|
692 |
+
/**
|
693 |
+
* Set Redirect to URL
|
694 |
+
*
|
695 |
+
* @param string $url
|
696 |
+
* @param bool $force
|
697 |
+
* @return Maged_Controller
|
698 |
+
*/
|
699 |
+
public function redirect($url, $force = false)
|
700 |
+
{
|
701 |
+
$this->_redirectUrl = $url;
|
702 |
+
if ($force) {
|
703 |
+
$this->processRedirect();
|
704 |
+
}
|
705 |
+
return $this;
|
706 |
+
}
|
707 |
+
|
708 |
+
/**
|
709 |
+
* Precess redirect
|
710 |
+
*
|
711 |
+
* @return Maged_Controller
|
712 |
+
*/
|
713 |
+
public function processRedirect()
|
714 |
+
{
|
715 |
+
if ($this->_redirectUrl) {
|
716 |
+
if (headers_sent()) {
|
717 |
+
echo '<script type="text/javascript">location.href="' . $this->_redirectUrl . '"</script>';
|
718 |
+
exit;
|
719 |
+
} else {
|
720 |
+
header("Location: " . $this->_redirectUrl);
|
721 |
+
exit;
|
722 |
+
}
|
723 |
+
}
|
724 |
+
return $this;
|
725 |
+
}
|
726 |
+
|
727 |
+
/**
|
728 |
+
* Forward to action
|
729 |
+
*
|
730 |
+
* @param string $action
|
731 |
+
* @return Maged_Controller
|
732 |
+
*/
|
733 |
+
public function forward($action)
|
734 |
+
{
|
735 |
+
$this->setAction($action);
|
736 |
+
$this->_isDispatched = false;
|
737 |
+
return $this;
|
738 |
+
}
|
739 |
+
|
740 |
+
/**
|
741 |
+
* Retrieve action method by action name
|
742 |
+
*
|
743 |
+
* @param string $action
|
744 |
+
* @return string
|
745 |
+
*/
|
746 |
+
public function getActionMethod($action = null)
|
747 |
+
{
|
748 |
+
$method = (!is_null($action) ? $action : $this->_action) . 'Action';
|
749 |
+
return $method;
|
750 |
+
}
|
751 |
+
|
752 |
+
/**
|
753 |
+
* Generate URL for action
|
754 |
+
*
|
755 |
+
* @param string $action
|
756 |
+
* @param array $params
|
757 |
+
*/
|
758 |
+
public function url($action = '', $params = array())
|
759 |
+
{
|
760 |
+
$args = array();
|
761 |
+
foreach ($params as $k => $v) {
|
762 |
+
$args[] = sprintf('%s=%s', rawurlencode($k), rawurlencode($v));
|
763 |
+
}
|
764 |
+
$args = $args ? join('&', $args) : '';
|
765 |
+
|
766 |
+
return sprintf('%s?%s=%s%s', $_SERVER['SCRIPT_NAME'], self::ACTION_KEY, rawurlencode($action), $args);
|
767 |
+
}
|
768 |
+
|
769 |
+
/**
|
770 |
+
* Dispatch process
|
771 |
+
*/
|
772 |
+
public function dispatch()
|
773 |
+
{
|
774 |
+
header('Content-type: text/html; charset=UTF-8');
|
775 |
+
|
776 |
+
$this->setAction();
|
777 |
+
|
778 |
+
if (!$this->isInstalled()) {
|
779 |
+
if (!in_array($this->getAction(), array('index', 'connectInstallAll', 'empty', 'cleanCache'))) {
|
780 |
+
$this->setAction('index');
|
781 |
+
}
|
782 |
+
} else {
|
783 |
+
$this->session()->authenticate();
|
784 |
+
}
|
785 |
+
|
786 |
+
while (!$this->_isDispatched) {
|
787 |
+
$this->_isDispatched = true;
|
788 |
+
|
789 |
+
$method = $this->getActionMethod();
|
790 |
+
$this->$method();
|
791 |
+
}
|
792 |
+
|
793 |
+
$this->processRedirect();
|
794 |
+
}
|
795 |
+
|
796 |
+
/**
|
797 |
+
* Check root dir is writable
|
798 |
+
*
|
799 |
+
* @return bool
|
800 |
+
*/
|
801 |
+
public function isWritable()
|
802 |
+
{
|
803 |
+
if (is_null($this->_writable)) {
|
804 |
+
$this->_writable = is_writable($this->getMageDir() . DIRECTORY_SEPARATOR)
|
805 |
+
&& is_writable($this->filepath())
|
806 |
+
&& (!file_exists($this->filepath('config.ini') || is_writable($this->filepath('config.ini'))));
|
807 |
+
}
|
808 |
+
return $this->_writable;
|
809 |
+
}
|
810 |
+
|
811 |
+
/**
|
812 |
+
* Check is Magento files downloaded
|
813 |
+
*
|
814 |
+
* @return bool
|
815 |
+
*/
|
816 |
+
public function isDownloaded()
|
817 |
+
{
|
818 |
+
return file_exists($this->getMageFilename()) && file_exists($this->getVarFilename());
|
819 |
+
}
|
820 |
+
|
821 |
+
/**
|
822 |
+
* Check is Magento installed
|
823 |
+
*
|
824 |
+
* @return bool
|
825 |
+
*/
|
826 |
+
public function isInstalled()
|
827 |
+
{
|
828 |
+
if (!$this->isDownloaded()) {
|
829 |
+
return false;
|
830 |
+
}
|
831 |
+
if (!class_exists('Mage', false)) {
|
832 |
+
if (!file_exists($this->getMageFilename())) {
|
833 |
+
return false;
|
834 |
+
}
|
835 |
+
include_once $this->getMageFilename();
|
836 |
+
Mage::setIsDownloader();
|
837 |
+
}
|
838 |
+
return Mage::isInstalled();
|
839 |
+
}
|
840 |
+
|
841 |
+
/**
|
842 |
+
* Retrieve Maintenance flag
|
843 |
+
*
|
844 |
+
* @return bool
|
845 |
+
*/
|
846 |
+
protected function _getMaintenanceFlag()
|
847 |
+
{
|
848 |
+
if (is_null($this->_maintenance)) {
|
849 |
+
$this->_maintenance = !empty($_REQUEST['maintenance']) && $_REQUEST['maintenance'] == '1' ? true : false;
|
850 |
+
}
|
851 |
+
return $this->_maintenance;
|
852 |
+
}
|
853 |
+
|
854 |
+
/**
|
855 |
+
* Retrieve Maintenance Flag file path
|
856 |
+
*
|
857 |
+
* @return string
|
858 |
+
*/
|
859 |
+
protected function _getMaintenanceFilePath()
|
860 |
+
{
|
861 |
+
if (is_null($this->_maintenanceFile)) {
|
862 |
+
$path = dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR;
|
863 |
+
$this->_maintenanceFile = $path . 'maintenance.flag';
|
864 |
+
}
|
865 |
+
return $this->_maintenanceFile;
|
866 |
+
}
|
867 |
+
|
868 |
+
/**
|
869 |
+
* Begin install package(s)
|
870 |
+
*/
|
871 |
+
public function startInstall()
|
872 |
+
{
|
873 |
+
if ($this->_getMaintenanceFlag()) {
|
874 |
+
$maintenance_filename='maintenance.flag';
|
875 |
+
$config = $this->config();
|
876 |
+
if (!$this->isWritable() || strlen($config->__get('remote_config')) > 0) {
|
877 |
+
$ftpObj = new Mage_Connect_Ftp();
|
878 |
+
$ftpObj->connect($config->__get('remote_config'));
|
879 |
+
$tempFile = tempnam(sys_get_temp_dir(),'maintenance');
|
880 |
+
@file_put_contents($tempFile, 'maintenance');
|
881 |
+
$ftpObj->upload($maintenance_filename, $tempFile);
|
882 |
+
$ftpObj->close();
|
883 |
+
} else {
|
884 |
+
@file_put_contents($this->_getMaintenanceFilePath(), 'maintenance');
|
885 |
+
}
|
886 |
+
}
|
887 |
+
}
|
888 |
+
|
889 |
+
/**
|
890 |
+
* End install package(s)
|
891 |
+
*/
|
892 |
+
public function endInstall()
|
893 |
+
{
|
894 |
+
//$connect
|
895 |
+
/** @var $connect Maged_Model_Connect */
|
896 |
+
$frontend = $this->model('connect', true)->connect()->getFrontend();
|
897 |
+
if (!($frontend instanceof Maged_Connect_Frontend)) {
|
898 |
+
$this->cleanCache();
|
899 |
+
}
|
900 |
+
}
|
901 |
+
|
902 |
+
protected function cleanCache()
|
903 |
+
{
|
904 |
+
$result = true;
|
905 |
+
$message = '';
|
906 |
+
try {
|
907 |
+
if ($this->isInstalled()) {
|
908 |
+
if (!empty($_REQUEST['clean_sessions'])) {
|
909 |
+
Mage::app()->cleanAllSessions();
|
910 |
+
$message .= 'Session cleaned successfully. ';
|
911 |
+
}
|
912 |
+
Mage::app()->cleanCache();
|
913 |
+
|
914 |
+
// reinit config and apply all updates
|
915 |
+
Mage::app()->getConfig()->reinit();
|
916 |
+
Mage_Core_Model_Resource_Setup::applyAllUpdates();
|
917 |
+
Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
|
918 |
+
$message .= 'Cache cleaned successfully';
|
919 |
+
} else {
|
920 |
+
$result = true;
|
921 |
+
}
|
922 |
+
} catch (Exception $e) {
|
923 |
+
$result = false;
|
924 |
+
$message = "Exception during cache and session cleaning: ".$e->getMessage();
|
925 |
+
$this->session()->addMessage('error', $message);
|
926 |
+
}
|
927 |
+
|
928 |
+
if ($result && $this->_getMaintenanceFlag()) {
|
929 |
+
$maintenance_filename='maintenance.flag';
|
930 |
+
$config = $this->config();
|
931 |
+
if (!$this->isWritable() && strlen($config->__get('remote_config')) > 0) {
|
932 |
+
$ftpObj = new Mage_Connect_Ftp();
|
933 |
+
$ftpObj->connect($config->__get('remote_config'));
|
934 |
+
$ftpObj->delete($maintenance_filename);
|
935 |
+
$ftpObj->close();
|
936 |
+
} else {
|
937 |
+
@unlink($this->_getMaintenanceFilePath());
|
938 |
+
}
|
939 |
+
}
|
940 |
+
return array('result' => $result, 'message' => $message);
|
941 |
+
}
|
942 |
+
|
943 |
+
/**
|
944 |
+
* Gets the current Magento Connect Manager (Downloader) version string
|
945 |
+
* @link http://www.magentocommerce.com/blog/new-community-edition-release-process/
|
946 |
+
*
|
947 |
+
* @return string
|
948 |
+
*/
|
949 |
+
public static function getVersion()
|
950 |
+
{
|
951 |
+
$i = self::getVersionInfo();
|
952 |
+
return trim(
|
953 |
+
"{$i['major']}.{$i['minor']}.{$i['revision']}"
|
954 |
+
. ($i['patch'] != '' ? ".{$i['patch']}" : "")
|
955 |
+
. "-{$i['stability']}{$i['number']}",
|
956 |
+
'.-'
|
957 |
+
);
|
958 |
+
}
|
959 |
+
|
960 |
+
/**
|
961 |
+
* Gets the detailed Magento Connect Manager (Downloader) version information
|
962 |
+
* @link http://www.magentocommerce.com/blog/new-community-edition-release-process/
|
963 |
+
*
|
964 |
+
* @return array
|
965 |
+
*/
|
966 |
+
public static function getVersionInfo()
|
967 |
+
{
|
968 |
+
return array(
|
969 |
+
'major' => '1',
|
970 |
+
'minor' => '5',
|
971 |
+
'revision' => '0',
|
972 |
+
'patch' => '0',
|
973 |
+
'stability' => '',
|
974 |
+
'number' => '',
|
975 |
+
);
|
976 |
+
}
|
977 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
?>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
?>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
?>
|
downloader/Maged/Model/Connect.php
ADDED
@@ -0,0 +1,491 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
echo('Invalid package identifier provided: '.$id);
|
104 |
+
exit;
|
105 |
+
}
|
106 |
+
|
107 |
+
$channel = $match[1];
|
108 |
+
$package = $match[2];
|
109 |
+
$version = (!empty($match[3]) ? trim($match[3],'/\-') : '');
|
110 |
+
|
111 |
+
$connect = $this->connect();
|
112 |
+
$sconfig = $connect->getSingleConfig();
|
113 |
+
|
114 |
+
$options = array();
|
115 |
+
$params = array($channel, $package, $version, $version);
|
116 |
+
$this->controller()->channelConfig()->setCommandOptions($this->controller()->session(), $options);
|
117 |
+
|
118 |
+
$connect->run('package-prepare', $options, $params);
|
119 |
+
$output = $connect->getOutput();
|
120 |
+
$errors = $connect->getFrontend()->getErrors();
|
121 |
+
$package_error = array();
|
122 |
+
foreach ($errors as $error){
|
123 |
+
if (isset($error[1])){
|
124 |
+
$package_error[] = $error[1];
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
$packages = array();
|
129 |
+
if (is_array($output) && isset($output['package-prepare'])){
|
130 |
+
$packages = array_merge($output['package-prepare'], array('errors'=>array('error'=>$package_error)));
|
131 |
+
} elseif (is_array($output) && !empty($package_error)) {
|
132 |
+
$packages = array('errors'=>array('error'=>$package_error));
|
133 |
+
}
|
134 |
+
return $packages;
|
135 |
+
}
|
136 |
+
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Retrieve all installed packages
|
140 |
+
*
|
141 |
+
* @return array
|
142 |
+
*/
|
143 |
+
public function getAllInstalledPackages()
|
144 |
+
{
|
145 |
+
$connect = $this->connect();
|
146 |
+
$sconfig = $connect->getSingleConfig(true);
|
147 |
+
$connect->run('list-installed');
|
148 |
+
$output = $connect->getOutput();
|
149 |
+
$packages = array();
|
150 |
+
if (is_array($output) && isset($output['list-installed']['data'])){
|
151 |
+
$packages = $output['list-installed']['data'];
|
152 |
+
} else {
|
153 |
+
|
154 |
+
}
|
155 |
+
foreach ($packages as $channel=>$package) {
|
156 |
+
foreach ($package as $name=>$data) {
|
157 |
+
$summary = $sconfig->getPackageObject($channel, $name)->getSummary();
|
158 |
+
$addition = array('summary'=>$summary, 'upgrade_versions'=>array(), 'upgrade_latest'=>'');
|
159 |
+
$packages[$channel][$name] = array_merge($data, $addition);
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
if (!empty($_GET['updates'])) {
|
164 |
+
$options = array();
|
165 |
+
$this->controller()->channelConfig()->setCommandOptions($this->controller()->session(), $options);
|
166 |
+
$result = $connect->run('list-upgrades', $options);
|
167 |
+
$output = $connect->getOutput();
|
168 |
+
if (is_array($output)) {
|
169 |
+
$channelData = $output;
|
170 |
+
if (!empty($channelData['list-upgrades']['data']) && is_array($channelData['list-upgrades']['data'])) {
|
171 |
+
foreach ($channelData['list-upgrades']['data'] as $channel=>$package) {
|
172 |
+
foreach ($package as $name=>$data) {
|
173 |
+
if (!isset($packages[$channel][$name])) {
|
174 |
+
continue;
|
175 |
+
}
|
176 |
+
$packages[$channel][$name]['upgrade_latest'] = $data['to'].' ('.$data['from'].')';
|
177 |
+
}
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
}
|
182 |
+
|
183 |
+
$states = array('snapshot'=>0, 'devel'=>1, 'alpha'=>2, 'beta'=>3, 'stable'=>4);
|
184 |
+
$preferredState = $states[$this->getPreferredState()];
|
185 |
+
|
186 |
+
foreach ($packages as $channel=>&$package) {
|
187 |
+
foreach ($package as $name=>&$data) {
|
188 |
+
$actions = array();
|
189 |
+
$systemPkg = $name==='Mage_Downloader';
|
190 |
+
if (!empty($data['upgrade_latest'])) {
|
191 |
+
$status = 'upgrade-available';
|
192 |
+
$releases = array();
|
193 |
+
$connect->run('info', array(), array($channel, $name));
|
194 |
+
$output = $connect->getOutput();
|
195 |
+
if (!empty($output['info']['releases'])) {
|
196 |
+
foreach ($output['info']['releases'] as $release) {
|
197 |
+
$stability = $packages[$channel][$name]['stability'];
|
198 |
+
if ($states[$release['s']] < min($preferredState, $states[$stability])) {
|
199 |
+
continue;
|
200 |
+
}
|
201 |
+
if (version_compare($release['v'], $packages[$channel][$name]['version']) < 1) {
|
202 |
+
continue;
|
203 |
+
}
|
204 |
+
$releases[$release['v']] = $release['v'].' ('.$release['s'].')';
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
if ($releases) {
|
209 |
+
uksort($releases, 'version_compare');
|
210 |
+
foreach ($releases as $version => $release) {
|
211 |
+
$actions['upgrade|'.$version] = 'Upgrade to '.$release;
|
212 |
+
}
|
213 |
+
} else {
|
214 |
+
$a = explode(' ', $data['upgrade_latest'], 2);
|
215 |
+
$actions['upgrade|'.$a[0]] = 'Upgrade';
|
216 |
+
}
|
217 |
+
if (!$systemPkg) {
|
218 |
+
$actions['uninstall'] = 'Uninstall';
|
219 |
+
}
|
220 |
+
} else {
|
221 |
+
$status = 'installed';
|
222 |
+
$actions['reinstall'] = 'Reinstall';
|
223 |
+
if (!$systemPkg) {
|
224 |
+
$actions['uninstall'] = 'Uninstall';
|
225 |
+
}
|
226 |
+
}
|
227 |
+
$packages[$channel][$name]['actions'] = $actions;
|
228 |
+
$packages[$channel][$name]['status'] = $status;
|
229 |
+
}
|
230 |
+
}
|
231 |
+
return $packages;
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Run packages action
|
236 |
+
*
|
237 |
+
* @param mixed $packages
|
238 |
+
*/
|
239 |
+
public function applyPackagesActions($packages, $ignoreLocalModification='')
|
240 |
+
{
|
241 |
+
$actions = array();
|
242 |
+
foreach ($packages as $package=>$action) {
|
243 |
+
if ($action) {
|
244 |
+
$a = explode('|', $package);
|
245 |
+
$b = explode('|', $action);
|
246 |
+
$package = $a[1];
|
247 |
+
$channel = $a[0];
|
248 |
+
$version = '';
|
249 |
+
if ($b[0]=='upgrade') {
|
250 |
+
$version = $b[1];
|
251 |
+
}
|
252 |
+
$actions[$b[0]][] = array($channel, $package, $version, $version);
|
253 |
+
}
|
254 |
+
}
|
255 |
+
if (empty($actions)) {
|
256 |
+
$this->connect()->runHtmlConsole('No actions selected');
|
257 |
+
exit;
|
258 |
+
}
|
259 |
+
|
260 |
+
$this->controller()->startInstall();
|
261 |
+
|
262 |
+
$options = array();
|
263 |
+
if (!empty($ignoreLocalModification)) {
|
264 |
+
$options = array('ignorelocalmodification'=>1);
|
265 |
+
}
|
266 |
+
if(!$this->controller()->isWritable()||strlen($this->connect()->getConfig()->__get('remote_config'))>0){
|
267 |
+
$options['ftp'] = $this->connect()->getConfig()->__get('remote_config');
|
268 |
+
}
|
269 |
+
|
270 |
+
$this->controller()->channelConfig()->setCommandOptions($this->controller()->session(), $options);
|
271 |
+
|
272 |
+
foreach ($actions as $action=>$packages) {
|
273 |
+
foreach ($packages as $package) {
|
274 |
+
switch ($action) {
|
275 |
+
case 'install': case 'uninstall': case 'upgrade':
|
276 |
+
$this->connect()->runHtmlConsole(array(
|
277 |
+
'command'=>$action,
|
278 |
+
'options'=>$options,
|
279 |
+
'params'=>$package
|
280 |
+
));
|
281 |
+
break;
|
282 |
+
|
283 |
+
case 'reinstall':
|
284 |
+
$package_info = $this->connect()->getSingleConfig()->getPackage($package[0], $package[1]);
|
285 |
+
if (isset($package_info['version'])) {
|
286 |
+
$package[2] = $package_info['version'];
|
287 |
+
$package[3] = $package_info['version'];
|
288 |
+
}
|
289 |
+
$this->connect()->runHtmlConsole(array(
|
290 |
+
'command'=>'install',
|
291 |
+
'options'=>array_merge($options, array('force'=>1, 'nodeps'=>1)),
|
292 |
+
'params'=>$package
|
293 |
+
));
|
294 |
+
break;
|
295 |
+
}
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
$this->controller()->endInstall();
|
300 |
+
}
|
301 |
+
|
302 |
+
|
303 |
+
public function installUploadedPackage($file)
|
304 |
+
{
|
305 |
+
$this->controller()->startInstall();
|
306 |
+
|
307 |
+
$options = array();
|
308 |
+
if(!$this->controller()->isWritable()||strlen($this->connect()->getConfig()->__get('remote_config'))>0){
|
309 |
+
$options['ftp'] = $this->connect()->getConfig()->__get('remote_config');
|
310 |
+
}
|
311 |
+
$this->connect()->runHtmlConsole(array(
|
312 |
+
'command'=>'install-file',
|
313 |
+
'options'=>$options,
|
314 |
+
'params'=>array($file),
|
315 |
+
));
|
316 |
+
$this->controller()->endInstall();
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Install package by id
|
321 |
+
*
|
322 |
+
* @param string $id
|
323 |
+
* @param boolean $force
|
324 |
+
*/
|
325 |
+
public function installPackage($id, $force=false)
|
326 |
+
{
|
327 |
+
$match = array();
|
328 |
+
if (!$this->checkExtensionKey($id, $match)) {
|
329 |
+
$this->connect()->runHtmlConsole('Invalid package identifier provided: '.$id);
|
330 |
+
exit;
|
331 |
+
}
|
332 |
+
|
333 |
+
$channel = $match[1];
|
334 |
+
$package = $match[2];//.(!empty($match[3]) ? $match[3] : '');
|
335 |
+
$version = (!empty($match[3]) ? trim($match[3],'/\-') : '');
|
336 |
+
|
337 |
+
$this->controller()->startInstall();
|
338 |
+
|
339 |
+
$options = array();
|
340 |
+
if ($force) {
|
341 |
+
$options['force'] = 1;
|
342 |
+
}
|
343 |
+
if(!$this->controller()->isWritable()||strlen($this->connect()->getConfig()->__get('remote_config'))>0){
|
344 |
+
$options['ftp'] = $this->connect()->getConfig()->__get('remote_config');
|
345 |
+
}
|
346 |
+
|
347 |
+
$this->controller()->channelConfig()->setCommandOptions($this->controller()->session(), $options);
|
348 |
+
|
349 |
+
$this->connect()->runHtmlConsole(array(
|
350 |
+
'command'=>'install',
|
351 |
+
'options'=>$options,
|
352 |
+
'params'=>array(0=>$channel, 1=>$package, 2=>$version),
|
353 |
+
));
|
354 |
+
|
355 |
+
$this->controller()->endInstall();
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Retrieve stability choosen client
|
360 |
+
*
|
361 |
+
* @return string alpha, beta, ...
|
362 |
+
*/
|
363 |
+
public function getPreferredState()
|
364 |
+
{
|
365 |
+
if (is_null($this->get('preferred_state'))) {
|
366 |
+
$connectConfig = $this->connect()->getConfig();
|
367 |
+
$this->set('preferred_state', $connectConfig->__get('preferred_state'));
|
368 |
+
}
|
369 |
+
return $this->get('preferred_state');
|
370 |
+
}
|
371 |
+
|
372 |
+
/**
|
373 |
+
* Retrieve protocol choosen client
|
374 |
+
*
|
375 |
+
* @return string http, ftp
|
376 |
+
*/
|
377 |
+
public function getProtocol()
|
378 |
+
{
|
379 |
+
if (is_null($this->get('protocol'))) {
|
380 |
+
$connectConfig = $this->connect()->getConfig();
|
381 |
+
$this->set('protocol', $connectConfig->__get('protocol'));
|
382 |
+
}
|
383 |
+
return $this->get('protocol');
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Validate settings post data.
|
388 |
+
*
|
389 |
+
* @param array $p
|
390 |
+
*/
|
391 |
+
public function validateConfigPost($p)
|
392 |
+
{
|
393 |
+
$errors = array();
|
394 |
+
$configTestFile = 'connect.cfgt';
|
395 |
+
$configObj = $this->connect()->getConfig();
|
396 |
+
if ('ftp' == $p['deployment_type'] || '1' == $p['inst_protocol']) {
|
397 |
+
/*check ftp*/
|
398 |
+
|
399 |
+
$confFile = $configObj->downloader_path.DIRECTORY_SEPARATOR.$configTestFile;
|
400 |
+
try {
|
401 |
+
$ftpObj = new Mage_Connect_Ftp();
|
402 |
+
$ftpObj->connect($p['ftp']);
|
403 |
+
$tempFile = tempnam(sys_get_temp_dir(),'config');
|
404 |
+
$serial = md5('config test file');
|
405 |
+
$f = @fopen($tempFile, "w+");
|
406 |
+
@fwrite($f, $serial);
|
407 |
+
@fclose($f);
|
408 |
+
$ret=$ftpObj->upload($confFile, $tempFile);
|
409 |
+
|
410 |
+
//read file
|
411 |
+
if (!$errors && is_file($configTestFile)) {
|
412 |
+
$size = filesize($configTestFile);
|
413 |
+
if(!$size) {
|
414 |
+
$errors[]='Unable to read saved settings. Please check Installation Path of FTP Connection.';
|
415 |
+
}
|
416 |
+
|
417 |
+
if (!$errors) {
|
418 |
+
$f = @fopen($configTestFile, "r");
|
419 |
+
@fseek($f, 0, SEEK_SET);
|
420 |
+
|
421 |
+
$contents = @fread($f, strlen($serial));
|
422 |
+
if ($serial != $contents) {
|
423 |
+
$errors[]='Wrong Installation Path of FTP Connection.';
|
424 |
+
}
|
425 |
+
fclose($f);
|
426 |
+
}
|
427 |
+
} else {
|
428 |
+
$errors[] = 'Unable to read saved settings. Please check Installation Path of FTP Connection.';
|
429 |
+
}
|
430 |
+
$ftpObj->delete($confFile);
|
431 |
+
$ftpObj->close();
|
432 |
+
} catch (Exception $e) {
|
433 |
+
$errors[] = 'Deployment FTP Error. ' . $e->getMessage();
|
434 |
+
}
|
435 |
+
} else {
|
436 |
+
$p['ftp'] = '';
|
437 |
+
}
|
438 |
+
|
439 |
+
if ('1' == $p['use_custom_permissions_mode']) {
|
440 |
+
/*check permissions*/
|
441 |
+
if (octdec(intval($p['mkdir_mode'])) < 73 || octdec(intval($p['mkdir_mode'])) > 511) {
|
442 |
+
$errors[]='Folders permissions not valid. ';
|
443 |
+
}
|
444 |
+
if (octdec(intval($p['chmod_file_mode'])) < 73 || octdec(intval($p['chmod_file_mode'])) > 511) {
|
445 |
+
$errors[]='Files permissions not valid. ';
|
446 |
+
}
|
447 |
+
}
|
448 |
+
//$this->controller()->session()->addMessage('success', 'Settings has been successfully saved');
|
449 |
+
return $errors;
|
450 |
+
}
|
451 |
+
/**
|
452 |
+
* Save settings.
|
453 |
+
*
|
454 |
+
* @param array $p
|
455 |
+
*/
|
456 |
+
public function saveConfigPost($p)
|
457 |
+
{
|
458 |
+
$configObj = $this->connect()->getConfig();
|
459 |
+
if ('ftp' == $p['deployment_type'] || '1' == $p['inst_protocol']){
|
460 |
+
$this->set('ftp',$p['ftp']);
|
461 |
+
} else {
|
462 |
+
$p['ftp'] = '';
|
463 |
+
}
|
464 |
+
$configObj->remote_config = $p['ftp'];
|
465 |
+
$configObj->preferred_state = $p['preferred_state'];
|
466 |
+
$configObj->protocol = $p['protocol'];
|
467 |
+
$configObj->use_custom_permissions_mode = $p['use_custom_permissions_mode'];
|
468 |
+
if ('1' == $p['use_custom_permissions_mode']) {
|
469 |
+
$configObj->global_dir_mode = octdec(intval($p['mkdir_mode']));
|
470 |
+
$configObj->global_file_mode = octdec(intval($p['chmod_file_mode']));
|
471 |
+
}
|
472 |
+
if ($configObj->save()) {
|
473 |
+
$this->controller()->session()->addMessage('success', 'Settings has been successfully saved');
|
474 |
+
} else {
|
475 |
+
$this->controller()->session()->addMessage('error', 'Settings cannot be saved');
|
476 |
+
}
|
477 |
+
return $this;
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Check Extension Key
|
482 |
+
*
|
483 |
+
* @param string $id
|
484 |
+
* @param array $match
|
485 |
+
* @return int
|
486 |
+
*/
|
487 |
+
public function checkExtensionKey($id, &$match)
|
488 |
+
{
|
489 |
+
return preg_match('#^([^ ]+)\/([^-]+)(-.+)?$#', $id, $match);
|
490 |
+
}
|
491 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
downloader/Maged/Model/Session.php
ADDED
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 (class_exists('Mage') && Mage::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']) && empty($_POST['username']))
|
107 |
+
|| (isset($_POST['password']) && empty($_POST['password']))) {
|
108 |
+
$this->addMessage('error', 'Invalid user name or password');
|
109 |
+
}
|
110 |
+
if (empty($_POST['username']) || empty($_POST['password'])) {
|
111 |
+
$this->controller()->setAction('login');
|
112 |
+
return $this;
|
113 |
+
}
|
114 |
+
$user = $this->_session->login($_POST['username'], $_POST['password']);
|
115 |
+
$this->_session->refreshAcl();
|
116 |
+
if ($this->_checkUserAccess($user)) {
|
117 |
+
return $this;
|
118 |
+
}
|
119 |
+
} catch (Exception $e) {
|
120 |
+
$this->addMessage('error', $e->getMessage());
|
121 |
+
}
|
122 |
+
|
123 |
+
$this->controller()
|
124 |
+
->redirect(
|
125 |
+
$this->controller()->url('loggedin'),
|
126 |
+
true
|
127 |
+
);
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Check is user logged in and permissions
|
132 |
+
*
|
133 |
+
* @param Mage_Admin_Model_User|null $user
|
134 |
+
* @return bool
|
135 |
+
*/
|
136 |
+
protected function _checkUserAccess($user = null)
|
137 |
+
{
|
138 |
+
if ($user && !$user->getId()) {
|
139 |
+
$this->addMessage('error', 'Invalid user name or password');
|
140 |
+
$this->controller()->setAction('login');
|
141 |
+
} elseif ($this->getUserId() || ($user && $user->getId())) {
|
142 |
+
if ($this->_session->isAllowed('all')) {
|
143 |
+
return true;
|
144 |
+
} else {
|
145 |
+
$this->logout();
|
146 |
+
$this->addMessage('error', 'Access Denied', true);
|
147 |
+
$this->controller()->setAction('login');
|
148 |
+
}
|
149 |
+
}
|
150 |
+
return false;
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Log Out
|
155 |
+
*
|
156 |
+
* @return Maged_Model_Session
|
157 |
+
*/
|
158 |
+
public function logout()
|
159 |
+
{
|
160 |
+
if (!$this->_session) {
|
161 |
+
return $this;
|
162 |
+
}
|
163 |
+
$this->_session->unsUser();
|
164 |
+
return $this;
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Retrieve user
|
169 |
+
*
|
170 |
+
* @return mixed
|
171 |
+
*/
|
172 |
+
public function getUserId()
|
173 |
+
{
|
174 |
+
if (($session = $this->_session) && ($user = $session->getUser())) {
|
175 |
+
return $user->getId();
|
176 |
+
}
|
177 |
+
return false;
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Add Message
|
182 |
+
*
|
183 |
+
* @param string $type
|
184 |
+
* @param string $msg
|
185 |
+
* @param string $clear
|
186 |
+
* @return Maged_Model_Session
|
187 |
+
*/
|
188 |
+
public function addMessage($type, $msg, $clear = false)
|
189 |
+
{
|
190 |
+
$msgs = $this->getMessages($clear);
|
191 |
+
$msgs[$type][] = $msg;
|
192 |
+
$this->set('messages', $msgs);
|
193 |
+
return $this;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Retrieve messages from cache
|
198 |
+
*
|
199 |
+
* @param boolean $clear
|
200 |
+
* @return mixed
|
201 |
+
*/
|
202 |
+
public function getMessages($clear = true)
|
203 |
+
{
|
204 |
+
$msgs = $this->get('messages');
|
205 |
+
$msgs = $msgs ? $msgs : array();
|
206 |
+
if ($clear) {
|
207 |
+
unset($_SESSION['messages']);
|
208 |
+
}
|
209 |
+
return $msgs;
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Retrieve url to adminhtml
|
214 |
+
*
|
215 |
+
* @return string
|
216 |
+
*/
|
217 |
+
public function getReturnUrl()
|
218 |
+
{
|
219 |
+
if (!$this->_session || !$this->_session->isLoggedIn()) {
|
220 |
+
return '';
|
221 |
+
}
|
222 |
+
return Mage::getSingleton('adminhtml/url')->getUrl('adminhtml');
|
223 |
+
}
|
224 |
+
}
|
downloader/Maged/View.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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
downloader/config.ini
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
root_channel=community
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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();
|
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,'&').replace(/</g,'<').replace(/>/g,'>');
|
405 |
+
},
|
406 |
+
unescapeHTML: function() {
|
407 |
+
return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/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();
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Archive
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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] . '.' . $archivers[$i-1];
|
161 |
+
}
|
162 |
+
$source = $this->_getArchiver($archivers[$i])->unpack($source, $packed);
|
163 |
+
|
164 |
+
//var_dump($packed, $source);
|
165 |
+
|
166 |
+
if ($clearInterm && $interimSource && $i >= 0) {
|
167 |
+
unlink($interimSource);
|
168 |
+
}
|
169 |
+
$interimSource = $source;
|
170 |
+
}
|
171 |
+
return $source;
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Extract one file from TAR (Tape Archiver).
|
176 |
+
*
|
177 |
+
* @param string $file
|
178 |
+
* @param string $source
|
179 |
+
* @param string $destination
|
180 |
+
* @return string Path to file
|
181 |
+
*/
|
182 |
+
public function extract($file, $source, $destination='.')
|
183 |
+
{
|
184 |
+
$tarFile = $this->unpack($source, $destination, true);
|
185 |
+
$resFile = $this->_getArchiver(self::TAPE_ARCHIVER)->extract($file, $tarFile, $destination);
|
186 |
+
if (!$this->isTar($source)) {
|
187 |
+
unlink($tarFile);
|
188 |
+
}
|
189 |
+
return $resFile;
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Check file is archive.
|
194 |
+
*
|
195 |
+
* @param string $file
|
196 |
+
* @return boolean
|
197 |
+
*/
|
198 |
+
public function isArchive($file)
|
199 |
+
{
|
200 |
+
$archivers = $this->_getArchivers($file);
|
201 |
+
if (count($archivers)) {
|
202 |
+
return true;
|
203 |
+
}
|
204 |
+
return false;
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Check file is TAR.
|
209 |
+
*
|
210 |
+
* @param mixed $file
|
211 |
+
* @return boolean
|
212 |
+
*/
|
213 |
+
public function isTar($file)
|
214 |
+
{
|
215 |
+
$archivers = $this->_getArchivers($file);
|
216 |
+
if (count($archivers)==1 && $archivers[0] == self::TAPE_ARCHIVER) {
|
217 |
+
return true;
|
218 |
+
}
|
219 |
+
return false;
|
220 |
+
}
|
221 |
+
|
222 |
+
}
|
downloader/lib/Mage/Archive/Abstract.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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Archive
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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,
|
38 |
+
*
|
39 |
+
* @param string $destination
|
40 |
+
* @param string $data
|
41 |
+
* @return boolean
|
42 |
+
*/
|
43 |
+
protected function _writeFile($destination, $data)
|
44 |
+
{
|
45 |
+
if(false === file_put_contents($destination, $data)) {
|
46 |
+
throw new Mage_Exception("Can't write to file: " . $destination);
|
47 |
+
}
|
48 |
+
return true;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Read data from file. If file can't be opened, throw to exception.
|
53 |
+
*
|
54 |
+
* @param string $source
|
55 |
+
* @return string
|
56 |
+
*/
|
57 |
+
protected function _readFile($source)
|
58 |
+
{
|
59 |
+
$data = '';
|
60 |
+
if (is_file($source) && is_readable($source)) {
|
61 |
+
$data = @file_get_contents($source);
|
62 |
+
if ($data === false) {
|
63 |
+
throw new Mage_Exception("Can't get contents from: " . $source);
|
64 |
+
}
|
65 |
+
}
|
66 |
+
return $data;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Get file name from source (URI) without last extension.
|
71 |
+
*
|
72 |
+
* @param string $source
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
public function getFilename($source, $withExtension=false)
|
76 |
+
{
|
77 |
+
$file = str_replace(dirname($source) . DS, '', $source);
|
78 |
+
if (!$withExtension) {
|
79 |
+
$file = substr($file, 0, strrpos($file, '.'));
|
80 |
+
}
|
81 |
+
return $file;
|
82 |
+
}
|
83 |
+
|
84 |
+
}
|
downloader/lib/Mage/Archive/Bz.php
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Archive
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
$data = $this->_readFile($source);
|
47 |
+
$bzData = bzcompress($data, 9);
|
48 |
+
$this->_writeFile($destination, $bzData);
|
49 |
+
return $destination;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Unpack file by BZIP2 compressor.
|
54 |
+
*
|
55 |
+
* @param string $source
|
56 |
+
* @param string $destination
|
57 |
+
* @return string
|
58 |
+
*/
|
59 |
+
public function unpack($source, $destination)
|
60 |
+
{
|
61 |
+
$data = '';
|
62 |
+
$bzPointer = bzopen($source, 'r' );
|
63 |
+
if (empty($bzPointer)) {
|
64 |
+
throw new Exception('Can\'t open BZ archive : ' . $source);
|
65 |
+
}
|
66 |
+
while (!feof($bzPointer)) {
|
67 |
+
$data .= bzread($bzPointer, 131072);
|
68 |
+
}
|
69 |
+
bzclose($bzPointer);
|
70 |
+
if (is_dir($destination)) {
|
71 |
+
$file = $this->getFilename($source);
|
72 |
+
$destination = $destination . $file;
|
73 |
+
}
|
74 |
+
echo $destination;
|
75 |
+
$this->_writeFile($destination, $data);
|
76 |
+
return $destination;
|
77 |
+
}
|
78 |
+
|
79 |
+
}
|
downloader/lib/Mage/Archive/Gz.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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Archive
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
$data = $this->_readFile($source);
|
46 |
+
$gzData = gzencode($data, 9);
|
47 |
+
$this->_writeFile($destination, $gzData);
|
48 |
+
return $destination;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Unpack file by GZ compressor.
|
53 |
+
*
|
54 |
+
* @param string $source
|
55 |
+
* @param string $destination
|
56 |
+
* @return string
|
57 |
+
*/
|
58 |
+
public function unpack($source, $destination)
|
59 |
+
{
|
60 |
+
$gzPointer = gzopen($source, 'r' );
|
61 |
+
if (empty($gzPointer)) {
|
62 |
+
throw new Mage_Exception('Can\'t open GZ archive : ' . $source);
|
63 |
+
}
|
64 |
+
$data = '';
|
65 |
+
while (!gzeof($gzPointer)) {
|
66 |
+
$data .= gzread($gzPointer, 131072);
|
67 |
+
}
|
68 |
+
gzclose($gzPointer);
|
69 |
+
if (is_dir($destination)) {
|
70 |
+
$file = $this->getFilename($source);
|
71 |
+
$destination = $destination . $file;
|
72 |
+
}
|
73 |
+
$this->_writeFile($destination, $data);
|
74 |
+
return $destination;
|
75 |
+
}
|
76 |
+
|
77 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Archive
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
downloader/lib/Mage/Archive/Tar.php
ADDED
@@ -0,0 +1,372 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Archive
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
* Constant is used for parse tar's header.
|
38 |
+
*/
|
39 |
+
const FORMAT_PARSE_HEADER = 'a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix/a12closer';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Keep file or directory for packing.
|
43 |
+
*
|
44 |
+
* @var string
|
45 |
+
*/
|
46 |
+
protected $_currentFile;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Keep path to file or directory for packing.
|
50 |
+
*
|
51 |
+
* @var mixed
|
52 |
+
*/
|
53 |
+
protected $_currentPath;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Skip first level parent directory. Example:
|
57 |
+
* use test/fip.php instead test/test/fip.php;
|
58 |
+
*
|
59 |
+
* @var mixed
|
60 |
+
*/
|
61 |
+
protected $_skipRoot;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Set option that define ability skip first catalog level.
|
65 |
+
*
|
66 |
+
* @param mixed $skipRoot
|
67 |
+
* @return Mage_Archive_Tar
|
68 |
+
*/
|
69 |
+
protected function _setSkipRoot($skipRoot)
|
70 |
+
{
|
71 |
+
$this->_skipRoot = $skipRoot;
|
72 |
+
return $this;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Set file which is packing.
|
77 |
+
*
|
78 |
+
* @param string $file
|
79 |
+
* @return Mage_Archive_Tar
|
80 |
+
*/
|
81 |
+
protected function _setCurrentFile($file)
|
82 |
+
{
|
83 |
+
$this->_currentFile = $file .((is_dir($file) && substr($file, -1)!=DS)?DS:'');
|
84 |
+
return $this;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Retrieve file which is packing.
|
89 |
+
*
|
90 |
+
* @return string
|
91 |
+
*/
|
92 |
+
protected function _getCurrentFile()
|
93 |
+
{
|
94 |
+
return $this->_currentFile;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Set path to file which is packing.
|
99 |
+
*
|
100 |
+
* @param string $path
|
101 |
+
* @return Mage_Archive_Tar
|
102 |
+
*/
|
103 |
+
protected function _setCurrentPath($path)
|
104 |
+
{
|
105 |
+
if ($this->_skipRoot && is_dir($path)) {
|
106 |
+
$this->_currentPath = $path.(substr($path, -1)!=DS?DS:'');
|
107 |
+
} else {
|
108 |
+
$this->_currentPath = dirname($path) . DS;
|
109 |
+
}
|
110 |
+
return $this;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Retrieve path to file which is packing.
|
115 |
+
*
|
116 |
+
* @return string
|
117 |
+
*/
|
118 |
+
protected function _getCurrentPath()
|
119 |
+
{
|
120 |
+
return $this->_currentPath;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Walk through directory and add to tar file or directory.
|
125 |
+
* Result is packed string on TAR format.
|
126 |
+
*
|
127 |
+
* @param boolean $skipRoot
|
128 |
+
* @return string
|
129 |
+
*/
|
130 |
+
protected function _packToTar($skipRoot=false)
|
131 |
+
{
|
132 |
+
$file = $this->_getCurrentFile();
|
133 |
+
$header = '';
|
134 |
+
$data = '';
|
135 |
+
if (!$skipRoot) {
|
136 |
+
$header = $this->_composeHeader();
|
137 |
+
$data = $this->_readFile($file);
|
138 |
+
$data = str_pad($data, floor(((is_dir($file) ? 0 : filesize($file)) + 512 - 1) / 512) * 512, "\0");
|
139 |
+
}
|
140 |
+
$sub = '';
|
141 |
+
if (is_dir($file)) {
|
142 |
+
$treeDir = scandir($file);
|
143 |
+
if (empty($treeDir)) {
|
144 |
+
throw new Mage_Exception('Can\'t scan dir: ' . $file);
|
145 |
+
}
|
146 |
+
array_shift($treeDir); /* remove './'*/
|
147 |
+
array_shift($treeDir); /* remove '../'*/
|
148 |
+
foreach ($treeDir as $item) {
|
149 |
+
$sub .= $this->_setCurrentFile($file.$item)->_packToTar(false);
|
150 |
+
}
|
151 |
+
}
|
152 |
+
$tarData = $header . $data . $sub;
|
153 |
+
$tarData = str_pad($tarData, floor((strlen($tarData) - 1) / 1536) * 1536, "\0");
|
154 |
+
return $tarData;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Compose header for current file in TAR format.
|
159 |
+
* If length of file's name greater 100 characters,
|
160 |
+
* method breaks header to two pieces. First conatins
|
161 |
+
* header and data with long name. Second contain only header.
|
162 |
+
*
|
163 |
+
* @param boolean $long
|
164 |
+
* @return string
|
165 |
+
*/
|
166 |
+
protected function _composeHeader($long = false)
|
167 |
+
{
|
168 |
+
$file = $this->_getCurrentFile();
|
169 |
+
$path = $this->_getCurrentPath();
|
170 |
+
$infoFile = stat($file);
|
171 |
+
$nameFile = str_replace($path, '', $file);
|
172 |
+
$nameFile = str_replace('\\', '/', $nameFile);
|
173 |
+
$packedHeader = '';
|
174 |
+
$longHeader = '';
|
175 |
+
if (!$long && strlen($nameFile)>100) {
|
176 |
+
$longHeader = $this->_composeHeader(true);
|
177 |
+
$longHeader .= str_pad($nameFile, floor((strlen($nameFile) + 512 - 1) / 512) * 512, "\0");
|
178 |
+
}
|
179 |
+
$header = array();
|
180 |
+
$header['100-name'] = $long?'././@LongLink':substr($nameFile, 0, 100);
|
181 |
+
$header['8-mode'] = $long?' ':str_pad(substr(sprintf("%07o", $infoFile['mode']),-4), 6, '0', STR_PAD_LEFT);
|
182 |
+
$header['8-uid'] = $long || $infoFile['uid']==0?"\0\0\0\0\0\0\0":sprintf("%07o", $infoFile['uid']);
|
183 |
+
$header['8-gid'] = $long || $infoFile['gid']==0?"\0\0\0\0\0\0\0":sprintf("%07o", $infoFile['gid']);
|
184 |
+
$header['12-size'] = $long?sprintf("%011o", strlen($nameFile)):sprintf("%011o", is_dir($file) ? 0 : filesize($file));
|
185 |
+
$header['12-mtime'] = $long?'00000000000':sprintf("%011o", $infoFile['mtime']);
|
186 |
+
$header['8-check'] = sprintf('% 8s', '');
|
187 |
+
$header['1-type'] = $long?'L':(is_link($file) ? 2 : is_dir ($file) ? 5 : 0);
|
188 |
+
$header['100-symlink'] = is_link($file) == 2 ? readlink($item) : '';
|
189 |
+
$header['6-magic'] = 'ustar ';
|
190 |
+
$header['2-version'] = ' ';
|
191 |
+
$a=function_exists('posix_getpwuid')?posix_getpwuid (fileowner($file)):array('name'=>'');
|
192 |
+
$header['32-uname'] = $a['name'];
|
193 |
+
$a=function_exists('posix_getgrgid')?posix_getgrgid (filegroup($file)):array('name'=>'');
|
194 |
+
$header['32-gname'] = $a['name'];
|
195 |
+
$header['8-devmajor'] = '';
|
196 |
+
$header['8-devminor'] = '';
|
197 |
+
$header['155-prefix'] = '';
|
198 |
+
$header['12-closer'] = '';
|
199 |
+
|
200 |
+
$packedHeader = '';
|
201 |
+
foreach ($header as $key=>$element) {
|
202 |
+
$length = explode('-', $key);
|
203 |
+
$packedHeader .= pack('a' . $length[0], $element);
|
204 |
+
}
|
205 |
+
|
206 |
+
$checksum = 0;
|
207 |
+
for ($i = 0; $i < 512; $i++) {
|
208 |
+
$checksum += ord(substr($packedHeader, $i, 1));
|
209 |
+
}
|
210 |
+
$packedHeader = substr_replace($packedHeader, sprintf("%07o", $checksum)."\0", 148, 8);
|
211 |
+
|
212 |
+
return $longHeader . $packedHeader;
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Read TAR string from file, and unpacked it.
|
217 |
+
* Create files and directories information about discribed
|
218 |
+
* in the string.
|
219 |
+
*
|
220 |
+
* @param string $destination path to file is unpacked
|
221 |
+
* @return array list of files
|
222 |
+
*/
|
223 |
+
protected function _unpackCurrentTar($destination)
|
224 |
+
{
|
225 |
+
$file = $this->_getCurrentFile();
|
226 |
+
$pointer = fopen($file, 'r');
|
227 |
+
if (empty($pointer)) {
|
228 |
+
throw new Mage_Exception('Can\'t open file: ' . $file);
|
229 |
+
}
|
230 |
+
$list = array();
|
231 |
+
while (!feof($pointer)) {
|
232 |
+
$header = $this->_parseHeader($pointer);
|
233 |
+
if ($header) {
|
234 |
+
$currentFile = $destination . $header['name'];
|
235 |
+
if ($header['type']=='5' && @mkdir($currentFile, 0777, true)) {
|
236 |
+
$list[] = $currentFile . DS;
|
237 |
+
} elseif (in_array($header['type'], array("0",chr(0), ''))) {
|
238 |
+
$dirname = dirname($currentFile);
|
239 |
+
if(!file_exists($dirname)) {
|
240 |
+
@mkdir($dirname, 0777, true);
|
241 |
+
}
|
242 |
+
$this->_writeFile($currentFile, $header['data']);
|
243 |
+
$list[] = $currentFile;
|
244 |
+
}
|
245 |
+
}
|
246 |
+
}
|
247 |
+
fclose($pointer);
|
248 |
+
return $list;
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Get header from TAR string and unpacked it by format.
|
253 |
+
*
|
254 |
+
* @param resource $pointer
|
255 |
+
* @return string
|
256 |
+
*/
|
257 |
+
protected function _parseHeader(&$pointer)
|
258 |
+
{
|
259 |
+
$firstLine = fread($pointer, 512);
|
260 |
+
|
261 |
+
if (strlen($firstLine)<512){
|
262 |
+
return false;
|
263 |
+
}
|
264 |
+
|
265 |
+
$fmt = self::FORMAT_PARSE_HEADER;
|
266 |
+
$header = unpack ($fmt, $firstLine);
|
267 |
+
|
268 |
+
|
269 |
+
$header['mode']=$header['mode']+0;
|
270 |
+
$header['uid']=octdec($header['uid']);
|
271 |
+
$header['gid']=octdec($header['gid']);
|
272 |
+
$header['size']=octdec($header['size']);
|
273 |
+
$header['mtime']=octdec($header['mtime']);
|
274 |
+
$header['checksum']=octdec($header['checksum']);
|
275 |
+
|
276 |
+
if ($header['type'] == "5") {
|
277 |
+
$header['size'] = 0;
|
278 |
+
}
|
279 |
+
|
280 |
+
$checksum = 0;
|
281 |
+
$firstLine = substr_replace($firstLine, ' ', 148, 8);
|
282 |
+
for ($i = 0; $i < 512; $i++) {
|
283 |
+
$checksum += ord(substr($firstLine, $i, 1));
|
284 |
+
}
|
285 |
+
|
286 |
+
$isUstar = 'ustar' == strtolower(substr($header['magic'], 0, 5));
|
287 |
+
|
288 |
+
$checksumOk = $header['checksum'] == $checksum;
|
289 |
+
if (isset($header['name']) && $checksumOk) {
|
290 |
+
if ($header['name'] == '././@LongLink' && $header['type'] == 'L') {
|
291 |
+
$realName = substr(fread($pointer, floor(($header['size'] + 512 - 1) / 512) * 512), 0, $header['size']);
|
292 |
+
$headerMain = $this->_parseHeader($pointer);
|
293 |
+
$headerMain['name'] = $realName;
|
294 |
+
return $headerMain;
|
295 |
+
} else {
|
296 |
+
if ($header['size']>0) {
|
297 |
+
$header['data'] = substr(fread($pointer, floor(($header['size'] + 512 - 1) / 512) * 512), 0, $header['size']);
|
298 |
+
} else {
|
299 |
+
$header['data'] = '';
|
300 |
+
}
|
301 |
+
return $header;
|
302 |
+
}
|
303 |
+
}
|
304 |
+
return false;
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Pack file to TAR (Tape Archiver).
|
309 |
+
*
|
310 |
+
* @param string $source
|
311 |
+
* @param string $destination
|
312 |
+
* @param boolean $skipRoot
|
313 |
+
* @return string
|
314 |
+
*/
|
315 |
+
public function pack($source, $destination, $skipRoot=false)
|
316 |
+
{
|
317 |
+
$this->_setSkipRoot($skipRoot);
|
318 |
+
$source = realpath($source);
|
319 |
+
$tarData = $this->_setCurrentPath($source)
|
320 |
+
->_setCurrentFile($source)
|
321 |
+
->_packToTar($skipRoot);
|
322 |
+
$this->_writeFile($destination, $tarData);
|
323 |
+
return $destination;
|
324 |
+
}
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Unpack file from TAR (Tape Archiver).
|
328 |
+
*
|
329 |
+
* @param string $source
|
330 |
+
* @param string $destination
|
331 |
+
* @return string
|
332 |
+
*/
|
333 |
+
public function unpack($source, $destination)
|
334 |
+
{
|
335 |
+
$tempFile = $destination . DS . '~tmp-'.microtime(true).'.tar';
|
336 |
+
$data = $this->_readFile($source);
|
337 |
+
$this->_writeFile($tempFile, $data);
|
338 |
+
$this->_setCurrentFile($tempFile)
|
339 |
+
->_setCurrentPath($tempFile)
|
340 |
+
->_unpackCurrentTar($destination);
|
341 |
+
unlink($tempFile);
|
342 |
+
return $destination;
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Extract one file from TAR (Tape Archiver).
|
347 |
+
*
|
348 |
+
* @param string $file
|
349 |
+
* @param string $source
|
350 |
+
* @param string $destination
|
351 |
+
* @return string
|
352 |
+
*/
|
353 |
+
public function extract($file, $source, $destination)
|
354 |
+
{
|
355 |
+
$pointer = fopen($source, 'r');
|
356 |
+
if (empty($pointer)) {
|
357 |
+
throw new Mage_Exception('Can\'t open file: '.$source);
|
358 |
+
}
|
359 |
+
$list = array();
|
360 |
+
$extractedFile = '';
|
361 |
+
while (!feof($pointer)) {
|
362 |
+
$header = $this->_parseHeader($pointer);
|
363 |
+
if ($header['name'] == $file) {
|
364 |
+
$extractedFile = $destination . basename($header['name']);
|
365 |
+
$this->_writeFile($extractedFile, $header['data']);
|
366 |
+
break;
|
367 |
+
}
|
368 |
+
}
|
369 |
+
fclose($pointer);
|
370 |
+
return $extractedFile;
|
371 |
+
}
|
372 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Autoload
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 $classFile;
|
50 |
+
}
|
51 |
+
|
52 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
downloader/lib/Mage/Connect/Command.php
ADDED
@@ -0,0 +1,390 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
class Mage_Connect_Command
|
29 |
+
{
|
30 |
+
/**
|
31 |
+
* All commands list
|
32 |
+
* @var array
|
33 |
+
*/
|
34 |
+
protected static $_commandsAll = array();
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Commands list hash (key=class)
|
38 |
+
* @var array
|
39 |
+
*/
|
40 |
+
protected static $_commandsByClass = array();
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Frontend object
|
44 |
+
* @var Mage_Connect_Fro
|
45 |
+
*/
|
46 |
+
protected static $_frontend = null;
|
47 |
+
protected static $_config = null;
|
48 |
+
protected static $_registry = null;
|
49 |
+
protected static $_validator = null;
|
50 |
+
protected static $_rest = null;
|
51 |
+
protected static $_sconfig = null;
|
52 |
+
|
53 |
+
protected $_data;
|
54 |
+
protected $_class;
|
55 |
+
protected static $_packager = null;
|
56 |
+
|
57 |
+
protected static $_return = array();
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Constructor
|
61 |
+
*
|
62 |
+
*/
|
63 |
+
public function __construct()
|
64 |
+
{
|
65 |
+
$class = $this->_class = get_class($this);
|
66 |
+
if(__CLASS__ == $class) {
|
67 |
+
throw new Exception("You shouldn't instantiate {$class} directly!");
|
68 |
+
}
|
69 |
+
$this->commandsInfo = self::$_commandsByClass[$class];
|
70 |
+
}
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Get command info (static)
|
75 |
+
* @param string $name command name
|
76 |
+
* @return array/bool
|
77 |
+
*/
|
78 |
+
public static function commandInfo($name)
|
79 |
+
{
|
80 |
+
$name = strtolower($name);
|
81 |
+
if(!isset(self::$_commandsAll[$name])) {
|
82 |
+
return false;
|
83 |
+
}
|
84 |
+
return self::$_commandsAll[$name];
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Get command info for current command object
|
89 |
+
* @param string $name
|
90 |
+
* @return array/bool
|
91 |
+
*/
|
92 |
+
|
93 |
+
public function getCommandInfo($name)
|
94 |
+
{
|
95 |
+
if(!isset(self::$_commandsByClass[$this->_class][$name])) {
|
96 |
+
return false;
|
97 |
+
}
|
98 |
+
return self::$_commandsByClass[$this->_class][$name];
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Run command
|
103 |
+
* @param string $command
|
104 |
+
* @param string $options
|
105 |
+
* @param string $params
|
106 |
+
* @throws Exception if there's no needed method
|
107 |
+
* @return mixed
|
108 |
+
*/
|
109 |
+
public function run($command, $options, $params)
|
110 |
+
{
|
111 |
+
$data = $this->getCommandInfo($command);
|
112 |
+
$method = $data['function'];
|
113 |
+
if(! method_exists($this, $method)) {
|
114 |
+
throw new Exception("$method does't exist in class ".$this->_class);
|
115 |
+
}
|
116 |
+
return $this->$method($command, $options, $params);
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Static functions
|
121 |
+
*/
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Static
|
125 |
+
* @param $commandName
|
126 |
+
* @return unknown_type
|
127 |
+
*/
|
128 |
+
public static function getInstance($commandName)
|
129 |
+
{
|
130 |
+
if(!isset(self::$_commandsAll[$commandName])) {
|
131 |
+
throw new UnexpectedValueException("Cannot find command $commandName");
|
132 |
+
}
|
133 |
+
$currentCommand = self::$_commandsAll[$commandName];
|
134 |
+
return new $currentCommand['class']();
|
135 |
+
}
|
136 |
+
|
137 |
+
|
138 |
+
public static function setSconfig($obj)
|
139 |
+
{
|
140 |
+
self::$_sconfig = $obj;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
*
|
145 |
+
* @return Mage_Connect_Singleconfig
|
146 |
+
*/
|
147 |
+
public function getSconfig()
|
148 |
+
{
|
149 |
+
return self::$_sconfig;
|
150 |
+
}
|
151 |
+
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Sets frontend object for all commands
|
155 |
+
*
|
156 |
+
* @param Mage_Connect_Frontend $obj
|
157 |
+
* @return void
|
158 |
+
*/
|
159 |
+
public static function setFrontendObject($obj)
|
160 |
+
{
|
161 |
+
self::$_frontend = $obj;
|
162 |
+
}
|
163 |
+
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Set config object for all commands
|
167 |
+
* @param Mage_Connect_Config $obj
|
168 |
+
* @return void
|
169 |
+
*/
|
170 |
+
public static function setConfigObject($obj)
|
171 |
+
{
|
172 |
+
self::$_config = $obj;
|
173 |
+
}
|
174 |
+
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Non-static getter for config
|
178 |
+
* @return Mage_Connect_Config
|
179 |
+
*/
|
180 |
+
public function config()
|
181 |
+
{
|
182 |
+
return self::$_config;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Non-static getter for UI
|
187 |
+
* @return Mage_Connect_Frontend
|
188 |
+
*/
|
189 |
+
public function ui()
|
190 |
+
{
|
191 |
+
return self::$_frontend;
|
192 |
+
}
|
193 |
+
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Get validator object
|
197 |
+
* @return Mage_Connect_Validator
|
198 |
+
*/
|
199 |
+
public function validator()
|
200 |
+
{
|
201 |
+
if(is_null(self::$_validator)) {
|
202 |
+
self::$_validator = new Mage_Connect_Validator();
|
203 |
+
}
|
204 |
+
return self::$_validator;
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Get rest object
|
209 |
+
* @return Mage_Connect_Rest
|
210 |
+
*/
|
211 |
+
public function rest()
|
212 |
+
{
|
213 |
+
if(is_null(self::$_rest)) {
|
214 |
+
self::$_rest = new Mage_Connect_Rest(self::config()->protocol);
|
215 |
+
}
|
216 |
+
return self::$_rest;
|
217 |
+
}
|
218 |
+
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Get commands list sorted
|
222 |
+
* @return array
|
223 |
+
*/
|
224 |
+
public static function getCommands()
|
225 |
+
{
|
226 |
+
if(!count(self::$_commandsAll)) {
|
227 |
+
self::registerCommands();
|
228 |
+
}
|
229 |
+
ksort(self::$_commandsAll);
|
230 |
+
return self::$_commandsAll;
|
231 |
+
}
|
232 |
+
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Get Getopt args from command definitions
|
236 |
+
* and parse them
|
237 |
+
* @param $command
|
238 |
+
* @return array
|
239 |
+
*/
|
240 |
+
public static function getGetoptArgs($command)
|
241 |
+
{
|
242 |
+
$commandInfo = self::commandInfo($command);
|
243 |
+
$short_args = '';
|
244 |
+
$long_args = array();
|
245 |
+
if (empty($commandInfo) || empty($commandInfo['options'])) {
|
246 |
+
return;
|
247 |
+
}
|
248 |
+
reset($commandInfo['options']);
|
249 |
+
while (list($option, $info) = each($commandInfo['options'])) {
|
250 |
+
$larg = $sarg = '';
|
251 |
+
if (isset($info['arg'])) {
|
252 |
+
if ($info['arg']{0} == '(') {
|
253 |
+
$larg = '==';
|
254 |
+
$sarg = '::';
|
255 |
+
$arg = substr($info['arg'], 1, -1);
|
256 |
+
} else {
|
257 |
+
$larg = '=';
|
258 |
+
$sarg = ':';
|
259 |
+
$arg = $info['arg'];
|
260 |
+
}
|
261 |
+
}
|
262 |
+
if (isset($info['shortopt'])) {
|
263 |
+
$short_args .= $info['shortopt'] . $sarg;
|
264 |
+
}
|
265 |
+
$long_args[] = $option . $larg;
|
266 |
+
}
|
267 |
+
return array($short_args, $long_args);
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Try to register commands automatically
|
272 |
+
* @return void
|
273 |
+
*/
|
274 |
+
public static function registerCommands()
|
275 |
+
{
|
276 |
+
$pathCommands = dirname(__FILE__).DIRECTORY_SEPARATOR.basename(__FILE__, ".php");
|
277 |
+
$f = new DirectoryIterator($pathCommands);
|
278 |
+
foreach($f as $file) {
|
279 |
+
if (! $file->isFile()) {
|
280 |
+
continue;
|
281 |
+
}
|
282 |
+
$pattern = preg_match("/(.*)_Header\.php/imsu", $file->getFilename(), $matches);
|
283 |
+
if(! $pattern) {
|
284 |
+
continue;
|
285 |
+
}
|
286 |
+
include($file->getPathname());
|
287 |
+
if(! isset($commands)) {
|
288 |
+
continue;
|
289 |
+
}
|
290 |
+
$class = __CLASS__."_".$matches[1];
|
291 |
+
foreach ($commands as $k=>$v) {
|
292 |
+
$commands[$k]['class'] = $class;
|
293 |
+
self::$_commandsAll[$k] = $commands[$k];
|
294 |
+
}
|
295 |
+
self::$_commandsByClass[$class] = $commands;
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
public function doError($command, $message)
|
300 |
+
{
|
301 |
+
return $this->ui()->doError($command, $message);
|
302 |
+
}
|
303 |
+
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Set command return
|
307 |
+
* @param string $key
|
308 |
+
* @param mixed $val
|
309 |
+
* @return void
|
310 |
+
*/
|
311 |
+
public static function setReturn($key, $val)
|
312 |
+
{
|
313 |
+
self::$_return[$key] = $val;
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Get command return
|
318 |
+
* @param $key
|
319 |
+
* @param $clear
|
320 |
+
* @return mixed
|
321 |
+
*/
|
322 |
+
public static function getReturn($key, $clear = true)
|
323 |
+
{
|
324 |
+
if(isset(self::$_return[$key])) {
|
325 |
+
$out = self::$_return[$key];
|
326 |
+
if($clear) {
|
327 |
+
unset(self::$_return[$key]);
|
328 |
+
}
|
329 |
+
return $out;
|
330 |
+
}
|
331 |
+
return null;
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Cleanup command params from empty strings
|
336 |
+
*
|
337 |
+
* @param array $params by reference
|
338 |
+
*/
|
339 |
+
public function cleanupParams(array & $params)
|
340 |
+
{
|
341 |
+
$newParams = array();
|
342 |
+
if(!count($params)) {
|
343 |
+
return;
|
344 |
+
}
|
345 |
+
foreach($params as $k=>$v) {
|
346 |
+
if(is_string($v)) {
|
347 |
+
$v = trim($v);
|
348 |
+
if(!strlen($v)) {
|
349 |
+
continue;
|
350 |
+
}
|
351 |
+
}
|
352 |
+
$newParams[] = $v;
|
353 |
+
}
|
354 |
+
$params = $newParams;
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Splits first command argument: channel/package
|
359 |
+
* to two arguments if found in top of array
|
360 |
+
*
|
361 |
+
* @param array $params
|
362 |
+
*/
|
363 |
+
public function splitPackageArgs(array & $params)
|
364 |
+
{
|
365 |
+
if(!count($params) || !isset($params[0])) {
|
366 |
+
return;
|
367 |
+
}
|
368 |
+
if($this->validator()->validateUrl($params[0])) {
|
369 |
+
return;
|
370 |
+
}
|
371 |
+
if(preg_match("@([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)@ims", $params[0], $subs)) {
|
372 |
+
$params[0] = $subs[2];
|
373 |
+
array_unshift($params, $subs[1]);
|
374 |
+
}
|
375 |
+
}
|
376 |
+
|
377 |
+
|
378 |
+
/**
|
379 |
+
* Get packager instance
|
380 |
+
* @return Mage_Connect_Pacakger
|
381 |
+
*/
|
382 |
+
public function getPackager()
|
383 |
+
{
|
384 |
+
if(!self::$_packager) {
|
385 |
+
self::$_packager = new Mage_Connect_Packager();
|
386 |
+
}
|
387 |
+
return self::$_packager;
|
388 |
+
}
|
389 |
+
|
390 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
);
|
downloader/lib/Mage/Connect/Command/Config.php
ADDED
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
class Mage_Connect_Command_Config
|
29 |
+
extends Mage_Connect_Command
|
30 |
+
|
31 |
+
{
|
32 |
+
const PARAM_KEY = 0;
|
33 |
+
const PARAM_VAL = 1;
|
34 |
+
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Show config variable
|
38 |
+
* @param string $command
|
39 |
+
* @param array $options
|
40 |
+
* @param array $params
|
41 |
+
* @return void
|
42 |
+
*/
|
43 |
+
public function doConfigShow($command, $options, $params)
|
44 |
+
{
|
45 |
+
$this->cleanupParams($params);
|
46 |
+
|
47 |
+
try {
|
48 |
+
$values = array();
|
49 |
+
|
50 |
+
$packager = $this->getPackager();
|
51 |
+
$ftp = empty($options['ftp']) ? false : $options['ftp'];
|
52 |
+
if($ftp) {
|
53 |
+
list($config, $ftpObj) = $packager->getRemoteConfig($ftp);
|
54 |
+
} else {
|
55 |
+
$config = $this->config();
|
56 |
+
}
|
57 |
+
foreach( $config as $k=>$v ) {
|
58 |
+
$values[$k] = $v;
|
59 |
+
}
|
60 |
+
if($ftp) {
|
61 |
+
@unlink($config->getFilename());
|
62 |
+
}
|
63 |
+
$data = array($command => array('data'=>$values));
|
64 |
+
$this->ui()->output($data);
|
65 |
+
} catch (Exception $e) {
|
66 |
+
if($ftp) {
|
67 |
+
@unlink($config->getFilename());
|
68 |
+
}
|
69 |
+
return $this->doError($command, $e->getMessage());
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Set config variable
|
76 |
+
* @param string $command
|
77 |
+
* @param array $options
|
78 |
+
* @param array $params
|
79 |
+
* @return void
|
80 |
+
*/
|
81 |
+
public function doConfigSet($command, $options, $params)
|
82 |
+
{
|
83 |
+
$this->cleanupParams($params);
|
84 |
+
|
85 |
+
try {
|
86 |
+
if(count($params) < 2) {
|
87 |
+
throw new Exception("Parameters count should be >= 2");
|
88 |
+
}
|
89 |
+
$key = strtolower($params[self::PARAM_KEY]);
|
90 |
+
$val = strval($params[self::PARAM_VAL]);
|
91 |
+
$packager = $this->getPackager();
|
92 |
+
|
93 |
+
$ftp = empty($options['ftp']) ? false : $options['ftp'];
|
94 |
+
if(!$ftp) {
|
95 |
+
$config = $this->config();
|
96 |
+
$ftp=$config->remote_config;
|
97 |
+
}
|
98 |
+
if($ftp) {
|
99 |
+
list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
|
100 |
+
}
|
101 |
+
|
102 |
+
if(!$config->hasKey($key)) {
|
103 |
+
throw new Exception ("No such config variable: {$key}!");
|
104 |
+
}
|
105 |
+
if(!$config->validate($key, $val)) {
|
106 |
+
$possible = $this->config()->possible($key);
|
107 |
+
$type = $this->config()->type($key);
|
108 |
+
$errString = "Invalid value specified for $key!";
|
109 |
+
throw new Exception($errString);
|
110 |
+
}
|
111 |
+
if($ftp) {
|
112 |
+
$packager->writeToRemoteConfig($config, $ftpObj);
|
113 |
+
}
|
114 |
+
$this->config()->$key = $val;
|
115 |
+
$this->ui()->output('Success');
|
116 |
+
} catch (Exception $e) {
|
117 |
+
if($ftp) {
|
118 |
+
@unlink($config->getFilename());
|
119 |
+
}
|
120 |
+
return $this->doError($command, $e->getMessage());
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Get config var
|
126 |
+
* @param string $command
|
127 |
+
* @param array $options
|
128 |
+
* @param array $params
|
129 |
+
* @return void
|
130 |
+
*/
|
131 |
+
public function doConfigGet($command, $options, $params)
|
132 |
+
{
|
133 |
+
$this->cleanupParams($params);
|
134 |
+
|
135 |
+
try {
|
136 |
+
if(count($params) < 1) {
|
137 |
+
throw new Exception("Parameters count should be >= 1");
|
138 |
+
}
|
139 |
+
$packager = $this->getPackager();
|
140 |
+
$ftp = empty($options['ftp']) ? false : $options['ftp'];
|
141 |
+
if($ftp) {
|
142 |
+
list($config, $ftpObj) = $packager->getRemoteConfig($ftp);
|
143 |
+
} else {
|
144 |
+
$config = $this->config();
|
145 |
+
}
|
146 |
+
$key = strtolower($params[self::PARAM_KEY]);
|
147 |
+
if(!$config->hasKey($key)) {
|
148 |
+
throw new Exception("No such config variable '{$key}'!");
|
149 |
+
}
|
150 |
+
if($ftp) {
|
151 |
+
@unlink($config->getFilename());
|
152 |
+
}
|
153 |
+
$this->ui()->output($config->$key);
|
154 |
+
} catch (Exception $e) {
|
155 |
+
if($ftp) {
|
156 |
+
@unlink($config->getFilename());
|
157 |
+
}
|
158 |
+
return $this->doError($command, $e->getMessage());
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Config help
|
164 |
+
* @param string $command
|
165 |
+
* @param array $options
|
166 |
+
* @param array $params
|
167 |
+
* @return void
|
168 |
+
*/
|
169 |
+
public function doConfigHelp($command, $options, $params)
|
170 |
+
{
|
171 |
+
try {
|
172 |
+
$this->cleanupParams($params);
|
173 |
+
if(count($params) < 1) {
|
174 |
+
throw new Exception( "Parameters count should be >= 1");
|
175 |
+
}
|
176 |
+
$packager = $this->getPackager();
|
177 |
+
$ftp = empty($options['ftp']) ? false : $options['ftp'];
|
178 |
+
if($ftp) {
|
179 |
+
list($config, $ftpObj) = $packager->getRemoteConfig($ftp);
|
180 |
+
} else {
|
181 |
+
$config = $this->config();
|
182 |
+
}
|
183 |
+
|
184 |
+
$key = strtolower($params[self::PARAM_KEY]);
|
185 |
+
if(!$this->config()->hasKey($key)) {
|
186 |
+
throw new Exception("No such config variable '{$key}'!");
|
187 |
+
}
|
188 |
+
|
189 |
+
$possible = $config->possible($key);
|
190 |
+
$type = $config->type($key);
|
191 |
+
$doc = $config->doc($key);
|
192 |
+
if($ftp) {
|
193 |
+
@unlink($config->getFilename());
|
194 |
+
}
|
195 |
+
$data = array();
|
196 |
+
$data[$command]['data'] = array(
|
197 |
+
'name' => array('Variable name', $key),
|
198 |
+
'type' => array('Value type', $type),
|
199 |
+
'possible' => array('Possible values', $possible),
|
200 |
+
'doc' => $doc,
|
201 |
+
);
|
202 |
+
$this->ui()->output($data);
|
203 |
+
} catch (Exception $e) {
|
204 |
+
if($ftp) {
|
205 |
+
@unlink($config->getFilename());
|
206 |
+
}
|
207 |
+
return $this->doError($command, $e->getMessage());
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
}
|
212 |
+
|
213 |
+
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
);
|
downloader/lib/Mage/Connect/Command/Install.php
ADDED
@@ -0,0 +1,567 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
final class Mage_Connect_Command_Install
|
29 |
+
extends Mage_Connect_Command
|
30 |
+
{
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Install action callback
|
34 |
+
* @param string $command
|
35 |
+
* @param array $options
|
36 |
+
* @param array $params
|
37 |
+
* @return void
|
38 |
+
*/
|
39 |
+
public function doInstall($command, $options, $params, $objects = array())
|
40 |
+
{
|
41 |
+
$this->cleanupParams($params);
|
42 |
+
|
43 |
+
$installFileMode = $command === 'install-file';
|
44 |
+
|
45 |
+
|
46 |
+
$cache=null;
|
47 |
+
/**
|
48 |
+
* @var $cache Mage_Connect_Singleconfig
|
49 |
+
*/
|
50 |
+
$ftpObj=null;
|
51 |
+
|
52 |
+
|
53 |
+
try {
|
54 |
+
$packager = $this->getPackager();
|
55 |
+
$forceMode = isset($options['force']);
|
56 |
+
$upgradeAllMode = $command == 'upgrade-all';
|
57 |
+
$upgradeMode = $command == 'upgrade' || $command == 'upgrade-all';
|
58 |
+
$noFilesInstall = isset($options['nofiles']);
|
59 |
+
$withDepsMode = !isset($options['nodeps']);
|
60 |
+
$ignoreModifiedMode = true || !isset($options['ignorelocalmodification']);
|
61 |
+
$clearInstallMode = $command == 'install' && !$forceMode;
|
62 |
+
$installAll = isset($options['install_all']);
|
63 |
+
$channelAuth = isset($options['auth'])?$options['auth']:array();
|
64 |
+
|
65 |
+
$rest = $this->rest();
|
66 |
+
$ftp = empty($options['ftp']) ? false : $options['ftp'];
|
67 |
+
if($ftp) {
|
68 |
+
list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
|
69 |
+
} else {
|
70 |
+
$config = $this->config();
|
71 |
+
$cache = $this->getSconfig();
|
72 |
+
}
|
73 |
+
if(empty($config->magento_root)){
|
74 |
+
$config->magento_root=dirname(dirname($_SERVER['SCRIPT_FILENAME']));
|
75 |
+
}
|
76 |
+
chdir($config->magento_root);
|
77 |
+
$dirCache = DIRECTORY_SEPARATOR . $config->downloader_path . DIRECTORY_SEPARATOR
|
78 |
+
. Mage_Connect_Config::DEFAULT_CACHE_PATH;
|
79 |
+
$dirTmp = DIRECTORY_SEPARATOR . Mage_Connect_Package_Reader::PATH_TO_TEMPORARY_DIRECTORY;
|
80 |
+
$dirMedia = DIRECTORY_SEPARATOR . 'media';
|
81 |
+
$isWritable = true;
|
82 |
+
if($ftp) {
|
83 |
+
$cwd=$ftpObj->getcwd();
|
84 |
+
$ftpObj->mkdirRecursive($cwd . $dirCache,0777);
|
85 |
+
$ftpObj->chdir($cwd);
|
86 |
+
$ftpObj->mkdirRecursive($cwd . $dirTmp,0777);
|
87 |
+
$ftpObj->chdir($cwd);
|
88 |
+
$ftpObj->mkdirRecursive($cwd . $dirMedia,0777);
|
89 |
+
$ftpObj->chdir($cwd);
|
90 |
+
$err = "Please check for sufficient ftp write file permissions.";
|
91 |
+
} else {
|
92 |
+
@mkdir($config->magento_root . $dirCache,0777,true);
|
93 |
+
@mkdir($config->magento_root . $dirTmp,0777,true);
|
94 |
+
@mkdir($config->magento_root . $dirMedia,0777,true);
|
95 |
+
$isWritable = is_writable($config->magento_root)
|
96 |
+
&& is_writable($config->magento_root . DIRECTORY_SEPARATOR . $config->downloader_path)
|
97 |
+
&& is_writable($config->magento_root . $dirCache)
|
98 |
+
&& is_writable($config->magento_root . $dirTmp)
|
99 |
+
&& is_writable($config->magento_root . $dirMedia);
|
100 |
+
$err = "Please check for sufficient write file permissions.";
|
101 |
+
}
|
102 |
+
$isWritable = $isWritable && is_writable($config->magento_root . $dirMedia)
|
103 |
+
&& is_writable($config->magento_root . $dirCache)
|
104 |
+
&& is_writable($config->magento_root . $dirTmp);
|
105 |
+
if(!$isWritable){
|
106 |
+
$this->doError($command, $err);
|
107 |
+
throw new Exception(
|
108 |
+
'Your Magento folder does not have sufficient write permissions, which downloader requires.'
|
109 |
+
);
|
110 |
+
}
|
111 |
+
if(!empty($channelAuth)){
|
112 |
+
$rest->getLoader()->setCredentials($channelAuth['username'], $channelAuth['password']);
|
113 |
+
}
|
114 |
+
|
115 |
+
if($installFileMode) {
|
116 |
+
if(count($params) < 1) {
|
117 |
+
throw new Exception("Argument should be: filename");
|
118 |
+
}
|
119 |
+
$filename = $params[0];
|
120 |
+
if(!@file_exists($filename)) {
|
121 |
+
throw new Exception("File '{$filename}' not found");
|
122 |
+
}
|
123 |
+
if(!@is_readable($filename)) {
|
124 |
+
throw new Exception("File '{$filename}' is not readable");
|
125 |
+
}
|
126 |
+
|
127 |
+
$package = new Mage_Connect_Package($filename);
|
128 |
+
$package->setConfig($config);
|
129 |
+
$package->validate();
|
130 |
+
$errors = $package->getErrors();
|
131 |
+
if(count($errors)) {
|
132 |
+
throw new Exception("Package file is invalid\n".implode("\n", $errors));
|
133 |
+
}
|
134 |
+
|
135 |
+
$pChan = $package->getChannel();
|
136 |
+
$pName = $package->getName();
|
137 |
+
$pVer = $package->getVersion();
|
138 |
+
|
139 |
+
|
140 |
+
if (!($cache->isChannelName($pChan) || $cache->isChannelAlias($pChan))) {
|
141 |
+
throw new Exception("The '{$pChan}' channel is not installed. Please use the MAGE shell "
|
142 |
+
. "script to install the '{$pChan}' channel.");
|
143 |
+
}
|
144 |
+
|
145 |
+
$conflicts = $cache->hasConflicts($pChan, $pName, $pVer);
|
146 |
+
|
147 |
+
if(false !== $conflicts) {
|
148 |
+
$conflicts = implode(", ",$conflicts);
|
149 |
+
if($forceMode) {
|
150 |
+
$this->doError($command, "Package {$pChan}/{$pName} {$pVer} conflicts with: ".$conflicts);
|
151 |
+
} else {
|
152 |
+
throw new Exception("Package {$pChan}/{$pName} {$pVer} conflicts with: ".$conflicts);
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
$conflicts = $package->checkPhpDependencies();
|
157 |
+
if(true !== $conflicts) {
|
158 |
+
$confilcts = implode(",",$conflicts);
|
159 |
+
$err = "Package {$pChan}/{$pName} {$pVer} depends on PHP extensions: ".$conflicts;
|
160 |
+
if($forceMode) {
|
161 |
+
$this->doError($command, $err);
|
162 |
+
} else {
|
163 |
+
throw new Exception($err);
|
164 |
+
}
|
165 |
+
}
|
166 |
+
|
167 |
+
$conflicts = $package->checkPhpVersion();
|
168 |
+
if(true !== $conflicts) {
|
169 |
+
$err = "Package {$pChan}/{$pName} {$pVer}: ".$conflicts;
|
170 |
+
if($forceMode) {
|
171 |
+
$this->doError($command, $err);
|
172 |
+
} else {
|
173 |
+
throw new Exception($err);
|
174 |
+
}
|
175 |
+
}
|
176 |
+
|
177 |
+
|
178 |
+
if(!$noFilesInstall) {
|
179 |
+
if($ftp) {
|
180 |
+
$packager->processInstallPackageFtp($package, $filename, $config, $ftpObj);
|
181 |
+
} else {
|
182 |
+
$packager->processInstallPackage($package, $filename, $config);
|
183 |
+
}
|
184 |
+
}
|
185 |
+
$cache->addPackage($package);
|
186 |
+
$installedDeps = array();
|
187 |
+
$installedDepsAssoc = array();
|
188 |
+
$installedDepsAssoc[] = array('channel'=>$pChan, 'name'=>$pName, 'version'=>$pVer);
|
189 |
+
$installedDeps[] = array($pChan, $pName, $pVer);
|
190 |
+
|
191 |
+
|
192 |
+
$title = isset($options['title']) ? $options['title'] : "Package installed: ";
|
193 |
+
$out = array($command => array('data'=>$installedDeps, 'assoc'=>$installedDepsAssoc, 'title'=>$title));
|
194 |
+
|
195 |
+
if($ftp) {
|
196 |
+
$packager->writeToRemoteCache($cache, $ftpObj);
|
197 |
+
@unlink($config->getFilename());
|
198 |
+
}
|
199 |
+
|
200 |
+
$this->ui()->output($out);
|
201 |
+
return $out[$command]['data'];
|
202 |
+
}
|
203 |
+
|
204 |
+
if(!$upgradeAllMode) {
|
205 |
+
|
206 |
+
if(count($params) < 2) {
|
207 |
+
throw new Exception("Argument should be: channelName packageName");
|
208 |
+
}
|
209 |
+
$channel = $params[0];
|
210 |
+
$package = $params[1];
|
211 |
+
$argVersionMax = isset($params[2]) ? $params[2]: false;
|
212 |
+
$argVersionMin = isset($params[3]) ? $params[3]: false;
|
213 |
+
|
214 |
+
$cache->checkChannel($channel, $config, $rest);
|
215 |
+
$channelName = $cache->chanName($channel);
|
216 |
+
$this->ui()->output("Checking dependencies of packages");
|
217 |
+
$packagesToInstall = $packager->getDependenciesList($channelName, $package, $cache, $config,
|
218 |
+
$argVersionMax, $argVersionMin, $withDepsMode, false, $rest
|
219 |
+
);
|
220 |
+
/*
|
221 |
+
* process 'failed' results
|
222 |
+
*/
|
223 |
+
if(count($packagesToInstall['failed'])) {
|
224 |
+
$showError=!count($packagesToInstall['result']);
|
225 |
+
foreach($packagesToInstall['failed'] as $failed){
|
226 |
+
//$failed = array(
|
227 |
+
// 'name'=>$package,
|
228 |
+
// 'channel'=>$chanName,
|
229 |
+
// 'max'=>$versionMax,
|
230 |
+
// 'min'=>$versionMin,
|
231 |
+
// 'reason'=>$e->getMessage()
|
232 |
+
//);
|
233 |
+
$msg="Package {$failed['channel']}/{$failed['name']} failed: ".$failed['reason'];
|
234 |
+
if($showError){
|
235 |
+
$this->doError($command, $msg);
|
236 |
+
}else{
|
237 |
+
$this->ui()->output($msg);
|
238 |
+
}
|
239 |
+
}
|
240 |
+
}
|
241 |
+
$packagesToInstall = $packagesToInstall['result'];
|
242 |
+
} else {
|
243 |
+
if(empty($params[0])) {
|
244 |
+
$channels = $cache->getChannelNames();
|
245 |
+
} else {
|
246 |
+
$channel = $params[0];
|
247 |
+
if(!$cache->isChannel($channel)) {
|
248 |
+
throw new Exception("'{$channel}' is not existant channel name / valid uri");
|
249 |
+
}
|
250 |
+
$channels = $cache->chanName($channel);
|
251 |
+
}
|
252 |
+
$packagesToInstall = array();
|
253 |
+
$neededToUpgrade = $packager->getUpgradesList($channels, $cache, $config, $rest);
|
254 |
+
foreach($neededToUpgrade as $chan=>$packages) {
|
255 |
+
foreach($packages as $name=>$data) {
|
256 |
+
$versionTo = $data['to'];
|
257 |
+
$tmp = $packager->getDependenciesList($chan, $name, $cache, $config, $versionTo, $versionTo,
|
258 |
+
$withDepsMode, false, $rest
|
259 |
+
);
|
260 |
+
if(count($tmp['result'])) {
|
261 |
+
$packagesToInstall = array_merge($packagesToInstall, $tmp['result']);
|
262 |
+
}
|
263 |
+
}
|
264 |
+
}
|
265 |
+
}
|
266 |
+
|
267 |
+
/**
|
268 |
+
* Make installation
|
269 |
+
*/
|
270 |
+
$installedDeps = array();
|
271 |
+
$installedDepsAssoc = array();
|
272 |
+
$keys = array();
|
273 |
+
|
274 |
+
foreach($packagesToInstall as $package) {
|
275 |
+
try {
|
276 |
+
$pName = $package['name'];
|
277 |
+
$pChan = $package['channel'];
|
278 |
+
$pVer = $package['downloaded_version'];
|
279 |
+
$pInstallState = $package['install_state'];
|
280 |
+
$rest->setChannel($cache->chanUrl($pChan));
|
281 |
+
|
282 |
+
/**
|
283 |
+
* Skip existing packages
|
284 |
+
*/
|
285 |
+
if ($upgradeMode && $cache->hasPackage($pChan, $pName, $pVer, $pVer)
|
286 |
+
|| ('already_installed' == $pInstallState && !$forceMode)
|
287 |
+
) {
|
288 |
+
$this->ui()->output("Already installed: {$pChan}/{$pName} {$pVer}, skipping");
|
289 |
+
continue;
|
290 |
+
}
|
291 |
+
|
292 |
+
if('incompartible' == $pInstallState) {
|
293 |
+
$this->ui()->output(
|
294 |
+
"Package incompartible with installed Magento: {$pChan}/{$pName} {$pVer}, skipping"
|
295 |
+
);
|
296 |
+
continue;
|
297 |
+
}
|
298 |
+
|
299 |
+
$conflicts = $cache->hasConflicts($pChan, $pName, $pVer);
|
300 |
+
|
301 |
+
if(false !== $conflicts) {
|
302 |
+
$conflicts = implode(", ",$conflicts);
|
303 |
+
if($forceMode) {
|
304 |
+
$this->doError($command, "Package {$pChan}/{$pName} {$pVer} conflicts with: ".$conflicts);
|
305 |
+
} else {
|
306 |
+
throw new Exception("Package {$pChan}/{$pName} {$pVer} conflicts with: ".$conflicts);
|
307 |
+
}
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Modifications
|
312 |
+
*/
|
313 |
+
if (($upgradeMode || ($pInstallState == 'upgrade')) && !$ignoreModifiedMode) {
|
314 |
+
if($ftp) {
|
315 |
+
$modifications = $packager->getRemoteModifiedFiles($pChan, $pName, $cache, $config, $ftp);
|
316 |
+
} else {
|
317 |
+
$modifications = $packager->getLocalModifiedFiles($pChan, $pName, $cache, $config);
|
318 |
+
}
|
319 |
+
if (count($modifications) > 0) {
|
320 |
+
$this->ui()->output('Changed locally: ');
|
321 |
+
foreach ($modifications as $row) {
|
322 |
+
if(!$ftp) {
|
323 |
+
$this->ui()->output($config->magento_root.DS.$row);
|
324 |
+
} else {
|
325 |
+
$this->ui()->output($row);
|
326 |
+
}
|
327 |
+
}
|
328 |
+
/*$this->ui()->confirm('Do you want rewrite all files?');
|
329 |
+
continue;*/
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
if($ftp) {
|
334 |
+
$cwd=$ftpObj->getcwd();
|
335 |
+
$dir=$cwd . DIRECTORY_SEPARATOR .$config->downloader_path . DIRECTORY_SEPARATOR
|
336 |
+
. Mage_Connect_Config::DEFAULT_CACHE_PATH . DIRECTORY_SEPARATOR . trim( $pChan, "\\/");
|
337 |
+
$ftpObj->mkdirRecursive($dir,0777);
|
338 |
+
$ftpObj->chdir($cwd);
|
339 |
+
} else {
|
340 |
+
$dir = $config->getChannelCacheDir($pChan);
|
341 |
+
@mkdir($dir, 0777, true);
|
342 |
+
}
|
343 |
+
$dir = $config->getChannelCacheDir($pChan);
|
344 |
+
$packageFileName = $pName."-".$pVer.".tgz";
|
345 |
+
$file = $dir.DIRECTORY_SEPARATOR.$packageFileName;
|
346 |
+
if(!@file_exists($file)) {
|
347 |
+
$this->ui()->output("Starting to download $packageFileName ...");
|
348 |
+
$rest->downloadPackageFileOfRelease($pName, $pVer, $file);
|
349 |
+
$this->ui()->output(sprintf("...done: %s bytes", number_format(filesize($file))));
|
350 |
+
}
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Remove old version package before install new
|
354 |
+
*/
|
355 |
+
if ($cache->hasPackage($pChan, $pName)) {
|
356 |
+
if ($ftp) {
|
357 |
+
$packager->processUninstallPackageFtp($pChan, $pName, $cache, $ftpObj);
|
358 |
+
} else {
|
359 |
+
$packager->processUninstallPackage($pChan, $pName, $cache, $config);
|
360 |
+
}
|
361 |
+
$cache->deletePackage($pChan, $pName);
|
362 |
+
}
|
363 |
+
|
364 |
+
$package = new Mage_Connect_Package($file);
|
365 |
+
if ($clearInstallMode && $pInstallState != 'upgrade' && !$installAll) {
|
366 |
+
$this->validator()->validateContents($package->getContents(), $config);
|
367 |
+
$errors = $this->validator()->getErrors();
|
368 |
+
if (count($errors)) {
|
369 |
+
throw new Exception("Package '{$pName}' is invalid\n" . implode("\n", $errors));
|
370 |
+
}
|
371 |
+
}
|
372 |
+
|
373 |
+
$conflicts = $package->checkPhpDependencies();
|
374 |
+
if(true !== $conflicts) {
|
375 |
+
$confilcts = implode(",",$conflicts);
|
376 |
+
$err = "Package {$pChan}/{$pName} {$pVer} depends on PHP extensions: ".$conflicts;
|
377 |
+
if($forceMode) {
|
378 |
+
$this->doError($command, $err);
|
379 |
+
} else {
|
380 |
+
throw new Exception($err);
|
381 |
+
}
|
382 |
+
}
|
383 |
+
|
384 |
+
$conflicts = $package->checkPhpVersion();
|
385 |
+
if(true !== $conflicts) {
|
386 |
+
$err = "Package {$pChan}/{$pName} {$pVer}: ".$conflicts;
|
387 |
+
if($forceMode) {
|
388 |
+
$this->doError($command, $err);
|
389 |
+
} else {
|
390 |
+
throw new Exception($err);
|
391 |
+
}
|
392 |
+
}
|
393 |
+
|
394 |
+
/**
|
395 |
+
* @todo: make "Use custom permissions" functionality working
|
396 |
+
*/
|
397 |
+
if(!$noFilesInstall) {
|
398 |
+
$this->ui()->output("Installing package {$pChan}/{$pName} {$pVer}");
|
399 |
+
if($ftp) {
|
400 |
+
$packager->processInstallPackageFtp($package, $file, $config, $ftpObj);
|
401 |
+
} else {
|
402 |
+
$packager->processInstallPackage($package, $file, $config);
|
403 |
+
}
|
404 |
+
$this->ui()->output("Package {$pChan}/{$pName} {$pVer} installed successfully");
|
405 |
+
}
|
406 |
+
$cache->addPackage($package);
|
407 |
+
|
408 |
+
$installedDepsAssoc[] = array('channel'=>$pChan, 'name'=>$pName, 'version'=>$pVer);
|
409 |
+
$installedDeps[] = array($pChan, $pName, $pVer);
|
410 |
+
|
411 |
+
} catch(Exception $e) {
|
412 |
+
$this->doError($command, $e->getMessage());
|
413 |
+
}
|
414 |
+
}
|
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 |
+
|
429 |
+
} catch (Exception $e) {
|
430 |
+
if($ftp) {
|
431 |
+
$packager->writeToRemoteCache($cache, $ftpObj);
|
432 |
+
@unlink($config->getFilename());
|
433 |
+
}
|
434 |
+
return $this->doError($command, $e->getMessage());
|
435 |
+
}
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* Upgrade action callback
|
440 |
+
* @param string $command
|
441 |
+
* @param array $options
|
442 |
+
* @param array $params
|
443 |
+
* @return void
|
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 |
+
* @param string $command
|
454 |
+
* @param array $options
|
455 |
+
* @param array $params
|
456 |
+
* @return void
|
457 |
+
*/
|
458 |
+
public function doUpgradeAll($command, $options, $params)
|
459 |
+
{
|
460 |
+
$options['title'] = "Package upgraded: ";
|
461 |
+
return $this->doInstall($command, $options, $params);
|
462 |
+
}
|
463 |
+
|
464 |
+
/**
|
465 |
+
* Uninstall package callback
|
466 |
+
* @param string $command
|
467 |
+
* @param array $options
|
468 |
+
* @param array $params
|
469 |
+
* @return unknown_type
|
470 |
+
*/
|
471 |
+
public function doUninstall($command, $options, $params)
|
472 |
+
{
|
473 |
+
$this->cleanupParams($params);
|
474 |
+
//$this->splitPackageArgs($params);
|
475 |
+
|
476 |
+
try {
|
477 |
+
if(count($params) != 2) {
|
478 |
+
throw new Exception("Argument count should be = 2");
|
479 |
+
}
|
480 |
+
|
481 |
+
$channel = $params[0];
|
482 |
+
$package = $params[1];
|
483 |
+
$packager = $this->getPackager();
|
484 |
+
$withDepsMode = !isset($options['nodeps']);
|
485 |
+
$forceMode = isset($options['force']);
|
486 |
+
|
487 |
+
$ftp = empty($options['ftp']) ? false : $options['ftp'];
|
488 |
+
if($ftp) {
|
489 |
+
list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
|
490 |
+
} else {
|
491 |
+
$cache = $this->getSconfig();
|
492 |
+
$config = $this->config();
|
493 |
+
}
|
494 |
+
|
495 |
+
$chan = $cache->getChannel($channel);
|
496 |
+
$channel = $cache->chanName($channel);
|
497 |
+
if(!$cache->hasPackage($channel, $package)) {
|
498 |
+
throw new Exception("Package is not installed");
|
499 |
+
}
|
500 |
+
|
501 |
+
$deletedPackages = array();
|
502 |
+
$list = $packager->getUninstallList($channel, $package, $cache, $config, $withDepsMode);
|
503 |
+
foreach($list['list'] as $packageData) {
|
504 |
+
try {
|
505 |
+
$reqd = $cache->requiredByOtherPackages(
|
506 |
+
$packageData['channel'],
|
507 |
+
$packageData['name'],
|
508 |
+
$list['list']
|
509 |
+
);
|
510 |
+
if(count($reqd)) {
|
511 |
+
$errMessage = "{$packageData['channel']}/{$packageData['name']} "
|
512 |
+
. "{$packageData['version']} is required by: ";
|
513 |
+
$t = array();
|
514 |
+
foreach($reqd as $r) {
|
515 |
+
$t[] = $r['channel']."/".$r['name']. " ".$r['version'];
|
516 |
+
}
|
517 |
+
$errMessage .= implode(", ", $t);
|
518 |
+
if($forceMode) {
|
519 |
+
$this->ui()->output("Warning: ".$errMessage);
|
520 |
+
} else {
|
521 |
+
throw new Exception($errMessage);
|
522 |
+
}
|
523 |
+
}
|
524 |
+
} catch(Exception $e) {
|
525 |
+
if($forceMode) {
|
526 |
+
$this->doError($command, $e->getMessage());
|
527 |
+
} else {
|
528 |
+
throw new Exception($e->getMessage());
|
529 |
+
}
|
530 |
+
}
|
531 |
+
}
|
532 |
+
foreach($list['list'] as $packageData) {
|
533 |
+
try {
|
534 |
+
list($chan, $pack) = array($packageData['channel'], $packageData['name']);
|
535 |
+
$packageName = $packageData['channel'] . "/" . $packageData['name'];
|
536 |
+
$this->ui()->output("Starting to uninstall $packageName ");
|
537 |
+
if($ftp) {
|
538 |
+
$packager->processUninstallPackageFtp($chan, $pack, $cache, $ftpObj);
|
539 |
+
} else {
|
540 |
+
$packager->processUninstallPackage($chan, $pack, $cache, $config);
|
541 |
+
}
|
542 |
+
$cache->deletePackage($chan, $pack);
|
543 |
+
$deletedPackages[] = array($chan, $pack);
|
544 |
+
$this->ui()->output("Package {$packageName} uninstalled");
|
545 |
+
} catch(Exception $e) {
|
546 |
+
if($forceMode) {
|
547 |
+
$this->doError($command, $e->getMessage());
|
548 |
+
} else {
|
549 |
+
throw new Exception($e->getMessage());
|
550 |
+
}
|
551 |
+
}
|
552 |
+
}
|
553 |
+
if($ftp) {
|
554 |
+
$packager->writeToRemoteCache($cache, $ftpObj);
|
555 |
+
@unlink($config->getFilename());
|
556 |
+
}
|
557 |
+
$out = array($command=>array('data'=>$deletedPackages, 'title'=>'Package deleted: '));
|
558 |
+
$this->ui()->output($out);
|
559 |
+
|
560 |
+
} catch (Exception $e) {
|
561 |
+
return $this->doError($command, $e->getMessage());
|
562 |
+
}
|
563 |
+
|
564 |
+
}
|
565 |
+
|
566 |
+
}
|
567 |
+
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
);
|
downloader/lib/Mage/Connect/Command/Package.php
ADDED
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 = new Mage_Connect_Rest($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(array($command=> array('data'=>$result, 'title'=>"Package installation information for {$params[1]}: ")));
|
143 |
+
|
144 |
+
} catch (Exception $e) {
|
145 |
+
$this->doError($command, $e->getMessage());
|
146 |
+
}
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Display/get dependencies
|
151 |
+
* @param string $command
|
152 |
+
* @param array $options
|
153 |
+
* @param array $params
|
154 |
+
* @return void/array
|
155 |
+
*/
|
156 |
+
public function doPackageDependencies($command, $options, $params)
|
157 |
+
{
|
158 |
+
$this->cleanupParams($params);
|
159 |
+
try {
|
160 |
+
if(count($params) < 2) {
|
161 |
+
return $this->doError($command, "Argument count should be >= 2");
|
162 |
+
}
|
163 |
+
|
164 |
+
$channel = $params[0];
|
165 |
+
$package = $params[1];
|
166 |
+
|
167 |
+
$argVersionMin = isset($params[3]) ? $params[3] : false;
|
168 |
+
$argVersionMax = isset($params[2]) ? $params[2] : false;
|
169 |
+
|
170 |
+
$ftp = empty($options['ftp']) ? false : $options['ftp'];
|
171 |
+
$packager = $this->getPackager();
|
172 |
+
if($ftp) {
|
173 |
+
list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp);
|
174 |
+
} else {
|
175 |
+
$cache = $this->getSconfig();
|
176 |
+
$config = $this->config();
|
177 |
+
}
|
178 |
+
$data = $packager->getDependenciesList($channel, $package, $cache, $config, $argVersionMax, $argVersionMin);
|
179 |
+
$this->ui()->output(array($command=> array('data'=>$data['deps'], 'title'=>"Package deps for {$params[1]}: ")));
|
180 |
+
|
181 |
+
} catch (Exception $e) {
|
182 |
+
$this->doError($command, $e->getMessage());
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
public function doConvert($command, $options, $params)
|
187 |
+
{
|
188 |
+
$this->cleanupParams($params);
|
189 |
+
try {
|
190 |
+
if(count($params) < 1) {
|
191 |
+
throw new Exception("Arguments should be: source.tgz [target.tgz]");
|
192 |
+
}
|
193 |
+
$sourceFile = $params[0];
|
194 |
+
$converter = new Mage_Connect_Converter();
|
195 |
+
$targetFile = isset($params[1]) ? $params[1] : false;
|
196 |
+
$result = $converter->convertPearToMage($sourceFile, $targetFile);
|
197 |
+
$this->ui()->output("Saved to: ".$result);
|
198 |
+
} catch (Exception $e) {
|
199 |
+
$this->doError($command, $e->getMessage());
|
200 |
+
}
|
201 |
+
|
202 |
+
}
|
203 |
+
|
204 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
);
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
);
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
);
|
downloader/lib/Mage/Connect/Config.php
ADDED
@@ -0,0 +1,464 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
class Mage_Connect_Config implements Iterator
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Config file name
|
30 |
+
*
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
protected $_configFile;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Config loaded from file
|
37 |
+
*
|
38 |
+
* @var bool
|
39 |
+
*/
|
40 |
+
protected $_configLoaded;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Save file even if it not modified
|
44 |
+
*
|
45 |
+
* @var bool
|
46 |
+
*/
|
47 |
+
protected $_forceSave = false;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Stores last error message
|
51 |
+
*
|
52 |
+
* @var string
|
53 |
+
*/
|
54 |
+
protected $_configError = '';
|
55 |
+
|
56 |
+
const HEADER = "::ConnectConfig::v::1.0::";
|
57 |
+
const DEFAULT_DOWNLOADER_PATH = "downloader";
|
58 |
+
const DEFAULT_CACHE_PATH = ".cache";
|
59 |
+
|
60 |
+
protected $defaultProperties = array();
|
61 |
+
protected $properties = array();
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Constructor loads the data from config file
|
65 |
+
* @param string $configFile
|
66 |
+
*/
|
67 |
+
public function __construct($configFile = "connect.cfg")
|
68 |
+
{
|
69 |
+
$this->initProperties();
|
70 |
+
$this->_configFile = $configFile;
|
71 |
+
$this->load();
|
72 |
+
}
|
73 |
+
|
74 |
+
protected function initProperties()
|
75 |
+
{
|
76 |
+
$this->defaultProperties = array (
|
77 |
+
'php_ini' => array(
|
78 |
+
'type' => 'file',
|
79 |
+
'value' => '',
|
80 |
+
'prompt' => 'location of php.ini',
|
81 |
+
'doc' => "It's a location of PHP.ini to use blah",
|
82 |
+
'possible' => '/path/php.ini',
|
83 |
+
),
|
84 |
+
'protocol' => array(
|
85 |
+
'type' => 'set',
|
86 |
+
'value' => 'http',
|
87 |
+
'prompt' => 'preffered protocol',
|
88 |
+
'doc' => 'preffered protocol',
|
89 |
+
'rules' => array('http', 'ftp')
|
90 |
+
),
|
91 |
+
'preferred_state' => array(
|
92 |
+
'type' => 'set',
|
93 |
+
'value' => 'stable',
|
94 |
+
'prompt' => 'preferred package state',
|
95 |
+
'doc' => 'preferred package state',
|
96 |
+
'rules' => array('beta','alpha','stable','devel')
|
97 |
+
),
|
98 |
+
'use_custom_permissions_mode' => array (
|
99 |
+
'type' => 'bool',
|
100 |
+
'value' => false,
|
101 |
+
'prompt' => 'Use custom permissions for directory and file creation',
|
102 |
+
'doc' => 'Use custom permissions for directory and file creation',
|
103 |
+
'possible' => 'true, false',
|
104 |
+
),
|
105 |
+
'global_dir_mode' => array (
|
106 |
+
'type' => 'octal',
|
107 |
+
'value' => 0777,
|
108 |
+
'prompt' => 'directory creation mode',
|
109 |
+
'doc' => 'directory creation mode',
|
110 |
+
'possible' => '0777, 0666 etc.',
|
111 |
+
),
|
112 |
+
'global_file_mode' => array (
|
113 |
+
'type' => 'octal',
|
114 |
+
'value' => 0666,
|
115 |
+
'prompt' => 'file creation mode',
|
116 |
+
'doc' => 'file creation mode',
|
117 |
+
'possible' => '0777, 0666 etc.',
|
118 |
+
),
|
119 |
+
'downloader_path' => array(
|
120 |
+
'type' => 'dir',
|
121 |
+
'value' => 'downloader',
|
122 |
+
'prompt' => 'relative path, location of magento downloader',
|
123 |
+
'doc' => "relative path, location of magento downloader",
|
124 |
+
'possible' => 'path',
|
125 |
+
),
|
126 |
+
'magento_root' => array(
|
127 |
+
'type' => 'dir',
|
128 |
+
'value' => '',
|
129 |
+
'prompt' => 'location of magento root dir',
|
130 |
+
'doc' => "Location of magento",
|
131 |
+
'possible' => '/path',
|
132 |
+
),
|
133 |
+
'root_channel_uri' => array(
|
134 |
+
'type' => 'string',
|
135 |
+
'value' => 'connect20.magentocommerce.com/community',
|
136 |
+
'prompt' => '',
|
137 |
+
'doc' => "",
|
138 |
+
'possible' => '',
|
139 |
+
),
|
140 |
+
'root_channel' => array(
|
141 |
+
'type' => 'string',
|
142 |
+
'value' => 'community',
|
143 |
+
'prompt' => '',
|
144 |
+
'doc' => "",
|
145 |
+
'possible' => '',
|
146 |
+
),
|
147 |
+
'remote_config' => array(
|
148 |
+
'type' => 'string',
|
149 |
+
'value' => '',
|
150 |
+
'prompt' => '',
|
151 |
+
'doc' => "",
|
152 |
+
'possible' => 'ftp://name:password@host.com:port/path/to/folder/',
|
153 |
+
),
|
154 |
+
'sync_pear' => array(
|
155 |
+
'type' => 'boolean',
|
156 |
+
'value' => false,
|
157 |
+
'prompt' => '',
|
158 |
+
'doc' => "",
|
159 |
+
'possible' => '',
|
160 |
+
)
|
161 |
+
);
|
162 |
+
$this->properties = $this->defaultProperties;
|
163 |
+
}
|
164 |
+
|
165 |
+
public function getDownloaderPath()
|
166 |
+
{
|
167 |
+
return $this->magento_root . DIRECTORY_SEPARATOR . $this->downloader_path;
|
168 |
+
}
|
169 |
+
|
170 |
+
public function getPackagesCacheDir()
|
171 |
+
{
|
172 |
+
return $this->getDownloaderPath() . DIRECTORY_SEPARATOR . self::DEFAULT_CACHE_PATH;
|
173 |
+
}
|
174 |
+
|
175 |
+
public function getChannelCacheDir($channel)
|
176 |
+
{
|
177 |
+
$channel = trim( $channel, "\\/");
|
178 |
+
return $this->getPackagesCacheDir(). DIRECTORY_SEPARATOR . $channel;
|
179 |
+
}
|
180 |
+
|
181 |
+
public function getFilename()
|
182 |
+
{
|
183 |
+
return $this->_configFile;
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Load data from config file
|
188 |
+
*
|
189 |
+
* @return bool
|
190 |
+
*/
|
191 |
+
public function load()
|
192 |
+
{
|
193 |
+
$this->_configLoaded=false;
|
194 |
+
if (!is_file($this->_configFile)) {
|
195 |
+
if (!$this->save()) {
|
196 |
+
$this->_configError = 'Config file does not exists please save Settings';
|
197 |
+
} else {
|
198 |
+
$this->_configLoaded=true;
|
199 |
+
return true;
|
200 |
+
}
|
201 |
+
return false;
|
202 |
+
}
|
203 |
+
|
204 |
+
try {
|
205 |
+
$f = fopen($this->_configFile, "r");
|
206 |
+
fseek($f, 0, SEEK_SET);
|
207 |
+
} catch (Exception $e) {
|
208 |
+
$this->_configError = "Cannot open config file {$this->_configFile} please check file permission";
|
209 |
+
return false;
|
210 |
+
}
|
211 |
+
|
212 |
+
clearstatcache();
|
213 |
+
$size = filesize($this->_configFile);
|
214 |
+
if(!$size) {
|
215 |
+
$this->_configError = "Wrong config file size {$this->_configFile} please save Settings again";
|
216 |
+
return false;
|
217 |
+
}
|
218 |
+
|
219 |
+
$headerLen = strlen(self::HEADER);
|
220 |
+
try {
|
221 |
+
$contents = fread($f, $headerLen);
|
222 |
+
if(self::HEADER != $contents) {
|
223 |
+
$this->_configError = "Wrong configuration file {$this->_configFile} please save Settings again";
|
224 |
+
return false;
|
225 |
+
}
|
226 |
+
|
227 |
+
$size -= $headerLen;
|
228 |
+
$contents = fread($f, $size);
|
229 |
+
} catch (Exception $e) {
|
230 |
+
$this->_configError = "Configuration file {$this->_configFile} read error '{$e->getMessage()}'"
|
231 |
+
. " please save Settings again";
|
232 |
+
return false;
|
233 |
+
}
|
234 |
+
$data = @unserialize($contents);
|
235 |
+
if($data === false) {
|
236 |
+
$this->_configError = "Wrong configuration file {$this->_configFile} please save Settings again";
|
237 |
+
return false;
|
238 |
+
}
|
239 |
+
foreach($data as $k=>$v) {
|
240 |
+
$this->$k = $v;
|
241 |
+
}
|
242 |
+
@fclose($f);
|
243 |
+
$this->_configLoaded=true;
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Save config file on the disk or over ftp
|
248 |
+
*
|
249 |
+
* @return bool
|
250 |
+
*/
|
251 |
+
public function store()
|
252 |
+
{
|
253 |
+
$result = false;
|
254 |
+
if ($this->_forceSave || $this->_configLoaded || strlen($this->remote_config)>0) {
|
255 |
+
$data = serialize($this->toArray());
|
256 |
+
if (strlen($this->remote_config)>0) {
|
257 |
+
//save config over ftp
|
258 |
+
$confFile = $this->downloader_path . DIRECTORY_SEPARATOR . "connect.cfg";
|
259 |
+
try {
|
260 |
+
$ftpObj = new Mage_Connect_Ftp();
|
261 |
+
$ftpObj->connect($this->remote_config);
|
262 |
+
} catch (Exception $e) {
|
263 |
+
$this->_configError = 'Cannot access to deployment FTP path. '
|
264 |
+
. 'Check deployment FTP Installation path settings.';
|
265 |
+
return $result;
|
266 |
+
}
|
267 |
+
try {
|
268 |
+
$tempFile = tempnam(sys_get_temp_dir(),'config');
|
269 |
+
$f = fopen($tempFile, "w+");
|
270 |
+
fwrite($f, self::HEADER);
|
271 |
+
fwrite($f, $data);
|
272 |
+
fclose($f);
|
273 |
+
} catch (Exception $e) {
|
274 |
+
$this->_configError = 'Cannot access to temporary file storage to save Settings.'
|
275 |
+
. 'Contact your system administrator.';
|
276 |
+
return $result;
|
277 |
+
}
|
278 |
+
try {
|
279 |
+
$result = $ftpObj->upload($confFile, $tempFile);
|
280 |
+
$ftpObj->close();
|
281 |
+
} catch (Exception $e) {
|
282 |
+
$this->_configError = 'Cannot write file over FTP. '
|
283 |
+
. 'Check deployment FTP Installation path settings.';
|
284 |
+
return $result;
|
285 |
+
}
|
286 |
+
if (!$result) {
|
287 |
+
$this->_configError = '';
|
288 |
+
}
|
289 |
+
} elseif (is_file($this->_configFile) && is_writable($this->_configFile) || is_writable(getcwd())) {
|
290 |
+
try {
|
291 |
+
$f = fopen($this->_configFile, "w+");
|
292 |
+
fwrite($f, self::HEADER);
|
293 |
+
fwrite($f, $data);
|
294 |
+
fclose($f);
|
295 |
+
$result = true;
|
296 |
+
} catch (Exception $e) {
|
297 |
+
$result = false;
|
298 |
+
}
|
299 |
+
}
|
300 |
+
}
|
301 |
+
return $result;
|
302 |
+
}
|
303 |
+
|
304 |
+
public function validate($key, $val)
|
305 |
+
{
|
306 |
+
$rules = $this->extractField($key, 'rules');
|
307 |
+
if(null === $rules) {
|
308 |
+
return true;
|
309 |
+
} elseif( is_array($rules) ) {
|
310 |
+
return in_array($val, $rules);
|
311 |
+
}
|
312 |
+
return false;
|
313 |
+
}
|
314 |
+
|
315 |
+
public function possible($key)
|
316 |
+
{
|
317 |
+
$data = $this->getKey($key);
|
318 |
+
if(! $data) {
|
319 |
+
return null;
|
320 |
+
}
|
321 |
+
if('set' == $data['type']) {
|
322 |
+
return implode("|", $data['rules']);
|
323 |
+
}
|
324 |
+
if(!empty($data['possible'])) {
|
325 |
+
return $data['possible'];
|
326 |
+
}
|
327 |
+
return "<".$data['type'].">";
|
328 |
+
}
|
329 |
+
|
330 |
+
public function type($key)
|
331 |
+
{
|
332 |
+
return $this->extractField($key, 'type');
|
333 |
+
}
|
334 |
+
|
335 |
+
public function doc($key)
|
336 |
+
{
|
337 |
+
return $this->extractField($key, 'doc');
|
338 |
+
}
|
339 |
+
|
340 |
+
public function extractField($key, $field)
|
341 |
+
{
|
342 |
+
if(!isset($this->properties[$key][$field])) {
|
343 |
+
return null;
|
344 |
+
}
|
345 |
+
return $this->properties[$key][$field];
|
346 |
+
}
|
347 |
+
|
348 |
+
public function hasKey($fld)
|
349 |
+
{
|
350 |
+
return isset($this->properties[$fld]);
|
351 |
+
}
|
352 |
+
|
353 |
+
public function getKey($fld)
|
354 |
+
{
|
355 |
+
if($this->hasKey($fld)) {
|
356 |
+
return $this->properties[$fld];
|
357 |
+
}
|
358 |
+
return null;
|
359 |
+
}
|
360 |
+
|
361 |
+
public function rewind() {
|
362 |
+
reset($this->properties);
|
363 |
+
}
|
364 |
+
|
365 |
+
public function valid() {
|
366 |
+
return current($this->properties) !== false;
|
367 |
+
}
|
368 |
+
|
369 |
+
public function key() {
|
370 |
+
return key($this->properties);
|
371 |
+
}
|
372 |
+
|
373 |
+
public function current() {
|
374 |
+
return current($this->properties);
|
375 |
+
}
|
376 |
+
|
377 |
+
public function next() {
|
378 |
+
next($this->properties);
|
379 |
+
}
|
380 |
+
|
381 |
+
public function __get($var)
|
382 |
+
{
|
383 |
+
if (isset($this->properties[$var]['value'])) {
|
384 |
+
return $this->properties[$var]['value'];
|
385 |
+
}
|
386 |
+
return null;
|
387 |
+
}
|
388 |
+
|
389 |
+
public function __set($var, $value)
|
390 |
+
{
|
391 |
+
if (is_string($value)) {
|
392 |
+
$value = trim($value);
|
393 |
+
}
|
394 |
+
if (isset($this->properties[$var])) {
|
395 |
+
if ($value === null) {
|
396 |
+
$value = '';
|
397 |
+
}
|
398 |
+
if($this->properties[$var]['value'] !== $value) {
|
399 |
+
$this->properties[$var]['value'] = $value;
|
400 |
+
$this->store();
|
401 |
+
}
|
402 |
+
}
|
403 |
+
}
|
404 |
+
|
405 |
+
public function toArray($withRules = false)
|
406 |
+
{
|
407 |
+
$out = array();
|
408 |
+
foreach($this as $k=>$v) {
|
409 |
+
$out[$k] = $withRules ? $v : $v['value'];
|
410 |
+
}
|
411 |
+
return $out;
|
412 |
+
}
|
413 |
+
|
414 |
+
/**
|
415 |
+
* Return default config value by key
|
416 |
+
*
|
417 |
+
* @param string $key
|
418 |
+
* @return mixed
|
419 |
+
*/
|
420 |
+
public function getDefaultValue($key)
|
421 |
+
{
|
422 |
+
if (isset($this->defaultProperties[$key]['value'])) {
|
423 |
+
return $this->defaultProperties[$key]['value'];
|
424 |
+
}
|
425 |
+
return false;
|
426 |
+
}
|
427 |
+
|
428 |
+
/**
|
429 |
+
* Check is config loaded
|
430 |
+
*
|
431 |
+
* @return string
|
432 |
+
*/
|
433 |
+
public function isLoaded()
|
434 |
+
{
|
435 |
+
return $this->_configLoaded;
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* Retrieve error message
|
440 |
+
*
|
441 |
+
* @return string
|
442 |
+
*/
|
443 |
+
public function getError()
|
444 |
+
{
|
445 |
+
return $this->_configError;
|
446 |
+
}
|
447 |
+
|
448 |
+
/**
|
449 |
+
* Save config
|
450 |
+
*
|
451 |
+
* @return string
|
452 |
+
*/
|
453 |
+
public function save()
|
454 |
+
{
|
455 |
+
$forceSave = $this->_forceSave;
|
456 |
+
$this->_forceSave = true;
|
457 |
+
|
458 |
+
$result = $this->store();
|
459 |
+
|
460 |
+
$this->_forceSave = $forceSave;
|
461 |
+
|
462 |
+
return $result;
|
463 |
+
}
|
464 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
downloader/lib/Mage/Connect/Frontend.php
ADDED
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
class Mage_Connect_Frontend
|
28 |
+
{
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Silent flag. If set no output is produced to view.
|
32 |
+
* Should be used in derived classes.
|
33 |
+
* @var bool
|
34 |
+
*/
|
35 |
+
protected $_silent = false;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Capture mode. If set command output should be collected
|
39 |
+
* by derived class impplementation
|
40 |
+
* @var bool
|
41 |
+
*/
|
42 |
+
protected $_capture = false;
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* push/pop variable for capture
|
47 |
+
* @var array
|
48 |
+
*/
|
49 |
+
protected $_captureSaved = array();
|
50 |
+
|
51 |
+
/**
|
52 |
+
* push/pop variable for silent
|
53 |
+
* @var array
|
54 |
+
*/
|
55 |
+
protected $_silentSaved = array();
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Errors list
|
59 |
+
* @var array
|
60 |
+
*/
|
61 |
+
protected $_errors = array();
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Add error to errors list
|
65 |
+
* @param mixed $data
|
66 |
+
* @return void
|
67 |
+
*/
|
68 |
+
public function addError($data)
|
69 |
+
{
|
70 |
+
$this->_errors[] = $data;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Get errors, clear errors list with first param
|
75 |
+
* @param bool $clear
|
76 |
+
* @return array
|
77 |
+
*/
|
78 |
+
public function getErrors($clear = true)
|
79 |
+
{
|
80 |
+
if(!$clear) {
|
81 |
+
return $this->_errors;
|
82 |
+
}
|
83 |
+
$out = $this->_errors;
|
84 |
+
$this->clearErrors();
|
85 |
+
return $out;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Clear errors array
|
90 |
+
* @return void
|
91 |
+
*/
|
92 |
+
public function clearErrors()
|
93 |
+
{
|
94 |
+
$this->_errors = array();
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Are there any errros?
|
99 |
+
* @return bool
|
100 |
+
*/
|
101 |
+
public function hasErrors()
|
102 |
+
{
|
103 |
+
return count($this->_errors) != 0;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Error processing
|
108 |
+
* @param string $command
|
109 |
+
* @param stting $message
|
110 |
+
* @return void
|
111 |
+
*/
|
112 |
+
public function doError($command, $message)
|
113 |
+
{
|
114 |
+
$this->addError(array($command, $message));
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Save capture state
|
119 |
+
* @return Mage_Connect_Frontend
|
120 |
+
*/
|
121 |
+
public function pushCapture()
|
122 |
+
{
|
123 |
+
array_push($this->_captureSaved, $this->_capture);
|
124 |
+
return $this;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Restore capture state
|
129 |
+
* @return Mage_Connect_Frontend
|
130 |
+
*/
|
131 |
+
public function popCapture()
|
132 |
+
{
|
133 |
+
$this->_capture = array_pop($this->_captureSaved);
|
134 |
+
return $this;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Set capture mode
|
139 |
+
* @param bool $arg true by default
|
140 |
+
* @return Mage_Connect_Frontend
|
141 |
+
*/
|
142 |
+
public function setCapture($arg = true)
|
143 |
+
{
|
144 |
+
$this->_capture = $arg;
|
145 |
+
return $this;
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Getter for capture mode
|
150 |
+
* @return bool
|
151 |
+
*/
|
152 |
+
public function isCapture()
|
153 |
+
{
|
154 |
+
return $this->_capture;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Log stub
|
159 |
+
* @param $msg
|
160 |
+
* @return
|
161 |
+
*/
|
162 |
+
public function log($msg)
|
163 |
+
{
|
164 |
+
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Ouptut method
|
169 |
+
* @param array $data
|
170 |
+
* @return void
|
171 |
+
*/
|
172 |
+
public function output($data)
|
173 |
+
{
|
174 |
+
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Get instance of derived class
|
179 |
+
*
|
180 |
+
* @param $class CLI for example will produce Mage_Connect_Frontend_CLI
|
181 |
+
* @return object
|
182 |
+
*/
|
183 |
+
public static function getInstance($class)
|
184 |
+
{
|
185 |
+
$class = __CLASS__."_".$class;
|
186 |
+
return new $class();
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Get output if capture mode set
|
191 |
+
* Clear prevoius if needed
|
192 |
+
* @param bool $clearPrevious
|
193 |
+
* @return mixed
|
194 |
+
*/
|
195 |
+
public function getOutput($clearPrevious = true)
|
196 |
+
{
|
197 |
+
|
198 |
+
}
|
199 |
+
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Save silent mode
|
203 |
+
* @return Mage_Connect_Frontend
|
204 |
+
*/
|
205 |
+
public function pushSilent()
|
206 |
+
{
|
207 |
+
array_push($this->_silentSaved, $this->_silent);
|
208 |
+
return $this;
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Restore silent mode
|
213 |
+
* @return Mage_Connect_Frontend
|
214 |
+
*/
|
215 |
+
public function popSilent()
|
216 |
+
{
|
217 |
+
$this->_silent = array_pop($this->_silentSaved);
|
218 |
+
return $this;
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Set silent mode
|
223 |
+
* @param bool $value
|
224 |
+
* @return Mage_Connect_Frontend
|
225 |
+
*/
|
226 |
+
public function setSilent($value = true)
|
227 |
+
{
|
228 |
+
$this->_silent = (bool) $value;
|
229 |
+
return $this;
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Is silent mode?
|
234 |
+
* @return bool
|
235 |
+
*/
|
236 |
+
public function isSilent()
|
237 |
+
{
|
238 |
+
return (bool) $this->_silent;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Method for ask client about rewrite all files.
|
243 |
+
*
|
244 |
+
* @param $string
|
245 |
+
*/
|
246 |
+
public function confirm($string)
|
247 |
+
{
|
248 |
+
|
249 |
+
}
|
250 |
+
}
|
251 |
+
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
downloader/lib/Mage/Connect/Ftp.php
ADDED
@@ -0,0 +1,523 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
/**
|
38 |
+
* Connection object
|
39 |
+
* @var resource
|
40 |
+
*/
|
41 |
+
protected $_conn = false;
|
42 |
+
|
43 |
+
public function __construct()
|
44 |
+
{
|
45 |
+
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Check connected, throw exception if not
|
50 |
+
* @throws Exception
|
51 |
+
* @return void
|
52 |
+
*/
|
53 |
+
protected function checkConnected()
|
54 |
+
{
|
55 |
+
if(!$this->_conn) {
|
56 |
+
throw new Exception(__CLASS__." - no connection established with server");
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* ftp_mkdir wrapper
|
62 |
+
* @param stin$name
|
63 |
+
* @return unknown_type
|
64 |
+
*/
|
65 |
+
public function mdkir($name)
|
66 |
+
{
|
67 |
+
$this->checkConnected();
|
68 |
+
return @ftp_mkdir($this->_conn, $name);
|
69 |
+
}
|
70 |
+
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Make dir recursive
|
75 |
+
* @param string $path
|
76 |
+
* @param int $mode
|
77 |
+
*/
|
78 |
+
public function mkdirRecursive($path, $mode = 0777)
|
79 |
+
{
|
80 |
+
$this->checkConnected();
|
81 |
+
$dir = explode('/', $path);
|
82 |
+
$path= "";
|
83 |
+
$ret = true;
|
84 |
+
for ($i=0; $i < count($dir); $i++) {
|
85 |
+
$path .= "/" .$dir[$i];
|
86 |
+
if(!@ftp_chdir($this->_conn, $path)) {
|
87 |
+
@ftp_chdir($this->_conn,"/");
|
88 |
+
if(!@ftp_mkdir($this->_conn,$path)) {
|
89 |
+
$ret=false;
|
90 |
+
break;
|
91 |
+
} else {
|
92 |
+
@ftp_chmod($this->_conn, $mode, $path);
|
93 |
+
}
|
94 |
+
}
|
95 |
+
}
|
96 |
+
return $ret;
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Try to login to server
|
102 |
+
* @param string $login
|
103 |
+
* @param string $password
|
104 |
+
* @throws Exception on invalid login credentials
|
105 |
+
* @return bool
|
106 |
+
*/
|
107 |
+
public function login($login = "anonymous", $password = "test@gmail.com")
|
108 |
+
{
|
109 |
+
$this->checkConnected();
|
110 |
+
$res = @ftp_login($this->_conn, $login, $password);
|
111 |
+
if(!$res) {
|
112 |
+
throw new Exception("Invalid login credentials");
|
113 |
+
}
|
114 |
+
return $res;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Validate connection string
|
119 |
+
* @param string $string
|
120 |
+
* @throws Exception
|
121 |
+
* @return string
|
122 |
+
*/
|
123 |
+
public function validateConnectionString($string)
|
124 |
+
{
|
125 |
+
if (empty($string)) {
|
126 |
+
throw new Exception("Connection string is empty");
|
127 |
+
}
|
128 |
+
$data = @parse_url($string);
|
129 |
+
if(false === $data) {
|
130 |
+
throw new Exception("Connection string invalid: '{$string}'");
|
131 |
+
}
|
132 |
+
if($data['scheme'] != 'ftp') {
|
133 |
+
throw new Exception("Support for scheme '{$data['scheme']}' unsupported");
|
134 |
+
}
|
135 |
+
return $data;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Connect to server using connect string
|
140 |
+
* Connection string: ftp://user:pass@server:port/path
|
141 |
+
* user,pass,port,path are optional parts
|
142 |
+
* @param string $string
|
143 |
+
*
|
144 |
+
* @param $timeout
|
145 |
+
* @return unknown_type
|
146 |
+
*/
|
147 |
+
public function connect($string, $timeout = 90)
|
148 |
+
{
|
149 |
+
$params = $this->validateConnectionString($string);
|
150 |
+
$port = isset($params['port']) ? intval($params['port']) : 21;
|
151 |
+
|
152 |
+
$this->_conn = @ftp_connect($params['host'], $port, $timeout);
|
153 |
+
|
154 |
+
if(!$this->_conn) {
|
155 |
+
throw new Exception("Cannot connect to host: {$params['host']}");
|
156 |
+
}
|
157 |
+
ftp_pasv($this->_conn, true);
|
158 |
+
if(isset($params['user']) && isset($params['pass'])) {
|
159 |
+
$this->login($params['user'], $params['pass']);
|
160 |
+
} else {
|
161 |
+
$this->login();
|
162 |
+
}
|
163 |
+
if(isset($params['path'])) {
|
164 |
+
if(!$this->chdir($params['path'])) {
|
165 |
+
throw new Exception ("Cannot chdir after login to: {$params['path']}");
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* ftp_fput wrapper
|
172 |
+
* @param string $remoteFile
|
173 |
+
* @param resource $handle
|
174 |
+
* @param int $mode FTP_BINARY | FTP_ASCII
|
175 |
+
* @param int $startPos
|
176 |
+
* @return bool
|
177 |
+
*/
|
178 |
+
|
179 |
+
public function fput($remoteFile, $handle, $mode = FTP_BINARY, $startPos = 0)
|
180 |
+
{
|
181 |
+
$this->checkConnected();
|
182 |
+
return @ftp_fput($this->_conn, $remoteFile, $handle, $mode, $startPos);
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* ftp_put wrapper
|
187 |
+
* @param string $remoteFile
|
188 |
+
* @param string $localFile
|
189 |
+
* @param int $mode FTP_BINARY | FTP_ASCII
|
190 |
+
* @param int $startPos
|
191 |
+
* @return bool
|
192 |
+
*/
|
193 |
+
public function put($remoteFile, $localFile, $mode = FTP_BINARY, $startPos = 0)
|
194 |
+
{
|
195 |
+
$this->checkConnected();
|
196 |
+
return @ftp_put($this->_conn, $remoteFile, $localFile, $mode, $startPos);
|
197 |
+
}
|
198 |
+
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Get current working directory
|
202 |
+
* @return mixed
|
203 |
+
*/
|
204 |
+
public function getcwd()
|
205 |
+
{
|
206 |
+
$d = $this->raw("pwd");
|
207 |
+
$data = explode(" ", $d[0], 3);
|
208 |
+
if(empty($data[1])) {
|
209 |
+
return false;
|
210 |
+
}
|
211 |
+
if(intval($data[0]) != 257) {
|
212 |
+
return false;
|
213 |
+
}
|
214 |
+
$out = trim($data[1], '"');
|
215 |
+
if($out !== "/") {
|
216 |
+
$out = rtrim($out, "/");
|
217 |
+
}
|
218 |
+
return $out;
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* ftp_raw wrapper
|
223 |
+
* @param string $cmd
|
224 |
+
* @return mixed
|
225 |
+
*/
|
226 |
+
public function raw($cmd)
|
227 |
+
{
|
228 |
+
$this->checkConnected();
|
229 |
+
return @ftp_raw($this->_conn, $cmd);
|
230 |
+
}
|
231 |
+
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Upload local file to remote
|
235 |
+
*
|
236 |
+
* Can be used for relative and absoulte remote paths
|
237 |
+
* Relative: use chdir before calling this
|
238 |
+
*
|
239 |
+
* @param srting $remote
|
240 |
+
* @param string $local
|
241 |
+
* @param int $dirMode
|
242 |
+
* @param int $fileMode
|
243 |
+
* @return bool
|
244 |
+
*/
|
245 |
+
public function upload($remote, $local, $dirMode = 0777, $fileMode=0)
|
246 |
+
{
|
247 |
+
$this->checkConnected();
|
248 |
+
|
249 |
+
if(!file_exists($local)) {
|
250 |
+
throw new Exception("Local file doesn't exist: {$local}");
|
251 |
+
}
|
252 |
+
if(!is_readable($local)) {
|
253 |
+
throw new Exception("Local file is not readable: {$local}");
|
254 |
+
}
|
255 |
+
if(is_dir($local)) {
|
256 |
+
throw new Exception("Directory given instead of file: {$local}");
|
257 |
+
}
|
258 |
+
|
259 |
+
$globalPathMode = substr($remote, 0, 1) == "/";
|
260 |
+
$dirname = dirname($remote);
|
261 |
+
$cwd = $this->getcwd();
|
262 |
+
if(false === $cwd) {
|
263 |
+
throw new Exception("Server returns something awful on PWD command");
|
264 |
+
}
|
265 |
+
|
266 |
+
if(!$globalPathMode) {
|
267 |
+
$dirname = $cwd."/".$dirname;
|
268 |
+
$remote = $cwd."/".$remote;
|
269 |
+
}
|
270 |
+
$res = $this->mkdirRecursive($dirname, $dirMode);
|
271 |
+
$this->chdir($cwd);
|
272 |
+
|
273 |
+
if(!$res) {
|
274 |
+
return false;
|
275 |
+
}
|
276 |
+
$res = $this->put($remote, $local);
|
277 |
+
|
278 |
+
if(!$res) {
|
279 |
+
return false;
|
280 |
+
}
|
281 |
+
|
282 |
+
if($fileMode){
|
283 |
+
$res=$this->chmod($fileMode, $remote);
|
284 |
+
}
|
285 |
+
return (bool)$res;
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Download remote file to local machine
|
290 |
+
* @param string $remote
|
291 |
+
* @param string $local
|
292 |
+
* @param int $ftpMode FTP_BINARY|FTP_ASCII
|
293 |
+
* @return bool
|
294 |
+
*/
|
295 |
+
public function download($remote, $local, $ftpMode = FTP_BINARY)
|
296 |
+
{
|
297 |
+
$this->checkConnected();
|
298 |
+
return $this->get($local, $remote, $ftpMode);
|
299 |
+
}
|
300 |
+
|
301 |
+
|
302 |
+
/**
|
303 |
+
* ftp_pasv wrapper
|
304 |
+
* @param bool $pasv
|
305 |
+
* @return bool
|
306 |
+
*/
|
307 |
+
public function pasv($pasv)
|
308 |
+
{
|
309 |
+
$this->checkConnected();
|
310 |
+
return @ftp_pasv($this->_conn, (bool) $pasv);
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Close FTP connection
|
315 |
+
* @return void
|
316 |
+
*/
|
317 |
+
public function close()
|
318 |
+
{
|
319 |
+
if($this->_conn) {
|
320 |
+
@ftp_close($this->_conn);
|
321 |
+
}
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* ftp_chmod wrapper
|
326 |
+
* @param $mode
|
327 |
+
* @param $remoteFile
|
328 |
+
* @return bool
|
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 |
+
* @param string $dir
|
339 |
+
* @return bool
|
340 |
+
*/
|
341 |
+
public function chdir($dir)
|
342 |
+
{
|
343 |
+
$this->checkConnected();
|
344 |
+
return @ftp_chdir($this->_conn, $dir);
|
345 |
+
}
|
346 |
+
|
347 |
+
/**
|
348 |
+
* ftp_cdup wrapper
|
349 |
+
* @return bool
|
350 |
+
*/
|
351 |
+
public function cdup()
|
352 |
+
{
|
353 |
+
$this->checkConnected();
|
354 |
+
return @ftp_cdup($this->_conn);
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* ftp_get wrapper
|
359 |
+
* @param string $localFile
|
360 |
+
* @param string $remoteFile
|
361 |
+
* @param int $fileMode FTP_BINARY | FTP_ASCII
|
362 |
+
* @param int $resumeOffset
|
363 |
+
* @return bool
|
364 |
+
*/
|
365 |
+
public function get($localFile, $remoteFile, $fileMode = FTP_BINARY, $resumeOffset = 0)
|
366 |
+
{
|
367 |
+
$remoteFile = $this->correctFilePath($remoteFile);
|
368 |
+
$this->checkConnected();
|
369 |
+
return @ftp_get($this->_conn, $localFile, $remoteFile, $fileMode, $resumeOffset);
|
370 |
+
}
|
371 |
+
|
372 |
+
/**
|
373 |
+
* ftp_nlist wrapper
|
374 |
+
* @param string $dir
|
375 |
+
* @return bool
|
376 |
+
*/
|
377 |
+
public function nlist($dir = "/")
|
378 |
+
{
|
379 |
+
$this->checkConnected();
|
380 |
+
$dir = $this->correctFilePath($dir);
|
381 |
+
return @ftp_nlist($this->_conn, $dir);
|
382 |
+
}
|
383 |
+
|
384 |
+
/**
|
385 |
+
* ftp_rawlist wrapper
|
386 |
+
* @param string $dir
|
387 |
+
* @param bool $recursive
|
388 |
+
* @return mixed
|
389 |
+
*/
|
390 |
+
public function rawlist( $dir = "/", $recursive = false )
|
391 |
+
{
|
392 |
+
$this->checkConnected();
|
393 |
+
$dir = $this->correctFilePath($dir);
|
394 |
+
return @ftp_rawlist($this->_conn, $dir, $recursive);
|
395 |
+
}
|
396 |
+
|
397 |
+
|
398 |
+
/**
|
399 |
+
* Convert byte count to float KB/MB format
|
400 |
+
* @param int $bytes
|
401 |
+
* @return string
|
402 |
+
*/
|
403 |
+
public static function byteconvert($bytes)
|
404 |
+
{
|
405 |
+
$symbol = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
|
406 |
+
$exp = floor( log($bytes) / log(1024) );
|
407 |
+
return sprintf( '%.2f ' . $symbol[ $exp ], ($bytes / pow(1024, floor($exp))) );
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* Chmod string "-rwxrwxrwx" to "777" converter
|
412 |
+
* @param string $chmod
|
413 |
+
* @return string
|
414 |
+
*/
|
415 |
+
public static function chmodnum($chmod)
|
416 |
+
{
|
417 |
+
$trans = array('-' => '0', 'r' => '4', 'w' => '2', 'x' => '1');
|
418 |
+
$chmod = substr(strtr($chmod, $trans), 1);
|
419 |
+
$array = str_split($chmod, 3);
|
420 |
+
return array_sum(str_split($array[0])) . array_sum(str_split($array[1])) . array_sum(str_split($array[2]));
|
421 |
+
}
|
422 |
+
|
423 |
+
/**
|
424 |
+
* Checks file exists
|
425 |
+
*
|
426 |
+
* @param string $path
|
427 |
+
* @param bool $excludeIfIsDir
|
428 |
+
* @return bool
|
429 |
+
*/
|
430 |
+
public function fileExists($path, $excludeIfIsDir = true)
|
431 |
+
{
|
432 |
+
$path = $this->correctFilePath($path);
|
433 |
+
$globalPathMode = substr($path, 0, 1) == "/";
|
434 |
+
|
435 |
+
$file = basename($path);
|
436 |
+
$dir = $globalPathMode ? dirname($path) : $this->getcwd()."/".($path==basename($path)?'':$path);
|
437 |
+
$data = $this->ls($dir);
|
438 |
+
foreach($data as $row) {
|
439 |
+
if($file == basename($row['name'])) {
|
440 |
+
if($excludeIfIsDir && $row['dir']) {
|
441 |
+
continue;
|
442 |
+
}
|
443 |
+
return true;
|
444 |
+
}
|
445 |
+
}
|
446 |
+
return false;
|
447 |
+
}
|
448 |
+
|
449 |
+
/**
|
450 |
+
* Get directory contents in PHP array
|
451 |
+
* @param string $dir
|
452 |
+
* @param bool $recursive
|
453 |
+
* @return array
|
454 |
+
*/
|
455 |
+
public function ls($dir = "/", $recursive = false)
|
456 |
+
{
|
457 |
+
$dir= $this->correctFilePath($dir);
|
458 |
+
$rawfiles = (array) $this->rawlist($dir, $recursive);
|
459 |
+
$structure = array();
|
460 |
+
$arraypointer = &$structure;
|
461 |
+
foreach ($rawfiles as $rawfile) {
|
462 |
+
if ($rawfile[0] == '/') {
|
463 |
+
$paths = array_slice(explode('/', str_replace(':', '', $rawfile)), 1);
|
464 |
+
$arraypointer = &$structure;
|
465 |
+
foreach ($paths as $path) {
|
466 |
+
foreach ($arraypointer as $i => $file) {
|
467 |
+
if ($file['name'] == $path) {
|
468 |
+
$arraypointer = &$arraypointer[ $i ]['children'];
|
469 |
+
break;
|
470 |
+
}
|
471 |
+
}
|
472 |
+
}
|
473 |
+
} elseif(!empty($rawfile)) {
|
474 |
+
$info = preg_split("/[\s]+/", $rawfile, 9);
|
475 |
+
$arraypointer[] = array(
|
476 |
+
'name' => $info[8],
|
477 |
+
'dir' => $info[0]{0} == 'd',
|
478 |
+
'size' => (int) $info[4],
|
479 |
+
'chmod' => self::chmodnum($info[0]),
|
480 |
+
'rawdata' => $info,
|
481 |
+
'raw' => $rawfile
|
482 |
+
);
|
483 |
+
}
|
484 |
+
}
|
485 |
+
return $structure;
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Correct file path
|
490 |
+
* @param $str
|
491 |
+
* @return string
|
492 |
+
*/
|
493 |
+
public function correctFilePath($str)
|
494 |
+
{
|
495 |
+
$str = str_replace("\\", "/", $str);
|
496 |
+
$str = preg_replace("/^.\//", "", $str);
|
497 |
+
return $str;
|
498 |
+
}
|
499 |
+
|
500 |
+
/**
|
501 |
+
* Delete file
|
502 |
+
* @param string $file
|
503 |
+
* @return bool
|
504 |
+
*/
|
505 |
+
public function delete($file)
|
506 |
+
{
|
507 |
+
$this->checkConnected();
|
508 |
+
$file = $this->correctFilePath($file);
|
509 |
+
return @ftp_delete($this->_conn, $file);
|
510 |
+
}
|
511 |
+
|
512 |
+
/**
|
513 |
+
* Remove directory
|
514 |
+
* @param string $dir
|
515 |
+
* @return bool
|
516 |
+
*/
|
517 |
+
public function rmdir($dir)
|
518 |
+
{
|
519 |
+
$this->checkConnected();
|
520 |
+
$dir = $this->correctFilePath($dir);
|
521 |
+
return @ftp_rmdir($this->_conn, $dir);
|
522 |
+
}
|
523 |
+
}
|
downloader/lib/Mage/Connect/Loader.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
/**
|
38 |
+
* Factory for HTTP client
|
39 |
+
* @param string/false $protocol 'curl'/'socket' or false for auto-detect
|
40 |
+
* @return Mage_HTTP_Client/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 |
+
|
51 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
downloader/lib/Mage/Connect/Package/Extension.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
downloader/lib/Mage/Connect/Package/Maintainer.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
downloader/lib/Mage/Connect/Packager.php
ADDED
@@ -0,0 +1,909 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
35 |
+
class Mage_Connect_Packager
|
36 |
+
{
|
37 |
+
const CONFIG_FILE_NAME='downloader/connect.cfg';
|
38 |
+
const CACHE_FILE_NAME='downloader/cache.cfg';
|
39 |
+
|
40 |
+
protected $install_states = array(
|
41 |
+
'install' => 'Ready to install',
|
42 |
+
'upgrade' => 'Ready to upgrade',
|
43 |
+
'already_installed' => 'Already installed',
|
44 |
+
'wrong_version' => 'Wrong version',
|
45 |
+
);
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Constructor
|
49 |
+
* @param Mage_connect_Config $config
|
50 |
+
*/
|
51 |
+
public function __construct()
|
52 |
+
{
|
53 |
+
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
*
|
58 |
+
* @var Mage_Archive
|
59 |
+
*/
|
60 |
+
protected $_archiver = null;
|
61 |
+
protected $_http = null;
|
62 |
+
|
63 |
+
|
64 |
+
|
65 |
+
/**
|
66 |
+
*
|
67 |
+
* @return Mage_Archive
|
68 |
+
*/
|
69 |
+
public function getArchiver()
|
70 |
+
{
|
71 |
+
if(is_null($this->_archiver)) {
|
72 |
+
$this->_archiver = new Mage_Archive();
|
73 |
+
}
|
74 |
+
return $this->_archiver;
|
75 |
+
}
|
76 |
+
|
77 |
+
public function getDownloader()
|
78 |
+
{
|
79 |
+
if(is_null($this->_http)) {
|
80 |
+
$this->_http = Mage_HTTP_Client::getInstance();
|
81 |
+
}
|
82 |
+
return $this->_http;
|
83 |
+
}
|
84 |
+
|
85 |
+
|
86 |
+
public function getRemoteConf($ftpString)
|
87 |
+
{
|
88 |
+
$ftpObj = new Mage_Connect_Ftp();
|
89 |
+
$ftpObj->connect($ftpString);
|
90 |
+
$cfgFile = self::CONFIG_FILE_NAME;
|
91 |
+
$cacheFile = self::CACHE_FILE_NAME;
|
92 |
+
|
93 |
+
|
94 |
+
$wd = $ftpObj->getcwd();
|
95 |
+
|
96 |
+
$remoteConfigExists = $ftpObj->fileExists($cfgFile);
|
97 |
+
$tempConfigFile = tempnam(sys_get_temp_dir(),'conf');
|
98 |
+
if(!$remoteConfigExists) {
|
99 |
+
$remoteCfg = new Mage_Connect_Config($tempConfigFile);
|
100 |
+
$remoteCfg->store();
|
101 |
+
$ftpObj->upload($cfgFile, $tempConfigFile);
|
102 |
+
} else {
|
103 |
+
$ftpObj->get($tempConfigFile, $cfgFile);
|
104 |
+
$remoteCfg = new Mage_Connect_Config($tempConfigFile);
|
105 |
+
}
|
106 |
+
|
107 |
+
$ftpObj->chdir($wd);
|
108 |
+
|
109 |
+
$remoteCacheExists = $ftpObj->fileExists($cacheFile);
|
110 |
+
$tempCacheFile = tempnam(sys_get_temp_dir(),'cache');
|
111 |
+
|
112 |
+
if(!$remoteCacheExists) {
|
113 |
+
$remoteCache = new Mage_Connect_Singleconfig($tempCacheFile);
|
114 |
+
$remoteCache->clear();
|
115 |
+
$ftpObj->upload($cacheFile, $tempCacheFile);
|
116 |
+
} else {
|
117 |
+
$ftpObj->get($tempCacheFile, $cacheFile);
|
118 |
+
$remoteCache = new Mage_Connect_Singleconfig($tempCacheFile);
|
119 |
+
}
|
120 |
+
$ftpObj->chdir($wd);
|
121 |
+
return array($remoteCache, $remoteCfg, $ftpObj);
|
122 |
+
}
|
123 |
+
|
124 |
+
|
125 |
+
public function getRemoteCache($ftpString)
|
126 |
+
{
|
127 |
+
|
128 |
+
$ftpObj = new Mage_Connect_Ftp();
|
129 |
+
$ftpObj->connect($ftpString);
|
130 |
+
$remoteConfigExists = $ftpObj->fileExists(self::CACHE_FILE_NAME);
|
131 |
+
if(!$remoteConfigExists) {
|
132 |
+
$configFile=tempnam(sys_get_temp_dir(),'conf');
|
133 |
+
$remoteCfg = new Mage_Connect_Singleconfig($configFile);
|
134 |
+
$remoteCfg->clear();
|
135 |
+
$ftpObj->upload(self::CACHE_FILE_NAME, $configFile);
|
136 |
+
} else {
|
137 |
+
$configFile=tempnam(sys_get_temp_dir(),'conf');
|
138 |
+
$ftpObj->get($configFile, self::CACHE_FILE_NAME);
|
139 |
+
$remoteCfg = new Mage_Connect_Singleconfig($configFile);
|
140 |
+
}
|
141 |
+
return array($remoteCfg, $ftpObj);
|
142 |
+
}
|
143 |
+
|
144 |
+
|
145 |
+
public function getRemoteConfig($ftpString)
|
146 |
+
{
|
147 |
+
$ftpObj = new Mage_Connect_Ftp();
|
148 |
+
$ftpObj->connect($ftpString);
|
149 |
+
$cfgFile = self::CONFIG_FILE_NAME;
|
150 |
+
|
151 |
+
$wd = $ftpObj->getcwd();
|
152 |
+
$remoteConfigExists = $ftpObj->fileExists($cfgFile);
|
153 |
+
$tempConfigFile = tempnam(sys_get_temp_dir(),'conf_');
|
154 |
+
if(!$remoteConfigExists) {
|
155 |
+
$remoteCfg = new Mage_Connect_Config($tempConfigFile);
|
156 |
+
$remoteCfg->store();
|
157 |
+
$ftpObj->upload($cfgFile, $tempConfigFile);
|
158 |
+
} else {
|
159 |
+
$ftpObj->get($tempConfigFile, $cfgFile);
|
160 |
+
$remoteCfg = new Mage_Connect_Config($tempConfigFile);
|
161 |
+
}
|
162 |
+
$ftpObj->chdir($wd);
|
163 |
+
return array($remoteCfg, $ftpObj);
|
164 |
+
}
|
165 |
+
|
166 |
+
public function writeToRemoteCache($cache, $ftpObj)
|
167 |
+
{
|
168 |
+
$wd = $ftpObj->getcwd();
|
169 |
+
$ftpObj->upload(self::CACHE_FILE_NAME, $cache->getFilename());
|
170 |
+
@unlink($cache->getFilename());
|
171 |
+
$ftpObj->chdir($wd);
|
172 |
+
}
|
173 |
+
|
174 |
+
public function writeToRemoteConfig($cache, $ftpObj)
|
175 |
+
{
|
176 |
+
$wd = $ftpObj->getcwd();
|
177 |
+
$ftpObj->upload(self::CONFIG_FILE_NAME, $cache->getFilename());
|
178 |
+
@unlink($cache->getFilename());
|
179 |
+
$ftpObj->chdir($wd);
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Remove empty directories recursively up
|
184 |
+
* @param string $dir
|
185 |
+
* @param Mage_Connect_Ftp $ftp
|
186 |
+
*/
|
187 |
+
protected function removeEmptyDirectory($dir, $ftp = null)
|
188 |
+
{
|
189 |
+
if ($ftp) {
|
190 |
+
if (count($ftp->nlist($dir))==0) {
|
191 |
+
if ($ftp->rmdir($dir)) {
|
192 |
+
$this->removeEmptyDirectory(dirname($dir), $ftp);
|
193 |
+
}
|
194 |
+
}
|
195 |
+
} else {
|
196 |
+
if (@rmdir($dir)) {
|
197 |
+
$this->removeEmptyDirectory(dirname($dir), $ftp);
|
198 |
+
}
|
199 |
+
}
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
*
|
204 |
+
* @param $chanName
|
205 |
+
* @param $package
|
206 |
+
* @param Mage_Connect_Singleconfig $cacheObj
|
207 |
+
* @param Mage_Connect_Config $configObj
|
208 |
+
* @return unknown_type
|
209 |
+
*/
|
210 |
+
public function processUninstallPackage($chanName, $package, $cacheObj, $configObj)
|
211 |
+
{
|
212 |
+
$package = $cacheObj->getPackageObject($chanName, $package);
|
213 |
+
$contents = $package->getContents();
|
214 |
+
|
215 |
+
$targetPath = rtrim($configObj->magento_root, "\\/");
|
216 |
+
foreach($contents as $file) {
|
217 |
+
$fileName = basename($file);
|
218 |
+
$filePath = dirname($file);
|
219 |
+
$dest = $targetPath . DIRECTORY_SEPARATOR . $filePath . DIRECTORY_SEPARATOR . $fileName;
|
220 |
+
if(@file_exists($dest)) {
|
221 |
+
@unlink($dest);
|
222 |
+
$this->removeEmptyDirectory(dirname($dest));
|
223 |
+
}
|
224 |
+
}
|
225 |
+
|
226 |
+
$destDir = $targetPath . DS . Mage_Connect_Package::PACKAGE_XML_DIR;
|
227 |
+
$destFile = $package->getReleaseFilename() . '.xml';
|
228 |
+
@unlink($destDir . DS . $destFile);
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
*
|
233 |
+
* @param $chanName
|
234 |
+
* @param $package
|
235 |
+
* @param Mage_Connect_Singleconfig $cacheObj
|
236 |
+
* @param Mage_Connect_Ftp $ftp
|
237 |
+
* @return unknown_type
|
238 |
+
*/
|
239 |
+
public function processUninstallPackageFtp($chanName, $package, $cacheObj, $ftp)
|
240 |
+
{
|
241 |
+
$ftpDir = $ftp->getcwd();
|
242 |
+
$package = $cacheObj->getPackageObject($chanName, $package);
|
243 |
+
$contents = $package->getContents();
|
244 |
+
foreach($contents as $file) {
|
245 |
+
$res = $ftp->delete($file);
|
246 |
+
$this->removeEmptyDirectory(dirname($file), $ftp);
|
247 |
+
}
|
248 |
+
$remoteXml = Mage_Connect_Package::PACKAGE_XML_DIR . DS . $package->getReleaseFilename() . '.xml';
|
249 |
+
$ftp->delete($remoteXml);
|
250 |
+
$ftp->chdir($ftpDir);
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Validation of mode permissions
|
255 |
+
*
|
256 |
+
* @param int $mode
|
257 |
+
* @return int
|
258 |
+
*/
|
259 |
+
protected function validPermMode($mode)
|
260 |
+
{
|
261 |
+
$mode = intval($mode);
|
262 |
+
if ($mode < 73 || $mode > 511) {
|
263 |
+
return false;
|
264 |
+
}
|
265 |
+
return true;
|
266 |
+
}
|
267 |
+
/**
|
268 |
+
*
|
269 |
+
* Return correct global dir mode in octal representation
|
270 |
+
*
|
271 |
+
* @param Maged_Model_Config $config
|
272 |
+
* @return int
|
273 |
+
*/
|
274 |
+
protected function _getDirMode($config)
|
275 |
+
{
|
276 |
+
if ($this->validPermMode($config->global_dir_mode)) {
|
277 |
+
return $config->global_dir_mode;
|
278 |
+
} else {
|
279 |
+
return $config->getDefaultValue('global_dir_mode');
|
280 |
+
}
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Return global file mode in octal representation
|
285 |
+
*
|
286 |
+
* @param Maged_Model_Config $config
|
287 |
+
* @return int
|
288 |
+
*/
|
289 |
+
protected function _getFileMode($config)
|
290 |
+
{
|
291 |
+
if ($this->validPermMode($config->global_file_mode)) {
|
292 |
+
return $config->global_file_mode;
|
293 |
+
} else {
|
294 |
+
return $config->getDefaultValue('global_file_mode');
|
295 |
+
}
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Convert FTP path
|
300 |
+
*
|
301 |
+
* @param string $str
|
302 |
+
* @return string
|
303 |
+
*/
|
304 |
+
protected function convertFtpPath($str)
|
305 |
+
{
|
306 |
+
return str_replace("\\", "/", $str);
|
307 |
+
}
|
308 |
+
|
309 |
+
public function processInstallPackageFtp($package, $file, $configObj, $ftp)
|
310 |
+
{
|
311 |
+
$ftpDir = $ftp->getcwd();
|
312 |
+
$contents = $package->getContents();
|
313 |
+
$arc = $this->getArchiver();
|
314 |
+
$target = dirname($file).DS.$package->getReleaseFilename();
|
315 |
+
@mkdir($target, 0777, true);
|
316 |
+
$tar = $arc->unpack($file, $target);
|
317 |
+
$modeFile = $this->_getFileMode($configObj);
|
318 |
+
$modeDir = $this->_getDirMode($configObj);
|
319 |
+
foreach($contents as $file) {
|
320 |
+
$fileName = basename($file);
|
321 |
+
$filePath = $this->convertFtpPath(dirname($file));
|
322 |
+
$source = $tar.DS.$file;
|
323 |
+
if (file_exists($source) && is_file($source)) {
|
324 |
+
$args = array(ltrim($file,"/"), $source);
|
325 |
+
if($modeDir||$modeFile) {
|
326 |
+
$args[] = $modeDir;
|
327 |
+
$args[] = $modeFile;
|
328 |
+
}
|
329 |
+
call_user_func_array(array($ftp,'upload'), $args);
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
$localXml = $tar . Mage_Connect_Package_Reader::DEFAULT_NAME_PACKAGE;
|
334 |
+
if (is_file($localXml)) {
|
335 |
+
$remoteXml = Mage_Connect_Package::PACKAGE_XML_DIR . DS . $package->getReleaseFilename() . '.xml';
|
336 |
+
$ftp->upload($remoteXml, $localXml, $modeDir, $modeFile);
|
337 |
+
}
|
338 |
+
|
339 |
+
$ftp->chdir($ftpDir);
|
340 |
+
Mage_System_Dirs::rm(array("-r",$target));
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* Package installation to FS
|
345 |
+
* @param Mage_Connect_Package $package
|
346 |
+
* @param string $file
|
347 |
+
* @return void
|
348 |
+
* @throws Exception
|
349 |
+
*/
|
350 |
+
public function processInstallPackage($package, $file, $configObj)
|
351 |
+
{
|
352 |
+
$contents = $package->getContents();
|
353 |
+
$arc = $this->getArchiver();
|
354 |
+
$target = dirname($file).DS.$package->getReleaseFilename();
|
355 |
+
@mkdir($target, 0777, true);
|
356 |
+
$tar = $arc->unpack($file, $target);
|
357 |
+
$modeFile = $this->_getFileMode($configObj);
|
358 |
+
$modeDir = $this->_getDirMode($configObj);
|
359 |
+
foreach($contents as $file) {
|
360 |
+
$fileName = basename($file);
|
361 |
+
$filePath = dirname($file);
|
362 |
+
$source = $tar.DS.$file;
|
363 |
+
$targetPath = rtrim($configObj->magento_root, "\\/");
|
364 |
+
@mkdir($targetPath. DS . $filePath, $modeDir, true);
|
365 |
+
$dest = $targetPath . DS . $filePath . DS . $fileName;
|
366 |
+
if (is_file($source)) {
|
367 |
+
@copy($source, $dest);
|
368 |
+
if($modeFile) {
|
369 |
+
@chmod($dest, $modeFile);
|
370 |
+
}
|
371 |
+
} else {
|
372 |
+
@mkdir($dest, $modeDir);
|
373 |
+
}
|
374 |
+
}
|
375 |
+
|
376 |
+
$packageXml = $tar . Mage_Connect_Package_Reader::DEFAULT_NAME_PACKAGE;
|
377 |
+
if (is_file($packageXml)) {
|
378 |
+
$destDir = $targetPath . DS . Mage_Connect_Package::PACKAGE_XML_DIR;
|
379 |
+
$destFile = $package->getReleaseFilename() . '.xml';
|
380 |
+
$dest = $destDir . DS . $destFile;
|
381 |
+
|
382 |
+
@copy($packageXml, $dest);
|
383 |
+
@chmod($dest, $modeFile);
|
384 |
+
}
|
385 |
+
|
386 |
+
Mage_System_Dirs::rm(array("-r",$target));
|
387 |
+
}
|
388 |
+
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Get local modified files
|
392 |
+
* @param $chanName
|
393 |
+
* @param $package
|
394 |
+
* @param $cacheObj
|
395 |
+
* @param $configObj
|
396 |
+
* @return array
|
397 |
+
*/
|
398 |
+
public function getLocalModifiedFiles($chanName, $package, $cacheObj, $configObj)
|
399 |
+
{
|
400 |
+
$p = $cacheObj->getPackageObject($chanName, $package);
|
401 |
+
$hashContents = $p->getHashContents();
|
402 |
+
$listModified = array();
|
403 |
+
foreach ($hashContents as $file=>$hash) {
|
404 |
+
if (md5_file($configObj->magento_root . DS . $file)!==$hash) {
|
405 |
+
$listModified[] = $file;
|
406 |
+
}
|
407 |
+
}
|
408 |
+
return $listModified;
|
409 |
+
}
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Get remote modified files
|
413 |
+
*
|
414 |
+
* @param $chanName
|
415 |
+
* @param $package
|
416 |
+
* @param $cacheObj
|
417 |
+
* @param Mage_Connect_Ftp $ftp
|
418 |
+
* @return array
|
419 |
+
*/
|
420 |
+
public function getRemoteModifiedFiles($chanName, $package, $cacheObj, $ftp)
|
421 |
+
{
|
422 |
+
$p = $cacheObj->getPackageObject($chanName, $package);
|
423 |
+
$hashContents = $p->getHashContents();
|
424 |
+
$listModified = array();
|
425 |
+
foreach ($hashContents as $file=>$hash) {
|
426 |
+
$localFile = uniqid("temp_remote_");
|
427 |
+
if(!$ftp->fileExists($file)) {
|
428 |
+
continue;
|
429 |
+
}
|
430 |
+
$ftp->get($localFile, $file);
|
431 |
+
if (file_exists($localFile) && md5_file($localFile)!==$hash) {
|
432 |
+
$listModified[] = $file;
|
433 |
+
}
|
434 |
+
@unlink($localFile);
|
435 |
+
}
|
436 |
+
return $listModified;
|
437 |
+
}
|
438 |
+
|
439 |
+
|
440 |
+
/**
|
441 |
+
*
|
442 |
+
* Get upgrades list
|
443 |
+
*
|
444 |
+
* @param string/array $channels
|
445 |
+
* @param Mage_Connect_Singleconfig $cacheObject
|
446 |
+
* @param Mage_Connect_Rest $restObj optional
|
447 |
+
* @param bool $checkConflicts
|
448 |
+
* @return array
|
449 |
+
*/
|
450 |
+
public function getUpgradesList($channels, $cacheObject, $configObj, $restObj = null, $checkConflicts = false)
|
451 |
+
{
|
452 |
+
if(is_scalar($channels)) {
|
453 |
+
$channels = array($channels);
|
454 |
+
}
|
455 |
+
|
456 |
+
if(!$restObj) {
|
457 |
+
$restObj = new Mage_Connect_Rest($configObj->protocol);
|
458 |
+
}
|
459 |
+
|
460 |
+
$updates = array();
|
461 |
+
foreach($channels as $chan) {
|
462 |
+
|
463 |
+
if(!$cacheObject->isChannel($chan)) {
|
464 |
+
continue;
|
465 |
+
}
|
466 |
+
$chanName = $cacheObject->chanName($chan);
|
467 |
+
$localPackages = $cacheObject->getInstalledPackages($chanName);
|
468 |
+
$localPackages = $localPackages[$chanName];
|
469 |
+
|
470 |
+
if(!count($localPackages)) {
|
471 |
+
continue;
|
472 |
+
}
|
473 |
+
|
474 |
+
$channel = $cacheObject->getChannel($chan);
|
475 |
+
$uri = $channel[Mage_Connect_Singleconfig::K_URI];
|
476 |
+
$restObj->setChannel($uri);
|
477 |
+
$remotePackages = $restObj->getPackagesHashed();
|
478 |
+
|
479 |
+
/**
|
480 |
+
* Iterate packages of channel $chan
|
481 |
+
*/
|
482 |
+
$state = $configObj->preferred_state ? $configObj->preferred_state : "stable";
|
483 |
+
|
484 |
+
foreach($localPackages as $localName=>$localData) {
|
485 |
+
if(!isset($remotePackages[$localName])) {
|
486 |
+
continue;
|
487 |
+
}
|
488 |
+
$package = $remotePackages[$localName];
|
489 |
+
$neededToUpgrade = false;
|
490 |
+
$remoteVersion = $localVersion = trim($localData[Mage_Connect_Singleconfig::K_VER]);
|
491 |
+
foreach($package as $version => $s) {
|
492 |
+
|
493 |
+
if( $cacheObject->compareStabilities($s, $state) < 0 ) {
|
494 |
+
continue;
|
495 |
+
}
|
496 |
+
|
497 |
+
if(version_compare($version, $localVersion, ">")) {
|
498 |
+
$neededToUpgrade = true;
|
499 |
+
$remoteVersion = $version;
|
500 |
+
}
|
501 |
+
|
502 |
+
if($checkConflicts) {
|
503 |
+
$conflicts = $cacheObject->hasConflicts($chanName, $localName, $remoteVersion);
|
504 |
+
if(false !== $conflicts) {
|
505 |
+
$neededToUpgrade = false;
|
506 |
+
}
|
507 |
+
}
|
508 |
+
}
|
509 |
+
if(!$neededToUpgrade) {
|
510 |
+
continue;
|
511 |
+
}
|
512 |
+
if(!isset($updates[$chanName])) {
|
513 |
+
$updates[$chanName] = array();
|
514 |
+
}
|
515 |
+
$updates[$chanName][$localName] = array("from"=>$localVersion, "to"=>$remoteVersion);
|
516 |
+
}
|
517 |
+
}
|
518 |
+
return $updates;
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Get uninstall list
|
523 |
+
* @param string $chanName
|
524 |
+
* @param string $package
|
525 |
+
* @param Mage_Connect_Singleconfig $cache
|
526 |
+
* @param Mage_Connect_Config $config
|
527 |
+
* @param bool $withDepsRecursive
|
528 |
+
* @return array
|
529 |
+
*/
|
530 |
+
public function getUninstallList($chanName, $package, $cache, $config, $withDepsRecursive = true)
|
531 |
+
{
|
532 |
+
static $level = 0;
|
533 |
+
static $hash = array();
|
534 |
+
|
535 |
+
$chanName = $cache->chanName($chanName);
|
536 |
+
$keyOuter = $chanName . "/" . $package;
|
537 |
+
$level++;
|
538 |
+
|
539 |
+
try {
|
540 |
+
$chanName = $cache->chanName($chanName);
|
541 |
+
if(!$cache->hasPackage($chanName, $package)) {
|
542 |
+
$level--;
|
543 |
+
if($level == 0) {
|
544 |
+
$hash = array();
|
545 |
+
return array('list'=>array());
|
546 |
+
}
|
547 |
+
return;
|
548 |
+
}
|
549 |
+
$dependencies = $cache->getPackageDependencies($chanName, $package);
|
550 |
+
$data = $cache->getPackage($chanName, $package);
|
551 |
+
$version = $data['version'];
|
552 |
+
$keyOuter = $chanName . "/" . $package;
|
553 |
+
|
554 |
+
//print "Processing outer: {$keyOuter} \n";
|
555 |
+
$hash[$keyOuter] = array (
|
556 |
+
'name' => $package,
|
557 |
+
'channel' => $chanName,
|
558 |
+
'version' => $version,
|
559 |
+
'packages' => $dependencies,
|
560 |
+
);
|
561 |
+
|
562 |
+
if($withDepsRecursive) {
|
563 |
+
$flds = array('name','channel','min','max');
|
564 |
+
$fldsCount = count($flds);
|
565 |
+
foreach($dependencies as $row) {
|
566 |
+
foreach($flds as $key) {
|
567 |
+
$varName = "p".ucfirst($key);
|
568 |
+
$$varName = $row[$key];
|
569 |
+
}
|
570 |
+
$method = __FUNCTION__;
|
571 |
+
$keyInner = $pChannel . "/" . $pName;
|
572 |
+
if(!isset($hash[$keyInner])) {
|
573 |
+
$this->$method($pChannel, $pName, $cache, $config,
|
574 |
+
$withDepsRecursive, false);
|
575 |
+
}
|
576 |
+
}
|
577 |
+
}
|
578 |
+
|
579 |
+
} catch (Exception $e) {
|
580 |
+
// $this->_failed[] = array(
|
581 |
+
// 'name'=>$package,
|
582 |
+
// 'channel'=>$chanName,
|
583 |
+
// 'max'=>$versionMax,
|
584 |
+
// 'min'=>$versionMin,
|
585 |
+
// 'reason'=>$e->getMessage()
|
586 |
+
// );
|
587 |
+
}
|
588 |
+
|
589 |
+
$level--;
|
590 |
+
if(0 === $level) {
|
591 |
+
$out = $this->processDepsHash($hash);
|
592 |
+
$hash = array();
|
593 |
+
return array('list'=>$out);
|
594 |
+
}
|
595 |
+
}
|
596 |
+
|
597 |
+
/**
|
598 |
+
* Add data to package dependencies hash array
|
599 |
+
* @param array $hash Package dependencies hash array
|
600 |
+
* @param string $name Package name
|
601 |
+
* @param string $channel Package chaannel
|
602 |
+
* @param string $downloaded_version Package downloaded version
|
603 |
+
* @param string $stability Package stability
|
604 |
+
* @param string $versionMin Required package minimum version
|
605 |
+
* @param string $versionMax Required package maximum version
|
606 |
+
* @param string $install_state Package install state
|
607 |
+
* @param string $message Package install message
|
608 |
+
* @param array $dependencies Package dependencies
|
609 |
+
*/
|
610 |
+
private function addHashData(&$hash, $name, $channel, $downloaded_version = '', $stability = '', $versionMin = '',
|
611 |
+
$versionMax = '', $install_state = '', $message = '', $dependencies = '')
|
612 |
+
{
|
613 |
+
/**
|
614 |
+
* @todo When we are building dependencies tree we should base this calculations not on full key as on a
|
615 |
+
* unique value but check it by parts. First part which should be checked is EXTENSION_NAME also this
|
616 |
+
* part should be unique globally not per channel.
|
617 |
+
*/
|
618 |
+
//$key = $chanName . "/" . $package;
|
619 |
+
$key = $name;
|
620 |
+
$hash[$key] = array (
|
621 |
+
'name' => $name,
|
622 |
+
'channel' => $channel,
|
623 |
+
'downloaded_version' => $downloaded_version,
|
624 |
+
'stability' => $stability,
|
625 |
+
'min' => $versionMin,
|
626 |
+
'max' => $versionMax,
|
627 |
+
'install_state' => $install_state,
|
628 |
+
'message' => (isset($this->install_states[$install_state]) ?
|
629 |
+
$this->install_states[$install_state] : '').$message,
|
630 |
+
'packages' => $dependencies,
|
631 |
+
);
|
632 |
+
|
633 |
+
return true;
|
634 |
+
}
|
635 |
+
|
636 |
+
/**
|
637 |
+
* Get dependencies list/install order info
|
638 |
+
*
|
639 |
+
*
|
640 |
+
* @param string $chanName
|
641 |
+
* @param string $package
|
642 |
+
* @param Mage_Connect_Singleconfig $cache
|
643 |
+
* @param Mage_Connect_Config $config
|
644 |
+
* @param mixed $versionMax
|
645 |
+
* @param mixed $versionMin
|
646 |
+
* @param boolean $withDepsRecursive
|
647 |
+
* @param boolean $forceRemote
|
648 |
+
* @param Mage_Connect_Rest $rest
|
649 |
+
* @return mixed
|
650 |
+
*/
|
651 |
+
public function getDependenciesList( $chanName, $package, $cache, $config, $versionMax = false, $versionMin = false,
|
652 |
+
$withDepsRecursive = true, $forceRemote = false, $rest = null)
|
653 |
+
{
|
654 |
+
|
655 |
+
static $level = 0;
|
656 |
+
static $_depsHash = array();
|
657 |
+
static $_deps = array();
|
658 |
+
static $_failed = array();
|
659 |
+
$install_state = 'install';
|
660 |
+
$version = '';
|
661 |
+
$stability = '';
|
662 |
+
$message = '';
|
663 |
+
$dependencies = array();
|
664 |
+
|
665 |
+
$level++;
|
666 |
+
|
667 |
+
try {
|
668 |
+
$chanName = $cache->chanName($chanName);
|
669 |
+
|
670 |
+
if (!$rest){
|
671 |
+
$rest = new Mage_Connect_Rest($config->protocol);
|
672 |
+
}
|
673 |
+
$rest->setChannel($cache->chanUrl($chanName));
|
674 |
+
$releases = $rest->getReleases($package);
|
675 |
+
if (!$releases || !count($releases)) {
|
676 |
+
throw new Exception("No releases for '{$package}', skipping");
|
677 |
+
}
|
678 |
+
$state = $config->preferred_state ? $config->preferred_state : 'stable';
|
679 |
+
/**
|
680 |
+
* Check current package version first
|
681 |
+
*/
|
682 |
+
$installedPackage = $cache->getPackage($chanName, $package);
|
683 |
+
if ($installedPackage && is_array($installedPackage)) {
|
684 |
+
$installedRelease = array(array(
|
685 |
+
'v' => $installedPackage['version'],
|
686 |
+
's' => $installedPackage['stability'],
|
687 |
+
));
|
688 |
+
$version = $cache->detectVersionFromRestArray($installedRelease, $versionMin, $versionMax, $state);
|
689 |
+
}
|
690 |
+
if (!$version) {
|
691 |
+
$version = $cache->detectVersionFromRestArray($releases, $versionMin, $versionMax, $state);
|
692 |
+
}
|
693 |
+
if (!$version) {
|
694 |
+
$versionState = $cache->detectVersionFromRestArray($releases, $versionMin, $versionMax);
|
695 |
+
if ($versionState) {
|
696 |
+
$packageInfo = $rest->getPackageReleaseInfo($package, $versionState);
|
697 |
+
if (false !== $packageInfo) {
|
698 |
+
$stability = $packageInfo->getStability();
|
699 |
+
throw new Exception("Extension is '{$stability}' please check(or change) stability settings".
|
700 |
+
" on Magento Connect Manager");
|
701 |
+
}
|
702 |
+
}
|
703 |
+
throw new Exception("Version for '{$package}' was not detected");
|
704 |
+
}
|
705 |
+
$packageInfo = $rest->getPackageReleaseInfo($package, $version);
|
706 |
+
if (false === $packageInfo) {
|
707 |
+
throw new Exception("Package release '{$package}' not found on server");
|
708 |
+
}
|
709 |
+
$stability = $packageInfo->getStability();
|
710 |
+
|
711 |
+
/**
|
712 |
+
* @todo check is package already installed
|
713 |
+
*/
|
714 |
+
if ($installedPackage = $cache->isPackageInstalled($package)) {
|
715 |
+
if ($chanName == $installedPackage['channel']){
|
716 |
+
/**
|
717 |
+
* @todo check versions!!!
|
718 |
+
*/
|
719 |
+
if (version_compare($version, $installedPackage['version'], '>')) {
|
720 |
+
$install_state = 'upgrade';
|
721 |
+
} elseif (version_compare($version, $installedPackage['version'], '<')) {
|
722 |
+
$version = $installedPackage['version'];
|
723 |
+
$stability = $installedPackage['stability'];
|
724 |
+
$install_state = 'wrong_version';
|
725 |
+
} else {
|
726 |
+
$install_state = 'already_installed';
|
727 |
+
}
|
728 |
+
} else {
|
729 |
+
$install_state = 'incompatible';
|
730 |
+
}
|
731 |
+
}
|
732 |
+
|
733 |
+
$deps_tmp = $packageInfo->getDependencyPackages();
|
734 |
+
|
735 |
+
/**
|
736 |
+
* @todo Select distinct packages grouped by name
|
737 |
+
*/
|
738 |
+
$dependencies = array();
|
739 |
+
foreach ($deps_tmp as $row) {
|
740 |
+
if (isset($dependencies[$row['name']])) {
|
741 |
+
if ($installedPackageDep = $cache->isPackageInstalled($row['name'])) {
|
742 |
+
if ($installedPackageDep['channel'] == $row['channel']) {
|
743 |
+
$dependencies[$row['name']]=$row;
|
744 |
+
}
|
745 |
+
} elseif ($config->root_channel == $row['channel']) {
|
746 |
+
$dependencies[$row['name']] = $row;
|
747 |
+
}
|
748 |
+
} else {
|
749 |
+
$dependencies[$row['name']] = $row;
|
750 |
+
}
|
751 |
+
}
|
752 |
+
|
753 |
+
/**
|
754 |
+
* @todo When we are building dependencies tree we should base this calculations not on full key as on a
|
755 |
+
* unique value but check it by parts. First part which should be checked is EXTENSION_NAME also this part
|
756 |
+
* should be unique globally not per channel.
|
757 |
+
*/
|
758 |
+
// $keyOuter = $chanName . "/" . $package;
|
759 |
+
$keyOuter = $package;
|
760 |
+
|
761 |
+
$this->addHashData($_depsHash, $package, $chanName, $version, $stability, $versionMin,
|
762 |
+
$versionMax, $install_state, $message, $dependencies);
|
763 |
+
|
764 |
+
if ($withDepsRecursive && 'incompatible' != $install_state) {
|
765 |
+
$flds = array('name','channel','min','max');
|
766 |
+
$fldsCount = count($flds);
|
767 |
+
foreach($dependencies as $row) {
|
768 |
+
foreach($flds as $key) {
|
769 |
+
$varName = "p".ucfirst($key);
|
770 |
+
$$varName = $row[$key];
|
771 |
+
}
|
772 |
+
$method = __FUNCTION__;
|
773 |
+
/**
|
774 |
+
* @todo When we are building dependencies tree we should base this calculations not on full key as
|
775 |
+
* on a unique value but check it by parts. First part which should be checked is EXTENSION_NAME
|
776 |
+
* also this part should be unique globally not per channel.
|
777 |
+
*/
|
778 |
+
//$keyInner = $pChannel . "/" . $pName;
|
779 |
+
$keyInner = $pName;
|
780 |
+
if(!isset($_depsHash[$keyInner])) {
|
781 |
+
$_deps[] = $row;
|
782 |
+
$this->$method($pChannel, $pName, $cache, $config,
|
783 |
+
$pMax, $pMin, $withDepsRecursive, $forceRemote, $rest);
|
784 |
+
} else {
|
785 |
+
$downloaded = $_depsHash[$keyInner]['downloaded_version'];
|
786 |
+
$hasMin = $_depsHash[$keyInner]['min'];
|
787 |
+
$hasMax = $_depsHash[$keyInner]['max'];
|
788 |
+
if($pMin === $hasMin && $pMax === $hasMax) {
|
789 |
+
//var_dump("Equal requirements, skipping");
|
790 |
+
continue;
|
791 |
+
}
|
792 |
+
|
793 |
+
if($cache->versionInRange($downloaded, $pMin, $pMax)) {
|
794 |
+
//var_dump("Downloaded package matches new range too");
|
795 |
+
continue;
|
796 |
+
}
|
797 |
+
|
798 |
+
$names = array("pMin","pMax","hasMin","hasMax");
|
799 |
+
for($i=0, $c=count($names); $i<$c; $i++) {
|
800 |
+
if(!isset($$names[$i])) {
|
801 |
+
continue;
|
802 |
+
}
|
803 |
+
if(false !== $$names[$i]) {
|
804 |
+
continue;
|
805 |
+
}
|
806 |
+
$$names[$i] = $i % 2 == 0 ? "0" : "999999999";
|
807 |
+
}
|
808 |
+
|
809 |
+
if(!$cache->hasVersionRangeIntersect($pMin,$pMax, $hasMin, $hasMax)) {
|
810 |
+
$reason = "Detected {$pName} conflict of versions: {$hasMin}-{$hasMax} and {$pMin}-{$pMax}";
|
811 |
+
unset($_depsHash[$keyInner]);
|
812 |
+
$_failed[] = array(
|
813 |
+
'name'=>$pName,
|
814 |
+
'channel'=>$pChannel,
|
815 |
+
'max'=>$pMax,
|
816 |
+
'min'=>$pMin,
|
817 |
+
'reason'=>$reason
|
818 |
+
);
|
819 |
+
continue;
|
820 |
+
}
|
821 |
+
$newMaxIsLess = version_compare($pMax, $hasMax, "<");
|
822 |
+
$newMinIsGreater = version_compare($pMin, $hasMin, ">");
|
823 |
+
$forceMax = $newMaxIsLess ? $pMax : $hasMax;
|
824 |
+
$forceMin = $newMinIsGreater ? $pMin : $hasMin;
|
825 |
+
//var_dump("Trying to process {$pName} : max {$forceMax} - min {$forceMin}");
|
826 |
+
$this->$method($pChannel, $pName, $cache, $config,
|
827 |
+
$forceMax, $forceMin, $withDepsRecursive, $forceRemote, $rest);
|
828 |
+
}
|
829 |
+
}
|
830 |
+
}
|
831 |
+
unset($rest);
|
832 |
+
} catch (Exception $e) {
|
833 |
+
$_failed[] = array(
|
834 |
+
'name'=>$package,
|
835 |
+
'channel'=>$chanName,
|
836 |
+
'max'=>$versionMax,
|
837 |
+
'min'=>$versionMin,
|
838 |
+
'reason'=>$e->getMessage()
|
839 |
+
);
|
840 |
+
}
|
841 |
+
|
842 |
+
|
843 |
+
$level--;
|
844 |
+
if($level == 0) {
|
845 |
+
$out = $this->processDepsHash($_depsHash, false);
|
846 |
+
$deps = $_deps;
|
847 |
+
$failed = $_failed;
|
848 |
+
$_depsHash = array();
|
849 |
+
$_deps = array();
|
850 |
+
$_failed = array();
|
851 |
+
return array('deps' => $deps, 'result' => $out, 'failed'=> $failed);
|
852 |
+
}
|
853 |
+
|
854 |
+
}
|
855 |
+
|
856 |
+
|
857 |
+
/**
|
858 |
+
* Process dependencies hash
|
859 |
+
* Makes topological sorting and gives operation order list
|
860 |
+
*
|
861 |
+
* @param array $depsHash
|
862 |
+
* @param bool $sortReverse
|
863 |
+
* @return array
|
864 |
+
*/
|
865 |
+
protected function processDepsHash(&$depsHash, $sortReverse = true)
|
866 |
+
{
|
867 |
+
$nodes = array();
|
868 |
+
$graph = new Mage_Connect_Structures_Graph();
|
869 |
+
|
870 |
+
foreach($depsHash as $key=>$data) {
|
871 |
+
$packages = $data['packages'];
|
872 |
+
$node = new Mage_Connect_Structures_Node();
|
873 |
+
$nodes[$key] =& $node;
|
874 |
+
unset($data['packages']);
|
875 |
+
$node->setData($data);
|
876 |
+
$graph->addNode($node);
|
877 |
+
unset($node);
|
878 |
+
}
|
879 |
+
|
880 |
+
if(count($nodes) > 1) {
|
881 |
+
foreach($depsHash as $key=>$data) {
|
882 |
+
$packages = $data['packages'];
|
883 |
+
foreach($packages as $pdata) {
|
884 |
+
$pName = $pdata['name'];
|
885 |
+
if(isset($nodes[$key], $nodes[$pName])) {
|
886 |
+
$nodes[$key]->connectTo($nodes[$pName]);
|
887 |
+
}
|
888 |
+
}
|
889 |
+
}
|
890 |
+
}
|
891 |
+
|
892 |
+
if (!$graph->isAcyclic()) {
|
893 |
+
throw new Exception("Dependency references are cyclic");
|
894 |
+
}
|
895 |
+
|
896 |
+
$result = $graph->topologicalSort();
|
897 |
+
$sortReverse ? krsort($result) : ksort($result);
|
898 |
+
$out = array();
|
899 |
+
$total = 0;
|
900 |
+
foreach($result as $order=>$nodes) {
|
901 |
+
foreach($nodes as $n) {
|
902 |
+
$out[] = $n->getData();
|
903 |
+
}
|
904 |
+
}
|
905 |
+
unset($graph, $nodes);
|
906 |
+
return $out;
|
907 |
+
}
|
908 |
+
|
909 |
+
}
|
downloader/lib/Mage/Connect/Repository.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
downloader/lib/Mage/Connect/Repository/Abstract.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
downloader/lib/Mage/Connect/Repository/Channel.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
downloader/lib/Mage/Connect/Repository/Channel/Abstract.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
downloader/lib/Mage/Connect/Repository/Channel/Commercial.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
downloader/lib/Mage/Connect/Repository/Channel/Community.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
downloader/lib/Mage/Connect/Repository/Channel/Core.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
downloader/lib/Mage/Connect/Repository/Local.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
|
downloader/lib/Mage/Connect/Rest.php
ADDED
@@ -0,0 +1,366 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
35 |
+
class Mage_Connect_Rest
|
36 |
+
{
|
37 |
+
|
38 |
+
const CHANNELS_XML = "channels.xml";
|
39 |
+
const CHANNEL_XML = "channel.xml";
|
40 |
+
const PACKAGES_XML = "packages.xml";
|
41 |
+
const RELEASES_XML = "releases.xml";
|
42 |
+
const PACKAGE_XML = "package.xml";
|
43 |
+
const EXT = "tgz";
|
44 |
+
|
45 |
+
/**
|
46 |
+
* HTTP Loader
|
47 |
+
* @var Mage_HTTP_IClient
|
48 |
+
*/
|
49 |
+
protected $_loader = null;
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* XML parser
|
54 |
+
* @var Mage_Xml_Parser
|
55 |
+
*/
|
56 |
+
protected $_parser = null;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Channel URI
|
60 |
+
* @var string
|
61 |
+
*/
|
62 |
+
protected $_chanUri = '';
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Protocol HTTP or FTP
|
66 |
+
*
|
67 |
+
* @var string http or ftp
|
68 |
+
*/
|
69 |
+
protected $_protocol = '';
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Constructor
|
73 |
+
*/
|
74 |
+
public function __construct($protocol="http")
|
75 |
+
{
|
76 |
+
switch ($protocol) {
|
77 |
+
case 'ftp':
|
78 |
+
$this->_protocol = 'ftp';
|
79 |
+
break;
|
80 |
+
case 'http':
|
81 |
+
$this->_protocol = 'http';
|
82 |
+
break;
|
83 |
+
default:
|
84 |
+
$this->_protocol = 'http';
|
85 |
+
break;
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Set channel info
|
91 |
+
*
|
92 |
+
* @param string $uri
|
93 |
+
* @param sting $name
|
94 |
+
*/
|
95 |
+
public function setChannel($uri)
|
96 |
+
{
|
97 |
+
$this->_chanUri = $uri;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Get HTTP loader
|
102 |
+
* @return Mage_Connect_Loader
|
103 |
+
*/
|
104 |
+
public function getLoader()
|
105 |
+
{
|
106 |
+
if(is_null($this->_loader)) {
|
107 |
+
$this->_loader = Mage_Connect_Loader::getInstance($this->_protocol);
|
108 |
+
}
|
109 |
+
return $this->_loader;
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Get parser
|
115 |
+
*
|
116 |
+
* @return Mage_Xml_Parser
|
117 |
+
*/
|
118 |
+
protected function getParser()
|
119 |
+
{
|
120 |
+
if(is_null($this->_parser)) {
|
121 |
+
$this->_parser = new Mage_Xml_Parser();
|
122 |
+
}
|
123 |
+
return $this->_parser;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Load URI response
|
128 |
+
* @param string $uri
|
129 |
+
*/
|
130 |
+
protected function loadChannelUri($uriSuffix)
|
131 |
+
{
|
132 |
+
$url = $this->_chanUri."/".$uriSuffix;
|
133 |
+
//print $url."\n";
|
134 |
+
$this->getLoader()->get($url);
|
135 |
+
$statusCode = $this->getLoader()->getStatus();
|
136 |
+
if($statusCode != 200) {
|
137 |
+
return false;
|
138 |
+
}
|
139 |
+
return $this->getLoader()->getBody();
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Get channels list of URI
|
144 |
+
* @return array
|
145 |
+
*/
|
146 |
+
public function getChannelInfo()
|
147 |
+
{
|
148 |
+
$out = $this->loadChannelUri(self::CHANNEL_XML);
|
149 |
+
$statusCode = $this->getLoader()->getStatus();
|
150 |
+
if($statusCode != 200) {
|
151 |
+
throw new Exception("Invalid server response for {$this->_chanUri}");
|
152 |
+
}
|
153 |
+
$parser = $this->getParser();
|
154 |
+
$out = $parser->loadXML($out)->xmlToArray();
|
155 |
+
|
156 |
+
// TODO: add channel validator
|
157 |
+
$vo = new Mage_Connect_Channel_VO();
|
158 |
+
$vo->fromArray($out['channel']);
|
159 |
+
if(!$vo->validate()) {
|
160 |
+
throw new Exception("Invalid channel.xml file");
|
161 |
+
}
|
162 |
+
return $vo;
|
163 |
+
}
|
164 |
+
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Get packages list of channel
|
168 |
+
* @return array
|
169 |
+
*/
|
170 |
+
public function getPackages()
|
171 |
+
{
|
172 |
+
$out = $this->loadChannelUri(self::PACKAGES_XML);
|
173 |
+
$statusCode = $this->getLoader()->getStatus();
|
174 |
+
if($statusCode != 200) {
|
175 |
+
return false;
|
176 |
+
}
|
177 |
+
$parser = $this->getParser();
|
178 |
+
$out = $parser->loadXML($out)->xmlToArray();
|
179 |
+
|
180 |
+
|
181 |
+
if(!isset($out['data']['p'])) {
|
182 |
+
return array();
|
183 |
+
}
|
184 |
+
if(isset($out['data']['p'][0])) {
|
185 |
+
return $out['data']['p'];
|
186 |
+
}
|
187 |
+
if(is_array($out['data']['p'])) {
|
188 |
+
return array($out['data']['p']);
|
189 |
+
}
|
190 |
+
return array();
|
191 |
+
}
|
192 |
+
|
193 |
+
|
194 |
+
public function getPackagesHashed()
|
195 |
+
{
|
196 |
+
$out = $this->loadChannelUri(self::PACKAGES_XML);
|
197 |
+
$statusCode = $this->getLoader()->getStatus();
|
198 |
+
if($statusCode != 200) {
|
199 |
+
return false;
|
200 |
+
}
|
201 |
+
$parser = $this->getParser();
|
202 |
+
$out = $parser->loadXML($out)->xmlToArray();
|
203 |
+
|
204 |
+
$return = array();
|
205 |
+
if(!isset($out['data']['p'])) {
|
206 |
+
return $return;
|
207 |
+
}
|
208 |
+
if(isset($out['data']['p'][0])) {
|
209 |
+
$return = $out['data']['p'];
|
210 |
+
}elseif(is_array($out['data']['p'])) {
|
211 |
+
$return = array($out['data']['p']);
|
212 |
+
}
|
213 |
+
$c = count($return);
|
214 |
+
if($c) {
|
215 |
+
$output = array();
|
216 |
+
for($i=0; $i<$c; $i++) {
|
217 |
+
$element = $return[$i];
|
218 |
+
$output[$element['n']] = $element['r'];
|
219 |
+
}
|
220 |
+
$return = $output;
|
221 |
+
}
|
222 |
+
|
223 |
+
$out = array();
|
224 |
+
foreach($return as $name=>$package) {
|
225 |
+
$stabilities = array_map(array($this, 'shortStateToLong'), array_keys($package));
|
226 |
+
$versions = array_map('trim', array_values($package));
|
227 |
+
$package = array_combine($versions, $stabilities);
|
228 |
+
ksort($package);
|
229 |
+
$out[$name] = $package;
|
230 |
+
}
|
231 |
+
return $out;
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Stub
|
236 |
+
* @param $n
|
237 |
+
* @return unknown_type
|
238 |
+
*/
|
239 |
+
public function escapePackageName($n)
|
240 |
+
{
|
241 |
+
return $n;
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Get releases list of package on current channel
|
246 |
+
* @param string $package package name
|
247 |
+
*/
|
248 |
+
public function getReleases($package)
|
249 |
+
{
|
250 |
+
$out = $this->loadChannelUri($this->escapePackageName($package)."/".self::RELEASES_XML);
|
251 |
+
$statusCode = $this->getLoader()->getStatus();
|
252 |
+
if($statusCode != 200) {
|
253 |
+
return false;
|
254 |
+
}
|
255 |
+
$parser = $this->getParser();
|
256 |
+
$out = $parser->loadXML($out)->xmlToArray();
|
257 |
+
if(!isset($out['releases']['r'])) {
|
258 |
+
return array();
|
259 |
+
}
|
260 |
+
$src = $out['releases']['r'];
|
261 |
+
if(!array_key_exists(0, $src)) {
|
262 |
+
return array($src);
|
263 |
+
}
|
264 |
+
$this->sortReleases($src);
|
265 |
+
return $src;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Sort releases
|
270 |
+
* @param array $releases
|
271 |
+
* @return void
|
272 |
+
*/
|
273 |
+
public function sortReleases(array &$releases)
|
274 |
+
{
|
275 |
+
usort($releases, array($this, 'sortReleasesCallback'));
|
276 |
+
$releases = array_reverse($releases);
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Sort releases callback
|
281 |
+
* @param string $a
|
282 |
+
* @param srting $b
|
283 |
+
* @return int
|
284 |
+
*/
|
285 |
+
protected function sortReleasesCallback($a, $b)
|
286 |
+
{
|
287 |
+
return version_compare($a['v'],$b['v']);
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Get package info (package.xml)
|
292 |
+
*
|
293 |
+
* @param $package
|
294 |
+
* @return unknown_type
|
295 |
+
*/
|
296 |
+
public function getPackageInfo($package)
|
297 |
+
{
|
298 |
+
$out = $this->loadChannelUri($this->escapePackageName($package)."/".self::PACKAGE_XML);
|
299 |
+
if(false === $out) {
|
300 |
+
return false;
|
301 |
+
}
|
302 |
+
return new Mage_Connect_Package($out);
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
*
|
307 |
+
* @param $package
|
308 |
+
* @param $version
|
309 |
+
* @return Mage_Connect_Package
|
310 |
+
*/
|
311 |
+
public function getPackageReleaseInfo($package, $version)
|
312 |
+
{
|
313 |
+
$out = $this->loadChannelUri($this->escapePackageName($package)."/".$version."/".self::PACKAGE_XML);
|
314 |
+
if(false === $out) {
|
315 |
+
return false;
|
316 |
+
}
|
317 |
+
return new Mage_Connect_Package($out);
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Get package archive file of release
|
322 |
+
* @param string $package package name
|
323 |
+
* @param string $version version
|
324 |
+
*/
|
325 |
+
public function downloadPackageFileOfRelease($package, $version, $targetFile)
|
326 |
+
{
|
327 |
+
$package = $this->escapePackageName($package);
|
328 |
+
$version = $this->escapePackageName($version);
|
329 |
+
|
330 |
+
|
331 |
+
if(file_exists($targetFile)) {
|
332 |
+
$chksum = $this->loadChannelUri($package."/".$version."/checksum");
|
333 |
+
$statusCode = $this->getLoader()->getStatus();
|
334 |
+
if($statusCode == 200) {
|
335 |
+
if(md5_file($targetFile) == $chksum) {
|
336 |
+
return true;
|
337 |
+
}
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
+
|
342 |
+
$out = $this->loadChannelUri($package."/".$version."/".$package."-".$version.".".self::EXT);
|
343 |
+
|
344 |
+
$statusCode = $this->getLoader()->getStatus();
|
345 |
+
if($statusCode != 200) {
|
346 |
+
throw new Exception("Package not found: {$package} {$version}");
|
347 |
+
}
|
348 |
+
$dir = dirname($targetFile);
|
349 |
+
@mkdir($dir, 0777, true);
|
350 |
+
$result = @file_put_contents($targetFile, $out);
|
351 |
+
if(false === $result) {
|
352 |
+
throw new Exception("Cannot write to file {$targetFile}");
|
353 |
+
}
|
354 |
+
return true;
|
355 |
+
}
|
356 |
+
|
357 |
+
protected $states = array('b'=>'beta', 'd'=>'dev', 's'=>'stable', 'a'=>'alpha');
|
358 |
+
|
359 |
+
public function shortStateToLong($s)
|
360 |
+
{
|
361 |
+
return isset($this->states[$s]) ? $this->states[$s] : 'dev';
|
362 |
+
}
|
363 |
+
|
364 |
+
|
365 |
+
}
|
366 |
+
|
downloader/lib/Mage/Connect/Singleconfig.php
ADDED
@@ -0,0 +1,934 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
35 |
+
class Mage_Connect_Singleconfig
|
36 |
+
{
|
37 |
+
/**
|
38 |
+
* Default single config filename
|
39 |
+
* 'cache.cfg'
|
40 |
+
*/
|
41 |
+
const DEFAULT_SCONFIG_FILENAME = 'cache.cfg';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Cache data
|
45 |
+
* @var array
|
46 |
+
*/
|
47 |
+
protected $_data = array();
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Filename
|
51 |
+
* @var string
|
52 |
+
*/
|
53 |
+
protected $_readFilename = false;
|
54 |
+
|
55 |
+
/**
|
56 |
+
*
|
57 |
+
* @var unknown_type
|
58 |
+
*/
|
59 |
+
protected $_debug = false;
|
60 |
+
|
61 |
+
/**
|
62 |
+
*
|
63 |
+
* @var unknown_type
|
64 |
+
*/
|
65 |
+
protected $_validator;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Internal keys constants
|
69 |
+
*/
|
70 |
+
const K_CHAN = 'channels_by_name';
|
71 |
+
const K_CHAN_URI = 'channels_by_uri';
|
72 |
+
const K_CHAN_ALIAS = 'channel_aliases';
|
73 |
+
const K_PACK = 'packages';
|
74 |
+
const K_URI = 'uri';
|
75 |
+
const K_CHAN_DATA = 'channel_data';
|
76 |
+
const K_NAME = 'name';
|
77 |
+
const K_VER = 'version';
|
78 |
+
const K_STATE = 'stability';
|
79 |
+
const K_XML = 'xml';
|
80 |
+
const K_DEPS = 'deps';
|
81 |
+
const K_PACK_DEPS = 'pack_deps';
|
82 |
+
const K_CONFIG = 'config';
|
83 |
+
|
84 |
+
public function getValidUri($str)
|
85 |
+
{
|
86 |
+
$data = @parse_url($str);
|
87 |
+
if(isset($data['path'])) {
|
88 |
+
return $data['path'];
|
89 |
+
}
|
90 |
+
return false;
|
91 |
+
}
|
92 |
+
|
93 |
+
public function getFilename()
|
94 |
+
{
|
95 |
+
return $this->_readFilename;
|
96 |
+
}
|
97 |
+
|
98 |
+
public function formatUri($uri)
|
99 |
+
{
|
100 |
+
$uri = rtrim($uri, "/");
|
101 |
+
$uri = str_replace("http://", '', $uri);
|
102 |
+
$uri = str_replace("https://", '', $uri);
|
103 |
+
$uri = str_replace("ftp://", '', $uri);
|
104 |
+
return $uri;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Get data
|
109 |
+
* @return unknown_type
|
110 |
+
*/
|
111 |
+
public function getData()
|
112 |
+
{
|
113 |
+
return $this->_data;
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Constructor
|
118 |
+
* @param srting $file
|
119 |
+
* @return void
|
120 |
+
*/
|
121 |
+
public function __construct($file = self::DEFAULT_SCONFIG_FILENAME)
|
122 |
+
{
|
123 |
+
$this->setEmptyConfig();
|
124 |
+
if($file) {
|
125 |
+
$this->_readFilename = $file;
|
126 |
+
$this->load();
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Load cache from file
|
133 |
+
* @param string $file
|
134 |
+
* @return void
|
135 |
+
*/
|
136 |
+
public function load($file = false)
|
137 |
+
{
|
138 |
+
if(false === $file) {
|
139 |
+
$file = $this->_readFilename;
|
140 |
+
}
|
141 |
+
if(false === $file) {
|
142 |
+
return;
|
143 |
+
}
|
144 |
+
|
145 |
+
if(!file_exists($file)||filesize($file)==0) {
|
146 |
+
$this->save($file);
|
147 |
+
return;
|
148 |
+
}
|
149 |
+
|
150 |
+
if(!is_readable($file)) {
|
151 |
+
return $this->doError("File is not readable: '{$file}'");
|
152 |
+
}
|
153 |
+
|
154 |
+
$this->_readFilename = $file;
|
155 |
+
|
156 |
+
$data = @file_get_contents($file);
|
157 |
+
if(false === $data) {
|
158 |
+
return $this->doError("Cannot get file contents: '{$file}'");
|
159 |
+
}
|
160 |
+
|
161 |
+
if(!$this->_debug) {
|
162 |
+
$data = @gzuncompress($data);
|
163 |
+
if(false === $data) {
|
164 |
+
return $this->doError("Cannot unpack gzipped data in file contents: '{$file}'");
|
165 |
+
}
|
166 |
+
}
|
167 |
+
$data = @unserialize($data);
|
168 |
+
if(unserialize(false) === $data) {
|
169 |
+
return $this->doError("Cannot unserialize data in file contents: '{$file}'");
|
170 |
+
}
|
171 |
+
|
172 |
+
|
173 |
+
$validData = true;
|
174 |
+
foreach(array_keys($this->_data) as $k) {
|
175 |
+
if(!isset($data[$k])) {
|
176 |
+
$validData = false;
|
177 |
+
} else {
|
178 |
+
$this->_data[$k] = $data[$k];
|
179 |
+
}
|
180 |
+
}
|
181 |
+
if($validData) {
|
182 |
+
$this->_data = $data;
|
183 |
+
} else {
|
184 |
+
$this->save();
|
185 |
+
}
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Save contents
|
190 |
+
* @param string $file
|
191 |
+
* @return void
|
192 |
+
*/
|
193 |
+
public function save($file = false)
|
194 |
+
{
|
195 |
+
if(false === $file) {
|
196 |
+
$file = $this->_readFilename;
|
197 |
+
}
|
198 |
+
if(false === $file) {
|
199 |
+
return;
|
200 |
+
}
|
201 |
+
$data = @serialize($this->_data);
|
202 |
+
if(!$this->_debug) {
|
203 |
+
$data = @gzcompress($data);
|
204 |
+
}
|
205 |
+
$res=true;
|
206 |
+
if((!file_exists($file)&&is_writable(dirname($file)))||(file_exists($file)&&is_writable($file))){
|
207 |
+
$res = @file_put_contents($file, $data);
|
208 |
+
}
|
209 |
+
if(!$res) {
|
210 |
+
$this->doError("Cannot save: '{$file}'");
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Set empty config skeleton
|
216 |
+
* @return void
|
217 |
+
*/
|
218 |
+
public function setEmptyConfig()
|
219 |
+
{
|
220 |
+
$this->_data = array(
|
221 |
+
self::K_CHAN => array (),
|
222 |
+
self::K_CHAN_URI => array (),
|
223 |
+
self::K_CHAN_ALIAS => array (),
|
224 |
+
);
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Check channel, add if valid name and not exist
|
229 |
+
* @param string $chanName
|
230 |
+
* @param Mage_Connect_Config $config
|
231 |
+
* @param Mage_Connect_Rest $rest
|
232 |
+
* @return boolean
|
233 |
+
*/
|
234 |
+
public function checkChannel($chanName, $config, $rest = null)
|
235 |
+
{
|
236 |
+
if ($this->isChannel($chanName)) {
|
237 |
+
return true;
|
238 |
+
}
|
239 |
+
|
240 |
+
$uri = '';
|
241 |
+
|
242 |
+
$_validator = new Mage_Connect_Validator();
|
243 |
+
if ($this->isChannelName($chanName)) {
|
244 |
+
$uri = $this->chanUrl($chanName);
|
245 |
+
} elseif ($_validator->validateUrl($chanName)) {
|
246 |
+
$uri = $chanName;
|
247 |
+
} elseif($chanName) {
|
248 |
+
$uri = $config->protocol.'://'.$chanName;
|
249 |
+
} else {
|
250 |
+
throw new Exception("'{$chanName}' is not existant channel name / valid uri");
|
251 |
+
}
|
252 |
+
|
253 |
+
if ($uri && !$this->isChannel($uri)) {
|
254 |
+
if (!isset($rest)) {
|
255 |
+
$rest = new Mage_Connect_Rest($config->protocol);
|
256 |
+
}
|
257 |
+
$rest->setChannel($uri);
|
258 |
+
$data = $rest->getChannelInfo();
|
259 |
+
$data->uri = $uri;
|
260 |
+
$this->addChannel($data->name, $uri);
|
261 |
+
}
|
262 |
+
|
263 |
+
return $this->isChannel($uri);
|
264 |
+
}
|
265 |
+
|
266 |
+
public function isChannel($chanName)
|
267 |
+
{
|
268 |
+
if($this->isChannelName($chanName)) {
|
269 |
+
return true;
|
270 |
+
}
|
271 |
+
if($this->isChannelUri($chanName)) {
|
272 |
+
return true;
|
273 |
+
}
|
274 |
+
if($this->isChannelAlias($chanName)) {
|
275 |
+
return true;
|
276 |
+
}
|
277 |
+
return false;
|
278 |
+
}
|
279 |
+
|
280 |
+
/**
|
281 |
+
* Get channel
|
282 |
+
* @param string $chanName
|
283 |
+
* @return array
|
284 |
+
*/
|
285 |
+
public function getChannel($chanName)
|
286 |
+
{
|
287 |
+
if($this->isChannelAlias($chanName)) {
|
288 |
+
$chanName = $this->getChannelNameByAlias($chanName);
|
289 |
+
} elseif($this->isChannelUri($chanName)) {
|
290 |
+
$chanName = $this->getChannelUriRecord($chanName);
|
291 |
+
}
|
292 |
+
if($this->isChannelName($chanName)) {
|
293 |
+
return $this->_data[self::K_CHAN][$chanName];
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* Is channel name?
|
299 |
+
* @param $chanName
|
300 |
+
* @return bool
|
301 |
+
*/
|
302 |
+
public function isChannelName($chanName)
|
303 |
+
{
|
304 |
+
return isset($this->_data[self::K_CHAN][$chanName]);
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Is channel alias?
|
309 |
+
* @param string $chanName
|
310 |
+
* @return bool
|
311 |
+
*/
|
312 |
+
public function isChannelAlias($chanName)
|
313 |
+
{
|
314 |
+
return isset($this->_data[self::K_CHAN_ALIAS][$chanName]);
|
315 |
+
}
|
316 |
+
|
317 |
+
/**
|
318 |
+
* Is channel uri?
|
319 |
+
* @param $uri
|
320 |
+
* @return bool
|
321 |
+
*/
|
322 |
+
public function isChannelUri($uri)
|
323 |
+
{
|
324 |
+
$uri = $this->formatUri($uri);
|
325 |
+
return isset($this->_data[self::K_CHAN_URI][$uri]);
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Unset channel uri record
|
330 |
+
* @param string $uri
|
331 |
+
* @return void
|
332 |
+
*/
|
333 |
+
protected function unsetChannelUriRecord($uri)
|
334 |
+
{
|
335 |
+
$uri = $this->formatUri($uri);
|
336 |
+
unset($this->_data[self::K_CHAN_URI][$uri]);
|
337 |
+
}
|
338 |
+
|
339 |
+
/**
|
340 |
+
* Set channel uri record: uri maps to channel record
|
341 |
+
* @param string $chanName
|
342 |
+
* @param string $uri
|
343 |
+
* @return void
|
344 |
+
*/
|
345 |
+
protected function setChannelUriRecord($chanName, $uri)
|
346 |
+
{
|
347 |
+
$uri = $this->formatUri($uri);
|
348 |
+
$this->_data[self::K_CHAN_URI][$uri] = $chanName;
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Get channel name by uri record
|
353 |
+
* @param string $uri
|
354 |
+
* @return string
|
355 |
+
*/
|
356 |
+
protected function getChannelUriRecord($uri)
|
357 |
+
{
|
358 |
+
$uri = $this->formatUri($uri);
|
359 |
+
return $this->_data[self::K_CHAN_URI][$uri];
|
360 |
+
}
|
361 |
+
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Unset channel record
|
365 |
+
* @param string $chanName
|
366 |
+
* @return void
|
367 |
+
*/
|
368 |
+
protected function unsetChannelRecord($chanName)
|
369 |
+
{
|
370 |
+
unset($this->_data[self::K_CHAN][$chanName]);
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Get channel record
|
375 |
+
* @param string $chanName
|
376 |
+
* @return array
|
377 |
+
*/
|
378 |
+
protected function getChannelRecord($chanName)
|
379 |
+
{
|
380 |
+
return $this->_data[self::K_CHAN][$chanName];
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Set channel record
|
385 |
+
* @param string $chanName
|
386 |
+
* @param string $uri
|
387 |
+
* @param mixed $data
|
388 |
+
* @param array $packages
|
389 |
+
* @return void
|
390 |
+
*/
|
391 |
+
protected function setChannelRecord($chanName, $uri, $data, $packages = array())
|
392 |
+
{
|
393 |
+
$this->_data[self::K_CHAN][$chanName] = array(
|
394 |
+
self::K_NAME=>$chanName,
|
395 |
+
self::K_URI=>$uri,
|
396 |
+
self::K_CHAN_DATA=>$data,
|
397 |
+
self::K_PACK=>$packages
|
398 |
+
);
|
399 |
+
}
|
400 |
+
|
401 |
+
/**
|
402 |
+
* Set package record
|
403 |
+
* @param string $chanName
|
404 |
+
* @param string $packageName
|
405 |
+
* @param mixed $data
|
406 |
+
* @return void
|
407 |
+
*/
|
408 |
+
protected function setPackageRecord($chanName, $packageName, $data, $oneField = null)
|
409 |
+
{
|
410 |
+
if(null === $oneField) {
|
411 |
+
$this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName] = $data;
|
412 |
+
} else {
|
413 |
+
$this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName][$oneField] = $data;
|
414 |
+
}
|
415 |
+
}
|
416 |
+
|
417 |
+
|
418 |
+
|
419 |
+
/**
|
420 |
+
* Unset package record
|
421 |
+
* @param string $chanName
|
422 |
+
* @param string $packageName
|
423 |
+
* @return void
|
424 |
+
*/
|
425 |
+
protected function unsetPackageRecord($chanName, $packageName)
|
426 |
+
{
|
427 |
+
unset($this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName]);
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* Get package record
|
432 |
+
*
|
433 |
+
* @param string $chanName
|
434 |
+
* @param string $packageName
|
435 |
+
* @return array
|
436 |
+
*/
|
437 |
+
protected function fetchPackage($chanName, $packageName, $field = null)
|
438 |
+
{
|
439 |
+
if(null === $field) {
|
440 |
+
return $this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName];
|
441 |
+
} else {
|
442 |
+
return $this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName][$field];
|
443 |
+
}
|
444 |
+
}
|
445 |
+
|
446 |
+
/**
|
447 |
+
* Has package record
|
448 |
+
* @param string $chanName
|
449 |
+
* @param string $packageName
|
450 |
+
* @return bool
|
451 |
+
*/
|
452 |
+
protected function hasPackageRecord($chanName, $packageName)
|
453 |
+
{
|
454 |
+
return isset($this->_data[self::K_CHAN][$chanName][self::K_PACK][$packageName]);
|
455 |
+
}
|
456 |
+
|
457 |
+
/**
|
458 |
+
* Get channel name by alias
|
459 |
+
* @param string $alias
|
460 |
+
* @return array
|
461 |
+
*/
|
462 |
+
protected function getChannelNameByAlias($alias)
|
463 |
+
{
|
464 |
+
return $this->_data[self::K_CHAN_ALIAS][$alias];
|
465 |
+
}
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Set channel alias
|
469 |
+
* @param string $alias
|
470 |
+
* @param string $chanName
|
471 |
+
* @return void
|
472 |
+
*/
|
473 |
+
protected function setChannelAlias($alias, $chanName)
|
474 |
+
{
|
475 |
+
$this->_data[self::K_CHAN_ALIAS][$alias] = $chanName;
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* Unset channel alias
|
480 |
+
* @param string $alias
|
481 |
+
* @return void
|
482 |
+
*/
|
483 |
+
protected function unsetChannelAlias($alias)
|
484 |
+
{
|
485 |
+
unset($this->_data[self::K_CHAN_ALIAS][$alias]);
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Clear all aliases of channel
|
490 |
+
* @param string $chanName channel name
|
491 |
+
* @return void
|
492 |
+
*/
|
493 |
+
protected function clearAliases($chanName)
|
494 |
+
{
|
495 |
+
$keys = array_keys($this->_data[self::K_CHAN_ALIAS]);
|
496 |
+
foreach ($keys as $key) {
|
497 |
+
if($this->_data[self::K_CHAN_ALIAS][$key] == $chanName) {
|
498 |
+
unset($this->_data[self::K_CHAN_ALIAS][$key]);
|
499 |
+
}
|
500 |
+
}
|
501 |
+
}
|
502 |
+
|
503 |
+
/**
|
504 |
+
* Add channel alias
|
505 |
+
* @param string $chanName
|
506 |
+
* @param string $alias
|
507 |
+
* @return void
|
508 |
+
*/
|
509 |
+
public function addChannelAlias($chanName, $alias)
|
510 |
+
{
|
511 |
+
if($this->isChannelName($alias)) {
|
512 |
+
return $this->doError("Alias '{$alias}' is existant channel name!");
|
513 |
+
}
|
514 |
+
|
515 |
+
if(!$this->isChannelName($chanName)) {
|
516 |
+
return $this->doError("Channel '{$chanName}' doesn't exist");
|
517 |
+
}
|
518 |
+
$this->setChannelAlias($alias, $chanName);
|
519 |
+
$this->save();
|
520 |
+
}
|
521 |
+
|
522 |
+
|
523 |
+
|
524 |
+
/**
|
525 |
+
* Add channel
|
526 |
+
* @param $chanName
|
527 |
+
* @param $uri
|
528 |
+
* @param $data
|
529 |
+
* @return void
|
530 |
+
*/
|
531 |
+
public function addChannel($chanName, $uri, $data = array())
|
532 |
+
{
|
533 |
+
if($this->isChannelName($chanName)) {
|
534 |
+
return $this->doError("Channel '{$chanName}' already exist!");
|
535 |
+
}
|
536 |
+
if($this->isChannelUri($uri)) {
|
537 |
+
return $this->doError("Channel with uri= '{$uri}' already exist!");
|
538 |
+
}
|
539 |
+
if($this->isChannelAlias($chanName)) {
|
540 |
+
$this->unsetChannelAlias($chanName);
|
541 |
+
}
|
542 |
+
$uri = $this->formatUri($uri);
|
543 |
+
$this->setChannelRecord($chanName, $uri, $data);
|
544 |
+
$this->setChannelUriRecord($chanName, $uri);
|
545 |
+
$this->save();
|
546 |
+
}
|
547 |
+
|
548 |
+
|
549 |
+
|
550 |
+
/**
|
551 |
+
* Delete channel
|
552 |
+
* @param $chanName
|
553 |
+
* @return void
|
554 |
+
*/
|
555 |
+
public function deleteChannel($chanName)
|
556 |
+
{
|
557 |
+
if($this->isChannelName($chanName)) {
|
558 |
+
$record = $this->getChannelRecord($chanName);
|
559 |
+
$this->unsetChannelUriRecord($record[self::K_URI]);
|
560 |
+
$this->unsetChannelRecord($chanName);
|
561 |
+
$this->clearAliases($chanName);
|
562 |
+
} elseif($this->isChannelUri($chanName)) {
|
563 |
+
$uri = $chanName;
|
564 |
+
$chanName = $this->getChannelUriRecord($uri);
|
565 |
+
$this->unsetChannelUriRecord($uri);
|
566 |
+
$this->unsetChannelRecord($chanName);
|
567 |
+
$this->clearAliases($chanName);
|
568 |
+
} elseif($this->isChannelAlias($chanName)) {
|
569 |
+
$this->unsetChannelAlias($chanName);
|
570 |
+
} else {
|
571 |
+
return $this->doError("'{$chanName}' was not found in aliases, channel names, channel uris");
|
572 |
+
}
|
573 |
+
$this->save();
|
574 |
+
}
|
575 |
+
|
576 |
+
|
577 |
+
/**
|
578 |
+
* Converts channel name, url or alias to channel name
|
579 |
+
* throws exception if not found
|
580 |
+
* @param srting $chanName
|
581 |
+
* @return string
|
582 |
+
*/
|
583 |
+
public function chanName($chanName)
|
584 |
+
{
|
585 |
+
$channelData = $this->getChannel($chanName);
|
586 |
+
if(!$channelData) {
|
587 |
+
return $this->doError("Channel '{$chanName}' doesn't exist");
|
588 |
+
}
|
589 |
+
return $channelData[self::K_NAME];
|
590 |
+
}
|
591 |
+
|
592 |
+
public function chanUrl($chan)
|
593 |
+
{
|
594 |
+
$channelData = $this->getChannel($chan);
|
595 |
+
if(!$channelData) {
|
596 |
+
return $this->doError("Channel '{$chan}' doesn't exist");
|
597 |
+
}
|
598 |
+
return $channelData[self::K_URI];
|
599 |
+
}
|
600 |
+
|
601 |
+
|
602 |
+
/**
|
603 |
+
* Add package
|
604 |
+
* @param Mage_Connect_Package $package
|
605 |
+
* @return void
|
606 |
+
*/
|
607 |
+
public function addPackage($package)
|
608 |
+
{
|
609 |
+
$channel = $this->chanName($package->getChannel());
|
610 |
+
$name = $package->getName();
|
611 |
+
$record = array (
|
612 |
+
self::K_VER => $package->getVersion(),
|
613 |
+
self::K_STATE => $package->getStability(),
|
614 |
+
self::K_XML => $package->getPackageXml(),
|
615 |
+
self::K_NAME => $name,
|
616 |
+
self::K_DEPS => array(),
|
617 |
+
self::K_PACK_DEPS => array(),
|
618 |
+
);
|
619 |
+
$this->setPackageRecord($channel, $name, $record);
|
620 |
+
$this->setPackageDependencies($channel, $name, $package->getDependencyPackages());
|
621 |
+
$this->save();
|
622 |
+
}
|
623 |
+
|
624 |
+
|
625 |
+
|
626 |
+
|
627 |
+
/**
|
628 |
+
* Delete package
|
629 |
+
* @param string $chanName
|
630 |
+
* @param string $package
|
631 |
+
* @return void
|
632 |
+
*/
|
633 |
+
public function deletePackage($chanName, $package)
|
634 |
+
{
|
635 |
+
$chanName = $this->chanName($chanName);
|
636 |
+
$this->unsetPackageRecord($chanName, $package);
|
637 |
+
$this->save();
|
638 |
+
}
|
639 |
+
|
640 |
+
/**
|
641 |
+
* Get package
|
642 |
+
* @param sting $chanName
|
643 |
+
* @param string $package
|
644 |
+
* @return void
|
645 |
+
*/
|
646 |
+
public function getPackage($chanName, $package)
|
647 |
+
{
|
648 |
+
$chanName = $this->chanName($chanName);
|
649 |
+
if($this->hasPackageRecord($chanName, $package)) {
|
650 |
+
return $this->fetchPackage($chanName, $package);
|
651 |
+
}
|
652 |
+
return null;
|
653 |
+
}
|
654 |
+
|
655 |
+
public function getPackageObject($chanName, $package)
|
656 |
+
{
|
657 |
+
$chanName = $this->chanName($chanName);
|
658 |
+
if($this->hasPackageRecord($chanName, $package)) {
|
659 |
+
$data = $this->fetchPackage($chanName, $package);
|
660 |
+
return new Mage_Connect_Package($data[self::K_XML]);
|
661 |
+
}
|
662 |
+
throw new Exception("Cannot get package: '{$package}'");
|
663 |
+
}
|
664 |
+
|
665 |
+
|
666 |
+
public function hasPackage($chanName, $package, $versionMin = false, $versionMax = false)
|
667 |
+
{
|
668 |
+
$chanName = $this->chanName($chanName);
|
669 |
+
$data = $this->getPackage($chanName, $package);
|
670 |
+
if(null === $data) {
|
671 |
+
return false;
|
672 |
+
}
|
673 |
+
$installedVersion = $data[self::K_VER];
|
674 |
+
return $this->versionInRange($installedVersion, $versionMin, $versionMax);
|
675 |
+
}
|
676 |
+
|
677 |
+
/**
|
678 |
+
* Check whether package installed or not. Return package if it installed
|
679 |
+
*
|
680 |
+
* @param string $package package name
|
681 |
+
* @return array
|
682 |
+
*/
|
683 |
+
public function isPackageInstalled($package)
|
684 |
+
{
|
685 |
+
$channels = $this->getChannelNames();
|
686 |
+
foreach ($channels as $channel) {
|
687 |
+
if ($installedPackage = $this->getPackage($channel, $package)) {
|
688 |
+
return array_merge(array('channel'=>$channel), $installedPackage);
|
689 |
+
}
|
690 |
+
|
691 |
+
}
|
692 |
+
return false;
|
693 |
+
}
|
694 |
+
|
695 |
+
/**
|
696 |
+
* Checks whether the version in in the specified range of versionMin to versionMax
|
697 |
+
*
|
698 |
+
* @param string $version
|
699 |
+
* @param string $versionMin
|
700 |
+
* @param string $versionMax
|
701 |
+
* @return bool
|
702 |
+
*/
|
703 |
+
public function versionInRange($version, $versionMin = false, $versionMax = false)
|
704 |
+
{
|
705 |
+
if(false === $versionMin || empty($versionMin)) {
|
706 |
+
$minOk = true;
|
707 |
+
} else {
|
708 |
+
$minOk = version_compare($version, $versionMin, ">=");
|
709 |
+
}
|
710 |
+
if(false === $versionMax || empty($versionMax)) {
|
711 |
+
$maxOk = true;
|
712 |
+
} else {
|
713 |
+
$maxOk = version_compare($version, $versionMax, "<=");
|
714 |
+
}
|
715 |
+
return $minOk && $maxOk;
|
716 |
+
}
|
717 |
+
|
718 |
+
public function hasVersionRangeIntersect($min1, $max1, $min2, $max2)
|
719 |
+
{
|
720 |
+
if(version_compare($min1, $min2, ">") && version_compare($max1, $max2, ">")) {
|
721 |
+
return false;
|
722 |
+
} elseif(version_compare($min1, $min2, "<") && version_compare($max1, $max2, "<")) {
|
723 |
+
return false;
|
724 |
+
} elseif(version_compare($min1, $min2, ">=") && version_compare($max1, $max2, "<=")) {
|
725 |
+
return true;
|
726 |
+
} elseif(version_compare($min1, $min2, "<=") && version_compare($max1, $max2, ">=")) {
|
727 |
+
return true;
|
728 |
+
}
|
729 |
+
return false;
|
730 |
+
}
|
731 |
+
|
732 |
+
/**
|
733 |
+
* Clear contents to defaults and save
|
734 |
+
* @return void
|
735 |
+
*/
|
736 |
+
public function clear()
|
737 |
+
{
|
738 |
+
$this->setEmptyConfig();
|
739 |
+
$this->save();
|
740 |
+
}
|
741 |
+
|
742 |
+
/**
|
743 |
+
* Output error - throw exception
|
744 |
+
* @param $message
|
745 |
+
* @throws Exception
|
746 |
+
* @return void
|
747 |
+
*/
|
748 |
+
protected function doError($message)
|
749 |
+
{
|
750 |
+
throw new Exception($message);
|
751 |
+
}
|
752 |
+
|
753 |
+
|
754 |
+
|
755 |
+
|
756 |
+
|
757 |
+
public function compareStabilities($s1, $s2)
|
758 |
+
{
|
759 |
+
if(!$this->_validator) {
|
760 |
+
$this->_validator = new Mage_Connect_Validator();
|
761 |
+
}
|
762 |
+
return $this->_validator->compareStabilities($s1, $s2);
|
763 |
+
}
|
764 |
+
|
765 |
+
|
766 |
+
|
767 |
+
public function detectVersionFromRestArray($restData, $argVersionMin = false, $argVersionMax = false,
|
768 |
+
$preferredStability = 'devel')
|
769 |
+
{
|
770 |
+
|
771 |
+
if(!is_array($restData)) {
|
772 |
+
return false;
|
773 |
+
}
|
774 |
+
|
775 |
+
foreach($restData as $vData) {
|
776 |
+
$stability = trim($vData['s']);
|
777 |
+
$version = trim($vData['v']);
|
778 |
+
$goodStability = $this->compareStabilities($stability, $preferredStability) >= 0;
|
779 |
+
if($goodStability && $this->versionInRange($version, $argVersionMin, $argVersionMax)) {
|
780 |
+
return $version;
|
781 |
+
}
|
782 |
+
}
|
783 |
+
return false;
|
784 |
+
}
|
785 |
+
|
786 |
+
|
787 |
+
public function setPackageDependencies($chanName, $package, $data)
|
788 |
+
{
|
789 |
+
$chanName = $this->chanName($chanName);
|
790 |
+
if($this->hasPackageRecord($chanName, $package)) {
|
791 |
+
$this->setPackageRecord($chanName, $package, $data, self::K_PACK_DEPS);
|
792 |
+
$this->save();
|
793 |
+
return true;
|
794 |
+
}
|
795 |
+
return false;
|
796 |
+
}
|
797 |
+
|
798 |
+
public function getPackageDependencies($chanName, $package)
|
799 |
+
{
|
800 |
+
$chanName = $this->chanName($chanName);
|
801 |
+
if($this->hasPackageRecord($chanName, $package)) {
|
802 |
+
return $this->fetchPackage($chanName, $package, self::K_PACK_DEPS);
|
803 |
+
}
|
804 |
+
return false;
|
805 |
+
}
|
806 |
+
|
807 |
+
|
808 |
+
|
809 |
+
public function setDependencyInfo($chanName, $package, $data)
|
810 |
+
{
|
811 |
+
$chanName = $this->chanName($chanName);
|
812 |
+
if($this->hasPackageRecord($chanName, $package)) {
|
813 |
+
$this->setPackageRecord($chanName, $package, $data, self::K_DEPS);
|
814 |
+
$this->save();
|
815 |
+
return true;
|
816 |
+
}
|
817 |
+
return false;
|
818 |
+
}
|
819 |
+
|
820 |
+
public function getDependencyInfo($chanName, $package)
|
821 |
+
{
|
822 |
+
$chanName = $this->chanName($chanName);
|
823 |
+
if($this->hasPackageRecord($chanName, $package)) {
|
824 |
+
return $this->fetchPackage($chanName, $package, self::K_DEPS);
|
825 |
+
}
|
826 |
+
return false;
|
827 |
+
}
|
828 |
+
|
829 |
+
public function getChannelNames()
|
830 |
+
{
|
831 |
+
return array_keys($this->_data[self::K_CHAN]);
|
832 |
+
}
|
833 |
+
|
834 |
+
public function getPackagesData($channel = false)
|
835 |
+
{
|
836 |
+
if(false == $channel) {
|
837 |
+
return $this->_data[self::K_CHAN];
|
838 |
+
}
|
839 |
+
|
840 |
+
if(!$this->isChannel($channel)) {
|
841 |
+
return array();
|
842 |
+
}
|
843 |
+
return $this->getChannel($channel);
|
844 |
+
}
|
845 |
+
|
846 |
+
public function specifiedInDependencyList($deps, $chanName, $packageName)
|
847 |
+
{
|
848 |
+
foreach($deps as $dep) {
|
849 |
+
if($chanName == $dep['channel'] && $packageName == $dep['name']) {
|
850 |
+
return true;
|
851 |
+
}
|
852 |
+
}
|
853 |
+
return false;
|
854 |
+
}
|
855 |
+
|
856 |
+
public function requiredByOtherPackages($chanName, $packageName, $excludeList = array())
|
857 |
+
{
|
858 |
+
$out = array();
|
859 |
+
foreach($this->_data[self::K_CHAN] as $channel=>$data) {
|
860 |
+
foreach($data[self::K_PACK] as $package) {
|
861 |
+
if($this->specifiedInDependencyList($excludeList, $channel, $package['name'])) {
|
862 |
+
continue;
|
863 |
+
}
|
864 |
+
$deps = $package[self::K_PACK_DEPS];
|
865 |
+
if($this->specifiedInDependencyList($deps, $chanName, $packageName)) {
|
866 |
+
$out[] = array('channel'=>$channel, 'name' =>$package['name'], 'version'=>$package['version']);
|
867 |
+
}
|
868 |
+
}
|
869 |
+
}
|
870 |
+
return $out;
|
871 |
+
}
|
872 |
+
|
873 |
+
public function getInstalledPackages($chanName = false)
|
874 |
+
{
|
875 |
+
if(false == $chanName) {
|
876 |
+
$data = $this->getChannelNames();
|
877 |
+
} elseif($this->isChannel($chanName)) {
|
878 |
+
$tmp = $this->getChannel($chanName);
|
879 |
+
$data = array($tmp[self::K_NAME]);
|
880 |
+
}
|
881 |
+
$out = array();
|
882 |
+
foreach( $data as $chanName) {
|
883 |
+
$channel = $this->getChannel($chanName);
|
884 |
+
$out[$chanName] = array();
|
885 |
+
foreach($channel[self::K_PACK] as $package=>$data) {
|
886 |
+
$out[$chanName][$package] = array();
|
887 |
+
foreach(array(self::K_VER, self::K_STATE) as $k) {
|
888 |
+
$out[$chanName][$package][$k] = $data[$k];
|
889 |
+
}
|
890 |
+
}
|
891 |
+
}
|
892 |
+
return $out;
|
893 |
+
}
|
894 |
+
|
895 |
+
/**
|
896 |
+
* Check if package conflicts with installed packages
|
897 |
+
* Returns:
|
898 |
+
* array with conflicts
|
899 |
+
* false if no conflicts
|
900 |
+
*
|
901 |
+
* @param string $chanName
|
902 |
+
* @param string $packageName
|
903 |
+
* @param string $version
|
904 |
+
* @return array|false
|
905 |
+
*/
|
906 |
+
public function hasConflicts($chanName, $packageName, $version)
|
907 |
+
{
|
908 |
+
$conflicts = array();
|
909 |
+
foreach($this->_data[self::K_CHAN] as $channel=>$data) {
|
910 |
+
foreach($data[self::K_PACK] as $package) {
|
911 |
+
/**
|
912 |
+
* @todo When we are building dependencies tree we should base this calculations not on full key as on
|
913 |
+
* a unique value but check it by parts. First part which should be checked is EXTENSION_NAME also this
|
914 |
+
* part should be unique globally not per channel.
|
915 |
+
*/
|
916 |
+
/*if($channel != $chanName) {
|
917 |
+
continue;
|
918 |
+
}*/
|
919 |
+
$deps = $package[self::K_PACK_DEPS];
|
920 |
+
foreach($deps as $dep) {
|
921 |
+
if($dep['name'] != $packageName) {
|
922 |
+
continue;
|
923 |
+
}
|
924 |
+
|
925 |
+
if(!$this->versionInRange($version, $dep['min'], $dep['max'])) {
|
926 |
+
//var_dump($version, $dep['min'], $dep['max']);
|
927 |
+
$conflicts[] = $channel . "/". $package['name'] ." ". $package['version'];
|
928 |
+
}
|
929 |
+
}
|
930 |
+
}
|
931 |
+
}
|
932 |
+
return count($conflicts) ? $conflicts : false;
|
933 |
+
}
|
934 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
downloader/lib/Mage/Connect/Validator.php
ADDED
@@ -0,0 +1,440 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
35 |
+
class Mage_Connect_Validator
|
36 |
+
{
|
37 |
+
protected static $_stability = array(0=>'devel',1=>'alpha',2=>'beta',3=>'stable');
|
38 |
+
|
39 |
+
|
40 |
+
public static function getStabilities()
|
41 |
+
{
|
42 |
+
return self::$_stability;
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Compare stabilities. Returns:
|
49 |
+
*
|
50 |
+
* -1 if the first stability is lower than the second
|
51 |
+
* 0 if they are equal
|
52 |
+
* 1 if the second is lower.
|
53 |
+
* @param $s1
|
54 |
+
* @param $s2
|
55 |
+
* @return int
|
56 |
+
*/
|
57 |
+
public function compareStabilities($s1, $s2)
|
58 |
+
{
|
59 |
+
$list = $this->getStabilities();
|
60 |
+
$tmp = array_combine(array_values($list),array_keys($list));
|
61 |
+
|
62 |
+
if(!isset($tmp[$s1], $tmp[$s2])) {
|
63 |
+
throw new Exception("Invalid stability in compareStabilities argument");
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
// 'stable' turns to 3
|
68 |
+
// 'devel' turns to 0
|
69 |
+
$s1 = $tmp[$s1];
|
70 |
+
$s2 = $tmp[$s2];
|
71 |
+
if($s1 === $s2) {
|
72 |
+
return 0;
|
73 |
+
} elseif($s1 > $s2) {
|
74 |
+
return 1;
|
75 |
+
} elseif($s1 < $s2) {
|
76 |
+
return -1;
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Constructor
|
82 |
+
*/
|
83 |
+
public function __construct()
|
84 |
+
{
|
85 |
+
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Validate max len of string
|
90 |
+
* @param string $str
|
91 |
+
* @param int $maxLen
|
92 |
+
* @return bool
|
93 |
+
*/
|
94 |
+
public function validateMaxLen($str, $maxLen)
|
95 |
+
{
|
96 |
+
return strlen((string) $str) <= (int) $maxLen;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Validate channel name and url
|
101 |
+
*
|
102 |
+
* @param mixed $str
|
103 |
+
* @return bool
|
104 |
+
*/
|
105 |
+
public function validateChannelNameOrUri($str)
|
106 |
+
{
|
107 |
+
return ( $this->validateUrl($str) || $this->validatePackageName($str));
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Validate License url
|
112 |
+
*
|
113 |
+
* @param mixed $str
|
114 |
+
* @return boolean
|
115 |
+
*/
|
116 |
+
public function validateLicenseUrl($str)
|
117 |
+
{
|
118 |
+
if ($str) {
|
119 |
+
return ( $this->validateUrl($str) || $this->validatePackageName($str));
|
120 |
+
}
|
121 |
+
return true;
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Validate compatible data
|
126 |
+
* @param array $data
|
127 |
+
* @return bool
|
128 |
+
*/
|
129 |
+
public function validateCompatible(array $data)
|
130 |
+
{
|
131 |
+
if(!count($data)) {
|
132 |
+
/**
|
133 |
+
* Allow empty
|
134 |
+
*/
|
135 |
+
return true;
|
136 |
+
}
|
137 |
+
$count = 0;
|
138 |
+
foreach($data as $k=>$v) {
|
139 |
+
foreach(array('name','channel','min','max') as $fld) {
|
140 |
+
$$fld = trim($v[$fld]);
|
141 |
+
}
|
142 |
+
$count++;
|
143 |
+
|
144 |
+
$res = $this->validateUrl($channel) && strlen($channel);
|
145 |
+
if(!$res) {
|
146 |
+
$this->addError("Invalid or empty channel in compat. #{$count}");
|
147 |
+
}
|
148 |
+
|
149 |
+
$res = $this->validatePackageName($name) && strlen($name);
|
150 |
+
if(!$res) {
|
151 |
+
$this->addError("Invalid or empty name in compat. #{$count}");
|
152 |
+
}
|
153 |
+
$res1 = $this->validateVersion($min);
|
154 |
+
if(!$res1) {
|
155 |
+
$this->addError("Invalid or empty minVersion in compat. #{$count}");
|
156 |
+
}
|
157 |
+
$res2 = $this->validateVersion($max);
|
158 |
+
if(!$res2) {
|
159 |
+
$this->addError("Invalid or empty maxVersion in compat. #{$count}");
|
160 |
+
}
|
161 |
+
if($res1 && $res2 && $this->versionLower($max, $min)) {
|
162 |
+
$this->addError("Max version is lower than min in compat #{$count}");
|
163 |
+
}
|
164 |
+
|
165 |
+
}
|
166 |
+
return ! $this->hasErrors();
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Validate authors of package
|
171 |
+
* @param array $authors
|
172 |
+
* @return bool
|
173 |
+
*/
|
174 |
+
public function validateAuthors(array $authors)
|
175 |
+
{
|
176 |
+
if(!count($authors)) {
|
177 |
+
$this->addError('Empty authors section');
|
178 |
+
return false;
|
179 |
+
}
|
180 |
+
$count = 0;
|
181 |
+
foreach($authors as $k=>$v) {
|
182 |
+
$count++;
|
183 |
+
array_map('trim', $v);
|
184 |
+
$name = $v['name'];
|
185 |
+
$login = $v['user'];
|
186 |
+
$email = $v['email'];
|
187 |
+
$res = $this->validateMaxLen($name, 256) && strlen($name);
|
188 |
+
if(!$res) {
|
189 |
+
$this->addError("Invalid or empty name for author #{$count}");
|
190 |
+
}
|
191 |
+
$res = $this->validatePackageName($login) && strlen($login);
|
192 |
+
if(!$res) {
|
193 |
+
$this->addError("Invalid or empty login for author #{$count}");
|
194 |
+
}
|
195 |
+
$res = $this->validateEmail($email);
|
196 |
+
if(!$res) {
|
197 |
+
$this->addError("Invalid or empty email for author #{$count}");
|
198 |
+
}
|
199 |
+
}
|
200 |
+
return ! $this->hasErrors();
|
201 |
+
}
|
202 |
+
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Validator errors
|
206 |
+
* @var array
|
207 |
+
*/
|
208 |
+
private $_errors = array();
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Add error
|
212 |
+
* @param string $err
|
213 |
+
* @return
|
214 |
+
*/
|
215 |
+
private function addError($err)
|
216 |
+
{
|
217 |
+
$this->_errors[] = $err;
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Set validator errors
|
222 |
+
* @param array $err
|
223 |
+
* @return
|
224 |
+
*/
|
225 |
+
|
226 |
+
private function setErrors(array $err)
|
227 |
+
{
|
228 |
+
$this->_errors = $err;
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Clear validator errors
|
233 |
+
* @return
|
234 |
+
*/
|
235 |
+
private function clearErrors()
|
236 |
+
{
|
237 |
+
$this->_errors = array();
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Check if there are validator errors set
|
242 |
+
* @return unknown_type
|
243 |
+
*/
|
244 |
+
public function hasErrors()
|
245 |
+
{
|
246 |
+
return count($this->_errors) != 0;
|
247 |
+
}
|
248 |
+
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Get errors
|
252 |
+
* @param bool $clear if true after this call erros will be cleared
|
253 |
+
* @return array
|
254 |
+
*/
|
255 |
+
public function getErrors($clear = true)
|
256 |
+
{
|
257 |
+
$out = $this->_errors;
|
258 |
+
if($clear) {
|
259 |
+
$this->clearErrors();
|
260 |
+
}
|
261 |
+
return $out;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Validate URL
|
266 |
+
* @param string $str
|
267 |
+
* @return bool
|
268 |
+
*/
|
269 |
+
public function validateUrl($str)
|
270 |
+
{
|
271 |
+
$regex = "@([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|"
|
272 |
+
."(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)"
|
273 |
+
."[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+)(:[0-9]*)?@i";
|
274 |
+
return preg_match($regex, $str);
|
275 |
+
}
|
276 |
+
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Validates package stability
|
280 |
+
* @param string $str
|
281 |
+
* @return bool
|
282 |
+
*/
|
283 |
+
public function validateStability($str)
|
284 |
+
{
|
285 |
+
return in_array(strval($str), self::$_stability);
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Validate date format
|
290 |
+
* @param $date
|
291 |
+
* @return bool
|
292 |
+
*/
|
293 |
+
public function validateDate($date)
|
294 |
+
{
|
295 |
+
$subs = null;
|
296 |
+
$check1 = preg_match("/^([\d]{4})-([\d]{2})-([\d]{2})$/i", $date, $subs);
|
297 |
+
if(!$check1) {
|
298 |
+
return false;
|
299 |
+
}
|
300 |
+
return checkdate($subs[2], $subs[3], $subs[1]);
|
301 |
+
}
|
302 |
+
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Validate email
|
306 |
+
* @param string $email
|
307 |
+
* @return bool
|
308 |
+
*/
|
309 |
+
public function validateEmail($email)
|
310 |
+
{
|
311 |
+
return preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $email);
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* Validate package name
|
316 |
+
* @param $name
|
317 |
+
* @return bool
|
318 |
+
*/
|
319 |
+
public function validatePackageName($name)
|
320 |
+
{
|
321 |
+
return preg_match("/^[a-zA-Z0-9_]+$/i", $name);
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* Validate version number
|
326 |
+
* @param string $version
|
327 |
+
* @return bool
|
328 |
+
*/
|
329 |
+
public function validateVersion($version)
|
330 |
+
{
|
331 |
+
return preg_match("/^[\d]+\.[\d]+\.[\d]+([[:alnum:]\.\-\_]+)?$/i", $version);
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Check versions are equal
|
336 |
+
* @param string $v1
|
337 |
+
* @param string $v2
|
338 |
+
* @return bool
|
339 |
+
*/
|
340 |
+
public function versionEqual($v1, $v2)
|
341 |
+
{
|
342 |
+
return version_compare($v1, $v2, "==");
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Check version $v1 <= $v2
|
347 |
+
* @param string $v1
|
348 |
+
* @param string $v2
|
349 |
+
* @return bool
|
350 |
+
*/
|
351 |
+
public function versionLowerEqual($v1, $v2)
|
352 |
+
{
|
353 |
+
return version_compare($v1, $v2, "le");
|
354 |
+
}
|
355 |
+
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Check if version $v1 lower than $v2
|
359 |
+
* @param string $v1
|
360 |
+
* @param string $v2
|
361 |
+
* @return bool
|
362 |
+
*/
|
363 |
+
public function versionLower($v1, $v2)
|
364 |
+
{
|
365 |
+
return version_compare($v1, $v2, "<");
|
366 |
+
}
|
367 |
+
|
368 |
+
/**
|
369 |
+
* Check version $v1 >= $v2
|
370 |
+
* @param string $v1
|
371 |
+
* @param string $v2
|
372 |
+
* @return bool
|
373 |
+
*/
|
374 |
+
public function versionGreaterEqual($v1, $v2)
|
375 |
+
{
|
376 |
+
return version_compare($v1, $v2, "ge");
|
377 |
+
}
|
378 |
+
|
379 |
+
|
380 |
+
/**
|
381 |
+
* Generic regex validation
|
382 |
+
* @param string $str
|
383 |
+
* @param string $regex
|
384 |
+
* @return bool
|
385 |
+
*/
|
386 |
+
public function validateRegex($str, $regex)
|
387 |
+
{
|
388 |
+
return preg_match($regex, $str);
|
389 |
+
}
|
390 |
+
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Check if PHP extension loaded
|
394 |
+
* @param string $name Extension name
|
395 |
+
* @return bool
|
396 |
+
*/
|
397 |
+
public function validatePhpExtension($name)
|
398 |
+
{
|
399 |
+
return extension_loaded($name);
|
400 |
+
}
|
401 |
+
|
402 |
+
|
403 |
+
public function validatePHPVersion($min, $max, $ver = PHP_VERSION)
|
404 |
+
{
|
405 |
+
$minAccepted = true;
|
406 |
+
if($min) {
|
407 |
+
$minAccepted = version_compare($ver, $min, ">=");
|
408 |
+
}
|
409 |
+
$maxAccepted = true;
|
410 |
+
if($max) {
|
411 |
+
$maxAccepted = version_compare($ver, $max, "<=");
|
412 |
+
}
|
413 |
+
return (bool) $minAccepted && $maxAccepted;
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Validate contents of package
|
418 |
+
*
|
419 |
+
* @param array $contents
|
420 |
+
* @param Mage_Connect_Config $config
|
421 |
+
* @return bool
|
422 |
+
*/
|
423 |
+
public function validateContents(array $contents, $config)
|
424 |
+
{
|
425 |
+
if (!count($contents)) {
|
426 |
+
$this->addError('Empty package contents section');
|
427 |
+
return false;
|
428 |
+
}
|
429 |
+
|
430 |
+
$targetPath = rtrim($config->magento_root, "\\/");
|
431 |
+
foreach ($contents as $file) {
|
432 |
+
$dest = $targetPath . DS . $file;
|
433 |
+
if (file_exists($dest)) {
|
434 |
+
$this->addError("'{$file}' already exists");
|
435 |
+
return false;
|
436 |
+
}
|
437 |
+
}
|
438 |
+
return true;
|
439 |
+
}
|
440 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_DB
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_DB
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Exception
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
{}
|
downloader/lib/Mage/HTTP/Client.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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_HTTP
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
35 |
+
class Mage_HTTP_Client
|
36 |
+
{
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Disallow to instantiate - pvt constructor
|
40 |
+
*/
|
41 |
+
private function __construct()
|
42 |
+
{
|
43 |
+
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Factory for HTTP client
|
49 |
+
* @param string/false $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 |
+
{
|
56 |
+
$frontend = self::detectFrontend();
|
57 |
+
}
|
58 |
+
if(false === $frontend)
|
59 |
+
{
|
60 |
+
throw new Exception("Cannot find frontend automatically, set it manually");
|
61 |
+
}
|
62 |
+
|
63 |
+
$class = __CLASS__."_".str_replace(' ', DIRECTORY_SEPARATOR, ucwords(str_replace('_', ' ', $frontend)));
|
64 |
+
$obj = new $class();
|
65 |
+
return $obj;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Detects frontend type.
|
70 |
+
* Priority is given to CURL
|
71 |
+
*
|
72 |
+
* @return string/bool
|
73 |
+
*/
|
74 |
+
protected static function detectFrontend()
|
75 |
+
{
|
76 |
+
if(function_exists("curl_init")) {
|
77 |
+
return "curl";
|
78 |
+
}
|
79 |
+
if(function_exists("fsockopen")) {
|
80 |
+
return "socket";
|
81 |
+
}
|
82 |
+
return false;
|
83 |
+
}
|
84 |
+
}
|
downloader/lib/Mage/HTTP/Client/Curl.php
ADDED
@@ -0,0 +1,556 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_HTTP
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
* @param string $method
|
365 |
+
* @param string $uri
|
366 |
+
* @param array $params
|
367 |
+
* @return null
|
368 |
+
*/
|
369 |
+
protected function makeRequest($method, $uri, $params = array())
|
370 |
+
{
|
371 |
+
static $isAuthorizationRequired = 0;
|
372 |
+
$this->_ch = curl_init();
|
373 |
+
|
374 |
+
// make request via secured layer
|
375 |
+
if ($isAuthorizationRequired && strpos($uri, 'https://') !== 0) {
|
376 |
+
$uri = str_replace('http://', '', $uri);
|
377 |
+
$uri = 'https://' . $uri;
|
378 |
+
}
|
379 |
+
|
380 |
+
$this->curlOption(CURLOPT_URL, $uri);
|
381 |
+
$this->curlOption(CURLOPT_SSL_VERIFYPEER, FALSE);
|
382 |
+
$this->curlOption(CURLOPT_SSL_VERIFYHOST, 2);
|
383 |
+
|
384 |
+
// force method to POST if secured
|
385 |
+
if ($isAuthorizationRequired) {
|
386 |
+
$method = 'POST';
|
387 |
+
}
|
388 |
+
|
389 |
+
if($method == 'POST') {
|
390 |
+
$this->curlOption(CURLOPT_POST, 1);
|
391 |
+
$postFields = is_array($params) ? $params : array();
|
392 |
+
if ($isAuthorizationRequired) {
|
393 |
+
$this->curlOption(CURLOPT_COOKIEJAR, self::COOKIE_FILE);
|
394 |
+
$this->curlOption(CURLOPT_COOKIEFILE, self::COOKIE_FILE);
|
395 |
+
$postFields = array_merge($postFields, $this->_auth);
|
396 |
+
}
|
397 |
+
if (!empty($postFields)) {
|
398 |
+
$this->curlOption(CURLOPT_POSTFIELDS, $postFields);
|
399 |
+
}
|
400 |
+
} elseif($method == "GET") {
|
401 |
+
$this->curlOption(CURLOPT_HTTPGET, 1);
|
402 |
+
} else {
|
403 |
+
$this->curlOption(CURLOPT_CUSTOMREQUEST, $method);
|
404 |
+
}
|
405 |
+
|
406 |
+
if(count($this->_headers)) {
|
407 |
+
$heads = array();
|
408 |
+
foreach($this->_headers as $k=>$v) {
|
409 |
+
$heads[] = $k.': '.$v;
|
410 |
+
}
|
411 |
+
$this->curlOption(CURLOPT_HTTPHEADER, $heads);
|
412 |
+
}
|
413 |
+
|
414 |
+
if(count($this->_cookies)) {
|
415 |
+
$cookies = array();
|
416 |
+
foreach($this->_cookies as $k=>$v) {
|
417 |
+
$cookies[] = "$k=$v";
|
418 |
+
}
|
419 |
+
$this->curlOption(CURLOPT_COOKIE, implode(";", $cookies));
|
420 |
+
}
|
421 |
+
|
422 |
+
if($this->_timeout) {
|
423 |
+
$this->curlOption(CURLOPT_TIMEOUT, $this->_timeout);
|
424 |
+
}
|
425 |
+
|
426 |
+
if($this->_port != 80) {
|
427 |
+
$this->curlOption(CURLOPT_PORT, $this->_port);
|
428 |
+
}
|
429 |
+
|
430 |
+
$this->curlOption(CURLOPT_RETURNTRANSFER, 1);
|
431 |
+
$this->curlOption(CURLOPT_FOLLOWLOCATION, 1);
|
432 |
+
$this->curlOption(CURLOPT_HEADERFUNCTION, array($this,'parseHeaders'));
|
433 |
+
|
434 |
+
if(count($this->_curlUserOptions)) {
|
435 |
+
foreach($this->_curlUserOptions as $k=>$v) {
|
436 |
+
$this->curlOption($k, $v);
|
437 |
+
}
|
438 |
+
}
|
439 |
+
|
440 |
+
$this->_responseHeaders = array();
|
441 |
+
$this->_responseBody = curl_exec($this->_ch);
|
442 |
+
$err = curl_errno($this->_ch);
|
443 |
+
if($err) {
|
444 |
+
$this->doError(curl_error($this->_ch));
|
445 |
+
}
|
446 |
+
if(!$this->getStatus()) {
|
447 |
+
return $this->doError("Invalid response headers returned from server.");
|
448 |
+
}
|
449 |
+
curl_close($this->_ch);
|
450 |
+
if (403 == $this->getStatus()) {
|
451 |
+
if (!$isAuthorizationRequired) {
|
452 |
+
$isAuthorizationRequired++;
|
453 |
+
$this->makeRequest($method, $uri, $params);
|
454 |
+
$isAuthorizationRequired=0;
|
455 |
+
} else {
|
456 |
+
return $this->doError(sprintf('Access denied for %s@%s', $_SESSION['auth']['login'], $uri));
|
457 |
+
}
|
458 |
+
}
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Throw error excpetion
|
463 |
+
* @param $string
|
464 |
+
* @throws Exception
|
465 |
+
*/
|
466 |
+
public function isAuthorizationRequired()
|
467 |
+
{
|
468 |
+
if (isset($_SESSION['auth']['username']) && isset($_SESSION['auth']['password']) && !empty($_SESSION['auth']['username'])) {
|
469 |
+
return true;
|
470 |
+
}
|
471 |
+
return false;
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Throw error excpetion
|
476 |
+
* @param $string
|
477 |
+
* @throws Exception
|
478 |
+
*/
|
479 |
+
public function doError($string)
|
480 |
+
{
|
481 |
+
throw new Exception($string);
|
482 |
+
}
|
483 |
+
|
484 |
+
|
485 |
+
/**
|
486 |
+
* Parse headers - CURL callback functin
|
487 |
+
*
|
488 |
+
* @param resource $ch curl handle, not needed
|
489 |
+
* @param string $data
|
490 |
+
* @return int
|
491 |
+
*/
|
492 |
+
protected function parseHeaders($ch, $data)
|
493 |
+
{
|
494 |
+
if(preg_match('/^HTTP\/[\d\.x]+ (\d+)/', $data, $m)) {
|
495 |
+
if (isset($m[1])) {
|
496 |
+
$this->_responseStatus = (int)$m[1];
|
497 |
+
}
|
498 |
+
} else {
|
499 |
+
$name = $value = '';
|
500 |
+
$out = explode(": ", trim($data), 2);
|
501 |
+
if(count($out) == 2) {
|
502 |
+
$name = $out[0];
|
503 |
+
$value = $out[1];
|
504 |
+
}
|
505 |
+
|
506 |
+
if(strlen($name)) {
|
507 |
+
if("Set-Cookie" == $name) {
|
508 |
+
if(!isset($this->_responseHeaders[$name])) {
|
509 |
+
$this->_responseHeaders[$name] = array();
|
510 |
+
}
|
511 |
+
$this->_responseHeaders[$name][] = $value;
|
512 |
+
} else {
|
513 |
+
$this->_responseHeaders[$name] = $value;
|
514 |
+
}
|
515 |
+
}
|
516 |
+
}
|
517 |
+
|
518 |
+
return strlen($data);
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Set curl option directly
|
523 |
+
*
|
524 |
+
* @param string $name
|
525 |
+
* @param string $value
|
526 |
+
*/
|
527 |
+
protected function curlOption($name, $value)
|
528 |
+
{
|
529 |
+
curl_setopt($this->_ch, $name, $value);
|
530 |
+
}
|
531 |
+
|
532 |
+
/**
|
533 |
+
* Set curl options array directly
|
534 |
+
* @param array $array
|
535 |
+
*/
|
536 |
+
protected function curlOptions($array)
|
537 |
+
{
|
538 |
+
curl_setopt_array($this->_ch, $arr);
|
539 |
+
}
|
540 |
+
|
541 |
+
/**
|
542 |
+
* Set CURL options ovverides array *
|
543 |
+
*/
|
544 |
+
public function setOptions($arr)
|
545 |
+
{
|
546 |
+
$this->_curlUserOptions = $arr;
|
547 |
+
}
|
548 |
+
|
549 |
+
/**
|
550 |
+
* Set curl option
|
551 |
+
*/
|
552 |
+
public function setOption($name, $value)
|
553 |
+
{
|
554 |
+
$this->_curlUserOptions[$name] = $value;
|
555 |
+
}
|
556 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_HTTP
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_HTTP
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_System
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_System
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Xml
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Xml
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Connect
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
19 |
+
*
|
20 |
+
* @category design
|
21 |
+
* @package default
|
22 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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; }
|
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@magentocommerce.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.magentocommerce.com for more information.
|
19 |
+
*
|
20 |
+
* @category design
|
21 |
+
* @package default
|
22 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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%; }
|
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@magentocommerce.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.magentocommerce.com for more information.
|
19 |
+
*
|
20 |
+
* @category design
|
21 |
+
* @package default
|
22 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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; }
|
downloader/skin/images/Magento_Connect.jpg
ADDED
Binary file
|
downloader/skin/images/ajax-loader-tr.gif
ADDED
Binary file
|
downloader/skin/images/btn_bg.gif
ADDED
Binary file
|
downloader/skin/images/header_bg.gif
ADDED
Binary file
|
downloader/skin/images/logo.gif
ADDED
Binary file
|
downloader/skin/images/nav_bg.gif
ADDED
Binary file
|
downloader/skin/images/nav_separator.gif
ADDED
Binary file
|
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@magentocommerce.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.magentocommerce.com for more information.
|
19 |
+
*
|
20 |
+
* @category design
|
21 |
+
* @package default
|
22 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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; }
|
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@magentocommerce.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.magentocommerce.com for more information.
|
19 |
+
*
|
20 |
+
* @category design
|
21 |
+
* @package default
|
22 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
}
|
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@magentocommerce.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.magentocommerce.com for more information.
|
19 |
+
*
|
20 |
+
* @category design
|
21 |
+
* @package default
|
22 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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; }
|
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@magentocommerce.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.magentocommerce.com for more information.
|
19 |
+
*
|
20 |
+
* @category design
|
21 |
+
* @package default
|
22 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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;}
|
downloader/skin/install/images/error_msg_icon.gif
ADDED
Binary file
|
downloader/skin/install/images/footer_bg.gif
ADDED
Binary file
|
downloader/skin/install/images/footer_container_bg.gif
ADDED
Binary file
|
downloader/skin/install/images/footer_info_separator.gif
ADDED
Binary file
|
downloader/skin/install/images/footer_informational_bg.gif
ADDED
Binary file
|
downloader/skin/install/images/footer_left.gif
ADDED
Binary file
|
downloader/skin/install/images/footer_legality_bg.gif
ADDED
Binary file
|
downloader/skin/install/images/footer_right.gif
ADDED
Binary file
|
downloader/skin/install/images/header_bg.gif
ADDED
Binary file
|
downloader/skin/install/images/header_nav_bg.gif
ADDED
Binary file
|
downloader/skin/install/images/header_top_bg.jpg
ADDED
Binary file
|
downloader/skin/install/images/header_top_container_bg.jpg
ADDED
Binary file
|
downloader/skin/install/images/logo.gif
ADDED
Binary file
|
downloader/skin/install/images/main_bg.gif
ADDED
Binary file
|
downloader/skin/install/images/main_container_bg.gif
ADDED
Binary file
|
downloader/skin/install/images/note_msg_icon.gif
ADDED
Binary file
|
downloader/skin/install/images/success_msg_icon.gif
ADDED
Binary file
|
downloader/skin/install/images/validation_advice_bg.gif
ADDED
Binary file
|
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@magentocommerce.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.magentocommerce.com for more information.
|
19 |
+
*
|
20 |
+
* @category design
|
21 |
+
* @package default
|
22 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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; }
|
downloader/template/.htaccess
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
Order deny,allow
|
2 |
+
Deny from all
|
downloader/template/connect/iframe.phtml
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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)formObj.action = addParamToUrl(formObj.action, 'maintenance', (top.$('maintenance').checked === true ? '1' : '0'));
|
55 |
+
top.$('connect_iframe_success').style.display = 'none';
|
56 |
+
top.$('connect_iframe_failure').style.display = 'none';
|
57 |
+
top.$('connect_iframe_container').style.display = '';
|
58 |
+
top.location.href = '#connect_iframe';
|
59 |
+
return true;
|
60 |
+
}
|
61 |
+
|
62 |
+
function onSuccess()
|
63 |
+
{
|
64 |
+
var div = top.$('connect_iframe_success');
|
65 |
+
if (div) {
|
66 |
+
top.location.href = top.location.href.replace(/#.*$/, '')+'#connect_iframe_result';
|
67 |
+
div.style.display = '';
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
function onFailure()
|
72 |
+
{
|
73 |
+
var div = top.$('connect_iframe_failure');
|
74 |
+
if (div) {
|
75 |
+
top.location.href = top.location.href.replace(/#.*$/, '')+'#connect_iframe_result';
|
76 |
+
div.style.display = '';
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
function checkForUpdateClick()
|
81 |
+
{
|
82 |
+
url = addParamToUrl(location.href, 'maintenance', (top.$('maintenance').checked === true ? '1' : '0'));
|
83 |
+
url = addParamToUrl(url, 'updates', 'yes');
|
84 |
+
location.href = url;
|
85 |
+
}
|
86 |
+
|
87 |
+
function addParamToUrl(url, param, value)
|
88 |
+
{
|
89 |
+
var anchor = null, params = {};
|
90 |
+
var anchorPos = url.search(/#/);
|
91 |
+
if (anchorPos != -1) {
|
92 |
+
anchor = url.substr(anchorPos + 1);
|
93 |
+
url = url.substr(0, anchorPos);
|
94 |
+
}
|
95 |
+
getPos = url.search(/\?/);
|
96 |
+
if (getPos != -1) {
|
97 |
+
url.substr(getPos + 1).split('&').each(function(pv){
|
98 |
+
if (pv != 'loggedin') {
|
99 |
+
pv = pv.split('=');
|
100 |
+
params[pv[0]] = pv[1];
|
101 |
+
}
|
102 |
+
});
|
103 |
+
url = url.substr(0, getPos);
|
104 |
+
}
|
105 |
+
|
106 |
+
params[param] = value;
|
107 |
+
|
108 |
+
if (params) {
|
109 |
+
url += '?';
|
110 |
+
for (k in params) {
|
111 |
+
url += k + '=' + params[k] + '&';
|
112 |
+
}
|
113 |
+
url = url.substr(0, url.length - 1);
|
114 |
+
}
|
115 |
+
if (anchor) {
|
116 |
+
url = url + '#' + anchor;
|
117 |
+
}
|
118 |
+
|
119 |
+
return url;
|
120 |
+
}
|
121 |
+
</script>
|
downloader/template/connect/packages.phtml
ADDED
@@ -0,0 +1,221 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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><input type="checkbox" id="maintenance" value="1" checked="checked" />
|
34 |
+
<label for="maintenance">Put store on the maintenance mode while installing/upgrading</label>
|
35 |
+
</li>
|
36 |
+
</ul>
|
37 |
+
|
38 |
+
<div class="bar-head">
|
39 |
+
<h4>Install New Extensions</h4>
|
40 |
+
</div>
|
41 |
+
<script type="text/javascript">
|
42 |
+
<!--
|
43 |
+
function connectPrepare(form) {
|
44 |
+
new Ajax.Request(form.action, {
|
45 |
+
method:'post',
|
46 |
+
parameters: {install_package_id: form.install_package_id.value},
|
47 |
+
onCreate: function() {
|
48 |
+
$('prepare_package_result').update(
|
49 |
+
'<div class="loading-mask" id="loading_mask_loader">'+
|
50 |
+
' <p class="loader">'+
|
51 |
+
' <img src="<?php echo $this->baseUrl()?>/skin/images/ajax-loader-tr.gif" alt="Loading..."/><br/>Please wait...'+
|
52 |
+
' </p>'+
|
53 |
+
'</div>'
|
54 |
+
);
|
55 |
+
$('loading_mask_loader').style.position = 'relative';
|
56 |
+
$('loading_mask_loader').top = 0;
|
57 |
+
$('prepare_package_result').show();
|
58 |
+
},
|
59 |
+
onSuccess: function(transport) {
|
60 |
+
// @TODO: check transport.status to show errors
|
61 |
+
$('prepare_package_result').update(transport.responseText);
|
62 |
+
$('prepare_package_result').show();
|
63 |
+
},
|
64 |
+
onFailure: function() {
|
65 |
+
$('prepare_package_result').update(
|
66 |
+
'<div id="packages_failure">' +
|
67 |
+
' <ul class="msgs"> ' +
|
68 |
+
' <li>' +
|
69 |
+
' <ul class="error-msg">' +
|
70 |
+
' <li>Connection Error try again later.</li>' +
|
71 |
+
' </ul>' +
|
72 |
+
' </li>' +
|
73 |
+
' </ul>' +
|
74 |
+
'</div> '
|
75 |
+
);
|
76 |
+
}
|
77 |
+
});
|
78 |
+
return(false);
|
79 |
+
}
|
80 |
+
//-->
|
81 |
+
</script>
|
82 |
+
<form action="<?php echo $this->url('connectPreparePackagePost')?>" method="post" onsubmit="return connectPrepare(this)">
|
83 |
+
<ul class="bare-list">
|
84 |
+
<li>
|
85 |
+
<span class="step-count">1</span> Search for modules via <a href="http://connect.magentocommerce.com/" target="Magento_Connect">Magento Connect</a>.
|
86 |
+
</li>
|
87 |
+
<li>
|
88 |
+
<span class="step-count">2</span>
|
89 |
+
<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"/>
|
90 |
+
<button type="submit">Install</button>
|
91 |
+
</li>
|
92 |
+
</ul>
|
93 |
+
</form>
|
94 |
+
|
95 |
+
<br/>
|
96 |
+
|
97 |
+
<div class="connect-packages" id="prepare_package_result" style="display:none;"></div>
|
98 |
+
<br/>
|
99 |
+
|
100 |
+
<div class="bar-head">
|
101 |
+
<h4>Direct package file upload</h4>
|
102 |
+
</div>
|
103 |
+
<form action="<?php echo $this->url('connectInstallPackageUpload')?>" method="post" target="connect_iframe" onsubmit="onSubmit(this)" enctype="multipart/form-data">
|
104 |
+
<ul class="bare-list">
|
105 |
+
<li><span class="step-count">1</span> Download or build package file.</li>
|
106 |
+
<li>
|
107 |
+
<span class="step-count">2</span> Upload package file:
|
108 |
+
<label for="file"></label>
|
109 |
+
<input type="file" id="file" name="file"/>
|
110 |
+
<button type="submit">Upload</button>
|
111 |
+
</li>
|
112 |
+
</ul>
|
113 |
+
</form>
|
114 |
+
|
115 |
+
<br/><br/>
|
116 |
+
<div class="bar-head">
|
117 |
+
<h4>Manage Existing Extensions</h4>
|
118 |
+
<?php if (empty($_GET['updates'])): ?>
|
119 |
+
<span class="bar-head-btn f-right"><button type="button" class="f-right" onclick="checkForUpdateClick()">Check for Upgrades</button></span>
|
120 |
+
<?php endif; ?>
|
121 |
+
</div>
|
122 |
+
<?php $packages = $this->get('connect')->getAllInstalledPackages(); $i = 0; $cnt = count($packages); ?>
|
123 |
+
<?php $channelConfig=$this->get('channel_config');?>
|
124 |
+
<script type="text/javascript">
|
125 |
+
function formSubmit(id)
|
126 |
+
{
|
127 |
+
var formObj = $(id);
|
128 |
+
if (onSubmit(formObj)) {
|
129 |
+
formObj.submit();
|
130 |
+
}
|
131 |
+
}
|
132 |
+
</script>
|
133 |
+
<?php foreach ($packages as $channel=>$pkgs): ?>
|
134 |
+
|
135 |
+
<form id="connect_packages_<?php echo $i ?>" class="connect-packages" action="<?php echo $this->url('connectPackagesPost')?>" method="post" target="connect_iframe">
|
136 |
+
<div class="no-display">
|
137 |
+
<input type="hidden" id="ignore_local_modification" name="ignore_local_modification" value=""/>
|
138 |
+
<input type="hidden" name="form_id" value="connect_packages_<?php echo $i ?>"/>
|
139 |
+
</div>
|
140 |
+
<p class="nm"><button type="button" onclick="formSubmit('connect_packages_<?php echo $i ?>')" class="f-right">Commit Changes</button></p>
|
141 |
+
<h2 class="page-head">Channel: <?php echo $channelConfig->getChannelLabel($channel); ?></h2>
|
142 |
+
<p class="f-right"><label for="clean_sessions">Clear all sessions after successfull install or upgrade: <input type="checkbox" id="clean_sessions"/></label></p>
|
143 |
+
<div class="clear"></div>
|
144 |
+
|
145 |
+
<table cellspacing="0" cellpadding="0" width="100%">
|
146 |
+
<?php if (!empty($_GET['updates'])): ?>
|
147 |
+
<col width="190" />
|
148 |
+
<col width="60" />
|
149 |
+
<col width="60" />
|
150 |
+
<col width="160" />
|
151 |
+
<col width="170" />
|
152 |
+
<?php else: ?>
|
153 |
+
<col width="200" />
|
154 |
+
<col width="100" />
|
155 |
+
<col width="70" />
|
156 |
+
<col width="180" />
|
157 |
+
<?php endif; ?>
|
158 |
+
<thead>
|
159 |
+
<tr>
|
160 |
+
<th class="first">Package Name</th>
|
161 |
+
<th class="a-center">Installed</th>
|
162 |
+
<?php if (!empty($_GET['updates'])): ?><th class="a-center">Available</th><?php endif; ?>
|
163 |
+
<th>Actions</th>
|
164 |
+
<th class="last">Summary</th>
|
165 |
+
</tr>
|
166 |
+
</thead>
|
167 |
+
<tbody>
|
168 |
+
<?php foreach ($pkgs as $pkgName=>$pkg): ?>
|
169 |
+
<tr class="<?php echo $pkg['status']?>">
|
170 |
+
<td class="first"><?php echo $pkgName?></td>
|
171 |
+
<td class="a-center"><?php echo $pkg['version'].' ('.$pkg['stability'].')'?> </td>
|
172 |
+
<?php if (!empty($_GET['updates'])): ?><td class="a-center"><?php echo $pkg['upgrade_latest']?> </td><?php endif; ?>
|
173 |
+
<td><select class="select" name="actions[<?php echo $channel.'|'.$pkgName ?>]">
|
174 |
+
<option selected="selected"></option>
|
175 |
+
<?php if(isset($pkg['actions']) && is_array($pkg['actions'])): ?>
|
176 |
+
<?php foreach ($pkg['actions'] as $k=>$v): ?>
|
177 |
+
<option value="<?php echo $k ?>"><?php echo $v ?></option>
|
178 |
+
<?php endforeach; ?>
|
179 |
+
<?php endif; ?>
|
180 |
+
</select>
|
181 |
+
</td>
|
182 |
+
<td class="last"><?php echo $pkg['summary']?></td>
|
183 |
+
</tr>
|
184 |
+
<?php endforeach; /*channel*/ ?>
|
185 |
+
</tbody>
|
186 |
+
</table>
|
187 |
+
<div class="clear"></div>
|
188 |
+
|
189 |
+
<div class="form-btn-set">
|
190 |
+
<button type="button" onclick="formSubmit('connect_packages_<?php echo $i ?>')" class="f-right">Commit Changes</button>
|
191 |
+
<?php if (!empty($_GET['updates'])): ?>
|
192 |
+
<p class="f-left a-left">
|
193 |
+
<span style="background:#f6f6f6;padding:0 5px;"> </span> Installed<br/>
|
194 |
+
<span style="background:#fcfbbb;padding:0 5px;"> </span> Upgrade Available<br/>
|
195 |
+
</p>
|
196 |
+
<?php endif; ?>
|
197 |
+
</div>
|
198 |
+
</form>
|
199 |
+
<script type="text/javascript">
|
200 |
+
$$('#connect_packages_' + <?php echo $i?> + ' select').each(function(el){el.value=''});
|
201 |
+
</script>
|
202 |
+
<?php if (++$i != $cnt): ?><div class="divider"></div><?php endif ?>
|
203 |
+
<br/>
|
204 |
+
<?php endforeach; /*all packages*/ ?>
|
205 |
+
|
206 |
+
|
207 |
+
<?php echo $this->template('connect/iframe.phtml') ?>
|
208 |
+
|
209 |
+
<a name="connect_iframe_result"></a>
|
210 |
+
<div id="connect_iframe_success" style="display:none">
|
211 |
+
<?php $this->set('messages', array('success'=>array('Procedure completed. Please check the output frame for useful information and refresh the page to see changes.'))) ?>
|
212 |
+
<?php echo $this->template('messages.phtml') ?>
|
213 |
+
<button onclick="location.href='<?php echo $this->baseUrl() ?>'">Refresh</button>
|
214 |
+
</div>
|
215 |
+
<div id="connect_iframe_failure" style="display:none">
|
216 |
+
<?php $this->set('messages', array('error'=>array('Please check the output frame for errors and refresh the page to retry changes.'))) ?>
|
217 |
+
<?php echo $this->template('messages.phtml') ?>
|
218 |
+
<button onclick="location.href='<?php echo $this->baseUrl() ?>'">Refresh</button>
|
219 |
+
</div>
|
220 |
+
|
221 |
+
<?php echo $this->template('footer.phtml') ?>
|
downloader/template/connect/packages_prepare.phtml
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 type="hidden" name="install_package_id" value="<?php echo $this->get('package_id'); ?>">
|
37 |
+
<table cellspacing="0" cellpadding="0" width="100%">
|
38 |
+
<col width="150" />
|
39 |
+
<col width="250" />
|
40 |
+
<col width="150" />
|
41 |
+
<col width="100" />
|
42 |
+
<thead>
|
43 |
+
<tr>
|
44 |
+
<th class="first">Channel</th>
|
45 |
+
<th class="first">Package Name</th>
|
46 |
+
<th>Version</th>
|
47 |
+
<th class="last">Status</th>
|
48 |
+
</tr>
|
49 |
+
</thead>
|
50 |
+
<tbody>
|
51 |
+
<?php foreach ($packages as $pkg): ?>
|
52 |
+
<tr class="<?php echo $pkg['status']?>">
|
53 |
+
<td class="first"><?php echo $pkg['channel']?></td>
|
54 |
+
<td><?php echo $pkg['name']?></td>
|
55 |
+
<td><?php echo $pkg['version'] . (!empty($pkg['stability']) ? ' (' . $pkg['stability'] . ')' : '')?></td>
|
56 |
+
<td class="last"><?php echo $pkg['message']?></td>
|
57 |
+
</tr>
|
58 |
+
<?php endforeach;?>
|
59 |
+
</tbody>
|
60 |
+
</table>
|
61 |
+
<div class="form-btn-set">
|
62 |
+
<button class="f-right" type="submit">Proceed</button>
|
63 |
+
<button class="f-right" style="margin-right:10px;" onclick="$('prepare_package_result').update();" type="reset">Cancel installation</button>
|
64 |
+
</div>
|
65 |
+
</form>
|
66 |
+
<?php
|
67 |
+
endif;
|
68 |
+
if (!$cnt || !empty($errors['error'])):
|
69 |
+
$_errors = array('error'=>array('Extension key is not valid.'));
|
70 |
+
if(!empty($errors) && is_array($errors)) $_errors = $errors;
|
71 |
+
$this->set('messages', $_errors)
|
72 |
+
?>
|
73 |
+
<div id="packages_failure">
|
74 |
+
<?php echo $this->template('messages.phtml') ?>
|
75 |
+
</div>
|
76 |
+
<?php
|
77 |
+
endif;
|
78 |
+
?>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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') ?>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 © 2010 Magento Inc.
|
37 |
+
</p>
|
38 |
+
</div>
|
39 |
+
</body>
|
40 |
+
</html>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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') ?>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
downloader/template/install/download.phtml
ADDED
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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">Use Custom Permissions:</td>
|
62 |
+
<td class="value">
|
63 |
+
<select onchange="togglePanel(this)" id="use_custom_permissions_mode" name="use_custom_permissions_mode">
|
64 |
+
<option value="1" <?php if ($this->get('use_custom_permissions_mode')=='1'):?>selected="selected"<?php endif ?>>Yes</option>
|
65 |
+
<option value="0" <?php if ($this->get('use_custom_permissions_mode')=='0'):?>selected="selected"<?php endif ?>>No</option>
|
66 |
+
</select>
|
67 |
+
</td>
|
68 |
+
</tr>
|
69 |
+
</table>
|
70 |
+
<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 ?> >
|
71 |
+
<tr>
|
72 |
+
<td class="label">Folders:</td>
|
73 |
+
<td class="value">
|
74 |
+
<input id="mkdir_mode" name="mkdir_mode" value="<?php echo($this->get('mkdir_mode'));?>" type="text" class="input-text"></input>
|
75 |
+
</td>
|
76 |
+
</tr>
|
77 |
+
<tr>
|
78 |
+
<td class="label">Files:</td>
|
79 |
+
<td class="value">
|
80 |
+
<input id="chmod_file_mode" name="chmod_file_mode" value="<?php echo($this->get('chmod_file_mode'));?>" type="text" class="input-text"></input>
|
81 |
+
</td>
|
82 |
+
</tr>
|
83 |
+
</table>
|
84 |
+
<table cellspacing="0" cellpadding="0" class="form-list">
|
85 |
+
<tr>
|
86 |
+
<td class="label">Deployment Type:</td>
|
87 |
+
<td class="value">
|
88 |
+
<select id="inst_protocol" onchange="togglePanel(this)" name="inst_protocol">
|
89 |
+
<option value="0">Local Filesystem</option>
|
90 |
+
<option value="1">FTP Connection</option>
|
91 |
+
</select>
|
92 |
+
</td>
|
93 |
+
</tr>
|
94 |
+
</table>
|
95 |
+
<table cellspacing="0" cellpadding="0" class="form-list" id="inst_protocol_panel">
|
96 |
+
<tr>
|
97 |
+
<td class="label">Host:</td>
|
98 |
+
<td class="value">
|
99 |
+
<input type="text" class="input-text" id="ftp_host" value="" name="ftp_host" />
|
100 |
+
</td>
|
101 |
+
</tr>
|
102 |
+
|
103 |
+
<tr>
|
104 |
+
<td class="label">User:</td>
|
105 |
+
<td class="value">
|
106 |
+
<input type="text" class="input-text" id="ftp_login" value="" name="ftp_login" />
|
107 |
+
</td>
|
108 |
+
</tr>
|
109 |
+
|
110 |
+
<tr>
|
111 |
+
<td class="label">Password:</td>
|
112 |
+
<td class="value">
|
113 |
+
<input type="password" id="ftp_password" value="" name="ftp_password" class="input-text" />
|
114 |
+
</td>
|
115 |
+
</tr>
|
116 |
+
|
117 |
+
<tr>
|
118 |
+
<td class="label">Installation Path:</td>
|
119 |
+
<td class="value">
|
120 |
+
<input id="ftp_path" name="ftp_path" value="" type="text" class="input-text" />
|
121 |
+
</td>
|
122 |
+
</tr>
|
123 |
+
</table>
|
124 |
+
|
125 |
+
<?php if (!$this->controller()->isDownloaded()): ?>
|
126 |
+
<button class="form-button" type="submit">Start the download process</button>
|
127 |
+
</fieldset>
|
128 |
+
</form>
|
129 |
+
<?php else: ?>
|
130 |
+
<button class="form-button" type="submit">Re-Download All Magento Core Packages</button>
|
131 |
+
</fieldset>
|
132 |
+
</form>
|
133 |
+
<?php endif; ?>
|
134 |
+
|
135 |
+
<br/>
|
136 |
+
<?php echo $this->template('connect/iframe.phtml') ?>
|
137 |
+
|
138 |
+
<a name="connect_iframe_result"></a>
|
139 |
+
<div id="connect_iframe_success" style="display:none">
|
140 |
+
<?php $this->set('messages', array('success'=>array(
|
141 |
+
'Download completed. You can proceed with installation',
|
142 |
+
))) ?>
|
143 |
+
<?php echo $this->template('messages.phtml') ?>
|
144 |
+
|
145 |
+
<button class="form-button" type="button" onclick="location.href='<?php echo $this->mageUrl() ?>'"><span>Continue Magento installation</span></button>
|
146 |
+
</div>
|
147 |
+
|
148 |
+
<div id="connect_iframe_failure" style="display:none">
|
149 |
+
<?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.'))) ?>
|
150 |
+
<?php echo $this->template('messages.phtml') ?>
|
151 |
+
<button class="form-button" type="button" onclick="location.reload()"><span>Refresh</span></button>
|
152 |
+
</div>
|
153 |
+
|
154 |
+
<script type="text/javascript">
|
155 |
+
function togglePanel (element)
|
156 |
+
{
|
157 |
+
if (element.value == '1') {
|
158 |
+
disabledMode = '';
|
159 |
+
} else {
|
160 |
+
disabledMode = 'none';
|
161 |
+
}
|
162 |
+
document.getElementById(element.id+'_panel').style.display = disabledMode;
|
163 |
+
}
|
164 |
+
togglePanel(document.getElementById('use_custom_permissions_mode'));
|
165 |
+
togglePanel(document.getElementById('inst_protocol'));
|
166 |
+
</script>
|
167 |
+
|
168 |
+
<script type="text/javascript">
|
169 |
+
function installAll(force)
|
170 |
+
{
|
171 |
+
if (force) {
|
172 |
+
if (!confirm("This will delete all files from core packages.\n\nAre you sure you wish to force re-install all Magento files?")) {
|
173 |
+
return false;
|
174 |
+
}
|
175 |
+
}
|
176 |
+
/**
|
177 |
+
* @TODO: create validation of directory/file permission fields
|
178 |
+
*/
|
179 |
+
|
180 |
+
return onSubmit();
|
181 |
+
}
|
182 |
+
</script>
|
183 |
+
|
184 |
+
<?php echo $this->template('install/footer.phtml') ?>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 © 2010 Magento Inc.</p>
|
45 |
+
</div>
|
46 |
+
</div>
|
47 |
+
<!-- [end] footer -->
|
48 |
+
</body>
|
49 |
+
</html>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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/install" 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 |
+
|
95 |
+
</div>
|
96 |
+
<div id="main" class="col-main">
|
97 |
+
<!-- [start] global messages -->
|
98 |
+
<!-- [end] global messages -->
|
99 |
+
<!-- [start] content -->
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
downloader/template/login.phtml
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
<h2 class="page-head">Log In</h2>
|
34 |
+
<p><small>Please re-enter your Magento Adminstration Credentials.<br/>Only administrators with full permissions will be able to log in.</small></p>
|
35 |
+
<table class="form-list">
|
36 |
+
<tr><td class="label"><label for="username">Username:</label></td><td class="value"><input id="username" name="username" value=""/></td></tr>
|
37 |
+
<tr><td class="label"><label for="password">Password:</label></td><td class="value"><input type="password" id="password" name="password"/></td></tr>
|
38 |
+
<tr><td></td>
|
39 |
+
<td class="value"><button type="submit">Log In</button></td></tr>
|
40 |
+
</table>
|
41 |
+
</form>
|
42 |
+
</div>
|
43 |
+
<?php echo $this->template('footer.phtml') ?>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 $msg ?></li>
|
34 |
+
<?php endforeach; ?>
|
35 |
+
</ul>
|
36 |
+
</li>
|
37 |
+
<?php endforeach; ?>
|
38 |
+
</ul>
|
39 |
+
<?php endif; ?>
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
|
downloader/template/settings.phtml
ADDED
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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 |
+
<fieldset>
|
54 |
+
<p>Magento Extensions are available in three different versions.</p>
|
55 |
+
<ul class="disc">
|
56 |
+
<li><strong>Stable</strong> means the extension can be used in a production environment.</li>
|
57 |
+
<li><strong>Beta</strong> means the extension is not recommended for use in a production environment.</li>
|
58 |
+
<li><strong>Alpha</strong> means the extension is still in development.</li>
|
59 |
+
</ul>
|
60 |
+
<p><strong>Please note: extensions are provided as is. Make sure to backup your data before installing new extensions.</strong></p>
|
61 |
+
<table cellspacing="0" class="form-list">
|
62 |
+
<tr>
|
63 |
+
<td class="label">Magento Connect Channel Protocol:</td>
|
64 |
+
<td class="value">
|
65 |
+
<select id="protocol" name="protocol">
|
66 |
+
<option value="http" <?php if ($this->get('protocol')=='http'):?>selected="selected"<?php endif ?>>Http</option>
|
67 |
+
<option value="ftp" <?php if ($this->get('protocol')=='ftp'):?>selected="selected"<?php endif ?>>Ftp</option>
|
68 |
+
</select>
|
69 |
+
</td>
|
70 |
+
</tr>
|
71 |
+
<?php echo $this->get('channel_protocol_fields'); ?>
|
72 |
+
<tr>
|
73 |
+
<td class="label">Preferred State:</td>
|
74 |
+
<td class="value">
|
75 |
+
<select id="preferred_state" name="preferred_state">
|
76 |
+
<option value="stable" <?php if ($this->get('preferred_state')=='stable'):?>selected="selected"<?php endif ?>>Stable</option>
|
77 |
+
<option value="beta" <?php if ($this->get('preferred_state')=='beta'):?>selected="selected"<?php endif ?>>Beta</option>
|
78 |
+
<option value="alpha" <?php if ($this->get('preferred_state')=='alpha'):?>selected="selected"<?php endif ?>>Alpha</option>
|
79 |
+
</select>
|
80 |
+
</td>
|
81 |
+
</tr>
|
82 |
+
<!--
|
83 |
+
<tr>
|
84 |
+
<td class="label">Magento Installation Directory:</td>
|
85 |
+
<td class="value"><input name="mage_dir" value="<?php echo htmlentities($this->get('mage_dir'))?>" style="width:250px;"/></td>
|
86 |
+
</tr>
|
87 |
+
-->
|
88 |
+
</table>
|
89 |
+
<p><strong>Permission to create new files and folders.</strong></p>
|
90 |
+
<table cellspacing="0" class="form-list">
|
91 |
+
<tr>
|
92 |
+
<td class="label">Use custom permissions:</td>
|
93 |
+
<td class="value">
|
94 |
+
<select onchange="useCustomPermissions(this)" id="use_custom_permissions_mode" name="use_custom_permissions_mode">
|
95 |
+
<option value="1" <?php if ($this->get('use_custom_permissions_mode')=='1'):?>selected="selected"<?php endif ?>>Yes</option>
|
96 |
+
<option value="0" <?php if ($this->get('use_custom_permissions_mode')=='0'):?>selected="selected"<?php endif ?>>No</option>
|
97 |
+
</select>
|
98 |
+
</td>
|
99 |
+
</tr>
|
100 |
+
</table>
|
101 |
+
<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 ?>>
|
102 |
+
<tr>
|
103 |
+
<td class="label">Folders:</td>
|
104 |
+
<td class="value">
|
105 |
+
<input id="mkdir_mode" name="mkdir_mode" value="<?php echo($this->get('mkdir_mode'));?>" class="input-text" type="text"></input>
|
106 |
+
</td>
|
107 |
+
</tr>
|
108 |
+
<tr>
|
109 |
+
<td class="label">Files:</td>
|
110 |
+
<td class="value">
|
111 |
+
<input id="chmod_file_mode" name="chmod_file_mode" value="<?php echo($this->get('chmod_file_mode'));?>" class="input-text" type="text"></input>
|
112 |
+
</td>
|
113 |
+
</tr>
|
114 |
+
</table>
|
115 |
+
|
116 |
+
<p><strong>Deployment.</strong></p>
|
117 |
+
<table cellspacing="0" class="form-list">
|
118 |
+
<tr>
|
119 |
+
<td class="label">Deployment Type:</td>
|
120 |
+
<td class="value">
|
121 |
+
<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 ?> />
|
122 |
+
<label for="deployment_fs"> <span class="label">Local Filesystem</span> </label>
|
123 |
+
</td>
|
124 |
+
</tr>
|
125 |
+
<tr>
|
126 |
+
<td class="label"> </td>
|
127 |
+
<td class="value">
|
128 |
+
<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 ?> />
|
129 |
+
<label for="deployment_ftp"><span class="label">FTP Connection</span></label>
|
130 |
+
</td>
|
131 |
+
</tr>
|
132 |
+
</table>
|
133 |
+
<table cellspacing="0" class="form-list" id="deployment_type_panel" <?php if ($this->get('deployment_type')!='ftp'):?>style="display:none;"<?php endif ?>>
|
134 |
+
<tr>
|
135 |
+
<td class="label">FTP Host:</td>
|
136 |
+
<td class="value">
|
137 |
+
<input id="ftp_host" name="ftp_host" value="<?php echo($this->get('ftp_host'));?>" class="input-text" type="text"></input>
|
138 |
+
</td>
|
139 |
+
</tr>
|
140 |
+
<tr>
|
141 |
+
<td class="label">FTP Login:</td>
|
142 |
+
<td class="value">
|
143 |
+
<input id="ftp_login" name="ftp_login" value="<?php echo($this->get('ftp_login'));?>" class="input-text" type="text"></input>
|
144 |
+
</td>
|
145 |
+
</tr>
|
146 |
+
<tr>
|
147 |
+
<td class="label">FTP Password:</td>
|
148 |
+
<td class="value">
|
149 |
+
<input id="ftp_password" name="ftp_password" value="<?php echo($this->get('ftp_password'));?>" class="input-text" type="password"></input>
|
150 |
+
</td>
|
151 |
+
</tr>
|
152 |
+
<tr>
|
153 |
+
<td class="label">Installation Path:</td>
|
154 |
+
<td class="value">
|
155 |
+
<input id="ftp_path" name="ftp_path" value="<?php echo($this->get('ftp_path'));?>" class="input-text" type="text"></input>
|
156 |
+
</td>
|
157 |
+
</tr>
|
158 |
+
</table>
|
159 |
+
|
160 |
+
<p><button type="submit">Save Settings</button></p>
|
161 |
+
</fieldset>
|
162 |
+
</form>
|
163 |
+
</div>
|
164 |
+
|
165 |
+
<?php echo $this->template('footer.phtml') ?>
|
166 |
+
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default
|
23 |
+
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.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>
|
index.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magentocommerce.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.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage
|
23 |
+
* @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.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 |
+
/**
|
33 |
+
* Error reporting
|
34 |
+
*/
|
35 |
+
error_reporting(E_ALL | E_STRICT);
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Compilation includes configuration file
|
39 |
+
*/
|
40 |
+
$compilerConfig = 'includes/config.php';
|
41 |
+
if (file_exists($compilerConfig)) {
|
42 |
+
include $compilerConfig;
|
43 |
+
}
|
44 |
+
|
45 |
+
$mageFilename = 'app/Mage.php';
|
46 |
+
$maintenanceFile = 'maintenance.flag';
|
47 |
+
|
48 |
+
if (!file_exists($mageFilename)) {
|
49 |
+
if (is_dir('downloader')) {
|
50 |
+
header("Location: downloader");
|
51 |
+
} else {
|
52 |
+
echo $mageFilename." was not found";
|
53 |
+
}
|
54 |
+
exit;
|
55 |
+
}
|
56 |
+
|
57 |
+
if (file_exists($maintenanceFile)) {
|
58 |
+
include_once dirname(__FILE__) . '/errors/503.php';
|
59 |
+
exit;
|
60 |
+
}
|
61 |
+
|
62 |
+
require_once $mageFilename;
|
63 |
+
|
64 |
+
#Varien_Profiler::enable();
|
65 |
+
|
66 |
+
if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) {
|
67 |
+
Mage::setIsDeveloperMode(true);
|
68 |
+
}
|
69 |
+
|
70 |
+
#ini_set('display_errors', 1);
|
71 |
+
|
72 |
+
umask(0);
|
73 |
+
|
74 |
+
/* Store or website code */
|
75 |
+
$mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
|
76 |
+
|
77 |
+
/* Run store or run website */
|
78 |
+
$mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
|
79 |
+
|
80 |
+
Mage::run($mageRunCode, $mageRunType);
|
mage
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/sh
|
2 |
+
|
3 |
+
# REPLACE with your PHP5 binary path (example: /usr/local/php5/bin/php )
|
4 |
+
#MAGE_PHP_BIN="php"
|
5 |
+
|
6 |
+
MAGE_PHP_SCRIPT="mage.php"
|
7 |
+
DOWNLOADER_PATH='downloader'
|
8 |
+
|
9 |
+
# initial setup
|
10 |
+
if test "x$1" = "xmage-setup"; then
|
11 |
+
echo 'Running initial setup...'
|
12 |
+
|
13 |
+
if test "x$2" != "x"; then
|
14 |
+
MAGE_ROOT_DIR="$2"
|
15 |
+
else
|
16 |
+
MAGE_ROOT_DIR="`pwd`"
|
17 |
+
fi
|
18 |
+
|
19 |
+
$0 config-set magento_root "$MAGE_ROOT_DIR"
|
20 |
+
$0 config-set preferred_state beta
|
21 |
+
$0 channel-add http://connect20.magentocommerce.com/community
|
22 |
+
exit
|
23 |
+
fi
|
24 |
+
|
25 |
+
# check that mage pear was initialized
|
26 |
+
|
27 |
+
if test "x$1" != "xconfig-set" &&
|
28 |
+
test "x$1" != "xconfig-get" &&
|
29 |
+
test "x$1" != "xconfig-show" &&
|
30 |
+
test "x$1" != "xchannel-add" &&
|
31 |
+
test "x`$0 config-get magento_root`" = "x"; then
|
32 |
+
echo 'Please initialize Magento Connect installer by running:'
|
33 |
+
echo "$0 mage-setup"
|
34 |
+
exit;
|
35 |
+
fi
|
36 |
+
|
37 |
+
# find which PHP binary to use
|
38 |
+
if test "x$MAGE_PHP_BIN" != "x"; then
|
39 |
+
PHP="$MAGE_PHP_BIN"
|
40 |
+
else
|
41 |
+
PHP=php
|
42 |
+
fi
|
43 |
+
|
44 |
+
|
45 |
+
# get default pear dir of not set
|
46 |
+
if test "x$MAGE_ROOT_DIR" = "x"; then
|
47 |
+
MAGE_ROOT_DIR="`pwd`/$DOWNLOADER_PATH"
|
48 |
+
fi
|
49 |
+
|
50 |
+
exec $PHP -C -q $INCARG -d output_buffering=1 -d variables_order=EGPCS \
|
51 |
+
-d open_basedir="" -d safe_mode=0 -d register_argc_argv="On" \
|
52 |
+
-d auto_prepend_file="" -d auto_append_file="" \
|
53 |
+
$MAGE_ROOT_DIR/$MAGE_PHP_SCRIPT "$@"
|
54 |
+
|
package.xml
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>Mage_Downloader</name>
|
4 |
+
<version>1.6.1.0</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Magento Downloader</summary>
|
10 |
+
<description>Magento Downloader</description>
|
11 |
+
<notes>1.6.1.0</notes>
|
12 |
+
<authors><author><name>Magento Core Team</name><user>core</user><email>core@magentocommerce.com</email></author></authors>
|
13 |
+
<date>2011-10-19</date>
|
14 |
+
<time>11:50:15</time>
|
15 |
+
<contents><target name="mage"><dir name="downloader"><dir name="js"><file name="prototype.js" hash="3766aeff5778b54f74f93670322ca0df"/></dir><dir name="Maged"><dir name="Connect"><file name="Frontend.php" hash="e469328440d5d865db40ed6dec2eb0dd"/></dir><file name="Connect.php" hash="3878355516c34d9544a02d44a4c1e2b8"/><file name="Controller.php" hash="667cee056eef10004144cbadab05a299"/><file name="Exception.php" hash="31befe07df0a61598f063f543991a04b"/><dir name="Model"><dir name="Config"><file name="Abstract.php" hash="b87bd9947efce3f373ff65e0c997334e"/><file name="Community.php" hash="0e39f2375ec50ef5c8d7994e67eaf49e"/><file name="Interface.php" hash="fe6daef73f9f63adcce14dd322a41050"/></dir><file name="Config.php" hash="0fdf21421b2874620f4708b835ad34d5"/><dir name="Connect"><file name="Request.php" hash="9b89d6528986fcd5b97d59a8ceb48eac"/></dir><file name="Connect.php" hash="c63a751c9c720a3c8b670134b816c2aa"/><file name="Dowloader.php" hash="01885097ba694f6e0119f3eaecfa463f"/><file name="Session.php" hash="2876ecde6b2c2bba65e11c3dcf2d913f"/></dir><file name="Model.php" hash="9d43f384a202246af906c65e156d4aaa"/><file name="View.php" hash="38f23f08650249dcb75ff6a0e203ad28"/></dir><dir name="skin"><file name="boxes.css" hash="5a6a94b06fbd4335b4d0f78b94cb9712"/><file name="ie7boxes.css" hash="c9e684ca787f6521190922e7e2e6ed9e"/><file name="ieboxes.css" hash="ff95c4f8ade70c9178f1315eb61eaabe"/><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="b6d074b3fce501813ed1d8dd323bf422"/><file name="clears.css" hash="bc94c9e4ee77d82530ca33b468b502e4"/><file name="ie7minus.css" hash="e0bad17242a3b6c20516bb292bf16493"/><file name="iestyles.css" hash="eb20094050695e0e02f0318b37c24e08"/><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="f473723e7a0aff5d6feedbbab6cb3392"/></dir></dir><dir name="template"><dir name="connect"><file name="iframe.phtml" hash="2aa7c28d092c43e14b8b1fe413e6a126"/><file name="packages.phtml" hash="72c6024a9891c01b603f2766f52ff914"/><file name="packages_prepare.phtml" hash="bd34d2a794e5fcc84d4ea22b5754d250"/></dir><file name="exception.phtml" hash="ce8145052f0a730088fc849c04c58c64"/><file name="footer.phtml" hash="454299883c093cc98b4550c99bba03b9"/><file name="header.phtml" hash="73ab5e15a8a58d624fb5b8e48da679d3"/><file name="index.phtml" hash="1c7d5cbca5c16632db3f891024086947"/><dir name="install"><file name="download.phtml" hash="b7f283992b89cae9e85cc655e4b2d4e3"/><file name="footer.phtml" hash="6a70fd31200cb9bfddf65d7f8f67ac5e"/><file name="header.phtml" hash="f07d63df229468c28043869f0b71e194"/><file name="writable.phtml" hash="2815049a02b3f1110b9f22e22047b941"/></dir><file name="login.phtml" hash="ad91f8daa2d8a8974782350a2d2e2578"/><file name="messages.phtml" hash="8753c0c5599fa55a190c4913651b2c77"/><file name="noroute.phtml" hash="ad5ded291fcbf3899af4f499b77aaf42"/><file name="settings.phtml" hash="5bda5f6e749e288f7e2cb0fc2b7f1b83"/><file name="writable.phtml" hash="5fc31df4f9795e8febe39da1e59d91cd"/><file name=".htaccess" hash="72617d60821288133a367f70bf39ad93"/></dir><file name="index.php" hash="db1b840cef501ba7830d1035d6a3df7b"/><dir name="lib"><dir name="Mage"><dir name="Archive"><file name="Abstract.php" hash="a17be2772775eac2d1e3a36041a9f3c1"/><file name="Bz.php" hash="4e95c019f7c8983ecb225d0847806bed"/><file name="Gz.php" hash="e832e68bd2a3165234b6d6b52b3fcac0"/><file name="Interface.php" hash="1c57bd8e6ee7dbe4cfcaa3dfdceb1d7b"/><file name="Tar.php" hash="12983e34995349ab736eb8c5bbe03ba6"/></dir><file name="Archive.php" hash="7947ccf15f5df8300e7cf1a4681b9569"/><dir name="Autoload"><file name="Simple.php" hash="e062bd1b45f0b08ac456d3e0dc4c06b6"/></dir><dir name="Connect"><dir name="Channel"><file name="Generator.php" hash="4bbda17b29549ae9a50ea09c0db54649"/><file name="Parser.php" hash="3546e3b66eafe78bdd5628dc37f4bca9"/><file name="VO.php" hash="0525a71b043486aca9febcac6ce0ccff"/></dir><dir name="Command"><file name="Channels.php" hash="83e47fe8f407212ecc1797028211d15d"/><file name="Channels_Header.php" hash="8a828b219ec1b57eba88806845f133cb"/><file name="Config.php" hash="22161cf90d8d2abb5409a30dbe28a44c"/><file name="Config_Header.php" hash="0ce12f7207fe610f886aae15df145615"/><file name="Install.php" hash="b40177f31744db26010c8fbe8e10b05a"/><file name="Install_Header.php" hash="1d4da6660edb2e63ea9a223ccfe4610d"/><file name="Package.php" hash="09d265ec9666b7729276a54c88db1263"/><file name="Package_Header.php" hash="102080d8fad7234b60b103a5dbf65754"/><file name="Registry.php" hash="898b91578ee622b4914023edc9e34984"/><file name="Registry_Header.php" hash="fb37813d34f75835e4ecccea704b2ab0"/><file name="Remote.php" hash="3b0f8aa676ddd677e3a57823d8b0c60e"/><file name="Remote_Header.php" hash="9bd703a45c70ccc959f922392decc962"/></dir><file name="Command.php" hash="b3314fecd974fc3d767049cf323cc254"/><file name="Config.php" hash="4d688d01fd05522fa36166656bd5c697"/><file name="Converter.php" hash="435aad5d121240eb7784f3f71a848392"/><dir name="Frontend"><file name="CLI.php" hash="0b71bae7609966ebfcfc04f63a0318a3"/></dir><file name="Frontend.php" hash="811d665cee46fdbea623d651cf4ac44b"/><file name="Ftp.php" hash="4adbc5b56bf2be7ca7d042f78ae61298"/><dir name="Loader"><file name="Ftp.php" hash="1fbff02e85c5e2f7f0e61d8577c248d6"/></dir><file name="Loader.php" hash="ba5151383e4931a7f767a2d1897cb2a7"/><dir name="Package"><file name="Extension.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="Hotfix.php" hash="370177a5cf2f3397e0b341466d34de75"/><file name="Maintainer.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="Reader.php" hash="7fa1d41c6145f178e50e8a266e361f1e"/><file name="Target.php" hash="09c91f931b37f5e350a7ebdbb6bbf442"/><file name="VO.php" hash="e42f4d13abcaa766ca35f24c6280043b"/><file name="Writer.php" hash="32088dd140dfd14b3bde9c11a32b7d35"/></dir><file name="Package.php" hash="bcc3ed40ad75f37e6be0d90e833a84bb"/><file name="Packager.php" hash="812c9dd97f990744d4a763e4b6c3a7b5"/><dir name="Repository"><file name="Abstract.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><dir name="Channel"><file name="Abstract.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="Commercial.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="Community.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="Core.php" hash="68b329da9893e34099c7d8ad5cb9c940"/></dir><file name="Channel.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="Local.php" hash="68b329da9893e34099c7d8ad5cb9c940"/></dir><file name="Repository.php" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="Rest.php" hash="9bf931f43e0840f903ce9089d90779a2"/><file name="Singleconfig.php" hash="bdcb3dcfb2a58b290cce8da370f8ac9c"/><dir name="Structures"><file name="Graph.php" hash="bb484f7ed43d819d9964c3dfa0489641"/><file name="Node.php" hash="5fe101c2a3c371ebca23b1a77a4d8b9a"/></dir><file name="Validator.php" hash="500f1fec82dc873ef02fae0d738b5162"/></dir><dir name="DB"><file name="Exception.php" hash="38385d6b8ba6dfabf53aa275ca5b1086"/><file name="Mysqli.php" hash="7afa22548284f2e6e8796fce50f736ce"/></dir><file name="Exception.php" hash="a5e649c88e376f850b83d35900525a7f"/><dir name="HTTP"><dir name="Client"><file name="Curl.php" hash="8eba20650fc9da09d8585e31ea3bd053"/><file name="Socket.php" hash="a1b2788a4fa596f70430d309ffc8f59f"/></dir><file name="Client.php" hash="189e5288453ce792e1eacbb178e20fd1"/><file name="IClient.php" hash="eb44927eabc6a87fbf37d52643732b2d"/></dir><dir name="System"><file name="Args.php" hash="a3058a52f975e8436a8d2b113943489a"/><file name="Dirs.php" hash="0addfeb8f206cc67539ca0625921e016"/></dir><dir name="Xml"><file name="Generator.php" hash="c0b790125cc714d1ca43cfdc046768ed"/><file name="Parser.php" hash="6f8ac6fb3c6332c257d28e335909e855"/></dir></dir></dir><file name="config.ini" hash="a52ba98e71ab19de387b3af1a04c6102"/><file name=".htaccess" hash="520cc012c84739584526b8a9ff098e23"/><file name="mage.php" hash="6de4d106e8080bd2be838d1674bf6136"/></dir><dir name="."><file name=".htaccess" hash="8c1f49780253bb13b4fa89d604e814b6"/><file name="index.php" hash="20b1633bd332a08e643afa4590ab8564"/><file name="mage" hash="091c45355c62a9189cff45c09328037c"/></dir></target></contents>
|
16 |
+
<compatible/>
|
17 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
|
18 |
+
</package>
|