Редакция 69 | Только различия | Учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS
Редакция 69 | Редакция 87 | ||
---|---|---|---|
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 | ?>
|