Хранилища Subversion ant

Редакция

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

Редакция 69 Редакция 94
1
<?php
1
<?php
2
/**
2
/**
3
 * PEAR_DependencyDB, advanced installed packages dependency database
3
 * PEAR_DependencyDB, advanced installed packages dependency database
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
 * @category   pear
13
 * @category   pear
14
 * @package    PEAR
14
 * @package    PEAR
15
 * @author     Tomas V. V. Cox <cox@idecnet.com>
15
 * @author     Tomas V. V. Cox <cox@idecnet.com>
16
 * @author     Greg Beaver <cellog@php.net>
16
 * @author     Greg Beaver <cellog@php.net>
17
 * @copyright  1997-2008 The PHP Group
17
 * @copyright  1997-2008 The PHP Group
18
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
18
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
19
 * @version    CVS: $Id: DependencyDB.php,v 1.37 2008/01/03 20:26:35 cellog Exp $
19
 * @version    CVS: $Id: DependencyDB.php,v 1.37 2008/01/03 20:26:35 cellog Exp $
20
 * @link       http://pear.php.net/package/PEAR
20
 * @link       http://pear.php.net/package/PEAR
21
 * @since      File available since Release 1.4.0a1
21
 * @since      File available since Release 1.4.0a1
22
 */
22
 */
23
23
24
/**
24
/**
25
 * Needed for error handling
25
 * Needed for error handling
26
 */
26
 */
27
require_once 'PEAR.php';
27
require_once 'PEAR.php';
28
require_once 'PEAR/Config.php';
28
require_once 'PEAR/Config.php';
29
29
30
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array();
30
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array();
31
/**
31
/**
32
 * Track dependency relationships between installed packages
32
 * Track dependency relationships between installed packages
33
 * @category   pear
33
 * @category   pear
34
 * @package    PEAR
34
 * @package    PEAR
35
 * @author     Greg Beaver <cellog@php.net>
35
 * @author     Greg Beaver <cellog@php.net>
36
 * @author     Tomas V.V.Cox <cox@idec.net.com>
36
 * @author     Tomas V.V.Cox <cox@idec.net.com>
37
 * @copyright  1997-2008 The PHP Group
37
 * @copyright  1997-2008 The PHP Group
38
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
38
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
39
 * @version    Release: 1.7.2
39
 * @version    Release: 1.7.2
40
 * @link       http://pear.php.net/package/PEAR
40
 * @link       http://pear.php.net/package/PEAR
41
 * @since      Class available since Release 1.4.0a1
41
 * @since      Class available since Release 1.4.0a1
42
 */
42
 */
43
class PEAR_DependencyDB
43
class PEAR_DependencyDB
44
{
44
{
45
    // {{{ properties
45
    // {{{ properties
46
46
47
    /**
47
    /**
48
     * This is initialized by {@link setConfig()}
48
     * This is initialized by {@link setConfig()}
49
     * @var PEAR_Config
49
     * @var PEAR_Config
50
     * @access private
50
     * @access private
51
     */
51
     */
52
    var $_config;
52
    var $_config;
53
    /**
53
    /**
54
     * This is initialized by {@link setConfig()}
54
     * This is initialized by {@link setConfig()}
55
     * @var PEAR_Registry
55
     * @var PEAR_Registry
56
     * @access private
56
     * @access private
57
     */
57
     */
58
    var $_registry;
58
    var $_registry;
59
    /**
59
    /**
60
     * Filename of the dependency DB (usually .depdb)
60
     * Filename of the dependency DB (usually .depdb)
61
     * @var string
61
     * @var string
62
     * @access private
62
     * @access private
63
     */
63
     */
64
    var $_depdb = false;
64
    var $_depdb = false;
65
    /**
65
    /**
66
     * File name of the lockfile (usually .depdblock)
66
     * File name of the lockfile (usually .depdblock)
67
     * @var string
67
     * @var string
68
     * @access private
68
     * @access private
69
     */
69
     */
70
    var $_lockfile = false;
70
    var $_lockfile = false;
71
    /**
71
    /**
72
     * Open file resource for locking the lockfile
72
     * Open file resource for locking the lockfile
73
     * @var resource|false
73
     * @var resource|false
74
     * @access private
74
     * @access private
75
     */
75
     */
76
    var $_lockFp = false;
76
    var $_lockFp = false;
77
    /**
77
    /**
78
     * API version of this class, used to validate a file on-disk
78
     * API version of this class, used to validate a file on-disk
79
     * @var string
79
     * @var string
80
     * @access private
80
     * @access private
81
     */
81
     */
82
    var $_version = '1.0';
82
    var $_version = '1.0';
83
    /**
83
    /**
84
     * Cached dependency database file
84
     * Cached dependency database file
85
     * @var array|null
85
     * @var array|null
86
     * @access private
86
     * @access private
87
     */
87
     */
88
    var $_cache;
88
    var $_cache;
89
89
90
    // }}}
90
    // }}}
91
    // {{{ & singleton()
91
    // {{{ & singleton()
92
92
93
    /**
93
    /**
94
     * Get a raw dependency database.  Calls setConfig() and assertDepsDB()
94
     * Get a raw dependency database.  Calls setConfig() and assertDepsDB()
95
     * @param PEAR_Config
95
     * @param PEAR_Config
96
     * @param string|false full path to the dependency database, or false to use default
96
     * @param string|false full path to the dependency database, or false to use default
97
     * @return PEAR_DependencyDB|PEAR_Error
97
     * @return PEAR_DependencyDB|PEAR_Error
98
     * @static
98
     * @static
99
     */
99
     */
100
    function &singleton(&$config, $depdb = false)
100
    function &singleton(&$config, $depdb = false)
101
    {
101
    {
102
        if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
102
        if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
103
              [$config->get('php_dir', null, 'pear.php.net')])) {
103
              [$config->get('php_dir', null, 'pear.php.net')])) {
104
            $a = new PEAR_DependencyDB;
104
            $a = new PEAR_DependencyDB;
105
            $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
105
            $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
106
              [$config->get('php_dir', null, 'pear.php.net')] = &$a;
106
              [$config->get('php_dir', null, 'pear.php.net')] = &$a;
107
            $a->setConfig($config, $depdb);
107
            $a->setConfig($config, $depdb);
108
            if (PEAR::isError($e = $a->assertDepsDB())) {
108
            if (PEAR::isError($e = $a->assertDepsDB())) {
109
                return $e;
109
                return $e;
110
            }
110
            }
111
        }
111
        }
112
        return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
112
        return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
113
              [$config->get('php_dir', null, 'pear.php.net')];
113
              [$config->get('php_dir', null, 'pear.php.net')];
114
    }
114
    }
115
115
116
    /**
116
    /**
117
     * Set up the registry/location of dependency DB
117
     * Set up the registry/location of dependency DB
118
     * @param PEAR_Config|false
118
     * @param PEAR_Config|false
119
     * @param string|false full path to the dependency database, or false to use default
119
     * @param string|false full path to the dependency database, or false to use default
120
     */
120
     */
121
    function setConfig(&$config, $depdb = false)
121
    function setConfig(&$config, $depdb = false)
122
    {
122
    {
123
        if (!$config) {
123
        if (!$config) {
124
            $this->_config = &PEAR_Config::singleton();
124
            $this->_config = &PEAR_Config::singleton();
125
        } else {
125
        } else {
126
            $this->_config = &$config;
126
            $this->_config = &$config;
127
        }
127
        }
128
        $this->_registry = &$this->_config->getRegistry();
128
        $this->_registry = &$this->_config->getRegistry();
129
        if (!$depdb) {
129
        if (!$depdb) {
130
            $this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') .
130
            $this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') .
131
                DIRECTORY_SEPARATOR . '.depdb';
131
                DIRECTORY_SEPARATOR . '.depdb';
132
        } else {
132
        } else {
133
            $this->_depdb = $depdb;
133
            $this->_depdb = $depdb;
134
        }
134
        }
135
        $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock';
135
        $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock';
136
    }
136
    }
137
    // }}}
137
    // }}}
138
138
139
    function hasWriteAccess()
139
    function hasWriteAccess()
140
    {
140
    {
141
        if (!file_exists($this->_depdb)) {
141
        if (!file_exists($this->_depdb)) {
142
            $dir = $this->_depdb;
142
            $dir = $this->_depdb;
143
            while ($dir && $dir != '.') {
143
            while ($dir && $dir != '.') {
144
                $dir = dirname($dir); // cd ..
144
                $dir = dirname($dir); // cd ..
145
                if ($dir != '.' && file_exists($dir)) {
145
                if ($dir != '.' && file_exists($dir)) {
146
                    if (is_writeable($dir)) {
146
                    if (is_writeable($dir)) {
147
                        return true;
147
                        return true;
148
                    } else {
148
                    } else {
149
                        return false;
149
                        return false;
150
                    }
150
                    }
151
                }
151
                }
152
            }
152
            }
153
            return false;
153
            return false;
154
        }
154
        }
155
        return is_writeable($this->_depdb);
155
        return is_writeable($this->_depdb);
156
    }
156
    }
157
157
158
    // {{{ assertDepsDB()
158
    // {{{ assertDepsDB()
159
159
160
    /**
160
    /**
161
     * Create the dependency database, if it doesn't exist.  Error if the database is
161
     * Create the dependency database, if it doesn't exist.  Error if the database is
162
     * newer than the code reading it.
162
     * newer than the code reading it.
163
     * @return void|PEAR_Error
163
     * @return void|PEAR_Error
164
     */
164
     */
165
    function assertDepsDB()
165
    function assertDepsDB()
166
    {
166
    {
167
        if (!is_file($this->_depdb)) {
167
        if (!is_file($this->_depdb)) {
168
            $this->rebuildDB();
168
            $this->rebuildDB();
169
        } else {
169
        } else {
170
            $depdb = $this->_getDepDB();
170
            $depdb = $this->_getDepDB();
171
            // Datatype format has been changed, rebuild the Deps DB
171
            // Datatype format has been changed, rebuild the Deps DB
172
            if ($depdb['_version'] < $this->_version) {
172
            if ($depdb['_version'] < $this->_version) {
173
                $this->rebuildDB();
173
                $this->rebuildDB();
174
            }
174
            }
175
            if ($depdb['_version']{0} > $this->_version{0}) {
175
            if ($depdb['_version']{0} > $this->_version{0}) {
176
                return PEAR::raiseError('Dependency database is version ' .
176
                return PEAR::raiseError('Dependency database is version ' .
177
                    $depdb['_version'] . ', and we are version ' .
177
                    $depdb['_version'] . ', and we are version ' .
178
                    $this->_version . ', cannot continue');
178
                    $this->_version . ', cannot continue');
179
            }
179
            }
180
        }
180
        }
181
    }
181
    }
182
182
183
    /**
183
    /**
184
     * Get a list of installed packages that depend on this package
184
     * Get a list of installed packages that depend on this package
185
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
185
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
186
     * @return array|false
186
     * @return array|false
187
     */
187
     */
188
    function getDependentPackages(&$pkg)
188
    function getDependentPackages(&$pkg)
189
    {
189
    {
190
        $data = $this->_getDepDB();
190
        $data = $this->_getDepDB();
191
        if (is_object($pkg)) {
191
        if (is_object($pkg)) {
192
            $channel = strtolower($pkg->getChannel());
192
            $channel = strtolower($pkg->getChannel());
193
            $package = strtolower($pkg->getPackage());
193
            $package = strtolower($pkg->getPackage());
194
        } else {
194
        } else {
195
            $channel = strtolower($pkg['channel']);
195
            $channel = strtolower($pkg['channel']);
196
            $package = strtolower($pkg['package']);
196
            $package = strtolower($pkg['package']);
197
        }
197
        }
198
        if (isset($data['packages'][$channel][$package])) {
198
        if (isset($data['packages'][$channel][$package])) {
199
            return $data['packages'][$channel][$package];
199
            return $data['packages'][$channel][$package];
200
        }
200
        }
201
        return false;
201
        return false;
202
    }
202
    }
203
203
204
    /**
204
    /**
205
     * Get a list of the actual dependencies of installed packages that depend on
205
     * Get a list of the actual dependencies of installed packages that depend on
206
     * a package.
206
     * a package.
207
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
207
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
208
     * @return array|false
208
     * @return array|false
209
     */
209
     */
210
    function getDependentPackageDependencies(&$pkg)
210
    function getDependentPackageDependencies(&$pkg)
211
    {
211
    {
212
        $data = $this->_getDepDB();
212
        $data = $this->_getDepDB();
213
        if (is_object($pkg)) {
213
        if (is_object($pkg)) {
214
            $channel = strtolower($pkg->getChannel());
214
            $channel = strtolower($pkg->getChannel());
215
            $package = strtolower($pkg->getPackage());
215
            $package = strtolower($pkg->getPackage());
216
        } else {
216
        } else {
217
            $channel = strtolower($pkg['channel']);
217
            $channel = strtolower($pkg['channel']);
218
            $package = strtolower($pkg['package']);
218
            $package = strtolower($pkg['package']);
219
        }
219
        }
220
        $depend = $this->getDependentPackages($pkg);
220
        $depend = $this->getDependentPackages($pkg);
221
        if (!$depend) {
221
        if (!$depend) {
222
            return false;
222
            return false;
223
        }
223
        }
224
        $dependencies = array();
224
        $dependencies = array();
225
        foreach ($depend as $info) {
225
        foreach ($depend as $info) {
226
            $temp = $this->getDependencies($info);
226
            $temp = $this->getDependencies($info);
227
            foreach ($temp as $dep) {
227
            foreach ($temp as $dep) {
228
                if (strtolower($dep['dep']['channel']) == strtolower($channel) &&
228
                if (strtolower($dep['dep']['channel']) == strtolower($channel) &&
229
                      strtolower($dep['dep']['name']) == strtolower($package)) {
229
                      strtolower($dep['dep']['name']) == strtolower($package)) {
230
                    if (!isset($dependencies[$info['channel']])) {
230
                    if (!isset($dependencies[$info['channel']])) {
231
                        $dependencies[$info['channel']] = array();
231
                        $dependencies[$info['channel']] = array();
232
                    }
232
                    }
233
                    if (!isset($dependencies[$info['channel']][$info['package']])) {
233
                    if (!isset($dependencies[$info['channel']][$info['package']])) {
234
                        $dependencies[$info['channel']][$info['package']] = array();
234
                        $dependencies[$info['channel']][$info['package']] = array();
235
                    }
235
                    }
236
                    $dependencies[$info['channel']][$info['package']][] = $dep;
236
                    $dependencies[$info['channel']][$info['package']][] = $dep;
237
                }
237
                }
238
            }
238
            }
239
        }
239
        }
240
        return $dependencies;
240
        return $dependencies;
241
    }
241
    }
242
242
243
    /**
243
    /**
244
     * Get a list of dependencies of this installed package
244
     * Get a list of dependencies of this installed package
245
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
245
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
246
     * @return array|false
246
     * @return array|false
247
     */
247
     */
248
    function getDependencies(&$pkg)
248
    function getDependencies(&$pkg)
249
    {
249
    {
250
        if (is_object($pkg)) {
250
        if (is_object($pkg)) {
251
            $channel = strtolower($pkg->getChannel());
251
            $channel = strtolower($pkg->getChannel());
252
            $package = strtolower($pkg->getPackage());
252
            $package = strtolower($pkg->getPackage());
253
        } else {
253
        } else {
254
            $channel = strtolower($pkg['channel']);
254
            $channel = strtolower($pkg['channel']);
255
            $package = strtolower($pkg['package']);
255
            $package = strtolower($pkg['package']);
256
        }
256
        }
257
        $data = $this->_getDepDB();
257
        $data = $this->_getDepDB();
258
        if (isset($data['dependencies'][$channel][$package])) {
258
        if (isset($data['dependencies'][$channel][$package])) {
259
            return $data['dependencies'][$channel][$package];
259
            return $data['dependencies'][$channel][$package];
260
        }
260
        }
261
        return false;
261
        return false;
262
    }
262
    }
263
263
264
    /**
264
    /**
265
     * Determine whether $parent depends on $child, near or deep
265
     * Determine whether $parent depends on $child, near or deep
266
     * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
266
     * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
267
     * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
267
     * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
268
     */
268
     */
269
    function dependsOn($parent, $child)
269
    function dependsOn($parent, $child)
270
    {
270
    {
271
        $c = array();
271
        $c = array();
272
        $this->_getDepDB();
272
        $this->_getDepDB();
273
        return $this->_dependsOn($parent, $child, $c);
273
        return $this->_dependsOn($parent, $child, $c);
274
    }
274
    }
275
   
275
   
276
    function _dependsOn($parent, $child, &$checked)
276
    function _dependsOn($parent, $child, &$checked)
277
    {
277
    {
278
        if (is_object($parent)) {
278
        if (is_object($parent)) {
279
            $channel = strtolower($parent->getChannel());
279
            $channel = strtolower($parent->getChannel());
280
            $package = strtolower($parent->getPackage());
280
            $package = strtolower($parent->getPackage());
281
        } else {
281
        } else {
282
            $channel = strtolower($parent['channel']);
282
            $channel = strtolower($parent['channel']);
283
            $package = strtolower($parent['package']);
283
            $package = strtolower($parent['package']);
284
        }
284
        }
285
        if (is_object($child)) {
285
        if (is_object($child)) {
286
            $depchannel = strtolower($child->getChannel());
286
            $depchannel = strtolower($child->getChannel());
287
            $deppackage = strtolower($child->getPackage());
287
            $deppackage = strtolower($child->getPackage());
288
        } else {
288
        } else {
289
            $depchannel = strtolower($child['channel']);
289
            $depchannel = strtolower($child['channel']);
290
            $deppackage = strtolower($child['package']);
290
            $deppackage = strtolower($child['package']);
291
        }
291
        }
292
        if (isset($checked[$channel][$package][$depchannel][$deppackage])) {
292
        if (isset($checked[$channel][$package][$depchannel][$deppackage])) {
293
            return false; // avoid endless recursion
293
            return false; // avoid endless recursion
294
        }
294
        }
295
        $checked[$channel][$package][$depchannel][$deppackage] = true;
295
        $checked[$channel][$package][$depchannel][$deppackage] = true;
296
        if (!isset($this->_cache['dependencies'][$channel][$package])) {
296
        if (!isset($this->_cache['dependencies'][$channel][$package])) {
297
            return false;
297
            return false;
298
        }
298
        }
299
        foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
299
        foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
300
            if (isset($info['dep']['uri'])) {
300
            if (isset($info['dep']['uri'])) {
301
                if (is_object($child)) {
301
                if (is_object($child)) {
302
                    if ($info['dep']['uri'] == $child->getURI()) {
302
                    if ($info['dep']['uri'] == $child->getURI()) {
303
                        return true;
303
                        return true;
304
                    }
304
                    }
305
                } elseif (isset($child['uri'])) {
305
                } elseif (isset($child['uri'])) {
306
                    if ($info['dep']['uri'] == $child['uri']) {
306
                    if ($info['dep']['uri'] == $child['uri']) {
307
                        return true;
307
                        return true;
308
                    }
308
                    }
309
                }
309
                }
310
                return false;
310
                return false;
311
            }
311
            }
312
            if (strtolower($info['dep']['channel']) == strtolower($depchannel) &&
312
            if (strtolower($info['dep']['channel']) == strtolower($depchannel) &&
313
                  strtolower($info['dep']['name']) == strtolower($deppackage)) {
313
                  strtolower($info['dep']['name']) == strtolower($deppackage)) {
314
                return true;
314
                return true;
315
            }
315
            }
316
        }
316
        }
317
        foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
317
        foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
318
            if (isset($info['dep']['uri'])) {
318
            if (isset($info['dep']['uri'])) {
319
                if ($this->_dependsOn(array(
319
                if ($this->_dependsOn(array(
320
                        'uri' => $info['dep']['uri'],
320
                        'uri' => $info['dep']['uri'],
321
                        'package' => $info['dep']['name']), $child, $checked)) {
321
                        'package' => $info['dep']['name']), $child, $checked)) {
322
                    return true;
322
                    return true;
323
                }
323
                }
324
            } else {
324
            } else {
325
                if ($this->_dependsOn(array(
325
                if ($this->_dependsOn(array(
326
                        'channel' => $info['dep']['channel'],
326
                        'channel' => $info['dep']['channel'],
327
                        'package' => $info['dep']['name']), $child, $checked)) {
327
                        'package' => $info['dep']['name']), $child, $checked)) {
328
                    return true;
328
                    return true;
329
                }
329
                }
330
            }
330
            }
331
        }
331
        }
332
        return false;
332
        return false;
333
    }
333
    }
334
334
335
    /**
335
    /**
336
     * Register dependencies of a package that is being installed or upgraded
336
     * Register dependencies of a package that is being installed or upgraded
337
     * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2
337
     * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2
338
     */
338
     */
339
    function installPackage(&$package)
339
    function installPackage(&$package)
340
    {
340
    {
341
        $data = $this->_getDepDB();
341
        $data = $this->_getDepDB();
342
        unset($this->_cache);
342
        unset($this->_cache);
343
        $this->_setPackageDeps($data, $package);
343
        $this->_setPackageDeps($data, $package);
344
        $this->_writeDepDB($data);
344
        $this->_writeDepDB($data);
345
    }
345
    }
346
346
347
    /**
347
    /**
348
     * Remove dependencies of a package that is being uninstalled, or upgraded.
348
     * Remove dependencies of a package that is being uninstalled, or upgraded.
349
     *
349
     *
350
     * Upgraded packages first uninstall, then install
350
     * Upgraded packages first uninstall, then install
351
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have
351
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have
352
     *        indices 'channel' and 'package'
352
     *        indices 'channel' and 'package'
353
     */
353
     */
354
    function uninstallPackage(&$pkg)
354
    function uninstallPackage(&$pkg)
355
    {
355
    {
356
        $data = $this->_getDepDB();
356
        $data = $this->_getDepDB();
357
        unset($this->_cache);
357
        unset($this->_cache);
358
        if (is_object($pkg)) {
358
        if (is_object($pkg)) {
359
            $channel = strtolower($pkg->getChannel());
359
            $channel = strtolower($pkg->getChannel());
360
            $package = strtolower($pkg->getPackage());
360
            $package = strtolower($pkg->getPackage());
361
        } else {
361
        } else {
362
            $channel = strtolower($pkg['channel']);
362
            $channel = strtolower($pkg['channel']);
363
            $package = strtolower($pkg['package']);
363
            $package = strtolower($pkg['package']);
364
        }
364
        }
365
        if (!isset($data['dependencies'][$channel][$package])) {
365
        if (!isset($data['dependencies'][$channel][$package])) {
366
            return true;
366
            return true;
367
        }
367
        }
368
        foreach ($data['dependencies'][$channel][$package] as $dep) {
368
        foreach ($data['dependencies'][$channel][$package] as $dep) {
369
            $found = false;
369
            $found = false;
370
            if (isset($dep['dep']['uri'])) {
370
            if (isset($dep['dep']['uri'])) {
371
                $depchannel = '__uri';
371
                $depchannel = '__uri';
372
            } else {
372
            } else {
373
                $depchannel = strtolower($dep['dep']['channel']);
373
                $depchannel = strtolower($dep['dep']['channel']);
374
            }
374
            }
375
            if (isset($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
375
            if (isset($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
376
                foreach ($data['packages'][$depchannel][strtolower($dep['dep']['name'])] as
376
                foreach ($data['packages'][$depchannel][strtolower($dep['dep']['name'])] as
377
                      $i => $info) {
377
                      $i => $info) {
378
                    if ($info['channel'] == $channel &&
378
                    if ($info['channel'] == $channel &&
379
                          $info['package'] == $package) {
379
                          $info['package'] == $package) {
380
                        $found = true;
380
                        $found = true;
381
                        break;
381
                        break;
382
                    }
382
                    }
383
                }
383
                }
384
            }
384
            }
385
            if ($found) {
385
            if ($found) {
386
                unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])][$i]);
386
                unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])][$i]);
387
                if (!count($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
387
                if (!count($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
388
                    unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
388
                    unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
389
                    if (!count($data['packages'][$depchannel])) {
389
                    if (!count($data['packages'][$depchannel])) {
390
                        unset($data['packages'][$depchannel]);
390
                        unset($data['packages'][$depchannel]);
391
                    }
391
                    }
392
                } else {
392
                } else {
393
                    $data['packages'][$depchannel][strtolower($dep['dep']['name'])] =
393
                    $data['packages'][$depchannel][strtolower($dep['dep']['name'])] =
394
                        array_values(
394
                        array_values(
395
                            $data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
395
                            $data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
396
                }
396
                }
397
            }
397
            }
398
        }
398
        }
399
        unset($data['dependencies'][$channel][$package]);
399
        unset($data['dependencies'][$channel][$package]);
400
        if (!count($data['dependencies'][$channel])) {
400
        if (!count($data['dependencies'][$channel])) {
401
            unset($data['dependencies'][$channel]);
401
            unset($data['dependencies'][$channel]);
402
        }
402
        }
403
        if (!count($data['dependencies'])) {
403
        if (!count($data['dependencies'])) {
404
            unset($data['dependencies']);
404
            unset($data['dependencies']);
405
        }
405
        }
406
        if (!count($data['packages'])) {
406
        if (!count($data['packages'])) {
407
            unset($data['packages']);
407
            unset($data['packages']);
408
        }
408
        }
409
        $this->_writeDepDB($data);
409
        $this->_writeDepDB($data);
410
    }
410
    }
411
411
412
    /**
412
    /**
413
     * Rebuild the dependency DB by reading registry entries.
413
     * Rebuild the dependency DB by reading registry entries.
414
     * @return true|PEAR_Error
414
     * @return true|PEAR_Error
415
     */
415
     */
416
    function rebuildDB()
416
    function rebuildDB()
417
    {
417
    {
418
        $depdb = array('_version' => $this->_version);
418
        $depdb = array('_version' => $this->_version);
419
        if (!$this->hasWriteAccess()) {
419
        if (!$this->hasWriteAccess()) {
420
            // allow startup for read-only with older Registry
420
            // allow startup for read-only with older Registry
421
            return $depdb;
421
            return $depdb;
422
        }
422
        }
423
        $packages = $this->_registry->listAllPackages();
423
        $packages = $this->_registry->listAllPackages();
424
        if (PEAR::isError($packages)) {
424
        if (PEAR::isError($packages)) {
425
            return $packages;
425
            return $packages;
426
        }
426
        }
427
        foreach ($packages as $channel => $ps) {
427
        foreach ($packages as $channel => $ps) {
428
            foreach ($ps as $package) {
428
            foreach ($ps as $package) {
429
                $package = $this->_registry->getPackage($package, $channel);
429
                $package = $this->_registry->getPackage($package, $channel);
430
                if (PEAR::isError($package)) {
430
                if (PEAR::isError($package)) {
431
                    return $package;
431
                    return $package;
432
                }
432
                }
433
                $this->_setPackageDeps($depdb, $package);
433
                $this->_setPackageDeps($depdb, $package);
434
            }
434
            }
435
        }
435
        }
436
        $error = $this->_writeDepDB($depdb);
436
        $error = $this->_writeDepDB($depdb);
437
        if (PEAR::isError($error)) {
437
        if (PEAR::isError($error)) {
438
            return $error;
438
            return $error;
439
        }
439
        }
440
        $this->_cache = $depdb;
440
        $this->_cache = $depdb;
441
        return true;
441
        return true;
442
    }
442
    }
443
443
444
    /**
444
    /**
445
     * Register usage of the dependency DB to prevent race conditions
445
     * Register usage of the dependency DB to prevent race conditions
446
     * @param int one of the LOCK_* constants
446
     * @param int one of the LOCK_* constants
447
     * @return true|PEAR_Error
447
     * @return true|PEAR_Error
448
     * @access private
448
     * @access private
449
     */
449
     */
450
    function _lock($mode = LOCK_EX)
450
    function _lock($mode = LOCK_EX)
451
    {
451
    {
452
        if (!eregi('Windows 9', php_uname())) {
452
        if (!eregi('Windows 9', php_uname())) {
453
            if ($mode != LOCK_UN && is_resource($this->_lockFp)) {
453
            if ($mode != LOCK_UN && is_resource($this->_lockFp)) {
454
                // XXX does not check type of lock (LOCK_SH/LOCK_EX)
454
                // XXX does not check type of lock (LOCK_SH/LOCK_EX)
455
                return true;
455
                return true;
456
            }
456
            }
457
            $open_mode = 'w';
457
            $open_mode = 'w';
458
            // XXX People reported problems with LOCK_SH and 'w'
458
            // XXX People reported problems with LOCK_SH and 'w'
459
            if ($mode === LOCK_SH) {
459
            if ($mode === LOCK_SH) {
460
                if (!file_exists($this->_lockfile)) {
460
                if (!file_exists($this->_lockfile)) {
461
                    touch($this->_lockfile);
461
                    touch($this->_lockfile);
462
                } elseif (!is_file($this->_lockfile)) {
462
                } elseif (!is_file($this->_lockfile)) {
463
                    return PEAR::raiseError('could not create Dependency lock file, ' .
463
                    return PEAR::raiseError('could not create Dependency lock file, ' .
464
                        'it exists and is not a regular file');
464
                        'it exists and is not a regular file');
465
                }
465
                }
466
                $open_mode = 'r';
466
                $open_mode = 'r';
467
            }
467
            }
468
468
469
            if (!is_resource($this->_lockFp)) {
469
            if (!is_resource($this->_lockFp)) {
470
                $this->_lockFp = @fopen($this->_lockfile, $open_mode);
470
                $this->_lockFp = @fopen($this->_lockfile, $open_mode);
471
            }
471
            }
472
            if (!is_resource($this->_lockFp)) {
472
            if (!is_resource($this->_lockFp)) {
473
                return PEAR::raiseError("could not create Dependency lock file" .
473
                return PEAR::raiseError("could not create Dependency lock file" .
474
                                         (isset($php_errormsg) ? ": " . $php_errormsg : ""));
474
                                         (isset($php_errormsg) ? ": " . $php_errormsg : ""));
475
            }
475
            }
476
            if (!(int)flock($this->_lockFp, $mode)) {
476
            if (!(int)flock($this->_lockFp, $mode)) {
477
                switch ($mode) {
477
                switch ($mode) {
478
                    case LOCK_SH: $str = 'shared';    break;
478
                    case LOCK_SH: $str = 'shared';    break;
479
                    case LOCK_EX: $str = 'exclusive'; break;
479
                    case LOCK_EX: $str = 'exclusive'; break;
480
                    case LOCK_UN: $str = 'unlock';    break;
480
                    case LOCK_UN: $str = 'unlock';    break;
481
                    default:      $str = 'unknown';   break;
481
                    default:      $str = 'unknown';   break;
482
                }
482
                }
483
                return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)");
483
                return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)");
484
            }
484
            }
485
        }
485
        }
486
        return true;
486
        return true;
487
    }
487
    }
488
488
489
    /**
489
    /**
490
     * Release usage of dependency DB
490
     * Release usage of dependency DB
491
     * @return true|PEAR_Error
491
     * @return true|PEAR_Error
492
     * @access private
492
     * @access private
493
     */
493
     */
494
    function _unlock()
494
    function _unlock()
495
    {
495
    {
496
        $ret = $this->_lock(LOCK_UN);
496
        $ret = $this->_lock(LOCK_UN);
497
        if (is_resource($this->_lockFp)) {
497
        if (is_resource($this->_lockFp)) {
498
            fclose($this->_lockFp);
498
            fclose($this->_lockFp);
499
        }
499
        }
500
        $this->_lockFp = null;
500
        $this->_lockFp = null;
501
        return $ret;
501
        return $ret;
502
    }
502
    }
503
503
504
    /**
504
    /**
505
     * Load the dependency database from disk, or return the cache
505
     * Load the dependency database from disk, or return the cache
506
     * @return array|PEAR_Error
506
     * @return array|PEAR_Error
507
     */
507
     */
508
    function _getDepDB()
508
    function _getDepDB()
509
    {
509
    {
510
        if (!$this->hasWriteAccess()) {
510
        if (!$this->hasWriteAccess()) {
511
            return array('_version' => $this->_version);
511
            return array('_version' => $this->_version);
512
        }
512
        }
513
        if (isset($this->_cache)) {
513
        if (isset($this->_cache)) {
514
            return $this->_cache;
514
            return $this->_cache;
515
        }
515
        }
516
        if (!$fp = fopen($this->_depdb, 'r')) {
516
        if (!$fp = fopen($this->_depdb, 'r')) {
517
            $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'");
517
            $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'");
518
            return $err;
518
            return $err;
519
        }
519
        }
520
        $rt = get_magic_quotes_runtime();
520
        $rt = get_magic_quotes_runtime();
521
        set_magic_quotes_runtime(0);
521
        set_magic_quotes_runtime(0);
522
        clearstatcache();
522
        clearstatcache();
523
        fclose($fp);
523
        fclose($fp);
524
        $data = unserialize(file_get_contents($this->_depdb));
524
        $data = unserialize(file_get_contents($this->_depdb));
525
        set_magic_quotes_runtime($rt);
525
        set_magic_quotes_runtime($rt);
526
        $this->_cache = $data;
526
        $this->_cache = $data;
527
        return $data;
527
        return $data;
528
    }
528
    }
529
529
530
    /**
530
    /**
531
     * Write out the dependency database to disk
531
     * Write out the dependency database to disk
532
     * @param array the database
532
     * @param array the database
533
     * @return true|PEAR_Error
533
     * @return true|PEAR_Error
534
     * @access private
534
     * @access private
535
     */
535
     */
536
    function _writeDepDB(&$deps)
536
    function _writeDepDB(&$deps)
537
    {
537
    {
538
        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
538
        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
539
            return $e;
539
            return $e;
540
        }
540
        }
541
        if (!$fp = fopen($this->_depdb, 'wb')) {
541
        if (!$fp = fopen($this->_depdb, 'wb')) {
542
            $this->_unlock();
542
            $this->_unlock();
543
            return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing");
543
            return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing");
544
        }
544
        }
545
        $rt = get_magic_quotes_runtime();
545
        $rt = get_magic_quotes_runtime();
546
        set_magic_quotes_runtime(0);
546
        set_magic_quotes_runtime(0);
547
        fwrite($fp, serialize($deps));
547
        fwrite($fp, serialize($deps));
548
        set_magic_quotes_runtime($rt);
548
        set_magic_quotes_runtime($rt);
549
        fclose($fp);
549
        fclose($fp);
550
        $this->_unlock();
550
        $this->_unlock();
551
        $this->_cache = $deps;
551
        $this->_cache = $deps;
552
        return true;
552
        return true;
553
    }
553
    }
554
554
555
    /**
555
    /**
556
     * Register all dependencies from a package in the dependencies database, in essence
556
     * Register all dependencies from a package in the dependencies database, in essence
557
     * "installing" the package's dependency information
557
     * "installing" the package's dependency information
558
     * @param array the database
558
     * @param array the database
559
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
559
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
560
     * @access private
560
     * @access private
561
     */
561
     */
562
    function _setPackageDeps(&$data, &$pkg)
562
    function _setPackageDeps(&$data, &$pkg)
563
    {
563
    {
564
        $pkg->setConfig($this->_config);
564
        $pkg->setConfig($this->_config);
565
        if ($pkg->getPackagexmlVersion() == '1.0') {
565
        if ($pkg->getPackagexmlVersion() == '1.0') {
566
            $gen = &$pkg->getDefaultGenerator();
566
            $gen = &$pkg->getDefaultGenerator();
567
            $deps = $gen->dependenciesToV2();
567
            $deps = $gen->dependenciesToV2();
568
        } else {
568
        } else {
569
            $deps = $pkg->getDeps(true);
569
            $deps = $pkg->getDeps(true);
570
        }
570
        }
571
        if (!$deps) {
571
        if (!$deps) {
572
            return;
572
            return;
573
        }
573
        }
574
        if (!is_array($data)) {
574
        if (!is_array($data)) {
575
            $data = array();
575
            $data = array();
576
        }
576
        }
577
        if (!isset($data['dependencies'])) {
577
        if (!isset($data['dependencies'])) {
578
            $data['dependencies'] = array();
578
            $data['dependencies'] = array();
579
        }
579
        }
580
        if (!isset($data['dependencies'][strtolower($pkg->getChannel())])) {
580
        if (!isset($data['dependencies'][strtolower($pkg->getChannel())])) {
581
            $data['dependencies'][strtolower($pkg->getChannel())] = array();
581
            $data['dependencies'][strtolower($pkg->getChannel())] = array();
582
        }
582
        }
583
        $data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())]
583
        $data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())]
584
            = array();
584
            = array();
585
        if (isset($deps['required']['package'])) {
585
        if (isset($deps['required']['package'])) {
586
            if (!isset($deps['required']['package'][0])) {
586
            if (!isset($deps['required']['package'][0])) {
587
                $deps['required']['package'] = array($deps['required']['package']);
587
                $deps['required']['package'] = array($deps['required']['package']);
588
            }
588
            }
589
            foreach ($deps['required']['package'] as $dep) {
589
            foreach ($deps['required']['package'] as $dep) {
590
                $this->_registerDep($data, $pkg, $dep, 'required');
590
                $this->_registerDep($data, $pkg, $dep, 'required');
591
            }
591
            }
592
        }
592
        }
593
        if (isset($deps['optional']['package'])) {
593
        if (isset($deps['optional']['package'])) {
594
            if (!isset($deps['optional']['package'][0])) {
594
            if (!isset($deps['optional']['package'][0])) {
595
                $deps['optional']['package'] = array($deps['optional']['package']);
595
                $deps['optional']['package'] = array($deps['optional']['package']);
596
            }
596
            }
597
            foreach ($deps['optional']['package'] as $dep) {
597
            foreach ($deps['optional']['package'] as $dep) {
598
                $this->_registerDep($data, $pkg, $dep, 'optional');
598
                $this->_registerDep($data, $pkg, $dep, 'optional');
599
            }
599
            }
600
        }
600
        }
601
        if (isset($deps['required']['subpackage'])) {
601
        if (isset($deps['required']['subpackage'])) {
602
            if (!isset($deps['required']['subpackage'][0])) {
602
            if (!isset($deps['required']['subpackage'][0])) {
603
                $deps['required']['subpackage'] = array($deps['required']['subpackage']);
603
                $deps['required']['subpackage'] = array($deps['required']['subpackage']);
604
            }
604
            }
605
            foreach ($deps['required']['subpackage'] as $dep) {
605
            foreach ($deps['required']['subpackage'] as $dep) {
606
                $this->_registerDep($data, $pkg, $dep, 'required');
606
                $this->_registerDep($data, $pkg, $dep, 'required');
607
            }
607
            }
608
        }
608
        }
609
        if (isset($deps['optional']['subpackage'])) {
609
        if (isset($deps['optional']['subpackage'])) {
610
            if (!isset($deps['optional']['subpackage'][0])) {
610
            if (!isset($deps['optional']['subpackage'][0])) {
611
                $deps['optional']['subpackage'] = array($deps['optional']['subpackage']);
611
                $deps['optional']['subpackage'] = array($deps['optional']['subpackage']);
612
            }
612
            }
613
            foreach ($deps['optional']['subpackage'] as $dep) {
613
            foreach ($deps['optional']['subpackage'] as $dep) {
614
                $this->_registerDep($data, $pkg, $dep, 'optional');
614
                $this->_registerDep($data, $pkg, $dep, 'optional');
615
            }
615
            }
616
        }
616
        }
617
        if (isset($deps['group'])) {
617
        if (isset($deps['group'])) {
618
            if (!isset($deps['group'][0])) {
618
            if (!isset($deps['group'][0])) {
619
                $deps['group'] = array($deps['group']);
619
                $deps['group'] = array($deps['group']);
620
            }
620
            }
621
            foreach ($deps['group'] as $group) {
621
            foreach ($deps['group'] as $group) {
622
                if (isset($group['package'])) {
622
                if (isset($group['package'])) {
623
                    if (!isset($group['package'][0])) {
623
                    if (!isset($group['package'][0])) {
624
                        $group['package'] = array($group['package']);
624
                        $group['package'] = array($group['package']);
625
                    }
625
                    }
626
                    foreach ($group['package'] as $dep) {
626
                    foreach ($group['package'] as $dep) {
627
                        $this->_registerDep($data, $pkg, $dep, 'optional',
627
                        $this->_registerDep($data, $pkg, $dep, 'optional',
628
                            $group['attribs']['name']);
628
                            $group['attribs']['name']);
629
                    }
629
                    }
630
                }
630
                }
631
                if (isset($group['subpackage'])) {
631
                if (isset($group['subpackage'])) {
632
                    if (!isset($group['subpackage'][0])) {
632
                    if (!isset($group['subpackage'][0])) {
633
                        $group['subpackage'] = array($group['subpackage']);
633
                        $group['subpackage'] = array($group['subpackage']);
634
                    }
634
                    }
635
                    foreach ($group['subpackage'] as $dep) {
635
                    foreach ($group['subpackage'] as $dep) {
636
                        $this->_registerDep($data, $pkg, $dep, 'optional',
636
                        $this->_registerDep($data, $pkg, $dep, 'optional',
637
                            $group['attribs']['name']);
637
                            $group['attribs']['name']);
638
                    }
638
                    }
639
                }
639
                }
640
            }
640
            }
641
        }
641
        }
642
        if ($data['dependencies'][strtolower($pkg->getChannel())]
642
        if ($data['dependencies'][strtolower($pkg->getChannel())]
643
              [strtolower($pkg->getPackage())] == array()) {
643
              [strtolower($pkg->getPackage())] == array()) {
644
            unset($data['dependencies'][strtolower($pkg->getChannel())]
644
            unset($data['dependencies'][strtolower($pkg->getChannel())]
645
              [strtolower($pkg->getPackage())]);
645
              [strtolower($pkg->getPackage())]);
646
            if (!count($data['dependencies'][strtolower($pkg->getChannel())])) {
646
            if (!count($data['dependencies'][strtolower($pkg->getChannel())])) {
647
                unset($data['dependencies'][strtolower($pkg->getChannel())]);
647
                unset($data['dependencies'][strtolower($pkg->getChannel())]);
648
            }
648
            }
649
        }
649
        }
650
    }
650
    }
651
651
652
    /**
652
    /**
653
     * @param array the database
653
     * @param array the database
654
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
654
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
655
     * @param array the specific dependency
655
     * @param array the specific dependency
656
     * @param required|optional whether this is a required or an optional dep
656
     * @param required|optional whether this is a required or an optional dep
657
     * @param string|false dependency group this dependency is from, or false for ordinary dep
657
     * @param string|false dependency group this dependency is from, or false for ordinary dep
658
     */
658
     */
659
    function _registerDep(&$data, &$pkg, $dep, $type, $group = false)
659
    function _registerDep(&$data, &$pkg, $dep, $type, $group = false)
660
    {
660
    {
661
        $info = array(
661
        $info = array(
662
            'dep' => $dep,
662
            'dep' => $dep,
663
            'type' => $type,
663
            'type' => $type,
664
            'group' => $group);
664
            'group' => $group);
665
665
666
        if (isset($dep['channel'])) {
666
        if (isset($dep['channel'])) {
667
            $depchannel = $dep['channel'];
667
            $depchannel = $dep['channel'];
668
        } else {
668
        } else {
669
            $depchannel = '__uri';
669
            $depchannel = '__uri';
670
        }
670
        }
671
        if (!isset($data['dependencies'])) {
671
        if (!isset($data['dependencies'])) {
672
            $data['dependencies'] = array();
672
            $data['dependencies'] = array();
673
        }
673
        }
674
        if (!isset($data['dependencies'][strtolower($pkg->getChannel())])) {
674
        if (!isset($data['dependencies'][strtolower($pkg->getChannel())])) {
675
            $data['dependencies'][strtolower($pkg->getChannel())] = array();
675
            $data['dependencies'][strtolower($pkg->getChannel())] = array();
676
        }
676
        }
677
        if (!isset($data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())])) {
677
        if (!isset($data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())])) {
678
            $data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())] = array();
678
            $data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())] = array();
679
        }
679
        }
680
        $data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())][]
680
        $data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())][]
681
            = $info;
681
            = $info;
682
        if (isset($data['packages'][strtolower($depchannel)][strtolower($dep['name'])])) {
682
        if (isset($data['packages'][strtolower($depchannel)][strtolower($dep['name'])])) {
683
            $found = false;
683
            $found = false;
684
            foreach ($data['packages'][strtolower($depchannel)][strtolower($dep['name'])]
684
            foreach ($data['packages'][strtolower($depchannel)][strtolower($dep['name'])]
685
                  as $i => $p) {
685
                  as $i => $p) {
686
                if ($p['channel'] == strtolower($pkg->getChannel()) &&
686
                if ($p['channel'] == strtolower($pkg->getChannel()) &&
687
                      $p['package'] == strtolower($pkg->getPackage())) {
687
                      $p['package'] == strtolower($pkg->getPackage())) {
688
                    $found = true;
688
                    $found = true;
689
                    break;
689
                    break;
690
                }
690
                }
691
            }
691
            }
692
            if (!$found) {
692
            if (!$found) {
693
                $data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
693
                $data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
694
                    = array('channel' => strtolower($pkg->getChannel()),
694
                    = array('channel' => strtolower($pkg->getChannel()),
695
                            'package' => strtolower($pkg->getPackage()));
695
                            'package' => strtolower($pkg->getPackage()));
696
            }
696
            }
697
        } else {
697
        } else {
698
            if (!isset($data['packages'])) {
698
            if (!isset($data['packages'])) {
699
                $data['packages'] = array();
699
                $data['packages'] = array();
700
            }
700
            }
701
            if (!isset($data['packages'][strtolower($depchannel)])) {
701
            if (!isset($data['packages'][strtolower($depchannel)])) {
702
                $data['packages'][strtolower($depchannel)] = array();
702
                $data['packages'][strtolower($depchannel)] = array();
703
            }
703
            }
704
            if (!isset($data['packages'][strtolower($depchannel)][strtolower($dep['name'])])) {
704
            if (!isset($data['packages'][strtolower($depchannel)][strtolower($dep['name'])])) {
705
                $data['packages'][strtolower($depchannel)][strtolower($dep['name'])] = array();
705
                $data['packages'][strtolower($depchannel)][strtolower($dep['name'])] = array();
706
            }
706
            }
707
            $data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
707
            $data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
708
                = array('channel' => strtolower($pkg->getChannel()),
708
                = array('channel' => strtolower($pkg->getChannel()),
709
                        'package' => strtolower($pkg->getPackage()));
709
                        'package' => strtolower($pkg->getPackage()));
710
        }
710
        }
711
    }
711
    }
712
}
712
}
713
?>
713
?>