Development

/branches/1.2/lib/autoload/sfSimpleAutoload.class.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/autoload/sfSimpleAutoload.class.php

Revision 17858, 5.9 kB (checked in by FabianLange, 5 years ago)

[1.1, 1.2, 1.3] fixed some codeing standards (fixes #6376 - patch from gimler)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  * sfSimpleAutoload class.
13  *
14  * This class is a singleton as PHP seems to be unable to register 2 autoloaders that are instances
15  * of the same class (why?).
16  *
17  * @package    symfony
18  * @subpackage autoload
19  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
20  * @version    SVN: $Id$
21  */
22 class sfSimpleAutoload
23 {
24   static protected
25     $registered = false,
26     $instance   = null;
27
28   protected
29     $cacheFile    = null,
30     $cacheLoaded  = false,
31     $cacheChanged = false,
32     $dirs         = array(),
33     $files        = array(),
34     $classes      = array();
35
36   protected function __construct($cacheFile = null)
37   {
38     if (!is_null($cacheFile))
39     {
40       $this->cacheFile = $cacheFile;
41     }
42
43     $this->loadCache();
44   }
45
46   /**
47    * Retrieves the singleton instance of this class.
48    *
49    * @param string $cacheFile The file path to save the cache
50    *
51    * @return sfSimpleAutoload A sfSimpleAutoload implementation instance.
52    */
53   static public function getInstance($cacheFile = null)
54   {
55     if (!isset(self::$instance))
56     {
57       self::$instance = new sfSimpleAutoload($cacheFile);
58     }
59
60     return self::$instance;
61   }
62
63   /**
64    * Register sfSimpleAutoload in spl autoloader.
65    *
66    * @return void
67    */
68   static public function register()
69   {
70     if (self::$registered)
71     {
72       return;
73     }
74
75     ini_set('unserialize_callback_func', 'spl_autoload_call');
76     if (false === spl_autoload_register(array(self::getInstance(), 'autoload')))
77     {
78       throw new sfException(sprintf('Unable to register %s::autoload as an autoloading method.', get_class(self::getInstance())));
79     }
80
81     if (self::getInstance()->cacheFile)
82     {
83       register_shutdown_function(array(self::getInstance(), 'saveCache'));
84     }
85
86     self::$registered = true;
87   }
88
89   /**
90    * Unregister sfSimpleAutoload from spl autoloader.
91    *
92    * @return void
93    */
94   static public function unregister()
95   {
96     spl_autoload_unregister(array(self::getInstance(), 'autoload'));
97     self::$registered = false;
98   }
99
100   /**
101    * Handles autoloading of classes.
102    *
103    * @param string $class A class name.
104    *
105    * @return boolean Returns true if the class has been loaded
106    */
107   public function autoload($class)
108   {
109     // class already exists
110     if (class_exists($class, false) || interface_exists($class, false))
111     {
112       return true;
113     }
114
115     // we have a class path, let's include it
116     if (isset($this->classes[$class]))
117     {
118       require($this->classes[$class]);
119
120       return true;
121     }
122
123     return false;
124   }
125
126   /**
127    * Loads the cache.
128    */
129   public function loadCache()
130   {
131     if (!$this->cacheFile || !is_readable($this->cacheFile))
132     {
133       return;
134     }
135
136     list($this->classes, $this->dirs, $this->files) = unserialize(file_get_contents($this->cacheFile));
137
138     $this->cacheLoaded = true;
139     $this->cacheChanged = false;
140   }
141
142   /**
143    * Saves the cache.
144    */
145   public function saveCache()
146   {
147     if ($this->cacheChanged)
148     {
149       if (is_writable(dirname($this->cacheFile)))
150       {
151         file_put_contents($this->cacheFile, serialize(array($this->classes, $this->dirs, $this->files)));
152       }
153
154       $this->cacheChanged = false;
155     }
156   }
157
158   /**
159    * Reloads cache.
160    */
161   public function reload()
162   {
163     $this->classes     = array();
164     $this->cacheLoaded = false;
165
166     foreach ($this->dirs as $dir)
167     {
168       $this->addDirectory($dir);
169     }
170
171     foreach ($this->files as $file)
172     {
173       $this->addFile($file);
174     }
175
176     $this->cacheLoaded  = true;
177     $this->cacheChanged = true;
178   }
179
180   /**
181    * Removes the cache.
182    */
183   public function removeCache()
184   {
185     @unlink($this->cacheFile);
186   }
187
188   /**
189    * Adds a directory to the autoloading system if not yet present and give it the highest possible precedence.
190    *
191    * @param string $dir The directory to look for classes
192    * @param string $ext The extension to look for
193    */
194   public function addDirectory($dir, $ext = '.php')
195   {
196     $finder = sfFinder::type('file')->follow_link()->name('*'.$ext);
197
198     if ($dirs = glob($dir))
199     {
200       foreach ($dirs as $dir)
201       {
202         if (false !== ($key = array_search($dir, $this->dirs)))
203         {
204           unset($this->dirs[$key]);
205           $this->dirs[] = $dir;
206
207           if ($this->cacheLoaded)
208           {
209             continue;
210           }
211         }
212         else
213         {
214           $this->dirs[] = $dir;
215         }
216
217         $this->cacheChanged = true;
218         $this->addFiles($finder->in($dir), false);
219       }
220     }
221   }
222
223   /**
224    * Adds files to the autoloading system.
225    *
226    * @param array   $files    An array of files
227    * @param Boolean $register Whether to register those files as single entities (used when reloading)
228    */
229   public function addFiles(array $files, $register = true)
230   {
231     foreach ($files as $file)
232     {
233       $this->addFile($file, $register);
234     }
235   }
236
237   /**
238    * Adds a file to the autoloading system.
239    *
240    * @param string  $file     A file path
241    * @param Boolean $register Whether to register those files as single entities (used when reloading)
242    */
243   public function addFile($file, $register = true)
244   {
245     if (!is_file($file))
246     {
247       return;
248     }
249
250     if (in_array($file, $this->files))
251     {
252       if ($this->cacheLoaded)
253       {
254         return;
255       }
256     }
257     else
258     {
259       if ($register)
260       {
261         $this->files[] = $file;
262       }
263     }
264
265     if ($register)
266     {
267       $this->cacheChanged = true;
268     }
269
270     preg_match_all('~^\s*(?:abstract\s+|final\s+)?(?:class|interface)\s+(\w+)~mi', file_get_contents($file), $classes);
271     foreach ($classes[1] as $class)
272     {
273       $this->classes[$class] = $file;
274     }
275   }
276
277   public function setClassPath($class, $path)
278   {
279     $this->overriden[$class] = $path;
280
281     $this->classes[$class] = $path;
282   }
283 }
284
Note: See TracBrowser for help on using the browser.