1<?php 2 3/* 4 * This file is part of the Assetic package, an OpenSky project. 5 * 6 * (c) 2010-2014 OpenSky Project Inc 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Assetic\Factory\Resource; 13 14/** 15 * A resource is something formulae can be loaded from. 16 * 17 * @author Kris Wallsmith <kris.wallsmith@gmail.com> 18 */ 19class DirectoryResource implements IteratorResourceInterface 20{ 21 private $path; 22 private $pattern; 23 24 /** 25 * Constructor. 26 * 27 * @param string $path A directory path 28 * @param string $pattern A filename pattern 29 */ 30 public function __construct($path, $pattern = null) 31 { 32 if (DIRECTORY_SEPARATOR != substr($path, -1)) { 33 $path .= DIRECTORY_SEPARATOR; 34 } 35 36 $this->path = $path; 37 $this->pattern = $pattern; 38 } 39 40 public function isFresh($timestamp) 41 { 42 if (!is_dir($this->path) || filemtime($this->path) > $timestamp) { 43 return false; 44 } 45 46 foreach ($this as $resource) { 47 if (!$resource->isFresh($timestamp)) { 48 return false; 49 } 50 } 51 52 return true; 53 } 54 55 /** 56 * Returns the combined content of all inner resources. 57 */ 58 public function getContent() 59 { 60 $content = array(); 61 foreach ($this as $resource) { 62 $content[] = $resource->getContent(); 63 } 64 65 return implode("\n", $content); 66 } 67 68 public function __toString() 69 { 70 return $this->path; 71 } 72 73 public function getIterator() 74 { 75 return is_dir($this->path) 76 ? new DirectoryResourceIterator($this->getInnerIterator()) 77 : new \EmptyIterator(); 78 } 79 80 protected function getInnerIterator() 81 { 82 return new DirectoryResourceFilterIterator(new \RecursiveDirectoryIterator($this->path, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS), $this->pattern); 83 } 84} 85 86/** 87 * An iterator that converts file objects into file resources. 88 * 89 * @author Kris Wallsmith <kris.wallsmith@gmail.com> 90 * @access private 91 */ 92class DirectoryResourceIterator extends \RecursiveIteratorIterator 93{ 94 public function current() 95 { 96 return new FileResource(parent::current()->getPathname()); 97 } 98} 99 100/** 101 * Filters files by a basename pattern. 102 * 103 * @author Kris Wallsmith <kris.wallsmith@gmail.com> 104 * @access private 105 */ 106class DirectoryResourceFilterIterator extends \RecursiveFilterIterator 107{ 108 protected $pattern; 109 110 public function __construct(\RecursiveDirectoryIterator $iterator, $pattern = null) 111 { 112 parent::__construct($iterator); 113 114 $this->pattern = $pattern; 115 } 116 117 public function accept() 118 { 119 $file = $this->current(); 120 $name = $file->getBasename(); 121 122 if ($file->isDir()) { 123 return '.' != $name[0]; 124 } 125 126 return null === $this->pattern || 0 < preg_match($this->pattern, $name); 127 } 128 129 public function getChildren() 130 { 131 return new self(new \RecursiveDirectoryIterator($this->current()->getPathname(), \RecursiveDirectoryIterator::FOLLOW_SYMLINKS), $this->pattern); 132 } 133} 134