]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/FileFinder.php
(Slightly modified) SF Patch #473466 by <ax@condat.de>.
[SourceForge/phpwiki.git] / lib / FileFinder.php
1 <?php rcs_id('$Id: FileFinder.php,v 1.3 2001-10-29 20:43:18 dairiki Exp $');
2
3 // FIXME: make this work with non-unix (e.g. DOS) filenames.
4
5 /**
6  * A class for finding files.
7  */
8 class FileFinder
9 {
10     /**
11      * Constructor.
12      *
13      * @param $path array A list of directories in which to search for files.
14      */
15     function FileFinder ($path = false) {
16         if ($path === false)
17             $path = $this->_get_include_path();
18         $this->_path = $path;
19     }
20
21     /**
22      * Find file.
23      *
24      * @param $file string File to search for.
25      * @return string The filename (including path), if found, otherwise false.
26      */
27     function findFile ($file, $missing_okay = false) {
28         if ($this->_is_abs($file)) {
29             if (file_exists($file))
30                 return $file;
31         }
32         elseif ( ($dir = $this->_search_path($file)) ) {
33             return "$dir/$file";
34         }
35
36         return $missing_okay ? false : $this->_not_found($file);
37     }
38             
39     /**
40      * Try to include file.
41      *
42      * If file is found in the path, then the files directory is added
43      * to PHP's include_path (if it's not already there.)  Then
44      * the file is include_once()'d.
45      *
46      * @param $file string File to include.
47      * @return bool True if file was successfully included.
48      */
49     function includeOnce ($file) {
50         if ( ($ret = @include_once($file)) )
51             return $ret;
52
53         if (!$this->_is_abs($file)) {
54             if ( ($dir = $this->_search_path($file)) && is_file("$dir/$file")) {
55                 $this->_append_to_include_path($dir);
56                 return include_once($file);
57             }
58         }
59         
60         return $this->_not_found($file);
61     }
62
63     /**
64      * Determine if path is absolute.
65      *
66      * @access private
67      * @param $path string Path.
68      * @return bool True iff path is absolute. 
69      */
70     function _is_abs($path) {
71         return ereg('^/', $path);
72     }
73     
74     /**
75      * Report a "file not found" error.
76      *
77      * @access private
78      * @param $file string Name of missing file.
79      * @return bool false.
80      */
81     function _not_found($file) {
82         trigger_error("$file: file not found", E_USER_ERROR);
83         return false;
84     }
85     
86         
87     /**
88      * Search our path for a file.
89      *
90      * @access private
91      * @param $file string File to find.
92      * @return string Directory which contains $file, or false.
93      */
94     function _search_path ($file) {
95         foreach ($this->_path as $dir) {
96             if (file_exists("$dir/$file"))
97                 return $dir;
98         }
99         return false;
100     }
101
102     /**
103      * The system-dependent path-separator character.  On UNIX systems,
104      * this character is ':'; on Win32 systems it is ';'.
105      *
106      * @access private
107      * @return string path_separator.
108      */
109     function _get_path_separator () {
110         return preg_match('/^Windows/', php_uname()) ? ';' : ':';
111     }
112         
113     /**
114      * Get the value of PHP's include_path.
115      *
116      * @access private
117      * @return array Include path.
118      */
119     function _get_include_path() {
120         $path = ini_get('include_path');
121         if (empty($path))
122             $path = '.';
123         return explode($this->_get_path_separator(), $path);
124     }
125     
126     /**
127      * Add a directory to the end of PHP's include_path.
128      *
129      * The directory is appended only if it is not already listed
130      * in the include_path.
131      *
132      * @access private
133      * @param $dir string Directory to add.
134      */
135     function _append_to_include_path ($dir) {
136         $path = $this->_get_include_path();
137         if (!in_array($dir, $path)) {
138             $path[] = $dir;
139             //ini_set('include_path', implode(':', $path));
140         }
141         /*
142          * Some (buggy) PHP's (notable SourceForge's PHP 4.0.6)
143          * sometimes don't seem to heed their include_path.
144          * I.e. sometimes a file is not found even though it seems
145          * to be in the current include_path.
146          * A simple ini_set('include_path', ini_get('include_path'))
147          * seems to be enough to fix the problem
148          *
149          * This following line should be in the above if-block,
150          * but we put it here, as it seems to work-around the bug. 
151          */
152         ini_set('include_path', implode($this->_get_path_separator(), $path));
153     }
154 }
155
156 /**
157  * A class for finding PEAR code.
158  *
159  * This is a subclass of FileFinder which searches a standard list of directories
160  * where PEAR code is likely to be installed.
161  *
162  * Example usage:
163  * <pre>
164  *   $pearFinder = new PearFileFinder;
165  *   $pearFinder->includeOnce('DB.php');
166  * </pre>
167  * The above code will look for 'DB.php', if found, the directory in which it was
168  * found will be added to PHP's include_path, and the file will be included.
169  * (If the file is not found, and E_USER_ERROR will be thrown.)
170  */
171 class PearFileFinder
172     extends FileFinder
173 {
174     /**
175      * Constructor.
176      *
177      * @param $path array Where to look for PEAR library code.
178      * A good set of defaults is provided, so you can probably leave
179      * this parameter blank.
180      */
181     function PearFileFinder ($path = false) {
182         $this->FileFinder(array('/usr/share/php4',
183                                 '/usr/share/php',
184                                 '/usr/lib/php4',
185                                 '/usr/lib/php',
186                                 '/usr/local/share/php4',
187                                 '/usr/local/share/php',
188                                 '/usr/local/lib/php4',
189                                 '/usr/local/lib/php'));
190     }
191 }
192
193 /**
194  * Find PhpWiki localized files.
195  *
196  * This is a subclass of FileFinder which searches PHP's include_path for
197  * files.  It looks first for "locale/$LANG/$file", then for "$file".
198  *
199  * If $LANG is something like "de_DE.iso8859-1@euro", this class will
200  * also search under various less specific variations like "de_DE.iso8859-1",
201  * "de_DE" and "de".
202  */
203 class LocalizedFileFinder
204     extends FileFinder
205 {
206     /**
207      * Constructor.
208      */
209     function LocalizedFileFinder () {
210         $include_path = $this->_get_include_path();
211         $path = array();
212
213         $lang = $this->_get_lang();
214         assert(!empty($lang));
215         
216         // A locale can be, e.g. de_DE.iso8859-1@euro.
217         // Try less specific versions of the locale: 
218         $langs[] = $lang;
219         foreach (array('@', '.', '_') as $sep) {
220             if ( ($tail = strchr($lang, $sep)) )
221                 $langs[] = substr($lang, 0, -strlen($tail));
222         }
223
224         foreach ($langs as $lang) {
225             foreach ($include_path as $dir) {
226                 $path[] = "$dir/locale/$lang";
227             }
228         }
229
230         $this->FileFinder(array_merge($path, $include_path));
231     }
232
233     /**
234      * Try to figure out the appropriate value for $LANG.
235      *
236      *@access private
237      *@return string The value of $LANG.
238      */
239     function _get_lang() {
240         if (!empty($GLOBALS['LANG']))
241             return $GLOBALS['LANG'];
242
243         foreach (array('LC_ALL', 'LC_MESSAGES', 'LC_RESPONSES', 'LANG') as $var) {
244             $lang = getenv($var);
245             if (!empty($lang))
246                 return $lang;
247         }
248         
249         return "C";
250     }
251
252 }
253     
254 // Local Variables:
255 // mode: php
256 // tab-width: 8
257 // c-basic-offset: 4
258 // c-hanging-comment-ender-p: nil
259 // indent-tabs-mode: nil
260 // End:   
261 ?>