Subversion-Projekte lars-tiefland.cakephp

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* SVN FILE: $Id: magic_db.php 7945 2008-12-19 02:16:01Z gwoo $ */
3
/**
4
 * MagicDb parser and file analyzer
5
 *
6
 * PHP versions 4 and 5
7
 *
8
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
9
 * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
10
 *
11
 * Licensed under The MIT License
12
 * Redistributions of files must retain the above copyright notice.
13
 *
14
 * @filesource
15
 * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
16
 * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
17
 * @package       cake
18
 * @subpackage    cake.cake.libs
19
 * @since         CakePHP(tm) v 1.2.0
20
 * @version       $Revision: 7945 $
21
 * @modifiedby    $LastChangedBy: gwoo $
22
 * @lastmodified  $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
23
 * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
24
 */
25
if (!class_exists('File')) {
26
	uses('object', 'file');
27
}
28
/**
29
 * A class to parse and use the MagicDb for file type analysis
30
 *
31
 * @package       cake.tests
32
 * @subpackage    cake.tests.cases.libs
33
 */
34
class MagicDb extends Object {
35
/**
36
 * Holds the parsed MagicDb for this class instance
37
 *
38
 * @var array
39
 **/
40
	var $db = array();
41
 
42
/**
43
 * Reads a MagicDb from various formats
44
 *
45
 * @var $magicDb mixed Can be an array containing the db, a magic db as a string, or a filename pointing to a magic db in .db or magic.db.php format
46
 * @return boolean Returns false if reading / validation failed or true on success.
47
 * @author        Felix
48
 **/
49
	function read($magicDb = null) {
50
		if (!is_string($magicDb) && !is_array($magicDb)) {
51
			return false;
52
		}
53
		if (is_array($magicDb) || strpos($magicDb, '# FILE_ID DB') === 0) {
54
			$data = $magicDb;
55
		} else {
56
			$File =& new File($magicDb);
57
			if (!$File->exists()) {
58
				return false;
59
			}
60
			if ($File->ext() == 'php') {
61
				include($File->pwd());
62
				$data = $magicDb;
63
			} else {
64
				// @TODO: Needs test coverage
65
				$data = $File->read();
66
			}
67
		}
68
 
69
		$magicDb = $this->toArray($data);
70
		if (!$this->validates($magicDb)) {
71
			return false;
72
		}
73
		return !!($this->db = $magicDb);
74
	}
75
 
76
/**
77
 * Parses a MagicDb $data string into an array or returns the current MagicDb instance as an array
78
 *
79
 * @param string $data A MagicDb string to turn into an array
80
 * @return array A parsed MagicDb array or an empty array if the $data param was invalid. Returns the db property if $data is not set.
81
 * @access public
82
 */
83
	function toArray($data = null) {
84
		if (is_array($data)) {
85
			return $data;
86
		}
87
		if ($data === null) {
88
			return $this->db;
89
		}
90
 
91
		if (strpos($data, '# FILE_ID DB') !== 0) {
92
			return array();
93
		}
94
 
95
		$lines = explode("\r\n", $data);
96
		$db = array();
97
 
98
		$validHeader = count($lines > 3)
99
					&& preg_match('/^# Date:([0-9]{4}-[0-9]{2}-[0-9]{2})$/', $lines[1], $date)
100
					&& preg_match('/^# Source:(.+)$/', $lines[2], $source)
101
					&& strlen($lines[3]) == 0;
102
		if (!$validHeader) {
103
			return $db;
104
		}
105
 
106
		$db = array('header' => array('Date' => $date[1], 'Source' => $source[1]), 'database' => array());
107
		$lines = array_splice($lines, 3);
108
 
109
		$format = array();
110
		while (!empty($lines)) {
111
			$line = array_shift($lines);
112
			if (isset($line[0]) && $line[0] == '#' || empty($line)) {
113
				continue;
114
			}
115
 
116
			$columns = explode("\t", $line);
117
			if (in_array($columns[0]{0}, array('>', '&'))) {
118
				$format[] = $columns;
119
			} elseif (!empty($format)) {
120
				$db['database'][] = $format;
121
				$format = array($columns);
122
			} else {
123
				$format = array($columns);
124
			}
125
		}
126
 
127
		return $db;
128
	}
129
 
130
/**
131
 * Returns true if the MagicDb instance or the passed $magicDb is valid
132
 *
133
 * @param mixed $magicDb A $magicDb string / array to validate (optional)
134
 * @return boolean True if the $magicDb / instance db validates, false if not
135
 * @access public
136
 */
137
	function validates($magicDb = null) {
138
		if (is_null($magicDb)) {
139
			$magicDb = $this->db;
140
		} elseif (!is_array($magicDb)) {
141
			$magicDb = $this->toArray($magicDb);
142
		}
143
 
144
		return isset($magicDb['header'], $magicDb['database']) && is_array($magicDb['header']) && is_array($magicDb['database']);
145
	}
146
 
147
/**
148
 * Analyzes a given $file using the currently loaded MagicDb information based on the desired $options
149
 *
150
 * @param string $file Absolute path to the file to analyze
151
 * @param array $options TBT
152
 * @return mixed
153
 * @access public
154
 */
155
	function analyze($file, $options = array()) {
156
		if (!is_string($file)) {
157
			return false;
158
		}
159
 
160
		$matches = array();
161
		$MagicFileResource =& new MagicFileResource($file);
162
		foreach ($this->db['database'] as $format) {
163
			$magic = $format[0];
164
			$match = $MagicFileResource->test($magic);
165
			if ($match === false) {
166
				continue;
167
			}
168
			$matches[] = $magic;
169
		}
170
 
171
		return $matches;
172
	}
173
}
174
 
175
/**
176
 * undocumented class
177
 *
178
 * @package       cake.tests
179
 * @subpackage    cake.tests.cases.libs
180
 */
181
class MagicFileResource extends Object{
182
/**
183
 * undocumented variable
184
 *
185
 * @var unknown
186
 * @access public
187
 */
188
	var $resource = null;
189
/**
190
 * undocumented variable
191
 *
192
 * @var unknown
193
 * @access public
194
 */
195
	var $offset = 0;
196
/**
197
 * undocumented function
198
 *
199
 * @param unknown $file
200
 * @return void
201
 * @access public
202
 */
203
	function __construct($file) {
204
		if (file_exists($file)) {
205
			$this->resource =& new File($file);
206
		} else {
207
			$this->resource = $file;
208
		}
209
	}
210
/**
211
 * undocumented function
212
 *
213
 * @param unknown $magic
214
 * @return void
215
 * @access public
216
 */
217
	function test($magic) {
218
		$offset = null;
219
		$type = null;
220
		$expected = null;
221
		$comment = null;
222
		if (isset($magic[0])) {
223
			$offset = $magic[0];
224
		}
225
		if (isset($magic[1])) {
226
			$type = $magic[1];
227
		}
228
		if (isset($magic[2])) {
229
			$expected = $magic[2];
230
		}
231
		if (isset($magic[3])) {
232
			$comment = $magic[3];
233
		}
234
		$val = $this->extract($offset, $type, $expected);
235
		return $val == $expected;
236
	}
237
/**
238
 * undocumented function
239
 *
240
 * @param unknown $type
241
 * @param unknown $length
242
 * @return void
243
 * @access public
244
 */
245
	function read($length = null) {
246
		if (!is_object($this->resource)) {
247
			return substr($this->resource, $this->offset, $length);
248
		}
249
		return $this->resource->read($length);
250
	}
251
/**
252
 * undocumented function
253
 *
254
 * @param unknown $type
255
 * @param unknown $expected
256
 * @return void
257
 * @access public
258
 */
259
	function extract($offset, $type, $expected) {
260
		switch ($type) {
261
			case 'string':
262
				$this->offset($offset);
263
				$val = $this->read(strlen($expected));
264
				if ($val === $expected) {
265
					return true;
266
				}
267
				break;
268
		}
269
	}
270
/**
271
 * undocumented function
272
 *
273
 * @param unknown $offset
274
 * @param unknown $whence
275
 * @return void
276
 * @access public
277
 */
278
	function offset($offset = null) {
279
		if (is_null($offset)) {
280
			if (!is_object($this->resource)) {
281
				return $this->offset;
282
			}
283
			return $this->offset;
284
		}
285
 
286
		if (!ctype_digit($offset)) {
287
			return false;
288
		}
289
		if (is_object($this->resource)) {
290
			$this->resource->offset($offset);
291
		} else {
292
			$this->offset = $offset;
293
		}
294
	}
295
}
296
 
297
?>