├── .gitignore ├── src └── dflydev │ └── core │ ├── io │ ├── exception │ │ ├── Exception.php │ │ └── ResourceNotFoundException.php │ ├── IResourceLoader.php │ ├── IResource.php │ ├── FileSystemResource.php │ ├── FileSystemResourceLoader.php │ └── CompositeResourceLoader.php │ └── ClassLoader.php ├── tests ├── bootstrap.php └── dflydev │ └── tests │ └── core │ └── io │ ├── FileSystemResourceLoaderTest.php │ └── CompositeResourceLoaderTest.php ├── autoload.php.dist ├── phpunit.xml.dist ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | phpunit.xml 2 | build 3 | -------------------------------------------------------------------------------- /src/dflydev/core/io/exception/Exception.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Exception extends \Exception { 18 | } -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | 16 | if (file_exists($file = __DIR__.'/../autoload.php')) { 17 | require_once $file; 18 | } elseif (file_exists($file = __DIR__.'/../autoload.php.dist')) { 19 | require_once $file; 20 | } -------------------------------------------------------------------------------- /src/dflydev/core/io/IResourceLoader.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | interface IResourceLoader { 17 | 18 | /** 19 | * Return a Resource handle for the specified resource. 20 | * @return IResource 21 | * @throws exception\ResourceNotFoundException 22 | */ 23 | function load($location); 24 | 25 | } -------------------------------------------------------------------------------- /autoload.php.dist: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | 16 | require_once(__DIR__ . '/src/dflydev/core/ClassLoader.php'); 17 | 18 | use dflydev\core\ClassLoader; 19 | 20 | $classLoader = new ClassLoader(); 21 | 22 | $classLoader->registerNamespaces(array( 23 | 'dflydev\core' => 'src', 24 | 'dflydev\tests\core' => 'tests', 25 | )); 26 | 27 | $classLoader->activate(); -------------------------------------------------------------------------------- /src/dflydev/core/io/exception/ResourceNotFoundException.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class ResourceNotFoundException extends Exception { 18 | 19 | /** 20 | * Constructor 21 | * @param string $location Requested resource location 22 | */ 23 | public function __construct($location) { 24 | parent::__construct('Could not find resource "' . $location . '"'); 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/dflydev/ 16 | 17 | 18 | 19 | 20 | 21 | ./src/dflydev/ 22 | 23 | ./src/dflydev/*/resources 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/dflydev/core/io/IResource.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | interface IResource { 17 | 18 | /** 19 | * Return whether this resource actually exists in physical form. 20 | * @return bool 21 | */ 22 | function exists(); 23 | 24 | /** 25 | * Return whether this resource is a file. 26 | * @return bool 27 | */ 28 | function isFile(); 29 | 30 | /** 31 | * Return whether this resource is a directory. 32 | * @return bool 33 | */ 34 | function isDirectory(); 35 | 36 | /** 37 | * Return the filename. 38 | * @return string 39 | */ 40 | function filename(); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/dflydev/core/io/FileSystemResource.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class FileSystemResource implements IResource { 18 | 19 | /** 20 | * @var string Filename 21 | */ 22 | protected $filename; 23 | 24 | /** 25 | * Constructor 26 | * @param string $filename 27 | */ 28 | public function __construct($filename) { 29 | $this->filename = $filename; 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function exists() { 36 | return file_exists($this->filename); 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function isFile() { 43 | return file_exists($this->filename) and is_file($this->filename); 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function isDirectory() { 50 | return file_exists($this->filename) and is_dir($this->filename); 51 | } 52 | 53 | /** 54 | * {@inheritdoc} 55 | */ 56 | public function filename() { 57 | return $this->filename; 58 | 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /src/dflydev/core/io/FileSystemResourceLoader.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class FileSystemResourceLoader implements IResourceLoader { 18 | 19 | /** 20 | * @var array 21 | */ 22 | private $paths = array(); 23 | 24 | /** 25 | * Constructor. 26 | * 27 | * @param type $paths Paths 28 | */ 29 | public function __construct($paths) { 30 | foreach ( (is_array($paths) ? $paths : array($paths)) as $path ) { 31 | if ( file_exists($path) ) { $this->paths[] = $path; } 32 | } 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function load($location) { 39 | if ( file_exists($location) ) { 40 | return new FileSystemResource(realpath($location)); 41 | } 42 | foreach ( $this->paths as $path ) { 43 | $filename = $path . '/' . $location; 44 | if ( file_exists($filename) ) { 45 | return new FileSystemResource(realpath($filename)); 46 | } 47 | } 48 | 49 | throw new exception\ResourceNotFoundException($location); 50 | 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011, Dragonfly Development Inc 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of Dragonfly Development Inc nor the names of its 13 | contributors may be used to endorse or promote products derived from 14 | this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dragonfly Development PHP Core Library # 2 | 3 | Provides basic bootstrapping functionality such as resource locating and 4 | class loading. 5 | 6 | ## Dependencies ## 7 | 8 | None. 9 | 10 | This package is likely a dependency for many Dragonfly Development libraries. 11 | At the very least, the dflydev\core\ClassLoader is likely to be suggested 12 | for a lack of a [better solution](https://github.com/symfony/ClassLoader). 13 | 14 | ## Usage ## 15 | 16 | ### Class Loader ### 17 | 18 | Simple class loader based on the [Symfony UniversalClassLoader](https://github.com/symfony/ClassLoader) 19 | that can be used to load classes following the [PSR-0 autoloader interoperability standard](http://groups.google.com/group/php-standards/web/psr-0-final-proposal). 20 | 21 | $classLoader = new ClassLoader(); 22 | $classLoader->registerNamespaces(array( 23 | // 'namespace' => '/path/to/namespace/root' 24 | 'dflydev\\core' => __DIR__.'/src', 25 | )); 26 | $classLoader->activate(); 27 | 28 | This class loader is provided as a fallback that can be used if a project 29 | does not already have a PSR-0 capable class loader. 30 | 31 | ### Resource Loader ### 32 | 33 | use dflydev\core\io\FileSystemResourceLoader 34 | $resourceLoader = new FileSystemResourceLoader('/tmp'); 35 | try { 36 | $resource = $resourceLoader->load('somefile.txt'); 37 | } catch (dflydev\core\io\exception\ResourceNotFoundException $e) { 38 | // somefile.txt must not have been able to be located 39 | // in the specified directory/directories. 40 | } 41 | 42 | ## More Information ## 43 | 44 | More information can be found on the [d2code Redmine](http://redmine.dflydev.com/projects/dflydev-core-php). 45 | 46 | -------------------------------------------------------------------------------- /src/dflydev/core/io/CompositeResourceLoader.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class CompositeResourceLoader implements IResourceLoader { 18 | 19 | /** 20 | * @var array 21 | */ 22 | private $resourceLoaders = array(); 23 | 24 | /** 25 | * Constructor 26 | * @param array|IResourceLoader $resourceLoaders Resource loaders 27 | */ 28 | public function __construct($resourceLoaders = null) { 29 | if ( $resourceLoaders !== null ) { 30 | $this->resourceLoaders = (array) $resourceLoaders; 31 | } 32 | } 33 | 34 | /** 35 | * Append a resource loader. 36 | * @param IResourceLoader $resourceLoader A resource loader 37 | */ 38 | public function appendResourceLoader(IResourceLoader $resourceLoader) { 39 | $this->resourceLoaders[] = $resourceLoader; 40 | } 41 | 42 | /** 43 | * Append resource loaders. 44 | * @param array $resourceLoaders A resource loader 45 | */ 46 | public function appendResourceLoaders(array $resourceLoaders) { 47 | $this->resourceLoaders = array_merge($this->resourceLoaders, $resourceLoaders); 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function load($location) { 54 | foreach ( $this->resourceLoaders as $resourceLoader ) { 55 | try { 56 | return $resourceLoader->load($location); 57 | } catch (exception\ResourceNotFoundException $e) { 58 | // fine, try the next... 59 | } 60 | } 61 | throw new exception\ResourceNotFoundException($location); 62 | } 63 | 64 | 65 | } -------------------------------------------------------------------------------- /src/dflydev/core/ClassLoader.php: -------------------------------------------------------------------------------- 1 | and can be found here: 8 | * 9 | * https://github.com/symfony/ClassLoader 10 | * 11 | * For the full copyright and license information, please view the LICENSE 12 | * file that was distributed with this source code. 13 | */ 14 | 15 | namespace dflydev\core; 16 | 17 | /** 18 | * Description of ClassLoader 19 | * 20 | * @author Beau Simensen 21 | */ 22 | class ClassLoader { 23 | 24 | /** 25 | * @var array 26 | */ 27 | private $namespaces = array(); 28 | 29 | /** 30 | * Registers an array of namespaces. 31 | * @param array $namespaces An array of namespaces (namespaces as keys and locations as values) 32 | */ 33 | public function registerNamespaces(array $namespaces) { 34 | foreach ( $namespaces as $namespace => $locations ) { 35 | $this->namespaces[$namespace] = (array) $locations; 36 | } 37 | } 38 | 39 | /** 40 | * Activate the autoloader. 41 | * @param type $prepend Whether to prepend the autoloader or not 42 | */ 43 | public function activate($prepend = false) { 44 | spl_autoload_register(array($this, 'load'), true, $prepend); 45 | } 46 | 47 | /** 48 | * Attempt to load a given class or interface. 49 | * @param string $class The name of the lass 50 | */ 51 | public function load($class) { 52 | $file = $this->locate($class); 53 | if ($file) { 54 | require $file; 55 | } 56 | } 57 | 58 | /** 59 | * Locates the file in which the class is defined. 60 | * @param type $class The name of the class 61 | * @return string Filename 62 | */ 63 | protected function locate($class) { 64 | if ( '\\' == $class[0] ) { 65 | $class = substr($class, 1); 66 | } 67 | if (false !== $pos = strrpos($class, '\\')) { 68 | $namespace = substr($class, 0, $pos); 69 | foreach ($this->namespaces as $ns => $dirs) { 70 | foreach ($dirs as $dir) { 71 | if (0 === strpos($namespace, $ns)) { 72 | $className = substr($class, $pos + 1); 73 | $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php'; 74 | if (file_exists($file)) { 75 | return $file; 76 | } 77 | } 78 | } 79 | } 80 | } 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /tests/dflydev/tests/core/io/FileSystemResourceLoaderTest.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class FileSystemResourceLoaderTest extends \PHPUnit_Framework_TestCase { 20 | static protected $tmpDir; 21 | static protected $files; 22 | public function testFile() { 23 | $resourceLoader = new FileSystemResourceLoader(self::$tmpDir); 24 | $resource = $resourceLoader->load("bar/test.properties"); 25 | $this->assertTrue($resource->exists(), '->exists() returns true for a resource representing something that exists on the filesystem'); 26 | $this->assertTrue($resource->isFile(), '->isFile() returns true for a resource representing an existing file'); 27 | $this->assertFalse($resource->isDirectory(), '->isDirectory() returns false for a resource representing an existing file'); 28 | } 29 | public function testDirectory() { 30 | $resourceLoader = new FileSystemResourceLoader(self::$tmpDir); 31 | $resource = $resourceLoader->load("bar"); 32 | $this->assertTrue($resource->exists(), '->exists() returns true for a resource representing something that exists on the filesystem'); 33 | $this->assertFalse($resource->isFile(), '->isFile() returns false for a resource representing an existing directory'); 34 | $this->assertTrue($resource->isDirectory(), '->isDirectory() returns true for a resource representing an existing directory'); 35 | } 36 | public function testMissing() { 37 | $resourceLoader = new FileSystemResourceLoader(self::$tmpDir); 38 | try { 39 | // This file is known to be missing in our test space. 40 | $resource = $resourceLoader->load("--MISSING--"); 41 | $this->fail(); 42 | } catch (\Exception $e) { 43 | $this->assertInstanceOf('dflydev\core\io\exception\ResourceNotFoundException', $e, '->load() throws dflydev\core\io\exception\ResourceNotFoundException when loading a resource that does not exist'); 44 | } 45 | } 46 | static public function setUpBeforeClass() { 47 | self::$tmpDir = $tmpDir = sys_get_temp_dir().'/dflydev_core_io_fsrl_tests_'.md5(time().rand()); 48 | self::$files = array( 49 | $tmpDir.'/foo/', 50 | $tmpDir.'/bar/', 51 | $tmpDir.'/bar/test.properties', 52 | $tmpDir.'/yar.txt', 53 | ); 54 | if ( is_dir($tmpDir) ) { 55 | self::removeAllFiles(); 56 | } else { 57 | mkdir($tmpDir); 58 | } 59 | foreach (self::$files as $file) { 60 | if ('/' === $file[strlen($file) - 1]) { 61 | mkdir($file); 62 | } else { 63 | touch($file); 64 | } 65 | } 66 | } 67 | static public function tearDownAfterClass() { 68 | self::removeAllFiles(); 69 | @rmdir(self::$tmpDir); 70 | } 71 | static protected function removeAllFiles() { 72 | foreach (array_reverse(self::$files) as $file) { 73 | if ('/' === $file[strlen($file) - 1]) { 74 | @rmdir($file); 75 | } else { 76 | @unlink($file); 77 | } 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /tests/dflydev/tests/core/io/CompositeResourceLoaderTest.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class CompositeResourceLoaderTest extends \PHPUnit_Framework_TestCase { 20 | public function testNoBackingResourceLoaders() { 21 | $resourceLoader = new CompositeResourceLoader(); 22 | try { 23 | // This can be anything and it should fail. 24 | $resource = $resourceLoader->load("--ANYTHING--"); 25 | $this->fail(); 26 | } catch (\Exception $e) { 27 | $this->assertInstanceOf('dflydev\core\io\exception\ResourceNotFoundException', $e, '->load() throws dflydev\core\io\exception\ResourceNotFoundException when loading a resource but no backing resource loaders are specified'); 28 | } 29 | } 30 | public function testLoadingMissingResource() { 31 | $location = 'foo.txt'; 32 | $firstResourceLoader = $this->getMock('dflydev\core\io\FileSystemResourceLoader', array('load'), array('anywhere')); 33 | $firstResourceLoader->expects($this->once()) 34 | ->method('load') 35 | ->with($this->equalTo($location)) 36 | ->will($this->throwException(new \dflydev\core\io\exception\ResourceNotFoundException($location))); 37 | $resourceLoader = new CompositeResourceLoader(array($firstResourceLoader)); 38 | try { 39 | $resourceLoader->load($location); 40 | $this->fail(); 41 | } catch (\Exception $e) { 42 | $this->assertInstanceOf('dflydev\core\io\exception\ResourceNotFoundException', $e, '->load() throws dflydev\core\io\exception\ResourceNotFoundException when loading a resource but no backing resource loaders are specified'); 43 | } 44 | } 45 | public function testLoadingExistingResource() { 46 | $location = 'foo.txt'; 47 | $firstResourceLoader = $this->getMock('dflydev\core\io\FileSystemResourceLoader', array('load'), array('anywhere')); 48 | $firstResourceLoader->expects($this->once()) 49 | ->method('load') 50 | ->with($this->equalTo($location)) 51 | ->will($this->throwException(new \dflydev\core\io\exception\ResourceNotFoundException($location))); 52 | $secondResourceLoader = $this->getMock('dflydev\core\io\FileSystemResourceLoader', array('load'), array('else')); 53 | $secondResourceLoader->expects($this->once()) 54 | ->method('load') 55 | ->with($this->equalTo($location)) 56 | ->will($this->returnValue(new \dflydev\core\io\FileSystemResource('else/'.$location))); 57 | $resourceLoader = new CompositeResourceLoader(array( 58 | $firstResourceLoader, 59 | $secondResourceLoader, 60 | )); 61 | 62 | $resource = $resourceLoader->load($location); 63 | $this->assertEquals('else/'.$location, $resource->filename()); 64 | } 65 | public function testAppendingResourceLoadersIndividually() { 66 | $location = 'foo.txt'; 67 | $firstResourceLoader = $this->getMock('dflydev\core\io\FileSystemResourceLoader', array('load'), array('anywhere')); 68 | $firstResourceLoader->expects($this->once()) 69 | ->method('load') 70 | ->with($this->equalTo($location)) 71 | ->will($this->throwException(new \dflydev\core\io\exception\ResourceNotFoundException($location))); 72 | $secondResourceLoader = $this->getMock('dflydev\core\io\FileSystemResourceLoader', array('load'), array('else')); 73 | $secondResourceLoader->expects($this->once()) 74 | ->method('load') 75 | ->with($this->equalTo($location)) 76 | ->will($this->returnValue(new \dflydev\core\io\FileSystemResource('else/'.$location))); 77 | $resourceLoader = new CompositeResourceLoader(); 78 | $resourceLoader->appendResourceLoader($firstResourceLoader); 79 | $resourceLoader->appendResourceLoader($secondResourceLoader); 80 | $resource = $resourceLoader->load($location); 81 | $this->assertEquals('else/'.$location, $resource->filename()); 82 | } 83 | public function testAppendingResourceLoadersTogether() { 84 | $location = 'foo.txt'; 85 | $firstResourceLoader = $this->getMock('dflydev\core\io\FileSystemResourceLoader', array('load'), array('anywhere')); 86 | $firstResourceLoader->expects($this->once()) 87 | ->method('load') 88 | ->with($this->equalTo($location)) 89 | ->will($this->throwException(new \dflydev\core\io\exception\ResourceNotFoundException($location))); 90 | $secondResourceLoader = $this->getMock('dflydev\core\io\FileSystemResourceLoader', array('load'), array('else')); 91 | $secondResourceLoader->expects($this->once()) 92 | ->method('load') 93 | ->with($this->equalTo($location)) 94 | ->will($this->returnValue(new \dflydev\core\io\FileSystemResource('else/'.$location))); 95 | $resourceLoader = new CompositeResourceLoader(); 96 | $resourceLoader->appendResourceLoaders(array( 97 | $firstResourceLoader, 98 | $secondResourceLoader, 99 | )); 100 | $resource = $resourceLoader->load($location); 101 | $this->assertEquals('else/'.$location, $resource->filename()); 102 | } 103 | } --------------------------------------------------------------------------------