1: <?php
2: /**
3: * SplClassLoader implementation that implements the technical interoperability
4: * standards for PHP 5.3 namespaces and class names.
5: *
6: * http://groups.google.com/group/php-standards/web/final-proposal
7: *
8: * // Example which loads classes for the Doctrine Common package in the
9: * // Doctrine\Common namespace.
10: * $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine');
11: * $classLoader->register();
12: *
13: * @author Jonathan H. Wage <jonwage@gmail.com>
14: * @author Roman S. Borschel <roman@code-factory.org>
15: * @author Matthew Weier O'Phinney <matthew@zend.com>
16: * @author Kris Wallsmith <kris.wallsmith@gmail.com>
17: * @author Fabien Potencier <fabien.potencier@symfony-project.org>
18: */
19:
20: namespace Mockery;
21:
22: class Loader
23: {
24: private $_fileExtension = '.php';
25: private $_namespace;
26: private $_includePath;
27: private $_namespaceSeparator = '\\';
28:
29: /**
30: * Creates a new <tt>Loader</tt> that loads classes of the
31: * specified namespace.
32: *
33: * @param string $ns The namespace to use.
34: */
35: public function __construct($ns = 'Mockery', $includePath = null)
36: {
37: $this->_namespace = $ns;
38: $this->_includePath = $includePath;
39: }
40:
41: /**
42: * Sets the namespace separator used by classes in the namespace of this class loader.
43: *
44: * @param string $sep The separator to use.
45: */
46: public function setNamespaceSeparator($sep)
47: {
48: $this->_namespaceSeparator = $sep;
49: }
50:
51: /**
52: * Gets the namespace seperator used by classes in the namespace of this class loader.
53: *
54: * @return void
55: */
56: public function getNamespaceSeparator()
57: {
58: return $this->_namespaceSeparator;
59: }
60:
61: /**
62: * Sets the base include path for all class files in the namespace of this class loader.
63: *
64: * @param string $includePath
65: */
66: public function setIncludePath($includePath)
67: {
68: $this->_includePath = $includePath;
69: }
70:
71: /**
72: * Gets the base include path for all class files in the namespace of this class loader.
73: *
74: * @return string $includePath
75: */
76: public function getIncludePath()
77: {
78: return $this->_includePath;
79: }
80:
81: /**
82: * Sets the file extension of class files in the namespace of this class loader.
83: *
84: * @param string $fileExtension
85: */
86: public function setFileExtension($fileExtension)
87: {
88: $this->_fileExtension = $fileExtension;
89: }
90:
91: /**
92: * Gets the file extension of class files in the namespace of this class loader.
93: *
94: * @return string $fileExtension
95: */
96: public function getFileExtension()
97: {
98: return $this->_fileExtension;
99: }
100:
101: /**
102: * Installs this class loader on the SPL autoload stack.
103: *
104: * @param bool $prepend If true, prepend autoloader on the autoload stack
105: */
106: public function register($prepend = false)
107: {
108: spl_autoload_register(array($this, 'loadClass'), true, $prepend);
109: }
110:
111: /**
112: * Uninstalls this class loader from the SPL autoloader stack.
113: */
114: public function unregister()
115: {
116: spl_autoload_unregister(array($this, 'loadClass'));
117: }
118:
119: /**
120: * Loads the given class or interface.
121: *
122: * @param string $className The name of the class to load.
123: * @return void
124: */
125: public function loadClass($className)
126: {
127: if ($className === 'Mockery') {
128: require $this->getFullPath('Mockery.php');
129: return;
130: }
131: if (null === $this->_namespace
132: || $this->_namespace.$this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace.$this->_namespaceSeparator))) {
133: $fileName = '';
134: $namespace = '';
135: if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) {
136: $namespace = substr($className, 0, $lastNsPos);
137: $className = substr($className, $lastNsPos + 1);
138: $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
139: }
140: $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension;
141: require $this->getFullPath($fileName);
142: }
143: }
144:
145: /**
146: * Returns full path for $fileName if _includePath is set, or leaves as-is for PHP's internal search in 'require'.
147: *
148: * @param string $fileName relative to include path.
149: * @return string
150: */
151: private function getFullPath($fileName)
152: {
153: return ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName;
154: }
155: }
156: