Редакция 69 | Только различия | Учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS
Редакция 69 | Редакция 94 | ||
---|---|---|---|
1 | <?php
|
1 | <?php
|
2 | /**
|
2 | /**
|
3 | * PEAR_PackageFile, package.xml parsing utility class
|
3 | * PEAR_PackageFile, package.xml parsing utility class
|
4 | *
|
4 | *
|
5 | * PHP versions 4 and 5
|
5 | * PHP versions 4 and 5
|
6 | *
|
6 | *
|
7 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
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 Greg Beaver <cellog@php.net>
|
15 | * @author Greg Beaver <cellog@php.net>
|
16 | * @copyright 1997-2008 The PHP Group
|
16 | * @copyright 1997-2008 The PHP Group
|
17 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
17 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
18 | * @version CVS: $Id: PackageFile.php,v 1.41 2008/01/03 20:26:36 cellog Exp $
|
18 | * @version CVS: $Id: PackageFile.php,v 1.41 2008/01/03 20:26:36 cellog Exp $
|
19 | * @link http://pear.php.net/package/PEAR
|
19 | * @link http://pear.php.net/package/PEAR
|
20 | * @since File available since Release 1.4.0a1
|
20 | * @since File available since Release 1.4.0a1
|
21 | */
|
21 | */
|
22 | 22 | ||
23 | /**
|
23 | /**
|
24 | * needed for PEAR_VALIDATE_* constants
|
24 | * needed for PEAR_VALIDATE_* constants
|
25 | */
|
25 | */
|
26 | require_once 'PEAR/Validate.php'; |
26 | require_once 'PEAR/Validate.php'; |
27 | /**
|
27 | /**
|
28 | * Error code if the package.xml <package> tag does not contain a valid version
|
28 | * Error code if the package.xml <package> tag does not contain a valid version
|
29 | */
|
29 | */
|
30 | define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1); |
30 | define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1); |
31 | /**
|
31 | /**
|
32 | * Error code if the package.xml <package> tag version is not supported (version 1.0 and 1.1 are the only supported versions,
|
32 | * Error code if the package.xml <package> tag version is not supported (version 1.0 and 1.1 are the only supported versions,
|
33 | * currently
|
33 | * currently
|
34 | */
|
34 | */
|
35 | define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); |
35 | define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); |
36 | /**
|
36 | /**
|
37 | * Abstraction for the package.xml package description file
|
37 | * Abstraction for the package.xml package description file
|
38 | *
|
38 | *
|
39 | * @category pear
|
39 | * @category pear
|
40 | * @package PEAR
|
40 | * @package PEAR
|
41 | * @author Greg Beaver <cellog@php.net>
|
41 | * @author Greg Beaver <cellog@php.net>
|
42 | * @copyright 1997-2008 The PHP Group
|
42 | * @copyright 1997-2008 The PHP Group
|
43 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
43 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
44 | * @version Release: 1.7.2
|
44 | * @version Release: 1.7.2
|
45 | * @link http://pear.php.net/package/PEAR
|
45 | * @link http://pear.php.net/package/PEAR
|
46 | * @since Class available since Release 1.4.0a1
|
46 | * @since Class available since Release 1.4.0a1
|
47 | */
|
47 | */
|
48 | class PEAR_PackageFile
|
48 | class PEAR_PackageFile
|
49 | {
|
49 | {
|
50 | /**
|
50 | /**
|
51 | * @var PEAR_Config
|
51 | * @var PEAR_Config
|
52 | */
|
52 | */
|
53 | var $_config; |
53 | var $_config; |
54 | var $_debug; |
54 | var $_debug; |
55 | /**
|
55 | /**
|
56 | * Temp directory for uncompressing tgz files.
|
56 | * Temp directory for uncompressing tgz files.
|
57 | * @var string|false
|
57 | * @var string|false
|
58 | */
|
58 | */
|
59 | var $_tmpdir; |
59 | var $_tmpdir; |
60 | var $_logger = false; |
60 | var $_logger = false; |
61 | /**
|
61 | /**
|
62 | * @var boolean
|
62 | * @var boolean
|
63 | */
|
63 | */
|
64 | var $_rawReturn = false; |
64 | var $_rawReturn = false; |
65 | 65 | ||
66 | /**
|
66 | /**
|
67 | *
|
67 | *
|
68 | * @param PEAR_Config $config
|
68 | * @param PEAR_Config $config
|
69 | * @param ? $debug
|
69 | * @param ? $debug
|
70 | * @param string @tmpdir Optional temporary directory for uncompressing
|
70 | * @param string @tmpdir Optional temporary directory for uncompressing
|
71 | * files
|
71 | * files
|
72 | */
|
72 | */
|
73 | function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false) |
73 | function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false) |
74 | {
|
74 | {
|
75 | $this->_config = $config; |
75 | $this->_config = $config; |
76 | $this->_debug = $debug; |
76 | $this->_debug = $debug; |
77 | $this->_tmpdir = $tmpdir; |
77 | $this->_tmpdir = $tmpdir; |
78 | }
|
78 | }
|
79 | 79 | ||
80 | /**
|
80 | /**
|
81 | * Turn off validation - return a parsed package.xml without checking it
|
81 | * Turn off validation - return a parsed package.xml without checking it
|
82 | *
|
82 | *
|
83 | * This is used by the package-validate command
|
83 | * This is used by the package-validate command
|
84 | */
|
84 | */
|
85 | function rawReturn() |
85 | function rawReturn() |
86 | {
|
86 | {
|
87 | $this->_rawReturn = true; |
87 | $this->_rawReturn = true; |
88 | }
|
88 | }
|
89 | 89 | ||
90 | function setLogger(&$l) |
90 | function setLogger(&$l) |
91 | {
|
91 | {
|
92 | $this->_logger = &$l; |
92 | $this->_logger = &$l; |
93 | }
|
93 | }
|
94 | 94 | ||
95 | /**
|
95 | /**
|
96 | * Create a PEAR_PackageFile_Parser_v* of a given version.
|
96 | * Create a PEAR_PackageFile_Parser_v* of a given version.
|
97 | * @param int $version
|
97 | * @param int $version
|
98 | * @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1
|
98 | * @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1
|
99 | */
|
99 | */
|
100 | function &parserFactory($version) |
100 | function &parserFactory($version) |
101 | {
|
101 | {
|
102 | if (!in_array($version{0}, array('1', '2'))) { |
102 | if (!in_array($version{0}, array('1', '2'))) { |
103 | $a = false; |
103 | $a = false; |
104 | return $a; |
104 | return $a; |
105 | }
|
105 | }
|
106 | include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php'; |
106 | include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php'; |
107 | $version = $version{0}; |
107 | $version = $version{0}; |
108 | $class = "PEAR_PackageFile_Parser_v$version"; |
108 | $class = "PEAR_PackageFile_Parser_v$version"; |
109 | $a = new $class; |
109 | $a = new $class; |
110 | return $a; |
110 | return $a; |
111 | }
|
111 | }
|
112 | 112 | ||
113 | /**
|
113 | /**
|
114 | * For simpler unit-testing
|
114 | * For simpler unit-testing
|
115 | * @return string
|
115 | * @return string
|
116 | */
|
116 | */
|
117 | function getClassPrefix() |
117 | function getClassPrefix() |
118 | {
|
118 | {
|
119 | return 'PEAR_PackageFile_v'; |
119 | return 'PEAR_PackageFile_v'; |
120 | }
|
120 | }
|
121 | 121 | ||
122 | /**
|
122 | /**
|
123 | * Create a PEAR_PackageFile_v* of a given version.
|
123 | * Create a PEAR_PackageFile_v* of a given version.
|
124 | * @param int $version
|
124 | * @param int $version
|
125 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v1
|
125 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v1
|
126 | */
|
126 | */
|
127 | function &factory($version) |
127 | function &factory($version) |
128 | {
|
128 | {
|
129 | if (!in_array($version{0}, array('1', '2'))) { |
129 | if (!in_array($version{0}, array('1', '2'))) { |
130 | $a = false; |
130 | $a = false; |
131 | return $a; |
131 | return $a; |
132 | }
|
132 | }
|
133 | include_once 'PEAR/PackageFile/v' . $version{0} . '.php'; |
133 | include_once 'PEAR/PackageFile/v' . $version{0} . '.php'; |
134 | $version = $version{0}; |
134 | $version = $version{0}; |
135 | $class = $this->getClassPrefix() . $version; |
135 | $class = $this->getClassPrefix() . $version; |
136 | $a = new $class; |
136 | $a = new $class; |
137 | return $a; |
137 | return $a; |
138 | }
|
138 | }
|
139 | 139 | ||
140 | /**
|
140 | /**
|
141 | * Create a PEAR_PackageFile_v* from its toArray() method
|
141 | * Create a PEAR_PackageFile_v* from its toArray() method
|
142 | *
|
142 | *
|
143 | * WARNING: no validation is performed, the array is assumed to be valid,
|
143 | * WARNING: no validation is performed, the array is assumed to be valid,
|
144 | * always parse from xml if you want validation.
|
144 | * always parse from xml if you want validation.
|
145 | * @param array $arr
|
145 | * @param array $arr
|
146 | * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2
|
146 | * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2
|
147 | * @uses factory() to construct the returned object.
|
147 | * @uses factory() to construct the returned object.
|
148 | */
|
148 | */
|
149 | function &fromArray($arr) |
149 | function &fromArray($arr) |
150 | {
|
150 | {
|
151 | if (isset($arr['xsdversion'])) { |
151 | if (isset($arr['xsdversion'])) { |
152 | $obj = &$this->factory($arr['xsdversion']); |
152 | $obj = &$this->factory($arr['xsdversion']); |
153 | if ($this->_logger) { |
153 | if ($this->_logger) { |
154 | $obj->setLogger($this->_logger); |
154 | $obj->setLogger($this->_logger); |
155 | }
|
155 | }
|
156 | $obj->setConfig($this->_config); |
156 | $obj->setConfig($this->_config); |
157 | $obj->fromArray($arr); |
157 | $obj->fromArray($arr); |
158 | return $obj; |
158 | return $obj; |
159 | } else { |
159 | } else { |
160 | if (isset($arr['package']['attribs']['version'])) { |
160 | if (isset($arr['package']['attribs']['version'])) { |
161 | $obj = &$this->factory($arr['package']['attribs']['version']); |
161 | $obj = &$this->factory($arr['package']['attribs']['version']); |
162 | } else { |
162 | } else { |
163 | $obj = &$this->factory('1.0'); |
163 | $obj = &$this->factory('1.0'); |
164 | }
|
164 | }
|
165 | if ($this->_logger) { |
165 | if ($this->_logger) { |
166 | $obj->setLogger($this->_logger); |
166 | $obj->setLogger($this->_logger); |
167 | }
|
167 | }
|
168 | $obj->setConfig($this->_config); |
168 | $obj->setConfig($this->_config); |
169 | $obj->fromArray($arr); |
169 | $obj->fromArray($arr); |
170 | return $obj; |
170 | return $obj; |
171 | }
|
171 | }
|
172 | }
|
172 | }
|
173 | 173 | ||
174 | /**
|
174 | /**
|
175 | * Create a PEAR_PackageFile_v* from an XML string.
|
175 | * Create a PEAR_PackageFile_v* from an XML string.
|
176 | * @access public
|
176 | * @access public
|
177 | * @param string $data contents of package.xml file
|
177 | * @param string $data contents of package.xml file
|
178 | * @param int $state package state (one of PEAR_VALIDATE_* constants)
|
178 | * @param int $state package state (one of PEAR_VALIDATE_* constants)
|
179 | * @param string $file full path to the package.xml file (and the files
|
179 | * @param string $file full path to the package.xml file (and the files
|
180 | * it references)
|
180 | * it references)
|
181 | * @param string $archive optional name of the archive that the XML was
|
181 | * @param string $archive optional name of the archive that the XML was
|
182 | * extracted from, if any
|
182 | * extracted from, if any
|
183 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
183 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
184 | * @uses parserFactory() to construct a parser to load the package.
|
184 | * @uses parserFactory() to construct a parser to load the package.
|
185 | */
|
185 | */
|
186 | function &fromXmlString($data, $state, $file, $archive = false) |
186 | function &fromXmlString($data, $state, $file, $archive = false) |
187 | {
|
187 | {
|
188 | if (preg_match('/<package[^>]+version="([0-9]+\.[0-9]+)"/', $data, $packageversion)) { |
188 | if (preg_match('/<package[^>]+version="([0-9]+\.[0-9]+)"/', $data, $packageversion)) { |
189 | if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) { |
189 | if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) { |
190 | return PEAR::raiseError('package.xml version "' . $packageversion[1] . |
190 | return PEAR::raiseError('package.xml version "' . $packageversion[1] . |
191 | '" is not supported, only 1.0, 2.0, and 2.1 are supported.'); |
191 | '" is not supported, only 1.0, 2.0, and 2.1 are supported.'); |
192 | }
|
192 | }
|
193 | $object = &$this->parserFactory($packageversion[1]); |
193 | $object = &$this->parserFactory($packageversion[1]); |
194 | if ($this->_logger) { |
194 | if ($this->_logger) { |
195 | $object->setLogger($this->_logger); |
195 | $object->setLogger($this->_logger); |
196 | }
|
196 | }
|
197 | $object->setConfig($this->_config); |
197 | $object->setConfig($this->_config); |
198 | $pf = $object->parse($data, $file, $archive); |
198 | $pf = $object->parse($data, $file, $archive); |
199 | if (PEAR::isError($pf)) { |
199 | if (PEAR::isError($pf)) { |
200 | return $pf; |
200 | return $pf; |
201 | }
|
201 | }
|
202 | if ($this->_rawReturn) { |
202 | if ($this->_rawReturn) { |
203 | return $pf; |
203 | return $pf; |
204 | }
|
204 | }
|
205 | if ($pf->validate($state)) { |
205 | if ($pf->validate($state)) { |
206 | if ($this->_logger) { |
206 | if ($this->_logger) { |
207 | if ($pf->getValidationWarnings(false)) { |
207 | if ($pf->getValidationWarnings(false)) { |
208 | foreach ($pf->getValidationWarnings() as $warning) { |
208 | foreach ($pf->getValidationWarnings() as $warning) { |
209 | $this->_logger->log(0, 'WARNING: ' . $warning['message']); |
209 | $this->_logger->log(0, 'WARNING: ' . $warning['message']); |
210 | }
|
210 | }
|
211 | }
|
211 | }
|
212 | }
|
212 | }
|
213 | if (method_exists($pf, 'flattenFilelist')) { |
213 | if (method_exists($pf, 'flattenFilelist')) { |
214 | $pf->flattenFilelist(); // for v2 |
214 | $pf->flattenFilelist(); // for v2 |
215 | }
|
215 | }
|
216 | return $pf; |
216 | return $pf; |
217 | } else { |
217 | } else { |
218 | if ($this->_config->get('verbose') > 0) { |
218 | if ($this->_config->get('verbose') > 0) { |
219 | if ($this->_logger) { |
219 | if ($this->_logger) { |
220 | if ($pf->getValidationWarnings(false)) { |
220 | if ($pf->getValidationWarnings(false)) { |
221 | foreach ($pf->getValidationWarnings(false) as $warning) { |
221 | foreach ($pf->getValidationWarnings(false) as $warning) { |
222 | $this->_logger->log(0, 'ERROR: ' . $warning['message']); |
222 | $this->_logger->log(0, 'ERROR: ' . $warning['message']); |
223 | }
|
223 | }
|
224 | }
|
224 | }
|
225 | }
|
225 | }
|
226 | }
|
226 | }
|
227 | $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', |
227 | $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', |
228 | 2, null, null, $pf->getValidationWarnings()); |
228 | 2, null, null, $pf->getValidationWarnings()); |
229 | return $a; |
229 | return $a; |
230 | }
|
230 | }
|
231 | } elseif (preg_match('/<package[^>]+version="([^"]+)"/', $data, $packageversion)) { |
231 | } elseif (preg_match('/<package[^>]+version="([^"]+)"/', $data, $packageversion)) { |
232 | $a = PEAR::raiseError('package.xml file "' . $file . |
232 | $a = PEAR::raiseError('package.xml file "' . $file . |
233 | '" has unsupported package.xml <package> version "' . $packageversion[1] . '"'); |
233 | '" has unsupported package.xml <package> version "' . $packageversion[1] . '"'); |
234 | return $a; |
234 | return $a; |
235 | } else { |
235 | } else { |
236 | if (!class_exists('PEAR_ErrorStack')) { |
236 | if (!class_exists('PEAR_ErrorStack')) { |
237 | require_once 'PEAR/ErrorStack.php'; |
237 | require_once 'PEAR/ErrorStack.php'; |
238 | }
|
238 | }
|
239 | PEAR_ErrorStack::staticPush('PEAR_PackageFile', |
239 | PEAR_ErrorStack::staticPush('PEAR_PackageFile', |
240 | PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION,
|
240 | PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION,
|
241 | 'warning', array('xml' => $data), 'package.xml "' . $file . |
241 | 'warning', array('xml' => $data), 'package.xml "' . $file . |
242 | '" has no package.xml <package> version'); |
242 | '" has no package.xml <package> version'); |
243 | $object = &$this->parserFactory('1.0'); |
243 | $object = &$this->parserFactory('1.0'); |
244 | $object->setConfig($this->_config); |
244 | $object->setConfig($this->_config); |
245 | $pf = $object->parse($data, $file, $archive); |
245 | $pf = $object->parse($data, $file, $archive); |
246 | if (PEAR::isError($pf)) { |
246 | if (PEAR::isError($pf)) { |
247 | return $pf; |
247 | return $pf; |
248 | }
|
248 | }
|
249 | if ($this->_rawReturn) { |
249 | if ($this->_rawReturn) { |
250 | return $pf; |
250 | return $pf; |
251 | }
|
251 | }
|
252 | if ($pf->validate($state)) { |
252 | if ($pf->validate($state)) { |
253 | if ($this->_logger) { |
253 | if ($this->_logger) { |
254 | if ($pf->getValidationWarnings(false)) { |
254 | if ($pf->getValidationWarnings(false)) { |
255 | foreach ($pf->getValidationWarnings() as $warning) { |
255 | foreach ($pf->getValidationWarnings() as $warning) { |
256 | $this->_logger->log(0, 'WARNING: ' . $warning['message']); |
256 | $this->_logger->log(0, 'WARNING: ' . $warning['message']); |
257 | }
|
257 | }
|
258 | }
|
258 | }
|
259 | }
|
259 | }
|
260 | if (method_exists($pf, 'flattenFilelist')) { |
260 | if (method_exists($pf, 'flattenFilelist')) { |
261 | $pf->flattenFilelist(); // for v2 |
261 | $pf->flattenFilelist(); // for v2 |
262 | }
|
262 | }
|
263 | return $pf; |
263 | return $pf; |
264 | } else { |
264 | } else { |
265 | $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', |
265 | $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', |
266 | 2, null, null, $pf->getValidationWarnings()); |
266 | 2, null, null, $pf->getValidationWarnings()); |
267 | return $a; |
267 | return $a; |
268 | }
|
268 | }
|
269 | }
|
269 | }
|
270 | }
|
270 | }
|
271 | 271 | ||
272 | /**
|
272 | /**
|
273 | * Register a temporary file or directory. When the destructor is
|
273 | * Register a temporary file or directory. When the destructor is
|
274 | * executed, all registered temporary files and directories are
|
274 | * executed, all registered temporary files and directories are
|
275 | * removed.
|
275 | * removed.
|
276 | *
|
276 | *
|
277 | * @param string $file name of file or directory
|
277 | * @param string $file name of file or directory
|
278 | * @return void
|
278 | * @return void
|
279 | */
|
279 | */
|
280 | function addTempFile($file) |
280 | function addTempFile($file) |
281 | {
|
281 | {
|
282 | $GLOBALS['_PEAR_Common_tempfiles'][] = $file; |
282 | $GLOBALS['_PEAR_Common_tempfiles'][] = $file; |
283 | }
|
283 | }
|
284 | 284 | ||
285 | /**
|
285 | /**
|
286 | * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file.
|
286 | * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file.
|
287 | * @access public
|
287 | * @access public
|
288 | * @param string contents of package.xml file
|
288 | * @param string contents of package.xml file
|
289 | * @param int package state (one of PEAR_VALIDATE_* constants)
|
289 | * @param int package state (one of PEAR_VALIDATE_* constants)
|
290 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
290 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
291 | * @using Archive_Tar to extract the files
|
291 | * @using Archive_Tar to extract the files
|
292 | * @using fromPackageFile() to load the package after the package.xml
|
292 | * @using fromPackageFile() to load the package after the package.xml
|
293 | * file is extracted.
|
293 | * file is extracted.
|
294 | */
|
294 | */
|
295 | function &fromTgzFile($file, $state) |
295 | function &fromTgzFile($file, $state) |
296 | {
|
296 | {
|
297 | if (!class_exists('Archive_Tar')) { |
297 | if (!class_exists('Archive_Tar')) { |
298 | require_once 'Archive/Tar.php'; |
298 | require_once 'Archive/Tar.php'; |
299 | }
|
299 | }
|
300 | $tar = new Archive_Tar($file); |
300 | $tar = new Archive_Tar($file); |
301 | if ($this->_debug <= 1) { |
301 | if ($this->_debug <= 1) { |
302 | $tar->pushErrorHandling(PEAR_ERROR_RETURN); |
302 | $tar->pushErrorHandling(PEAR_ERROR_RETURN); |
303 | }
|
303 | }
|
304 | $content = $tar->listContent(); |
304 | $content = $tar->listContent(); |
305 | if ($this->_debug <= 1) { |
305 | if ($this->_debug <= 1) { |
306 | $tar->popErrorHandling(); |
306 | $tar->popErrorHandling(); |
307 | }
|
307 | }
|
308 | if (!is_array($content)) { |
308 | if (!is_array($content)) { |
309 | if (is_string($file) && strlen($file < 255) && |
309 | if (is_string($file) && strlen($file < 255) && |
310 | (!file_exists($file) || !@is_file($file))) { |
310 | (!file_exists($file) || !@is_file($file))) { |
311 | $ret = PEAR::raiseError("could not open file \"$file\""); |
311 | $ret = PEAR::raiseError("could not open file \"$file\""); |
312 | return $ret; |
312 | return $ret; |
313 | }
|
313 | }
|
314 | $file = realpath($file); |
314 | $file = realpath($file); |
315 | $ret = PEAR::raiseError("Could not get contents of package \"$file\"". |
315 | $ret = PEAR::raiseError("Could not get contents of package \"$file\"". |
316 | '. Invalid tgz file.'); |
316 | '. Invalid tgz file.'); |
317 | return $ret; |
317 | return $ret; |
318 | } else { |
318 | } else { |
319 | if (!count($content) && !@is_file($file)) { |
319 | if (!count($content) && !@is_file($file)) { |
320 | $ret = PEAR::raiseError("could not open file \"$file\""); |
320 | $ret = PEAR::raiseError("could not open file \"$file\""); |
321 | return $ret; |
321 | return $ret; |
322 | }
|
322 | }
|
323 | }
|
323 | }
|
324 | $xml = null; |
324 | $xml = null; |
325 | $origfile = $file; |
325 | $origfile = $file; |
326 | foreach ($content as $file) { |
326 | foreach ($content as $file) { |
327 | $name = $file['filename']; |
327 | $name = $file['filename']; |
328 | if ($name == 'package2.xml') { // allow a .tgz to distribute both versions |
328 | if ($name == 'package2.xml') { // allow a .tgz to distribute both versions |
329 | $xml = $name; |
329 | $xml = $name; |
330 | break; |
330 | break; |
331 | }
|
331 | }
|
332 | if ($name == 'package.xml') { |
332 | if ($name == 'package.xml') { |
333 | $xml = $name; |
333 | $xml = $name; |
334 | break; |
334 | break; |
335 | } elseif (ereg('package.xml$', $name, $match)) { |
335 | } elseif (ereg('package.xml$', $name, $match)) { |
336 | $xml = $name; |
336 | $xml = $name; |
337 | break; |
337 | break; |
338 | }
|
338 | }
|
339 | }
|
339 | }
|
340 | if ($this->_tmpdir) { |
340 | if ($this->_tmpdir) { |
341 | $tmpdir = $this->_tmpdir; |
341 | $tmpdir = $this->_tmpdir; |
342 | } else { |
342 | } else { |
343 | $tmpdir = System::mkTemp(array('-d', 'pear')); |
343 | $tmpdir = System::mkTemp(array('-d', 'pear')); |
344 | PEAR_PackageFile::addTempFile($tmpdir); |
344 | PEAR_PackageFile::addTempFile($tmpdir); |
345 | }
|
345 | }
|
346 | $this->_extractErrors(); |
346 | $this->_extractErrors(); |
347 | PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors')); |
347 | PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors')); |
348 | if (!$xml || !$tar->extractList(array($xml), $tmpdir)) { |
348 | if (!$xml || !$tar->extractList(array($xml), $tmpdir)) { |
349 | $extra = implode("\n", $this->_extractErrors()); |
349 | $extra = implode("\n", $this->_extractErrors()); |
350 | if ($extra) { |
350 | if ($extra) { |
351 | $extra = ' ' . $extra; |
351 | $extra = ' ' . $extra; |
352 | }
|
352 | }
|
353 | PEAR::staticPopErrorHandling(); |
353 | PEAR::staticPopErrorHandling(); |
354 | $ret = PEAR::raiseError('could not extract the package.xml file from "' . |
354 | $ret = PEAR::raiseError('could not extract the package.xml file from "' . |
355 | $origfile . '"' . $extra); |
355 | $origfile . '"' . $extra); |
356 | return $ret; |
356 | return $ret; |
357 | }
|
357 | }
|
358 | PEAR::staticPopErrorHandling(); |
358 | PEAR::staticPopErrorHandling(); |
359 | $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile); |
359 | $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile); |
360 | return $ret; |
360 | return $ret; |
361 | }
|
361 | }
|
362 | 362 | ||
363 | /**
|
363 | /**
|
364 | * helper for extracting Archive_Tar errors
|
364 | * helper for extracting Archive_Tar errors
|
365 | * @var array
|
365 | * @var array
|
366 | * @access private
|
366 | * @access private
|
367 | */
|
367 | */
|
368 | var $_extractErrors = array(); |
368 | var $_extractErrors = array(); |
369 | 369 | ||
370 | /**
|
370 | /**
|
371 | * helper callback for extracting Archive_Tar errors
|
371 | * helper callback for extracting Archive_Tar errors
|
372 | *
|
372 | *
|
373 | * @param PEAR_Error|null $err
|
373 | * @param PEAR_Error|null $err
|
374 | * @return array
|
374 | * @return array
|
375 | * @access private
|
375 | * @access private
|
376 | */
|
376 | */
|
377 | function _extractErrors($err = null) |
377 | function _extractErrors($err = null) |
378 | {
|
378 | {
|
379 | static $errors = array(); |
379 | static $errors = array(); |
380 | if ($err === null) { |
380 | if ($err === null) { |
381 | $e = $errors; |
381 | $e = $errors; |
382 | $errors = array(); |
382 | $errors = array(); |
383 | return $e; |
383 | return $e; |
384 | }
|
384 | }
|
385 | $errors[] = $err->getMessage(); |
385 | $errors[] = $err->getMessage(); |
386 | }
|
386 | }
|
387 | 387 | ||
388 | /**
|
388 | /**
|
389 | * Create a PEAR_PackageFile_v* from a package.xml file.
|
389 | * Create a PEAR_PackageFile_v* from a package.xml file.
|
390 | *
|
390 | *
|
391 | * @access public
|
391 | * @access public
|
392 | * @param string $descfile name of package xml file
|
392 | * @param string $descfile name of package xml file
|
393 | * @param int $state package state (one of PEAR_VALIDATE_* constants)
|
393 | * @param int $state package state (one of PEAR_VALIDATE_* constants)
|
394 | * @param string|false $archive name of the archive this package.xml came
|
394 | * @param string|false $archive name of the archive this package.xml came
|
395 | * from, if any
|
395 | * from, if any
|
396 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
396 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
397 | * @uses PEAR_PackageFile::fromXmlString to create the oject after the
|
397 | * @uses PEAR_PackageFile::fromXmlString to create the oject after the
|
398 | * XML is loaded from the package.xml file.
|
398 | * XML is loaded from the package.xml file.
|
399 | */
|
399 | */
|
400 | function &fromPackageFile($descfile, $state, $archive = false) |
400 | function &fromPackageFile($descfile, $state, $archive = false) |
401 | {
|
401 | {
|
402 | if (is_string($descfile) && strlen($descfile) < 255 && |
402 | if (is_string($descfile) && strlen($descfile) < 255 && |
403 | (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) || |
403 | (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) || |
404 | (!$fp = @fopen($descfile, 'r')))) { |
404 | (!$fp = @fopen($descfile, 'r')))) { |
405 | $a = PEAR::raiseError("Unable to open $descfile"); |
405 | $a = PEAR::raiseError("Unable to open $descfile"); |
406 | return $a; |
406 | return $a; |
407 | }
|
407 | }
|
408 | 408 | ||
409 | // read the whole thing so we only get one cdata callback
|
409 | // read the whole thing so we only get one cdata callback
|
410 | // for each block of cdata
|
410 | // for each block of cdata
|
411 | fclose($fp); |
411 | fclose($fp); |
412 | $data = file_get_contents($descfile); |
412 | $data = file_get_contents($descfile); |
413 | $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive); |
413 | $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive); |
414 | return $ret; |
414 | return $ret; |
415 | }
|
415 | }
|
416 | 416 | ||
417 | 417 | ||
418 | /**
|
418 | /**
|
419 | * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file.
|
419 | * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file.
|
420 | *
|
420 | *
|
421 | * This method is able to extract information about a package from a .tgz
|
421 | * This method is able to extract information about a package from a .tgz
|
422 | * archive or from a XML package definition file.
|
422 | * archive or from a XML package definition file.
|
423 | *
|
423 | *
|
424 | * @access public
|
424 | * @access public
|
425 | * @param string $info file name
|
425 | * @param string $info file name
|
426 | * @param int $state package state (one of PEAR_VALIDATE_* constants)
|
426 | * @param int $state package state (one of PEAR_VALIDATE_* constants)
|
427 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
427 | * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
428 | * @uses fromPackageFile() if the file appears to be XML
|
428 | * @uses fromPackageFile() if the file appears to be XML
|
429 | * @uses fromTgzFile() to load all non-XML files
|
429 | * @uses fromTgzFile() to load all non-XML files
|
430 | */
|
430 | */
|
431 | function &fromAnyFile($info, $state) |
431 | function &fromAnyFile($info, $state) |
432 | {
|
432 | {
|
433 | if (is_dir($info)) { |
433 | if (is_dir($info)) { |
434 | $dir_name = realpath($info); |
434 | $dir_name = realpath($info); |
435 | if (file_exists($dir_name . '/package.xml')) { |
435 | if (file_exists($dir_name . '/package.xml')) { |
436 | $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state); |
436 | $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state); |
437 | } elseif (file_exists($dir_name . '/package2.xml')) { |
437 | } elseif (file_exists($dir_name . '/package2.xml')) { |
438 | $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state); |
438 | $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state); |
439 | } else { |
439 | } else { |
440 | $info = PEAR::raiseError("No package definition found in '$info' directory"); |
440 | $info = PEAR::raiseError("No package definition found in '$info' directory"); |
441 | }
|
441 | }
|
442 | return $info; |
442 | return $info; |
443 | }
|
443 | }
|
444 | 444 | ||
445 | $fp = false; |
445 | $fp = false; |
446 | if (is_string($info) && strlen($info) < 255 && |
446 | if (is_string($info) && strlen($info) < 255 && |
447 | (file_exists($info) || ($fp = @fopen($info, 'r')))) { |
447 | (file_exists($info) || ($fp = @fopen($info, 'r')))) { |
448 | if ($fp) { |
448 | if ($fp) { |
449 | fclose($fp); |
449 | fclose($fp); |
450 | }
|
450 | }
|
451 | $tmp = substr($info, -4); |
451 | $tmp = substr($info, -4); |
452 | if ($tmp == '.xml') { |
452 | if ($tmp == '.xml') { |
453 | $info = &PEAR_PackageFile::fromPackageFile($info, $state); |
453 | $info = &PEAR_PackageFile::fromPackageFile($info, $state); |
454 | } elseif ($tmp == '.tar' || $tmp == '.tgz') { |
454 | } elseif ($tmp == '.tar' || $tmp == '.tgz') { |
455 | $info = &PEAR_PackageFile::fromTgzFile($info, $state); |
455 | $info = &PEAR_PackageFile::fromTgzFile($info, $state); |
456 | } else { |
456 | } else { |
457 | $fp = fopen($info, "r"); |
457 | $fp = fopen($info, "r"); |
458 | $test = fread($fp, 5); |
458 | $test = fread($fp, 5); |
459 | fclose($fp); |
459 | fclose($fp); |
460 | if ($test == "<?xml") { |
460 | if ($test == "<?xml") { |
461 | $info = &PEAR_PackageFile::fromPackageFile($info, $state); |
461 | $info = &PEAR_PackageFile::fromPackageFile($info, $state); |
462 | } else { |
462 | } else { |
463 | $info = &PEAR_PackageFile::fromTgzFile($info, $state); |
463 | $info = &PEAR_PackageFile::fromTgzFile($info, $state); |
464 | }
|
464 | }
|
465 | }
|
465 | }
|
466 | } else { |
466 | } else { |
467 | $info = PEAR::raiseError("Cannot open '$info' for parsing"); |
467 | $info = PEAR::raiseError("Cannot open '$info' for parsing"); |
468 | return $info; |
468 | return $info; |
469 | }
|
469 | }
|
470 | return $info; |
470 | return $info; |
471 | }
|
471 | }
|
472 | }
|
472 | }
|
473 | 473 | ||
474 | ?>
|
474 | ?>
|
475 | 475 |