Subversion Repositories Applications.gtt

Rev

Rev 94 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 94 Rev 187
1
<?php
1
<?php
2
/**
2
/**
3
 * PEAR_ChannelFile, the channel handling class
3
 * PEAR_ChannelFile, the channel handling class
4
 *
4
 *
5
 * PHP versions 4 and 5
5
 * PHP versions 4 and 5
6
 *
6
 *
7
 * LICENSE: This source file is subject to version 3.0 of the PHP license
-
 
8
 * that is available through the world-wide-web at the following URI:
-
 
9
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
-
 
10
 * the PHP License and are unable to obtain it through the web, please
-
 
11
 * send a note to license@php.net so we can mail you a copy immediately.
-
 
12
 *
-
 
13
 * @category   pear
7
 * @category   pear
14
 * @package    PEAR
8
 * @package    PEAR
15
 * @author     Greg Beaver <cellog@php.net>
9
 * @author     Greg Beaver <cellog@php.net>
16
 * @copyright  1997-2006 The PHP Group
10
 * @copyright  1997-2009 The Authors
17
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
11
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
18
 * @version    CVS: $Id: ChannelFile.php,v 1.78 2006/10/31 02:54:40 cellog Exp $
-
 
19
 * @link       http://pear.php.net/package/PEAR
12
 * @link       http://pear.php.net/package/PEAR
20
 * @since      File available since Release 1.4.0a1
13
 * @since      File available since Release 1.4.0a1
21
 */
14
 */
22
 
15
 
23
/**
16
/**
24
 * Needed for error handling
17
 * Needed for error handling
25
 */
18
 */
26
require_once 'PEAR/ErrorStack.php';
19
require_once 'PEAR/ErrorStack.php';
27
require_once 'PEAR/XMLParser.php';
20
require_once 'PEAR/XMLParser.php';
28
require_once 'PEAR/Common.php';
21
require_once 'PEAR/Common.php';
29
 
22
 
30
/**
23
/**
31
 * Error code if the channel.xml <channel> tag does not contain a valid version
24
 * Error code if the channel.xml <channel> tag does not contain a valid version
32
 */
25
 */
33
define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1);
26
define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1);
34
/**
27
/**
35
 * Error code if the channel.xml <channel> tag version is not supported (version 1.0 is the only supported version,
28
 * Error code if the channel.xml <channel> tag version is not supported (version 1.0 is the only supported version,
36
 * currently
29
 * currently
37
 */
30
 */
38
define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2);
31
define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2);
39
 
32
 
40
/**
33
/**
41
 * Error code if parsing is attempted with no xml extension
34
 * Error code if parsing is attempted with no xml extension
42
 */
35
 */
43
define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3);
36
define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3);
44
 
37
 
45
/**
38
/**
46
 * Error code if creating the xml parser resource fails
39
 * Error code if creating the xml parser resource fails
47
 */
40
 */
48
define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4);
41
define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4);
49
 
42
 
50
/**
43
/**
51
 * Error code used for all sax xml parsing errors
44
 * Error code used for all sax xml parsing errors
52
 */
45
 */
53
define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5);
46
define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5);
54
 
47
 
55
/**#@+
48
/**#@+
56
 * Validation errors
49
 * Validation errors
57
 */
50
 */
58
/**
51
/**
59
 * Error code when channel name is missing
52
 * Error code when channel name is missing
60
 */
53
 */
61
define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6);
54
define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6);
62
/**
55
/**
63
 * Error code when channel name is invalid
56
 * Error code when channel name is invalid
64
 */
57
 */
65
define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7);
58
define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7);
66
/**
59
/**
67
 * Error code when channel summary is missing
60
 * Error code when channel summary is missing
68
 */
61
 */
69
define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8);
62
define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8);
70
/**
63
/**
71
 * Error code when channel summary is multi-line
64
 * Error code when channel summary is multi-line
72
 */
65
 */
73
define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9);
66
define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9);
74
/**
67
/**
75
 * Error code when channel server is missing for xmlrpc or soap protocol
68
 * Error code when channel server is missing for protocol
76
 */
69
 */
77
define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10);
70
define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10);
78
/**
71
/**
79
 * Error code when channel server is invalid for xmlrpc or soap protocol
72
 * Error code when channel server is invalid for protocol
80
 */
73
 */
81
define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11);
74
define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11);
82
/**
75
/**
83
 * Error code when a mirror name is invalid
76
 * Error code when a mirror name is invalid
84
 */
77
 */
85
define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21);
78
define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21);
86
/**
79
/**
87
 * Error code when a mirror type is invalid
80
 * Error code when a mirror type is invalid
88
 */
81
 */
89
define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22);
82
define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22);
90
/**
83
/**
91
 * Error code when an attempt is made to generate xml, but the parsed content is invalid
84
 * Error code when an attempt is made to generate xml, but the parsed content is invalid
92
 */
85
 */
93
define('PEAR_CHANNELFILE_ERROR_INVALID', 23);
86
define('PEAR_CHANNELFILE_ERROR_INVALID', 23);
94
/**
87
/**
95
 * Error code when an empty package name validate regex is passed in
88
 * Error code when an empty package name validate regex is passed in
96
 */
89
 */
97
define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24);
90
define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24);
98
/**
91
/**
99
 * Error code when a <function> tag has no version
92
 * Error code when a <function> tag has no version
100
 */
93
 */
101
define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25);
94
define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25);
102
/**
95
/**
103
 * Error code when a <function> tag has no name
96
 * Error code when a <function> tag has no name
104
 */
97
 */
105
define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26);
98
define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26);
106
/**
99
/**
107
 * Error code when a <validatepackage> tag has no name
100
 * Error code when a <validatepackage> tag has no name
108
 */
101
 */
109
define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27);
102
define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27);
110
/**
103
/**
111
 * Error code when a <validatepackage> tag has no version attribute
104
 * Error code when a <validatepackage> tag has no version attribute
112
 */
105
 */
113
define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28);
106
define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28);
114
/**
107
/**
115
 * Error code when a mirror does not exist but is called for in one of the set*
108
 * Error code when a mirror does not exist but is called for in one of the set*
116
 * methods.
109
 * methods.
117
 */
110
 */
118
define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32);
111
define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32);
119
/**
112
/**
120
 * Error code when a server port is not numeric
113
 * Error code when a server port is not numeric
121
 */
114
 */
122
define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33);
115
define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33);
123
/**
116
/**
124
 * Error code when <static> contains no version attribute
117
 * Error code when <static> contains no version attribute
125
 */
118
 */
126
define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34);
119
define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34);
127
/**
120
/**
128
 * Error code when <baseurl> contains no type attribute in a <rest> protocol definition
121
 * Error code when <baseurl> contains no type attribute in a <rest> protocol definition
129
 */
122
 */
130
define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35);
123
define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35);
131
/** 
124
/**
132
 * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel
125
 * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel
133
 */
126
 */
134
define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36);
127
define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36);
135
/** 
128
/**
136
 * Error code when ssl attribute is present and is not "yes"
129
 * Error code when ssl attribute is present and is not "yes"
137
 */
130
 */
138
define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37);
131
define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37);
139
/**#@-*/
132
/**#@-*/
140
 
133
 
141
/**
134
/**
142
 * Mirror types allowed.  Currently only internet servers are recognized.
135
 * Mirror types allowed.  Currently only internet servers are recognized.
143
 */
136
 */
144
$GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] =  array('server');
137
$GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] =  array('server');
145
 
138
 
146
 
139
 
147
/**
140
/**
148
 * The Channel handling class
141
 * The Channel handling class
149
 *
142
 *
150
 * @category   pear
143
 * @category   pear
151
 * @package    PEAR
144
 * @package    PEAR
152
 * @author     Greg Beaver <cellog@php.net>
145
 * @author     Greg Beaver <cellog@php.net>
153
 * @copyright  1997-2006 The PHP Group
146
 * @copyright  1997-2009 The Authors
154
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
147
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
155
 * @version    Release: 1.5.1
148
 * @version    Release: 1.10.1
156
 * @link       http://pear.php.net/package/PEAR
149
 * @link       http://pear.php.net/package/PEAR
157
 * @since      Class available since Release 1.4.0a1
150
 * @since      Class available since Release 1.4.0a1
158
 */
151
 */
159
class PEAR_ChannelFile {
152
class PEAR_ChannelFile
-
 
153
{
160
    /**
154
    /**
161
     * @access private
155
     * @access private
162
     * @var PEAR_ErrorStack
156
     * @var PEAR_ErrorStack
163
     * @access private
157
     * @access private
164
     */
158
     */
165
    var $_stack;
159
    var $_stack;
166
    
160
 
167
    /**
161
    /**
168
     * Supported channel.xml versions, for parsing
162
     * Supported channel.xml versions, for parsing
169
     * @var array
163
     * @var array
170
     * @access private
164
     * @access private
171
     */
165
     */
172
    var $_supportedVersions = array('1.0');
166
    var $_supportedVersions = array('1.0');
173
 
167
 
174
    /**
168
    /**
175
     * Parsed channel information
169
     * Parsed channel information
176
     * @var array
170
     * @var array
177
     * @access private
171
     * @access private
178
     */
172
     */
179
    var $_channelInfo;
173
    var $_channelInfo;
180
 
174
 
181
    /**
175
    /**
182
     * index into the subchannels array, used for parsing xml
176
     * index into the subchannels array, used for parsing xml
183
     * @var int
177
     * @var int
184
     * @access private
178
     * @access private
185
     */
179
     */
186
    var $_subchannelIndex;
180
    var $_subchannelIndex;
187
 
181
 
188
    /**
182
    /**
189
     * index into the mirrors array, used for parsing xml
183
     * index into the mirrors array, used for parsing xml
190
     * @var int
184
     * @var int
191
     * @access private
185
     * @access private
192
     */
186
     */
193
    var $_mirrorIndex;
187
    var $_mirrorIndex;
194
    
188
 
195
    /**
189
    /**
196
     * Flag used to determine the validity of parsed content
190
     * Flag used to determine the validity of parsed content
197
     * @var boolean
191
     * @var boolean
198
     * @access private
192
     * @access private
199
     */
193
     */
200
    var $_isValid = false;
194
    var $_isValid = false;
201
 
195
 
202
    function PEAR_ChannelFile()
196
    function __construct()
203
    {
197
    {
204
        $this->_stack = &new PEAR_ErrorStack('PEAR_ChannelFile');
198
        $this->_stack = new PEAR_ErrorStack('PEAR_ChannelFile');
205
        $this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
199
        $this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
206
        $this->_isValid = false;
200
        $this->_isValid = false;
207
    }
201
    }
208
    
202
 
209
    /**
203
    /**
210
     * @return array
204
     * @return array
211
     * @access protected
205
     * @access protected
212
     */
206
     */
213
    function _getErrorMessage()
207
    function _getErrorMessage()
214
    {
208
    {
215
        return
209
        return
216
            array(
210
            array(
217
                PEAR_CHANNELFILE_ERROR_INVALID_VERSION =>
211
                PEAR_CHANNELFILE_ERROR_INVALID_VERSION =>
218
                    'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%',
212
                    'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%',
219
                PEAR_CHANNELFILE_ERROR_NO_VERSION =>
213
                PEAR_CHANNELFILE_ERROR_NO_VERSION =>
220
                    'No version number found in <channel> tag',
214
                    'No version number found in <channel> tag',
221
                PEAR_CHANNELFILE_ERROR_NO_XML_EXT =>
215
                PEAR_CHANNELFILE_ERROR_NO_XML_EXT =>
222
                    '%error%',
216
                    '%error%',
223
                PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER =>
217
                PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER =>
224
                    'Unable to create XML parser',
218
                    'Unable to create XML parser',
225
                PEAR_CHANNELFILE_ERROR_PARSER_ERROR =>
219
                PEAR_CHANNELFILE_ERROR_PARSER_ERROR =>
226
                    '%error%',
220
                    '%error%',
227
                PEAR_CHANNELFILE_ERROR_NO_NAME =>
221
                PEAR_CHANNELFILE_ERROR_NO_NAME =>
228
                    'Missing channel name',
222
                    'Missing channel name',
229
                PEAR_CHANNELFILE_ERROR_INVALID_NAME =>
223
                PEAR_CHANNELFILE_ERROR_INVALID_NAME =>
230
                    'Invalid channel %tag% "%name%"',
224
                    'Invalid channel %tag% "%name%"',
231
                PEAR_CHANNELFILE_ERROR_NO_SUMMARY =>
225
                PEAR_CHANNELFILE_ERROR_NO_SUMMARY =>
232
                    'Missing channel summary',
226
                    'Missing channel summary',
233
                PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY =>
227
                PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY =>
234
                    'Channel summary should be on one line, but is multi-line',
228
                    'Channel summary should be on one line, but is multi-line',
235
                PEAR_CHANNELFILE_ERROR_NO_HOST =>
229
                PEAR_CHANNELFILE_ERROR_NO_HOST =>
236
                    'Missing channel server for %type% server',
230
                    'Missing channel server for %type% server',
237
                PEAR_CHANNELFILE_ERROR_INVALID_HOST =>
231
                PEAR_CHANNELFILE_ERROR_INVALID_HOST =>
238
                    'Server name "%server%" is invalid for %type% server',
232
                    'Server name "%server%" is invalid for %type% server',
239
                PEAR_CHANNELFILE_ERROR_INVALID_MIRROR =>
233
                PEAR_CHANNELFILE_ERROR_INVALID_MIRROR =>
240
                    'Invalid mirror name "%name%", mirror type %type%',
234
                    'Invalid mirror name "%name%", mirror type %type%',
241
                PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE =>
235
                PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE =>
242
                    'Invalid mirror type "%type%"',
236
                    'Invalid mirror type "%type%"',
243
                PEAR_CHANNELFILE_ERROR_INVALID =>
237
                PEAR_CHANNELFILE_ERROR_INVALID =>
244
                    'Cannot generate xml, contents are invalid',
238
                    'Cannot generate xml, contents are invalid',
245
                PEAR_CHANNELFILE_ERROR_EMPTY_REGEX =>
239
                PEAR_CHANNELFILE_ERROR_EMPTY_REGEX =>
246
                    'packagenameregex cannot be empty',
240
                    'packagenameregex cannot be empty',
247
                PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION =>
241
                PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION =>
248
                    '%parent% %protocol% function has no version',
242
                    '%parent% %protocol% function has no version',
249
                PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME =>
243
                PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME =>
250
                    '%parent% %protocol% function has no name',
244
                    '%parent% %protocol% function has no name',
251
                PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE =>
245
                PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE =>
252
                    '%parent% rest baseurl has no type',
246
                    '%parent% rest baseurl has no type',
253
                PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME =>
247
                PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME =>
254
                    'Validation package has no name in <validatepackage> tag',
248
                    'Validation package has no name in <validatepackage> tag',
255
                PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION =>
249
                PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION =>
256
                    'Validation package "%package%" has no version',
250
                    'Validation package "%package%" has no version',
257
                PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND =>
251
                PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND =>
258
                    'Mirror "%mirror%" does not exist',
252
                    'Mirror "%mirror%" does not exist',
259
                PEAR_CHANNELFILE_ERROR_INVALID_PORT =>
253
                PEAR_CHANNELFILE_ERROR_INVALID_PORT =>
260
                    'Port "%port%" must be numeric',
254
                    'Port "%port%" must be numeric',
261
                PEAR_CHANNELFILE_ERROR_NO_STATICVERSION =>
255
                PEAR_CHANNELFILE_ERROR_NO_STATICVERSION =>
262
                    '<static> tag must contain version attribute',
256
                    '<static> tag must contain version attribute',
263
                PEAR_CHANNELFILE_URI_CANT_MIRROR =>
257
                PEAR_CHANNELFILE_URI_CANT_MIRROR =>
264
                    'The __uri pseudo-channel cannot have mirrors',
258
                    'The __uri pseudo-channel cannot have mirrors',
265
                PEAR_CHANNELFILE_ERROR_INVALID_SSL =>
259
                PEAR_CHANNELFILE_ERROR_INVALID_SSL =>
266
                    '%server% has invalid ssl attribute "%ssl%" can only be yes or not present',
260
                    '%server% has invalid ssl attribute "%ssl%" can only be yes or not present',
267
            );
261
            );
268
    }
262
    }
269
 
263
 
270
    /**
264
    /**
271
     * @param string contents of package.xml file
265
     * @param string contents of package.xml file
272
     * @return bool success of parsing
266
     * @return bool success of parsing
273
     */
267
     */
274
    function fromXmlString($data)
268
    function fromXmlString($data)
275
    {
269
    {
276
        if (preg_match('/<channel\s+version="([0-9]+\.[0-9]+)"/', $data, $channelversion)) {
270
        if (preg_match('/<channel\s+version="([0-9]+\.[0-9]+)"/', $data, $channelversion)) {
277
            if (!in_array($channelversion[1], $this->_supportedVersions)) {
271
            if (!in_array($channelversion[1], $this->_supportedVersions)) {
278
                $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error',
272
                $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error',
279
                    array('version' => $channelversion[1]));
273
                    array('version' => $channelversion[1]));
280
                return false;
274
                return false;
281
            }
275
            }
282
            $parser = new PEAR_XMLParser;
276
            $parser = new PEAR_XMLParser;
283
            $result = $parser->parse($data);
277
            $result = $parser->parse($data);
284
            if ($result !== true) {
278
            if ($result !== true) {
285
                if ($result->getCode() == 1) {
279
                if ($result->getCode() == 1) {
286
                    $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error',
280
                    $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error',
287
                        array('error' => $error));
281
                        array('error' => $result->getMessage()));
288
                } else {
282
                } else {
289
                    $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error');
283
                    $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error');
290
                }
284
                }
291
                return false;
285
                return false;
292
            }
286
            }
293
            $this->_channelInfo = $parser->getData();
287
            $this->_channelInfo = $parser->getData();
294
            return true;
288
            return true;
295
        } else {
289
        } else {
296
            $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data));
290
            $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data));
297
            return false;
291
            return false;
298
        }
292
        }
299
    }
293
    }
300
    
294
 
301
    /**
295
    /**
302
     * @return array
296
     * @return array
303
     */
297
     */
304
    function toArray()
298
    function toArray()
305
    {
299
    {
306
        if (!$this->_isValid && !$this->validate()) {
300
        if (!$this->_isValid && !$this->validate()) {
307
            return false;
301
            return false;
308
        }
302
        }
309
        return $this->_channelInfo;
303
        return $this->_channelInfo;
310
    }
304
    }
311
    
305
 
312
    /**
306
    /**
313
     * @param array
307
     * @param array
314
     * @static
308
     *
315
     * @return PEAR_ChannelFile|false false if invalid
309
     * @return PEAR_ChannelFile|false false if invalid
316
     */
310
     */
-
 
311
    public static function &fromArray(
317
    function &fromArray($data, $compatibility = false, $stackClass = 'PEAR_ErrorStack')
312
        $data, $compatibility = false, $stackClass = 'PEAR_ErrorStack'
318
    {
313
    ) {
319
        $a = new PEAR_ChannelFile($compatibility, $stackClass);
314
        $a = new PEAR_ChannelFile($compatibility, $stackClass);
320
        $a->_fromArray($data);
315
        $a->_fromArray($data);
321
        if (!$a->validate()) {
316
        if (!$a->validate()) {
322
            $a = false;
317
            $a = false;
323
            return $a;
318
            return $a;
324
        }
319
        }
325
        return $a;
320
        return $a;
326
    }
321
    }
327
 
322
 
328
    /**
323
    /**
329
     * Unlike {@link fromArray()} this does not do any validation
324
     * Unlike {@link fromArray()} this does not do any validation
-
 
325
     *
330
     * @param array
326
     * @param array
331
     * @static
327
     *
332
     * @return PEAR_ChannelFile
328
     * @return PEAR_ChannelFile
333
     */
329
     */
334
    function &fromArrayWithErrors($data, $compatibility = false,
330
    public static function &fromArrayWithErrors(
335
                                  $stackClass = 'PEAR_ErrorStack')
331
        $data, $compatibility = false, $stackClass = 'PEAR_ErrorStack'
336
    {
332
    ) {
337
        $a = new PEAR_ChannelFile($compatibility, $stackClass);
333
        $a = new PEAR_ChannelFile($compatibility, $stackClass);
338
        $a->_fromArray($data);
334
        $a->_fromArray($data);
339
        return $a;
335
        return $a;
340
    }
336
    }
341
    
337
 
342
    /**
338
    /**
343
     * @param array
339
     * @param array
344
     * @access private
340
     * @access private
345
     */
341
     */
346
    function _fromArray($data)
342
    function _fromArray($data)
347
    {
343
    {
348
        $this->_channelInfo = $data;
344
        $this->_channelInfo = $data;
349
    }
345
    }
350
    
346
 
351
    /**
347
    /**
352
     * Wrapper to {@link PEAR_ErrorStack::getErrors()}
348
     * Wrapper to {@link PEAR_ErrorStack::getErrors()}
353
     * @param boolean determines whether to purge the error stack after retrieving
349
     * @param boolean determines whether to purge the error stack after retrieving
354
     * @return array
350
     * @return array
355
     */
351
     */
356
    function getErrors($purge = false)
352
    function getErrors($purge = false)
357
    {
353
    {
358
        return $this->_stack->getErrors($purge);
354
        return $this->_stack->getErrors($purge);
359
    }
355
    }
360
 
356
 
361
    /**
357
    /**
362
     * Unindent given string (?)
358
     * Unindent given string (?)
363
     *
359
     *
364
     * @param string $str The string that has to be unindented.
360
     * @param string $str The string that has to be unindented.
365
     * @return string
361
     * @return string
366
     * @access private
362
     * @access private
367
     */
363
     */
368
    function _unIndent($str)
364
    function _unIndent($str)
369
    {
365
    {
370
        // remove leading newlines
366
        // remove leading newlines
371
        $str = preg_replace('/^[\r\n]+/', '', $str);
367
        $str = preg_replace('/^[\r\n]+/', '', $str);
372
        // find whitespace at the beginning of the first line
368
        // find whitespace at the beginning of the first line
373
        $indent_len = strspn($str, " \t");
369
        $indent_len = strspn($str, " \t");
374
        $indent = substr($str, 0, $indent_len);
370
        $indent = substr($str, 0, $indent_len);
375
        $data = '';
371
        $data = '';
376
        // remove the same amount of whitespace from following lines
372
        // remove the same amount of whitespace from following lines
377
        foreach (explode("\n", $str) as $line) {
373
        foreach (explode("\n", $str) as $line) {
378
            if (substr($line, 0, $indent_len) == $indent) {
374
            if (substr($line, 0, $indent_len) == $indent) {
379
                $data .= substr($line, $indent_len) . "\n";
375
                $data .= substr($line, $indent_len) . "\n";
380
            }
376
            }
381
        }
377
        }
382
        return $data;
378
        return $data;
383
    }
379
    }
384
 
380
 
385
    /**
381
    /**
386
     * Parse a channel.xml file.  Expects the name of
382
     * Parse a channel.xml file.  Expects the name of
387
     * a channel xml file as input.
383
     * a channel xml file as input.
388
     *
384
     *
389
     * @param string  $descfile  name of channel xml file
385
     * @param string  $descfile  name of channel xml file
390
     * @return bool success of parsing
386
     * @return bool success of parsing
391
     */
387
     */
392
    function fromXmlFile($descfile)
388
    function fromXmlFile($descfile)
393
    {
389
    {
394
        if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) ||
390
        if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) ||
395
             (!$fp = fopen($descfile, 'r'))) {
391
             (!$fp = fopen($descfile, 'r'))) {
396
            require_once 'PEAR.php';
392
            require_once 'PEAR.php';
397
            return PEAR::raiseError("Unable to open $descfile");
393
            return PEAR::raiseError("Unable to open $descfile");
398
        }
394
        }
399
 
395
 
400
        // read the whole thing so we only get one cdata callback
396
        // read the whole thing so we only get one cdata callback
401
        // for each block of cdata
397
        // for each block of cdata
402
        fclose($fp);
398
        fclose($fp);
403
        $data = file_get_contents($descfile);
399
        $data = file_get_contents($descfile);
404
        return $this->fromXmlString($data);
400
        return $this->fromXmlString($data);
405
    }
401
    }
406
 
402
 
407
    /**
403
    /**
408
     * Parse channel information from different sources
404
     * Parse channel information from different sources
409
     *
405
     *
410
     * This method is able to extract information about a channel
406
     * This method is able to extract information about a channel
411
     * from an .xml file or a string
407
     * from an .xml file or a string
412
     *
408
     *
413
     * @access public
409
     * @access public
414
     * @param  string Filename of the source or the source itself
410
     * @param  string Filename of the source or the source itself
415
     * @return bool
411
     * @return bool
416
     */
412
     */
417
    function fromAny($info)
413
    function fromAny($info)
418
    {
414
    {
419
        if (is_string($info) && file_exists($info) && strlen($info) < 255) {
415
        if (is_string($info) && file_exists($info) && strlen($info) < 255) {
420
            $tmp = substr($info, -4);
416
            $tmp = substr($info, -4);
421
            if ($tmp == '.xml') {
417
            if ($tmp == '.xml') {
422
                $info = $this->fromXmlFile($info);
418
                $info = $this->fromXmlFile($info);
423
            } else {
419
            } else {
424
                $fp = fopen($info, "r");
420
                $fp = fopen($info, "r");
425
                $test = fread($fp, 5);
421
                $test = fread($fp, 5);
426
                fclose($fp);
422
                fclose($fp);
427
                if ($test == "<?xml") {
423
                if ($test == "<?xml") {
428
                    $info = $this->fromXmlFile($info);
424
                    $info = $this->fromXmlFile($info);
429
                }
425
                }
430
            }
426
            }
431
            if (PEAR::isError($info)) {
427
            if (PEAR::isError($info)) {
432
                require_once 'PEAR.php';
428
                require_once 'PEAR.php';
433
                return PEAR::raiseError($info);
429
                return PEAR::raiseError($info);
434
            }
430
            }
435
        }
431
        }
436
        if (is_string($info)) {
432
        if (is_string($info)) {
437
            $info = $this->fromXmlString($info);
433
            $info = $this->fromXmlString($info);
438
        }
434
        }
439
        return $info;
435
        return $info;
440
    }
436
    }
441
 
437
 
442
    /**
438
    /**
443
     * Return an XML document based on previous parsing and modifications
439
     * Return an XML document based on previous parsing and modifications
444
     *
440
     *
445
     * @return string XML data
441
     * @return string XML data
446
     *
442
     *
447
     * @access public
443
     * @access public
448
     */
444
     */
449
    function toXml()
445
    function toXml()
450
    {
446
    {
451
        if (!$this->_isValid && !$this->validate()) {
447
        if (!$this->_isValid && !$this->validate()) {
452
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID);
448
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID);
453
            return false;
449
            return false;
454
        }
450
        }
455
        if (!isset($this->_channelInfo['attribs']['version'])) {
451
        if (!isset($this->_channelInfo['attribs']['version'])) {
456
            $this->_channelInfo['attribs']['version'] = '1.0';
452
            $this->_channelInfo['attribs']['version'] = '1.0';
457
        }
453
        }
458
        $channelInfo = $this->_channelInfo;
454
        $channelInfo = $this->_channelInfo;
459
        $ret = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n";
455
        $ret = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n";
460
        $ret .= "<channel version=\"" .
456
        $ret .= "<channel version=\"" .
461
            $channelInfo['attribs']['version'] . "\" xmlns=\"http://pear.php.net/channel-1.0\"
457
            $channelInfo['attribs']['version'] . "\" xmlns=\"http://pear.php.net/channel-1.0\"
462
  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
458
  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
463
  xsi:schemaLocation=\"http://pear.php.net/dtd/channel-"
459
  xsi:schemaLocation=\"http://pear.php.net/dtd/channel-"
464
            . $channelInfo['attribs']['version'] . " http://pear.php.net/dtd/channel-" .
460
            . $channelInfo['attribs']['version'] . " http://pear.php.net/dtd/channel-" .
465
            $channelInfo['attribs']['version'] . ".xsd\">
461
            $channelInfo['attribs']['version'] . ".xsd\">
466
 <name>$channelInfo[name]</name>
462
 <name>$channelInfo[name]</name>
467
 <summary>" . htmlspecialchars($channelInfo['summary'])."</summary>
463
 <summary>" . htmlspecialchars($channelInfo['summary'])."</summary>
468
";
464
";
469
        if (isset($channelInfo['suggestedalias'])) {
465
        if (isset($channelInfo['suggestedalias'])) {
470
            $ret .= ' <suggestedalias>' . $channelInfo['suggestedalias'] . "</suggestedalias>\n";
466
            $ret .= ' <suggestedalias>' . $channelInfo['suggestedalias'] . "</suggestedalias>\n";
471
        }
467
        }
472
        if (isset($channelInfo['validatepackage'])) {
468
        if (isset($channelInfo['validatepackage'])) {
473
            $ret .= ' <validatepackage version="' .
469
            $ret .= ' <validatepackage version="' .
474
                $channelInfo['validatepackage']['attribs']['version']. '">' .
470
                $channelInfo['validatepackage']['attribs']['version']. '">' .
475
                htmlspecialchars($channelInfo['validatepackage']['_content']) .
471
                htmlspecialchars($channelInfo['validatepackage']['_content']) .
476
                "</validatepackage>\n";
472
                "</validatepackage>\n";
477
        }
473
        }
478
        $ret .= " <servers>\n";
474
        $ret .= " <servers>\n";
479
        $ret .= '  <primary';
475
        $ret .= '  <primary';
480
        if (isset($channelInfo['servers']['primary']['attribs']['ssl'])) {
476
        if (isset($channelInfo['servers']['primary']['attribs']['ssl'])) {
481
            $ret .= ' ssl="' . $channelInfo['servers']['primary']['attribs']['ssl'] . '"';
477
            $ret .= ' ssl="' . $channelInfo['servers']['primary']['attribs']['ssl'] . '"';
482
        }
478
        }
483
        if (isset($channelInfo['servers']['primary']['attribs']['port'])) {
479
        if (isset($channelInfo['servers']['primary']['attribs']['port'])) {
484
            $ret .= ' port="' . $channelInfo['servers']['primary']['attribs']['port'] . '"';
480
            $ret .= ' port="' . $channelInfo['servers']['primary']['attribs']['port'] . '"';
485
        }
481
        }
486
        $ret .= ">\n";
482
        $ret .= ">\n";
487
        if (isset($channelInfo['servers']['primary']['xmlrpc'])) {
-
 
488
            $ret .= $this->_makeXmlrpcXml($channelInfo['servers']['primary']['xmlrpc'], '   ');
-
 
489
        }
-
 
490
        if (isset($channelInfo['servers']['primary']['rest'])) {
483
        if (isset($channelInfo['servers']['primary']['rest'])) {
491
            $ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], '   ');
484
            $ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], '   ');
492
        }
485
        }
493
        if (isset($channelInfo['servers']['primary']['soap'])) {
-
 
494
            $ret .= $this->_makeSoapXml($channelInfo['servers']['primary']['soap'], '   ');
-
 
495
        }
-
 
496
        $ret .= "  </primary>\n";
486
        $ret .= "  </primary>\n";
497
        if (isset($channelInfo['servers']['mirror'])) {
487
        if (isset($channelInfo['servers']['mirror'])) {
498
            $ret .= $this->_makeMirrorsXml($channelInfo);
488
            $ret .= $this->_makeMirrorsXml($channelInfo);
499
        }
489
        }
500
        $ret .= " </servers>\n";
490
        $ret .= " </servers>\n";
501
        $ret .= "</channel>";
491
        $ret .= "</channel>";
502
        return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret));
492
        return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret));
503
    }
493
    }
504
 
494
 
505
    /**
495
    /**
506
     * Generate the <xmlrpc> tag
-
 
507
     * @access private
-
 
508
     */
-
 
509
    function _makeXmlrpcXml($info, $indent)
-
 
510
    {
-
 
511
        $ret = $indent . "<xmlrpc";
-
 
512
        if (isset($info['attribs']['path'])) {
-
 
513
            $ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
-
 
514
        }
-
 
515
        $ret .= ">\n";
-
 
516
        $ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
-
 
517
        $ret .= $indent . "</xmlrpc>\n";
-
 
518
        return $ret;
-
 
519
    }
-
 
520
 
-
 
521
    /**
-
 
522
     * Generate the <soap> tag
-
 
523
     * @access private
-
 
524
     */
-
 
525
    function _makeSoapXml($info, $indent)
-
 
526
    {
-
 
527
        $ret = $indent . "<soap";
-
 
528
        if (isset($info['attribs']['path'])) {
-
 
529
            $ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
-
 
530
        }
-
 
531
        $ret .= ">\n";
-
 
532
        $ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
-
 
533
        $ret .= $indent . "</soap>\n";
-
 
534
        return $ret;
-
 
535
    }
-
 
536
 
-
 
537
    /**
-
 
538
     * Generate the <rest> tag
496
     * Generate the <rest> tag
539
     * @access private
497
     * @access private
540
     */
498
     */
541
    function _makeRestXml($info, $indent)
499
    function _makeRestXml($info, $indent)
542
    {
500
    {
543
        $ret = $indent . "<rest>\n";
501
        $ret = $indent . "<rest>\n";
544
        if (!isset($info['baseurl'][0])) {
502
        if (isset($info['baseurl']) && !isset($info['baseurl'][0])) {
545
            $info['baseurl'] = array($info['baseurl']);
503
            $info['baseurl'] = array($info['baseurl']);
546
        }
504
        }
-
 
505
 
-
 
506
        if (isset($info['baseurl'])) {
547
        foreach ($info['baseurl'] as $url) {
507
            foreach ($info['baseurl'] as $url) {
548
            $ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\"";
508
                $ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\"";
549
            $ret .= ">" . $url['_content'] . "</baseurl>\n";
509
                $ret .= ">" . $url['_content'] . "</baseurl>\n";
-
 
510
            }
550
        }
511
        }
551
        $ret .= $indent . "</rest>\n";
512
        $ret .= $indent . "</rest>\n";
552
        return $ret;
513
        return $ret;
553
    }
514
    }
554
 
515
 
555
    /**
516
    /**
556
     * Generate the <mirrors> tag
517
     * Generate the <mirrors> tag
557
     * @access private
518
     * @access private
558
     */
519
     */
559
    function _makeMirrorsXml($channelInfo)
520
    function _makeMirrorsXml($channelInfo)
560
    {
521
    {
561
        $ret = "";
522
        $ret = "";
562
        if (!isset($channelInfo['servers']['mirror'][0])) {
523
        if (!isset($channelInfo['servers']['mirror'][0])) {
563
            $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']);
524
            $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']);
564
        }
525
        }
565
        foreach ($channelInfo['servers']['mirror'] as $mirror) {
526
        foreach ($channelInfo['servers']['mirror'] as $mirror) {
566
            $ret .= '  <mirror host="' . $mirror['attribs']['host'] . '"';
527
            $ret .= '  <mirror host="' . $mirror['attribs']['host'] . '"';
567
            if (isset($mirror['attribs']['port'])) {
528
            if (isset($mirror['attribs']['port'])) {
568
                $ret .= ' port="' . $mirror['attribs']['port'] . '"';
529
                $ret .= ' port="' . $mirror['attribs']['port'] . '"';
569
            }
530
            }
570
            if (isset($mirror['attribs']['ssl'])) {
531
            if (isset($mirror['attribs']['ssl'])) {
571
                $ret .= ' ssl="' . $mirror['attribs']['ssl'] . '"';
532
                $ret .= ' ssl="' . $mirror['attribs']['ssl'] . '"';
572
            }
533
            }
573
            $ret .= ">\n";
534
            $ret .= ">\n";
574
            if (isset($mirror['xmlrpc']) || isset($mirror['soap'])) {
-
 
575
                if (isset($mirror['xmlrpc'])) {
535
            if (isset($mirror['rest'])) {
576
                    $ret .= $this->_makeXmlrpcXml($mirror['xmlrpc'], '   ');
-
 
577
                }
-
 
578
                if (isset($mirror['rest'])) {
536
                if (isset($mirror['rest'])) {
579
                    $ret .= $this->_makeRestXml($mirror['rest'], '   ');
537
                    $ret .= $this->_makeRestXml($mirror['rest'], '   ');
580
                }
538
                }
581
                if (isset($mirror['soap'])) {
-
 
582
                    $ret .= $this->_makeSoapXml($mirror['soap'], '   ');
-
 
583
                }
-
 
584
                $ret .= "  </mirror>\n";
539
                $ret .= "  </mirror>\n";
585
            } else {
540
            } else {
586
                $ret .= "/>\n";
541
                $ret .= "/>\n";
587
            }
542
            }
588
        }
543
        }
589
        return $ret;
544
        return $ret;
590
    }
545
    }
591
 
546
 
592
    /**
547
    /**
593
     * Generate the <functions> tag
548
     * Generate the <functions> tag
594
     * @access private
549
     * @access private
595
     */
550
     */
596
    function _makeFunctionsXml($functions, $indent, $rest = false)
551
    function _makeFunctionsXml($functions, $indent, $rest = false)
597
    {
552
    {
598
        $ret = '';
553
        $ret = '';
599
        if (!isset($functions[0])) {
554
        if (!isset($functions[0])) {
600
            $functions = array($functions);
555
            $functions = array($functions);
601
        }
556
        }
602
        foreach ($functions as $function) {
557
        foreach ($functions as $function) {
603
            $ret .= "$indent<function version=\"" . $function['attribs']['version'] . "\"";
558
            $ret .= "$indent<function version=\"" . $function['attribs']['version'] . "\"";
604
            if ($rest) {
559
            if ($rest) {
605
                $ret .= ' uri="' . $function['attribs']['uri'] . '"';
560
                $ret .= ' uri="' . $function['attribs']['uri'] . '"';
606
            }
561
            }
607
            $ret .= ">" . $function['_content'] . "</function>\n";
562
            $ret .= ">" . $function['_content'] . "</function>\n";
608
        }
563
        }
609
        return $ret;
564
        return $ret;
610
    }
565
    }
611
 
566
 
612
    /**
567
    /**
613
     * Validation error.  Also marks the object contents as invalid
568
     * Validation error.  Also marks the object contents as invalid
614
     * @param error code
569
     * @param error code
615
     * @param array error information
570
     * @param array error information
616
     * @access private
571
     * @access private
617
     */
572
     */
618
    function _validateError($code, $params = array())
573
    function _validateError($code, $params = array())
619
    {
574
    {
620
        $this->_stack->push($code, 'error', $params);
575
        $this->_stack->push($code, 'error', $params);
621
        $this->_isValid = false;
576
        $this->_isValid = false;
622
    }
577
    }
623
 
578
 
624
    /**
579
    /**
625
     * Validation warning.  Does not mark the object contents invalid.
580
     * Validation warning.  Does not mark the object contents invalid.
626
     * @param error code
581
     * @param error code
627
     * @param array error information
582
     * @param array error information
628
     * @access private
583
     * @access private
629
     */
584
     */
630
    function _validateWarning($code, $params = array())
585
    function _validateWarning($code, $params = array())
631
    {
586
    {
632
        $this->_stack->push($code, 'warning', $params);
587
        $this->_stack->push($code, 'warning', $params);
633
    }
588
    }
634
 
589
 
635
    /**
590
    /**
636
     * Validate parsed file.
591
     * Validate parsed file.
637
     *
592
     *
638
     * @access public
593
     * @access public
639
     * @return boolean
594
     * @return boolean
640
     */
595
     */
641
    function validate()
596
    function validate()
642
    {
597
    {
643
        $this->_isValid = true;
598
        $this->_isValid = true;
644
        $info = $this->_channelInfo;
599
        $info = $this->_channelInfo;
645
        if (empty($info['name'])) {
600
        if (empty($info['name'])) {
646
            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME);
601
            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME);
647
        } elseif (!$this->validChannelServer($info['name'])) {
602
        } elseif (!$this->validChannelServer($info['name'])) {
648
            if ($info['name'] != '__uri') {
603
            if ($info['name'] != '__uri') {
649
                $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name',
604
                $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name',
650
                    'name' => $info['name']));
605
                    'name' => $info['name']));
651
            }
606
            }
652
        }
607
        }
653
        if (empty($info['summary'])) {
608
        if (empty($info['summary'])) {
654
            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
609
            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
655
        } elseif (strpos(trim($info['summary']), "\n") !== false) {
610
        } elseif (strpos(trim($info['summary']), "\n") !== false) {
656
            $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
611
            $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
657
                array('summary' => $info['summary']));
612
                array('summary' => $info['summary']));
658
        }
613
        }
659
        if (isset($info['suggestedalias'])) {
614
        if (isset($info['suggestedalias'])) {
660
            if (!$this->validChannelServer($info['suggestedalias'])) {
615
            if (!$this->validChannelServer($info['suggestedalias'])) {
661
                $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
616
                $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
662
                    array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias']));
617
                    array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias']));
663
            }
618
            }
664
        }
619
        }
665
        if (isset($info['localalias'])) {
620
        if (isset($info['localalias'])) {
666
            if (!$this->validChannelServer($info['localalias'])) {
621
            if (!$this->validChannelServer($info['localalias'])) {
667
                $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
622
                $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
668
                    array('tag' => 'localalias', 'name' =>$info['localalias']));
623
                    array('tag' => 'localalias', 'name' =>$info['localalias']));
669
            }
624
            }
670
        }
625
        }
671
        if (isset($info['validatepackage'])) {
626
        if (isset($info['validatepackage'])) {
672
            if (!isset($info['validatepackage']['_content'])) {
627
            if (!isset($info['validatepackage']['_content'])) {
673
                $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME);
628
                $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME);
674
            }
629
            }
675
            if (!isset($info['validatepackage']['attribs']['version'])) {
630
            if (!isset($info['validatepackage']['attribs']['version'])) {
676
                $content = isset($info['validatepackage']['_content']) ?
631
                $content = isset($info['validatepackage']['_content']) ?
677
                    $info['validatepackage']['_content'] :
632
                    $info['validatepackage']['_content'] :
678
                    null;
633
                    null;
679
                $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION,
634
                $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION,
680
                    array('package' => $content));
635
                    array('package' => $content));
681
            }
636
            }
682
        }
637
        }
-
 
638
 
683
        if (isset($info['servers']['primary']['attribs']['port']) &&
639
        if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['port']) &&
684
              !is_numeric($info['servers']['primary']['attribs']['port'])) {
640
              !is_numeric($info['servers']['primary']['attribs']['port'])) {
685
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT,
641
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT,
686
                array('port' => $info['servers']['primary']['attribs']['port']));
642
                array('port' => $info['servers']['primary']['attribs']['port']));
687
        }
643
        }
-
 
644
 
688
        if (isset($info['servers']['primary']['attribs']['ssl']) &&
645
        if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['ssl']) &&
689
              $info['servers']['primary']['attribs']['ssl'] != 'yes') {
646
              $info['servers']['primary']['attribs']['ssl'] != 'yes') {
690
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
647
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
691
                array('ssl' => $info['servers']['primary']['attribs']['ssl'],
648
                array('ssl' => $info['servers']['primary']['attribs']['ssl'],
692
                    'server' => $info['name']));
649
                    'server' => $info['name']));
693
        }
650
        }
694
 
-
 
695
        if (isset($info['servers']['primary']['xmlrpc']) &&
-
 
696
              isset($info['servers']['primary']['xmlrpc']['function'])) {
-
 
697
            $this->_validateFunctions('xmlrpc', $info['servers']['primary']['xmlrpc']['function']);
-
 
698
        }
-
 
699
        if (isset($info['servers']['primary']['soap']) &&
-
 
700
              isset($info['servers']['primary']['soap']['function'])) {
-
 
701
            $this->_validateFunctions('soap', $info['servers']['primary']['soap']['function']);
-
 
702
        }
651
 
703
        if (isset($info['servers']['primary']['rest']) &&
652
        if (isset($info['servers']['primary']['rest']) &&
704
              isset($info['servers']['primary']['rest']['baseurl'])) {
653
              isset($info['servers']['primary']['rest']['baseurl'])) {
705
            $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']);
654
            $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']);
706
        }
655
        }
707
        if (isset($info['servers']['mirror'])) {
656
        if (isset($info['servers']['mirror'])) {
708
            if ($this->_channelInfo['name'] == '__uri') {
657
            if ($this->_channelInfo['name'] == '__uri') {
709
                $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR);
658
                $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR);
710
            }
659
            }
711
            if (!isset($info['servers']['mirror'][0])) {
660
            if (!isset($info['servers']['mirror'][0])) {
712
                $info['servers']['mirror'] = array($info['servers']['mirror']);
661
                $info['servers']['mirror'] = array($info['servers']['mirror']);
713
            }
662
            }
714
            $i = 0;
-
 
715
            foreach ($info['servers']['mirror'] as $mirror) {
663
            foreach ($info['servers']['mirror'] as $mirror) {
716
                if (!isset($mirror['attribs']['host'])) {
664
                if (!isset($mirror['attribs']['host'])) {
717
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST,
665
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST,
718
                      array('type' => 'mirror'));
666
                      array('type' => 'mirror'));
719
                } elseif (!$this->validChannelServer($mirror['attribs']['host'])) {
667
                } elseif (!$this->validChannelServer($mirror['attribs']['host'])) {
720
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST,
668
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST,
721
                        array('server' => $mirror['attribs']['host'], 'type' => 'mirror'));
669
                        array('server' => $mirror['attribs']['host'], 'type' => 'mirror'));
722
                }
670
                }
723
                if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') {
671
                if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') {
724
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
672
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
725
                        array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host']));
673
                        array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host']));
726
                }
674
                }
727
                if (isset($mirror['xmlrpc'])) {
-
 
728
                    $this->_validateFunctions('xmlrpc',
-
 
729
                        $mirror['xmlrpc']['function'], $mirror['attribs']['host']);
-
 
730
                }
-
 
731
                if (isset($mirror['soap'])) {
-
 
732
                    $this->_validateFunctions('soap', $mirror['soap']['function'],
-
 
733
                        $mirror['attribs']['host']);
-
 
734
                }
-
 
735
                if (isset($mirror['rest'])) {
675
                if (isset($mirror['rest'])) {
736
                    $this->_validateFunctions('rest', $mirror['rest']['baseurl'],
676
                    $this->_validateFunctions('rest', $mirror['rest']['baseurl'],
737
                        $mirror['attribs']['host']);
677
                        $mirror['attribs']['host']);
738
                }
678
                }
739
            }
679
            }
740
        }
680
        }
741
        return $this->_isValid;
681
        return $this->_isValid;
742
    }
682
    }
743
 
683
 
744
    /**
684
    /**
745
     * @param string xmlrpc or soap - protocol name this function applies to
685
     * @param string  rest - protocol name this function applies to
746
     * @param array the functions
686
     * @param array the functions
747
     * @param string the name of the parent element (mirror name, for instance)
687
     * @param string the name of the parent element (mirror name, for instance)
748
     */
688
     */
749
    function _validateFunctions($protocol, $functions, $parent = '')
689
    function _validateFunctions($protocol, $functions, $parent = '')
750
    {
690
    {
751
        if (!isset($functions[0])) {
691
        if (!isset($functions[0])) {
752
            $functions = array($functions);
692
            $functions = array($functions);
753
        }
693
        }
-
 
694
 
754
        foreach ($functions as $function) {
695
        foreach ($functions as $function) {
755
            if (!isset($function['_content']) || empty($function['_content'])) {
696
            if (!isset($function['_content']) || empty($function['_content'])) {
756
                $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME,
697
                $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME,
757
                    array('parent' => $parent, 'protocol' => $protocol));
698
                    array('parent' => $parent, 'protocol' => $protocol));
758
            }
699
            }
-
 
700
 
759
            if ($protocol == 'rest') {
701
            if ($protocol == 'rest') {
760
                if (!isset($function['attribs']['type']) ||
702
                if (!isset($function['attribs']['type']) ||
761
                      empty($function['attribs']['type'])) {
703
                      empty($function['attribs']['type'])) {
762
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_BASEURLTYPE,
704
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE,
763
                        array('parent' => $parent, 'protocol' => $protocol));
705
                        array('parent' => $parent, 'protocol' => $protocol));
764
                }
706
                }
765
            } else {
707
            } else {
766
                if (!isset($function['attribs']['version']) ||
708
                if (!isset($function['attribs']['version']) ||
767
                      empty($function['attribs']['version'])) {
709
                      empty($function['attribs']['version'])) {
768
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION,
710
                    $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION,
769
                        array('parent' => $parent, 'protocol' => $protocol));
711
                        array('parent' => $parent, 'protocol' => $protocol));
770
                }
712
                }
771
            }
713
            }
772
        }
714
        }
773
    }
715
    }
774
 
716
 
775
    /**
717
    /**
776
     * Test whether a string contains a valid channel server.
718
     * Test whether a string contains a valid channel server.
777
     * @param string $ver the package version to test
719
     * @param string $ver the package version to test
778
     * @return bool
720
     * @return bool
779
     */
721
     */
780
    function validChannelServer($server)
722
    function validChannelServer($server)
781
    {
723
    {
782
        if ($server == '__uri') {
724
        if ($server == '__uri') {
783
            return true;
725
            return true;
784
        }
726
        }
785
        return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server);
727
        return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server);
786
    }
728
    }
787
 
729
 
788
    /**
730
    /**
789
     * @return string|false
731
     * @return string|false
790
     */
732
     */
791
    function getName()
733
    function getName()
792
    {
734
    {
793
        if (isset($this->_channelInfo['name'])) {
735
        if (isset($this->_channelInfo['name'])) {
794
            return $this->_channelInfo['name'];
736
            return $this->_channelInfo['name'];
795
        } else {
-
 
796
            return false;
-
 
797
        }
737
        }
-
 
738
 
-
 
739
        return false;
798
    }
740
    }
799
 
741
 
800
    /**
742
    /**
801
     * @return string|false
743
     * @return string|false
802
     */
744
     */
803
    function getServer()
745
    function getServer()
804
    {
746
    {
805
        if (isset($this->_channelInfo['name'])) {
747
        if (isset($this->_channelInfo['name'])) {
806
            return $this->_channelInfo['name'];
748
            return $this->_channelInfo['name'];
807
        } else {
-
 
808
            return false;
-
 
809
        }
749
        }
-
 
750
 
-
 
751
        return false;
810
    }
752
    }
811
 
753
 
812
    /**
754
    /**
813
     * @return int|80 port number to connect to
755
     * @return int|80 port number to connect to
814
     */
756
     */
815
    function getPort($mirror = false)
757
    function getPort($mirror = false)
816
    {
758
    {
817
        if ($mirror) {
759
        if ($mirror) {
818
            if ($mir = $this->getMirror($mirror)) {
760
            if ($mir = $this->getMirror($mirror)) {
819
                if (isset($mir['attribs']['port'])) {
761
                if (isset($mir['attribs']['port'])) {
820
                    return $mir['attribs']['port'];
762
                    return $mir['attribs']['port'];
821
                } else {
-
 
822
                    if ($this->getSSL($mirror)) {
-
 
823
                        return 443;
-
 
824
                    }
-
 
825
                    return 80;
-
 
826
                }
763
                }
-
 
764
 
-
 
765
                if ($this->getSSL($mirror)) {
-
 
766
                    return 443;
-
 
767
                }
-
 
768
 
-
 
769
                return 80;
827
            }
770
            }
-
 
771
 
828
            return false;
772
            return false;
829
        }
773
        }
-
 
774
 
830
        if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) {
775
        if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) {
831
            return $this->_channelInfo['servers']['primary']['attribs']['port'];
776
            return $this->_channelInfo['servers']['primary']['attribs']['port'];
832
        }
777
        }
-
 
778
 
833
        if ($this->getSSL()) {
779
        if ($this->getSSL()) {
834
            return 443;
780
            return 443;
835
        }
781
        }
-
 
782
 
836
        return 80;
783
        return 80;
837
    }
784
    }
838
 
785
 
839
    /**
786
    /**
840
     * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel
787
     * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel
841
     */
788
     */
842
    function getSSL($mirror = false)
789
    function getSSL($mirror = false)
843
    {
790
    {
844
        if ($mirror) {
791
        if ($mirror) {
845
            if ($mir = $this->getMirror($mirror)) {
792
            if ($mir = $this->getMirror($mirror)) {
846
                if (isset($mir['attribs']['ssl'])) {
793
                if (isset($mir['attribs']['ssl'])) {
847
                    return true;
794
                    return true;
848
                } else {
-
 
849
                    return false;
-
 
850
                }
795
                }
-
 
796
 
-
 
797
                return false;
851
            }
798
            }
-
 
799
 
852
            return false;
800
            return false;
853
        }
801
        }
-
 
802
 
854
        if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
803
        if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
855
            return true;
804
            return true;
856
        }
805
        }
-
 
806
 
857
        return false;
807
        return false;
858
    }
808
    }
859
 
809
 
860
    /**
810
    /**
861
     * @return string|false
811
     * @return string|false
862
     */
812
     */
863
    function getSummary()
813
    function getSummary()
864
    {
814
    {
865
        if (isset($this->_channelInfo['summary'])) {
815
        if (isset($this->_channelInfo['summary'])) {
866
            return $this->_channelInfo['summary'];
816
            return $this->_channelInfo['summary'];
867
        } else {
-
 
868
            return false;
-
 
869
        }
817
        }
870
    }
-
 
871
 
-
 
872
    /**
-
 
873
     * @param string xmlrpc or soap
-
 
874
     * @param string|false mirror name or false for primary server
-
 
875
     */
-
 
876
    function getPath($protocol, $mirror = false)
-
 
877
    {   
-
 
878
        if (!in_array($protocol, array('xmlrpc', 'soap'))) {
818
 
879
            return false;
-
 
880
        }
-
 
881
        if ($mirror) {
-
 
882
            if (!($mir = $this->getMirror($mirror))) {
-
 
883
                return false;
-
 
884
            }
-
 
885
            if (isset($mir[$protocol]['attribs']['path'])) {
-
 
886
                return $mir[$protocol]['attribs']['path'];
-
 
887
            } else {
-
 
888
                return $protocol . '.php';
-
 
889
            }
-
 
890
        } elseif (isset($this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'])) {
-
 
891
            return $this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'];
-
 
892
        }
-
 
893
        return $protocol . '.php';
819
        return false;
894
    }
820
    }
895
 
821
 
896
    /**
822
    /**
897
     * @param string protocol type (xmlrpc, soap)
823
     * @param string protocol type
898
     * @param string Mirror name
824
     * @param string Mirror name
899
     * @return array|false
825
     * @return array|false
900
     */
826
     */
901
    function getFunctions($protocol, $mirror = false)
827
    function getFunctions($protocol, $mirror = false)
902
    {
828
    {
903
        if ($this->getName() == '__uri') {
829
        if ($this->getName() == '__uri') {
904
            return false;
830
            return false;
905
        }
831
        }
-
 
832
 
906
        if ($protocol == 'rest') {
833
        $function = $protocol == 'rest' ? 'baseurl' : 'function';
907
            $function = 'baseurl';
-
 
908
        } else {
-
 
909
            $function = 'function';
-
 
910
        }
-
 
911
        if ($mirror) {
834
        if ($mirror) {
912
            if ($mir = $this->getMirror($mirror)) {
835
            if ($mir = $this->getMirror($mirror)) {
913
                if (isset($mir[$protocol][$function])) {
836
                if (isset($mir[$protocol][$function])) {
914
                    return $mir[$protocol][$function];
837
                    return $mir[$protocol][$function];
915
                }
838
                }
916
            }
839
            }
-
 
840
 
917
            return false;
841
            return false;
918
        }
842
        }
-
 
843
 
919
        if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) {
844
        if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) {
920
            return $this->_channelInfo['servers']['primary'][$protocol][$function];
845
            return $this->_channelInfo['servers']['primary'][$protocol][$function];
921
        } else {
-
 
922
            return false;
-
 
923
        }
846
        }
-
 
847
 
-
 
848
        return false;
924
    }
849
    }
925
 
850
 
926
    /**
851
    /**
927
     * @param string Protocol type
852
     * @param string Protocol type
928
     * @param string Function name (null to return the
853
     * @param string Function name (null to return the
929
     *               first protocol of the type requested)
854
     *               first protocol of the type requested)
930
     * @param string Mirror name, if any
855
     * @param string Mirror name, if any
931
     * @return array
856
     * @return array
932
     */
857
     */
933
     function getFunction($type, $name = null, $mirror = false)
858
     function getFunction($type, $name = null, $mirror = false)
934
     {
859
     {
935
        $protocols = $this->getFunctions($type, $mirror);
860
        $protocols = $this->getFunctions($type, $mirror);
936
        if (!$protocols) {
861
        if (!$protocols) {
937
            return false;
862
            return false;
938
        }
863
        }
-
 
864
 
939
        foreach ($protocols as $protocol) {
865
        foreach ($protocols as $protocol) {
940
            if ($name === null) {
866
            if ($name === null) {
941
                return $protocol;
867
                return $protocol;
942
            }
868
            }
-
 
869
 
943
            if ($protocol['_content'] != $name) {
870
            if ($protocol['_content'] != $name) {
944
                continue;
871
                continue;
945
            }
872
            }
-
 
873
 
946
            return $protocol;
874
            return $protocol;
947
        }
875
        }
-
 
876
 
948
        return false;
877
        return false;
949
     }
878
     }
950
 
879
 
951
    /**
880
    /**
952
     * @param string protocol type
881
     * @param string protocol type
953
     * @param string protocol name
882
     * @param string protocol name
954
     * @param string version
883
     * @param string version
955
     * @param string mirror name
884
     * @param string mirror name
956
     * @return boolean
885
     * @return boolean
957
     */
886
     */
958
    function supports($type, $name = null, $mirror = false, $version = '1.0')
887
    function supports($type, $name = null, $mirror = false, $version = '1.0')
959
    {
888
    {
960
        $protocols = $this->getFunctions($type, $mirror);
889
        $protocols = $this->getFunctions($type, $mirror);
961
        if (!$protocols) {
890
        if (!$protocols) {
962
            return false;
891
            return false;
963
        }
892
        }
-
 
893
 
964
        foreach ($protocols as $protocol) {
894
        foreach ($protocols as $protocol) {
965
            if ($protocol['attribs']['version'] != $version) {
895
            if ($protocol['attribs']['version'] != $version) {
966
                continue;
896
                continue;
967
            }
897
            }
-
 
898
 
968
            if ($name === null) {
899
            if ($name === null) {
969
                return true;
900
                return true;
970
            }
901
            }
-
 
902
 
971
            if ($protocol['_content'] != $name) {
903
            if ($protocol['_content'] != $name) {
972
                continue;
904
                continue;
973
            }
905
            }
-
 
906
 
974
            return true;
907
            return true;
975
        }
908
        }
-
 
909
 
976
        return false;
910
        return false;
977
    }
911
    }
978
 
912
 
979
    /**
913
    /**
980
     * Determines whether a channel supports Representational State Transfer (REST) protocols
914
     * Determines whether a channel supports Representational State Transfer (REST) protocols
981
     * for retrieving channel information
915
     * for retrieving channel information
982
     * @param string
916
     * @param string
983
     * @return bool
917
     * @return bool
984
     */
918
     */
985
    function supportsREST($mirror = false)
919
    function supportsREST($mirror = false)
986
    {
920
    {
987
        if ($mirror == $this->_channelInfo['name']) {
921
        if ($mirror == $this->_channelInfo['name']) {
988
            $mirror = false;
922
            $mirror = false;
989
        }
923
        }
-
 
924
 
990
        if ($mirror) {
925
        if ($mirror) {
991
            if ($mir = $this->getMirror($mirror)) {
926
            if ($mir = $this->getMirror($mirror)) {
992
                return isset($mir['rest']);
927
                return isset($mir['rest']);
993
            }
928
            }
-
 
929
 
994
            return false;
930
            return false;
995
        }
931
        }
-
 
932
 
996
        return isset($this->_channelInfo['servers']['primary']['rest']);
933
        return isset($this->_channelInfo['servers']['primary']['rest']);
997
    }
934
    }
998
 
935
 
999
    /**
936
    /**
1000
     * Get the URL to access a base resource.
937
     * Get the URL to access a base resource.
1001
     *
938
     *
1002
     * Hyperlinks in the returned xml will be used to retrieve the proper information
939
     * Hyperlinks in the returned xml will be used to retrieve the proper information
1003
     * needed.  This allows extreme extensibility and flexibility in implementation
940
     * needed.  This allows extreme extensibility and flexibility in implementation
1004
     * @param string Resource Type to retrieve
941
     * @param string Resource Type to retrieve
1005
     */
942
     */
1006
    function getBaseURL($resourceType, $mirror = false)
943
    function getBaseURL($resourceType, $mirror = false)
1007
    {
944
    {
1008
        if ($mirror == $this->_channelInfo['name']) {
945
        if ($mirror == $this->_channelInfo['name']) {
1009
            $mirror = false;
946
            $mirror = false;
1010
        }
947
        }
-
 
948
 
1011
        if ($mirror) {
949
        if ($mirror) {
1012
            if ($mir = $this->getMirror($mirror)) {
950
            $mir = $this->getMirror($mirror);
1013
                $rest = $mir['rest'];
-
 
1014
            } else {
951
            if (!$mir) {
1015
                return false;
952
                return false;
1016
            }
953
            }
-
 
954
 
1017
            $server = $mirror;
955
            $rest = $mir['rest'];
1018
        } else {
956
        } else {
1019
            $rest = $this->_channelInfo['servers']['primary']['rest'];
957
            $rest = $this->_channelInfo['servers']['primary']['rest'];
1020
            $server = $this->getServer();
-
 
1021
        }
958
        }
-
 
959
 
1022
        if (!isset($rest['baseurl'][0])) {
960
        if (!isset($rest['baseurl'][0])) {
1023
            $rest['baseurl'] = array($rest['baseurl']);
961
            $rest['baseurl'] = array($rest['baseurl']);
1024
        }
962
        }
-
 
963
 
1025
        foreach ($rest['baseurl'] as $baseurl) {
964
        foreach ($rest['baseurl'] as $baseurl) {
1026
            if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) {
965
            if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) {
1027
                return $baseurl['_content'];
966
                return $baseurl['_content'];
1028
            }
967
            }
1029
        }
968
        }
-
 
969
 
1030
        return false;
970
        return false;
1031
    }
971
    }
1032
 
972
 
1033
    /**
973
    /**
1034
     * Since REST does not implement RPC, provide this as a logical wrapper around
974
     * Since REST does not implement RPC, provide this as a logical wrapper around
1035
     * resetFunctions for REST
975
     * resetFunctions for REST
1036
     * @param string|false mirror name, if any
976
     * @param string|false mirror name, if any
1037
     */
977
     */
1038
    function resetREST($mirror = false)
978
    function resetREST($mirror = false)
1039
    {
979
    {
1040
        return $this->resetFunctions('rest', $mirror);
980
        return $this->resetFunctions('rest', $mirror);
1041
    }
981
    }
1042
 
982
 
1043
    /**
983
    /**
1044
     * Empty all protocol definitions
984
     * Empty all protocol definitions
1045
     * @param string protocol type (xmlrpc, soap)
985
     * @param string protocol type
1046
     * @param string|false mirror name, if any
986
     * @param string|false mirror name, if any
1047
     */
987
     */
1048
    function resetFunctions($type, $mirror = false)
988
    function resetFunctions($type, $mirror = false)
1049
    {
989
    {
1050
        if ($mirror) {
990
        if ($mirror) {
1051
            if (isset($this->_channelInfo['servers']['mirror'])) {
991
            if (isset($this->_channelInfo['servers']['mirror'])) {
1052
                $mirrors = $this->_channelInfo['servers']['mirror'];
992
                $mirrors = $this->_channelInfo['servers']['mirror'];
1053
                if (!isset($mirrors[0])) {
993
                if (!isset($mirrors[0])) {
1054
                    $mirrors = array($mirrors);
994
                    $mirrors = array($mirrors);
1055
                }
995
                }
-
 
996
 
1056
                foreach ($mirrors as $i => $mir) {
997
                foreach ($mirrors as $i => $mir) {
1057
                    if ($mir['attribs']['host'] == $mirror) {
998
                    if ($mir['attribs']['host'] == $mirror) {
1058
                        if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) {
999
                        if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) {
1059
                            unset($this->_channelInfo['servers']['mirror'][$i][$type]);
1000
                            unset($this->_channelInfo['servers']['mirror'][$i][$type]);
1060
                        }
1001
                        }
-
 
1002
 
1061
                        return true;
1003
                        return true;
1062
                    }
1004
                    }
1063
                }
1005
                }
-
 
1006
 
1064
                return false;
1007
                return false;
1065
            } else {
-
 
1066
                return false;
-
 
1067
            }
-
 
1068
        } else {
-
 
1069
            if (isset($this->_channelInfo['servers']['primary'][$type])) {
-
 
1070
                unset($this->_channelInfo['servers']['primary'][$type]);
-
 
1071
            }
1008
            }
-
 
1009
 
1072
            return true;
1010
            return false;
1073
        }
1011
        }
-
 
1012
 
-
 
1013
        if (isset($this->_channelInfo['servers']['primary'][$type])) {
-
 
1014
            unset($this->_channelInfo['servers']['primary'][$type]);
-
 
1015
        }
-
 
1016
 
-
 
1017
        return true;
1074
    }
1018
    }
1075
 
1019
 
1076
    /**
1020
    /**
1077
     * Set a channel's protocols to the protocols supported by pearweb
1021
     * Set a channel's protocols to the protocols supported by pearweb
1078
     */
1022
     */
1079
    function setDefaultPEARProtocols($version = '1.0', $mirror = false)
1023
    function setDefaultPEARProtocols($version = '1.0', $mirror = false)
1080
    {
1024
    {
1081
        switch ($version) {
1025
        switch ($version) {
1082
            case '1.0' :
1026
            case '1.0' :
1083
                $this->resetFunctions('xmlrpc', $mirror);
-
 
1084
                $this->resetFunctions('soap', $mirror);
-
 
1085
                $this->resetREST($mirror);
1027
                $this->resetREST($mirror);
-
 
1028
 
1086
                $this->addFunction('xmlrpc', '1.0', 'logintest', $mirror);
1029
                if (!isset($this->_channelInfo['servers'])) {
1087
                $this->addFunction('xmlrpc', '1.0', 'package.listLatestReleases', $mirror);
-
 
1088
                $this->addFunction('xmlrpc', '1.0', 'package.listAll', $mirror);
1030
                    $this->_channelInfo['servers'] = array('primary' =>
1089
                $this->addFunction('xmlrpc', '1.0', 'package.info', $mirror);
1031
                        array('rest' => array()));
1090
                $this->addFunction('xmlrpc', '1.0', 'package.getDownloadURL', $mirror);
-
 
1091
                $this->addFunction('xmlrpc', '1.1', 'package.getDownloadURL', $mirror);
1032
                } elseif (!isset($this->_channelInfo['servers']['primary'])) {
1092
                $this->addFunction('xmlrpc', '1.0', 'package.getDepDownloadURL', $mirror);
-
 
1093
                $this->addFunction('xmlrpc', '1.1', 'package.getDepDownloadURL', $mirror);
-
 
1094
                $this->addFunction('xmlrpc', '1.0', 'package.search', $mirror);
1033
                    $this->_channelInfo['servers']['primary'] = array('rest' => array());
1095
                $this->addFunction('xmlrpc', '1.0', 'channel.listAll', $mirror);
1034
                }
-
 
1035
 
1096
                return true;
1036
                return true;
1097
            break;
1037
            break;
1098
            default :
1038
            default :
1099
                return false;
1039
                return false;
1100
            break;
1040
            break;
1101
        }
1041
        }
1102
    }
1042
    }
1103
    
1043
 
1104
    /**
1044
    /**
1105
     * @return array
1045
     * @return array
1106
     */
1046
     */
1107
    function getMirrors()
1047
    function getMirrors()
1108
    {
1048
    {
1109
        if (isset($this->_channelInfo['servers']['mirror'])) {
1049
        if (isset($this->_channelInfo['servers']['mirror'])) {
1110
            $mirrors = $this->_channelInfo['servers']['mirror'];
1050
            $mirrors = $this->_channelInfo['servers']['mirror'];
1111
            if (!isset($mirrors[0])) {
1051
            if (!isset($mirrors[0])) {
1112
                $mirrors = array($mirrors);
1052
                $mirrors = array($mirrors);
1113
            }
1053
            }
-
 
1054
 
1114
            return $mirrors;
1055
            return $mirrors;
1115
        } else {
-
 
1116
            return array();
-
 
1117
        }
1056
        }
-
 
1057
 
-
 
1058
        return array();
1118
    }
1059
    }
1119
 
1060
 
1120
    /**
1061
    /**
1121
     * Get the unserialized XML representing a mirror
1062
     * Get the unserialized XML representing a mirror
1122
     * @return array|false
1063
     * @return array|false
1123
     */
1064
     */
1124
    function getMirror($server)
1065
    function getMirror($server)
1125
    {
1066
    {
1126
        foreach ($this->getMirrors() as $mirror) {
1067
        foreach ($this->getMirrors() as $mirror) {
1127
            if ($mirror['attribs']['host'] == $server) {
1068
            if ($mirror['attribs']['host'] == $server) {
1128
                return $mirror;
1069
                return $mirror;
1129
            }
1070
            }
1130
        }
1071
        }
-
 
1072
 
1131
        return false;
1073
        return false;
1132
    }
1074
    }
1133
 
1075
 
1134
    /**
1076
    /**
1135
     * @param string
1077
     * @param string
1136
     * @return string|false
1078
     * @return string|false
1137
     * @error PEAR_CHANNELFILE_ERROR_NO_NAME
1079
     * @error PEAR_CHANNELFILE_ERROR_NO_NAME
1138
     * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME
1080
     * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME
1139
     */
1081
     */
1140
    function setName($name)
1082
    function setName($name)
1141
    {
1083
    {
1142
        return $this->setServer($name);
1084
        return $this->setServer($name);
1143
    }
1085
    }
1144
 
1086
 
1145
    /**
1087
    /**
1146
     * Set the socket number (port) that is used to connect to this channel
1088
     * Set the socket number (port) that is used to connect to this channel
1147
     * @param integer
1089
     * @param integer
1148
     * @param string|false name of the mirror server, or false for the primary
1090
     * @param string|false name of the mirror server, or false for the primary
1149
     */
1091
     */
1150
    function setPort($port, $mirror = false)
1092
    function setPort($port, $mirror = false)
1151
    {
1093
    {
1152
        if ($mirror) {
1094
        if ($mirror) {
1153
            if (!isset($this->_channelInfo['servers']['mirror'])) {
1095
            if (!isset($this->_channelInfo['servers']['mirror'])) {
1154
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1096
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1155
                    array('mirror' => $mirror));
1097
                    array('mirror' => $mirror));
1156
                return false;
1098
                return false;
1157
            }
1099
            }
1158
            $setmirror = false;
-
 
-
 
1100
 
1159
            if (isset($this->_channelInfo['servers']['mirror'][0])) {
1101
            if (isset($this->_channelInfo['servers']['mirror'][0])) {
1160
                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1102
                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1161
                    if ($mirror == $mir['attribs']['host']) {
1103
                    if ($mirror == $mir['attribs']['host']) {
1162
                        $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port;
1104
                        $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port;
1163
                        return true;
1105
                        return true;
1164
                    }
1106
                    }
1165
                }
1107
                }
-
 
1108
 
1166
                return false;
1109
                return false;
1167
            } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1110
            } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1168
                $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port;
1111
                $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port;
1169
                $this->_isValid = false;
1112
                $this->_isValid = false;
1170
                return true;
1113
                return true;
1171
            }
1114
            }
1172
        }
1115
        }
-
 
1116
 
1173
        $this->_channelInfo['servers']['primary']['attribs']['port'] = $port;
1117
        $this->_channelInfo['servers']['primary']['attribs']['port'] = $port;
1174
        $this->_isValid = false;
1118
        $this->_isValid = false;
1175
        return true;
1119
        return true;
1176
    }
1120
    }
1177
 
1121
 
1178
    /**
1122
    /**
1179
     * Set the socket number (port) that is used to connect to this channel
1123
     * Set the socket number (port) that is used to connect to this channel
1180
     * @param bool Determines whether to turn on SSL support or turn it off
1124
     * @param bool Determines whether to turn on SSL support or turn it off
1181
     * @param string|false name of the mirror server, or false for the primary
1125
     * @param string|false name of the mirror server, or false for the primary
1182
     */
1126
     */
1183
    function setSSL($ssl = true, $mirror = false)
1127
    function setSSL($ssl = true, $mirror = false)
1184
    {
1128
    {
1185
        if ($mirror) {
1129
        if ($mirror) {
1186
            if (!isset($this->_channelInfo['servers']['mirror'])) {
1130
            if (!isset($this->_channelInfo['servers']['mirror'])) {
1187
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1131
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1188
                    array('mirror' => $mirror));
1132
                    array('mirror' => $mirror));
1189
                return false;
1133
                return false;
1190
            }
1134
            }
1191
            $setmirror = false;
-
 
-
 
1135
 
1192
            if (isset($this->_channelInfo['servers']['mirror'][0])) {
1136
            if (isset($this->_channelInfo['servers']['mirror'][0])) {
1193
                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1137
                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1194
                    if ($mirror == $mir['attribs']['host']) {
1138
                    if ($mirror == $mir['attribs']['host']) {
1195
                        if (!$ssl) {
1139
                        if (!$ssl) {
1196
                            if (isset($this->_channelInfo['servers']['mirror'][$i]
1140
                            if (isset($this->_channelInfo['servers']['mirror'][$i]
1197
                                  ['attribs']['ssl'])) {
1141
                                  ['attribs']['ssl'])) {
1198
                                unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']);
1142
                                unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']);
1199
                            }
1143
                            }
1200
                        } else {
1144
                        } else {
1201
                            $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes';
1145
                            $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes';
1202
                        }
1146
                        }
-
 
1147
 
1203
                        return true;
1148
                        return true;
1204
                    }
1149
                    }
1205
                }
1150
                }
-
 
1151
 
1206
                return false;
1152
                return false;
1207
            } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1153
            } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1208
                if (!$ssl) {
1154
                if (!$ssl) {
1209
                    if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) {
1155
                    if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) {
1210
                        unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']);
1156
                        unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']);
1211
                    }
1157
                    }
1212
                } else {
1158
                } else {
1213
                    $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes';
1159
                    $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes';
1214
                }
1160
                }
-
 
1161
 
1215
                $this->_isValid = false;
1162
                $this->_isValid = false;
1216
                return true;
1163
                return true;
1217
            }
1164
            }
1218
        }
1165
        }
-
 
1166
 
1219
        if ($ssl) {
1167
        if ($ssl) {
1220
            $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes';
1168
            $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes';
1221
        } else {
1169
        } else {
1222
            if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
1170
            if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
1223
                unset($this->_channelInfo['servers']['primary']['attribs']['ssl']);
1171
                unset($this->_channelInfo['servers']['primary']['attribs']['ssl']);
1224
            }
1172
            }
1225
        }
1173
        }
1226
        $this->_isValid = false;
-
 
1227
        return true;
-
 
1228
    }
-
 
1229
 
-
 
1230
    /**
-
 
1231
     * Set the socket number (port) that is used to connect to this channel
-
 
1232
     * @param integer
-
 
1233
     * @param string|false name of the mirror server, or false for the primary
-
 
1234
     */
-
 
1235
    function setPath($protocol, $path, $mirror = false)
-
 
1236
    {
-
 
1237
        if (!in_array($protocol, array('xmlrpc', 'soap'))) {
-
 
1238
            return false;
-
 
1239
        }
-
 
1240
        if ($mirror) {
-
 
1241
            if (!isset($this->_channelInfo['servers']['mirror'])) {
-
 
1242
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
-
 
1243
                    array('mirror' => $mirror));
-
 
1244
                return false;
-
 
1245
            }
-
 
1246
            $setmirror = false;
-
 
1247
            if (isset($this->_channelInfo['servers']['mirror'][0])) {
-
 
1248
                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
-
 
1249
                    if ($mirror == $mir['attribs']['host']) {
-
 
1250
                        $this->_channelInfo['servers']['mirror'][$i][$protocol]['attribs']['path'] =
-
 
1251
                            $path;
-
 
1252
                        return true;
-
 
1253
                    }
-
 
1254
                }
-
 
1255
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
-
 
1256
                    array('mirror' => $mirror));
-
 
1257
                return false;
-
 
1258
            } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
-
 
1259
                $this->_channelInfo['servers']['mirror'][$protocol]['attribs']['path'] = $path;
-
 
1260
                $this->_isValid = false;
-
 
1261
                return true;
-
 
1262
            }
-
 
1263
        }
-
 
1264
        $this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'] = $path;
1174
 
1265
        $this->_isValid = false;
1175
        $this->_isValid = false;
1266
        return true;
1176
        return true;
1267
    }
1177
    }
1268
 
1178
 
1269
    /**
1179
    /**
1270
     * @param string
1180
     * @param string
1271
     * @return string|false
1181
     * @return string|false
1272
     * @error PEAR_CHANNELFILE_ERROR_NO_SERVER
1182
     * @error PEAR_CHANNELFILE_ERROR_NO_SERVER
1273
     * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER
1183
     * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER
1274
     */
1184
     */
1275
    function setServer($server, $mirror = false)
1185
    function setServer($server, $mirror = false)
1276
    {
1186
    {
1277
        if (empty($server)) {
1187
        if (empty($server)) {
1278
            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER);
1188
            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER);
1279
            return false;
1189
            return false;
1280
        } elseif (!$this->validChannelServer($server)) {
1190
        } elseif (!$this->validChannelServer($server)) {
1281
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
1191
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
1282
                array('tag' => 'name', 'name' => $server));
1192
                array('tag' => 'name', 'name' => $server));
1283
            return false;
1193
            return false;
1284
        }
1194
        }
-
 
1195
 
1285
        if ($mirror) {
1196
        if ($mirror) {
1286
            $found = false;
1197
            $found = false;
1287
            foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1198
            foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1288
                if ($mirror == $mir['attribs']['host']) {
1199
                if ($mirror == $mir['attribs']['host']) {
1289
                    $found = true;
1200
                    $found = true;
1290
                    break;
1201
                    break;
1291
                }
1202
                }
1292
            }
1203
            }
-
 
1204
 
1293
            if (!$found) {
1205
            if (!$found) {
1294
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1206
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1295
                    array('mirror' => $mirror));
1207
                    array('mirror' => $mirror));
1296
                return false;
1208
                return false;
1297
            }
1209
            }
-
 
1210
 
1298
            $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server;
1211
            $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server;
1299
            return true;
1212
            return true;
1300
        }
1213
        }
-
 
1214
 
1301
        $this->_channelInfo['name'] = $server;
1215
        $this->_channelInfo['name'] = $server;
1302
        return true;
1216
        return true;
1303
    }
1217
    }
1304
 
1218
 
1305
    /**
1219
    /**
1306
     * @param string
1220
     * @param string
1307
     * @return boolean success
1221
     * @return boolean success
1308
     * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY
1222
     * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY
1309
     * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY
1223
     * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY
1310
     */
1224
     */
1311
    function setSummary($summary)
1225
    function setSummary($summary)
1312
    {
1226
    {
1313
        if (empty($summary)) {
1227
        if (empty($summary)) {
1314
            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
1228
            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
1315
            return false;
1229
            return false;
1316
        } elseif (strpos(trim($summary), "\n") !== false) {
1230
        } elseif (strpos(trim($summary), "\n") !== false) {
1317
            $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
1231
            $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
1318
                array('summary' => $summary));
1232
                array('summary' => $summary));
1319
        }
1233
        }
-
 
1234
 
1320
        $this->_channelInfo['summary'] = $summary;
1235
        $this->_channelInfo['summary'] = $summary;
1321
        return true;
1236
        return true;
1322
    }
1237
    }
1323
 
1238
 
1324
    /**
1239
    /**
1325
     * @param string
1240
     * @param string
1326
     * @param boolean determines whether the alias is in channel.xml or local
1241
     * @param boolean determines whether the alias is in channel.xml or local
1327
     * @return boolean success
1242
     * @return boolean success
1328
     */
1243
     */
1329
    function setAlias($alias, $local = false)
1244
    function setAlias($alias, $local = false)
1330
    {
1245
    {
1331
        if (!$this->validChannelServer($alias)) {
1246
        if (!$this->validChannelServer($alias)) {
1332
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
1247
            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
1333
                array('tag' => 'suggestedalias', 'name' => $alias));
1248
                array('tag' => 'suggestedalias', 'name' => $alias));
1334
            return false;
1249
            return false;
1335
        }
1250
        }
-
 
1251
 
1336
        if ($local) {
1252
        if ($local) {
1337
            $this->_channelInfo['localalias'] = $alias;
1253
            $this->_channelInfo['localalias'] = $alias;
1338
        } else {
1254
        } else {
1339
            $this->_channelInfo['suggestedalias'] = $alias;
1255
            $this->_channelInfo['suggestedalias'] = $alias;
1340
        }
1256
        }
-
 
1257
 
1341
        return true;
1258
        return true;
1342
    }
1259
    }
1343
 
1260
 
1344
    /**
1261
    /**
1345
     * @return string
1262
     * @return string
1346
     */
1263
     */
1347
    function getAlias()
1264
    function getAlias()
1348
    {
1265
    {
1349
        if (isset($this->_channelInfo['localalias'])) {
1266
        if (isset($this->_channelInfo['localalias'])) {
1350
            return $this->_channelInfo['localalias'];
1267
            return $this->_channelInfo['localalias'];
1351
        }
1268
        }
1352
        if (isset($this->_channelInfo['suggestedalias'])) {
1269
        if (isset($this->_channelInfo['suggestedalias'])) {
1353
            return $this->_channelInfo['suggestedalias'];
1270
            return $this->_channelInfo['suggestedalias'];
1354
        }
1271
        }
1355
        if (isset($this->_channelInfo['name'])) {
1272
        if (isset($this->_channelInfo['name'])) {
1356
            return $this->_channelInfo['name'];
1273
            return $this->_channelInfo['name'];
1357
        }
1274
        }
-
 
1275
        return '';
1358
    }
1276
    }
1359
 
1277
 
1360
    /**
1278
    /**
1361
     * Set the package validation object if it differs from PEAR's default
1279
     * Set the package validation object if it differs from PEAR's default
1362
     * The class must be includeable via changing _ in the classname to path separator,
1280
     * The class must be includeable via changing _ in the classname to path separator,
1363
     * but no checking of this is made.
1281
     * but no checking of this is made.
1364
     * @param string|false pass in false to reset to the default packagename regex
1282
     * @param string|false pass in false to reset to the default packagename regex
1365
     * @return boolean success
1283
     * @return boolean success
1366
     */
1284
     */
1367
    function setValidationPackage($validateclass, $version)
1285
    function setValidationPackage($validateclass, $version)
1368
    {
1286
    {
1369
        if (empty($validateclass)) {
1287
        if (empty($validateclass)) {
1370
            unset($this->_channelInfo['validatepackage']);
1288
            unset($this->_channelInfo['validatepackage']);
1371
        }
1289
        }
1372
        $this->_channelInfo['validatepackage'] = array('_content' => $validateclass);
1290
        $this->_channelInfo['validatepackage'] = array('_content' => $validateclass);
1373
        $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version);
1291
        $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version);
1374
    }
1292
    }
1375
 
1293
 
1376
    /**
1294
    /**
1377
     * Add a protocol to the provides section
1295
     * Add a protocol to the provides section
1378
     * @param string protocol type
1296
     * @param string protocol type
1379
     * @param string protocol version
1297
     * @param string protocol version
1380
     * @param string protocol name, if any
1298
     * @param string protocol name, if any
1381
     * @param string mirror name, if this is a mirror's protocol
1299
     * @param string mirror name, if this is a mirror's protocol
1382
     * @return bool
1300
     * @return bool
1383
     */
1301
     */
1384
    function addFunction($type, $version, $name = '', $mirror = false)
1302
    function addFunction($type, $version, $name = '', $mirror = false)
1385
    {
1303
    {
1386
        if ($mirror) {
1304
        if ($mirror) {
1387
            return $this->addMirrorFunction($mirror, $type, $version, $name);
1305
            return $this->addMirrorFunction($mirror, $type, $version, $name);
1388
        }
1306
        }
-
 
1307
 
1389
        $set = array('attribs' => array('version' => $version), '_content' => $name);
1308
        $set = array('attribs' => array('version' => $version), '_content' => $name);
1390
        if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) {
1309
        if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) {
1391
            if (!isset($this->_channelInfo['servers'])) {
1310
            if (!isset($this->_channelInfo['servers'])) {
1392
                $this->_channelInfo['servers'] = array('primary' =>
1311
                $this->_channelInfo['servers'] = array('primary' =>
1393
                    array($type => array()));
1312
                    array($type => array()));
1394
            } elseif (!isset($this->_channelInfo['servers']['primary'])) {
1313
            } elseif (!isset($this->_channelInfo['servers']['primary'])) {
1395
                $this->_channelInfo['servers']['primary'] = array($type => array());
1314
                $this->_channelInfo['servers']['primary'] = array($type => array());
1396
            }
1315
            }
-
 
1316
 
1397
            $this->_channelInfo['servers']['primary'][$type]['function'] = $set;
1317
            $this->_channelInfo['servers']['primary'][$type]['function'] = $set;
1398
            $this->_isValid = false;
1318
            $this->_isValid = false;
1399
            return true;
1319
            return true;
1400
        } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) {
1320
        } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) {
1401
            $this->_channelInfo['servers']['primary'][$type]['function'] = array(
1321
            $this->_channelInfo['servers']['primary'][$type]['function'] = array(
1402
                $this->_channelInfo['servers']['primary'][$type]['function']);
1322
                $this->_channelInfo['servers']['primary'][$type]['function']);
1403
        }
1323
        }
-
 
1324
 
1404
        $this->_channelInfo['servers']['primary'][$type]['function'][] = $set;
1325
        $this->_channelInfo['servers']['primary'][$type]['function'][] = $set;
1405
        return true;
1326
        return true;
1406
    }
1327
    }
1407
    /**
1328
    /**
1408
     * Add a protocol to a mirror's provides section
1329
     * Add a protocol to a mirror's provides section
1409
     * @param string mirror name (server)
1330
     * @param string mirror name (server)
1410
     * @param string protocol type
1331
     * @param string protocol type
1411
     * @param string protocol version
1332
     * @param string protocol version
1412
     * @param string protocol name, if any
1333
     * @param string protocol name, if any
1413
     */
1334
     */
1414
    function addMirrorFunction($mirror, $type, $version, $name = '')
1335
    function addMirrorFunction($mirror, $type, $version, $name = '')
1415
    {
1336
    {
1416
        $found = false;
-
 
1417
        if (!isset($this->_channelInfo['servers']['mirror'])) {
1337
        if (!isset($this->_channelInfo['servers']['mirror'])) {
1418
            $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1338
            $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1419
                array('mirror' => $mirror));
1339
                array('mirror' => $mirror));
1420
            return false;
1340
            return false;
1421
        }
1341
        }
-
 
1342
 
1422
        $setmirror = false;
1343
        $setmirror = false;
1423
        if (isset($this->_channelInfo['servers']['mirror'][0])) {
1344
        if (isset($this->_channelInfo['servers']['mirror'][0])) {
1424
            foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1345
            foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1425
                if ($mirror == $mir['attribs']['host']) {
1346
                if ($mirror == $mir['attribs']['host']) {
1426
                    $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
1347
                    $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
1427
                    break;
1348
                    break;
1428
                }
1349
                }
1429
            }
1350
            }
1430
        } else {
1351
        } else {
1431
            if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1352
            if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1432
                $setmirror = &$this->_channelInfo['servers']['mirror'];
1353
                $setmirror = &$this->_channelInfo['servers']['mirror'];
1433
            }
1354
            }
1434
        }
1355
        }
-
 
1356
 
1435
        if (!$setmirror) {
1357
        if (!$setmirror) {
1436
            $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1358
            $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1437
                array('mirror' => $mirror));
1359
                array('mirror' => $mirror));
1438
            return false;
1360
            return false;
1439
        }
1361
        }
-
 
1362
 
1440
        $set = array('attribs' => array('version' => $version), '_content' => $name);
1363
        $set = array('attribs' => array('version' => $version), '_content' => $name);
1441
        if (!isset($setmirror[$type]['function'])) {
1364
        if (!isset($setmirror[$type]['function'])) {
1442
            $setmirror[$type]['function'] = $set;
1365
            $setmirror[$type]['function'] = $set;
1443
            $this->_isValid = false;
1366
            $this->_isValid = false;
1444
            return true;
1367
            return true;
1445
        } elseif (!isset($setmirror[$type]['function'][0])) {
1368
        } elseif (!isset($setmirror[$type]['function'][0])) {
1446
            $setmirror[$type]['function'] = array($setmirror[$type]['function']);
1369
            $setmirror[$type]['function'] = array($setmirror[$type]['function']);
1447
        }
1370
        }
-
 
1371
 
1448
        $setmirror[$type]['function'][] = $set;
1372
        $setmirror[$type]['function'][] = $set;
1449
        $this->_isValid = false;
1373
        $this->_isValid = false;
1450
        return true;
1374
        return true;
1451
    }
1375
    }
1452
 
1376
 
1453
    /**
1377
    /**
1454
     * @param string Resource Type this url links to
1378
     * @param string Resource Type this url links to
1455
     * @param string URL
1379
     * @param string URL
1456
     * @param string|false mirror name, if this is not a primary server REST base URL
1380
     * @param string|false mirror name, if this is not a primary server REST base URL
1457
     */
1381
     */
1458
    function setBaseURL($resourceType, $url, $mirror = false)
1382
    function setBaseURL($resourceType, $url, $mirror = false)
1459
    {
1383
    {
1460
        if ($mirror) {
1384
        if ($mirror) {
1461
            $found = false;
-
 
1462
            if (!isset($this->_channelInfo['servers']['mirror'])) {
1385
            if (!isset($this->_channelInfo['servers']['mirror'])) {
1463
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1386
                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1464
                    array('mirror' => $mirror));
1387
                    array('mirror' => $mirror));
1465
                return false;
1388
                return false;
1466
            }
1389
            }
-
 
1390
 
1467
            $setmirror = false;
1391
            $setmirror = false;
1468
            if (isset($this->_channelInfo['servers']['mirror'][0])) {
1392
            if (isset($this->_channelInfo['servers']['mirror'][0])) {
1469
                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1393
                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1470
                    if ($mirror == $mir['attribs']['host']) {
1394
                    if ($mirror == $mir['attribs']['host']) {
1471
                        $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
1395
                        $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
1472
                        break;
1396
                        break;
1473
                    }
1397
                    }
1474
                }
1398
                }
1475
            } else {
1399
            } else {
1476
                if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1400
                if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1477
                    $setmirror = &$this->_channelInfo['servers']['mirror'];
1401
                    $setmirror = &$this->_channelInfo['servers']['mirror'];
1478
                }
1402
                }
1479
            }
1403
            }
1480
        } else {
1404
        } else {
1481
            $setmirror = &$this->_channelInfo['servers']['primary'];
1405
            $setmirror = &$this->_channelInfo['servers']['primary'];
1482
        }
1406
        }
-
 
1407
 
1483
        $set = array('attribs' => array('type' => $resourceType), '_content' => $url);
1408
        $set = array('attribs' => array('type' => $resourceType), '_content' => $url);
1484
        if (!isset($setmirror['rest'])) {
1409
        if (!isset($setmirror['rest'])) {
1485
            $setmirror['rest'] = array();
1410
            $setmirror['rest'] = array();
1486
        }
1411
        }
-
 
1412
 
1487
        if (!isset($setmirror['rest']['baseurl'])) {
1413
        if (!isset($setmirror['rest']['baseurl'])) {
1488
            $setmirror['rest']['baseurl'] = $set;
1414
            $setmirror['rest']['baseurl'] = $set;
1489
            $this->_isValid = false;
1415
            $this->_isValid = false;
1490
            return true;
1416
            return true;
1491
        } elseif (!isset($setmirror['rest']['baseurl'][0])) {
1417
        } elseif (!isset($setmirror['rest']['baseurl'][0])) {
1492
            $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']);
1418
            $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']);
1493
        }
1419
        }
-
 
1420
 
1494
        foreach ($setmirror['rest']['baseurl'] as $i => $url) {
1421
        foreach ($setmirror['rest']['baseurl'] as $i => $url) {
1495
            if ($url['attribs']['type'] == $resourceType) {
1422
            if ($url['attribs']['type'] == $resourceType) {
1496
                $this->_isValid = false;
1423
                $this->_isValid = false;
1497
                $setmirror['rest']['baseurl'][$i] = $set;
1424
                $setmirror['rest']['baseurl'][$i] = $set;
1498
                return true;
1425
                return true;
1499
            }
1426
            }
1500
        }
1427
        }
-
 
1428
 
1501
        $setmirror['rest']['baseurl'][] = $set;
1429
        $setmirror['rest']['baseurl'][] = $set;
1502
        $this->_isValid = false;
1430
        $this->_isValid = false;
1503
        return true;
1431
        return true;
1504
    }
1432
    }
1505
 
1433
 
1506
    /**
1434
    /**
1507
     * @param string mirror server
1435
     * @param string mirror server
1508
     * @param int mirror http port
1436
     * @param int mirror http port
1509
     * @return boolean
1437
     * @return boolean
1510
     */
1438
     */
1511
    function addMirror($server, $port = null)
1439
    function addMirror($server, $port = null)
1512
    {
1440
    {
1513
        if ($this->_channelInfo['name'] == '__uri') {
1441
        if ($this->_channelInfo['name'] == '__uri') {
1514
            return false; // the __uri channel cannot have mirrors by definition
1442
            return false; // the __uri channel cannot have mirrors by definition
1515
        }
1443
        }
-
 
1444
 
1516
        $set = array('attribs' => array('host' => $server));
1445
        $set = array('attribs' => array('host' => $server));
1517
        if (is_numeric($port)) {
1446
        if (is_numeric($port)) {
1518
            $set['attribs']['port'] = $port;
1447
            $set['attribs']['port'] = $port;
1519
        }
1448
        }
-
 
1449
 
1520
        if (!isset($this->_channelInfo['servers']['mirror'])) {
1450
        if (!isset($this->_channelInfo['servers']['mirror'])) {
1521
            $this->_channelInfo['servers']['mirror'] = $set;
1451
            $this->_channelInfo['servers']['mirror'] = $set;
1522
            return true;
1452
            return true;
1523
        } else {
-
 
1524
            if (!isset($this->_channelInfo['servers']['mirror'][0])) {
-
 
1525
                $this->_channelInfo['servers']['mirror'] =
-
 
1526
                    array($this->_channelInfo['servers']['mirror']);
-
 
1527
            }
-
 
1528
        }
1453
        }
-
 
1454
 
-
 
1455
        if (!isset($this->_channelInfo['servers']['mirror'][0])) {
-
 
1456
            $this->_channelInfo['servers']['mirror'] =
-
 
1457
                array($this->_channelInfo['servers']['mirror']);
-
 
1458
        }
-
 
1459
 
1529
        $this->_channelInfo['servers']['mirror'][] = $set;
1460
        $this->_channelInfo['servers']['mirror'][] = $set;
1530
        return true;
1461
        return true;
1531
    }
1462
    }
1532
 
1463
 
1533
    /**
1464
    /**
1534
     * Retrieve the name of the validation package for this channel
1465
     * Retrieve the name of the validation package for this channel
1535
     * @return string|false
1466
     * @return string|false
1536
     */
1467
     */
1537
    function getValidationPackage()
1468
    function getValidationPackage()
1538
    {
1469
    {
1539
        if (!$this->_isValid && !$this->validate()) {
1470
        if (!$this->_isValid && !$this->validate()) {
1540
            return false;
1471
            return false;
1541
        }
1472
        }
-
 
1473
 
1542
        if (!isset($this->_channelInfo['validatepackage'])) {
1474
        if (!isset($this->_channelInfo['validatepackage'])) {
1543
            return array('attribs' => array('version' => 'default'),
1475
            return array('attribs' => array('version' => 'default'),
1544
                '_content' => 'PEAR_Validate');
1476
                '_content' => 'PEAR_Validate');
1545
        }
1477
        }
-
 
1478
 
1546
        return $this->_channelInfo['validatepackage'];
1479
        return $this->_channelInfo['validatepackage'];
1547
    }
1480
    }
1548
 
1481
 
1549
    /**
1482
    /**
1550
     * Retrieve the object that can be used for custom validation
1483
     * Retrieve the object that can be used for custom validation
1551
     * @param string|false the name of the package to validate.  If the package is
1484
     * @param string|false the name of the package to validate.  If the package is
1552
     *                     the channel validation package, PEAR_Validate is returned
1485
     *                     the channel validation package, PEAR_Validate is returned
1553
     * @return PEAR_Validate|false false is returned if the validation package
1486
     * @return PEAR_Validate|false false is returned if the validation package
1554
     *         cannot be located
1487
     *         cannot be located
1555
     */
1488
     */
1556
    function &getValidationObject($package = false)
1489
    function &getValidationObject($package = false)
1557
    {
1490
    {
1558
        if (!class_exists('PEAR_Validate')) {
1491
        if (!class_exists('PEAR_Validate')) {
1559
            require_once 'PEAR/Validate.php';
1492
            require_once 'PEAR/Validate.php';
1560
        }
1493
        }
-
 
1494
 
1561
        if (!$this->_isValid) {
1495
        if (!$this->_isValid) {
1562
            if (!$this->validate()) {
1496
            if (!$this->validate()) {
1563
                $a = false;
1497
                $a = false;
1564
                return $a;
1498
                return $a;
1565
            }
1499
            }
1566
        }
1500
        }
-
 
1501
 
1567
        if (isset($this->_channelInfo['validatepackage'])) {
1502
        if (isset($this->_channelInfo['validatepackage'])) {
1568
            if ($package == $this->_channelInfo['validatepackage']) {
1503
            if ($package == $this->_channelInfo['validatepackage']) {
1569
                // channel validation packages are always validated by PEAR_Validate
1504
                // channel validation packages are always validated by PEAR_Validate
1570
                $val = &new PEAR_Validate;
1505
                $val = new PEAR_Validate;
1571
                return $val;
1506
                return $val;
1572
            }
1507
            }
-
 
1508
 
1573
            if (!class_exists(str_replace('.', '_',
1509
            if (!class_exists(str_replace('.', '_',
1574
                  $this->_channelInfo['validatepackage']['_content']))) {
1510
                  $this->_channelInfo['validatepackage']['_content']))) {
1575
                if ($this->isIncludeable(str_replace('_', '/',
1511
                if ($this->isIncludeable(str_replace('_', '/',
1576
                      $this->_channelInfo['validatepackage']['_content']) . '.php')) {
1512
                      $this->_channelInfo['validatepackage']['_content']) . '.php')) {
1577
                    include_once str_replace('_', '/',
1513
                    include_once str_replace('_', '/',
1578
                        $this->_channelInfo['validatepackage']['_content']) . '.php';
1514
                        $this->_channelInfo['validatepackage']['_content']) . '.php';
1579
                    $vclass = str_replace('.', '_',
1515
                    $vclass = str_replace('.', '_',
1580
                        $this->_channelInfo['validatepackage']['_content']);
1516
                        $this->_channelInfo['validatepackage']['_content']);
1581
                    $val = &new $vclass;
1517
                    $val = new $vclass;
1582
                } else {
1518
                } else {
1583
                    $a = false;
1519
                    $a = false;
1584
                    return $a;
1520
                    return $a;
1585
                }
1521
                }
1586
            } else {
1522
            } else {
1587
                $vclass = str_replace('.', '_',
1523
                $vclass = str_replace('.', '_',
1588
                    $this->_channelInfo['validatepackage']['_content']);
1524
                    $this->_channelInfo['validatepackage']['_content']);
1589
                $val = &new $vclass;
1525
                $val = new $vclass;
1590
            }
1526
            }
1591
        } else {
1527
        } else {
1592
            $val = &new PEAR_Validate;
1528
            $val = new PEAR_Validate;
1593
        }
1529
        }
-
 
1530
 
1594
        return $val;
1531
        return $val;
1595
    }
1532
    }
1596
 
1533
 
1597
    function isIncludeable($path)
1534
    function isIncludeable($path)
1598
    {
1535
    {
1599
        $possibilities = explode(PATH_SEPARATOR, ini_get('include_path'));
1536
        $possibilities = explode(PATH_SEPARATOR, ini_get('include_path'));
1600
        foreach ($possibilities as $dir) {
1537
        foreach ($possibilities as $dir) {
1601
            if (file_exists($dir . DIRECTORY_SEPARATOR . $path)
1538
            if (file_exists($dir . DIRECTORY_SEPARATOR . $path)
1602
                  && is_readable($dir . DIRECTORY_SEPARATOR . $path)) {
1539
                  && is_readable($dir . DIRECTORY_SEPARATOR . $path)) {
1603
                return true;
1540
                return true;
1604
            }
1541
            }
1605
        }
1542
        }
-
 
1543
 
1606
        return false;
1544
        return false;
1607
    }
1545
    }
1608
 
1546
 
1609
    /**
1547
    /**
1610
     * This function is used by the channel updater and retrieves a value set by
1548
     * This function is used by the channel updater and retrieves a value set by
1611
     * the registry, or the current time if it has not been set
1549
     * the registry, or the current time if it has not been set
1612
     * @return string
1550
     * @return string
1613
     */
1551
     */
1614
    function lastModified()
1552
    function lastModified()
1615
    {
1553
    {
1616
        if (isset($this->_channelInfo['_lastmodified'])) {
1554
        if (isset($this->_channelInfo['_lastmodified'])) {
1617
            return $this->_channelInfo['_lastmodified'];
1555
            return $this->_channelInfo['_lastmodified'];
1618
        }
1556
        }
-
 
1557
 
1619
        return time();
1558
        return time();
1620
    }
1559
    }
1621
}
1560
}
1622
?>
-