Редакция 69 | Только различия | Не учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS
Редакция 69 | Редакция 87 | ||
---|---|---|---|
1 | <?php
|
1 | <?php
|
2 | // /* vim: set expandtab tabstop=4 shiftwidth=4: */
|
2 | // /* vim: set expandtab tabstop=4 shiftwidth=4: */
|
3 | /**
|
3 | /**
|
4 | * PEAR_Command_Channels (list-channels, update-channels, channel-delete, channel-add,
|
4 | * PEAR_Command_Channels (list-channels, update-channels, channel-delete, channel-add,
|
5 | * channel-update, channel-info, channel-alias, channel-discover commands)
|
5 | * channel-update, channel-info, channel-alias, channel-discover commands)
|
6 | *
|
6 | *
|
7 | * PHP versions 4 and 5
|
7 | * PHP versions 4 and 5
|
8 | *
|
8 | *
|
9 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
9 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
10 | * that is available through the world-wide-web at the following URI:
|
10 | * that is available through the world-wide-web at the following URI:
|
11 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
11 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
12 | * the PHP License and are unable to obtain it through the web, please
|
12 | * the PHP License and are unable to obtain it through the web, please
|
13 | * send a note to license@php.net so we can mail you a copy immediately.
|
13 | * send a note to license@php.net so we can mail you a copy immediately.
|
14 | *
|
14 | *
|
15 | * @category pear
|
15 | * @category pear
|
16 | * @package PEAR
|
16 | * @package PEAR
|
17 | * @author Stig Bakken <ssb@php.net>
|
17 | * @author Stig Bakken <ssb@php.net>
|
18 | * @author Greg Beaver <cellog@php.net>
|
18 | * @author Greg Beaver <cellog@php.net>
|
19 | * @copyright 1997-2008 The PHP Group
|
19 | * @copyright 1997-2008 The PHP Group
|
20 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
20 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
21 | * @version CVS: $Id: Channels.php,v 1.57 2008/01/03 20:26:36 cellog Exp $
|
21 | * @version CVS: $Id: Channels.php,v 1.57 2008/01/03 20:26:36 cellog Exp $
|
22 | * @link http://pear.php.net/package/PEAR
|
22 | * @link http://pear.php.net/package/PEAR
|
23 | * @since File available since Release 1.4.0a1
|
23 | * @since File available since Release 1.4.0a1
|
24 | */
|
24 | */
|
25 | 25 | ||
26 | /**
|
26 | /**
|
27 | * base class
|
27 | * base class
|
28 | */
|
28 | */
|
29 | require_once 'PEAR/Command/Common.php'; |
29 | require_once 'PEAR/Command/Common.php'; |
30 | 30 | ||
31 | /**
|
31 | /**
|
32 | * PEAR commands for managing channels.
|
32 | * PEAR commands for managing channels.
|
33 | *
|
33 | *
|
34 | * @category pear
|
34 | * @category pear
|
35 | * @package PEAR
|
35 | * @package PEAR
|
36 | * @author Greg Beaver <cellog@php.net>
|
36 | * @author Greg Beaver <cellog@php.net>
|
37 | * @copyright 1997-2008 The PHP Group
|
37 | * @copyright 1997-2008 The PHP Group
|
38 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
38 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
39 | * @version Release: 1.7.2
|
39 | * @version Release: 1.7.2
|
40 | * @link http://pear.php.net/package/PEAR
|
40 | * @link http://pear.php.net/package/PEAR
|
41 | * @since Class available since Release 1.4.0a1
|
41 | * @since Class available since Release 1.4.0a1
|
42 | */
|
42 | */
|
43 | class PEAR_Command_Channels extends PEAR_Command_Common |
43 | class PEAR_Command_Channels extends PEAR_Command_Common |
44 | {
|
44 | {
|
45 | // {{{ properties
|
45 | // {{{ properties
|
46 | 46 | ||
47 | var $commands = array( |
47 | var $commands = array( |
48 | 'list-channels' => array( |
48 | 'list-channels' => array( |
49 | 'summary' => 'List Available Channels', |
49 | 'summary' => 'List Available Channels', |
50 | 'function' => 'doList', |
50 | 'function' => 'doList', |
51 | 'shortcut' => 'lc', |
51 | 'shortcut' => 'lc', |
52 | 'options' => array(), |
52 | 'options' => array(), |
53 | 'doc' => ' |
53 | 'doc' => ' |
54 | List all available channels for installation.
|
54 | List all available channels for installation.
|
55 | ', |
55 | ', |
56 | ), |
56 | ), |
57 | 'update-channels' => array( |
57 | 'update-channels' => array( |
58 | 'summary' => 'Update the Channel List', |
58 | 'summary' => 'Update the Channel List', |
59 | 'function' => 'doUpdateAll', |
59 | 'function' => 'doUpdateAll', |
60 | 'shortcut' => 'uc', |
60 | 'shortcut' => 'uc', |
61 | 'options' => array(), |
61 | 'options' => array(), |
62 | 'doc' => ' |
62 | 'doc' => ' |
63 | List all installed packages in all channels.
|
63 | List all installed packages in all channels.
|
64 | '
|
64 | '
|
65 | ), |
65 | ), |
66 | 'channel-delete' => array( |
66 | 'channel-delete' => array( |
67 | 'summary' => 'Remove a Channel From the List', |
67 | 'summary' => 'Remove a Channel From the List', |
68 | 'function' => 'doDelete', |
68 | 'function' => 'doDelete', |
69 | 'shortcut' => 'cde', |
69 | 'shortcut' => 'cde', |
70 | 'options' => array(), |
70 | 'options' => array(), |
71 | 'doc' => '<channel name> |
71 | 'doc' => '<channel name> |
72 | Delete a channel from the registry. You may not
|
72 | Delete a channel from the registry. You may not
|
73 | remove any channel that has installed packages.
|
73 | remove any channel that has installed packages.
|
74 | '
|
74 | '
|
75 | ), |
75 | ), |
76 | 'channel-add' => array( |
76 | 'channel-add' => array( |
77 | 'summary' => 'Add a Channel', |
77 | 'summary' => 'Add a Channel', |
78 | 'function' => 'doAdd', |
78 | 'function' => 'doAdd', |
79 | 'shortcut' => 'ca', |
79 | 'shortcut' => 'ca', |
80 | 'options' => array(), |
80 | 'options' => array(), |
81 | 'doc' => '<channel.xml> |
81 | 'doc' => '<channel.xml> |
82 | Add a private channel to the channel list. Note that all
|
82 | Add a private channel to the channel list. Note that all
|
83 | public channels should be synced using "update-channels".
|
83 | public channels should be synced using "update-channels".
|
84 | Parameter may be either a local file or remote URL to a
|
84 | Parameter may be either a local file or remote URL to a
|
85 | channel.xml.
|
85 | channel.xml.
|
86 | '
|
86 | '
|
87 | ), |
87 | ), |
88 | 'channel-update' => array( |
88 | 'channel-update' => array( |
89 | 'summary' => 'Update an Existing Channel', |
89 | 'summary' => 'Update an Existing Channel', |
90 | 'function' => 'doUpdate', |
90 | 'function' => 'doUpdate', |
91 | 'shortcut' => 'cu', |
91 | 'shortcut' => 'cu', |
92 | 'options' => array( |
92 | 'options' => array( |
93 | 'force' => array( |
93 | 'force' => array( |
94 | 'shortopt' => 'f', |
94 | 'shortopt' => 'f', |
95 | 'doc' => 'will force download of new channel.xml if an existing channel name is used', |
95 | 'doc' => 'will force download of new channel.xml if an existing channel name is used', |
96 | ), |
96 | ), |
97 | 'channel' => array( |
97 | 'channel' => array( |
98 | 'shortopt' => 'c', |
98 | 'shortopt' => 'c', |
99 | 'arg' => 'CHANNEL', |
99 | 'arg' => 'CHANNEL', |
100 | 'doc' => 'will force download of new channel.xml if an existing channel name is used', |
100 | 'doc' => 'will force download of new channel.xml if an existing channel name is used', |
101 | ), |
101 | ), |
102 | ), |
102 | ), |
103 | 'doc' => '[<channel.xml>|<channel name>] |
103 | 'doc' => '[<channel.xml>|<channel name>] |
104 | Update a channel in the channel list directly. Note that all
|
104 | Update a channel in the channel list directly. Note that all
|
105 | public channels can be synced using "update-channels".
|
105 | public channels can be synced using "update-channels".
|
106 | Parameter may be a local or remote channel.xml, or the name of
|
106 | Parameter may be a local or remote channel.xml, or the name of
|
107 | an existing channel.
|
107 | an existing channel.
|
108 | '
|
108 | '
|
109 | ), |
109 | ), |
110 | 'channel-info' => array( |
110 | 'channel-info' => array( |
111 | 'summary' => 'Retrieve Information on a Channel', |
111 | 'summary' => 'Retrieve Information on a Channel', |
112 | 'function' => 'doInfo', |
112 | 'function' => 'doInfo', |
113 | 'shortcut' => 'ci', |
113 | 'shortcut' => 'ci', |
114 | 'options' => array(), |
114 | 'options' => array(), |
115 | 'doc' => '<package> |
115 | 'doc' => '<package> |
116 | List the files in an installed package.
|
116 | List the files in an installed package.
|
117 | '
|
117 | '
|
118 | ), |
118 | ), |
119 | 'channel-alias' => array( |
119 | 'channel-alias' => array( |
120 | 'summary' => 'Specify an alias to a channel name', |
120 | 'summary' => 'Specify an alias to a channel name', |
121 | 'function' => 'doAlias', |
121 | 'function' => 'doAlias', |
122 | 'shortcut' => 'cha', |
122 | 'shortcut' => 'cha', |
123 | 'options' => array(), |
123 | 'options' => array(), |
124 | 'doc' => '<channel> <alias> |
124 | 'doc' => '<channel> <alias> |
125 | Specify a specific alias to use for a channel name.
|
125 | Specify a specific alias to use for a channel name.
|
126 | The alias may not be an existing channel name or
|
126 | The alias may not be an existing channel name or
|
127 | alias.
|
127 | alias.
|
128 | '
|
128 | '
|
129 | ), |
129 | ), |
130 | 'channel-discover' => array( |
130 | 'channel-discover' => array( |
131 | 'summary' => 'Initialize a Channel from its server', |
131 | 'summary' => 'Initialize a Channel from its server', |
132 | 'function' => 'doDiscover', |
132 | 'function' => 'doDiscover', |
133 | 'shortcut' => 'di', |
133 | 'shortcut' => 'di', |
134 | 'options' => array(), |
134 | 'options' => array(), |
135 | 'doc' => '[<channel.xml>|<channel name>] |
135 | 'doc' => '[<channel.xml>|<channel name>] |
136 | Initialize a channel from its server and create a local channel.xml.
|
136 | Initialize a channel from its server and create a local channel.xml.
|
137 | If <channel name> is in the format "<username>:<password>@<channel>" then
|
137 | If <channel name> is in the format "<username>:<password>@<channel>" then
|
138 | <username> and <password> will be set as the login username/password for
|
138 | <username> and <password> will be set as the login username/password for
|
139 | <channel>. Use caution when passing the username/password in this way, as
|
139 | <channel>. Use caution when passing the username/password in this way, as
|
140 | it may allow other users on your computer to briefly view your username/
|
140 | it may allow other users on your computer to briefly view your username/
|
141 | password via the system\'s process list.
|
141 | password via the system\'s process list.
|
142 | '
|
142 | '
|
143 | ), |
143 | ), |
144 | ); |
144 | ); |
145 | 145 | ||
146 | // }}}
|
146 | // }}}
|
147 | // {{{ constructor
|
147 | // {{{ constructor
|
148 | 148 | ||
149 | /**
|
149 | /**
|
150 | * PEAR_Command_Registry constructor.
|
150 | * PEAR_Command_Registry constructor.
|
151 | *
|
151 | *
|
152 | * @access public
|
152 | * @access public
|
153 | */
|
153 | */
|
154 | function PEAR_Command_Channels(&$ui, &$config) |
154 | function PEAR_Command_Channels(&$ui, &$config) |
155 | {
|
155 | {
|
156 | parent::PEAR_Command_Common($ui, $config); |
156 | parent::PEAR_Command_Common($ui, $config); |
157 | }
|
157 | }
|
158 | 158 | ||
159 | // }}}
|
159 | // }}}
|
160 | 160 | ||
161 | // {{{ doList()
|
161 | // {{{ doList()
|
162 | 162 | ||
163 | function _sortChannels($a, $b) |
163 | function _sortChannels($a, $b) |
164 | {
|
164 | {
|
165 | return strnatcasecmp($a->getName(), $b->getName()); |
165 | return strnatcasecmp($a->getName(), $b->getName()); |
166 | }
|
166 | }
|
167 | 167 | ||
168 | function doList($command, $options, $params) |
168 | function doList($command, $options, $params) |
169 | {
|
169 | {
|
170 | $reg = &$this->config->getRegistry(); |
170 | $reg = &$this->config->getRegistry(); |
171 | $registered = $reg->getChannels(); |
171 | $registered = $reg->getChannels(); |
172 | usort($registered, array(&$this, '_sortchannels')); |
172 | usort($registered, array(&$this, '_sortchannels')); |
173 | $i = $j = 0; |
173 | $i = $j = 0; |
174 | $data = array( |
174 | $data = array( |
175 | 'caption' => 'Registered Channels:', |
175 | 'caption' => 'Registered Channels:', |
176 | 'border' => true, |
176 | 'border' => true, |
177 | 'headline' => array('Channel', 'Summary') |
177 | 'headline' => array('Channel', 'Summary') |
178 | ); |
178 | ); |
179 | foreach ($registered as $channel) { |
179 | foreach ($registered as $channel) { |
180 | $data['data'][] = array($channel->getName(), |
180 | $data['data'][] = array($channel->getName(), |
181 | $channel->getSummary()); |
181 | $channel->getSummary()); |
182 | }
|
182 | }
|
183 | if (count($registered)==0) { |
183 | if (count($registered)==0) { |
184 | $data = '(no registered channels)'; |
184 | $data = '(no registered channels)'; |
185 | }
|
185 | }
|
186 | $this->ui->outputData($data, $command); |
186 | $this->ui->outputData($data, $command); |
187 | return true; |
187 | return true; |
188 | }
|
188 | }
|
189 | 189 | ||
190 | function doUpdateAll($command, $options, $params) |
190 | function doUpdateAll($command, $options, $params) |
191 | {
|
191 | {
|
192 | $reg = &$this->config->getRegistry(); |
192 | $reg = &$this->config->getRegistry(); |
193 | $channels = $reg->getChannels(); |
193 | $channels = $reg->getChannels(); |
194 | 194 | ||
195 | $success = true; |
195 | $success = true; |
196 | foreach ($channels as $channel) { |
196 | foreach ($channels as $channel) { |
197 | if ($channel->getName() != '__uri') { |
197 | if ($channel->getName() != '__uri') { |
198 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
198 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
199 | $err = $this->doUpdate('channel-update', |
199 | $err = $this->doUpdate('channel-update', |
200 | $options, |
200 | $options, |
201 | array($channel->getName())); |
201 | array($channel->getName())); |
202 | if (PEAR::isError($err)) { |
202 | if (PEAR::isError($err)) { |
203 | $this->ui->outputData($err->getMessage(), $command); |
203 | $this->ui->outputData($err->getMessage(), $command); |
204 | $success = false; |
204 | $success = false; |
205 | } else { |
205 | } else { |
206 | $success &= $err; |
206 | $success &= $err; |
207 | }
|
207 | }
|
208 | }
|
208 | }
|
209 | }
|
209 | }
|
210 | return $success; |
210 | return $success; |
211 | }
|
211 | }
|
212 | 212 | ||
213 | function doInfo($command, $options, $params) |
213 | function doInfo($command, $options, $params) |
214 | {
|
214 | {
|
215 | if (sizeof($params) != 1) { |
215 | if (sizeof($params) != 1) { |
216 | return $this->raiseError("No channel specified"); |
216 | return $this->raiseError("No channel specified"); |
217 | }
|
217 | }
|
218 | $reg = &$this->config->getRegistry(); |
218 | $reg = &$this->config->getRegistry(); |
219 | $channel = strtolower($params[0]); |
219 | $channel = strtolower($params[0]); |
220 | if ($reg->channelExists($channel)) { |
220 | if ($reg->channelExists($channel)) { |
221 | $chan = $reg->getChannel($channel); |
221 | $chan = $reg->getChannel($channel); |
222 | if (PEAR::isError($chan)) { |
222 | if (PEAR::isError($chan)) { |
223 | return $this->raiseError($chan); |
223 | return $this->raiseError($chan); |
224 | }
|
224 | }
|
225 | } else { |
225 | } else { |
226 | if (strpos($channel, '://')) { |
226 | if (strpos($channel, '://')) { |
227 | $downloader = &$this->getDownloader(); |
227 | $downloader = &$this->getDownloader(); |
228 | $tmpdir = $this->config->get('temp_dir'); |
228 | $tmpdir = $this->config->get('temp_dir'); |
229 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
229 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
230 | $loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir); |
230 | $loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir); |
231 | PEAR::staticPopErrorHandling(); |
231 | PEAR::staticPopErrorHandling(); |
232 | if (PEAR::isError($loc)) { |
232 | if (PEAR::isError($loc)) { |
233 | return $this->raiseError('Cannot open "' . $channel . |
233 | return $this->raiseError('Cannot open "' . $channel . |
234 | '" (' . $loc->getMessage() . ')'); |
234 | '" (' . $loc->getMessage() . ')'); |
235 | } else { |
235 | } else { |
236 | $contents = implode('', file($loc)); |
236 | $contents = implode('', file($loc)); |
237 | }
|
237 | }
|
238 | } else { |
238 | } else { |
239 | if (file_exists($params[0])) { |
239 | if (file_exists($params[0])) { |
240 | $fp = fopen($params[0], 'r'); |
240 | $fp = fopen($params[0], 'r'); |
241 | if (!$fp) { |
241 | if (!$fp) { |
242 | return $this->raiseError('Cannot open "' . $params[0] . '"'); |
242 | return $this->raiseError('Cannot open "' . $params[0] . '"'); |
243 | }
|
243 | }
|
244 | } else { |
244 | } else { |
245 | return $this->raiseError('Unknown channel "' . $channel . '"'); |
245 | return $this->raiseError('Unknown channel "' . $channel . '"'); |
246 | }
|
246 | }
|
247 | $contents = ''; |
247 | $contents = ''; |
248 | while (!feof($fp)) { |
248 | while (!feof($fp)) { |
249 | $contents .= fread($fp, 1024); |
249 | $contents .= fread($fp, 1024); |
250 | }
|
250 | }
|
251 | fclose($fp); |
251 | fclose($fp); |
252 | }
|
252 | }
|
253 | if (!class_exists('PEAR_ChannelFile')) { |
253 | if (!class_exists('PEAR_ChannelFile')) { |
254 | require_once 'PEAR/ChannelFile.php'; |
254 | require_once 'PEAR/ChannelFile.php'; |
255 | }
|
255 | }
|
256 | $chan = new PEAR_ChannelFile; |
256 | $chan = new PEAR_ChannelFile; |
257 | $chan->fromXmlString($contents); |
257 | $chan->fromXmlString($contents); |
258 | $chan->validate(); |
258 | $chan->validate(); |
259 | if ($errs = $chan->getErrors(true)) { |
259 | if ($errs = $chan->getErrors(true)) { |
260 | foreach ($errs as $err) { |
260 | foreach ($errs as $err) { |
261 | $this->ui->outputData($err['level'] . ': ' . $err['message']); |
261 | $this->ui->outputData($err['level'] . ': ' . $err['message']); |
262 | }
|
262 | }
|
263 | return $this->raiseError('Channel file "' . $params[0] . '" is not valid'); |
263 | return $this->raiseError('Channel file "' . $params[0] . '" is not valid'); |
264 | }
|
264 | }
|
265 | }
|
265 | }
|
266 | if ($chan) { |
266 | if ($chan) { |
267 | $channel = $chan->getName(); |
267 | $channel = $chan->getName(); |
268 | $caption = 'Channel ' . $channel . ' Information:'; |
268 | $caption = 'Channel ' . $channel . ' Information:'; |
269 | $data1 = array( |
269 | $data1 = array( |
270 | 'caption' => $caption, |
270 | 'caption' => $caption, |
271 | 'border' => true); |
271 | 'border' => true); |
272 | $data1['data']['server'] = array('Name and Server', $chan->getName()); |
272 | $data1['data']['server'] = array('Name and Server', $chan->getName()); |
273 | if ($chan->getAlias() != $chan->getName()) { |
273 | if ($chan->getAlias() != $chan->getName()) { |
274 | $data1['data']['alias'] = array('Alias', $chan->getAlias()); |
274 | $data1['data']['alias'] = array('Alias', $chan->getAlias()); |
275 | }
|
275 | }
|
276 | $data1['data']['summary'] = array('Summary', $chan->getSummary()); |
276 | $data1['data']['summary'] = array('Summary', $chan->getSummary()); |
277 | $validate = $chan->getValidationPackage(); |
277 | $validate = $chan->getValidationPackage(); |
278 | $data1['data']['vpackage'] = array('Validation Package Name', $validate['_content']); |
278 | $data1['data']['vpackage'] = array('Validation Package Name', $validate['_content']); |
279 | $data1['data']['vpackageversion'] = |
279 | $data1['data']['vpackageversion'] = |
280 | array('Validation Package Version', $validate['attribs']['version']); |
280 | array('Validation Package Version', $validate['attribs']['version']); |
281 | $d = array(); |
281 | $d = array(); |
282 | $d['main'] = $data1; |
282 | $d['main'] = $data1; |
283 | 283 | ||
284 | $data['data'] = array(); |
284 | $data['data'] = array(); |
285 | $data['caption'] = 'Server Capabilities'; |
285 | $data['caption'] = 'Server Capabilities'; |
286 | $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base'); |
286 | $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base'); |
287 | $capabilities = $chan->getFunctions('xmlrpc'); |
287 | $capabilities = $chan->getFunctions('xmlrpc'); |
288 | $soaps = $chan->getFunctions('soap'); |
288 | $soaps = $chan->getFunctions('soap'); |
289 | if ($capabilities || $soaps || $chan->supportsREST()) { |
289 | if ($capabilities || $soaps || $chan->supportsREST()) { |
290 | if ($capabilities) { |
290 | if ($capabilities) { |
291 | if (!isset($capabilities[0])) { |
291 | if (!isset($capabilities[0])) { |
292 | $capabilities = array($capabilities); |
292 | $capabilities = array($capabilities); |
293 | }
|
293 | }
|
294 | foreach ($capabilities as $protocol) { |
294 | foreach ($capabilities as $protocol) { |
295 | $data['data'][] = array('xmlrpc', $protocol['attribs']['version'], |
295 | $data['data'][] = array('xmlrpc', $protocol['attribs']['version'], |
296 | $protocol['_content']); |
296 | $protocol['_content']); |
297 | }
|
297 | }
|
298 | }
|
298 | }
|
299 | if ($soaps) { |
299 | if ($soaps) { |
300 | if (!isset($soaps[0])) { |
300 | if (!isset($soaps[0])) { |
301 | $soaps = array($soaps); |
301 | $soaps = array($soaps); |
302 | }
|
302 | }
|
303 | foreach ($soaps as $protocol) { |
303 | foreach ($soaps as $protocol) { |
304 | $data['data'][] = array('soap', $protocol['attribs']['version'], |
304 | $data['data'][] = array('soap', $protocol['attribs']['version'], |
305 | $protocol['_content']); |
305 | $protocol['_content']); |
306 | }
|
306 | }
|
307 | }
|
307 | }
|
308 | if ($chan->supportsREST()) { |
308 | if ($chan->supportsREST()) { |
309 | $funcs = $chan->getFunctions('rest'); |
309 | $funcs = $chan->getFunctions('rest'); |
310 | if (!isset($funcs[0])) { |
310 | if (!isset($funcs[0])) { |
311 | $funcs = array($funcs); |
311 | $funcs = array($funcs); |
312 | }
|
312 | }
|
313 | foreach ($funcs as $protocol) { |
313 | foreach ($funcs as $protocol) { |
314 | $data['data'][] = array('rest', $protocol['attribs']['type'], |
314 | $data['data'][] = array('rest', $protocol['attribs']['type'], |
315 | $protocol['_content']); |
315 | $protocol['_content']); |
316 | }
|
316 | }
|
317 | }
|
317 | }
|
318 | } else { |
318 | } else { |
319 | $data['data'][] = array('No supported protocols'); |
319 | $data['data'][] = array('No supported protocols'); |
320 | }
|
320 | }
|
321 | $d['protocols'] = $data; |
321 | $d['protocols'] = $data; |
322 | $data['data'] = array(); |
322 | $data['data'] = array(); |
323 | $mirrors = $chan->getMirrors(); |
323 | $mirrors = $chan->getMirrors(); |
324 | if ($mirrors) { |
324 | if ($mirrors) { |
325 | $data['caption'] = 'Channel ' . $channel . ' Mirrors:'; |
325 | $data['caption'] = 'Channel ' . $channel . ' Mirrors:'; |
326 | unset($data['headline']); |
326 | unset($data['headline']); |
327 | foreach ($mirrors as $mirror) { |
327 | foreach ($mirrors as $mirror) { |
328 | $data['data'][] = array($mirror['attribs']['host']); |
328 | $data['data'][] = array($mirror['attribs']['host']); |
329 | $d['mirrors'] = $data; |
329 | $d['mirrors'] = $data; |
330 | }
|
330 | }
|
331 | foreach ($mirrors as $i => $mirror) { |
331 | foreach ($mirrors as $i => $mirror) { |
332 | $data['data'] = array(); |
332 | $data['data'] = array(); |
333 | $data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities'; |
333 | $data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities'; |
334 | $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base'); |
334 | $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base'); |
335 | $capabilities = $chan->getFunctions('xmlrpc', $mirror['attribs']['host']); |
335 | $capabilities = $chan->getFunctions('xmlrpc', $mirror['attribs']['host']); |
336 | $soaps = $chan->getFunctions('soap', $mirror['attribs']['host']); |
336 | $soaps = $chan->getFunctions('soap', $mirror['attribs']['host']); |
337 | if ($capabilities || $soaps || $chan->supportsREST($mirror['attribs']['host'])) { |
337 | if ($capabilities || $soaps || $chan->supportsREST($mirror['attribs']['host'])) { |
338 | if ($capabilities) { |
338 | if ($capabilities) { |
339 | if (!isset($capabilities[0])) { |
339 | if (!isset($capabilities[0])) { |
340 | $capabilities = array($capabilities); |
340 | $capabilities = array($capabilities); |
341 | }
|
341 | }
|
342 | foreach ($capabilities as $protocol) { |
342 | foreach ($capabilities as $protocol) { |
343 | $data['data'][] = array('xmlrpc', $protocol['attribs']['version'], |
343 | $data['data'][] = array('xmlrpc', $protocol['attribs']['version'], |
344 | $protocol['_content']); |
344 | $protocol['_content']); |
345 | }
|
345 | }
|
346 | }
|
346 | }
|
347 | if ($soaps) { |
347 | if ($soaps) { |
348 | if (!isset($soaps[0])) { |
348 | if (!isset($soaps[0])) { |
349 | $soaps = array($soaps); |
349 | $soaps = array($soaps); |
350 | }
|
350 | }
|
351 | foreach ($soaps as $protocol) { |
351 | foreach ($soaps as $protocol) { |
352 | $data['data'][] = array('soap', $protocol['attribs']['version'], |
352 | $data['data'][] = array('soap', $protocol['attribs']['version'], |
353 | $protocol['_content']); |
353 | $protocol['_content']); |
354 | }
|
354 | }
|
355 | }
|
355 | }
|
356 | if ($chan->supportsREST($mirror['attribs']['host'])) { |
356 | if ($chan->supportsREST($mirror['attribs']['host'])) { |
357 | $funcs = $chan->getFunctions('rest', $mirror['attribs']['host']); |
357 | $funcs = $chan->getFunctions('rest', $mirror['attribs']['host']); |
358 | if (!isset($funcs[0])) { |
358 | if (!isset($funcs[0])) { |
359 | $funcs = array($funcs); |
359 | $funcs = array($funcs); |
360 | }
|
360 | }
|
361 | foreach ($funcs as $protocol) { |
361 | foreach ($funcs as $protocol) { |
362 | $data['data'][] = array('rest', $protocol['attribs']['type'], |
362 | $data['data'][] = array('rest', $protocol['attribs']['type'], |
363 | $protocol['_content']); |
363 | $protocol['_content']); |
364 | }
|
364 | }
|
365 | }
|
365 | }
|
366 | } else { |
366 | } else { |
367 | $data['data'][] = array('No supported protocols'); |
367 | $data['data'][] = array('No supported protocols'); |
368 | }
|
368 | }
|
369 | $d['mirrorprotocols' . $i] = $data; |
369 | $d['mirrorprotocols' . $i] = $data; |
370 | }
|
370 | }
|
371 | }
|
371 | }
|
372 | $this->ui->outputData($d, 'channel-info'); |
372 | $this->ui->outputData($d, 'channel-info'); |
373 | } else { |
373 | } else { |
374 | return $this->raiseError('Serious error: Channel "' . $params[0] . |
374 | return $this->raiseError('Serious error: Channel "' . $params[0] . |
375 | '" has a corrupted registry entry'); |
375 | '" has a corrupted registry entry'); |
376 | }
|
376 | }
|
377 | }
|
377 | }
|
378 | 378 | ||
379 | // }}}
|
379 | // }}}
|
380 | 380 | ||
381 | function doDelete($command, $options, $params) |
381 | function doDelete($command, $options, $params) |
382 | {
|
382 | {
|
383 | if (sizeof($params) != 1) { |
383 | if (sizeof($params) != 1) { |
384 | return $this->raiseError('channel-delete: no channel specified'); |
384 | return $this->raiseError('channel-delete: no channel specified'); |
385 | }
|
385 | }
|
386 | $reg = &$this->config->getRegistry(); |
386 | $reg = &$this->config->getRegistry(); |
387 | if (!$reg->channelExists($params[0])) { |
387 | if (!$reg->channelExists($params[0])) { |
388 | return $this->raiseError('channel-delete: channel "' . $params[0] . '" does not exist'); |
388 | return $this->raiseError('channel-delete: channel "' . $params[0] . '" does not exist'); |
389 | }
|
389 | }
|
390 | $channel = $reg->channelName($params[0]); |
390 | $channel = $reg->channelName($params[0]); |
391 | if ($channel == 'pear.php.net') { |
391 | if ($channel == 'pear.php.net') { |
392 | return $this->raiseError('Cannot delete the pear.php.net channel'); |
392 | return $this->raiseError('Cannot delete the pear.php.net channel'); |
393 | }
|
393 | }
|
394 | if ($channel == 'pecl.php.net') { |
394 | if ($channel == 'pecl.php.net') { |
395 | return $this->raiseError('Cannot delete the pecl.php.net channel'); |
395 | return $this->raiseError('Cannot delete the pecl.php.net channel'); |
396 | }
|
396 | }
|
397 | if ($channel == '__uri') { |
397 | if ($channel == '__uri') { |
398 | return $this->raiseError('Cannot delete the __uri pseudo-channel'); |
398 | return $this->raiseError('Cannot delete the __uri pseudo-channel'); |
399 | }
|
399 | }
|
400 | if (PEAR::isError($err = $reg->listPackages($channel))) { |
400 | if (PEAR::isError($err = $reg->listPackages($channel))) { |
401 | return $err; |
401 | return $err; |
402 | }
|
402 | }
|
403 | if (count($err)) { |
403 | if (count($err)) { |
404 | return $this->raiseError('Channel "' . $channel . |
404 | return $this->raiseError('Channel "' . $channel . |
405 | '" has installed packages, cannot delete'); |
405 | '" has installed packages, cannot delete'); |
406 | }
|
406 | }
|
407 | if (!$reg->deleteChannel($channel)) { |
407 | if (!$reg->deleteChannel($channel)) { |
408 | return $this->raiseError('Channel "' . $channel . '" deletion failed'); |
408 | return $this->raiseError('Channel "' . $channel . '" deletion failed'); |
409 | } else { |
409 | } else { |
410 | $this->config->deleteChannel($channel); |
410 | $this->config->deleteChannel($channel); |
411 | $this->ui->outputData('Channel "' . $channel . '" deleted', $command); |
411 | $this->ui->outputData('Channel "' . $channel . '" deleted', $command); |
412 | }
|
412 | }
|
413 | }
|
413 | }
|
414 | 414 | ||
415 | function doAdd($command, $options, $params) |
415 | function doAdd($command, $options, $params) |
416 | {
|
416 | {
|
417 | if (sizeof($params) != 1) { |
417 | if (sizeof($params) != 1) { |
418 | return $this->raiseError('channel-add: no channel file specified'); |
418 | return $this->raiseError('channel-add: no channel file specified'); |
419 | }
|
419 | }
|
420 | if (strpos($params[0], '://')) { |
420 | if (strpos($params[0], '://')) { |
421 | $downloader = &$this->getDownloader(); |
421 | $downloader = &$this->getDownloader(); |
422 | $tmpdir = $this->config->get('temp_dir'); |
422 | $tmpdir = $this->config->get('temp_dir'); |
423 | if (!file_exists($tmpdir)) { |
423 | if (!file_exists($tmpdir)) { |
424 | require_once 'System.php'; |
424 | require_once 'System.php'; |
425 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
425 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
426 | $err = System::mkdir(array('-p', $tmpdir)); |
426 | $err = System::mkdir(array('-p', $tmpdir)); |
427 | PEAR::staticPopErrorHandling(); |
427 | PEAR::staticPopErrorHandling(); |
428 | if (PEAR::isError($err)) { |
428 | if (PEAR::isError($err)) { |
429 | return $this->raiseError('channel-add: temp_dir does not exist: "' . |
429 | return $this->raiseError('channel-add: temp_dir does not exist: "' . |
430 | $tmpdir . |
430 | $tmpdir . |
431 | '" - You can change this location with "pear config-set temp_dir"'); |
431 | '" - You can change this location with "pear config-set temp_dir"'); |
432 | }
|
432 | }
|
433 | }
|
433 | }
|
434 | if (!is_writable($tmpdir)) { |
434 | if (!is_writable($tmpdir)) { |
435 | return $this->raiseError('channel-add: temp_dir is not writable: "' . |
435 | return $this->raiseError('channel-add: temp_dir is not writable: "' . |
436 | $tmpdir . |
436 | $tmpdir . |
437 | '" - You can change this location with "pear config-set temp_dir"'); |
437 | '" - You can change this location with "pear config-set temp_dir"'); |
438 | }
|
438 | }
|
439 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
439 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
440 | $loc = $downloader->downloadHttp($params[0], $this->ui, $tmpdir, null, false); |
440 | $loc = $downloader->downloadHttp($params[0], $this->ui, $tmpdir, null, false); |
441 | PEAR::staticPopErrorHandling(); |
441 | PEAR::staticPopErrorHandling(); |
442 | if (PEAR::isError($loc)) { |
442 | if (PEAR::isError($loc)) { |
443 | return $this->raiseError('channel-add: Cannot open "' . $params[0] . |
443 | return $this->raiseError('channel-add: Cannot open "' . $params[0] . |
444 | '" (' . $loc->getMessage() . ')'); |
444 | '" (' . $loc->getMessage() . ')'); |
445 | } else { |
445 | } else { |
446 | list($loc, $lastmodified) = $loc; |
446 | list($loc, $lastmodified) = $loc; |
447 | $contents = implode('', file($loc)); |
447 | $contents = implode('', file($loc)); |
448 | }
|
448 | }
|
449 | } else { |
449 | } else { |
450 | $lastmodified = $fp = false; |
450 | $lastmodified = $fp = false; |
451 | if (file_exists($params[0])) { |
451 | if (file_exists($params[0])) { |
452 | $fp = fopen($params[0], 'r'); |
452 | $fp = fopen($params[0], 'r'); |
453 | }
|
453 | }
|
454 | if (!$fp) { |
454 | if (!$fp) { |
455 | return $this->raiseError('channel-add: cannot open "' . $params[0] . '"'); |
455 | return $this->raiseError('channel-add: cannot open "' . $params[0] . '"'); |
456 | }
|
456 | }
|
457 | $contents = ''; |
457 | $contents = ''; |
458 | while (!feof($fp)) { |
458 | while (!feof($fp)) { |
459 | $contents .= fread($fp, 1024); |
459 | $contents .= fread($fp, 1024); |
460 | }
|
460 | }
|
461 | fclose($fp); |
461 | fclose($fp); |
462 | }
|
462 | }
|
463 | if (!class_exists('PEAR_ChannelFile')) { |
463 | if (!class_exists('PEAR_ChannelFile')) { |
464 | require_once 'PEAR/ChannelFile.php'; |
464 | require_once 'PEAR/ChannelFile.php'; |
465 | }
|
465 | }
|
466 | $channel = new PEAR_ChannelFile; |
466 | $channel = new PEAR_ChannelFile; |
467 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
467 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
468 | $result = $channel->fromXmlString($contents); |
468 | $result = $channel->fromXmlString($contents); |
469 | PEAR::staticPopErrorHandling(); |
469 | PEAR::staticPopErrorHandling(); |
470 | if (!$result) { |
470 | if (!$result) { |
471 | $exit = false; |
471 | $exit = false; |
472 | if (count($errors = $channel->getErrors(true))) { |
472 | if (count($errors = $channel->getErrors(true))) { |
473 | foreach ($errors as $error) { |
473 | foreach ($errors as $error) { |
474 | $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message'])); |
474 | $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message'])); |
475 | if (!$exit) { |
475 | if (!$exit) { |
476 | $exit = $error['level'] == 'error' ? true : false; |
476 | $exit = $error['level'] == 'error' ? true : false; |
477 | }
|
477 | }
|
478 | }
|
478 | }
|
479 | if ($exit) { |
479 | if ($exit) { |
480 | return $this->raiseError('channel-add: invalid channel.xml file'); |
480 | return $this->raiseError('channel-add: invalid channel.xml file'); |
481 | }
|
481 | }
|
482 | }
|
482 | }
|
483 | }
|
483 | }
|
484 | $reg = &$this->config->getRegistry(); |
484 | $reg = &$this->config->getRegistry(); |
485 | if ($reg->channelExists($channel->getName())) { |
485 | if ($reg->channelExists($channel->getName())) { |
486 | return $this->raiseError('channel-add: Channel "' . $channel->getName() . |
486 | return $this->raiseError('channel-add: Channel "' . $channel->getName() . |
487 | '" exists, use channel-update to update entry'); |
487 | '" exists, use channel-update to update entry'); |
488 | }
|
488 | }
|
489 | $ret = $reg->addChannel($channel, $lastmodified); |
489 | $ret = $reg->addChannel($channel, $lastmodified); |
490 | if (PEAR::isError($ret)) { |
490 | if (PEAR::isError($ret)) { |
491 | return $ret; |
491 | return $ret; |
492 | }
|
492 | }
|
493 | if (!$ret) { |
493 | if (!$ret) { |
494 | return $this->raiseError('channel-add: adding Channel "' . $channel->getName() . |
494 | return $this->raiseError('channel-add: adding Channel "' . $channel->getName() . |
495 | '" to registry failed'); |
495 | '" to registry failed'); |
496 | }
|
496 | }
|
497 | $this->config->setChannels($reg->listChannels()); |
497 | $this->config->setChannels($reg->listChannels()); |
498 | $this->config->writeConfigFile(); |
498 | $this->config->writeConfigFile(); |
499 | $this->ui->outputData('Adding Channel "' . $channel->getName() . '" succeeded', $command); |
499 | $this->ui->outputData('Adding Channel "' . $channel->getName() . '" succeeded', $command); |
500 | }
|
500 | }
|
501 | 501 | ||
502 | function doUpdate($command, $options, $params) |
502 | function doUpdate($command, $options, $params) |
503 | {
|
503 | {
|
504 | $tmpdir = $this->config->get('temp_dir'); |
504 | $tmpdir = $this->config->get('temp_dir'); |
505 | if (!file_exists($tmpdir)) { |
505 | if (!file_exists($tmpdir)) { |
506 | require_once 'System.php'; |
506 | require_once 'System.php'; |
507 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
507 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
508 | $err = System::mkdir(array('-p', $tmpdir)); |
508 | $err = System::mkdir(array('-p', $tmpdir)); |
509 | PEAR::staticPopErrorHandling(); |
509 | PEAR::staticPopErrorHandling(); |
510 | if (PEAR::isError($err)) { |
510 | if (PEAR::isError($err)) { |
511 | return $this->raiseError('channel-add: temp_dir does not exist: "' . |
511 | return $this->raiseError('channel-add: temp_dir does not exist: "' . |
512 | $tmpdir . |
512 | $tmpdir . |
513 | '" - You can change this location with "pear config-set temp_dir"'); |
513 | '" - You can change this location with "pear config-set temp_dir"'); |
514 | }
|
514 | }
|
515 | }
|
515 | }
|
516 | if (!is_writable($tmpdir)) { |
516 | if (!is_writable($tmpdir)) { |
517 | return $this->raiseError('channel-add: temp_dir is not writable: "' . |
517 | return $this->raiseError('channel-add: temp_dir is not writable: "' . |
518 | $tmpdir . |
518 | $tmpdir . |
519 | '" - You can change this location with "pear config-set temp_dir"'); |
519 | '" - You can change this location with "pear config-set temp_dir"'); |
520 | }
|
520 | }
|
521 | $reg = &$this->config->getRegistry(); |
521 | $reg = &$this->config->getRegistry(); |
522 | if (sizeof($params) != 1) { |
522 | if (sizeof($params) != 1) { |
523 | return $this->raiseError("No channel file specified"); |
523 | return $this->raiseError("No channel file specified"); |
524 | }
|
524 | }
|
525 | $lastmodified = false; |
525 | $lastmodified = false; |
526 | if ((!file_exists($params[0]) || is_dir($params[0])) |
526 | if ((!file_exists($params[0]) || is_dir($params[0])) |
527 | && $reg->channelExists(strtolower($params[0]))) { |
527 | && $reg->channelExists(strtolower($params[0]))) { |
528 | $c = $reg->getChannel(strtolower($params[0])); |
528 | $c = $reg->getChannel(strtolower($params[0])); |
529 | if (PEAR::isError($c)) { |
529 | if (PEAR::isError($c)) { |
530 | return $this->raiseError($c); |
530 | return $this->raiseError($c); |
531 | }
|
531 | }
|
532 | $this->ui->outputData("Updating channel \"$params[0]\"", $command); |
532 | $this->ui->outputData("Updating channel \"$params[0]\"", $command); |
533 | $dl = &$this->getDownloader(array()); |
533 | $dl = &$this->getDownloader(array()); |
534 | // if force is specified, use a timestamp of "1" to force retrieval
|
534 | // if force is specified, use a timestamp of "1" to force retrieval
|
535 | $lastmodified = isset($options['force']) ? false : $c->lastModified(); |
535 | $lastmodified = isset($options['force']) ? false : $c->lastModified(); |
536 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
536 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
537 | $contents = $dl->downloadHttp('http://' . $c->getName() . '/channel.xml', |
537 | $contents = $dl->downloadHttp('http://' . $c->getName() . '/channel.xml', |
538 | $this->ui, $tmpdir, null, $lastmodified); |
538 | $this->ui, $tmpdir, null, $lastmodified); |
539 | PEAR::staticPopErrorHandling(); |
539 | PEAR::staticPopErrorHandling(); |
540 | if (PEAR::isError($contents)) { |
540 | if (PEAR::isError($contents)) { |
541 | return $this->raiseError('Cannot retrieve channel.xml for channel "' . |
541 | return $this->raiseError('Cannot retrieve channel.xml for channel "' . |
542 | $c->getName() . '" (' . $contents->getMessage() . ')'); |
542 | $c->getName() . '" (' . $contents->getMessage() . ')'); |
543 | }
|
543 | }
|
544 | list($contents, $lastmodified) = $contents; |
544 | list($contents, $lastmodified) = $contents; |
545 | if (!$contents) { |
545 | if (!$contents) { |
546 | $this->ui->outputData("Channel \"$params[0]\" is up to date"); |
546 | $this->ui->outputData("Channel \"$params[0]\" is up to date"); |
547 | return; |
547 | return; |
548 | }
|
548 | }
|
549 | $contents = implode('', file($contents)); |
549 | $contents = implode('', file($contents)); |
550 | if (!class_exists('PEAR_ChannelFile')) { |
550 | if (!class_exists('PEAR_ChannelFile')) { |
551 | require_once 'PEAR/ChannelFile.php'; |
551 | require_once 'PEAR/ChannelFile.php'; |
552 | }
|
552 | }
|
553 | $channel = new PEAR_ChannelFile; |
553 | $channel = new PEAR_ChannelFile; |
554 | $channel->fromXmlString($contents); |
554 | $channel->fromXmlString($contents); |
555 | if (!$channel->getErrors()) { |
555 | if (!$channel->getErrors()) { |
556 | // security check: is the downloaded file for the channel we got it from?
|
556 | // security check: is the downloaded file for the channel we got it from?
|
557 | if (strtolower($channel->getName()) != strtolower($c->getName())) { |
557 | if (strtolower($channel->getName()) != strtolower($c->getName())) { |
558 | if (isset($options['force'])) { |
558 | if (isset($options['force'])) { |
559 | $this->ui->log(0, 'WARNING: downloaded channel definition file' . |
559 | $this->ui->log(0, 'WARNING: downloaded channel definition file' . |
560 | ' for channel "' . $channel->getName() . '" from channel "' . |
560 | ' for channel "' . $channel->getName() . '" from channel "' . |
561 | strtolower($c->getName()) . '"'); |
561 | strtolower($c->getName()) . '"'); |
562 | } else { |
562 | } else { |
563 | return $this->raiseError('ERROR: downloaded channel definition file' . |
563 | return $this->raiseError('ERROR: downloaded channel definition file' . |
564 | ' for channel "' . $channel->getName() . '" from channel "' . |
564 | ' for channel "' . $channel->getName() . '" from channel "' . |
565 | strtolower($c->getName()) . '"'); |
565 | strtolower($c->getName()) . '"'); |
566 | }
|
566 | }
|
567 | }
|
567 | }
|
568 | }
|
568 | }
|
569 | } else { |
569 | } else { |
570 | if (strpos($params[0], '://')) { |
570 | if (strpos($params[0], '://')) { |
571 | $dl = &$this->getDownloader(); |
571 | $dl = &$this->getDownloader(); |
572 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
572 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
573 | $loc = $dl->downloadHttp($params[0], |
573 | $loc = $dl->downloadHttp($params[0], |
574 | $this->ui, $tmpdir, null, $lastmodified); |
574 | $this->ui, $tmpdir, null, $lastmodified); |
575 | PEAR::staticPopErrorHandling(); |
575 | PEAR::staticPopErrorHandling(); |
576 | if (PEAR::isError($loc)) { |
576 | if (PEAR::isError($loc)) { |
577 | return $this->raiseError("Cannot open " . $params[0] . |
577 | return $this->raiseError("Cannot open " . $params[0] . |
578 | ' (' . $loc->getMessage() . ')'); |
578 | ' (' . $loc->getMessage() . ')'); |
579 | } else { |
579 | } else { |
580 | list($loc, $lastmodified) = $loc; |
580 | list($loc, $lastmodified) = $loc; |
581 | $contents = implode('', file($loc)); |
581 | $contents = implode('', file($loc)); |
582 | }
|
582 | }
|
583 | } else { |
583 | } else { |
584 | $fp = false; |
584 | $fp = false; |
585 | if (file_exists($params[0])) { |
585 | if (file_exists($params[0])) { |
586 | $fp = fopen($params[0], 'r'); |
586 | $fp = fopen($params[0], 'r'); |
587 | }
|
587 | }
|
588 | if (!$fp) { |
588 | if (!$fp) { |
589 | return $this->raiseError("Cannot open " . $params[0]); |
589 | return $this->raiseError("Cannot open " . $params[0]); |
590 | }
|
590 | }
|
591 | $contents = ''; |
591 | $contents = ''; |
592 | while (!feof($fp)) { |
592 | while (!feof($fp)) { |
593 | $contents .= fread($fp, 1024); |
593 | $contents .= fread($fp, 1024); |
594 | }
|
594 | }
|
595 | fclose($fp); |
595 | fclose($fp); |
596 | }
|
596 | }
|
597 | if (!class_exists('PEAR_ChannelFile')) { |
597 | if (!class_exists('PEAR_ChannelFile')) { |
598 | require_once 'PEAR/ChannelFile.php'; |
598 | require_once 'PEAR/ChannelFile.php'; |
599 | }
|
599 | }
|
600 | $channel = new PEAR_ChannelFile; |
600 | $channel = new PEAR_ChannelFile; |
601 | $channel->fromXmlString($contents); |
601 | $channel->fromXmlString($contents); |
602 | }
|
602 | }
|
603 | $exit = false; |
603 | $exit = false; |
604 | if (count($errors = $channel->getErrors(true))) { |
604 | if (count($errors = $channel->getErrors(true))) { |
605 | foreach ($errors as $error) { |
605 | foreach ($errors as $error) { |
606 | $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message'])); |
606 | $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message'])); |
607 | if (!$exit) { |
607 | if (!$exit) { |
608 | $exit = $error['level'] == 'error' ? true : false; |
608 | $exit = $error['level'] == 'error' ? true : false; |
609 | }
|
609 | }
|
610 | }
|
610 | }
|
611 | if ($exit) { |
611 | if ($exit) { |
612 | return $this->raiseError('Invalid channel.xml file'); |
612 | return $this->raiseError('Invalid channel.xml file'); |
613 | }
|
613 | }
|
614 | }
|
614 | }
|
615 | if (!$reg->channelExists($channel->getName())) { |
615 | if (!$reg->channelExists($channel->getName())) { |
616 | return $this->raiseError('Error: Channel "' . $channel->getName() . |
616 | return $this->raiseError('Error: Channel "' . $channel->getName() . |
617 | '" does not exist, use channel-add to add an entry'); |
617 | '" does not exist, use channel-add to add an entry'); |
618 | }
|
618 | }
|
619 | $ret = $reg->updateChannel($channel, $lastmodified); |
619 | $ret = $reg->updateChannel($channel, $lastmodified); |
620 | if (PEAR::isError($ret)) { |
620 | if (PEAR::isError($ret)) { |
621 | return $ret; |
621 | return $ret; |
622 | }
|
622 | }
|
623 | if (!$ret) { |
623 | if (!$ret) { |
624 | return $this->raiseError('Updating Channel "' . $channel->getName() . |
624 | return $this->raiseError('Updating Channel "' . $channel->getName() . |
625 | '" in registry failed'); |
625 | '" in registry failed'); |
626 | }
|
626 | }
|
627 | $this->config->setChannels($reg->listChannels()); |
627 | $this->config->setChannels($reg->listChannels()); |
628 | $this->config->writeConfigFile(); |
628 | $this->config->writeConfigFile(); |
629 | $this->ui->outputData('Update of Channel "' . $channel->getName() . '" succeeded'); |
629 | $this->ui->outputData('Update of Channel "' . $channel->getName() . '" succeeded'); |
630 | }
|
630 | }
|
631 | 631 | ||
632 | function &getDownloader() |
632 | function &getDownloader() |
633 | {
|
633 | {
|
634 | if (!class_exists('PEAR_Downloader')) { |
634 | if (!class_exists('PEAR_Downloader')) { |
635 | require_once 'PEAR/Downloader.php'; |
635 | require_once 'PEAR/Downloader.php'; |
636 | }
|
636 | }
|
637 | $a = new PEAR_Downloader($this->ui, array(), $this->config); |
637 | $a = new PEAR_Downloader($this->ui, array(), $this->config); |
638 | return $a; |
638 | return $a; |
639 | }
|
639 | }
|
640 | 640 | ||
641 | function doAlias($command, $options, $params) |
641 | function doAlias($command, $options, $params) |
642 | {
|
642 | {
|
643 | $reg = &$this->config->getRegistry(); |
643 | $reg = &$this->config->getRegistry(); |
644 | if (sizeof($params) == 1) { |
644 | if (sizeof($params) == 1) { |
645 | return $this->raiseError('No channel alias specified'); |
645 | return $this->raiseError('No channel alias specified'); |
646 | }
|
646 | }
|
647 | if (sizeof($params) != 2) { |
647 | if (sizeof($params) != 2) { |
648 | return $this->raiseError( |
648 | return $this->raiseError( |
649 | 'Invalid format, correct is: channel-alias channel alias'); |
649 | 'Invalid format, correct is: channel-alias channel alias'); |
650 | }
|
650 | }
|
651 | if (!$reg->channelExists($params[0], true)) { |
651 | if (!$reg->channelExists($params[0], true)) { |
652 | if ($reg->isAlias($params[0])) { |
652 | if ($reg->isAlias($params[0])) { |
653 | $extra = ' (use "channel-alias ' . $reg->channelName($params[0]) . ' ' . |
653 | $extra = ' (use "channel-alias ' . $reg->channelName($params[0]) . ' ' . |
654 | strtolower($params[1]) . '")'; |
654 | strtolower($params[1]) . '")'; |
655 | } else { |
655 | } else { |
656 | $extra = ''; |
656 | $extra = ''; |
657 | }
|
657 | }
|
658 | return $this->raiseError('"' . $params[0] . '" is not a valid channel' . $extra); |
658 | return $this->raiseError('"' . $params[0] . '" is not a valid channel' . $extra); |
659 | }
|
659 | }
|
660 | if ($reg->isAlias($params[1])) { |
660 | if ($reg->isAlias($params[1])) { |
661 | return $this->raiseError('Channel "' . $reg->channelName($params[1]) . '" is ' . |
661 | return $this->raiseError('Channel "' . $reg->channelName($params[1]) . '" is ' . |
662 | 'already aliased to "' . strtolower($params[1]) . '", cannot re-alias'); |
662 | 'already aliased to "' . strtolower($params[1]) . '", cannot re-alias'); |
663 | }
|
663 | }
|
664 | $chan = &$reg->getChannel($params[0]); |
664 | $chan = &$reg->getChannel($params[0]); |
665 | if (PEAR::isError($chan)) { |
665 | if (PEAR::isError($chan)) { |
666 | return $this->raiseError('Corrupt registry? Error retrieving channel "' . $params[0] . |
666 | return $this->raiseError('Corrupt registry? Error retrieving channel "' . $params[0] . |
667 | '" information (' . $chan->getMessage() . ')'); |
667 | '" information (' . $chan->getMessage() . ')'); |
668 | }
|
668 | }
|
669 | // make it a local alias
|
669 | // make it a local alias
|
670 | if (!$chan->setAlias(strtolower($params[1]), true)) { |
670 | if (!$chan->setAlias(strtolower($params[1]), true)) { |
671 | return $this->raiseError('Alias "' . strtolower($params[1]) . |
671 | return $this->raiseError('Alias "' . strtolower($params[1]) . |
672 | '" is not a valid channel alias'); |
672 | '" is not a valid channel alias'); |
673 | }
|
673 | }
|
674 | $reg->updateChannel($chan); |
674 | $reg->updateChannel($chan); |
675 | $this->ui->outputData('Channel "' . $chan->getName() . '" aliased successfully to "' . |
675 | $this->ui->outputData('Channel "' . $chan->getName() . '" aliased successfully to "' . |
676 | strtolower($params[1]) . '"'); |
676 | strtolower($params[1]) . '"'); |
677 | }
|
677 | }
|
678 | 678 | ||
679 | /**
|
679 | /**
|
680 | * The channel-discover command
|
680 | * The channel-discover command
|
681 | *
|
681 | *
|
682 | * @param string $command command name
|
682 | * @param string $command command name
|
683 | * @param array $options option_name => value
|
683 | * @param array $options option_name => value
|
684 | * @param array $params list of additional parameters.
|
684 | * @param array $params list of additional parameters.
|
685 | * $params[0] should contain a string with either:
|
685 | * $params[0] should contain a string with either:
|
686 | * - <channel name> or
|
686 | * - <channel name> or
|
687 | * - <username>:<password>@<channel name>
|
687 | * - <username>:<password>@<channel name>
|
688 | * @return null|PEAR_Error
|
688 | * @return null|PEAR_Error
|
689 | */
|
689 | */
|
690 | function doDiscover($command, $options, $params) |
690 | function doDiscover($command, $options, $params) |
691 | {
|
691 | {
|
692 | $reg = &$this->config->getRegistry(); |
692 | $reg = &$this->config->getRegistry(); |
693 | if (sizeof($params) != 1) { |
693 | if (sizeof($params) != 1) { |
694 | return $this->raiseError("No channel server specified"); |
694 | return $this->raiseError("No channel server specified"); |
695 | }
|
695 | }
|
696 | 696 | ||
697 | // Look for the possible input format "<username>:<password>@<channel>"
|
697 | // Look for the possible input format "<username>:<password>@<channel>"
|
698 | if (preg_match('/^(.+):(.+)@(.+)\\z/', $params[0], $matches)) { |
698 | if (preg_match('/^(.+):(.+)@(.+)\\z/', $params[0], $matches)) { |
699 | $username = $matches[1]; |
699 | $username = $matches[1]; |
700 | $password = $matches[2]; |
700 | $password = $matches[2]; |
701 | $channel = $matches[3]; |
701 | $channel = $matches[3]; |
702 | } else { |
702 | } else { |
703 | $channel = $params[0]; |
703 | $channel = $params[0]; |
704 | }
|
704 | }
|
705 | 705 | ||
706 | if ($reg->channelExists($channel)) { |
706 | if ($reg->channelExists($channel)) { |
707 | if ($reg->isAlias($channel)) { |
707 | if ($reg->isAlias($channel)) { |
708 | return $this->raiseError("A channel alias named \"$channel\" " . |
708 | return $this->raiseError("A channel alias named \"$channel\" " . |
709 | 'already exists, aliasing channel "' . $reg->channelName($channel) |
709 | 'already exists, aliasing channel "' . $reg->channelName($channel) |
710 | . '"'); |
710 | . '"'); |
711 | } else { |
711 | } else { |
712 | return $this->raiseError("Channel \"$channel\" is already initialized"); |
712 | return $this->raiseError("Channel \"$channel\" is already initialized"); |
713 | }
|
713 | }
|
714 | }
|
714 | }
|
715 | $this->pushErrorHandling(PEAR_ERROR_RETURN); |
715 | $this->pushErrorHandling(PEAR_ERROR_RETURN); |
716 | $err = $this->doAdd($command, $options, array('http://' . $channel . '/channel.xml')); |
716 | $err = $this->doAdd($command, $options, array('http://' . $channel . '/channel.xml')); |
717 | $this->popErrorHandling(); |
717 | $this->popErrorHandling(); |
718 | if (PEAR::isError($err)) { |
718 | if (PEAR::isError($err)) { |
719 | return $this->raiseError("Discovery of channel \"$channel\" failed (" . |
719 | return $this->raiseError("Discovery of channel \"$channel\" failed (" . |
720 | $err->getMessage() . ')'); |
720 | $err->getMessage() . ')'); |
721 | }
|
721 | }
|
722 | 722 | ||
723 | // Store username/password if they were given
|
723 | // Store username/password if they were given
|
724 | // Arguably we should do a logintest on the channel here, but since
|
724 | // Arguably we should do a logintest on the channel here, but since
|
725 | // that's awkward on a REST-based channel (even "pear login" doesn't
|
725 | // that's awkward on a REST-based channel (even "pear login" doesn't
|
726 | // do it for those), and XML-RPC is deprecated, it's fairly pointless.
|
726 | // do it for those), and XML-RPC is deprecated, it's fairly pointless.
|
727 | if (isset($username)) { |
727 | if (isset($username)) { |
728 | $this->config->set('username', $username, 'user', $channel); |
728 | $this->config->set('username', $username, 'user', $channel); |
729 | $this->config->set('password', $password, 'user', $channel); |
729 | $this->config->set('password', $password, 'user', $channel); |
730 | $this->config->store(); |
730 | $this->config->store(); |
731 | $this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\"", $command); |
731 | $this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\"", $command); |
732 | }
|
732 | }
|
733 | 733 | ||
734 | $this->ui->outputData("Discovery of channel \"$channel\" succeeded", $command); |
734 | $this->ui->outputData("Discovery of channel \"$channel\" succeeded", $command); |
735 | }
|
735 | }
|
736 | }
|
736 | }
|
737 | ?>
|
737 | ?>
|
738 | 738 |