Хранилища Subversion ant

Редакция

Редакция 69 | Только различия | Не учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS

Редакция 69 Редакция 94
1
<?php
1
<?php
2
/**
2
/**
3
 * PEAR_Dependency
3
 * PEAR_Dependency
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
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:
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
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
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.
11
 * send a note to license@php.net so we can mail you a copy immediately.
12
 *
12
 *
13
 * THIS FILE IS DEPRECATED IN FAVOR OF DEPENDENCY2.PHP, AND IS NOT USED IN THE INSTALLER
13
 * THIS FILE IS DEPRECATED IN FAVOR OF DEPENDENCY2.PHP, AND IS NOT USED IN THE INSTALLER
14
 *
14
 *
15
 * @category   pear
15
 * @category   pear
16
 * @package    PEAR
16
 * @package    PEAR
17
 * @author     Tomas V.V.Cox <cox@idecnet.com>
17
 * @author     Tomas V.V.Cox <cox@idecnet.com>
18
 * @author     Stig Bakken <ssb@php.net>
18
 * @author     Stig Bakken <ssb@php.net>
19
 * @copyright  1997-2008 The PHP Group
19
 * @copyright  1997-2008 The PHP Group
20
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
20
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
21
 * @version    CVS: $Id: Dependency.php,v 1.43 2008/01/03 20:26:34 cellog Exp $
21
 * @version    CVS: $Id: Dependency.php,v 1.43 2008/01/03 20:26:34 cellog Exp $
22
 * @link       http://pear.php.net/package/PEAR
22
 * @link       http://pear.php.net/package/PEAR
23
 * @since      File available since Release 1.4.0a1
23
 * @since      File available since Release 1.4.0a1
24
 */
24
 */
25
25
26
require_once "PEAR.php";
26
require_once "PEAR.php";
27
require_once "OS/Guess.php";
27
require_once "OS/Guess.php";
28
28
29
define('PEAR_DEPENDENCY_MISSING',        -1);
29
define('PEAR_DEPENDENCY_MISSING',        -1);
30
define('PEAR_DEPENDENCY_CONFLICT',       -2);
30
define('PEAR_DEPENDENCY_CONFLICT',       -2);
31
define('PEAR_DEPENDENCY_UPGRADE_MINOR',  -3);
31
define('PEAR_DEPENDENCY_UPGRADE_MINOR',  -3);
32
define('PEAR_DEPENDENCY_UPGRADE_MAJOR',  -4);
32
define('PEAR_DEPENDENCY_UPGRADE_MAJOR',  -4);
33
define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5);
33
define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5);
34
define('PEAR_DEPENDENCY_MISSING_OPTIONAL', -6);
34
define('PEAR_DEPENDENCY_MISSING_OPTIONAL', -6);
35
define('PEAR_DEPENDENCY_CONFLICT_OPTIONAL',       -7);
35
define('PEAR_DEPENDENCY_CONFLICT_OPTIONAL',       -7);
36
define('PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL',  -8);
36
define('PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL',  -8);
37
define('PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL',  -9);
37
define('PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL',  -9);
38
38
39
/**
39
/**
40
 * Dependency check for PEAR packages
40
 * Dependency check for PEAR packages
41
 *
41
 *
42
 * The class is based on the dependency RFC that can be found at
42
 * The class is based on the dependency RFC that can be found at
43
 * http://cvs.php.net/cvs.php/pearweb/rfc. It requires PHP >= 4.1
43
 * http://cvs.php.net/cvs.php/pearweb/rfc. It requires PHP >= 4.1
44
 *
44
 *
45
 * @author Tomas V.V.Vox <cox@idecnet.com>
45
 * @author Tomas V.V.Vox <cox@idecnet.com>
46
 * @author Stig Bakken <ssb@php.net>
46
 * @author Stig Bakken <ssb@php.net>
47
 */
47
 */
48
class PEAR_Dependency
48
class PEAR_Dependency
49
{
49
{
50
    // {{{ constructor
50
    // {{{ constructor
51
    /**
51
    /**
52
     * Constructor
52
     * Constructor
53
     *
53
     *
54
     * @access public
54
     * @access public
55
     * @param  object Registry object
55
     * @param  object Registry object
56
     * @return void
56
     * @return void
57
     */
57
     */
58
    function PEAR_Dependency(&$registry)
58
    function PEAR_Dependency(&$registry)
59
    {
59
    {
60
        $this->registry = &$registry;
60
        $this->registry = &$registry;
61
    }
61
    }
62
62
63
    // }}}
63
    // }}}
64
    // {{{ callCheckMethod()
64
    // {{{ callCheckMethod()
65
65
66
    /**
66
    /**
67
    * This method maps the XML dependency definition to the
67
    * This method maps the XML dependency definition to the
68
    * corresponding one from PEAR_Dependency
68
    * corresponding one from PEAR_Dependency
69
    *
69
    *
70
    * <pre>
70
    * <pre>
71
    * $opts => Array
71
    * $opts => Array
72
    *    (
72
    *    (
73
    *        [type] => pkg
73
    *        [type] => pkg
74
    *        [rel] => ge
74
    *        [rel] => ge
75
    *        [version] => 3.4
75
    *        [version] => 3.4
76
    *        [name] => HTML_Common
76
    *        [name] => HTML_Common
77
    *        [optional] => false
77
    *        [optional] => false
78
    *    )
78
    *    )
79
    * </pre>
79
    * </pre>
80
    *
80
    *
81
    * @param  string Error message
81
    * @param  string Error message
82
    * @param  array  Options
82
    * @param  array  Options
83
    * @return boolean
83
    * @return boolean
84
    */
84
    */
85
    function callCheckMethod(&$errmsg, $opts)
85
    function callCheckMethod(&$errmsg, $opts)
86
    {
86
    {
87
        $rel = isset($opts['rel']) ? $opts['rel'] : 'has';
87
        $rel = isset($opts['rel']) ? $opts['rel'] : 'has';
88
        $req = isset($opts['version']) ? $opts['version'] : null;
88
        $req = isset($opts['version']) ? $opts['version'] : null;
89
        $name = isset($opts['name']) ? $opts['name'] : null;
89
        $name = isset($opts['name']) ? $opts['name'] : null;
90
        $channel = isset($opts['channel']) ? $opts['channel'] : 'pear.php.net';
90
        $channel = isset($opts['channel']) ? $opts['channel'] : 'pear.php.net';
91
        $opt = (isset($opts['optional']) && $opts['optional'] == 'yes') ?
91
        $opt = (isset($opts['optional']) && $opts['optional'] == 'yes') ?
92
            $opts['optional'] : null;
92
            $opts['optional'] : null;
93
        $errmsg = '';
93
        $errmsg = '';
94
        switch ($opts['type']) {
94
        switch ($opts['type']) {
95
            case 'pkg':
95
            case 'pkg':
96
                return $this->checkPackage($errmsg, $name, $req, $rel, $opt, $channel);
96
                return $this->checkPackage($errmsg, $name, $req, $rel, $opt, $channel);
97
                break;
97
                break;
98
            case 'ext':
98
            case 'ext':
99
                return $this->checkExtension($errmsg, $name, $req, $rel, $opt);
99
                return $this->checkExtension($errmsg, $name, $req, $rel, $opt);
100
                break;
100
                break;
101
            case 'php':
101
            case 'php':
102
                return $this->checkPHP($errmsg, $req, $rel);
102
                return $this->checkPHP($errmsg, $req, $rel);
103
                break;
103
                break;
104
            case 'prog':
104
            case 'prog':
105
                return $this->checkProgram($errmsg, $name);
105
                return $this->checkProgram($errmsg, $name);
106
                break;
106
                break;
107
            case 'os':
107
            case 'os':
108
                return $this->checkOS($errmsg, $name);
108
                return $this->checkOS($errmsg, $name);
109
                break;
109
                break;
110
            case 'sapi':
110
            case 'sapi':
111
                return $this->checkSAPI($errmsg, $name);
111
                return $this->checkSAPI($errmsg, $name);
112
                break;
112
                break;
113
            case 'zend':
113
            case 'zend':
114
                return $this->checkZend($errmsg, $name);
114
                return $this->checkZend($errmsg, $name);
115
                break;
115
                break;
116
            default:
116
            default:
117
                return "'{$opts['type']}' dependency type not supported";
117
                return "'{$opts['type']}' dependency type not supported";
118
        }
118
        }
119
    }
119
    }
120
120
121
    // }}}
121
    // }}}
122
    // {{{ checkPackage()
122
    // {{{ checkPackage()
123
123
124
    /**
124
    /**
125
     * Package dependencies check method
125
     * Package dependencies check method
126
     *
126
     *
127
     * @param string $errmsg    Empty string, it will be populated with an error message, if any
127
     * @param string $errmsg    Empty string, it will be populated with an error message, if any
128
     * @param string $name      Name of the package to test
128
     * @param string $name      Name of the package to test
129
     * @param string $req       The package version required
129
     * @param string $req       The package version required
130
     * @param string $relation  How to compare versions with each other
130
     * @param string $relation  How to compare versions with each other
131
     * @param bool   $opt       Whether the relationship is optional
131
     * @param bool   $opt       Whether the relationship is optional
132
     * @param string $channel   Channel name
132
     * @param string $channel   Channel name
133
     *
133
     *
134
     * @return mixed bool false if no error or the error string
134
     * @return mixed bool false if no error or the error string
135
     */
135
     */
136
    function checkPackage(&$errmsg, $name, $req = null, $relation = 'has',
136
    function checkPackage(&$errmsg, $name, $req = null, $relation = 'has',
137
                          $opt = false, $channel = 'pear.php.net')
137
                          $opt = false, $channel = 'pear.php.net')
138
    {
138
    {
139
        if (is_string($req) && substr($req, 0, 2) == 'v.') {
139
        if (is_string($req) && substr($req, 0, 2) == 'v.') {
140
            $req = substr($req, 2);
140
            $req = substr($req, 2);
141
        }
141
        }
142
        switch ($relation) {
142
        switch ($relation) {
143
            case 'has':
143
            case 'has':
144
                if (!$this->registry->packageExists($name, $channel)) {
144
                if (!$this->registry->packageExists($name, $channel)) {
145
                    if ($opt) {
145
                    if ($opt) {
146
                        $errmsg = "package `$channel/$name' is recommended to utilize some features.";
146
                        $errmsg = "package `$channel/$name' is recommended to utilize some features.";
147
                        return PEAR_DEPENDENCY_MISSING_OPTIONAL;
147
                        return PEAR_DEPENDENCY_MISSING_OPTIONAL;
148
                    }
148
                    }
149
                    $errmsg = "requires package `$channel/$name'";
149
                    $errmsg = "requires package `$channel/$name'";
150
                    return PEAR_DEPENDENCY_MISSING;
150
                    return PEAR_DEPENDENCY_MISSING;
151
                }
151
                }
152
                return false;
152
                return false;
153
            case 'not':
153
            case 'not':
154
                if ($this->registry->packageExists($name, $channel)) {
154
                if ($this->registry->packageExists($name, $channel)) {
155
                    $errmsg = "conflicts with package `$channel/$name'";
155
                    $errmsg = "conflicts with package `$channel/$name'";
156
                    return PEAR_DEPENDENCY_CONFLICT;
156
                    return PEAR_DEPENDENCY_CONFLICT;
157
                }
157
                }
158
                return false;
158
                return false;
159
            case 'lt':
159
            case 'lt':
160
            case 'le':
160
            case 'le':
161
            case 'eq':
161
            case 'eq':
162
            case 'ne':
162
            case 'ne':
163
            case 'ge':
163
            case 'ge':
164
            case 'gt':
164
            case 'gt':
165
                $version = $this->registry->packageInfo($name, 'version', $channel);
165
                $version = $this->registry->packageInfo($name, 'version', $channel);
166
                if (!$this->registry->packageExists($name, $channel)
166
                if (!$this->registry->packageExists($name, $channel)
167
                    || !version_compare("$version", "$req", $relation))
167
                    || !version_compare("$version", "$req", $relation))
168
                {
168
                {
169
                    $code = $this->codeFromRelation($relation, $version, $req, $opt);
169
                    $code = $this->codeFromRelation($relation, $version, $req, $opt);
170
                    if ($opt) {
170
                    if ($opt) {
171
                        $errmsg = "package `$channel/$name' version " . $this->signOperator($relation) .
171
                        $errmsg = "package `$channel/$name' version " . $this->signOperator($relation) .
172
                            " $req is recommended to utilize some features.";
172
                            " $req is recommended to utilize some features.";
173
                        if ($version) {
173
                        if ($version) {
174
                            $errmsg .= "  Installed version is $version";
174
                            $errmsg .= "  Installed version is $version";
175
                        }
175
                        }
176
                        return $code;
176
                        return $code;
177
                    }
177
                    }
178
                    $errmsg = "requires package `$channel/$name' " .
178
                    $errmsg = "requires package `$channel/$name' " .
179
                        $this->signOperator($relation) . " $req";
179
                        $this->signOperator($relation) . " $req";
180
                    return $code;
180
                    return $code;
181
                }
181
                }
182
                return false;
182
                return false;
183
        }
183
        }
184
        $errmsg = "relation '$relation' with requirement '$req' is not supported (name=$channel/$name)";
184
        $errmsg = "relation '$relation' with requirement '$req' is not supported (name=$channel/$name)";
185
        return PEAR_DEPENDENCY_BAD_DEPENDENCY;
185
        return PEAR_DEPENDENCY_BAD_DEPENDENCY;
186
    }
186
    }
187
187
188
    // }}}
188
    // }}}
189
    // {{{ checkPackageUninstall()
189
    // {{{ checkPackageUninstall()
190
190
191
    /**
191
    /**
192
     * Check package dependencies on uninstall
192
     * Check package dependencies on uninstall
193
     *
193
     *
194
     * @param string $error     The resultant error string
194
     * @param string $error     The resultant error string
195
     * @param string $warning   The resultant warning string
195
     * @param string $warning   The resultant warning string
196
     * @param string $name      Name of the package to test
196
     * @param string $name      Name of the package to test
197
     * @param string $channel   Channel name of the package
197
     * @param string $channel   Channel name of the package
198
     *
198
     *
199
     * @return bool true if there were errors
199
     * @return bool true if there were errors
200
     */
200
     */
201
    function checkPackageUninstall(&$error, &$warning, $package, $channel = 'pear.php.net')
201
    function checkPackageUninstall(&$error, &$warning, $package, $channel = 'pear.php.net')
202
    {
202
    {
203
        $channel = strtolower($channel);
203
        $channel = strtolower($channel);
204
        $error = null;
204
        $error = null;
205
        $channels = $this->registry->listAllPackages();
205
        $channels = $this->registry->listAllPackages();
206
        foreach ($channels as $channelname => $packages) {
206
        foreach ($channels as $channelname => $packages) {
207
            foreach ($packages as $pkg) {
207
            foreach ($packages as $pkg) {
208
                if ($pkg == $package && $channel == $channelname) {
208
                if ($pkg == $package && $channel == $channelname) {
209
                    continue;
209
                    continue;
210
                }
210
                }
211
                $deps = $this->registry->packageInfo($pkg, 'release_deps', $channel);
211
                $deps = $this->registry->packageInfo($pkg, 'release_deps', $channel);
212
                if (empty($deps)) {
212
                if (empty($deps)) {
213
                    continue;
213
                    continue;
214
                }
214
                }
215
                foreach ($deps as $dep) {
215
                foreach ($deps as $dep) {
216
                    $depchannel = isset($dep['channel']) ? $dep['channel'] : 'pear.php.net';
216
                    $depchannel = isset($dep['channel']) ? $dep['channel'] : 'pear.php.net';
217
                    if ($dep['type'] == 'pkg' && (strcasecmp($dep['name'], $package) == 0) &&
217
                    if ($dep['type'] == 'pkg' && (strcasecmp($dep['name'], $package) == 0) &&
218
                          ($depchannel == $channel)) {
218
                          ($depchannel == $channel)) {
219
                        if ($dep['rel'] == 'ne') {
219
                        if ($dep['rel'] == 'ne') {
220
                            continue;
220
                            continue;
221
                        }
221
                        }
222
                        if (isset($dep['optional']) && $dep['optional'] == 'yes') {
222
                        if (isset($dep['optional']) && $dep['optional'] == 'yes') {
223
                            $warning .= "\nWarning: Package '$depchannel/$pkg' optionally depends on '$channel:/package'";
223
                            $warning .= "\nWarning: Package '$depchannel/$pkg' optionally depends on '$channel:/package'";
224
                        } else {
224
                        } else {
225
                            $error .= "Package '$depchannel/$pkg' depends on '$channel/$package'\n";
225
                            $error .= "Package '$depchannel/$pkg' depends on '$channel/$package'\n";
226
                        }
226
                        }
227
                    }
227
                    }
228
                }
228
                }
229
            }
229
            }
230
        }
230
        }
231
        return ($error) ? true : false;
231
        return ($error) ? true : false;
232
    }
232
    }
233
233
234
    // }}}
234
    // }}}
235
    // {{{ checkExtension()
235
    // {{{ checkExtension()
236
236
237
    /**
237
    /**
238
     * Extension dependencies check method
238
     * Extension dependencies check method
239
     *
239
     *
240
     * @param string $name        Name of the extension to test
240
     * @param string $name        Name of the extension to test
241
     * @param string $req_ext_ver Required extension version to compare with
241
     * @param string $req_ext_ver Required extension version to compare with
242
     * @param string $relation    How to compare versions with eachother
242
     * @param string $relation    How to compare versions with eachother
243
     * @param bool   $opt         Whether the relationship is optional
243
     * @param bool   $opt         Whether the relationship is optional
244
     *
244
     *
245
     * @return mixed bool false if no error or the error string
245
     * @return mixed bool false if no error or the error string
246
     */
246
     */
247
    function checkExtension(&$errmsg, $name, $req = null, $relation = 'has',
247
    function checkExtension(&$errmsg, $name, $req = null, $relation = 'has',
248
        $opt = false)
248
        $opt = false)
249
    {
249
    {
250
        if ($relation == 'not') {
250
        if ($relation == 'not') {
251
            if (extension_loaded($name)) {
251
            if (extension_loaded($name)) {
252
                $errmsg = "conflicts with  PHP extension '$name'";
252
                $errmsg = "conflicts with  PHP extension '$name'";
253
                return PEAR_DEPENDENCY_CONFLICT;
253
                return PEAR_DEPENDENCY_CONFLICT;
254
            } else {
254
            } else {
255
                return false;
255
                return false;
256
            }
256
            }
257
        }
257
        }
258
258
259
        if (!extension_loaded($name)) {
259
        if (!extension_loaded($name)) {
260
            if ($relation == 'ne') {
260
            if ($relation == 'ne') {
261
                return false;
261
                return false;
262
            }
262
            }
263
            if ($opt) {
263
            if ($opt) {
264
                $errmsg = "'$name' PHP extension is recommended to utilize some features";
264
                $errmsg = "'$name' PHP extension is recommended to utilize some features";
265
                return PEAR_DEPENDENCY_MISSING_OPTIONAL;
265
                return PEAR_DEPENDENCY_MISSING_OPTIONAL;
266
            }
266
            }
267
            $errmsg = "'$name' PHP extension is not installed";
267
            $errmsg = "'$name' PHP extension is not installed";
268
            return PEAR_DEPENDENCY_MISSING;
268
            return PEAR_DEPENDENCY_MISSING;
269
        }
269
        }
270
        if ($relation == 'has') {
270
        if ($relation == 'has') {
271
            return false;
271
            return false;
272
        }
272
        }
273
        $code = false;
273
        $code = false;
274
        if (is_string($req) && substr($req, 0, 2) == 'v.') {
274
        if (is_string($req) && substr($req, 0, 2) == 'v.') {
275
            $req = substr($req, 2);
275
            $req = substr($req, 2);
276
        }
276
        }
277
        $ext_ver = phpversion($name);
277
        $ext_ver = phpversion($name);
278
        $operator = $relation;
278
        $operator = $relation;
279
        // Force params to be strings, otherwise the comparation will fail (ex. 0.9==0.90)
279
        // Force params to be strings, otherwise the comparation will fail (ex. 0.9==0.90)
280
        if (!version_compare("$ext_ver", "$req", $operator)) {
280
        if (!version_compare("$ext_ver", "$req", $operator)) {
281
            $errmsg = "'$name' PHP extension version " .
281
            $errmsg = "'$name' PHP extension version " .
282
                $this->signOperator($operator) . " $req is required";
282
                $this->signOperator($operator) . " $req is required";
283
            $code = $this->codeFromRelation($relation, $ext_ver, $req, $opt);
283
            $code = $this->codeFromRelation($relation, $ext_ver, $req, $opt);
284
            if ($opt) {
284
            if ($opt) {
285
                $errmsg = "'$name' PHP extension version " . $this->signOperator($operator) .
285
                $errmsg = "'$name' PHP extension version " . $this->signOperator($operator) .
286
                    " $req is recommended to utilize some features";
286
                    " $req is recommended to utilize some features";
287
                return $code;
287
                return $code;
288
            }
288
            }
289
        }
289
        }
290
        return $code;
290
        return $code;
291
    }
291
    }
292
292
293
    // }}}
293
    // }}}
294
    // {{{ checkOS()
294
    // {{{ checkOS()
295
295
296
    /**
296
    /**
297
     * Operating system  dependencies check method
297
     * Operating system  dependencies check method
298
     *
298
     *
299
     * @param string $os  Name of the operating system
299
     * @param string $os  Name of the operating system
300
     *
300
     *
301
     * @return mixed bool false if no error or the error string
301
     * @return mixed bool false if no error or the error string
302
     */
302
     */
303
    function checkOS(&$errmsg, $os)
303
    function checkOS(&$errmsg, $os)
304
    {
304
    {
305
        // XXX Fixme: Implement a more flexible way, like
305
        // XXX Fixme: Implement a more flexible way, like
306
        // comma separated values or something similar to PEAR_OS
306
        // comma separated values or something similar to PEAR_OS
307
        static $myos;
307
        static $myos;
308
        if (empty($myos)) {
308
        if (empty($myos)) {
309
            $myos = new OS_Guess();
309
            $myos = new OS_Guess();
310
        }
310
        }
311
        // only 'has' relation is currently supported
311
        // only 'has' relation is currently supported
312
        if ($myos->matchSignature($os)) {
312
        if ($myos->matchSignature($os)) {
313
            return false;
313
            return false;
314
        }
314
        }
315
        $errmsg = "'$os' operating system not supported";
315
        $errmsg = "'$os' operating system not supported";
316
        return PEAR_DEPENDENCY_CONFLICT;
316
        return PEAR_DEPENDENCY_CONFLICT;
317
    }
317
    }
318
318
319
    // }}}
319
    // }}}
320
    // {{{ checkPHP()
320
    // {{{ checkPHP()
321
321
322
    /**
322
    /**
323
     * PHP version check method
323
     * PHP version check method
324
     *
324
     *
325
     * @param string $req   which version to compare
325
     * @param string $req   which version to compare
326
     * @param string $relation  how to compare the version
326
     * @param string $relation  how to compare the version
327
     *
327
     *
328
     * @return mixed bool false if no error or the error string
328
     * @return mixed bool false if no error or the error string
329
     */
329
     */
330
    function checkPHP(&$errmsg, $req, $relation = 'ge')
330
    function checkPHP(&$errmsg, $req, $relation = 'ge')
331
    {
331
    {
332
        // this would be a bit stupid, but oh well :)
332
        // this would be a bit stupid, but oh well :)
333
        if ($relation == 'has') {
333
        if ($relation == 'has') {
334
            return false;
334
            return false;
335
        }
335
        }
336
        if ($relation == 'not') {
336
        if ($relation == 'not') {
337
            $errmsg = "Invalid dependency - 'not' is allowed when specifying PHP, you must run PHP in PHP";
337
            $errmsg = "Invalid dependency - 'not' is allowed when specifying PHP, you must run PHP in PHP";
338
            return PEAR_DEPENDENCY_BAD_DEPENDENCY;
338
            return PEAR_DEPENDENCY_BAD_DEPENDENCY;
339
        }
339
        }
340
        if (substr($req, 0, 2) == 'v.') {
340
        if (substr($req, 0, 2) == 'v.') {
341
            $req = substr($req,2, strlen($req) - 2);
341
            $req = substr($req,2, strlen($req) - 2);
342
        }
342
        }
343
        $php_ver = phpversion();
343
        $php_ver = phpversion();
344
        $operator = $relation;
344
        $operator = $relation;
345
        if (!version_compare("$php_ver", "$req", $operator)) {
345
        if (!version_compare("$php_ver", "$req", $operator)) {
346
            $errmsg = "PHP version " . $this->signOperator($operator) .
346
            $errmsg = "PHP version " . $this->signOperator($operator) .
347
                " $req is required";
347
                " $req is required";
348
            return PEAR_DEPENDENCY_CONFLICT;
348
            return PEAR_DEPENDENCY_CONFLICT;
349
        }
349
        }
350
        return false;
350
        return false;
351
    }
351
    }
352
352
353
    // }}}
353
    // }}}
354
    // {{{ checkProgram()
354
    // {{{ checkProgram()
355
355
356
    /**
356
    /**
357
     * External program check method.  Looks for executable files in
357
     * External program check method.  Looks for executable files in
358
     * directories listed in the PATH environment variable.
358
     * directories listed in the PATH environment variable.
359
     *
359
     *
360
     * @param string $program   which program to look for
360
     * @param string $program   which program to look for
361
     *
361
     *
362
     * @return mixed bool false if no error or the error string
362
     * @return mixed bool false if no error or the error string
363
     */
363
     */
364
    function checkProgram(&$errmsg, $program)
364
    function checkProgram(&$errmsg, $program)
365
    {
365
    {
366
        // XXX FIXME honor safe mode
366
        // XXX FIXME honor safe mode
367
        $exe_suffix = OS_WINDOWS ? '.exe' : '';
367
        $exe_suffix = OS_WINDOWS ? '.exe' : '';
368
        $path_elements = explode(PATH_SEPARATOR, getenv('PATH'));
368
        $path_elements = explode(PATH_SEPARATOR, getenv('PATH'));
369
        foreach ($path_elements as $dir) {
369
        foreach ($path_elements as $dir) {
370
            $file = $dir . DIRECTORY_SEPARATOR . $program . $exe_suffix;
370
            $file = $dir . DIRECTORY_SEPARATOR . $program . $exe_suffix;
371
            if (file_exists($file) && is_executable($file)) {
371
            if (file_exists($file) && is_executable($file)) {
372
                return false;
372
                return false;
373
            }
373
            }
374
        }
374
        }
375
        $errmsg = "'$program' program is not present in the PATH";
375
        $errmsg = "'$program' program is not present in the PATH";
376
        return PEAR_DEPENDENCY_MISSING;
376
        return PEAR_DEPENDENCY_MISSING;
377
    }
377
    }
378
378
379
    // }}}
379
    // }}}
380
    // {{{ checkSAPI()
380
    // {{{ checkSAPI()
381
381
382
    /**
382
    /**
383
     * SAPI backend check method.  Version comparison is not yet
383
     * SAPI backend check method.  Version comparison is not yet
384
     * available here.
384
     * available here.
385
     *
385
     *
386
     * @param string $name      name of SAPI backend
386
     * @param string $name      name of SAPI backend
387
     * @param string $req   which version to compare
387
     * @param string $req   which version to compare
388
     * @param string $relation  how to compare versions (currently
388
     * @param string $relation  how to compare versions (currently
389
     *                          hardcoded to 'has')
389
     *                          hardcoded to 'has')
390
     * @return mixed bool false if no error or the error string
390
     * @return mixed bool false if no error or the error string
391
     */
391
     */
392
    function checkSAPI(&$errmsg, $name, $req = null, $relation = 'has')
392
    function checkSAPI(&$errmsg, $name, $req = null, $relation = 'has')
393
    {
393
    {
394
        // XXX Fixme: There is no way to know if the user has or
394
        // XXX Fixme: There is no way to know if the user has or
395
        // not other SAPI backends installed than the installer one
395
        // not other SAPI backends installed than the installer one
396
396
397
        $sapi_backend = php_sapi_name();
397
        $sapi_backend = php_sapi_name();
398
        // Version comparisons not supported, sapi backends don't have
398
        // Version comparisons not supported, sapi backends don't have
399
        // version information yet.
399
        // version information yet.
400
        if ($sapi_backend == $name) {
400
        if ($sapi_backend == $name) {
401
            return false;
401
            return false;
402
        }
402
        }
403
        $errmsg = "'$sapi_backend' SAPI backend not supported";
403
        $errmsg = "'$sapi_backend' SAPI backend not supported";
404
        return PEAR_DEPENDENCY_CONFLICT;
404
        return PEAR_DEPENDENCY_CONFLICT;
405
    }
405
    }
406
406
407
    // }}}
407
    // }}}
408
    // {{{ checkZend()
408
    // {{{ checkZend()
409
409
410
    /**
410
    /**
411
     * Zend version check method
411
     * Zend version check method
412
     *
412
     *
413
     * @param string $req   which version to compare
413
     * @param string $req   which version to compare
414
     * @param string $relation  how to compare the version
414
     * @param string $relation  how to compare the version
415
     *
415
     *
416
     * @return mixed bool false if no error or the error string
416
     * @return mixed bool false if no error or the error string
417
     */
417
     */
418
    function checkZend(&$errmsg, $req, $relation = 'ge')
418
    function checkZend(&$errmsg, $req, $relation = 'ge')
419
    {
419
    {
420
        if (substr($req, 0, 2) == 'v.') {
420
        if (substr($req, 0, 2) == 'v.') {
421
            $req = substr($req,2, strlen($req) - 2);
421
            $req = substr($req,2, strlen($req) - 2);
422
        }
422
        }
423
        $zend_ver = zend_version();
423
        $zend_ver = zend_version();
424
        $operator = substr($relation,0,2);
424
        $operator = substr($relation,0,2);
425
        if (!version_compare("$zend_ver", "$req", $operator)) {
425
        if (!version_compare("$zend_ver", "$req", $operator)) {
426
            $errmsg = "Zend version " . $this->signOperator($operator) .
426
            $errmsg = "Zend version " . $this->signOperator($operator) .
427
                " $req is required";
427
                " $req is required";
428
            return PEAR_DEPENDENCY_CONFLICT;
428
            return PEAR_DEPENDENCY_CONFLICT;
429
        }
429
        }
430
        return false;
430
        return false;
431
    }
431
    }
432
432
433
    // }}}
433
    // }}}
434
    // {{{ signOperator()
434
    // {{{ signOperator()
435
435
436
    /**
436
    /**
437
     * Converts text comparing operators to them sign equivalents
437
     * Converts text comparing operators to them sign equivalents
438
     *
438
     *
439
     * Example: 'ge' to '>='
439
     * Example: 'ge' to '>='
440
     *
440
     *
441
     * @access public
441
     * @access public
442
     * @param  string Operator
442
     * @param  string Operator
443
     * @return string Sign equivalent
443
     * @return string Sign equivalent
444
     */
444
     */
445
    function signOperator($operator)
445
    function signOperator($operator)
446
    {
446
    {
447
        switch($operator) {
447
        switch($operator) {
448
            case 'lt': return '<';
448
            case 'lt': return '<';
449
            case 'le': return '<=';
449
            case 'le': return '<=';
450
            case 'gt': return '>';
450
            case 'gt': return '>';
451
            case 'ge': return '>=';
451
            case 'ge': return '>=';
452
            case 'eq': return '==';
452
            case 'eq': return '==';
453
            case 'ne': return '!=';
453
            case 'ne': return '!=';
454
            default:
454
            default:
455
                return $operator;
455
                return $operator;
456
        }
456
        }
457
    }
457
    }
458
458
459
    // }}}
459
    // }}}
460
    // {{{ codeFromRelation()
460
    // {{{ codeFromRelation()
461
461
462
    /**
462
    /**
463
     * Convert relation into corresponding code
463
     * Convert relation into corresponding code
464
     *
464
     *
465
     * @access public
465
     * @access public
466
     * @param  string Relation
466
     * @param  string Relation
467
     * @param  string Version
467
     * @param  string Version
468
     * @param  string Requirement
468
     * @param  string Requirement
469
     * @param  bool   Optional dependency indicator
469
     * @param  bool   Optional dependency indicator
470
     * @return integer
470
     * @return integer
471
     */
471
     */
472
    function codeFromRelation($relation, $version, $req, $opt = false)
472
    function codeFromRelation($relation, $version, $req, $opt = false)
473
    {
473
    {
474
        $code = PEAR_DEPENDENCY_BAD_DEPENDENCY;
474
        $code = PEAR_DEPENDENCY_BAD_DEPENDENCY;
475
        switch ($relation) {
475
        switch ($relation) {
476
            case 'gt': case 'ge': case 'eq':
476
            case 'gt': case 'ge': case 'eq':
477
                // upgrade
477
                // upgrade
478
                $have_major = preg_replace('/\D.*/', '', $version);
478
                $have_major = preg_replace('/\D.*/', '', $version);
479
                $need_major = preg_replace('/\D.*/', '', $req);
479
                $need_major = preg_replace('/\D.*/', '', $req);
480
                if ($need_major > $have_major) {
480
                if ($need_major > $have_major) {
481
                    $code = $opt ? PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL :
481
                    $code = $opt ? PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL :
482
                                   PEAR_DEPENDENCY_UPGRADE_MAJOR;
482
                                   PEAR_DEPENDENCY_UPGRADE_MAJOR;
483
                } else {
483
                } else {
484
                    $code = $opt ? PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL :
484
                    $code = $opt ? PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL :
485
                                   PEAR_DEPENDENCY_UPGRADE_MINOR;
485
                                   PEAR_DEPENDENCY_UPGRADE_MINOR;
486
                }
486
                }
487
                break;
487
                break;
488
            case 'lt': case 'le': case 'ne':
488
            case 'lt': case 'le': case 'ne':
489
                $code = $opt ? PEAR_DEPENDENCY_CONFLICT_OPTIONAL :
489
                $code = $opt ? PEAR_DEPENDENCY_CONFLICT_OPTIONAL :
490
                               PEAR_DEPENDENCY_CONFLICT;
490
                               PEAR_DEPENDENCY_CONFLICT;
491
                break;
491
                break;
492
        }
492
        }
493
        return $code;
493
        return $code;
494
    }
494
    }
495
495
496
    // }}}
496
    // }}}
497
}
497
}
498
?>
498
?>
499
 
499