1<?php 2/** 3 * This file is part of the static reflection component. 4 * 5 * PHP Version 5 6 * 7 * Copyright (c) 2009-2011, Manuel Pichler <mapi@pdepend.org>. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * * Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 17 * * Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in 19 * the documentation and/or other materials provided with the 20 * distribution. 21 * 22 * * Neither the name of Manuel Pichler nor the names of his 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 29 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 30 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 32 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 33 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 34 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 36 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 * 39 * @category PHP 40 * @package pdepend\reflection\queries 41 * @author Manuel Pichler <mapi@pdepend.org> 42 * @copyright 2009-2011 Manuel Pichler. All rights reserved. 43 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 44 * @version SVN: $Id$ 45 * @link http://pdepend.org/ 46 */ 47 48namespace pdepend\reflection\queries; 49 50/** 51 * This query class allows access to reflection class instances for all classes 52 * and interfaces declared in a given directory. 53 * 54 * <code> 55 * $query = $session->createDirectoryQuery(); 56 * $classes = $query->find( __DIR__ . '/source' ); 57 * 58 * foreach ( $classes as $class ) 59 * { 60 * echo 'Class: ', $class->getShortName(), PHP_EOL, 61 * 'File: ', $class->getFileName(), PHP_EOL, 62 * '-- ', PHP_EOL; 63 * } 64 * </code> 65 * 66 * @category PHP 67 * @package pdepend\reflection\queries 68 * @author Manuel Pichler <mapi@pdepend.org> 69 * @copyright 2009-2011 Manuel Pichler. All rights reserved. 70 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 71 * @version Release: @package_version@ 72 * @link http://pdepend.org/ 73 */ 74class ReflectionDirectoryQuery extends ReflectionQuery 75{ 76 /** 77 * The type of this class. 78 */ 79 const TYPE = __CLASS__; 80 81 /** 82 * Array with regular expressions used to exclude some files. 83 * 84 * @var array(string) 85 */ 86 private $_excludes = array( '([/\\\\]\.)' ); 87 88 /** 89 * This method will create reflection class instances for all interfaces 90 * and classes that can be found in the source code files within the given 91 * directory. 92 * 93 * @param string $directory The source directory that is the target of the 94 * class search. 95 * 96 * @return Iterator 97 */ 98 public function find( $directory ) 99 { 100 if ( file_exists( $directory ) === false || is_file( $directory ) ) 101 { 102 throw new \LogicException( 'Invalid or not existant directory ' . $directory ); 103 } 104 105 $classes = array(); 106 foreach ( $this->_createIterator( $directory ) as $fileInfo ) 107 { 108 if ( !$fileInfo->isFile() || $this->_isExcluded( $fileInfo, $directory ) ) 109 { 110 continue; 111 } 112 foreach ( $this->parseFile( $fileInfo->getRealpath() ) as $class ) 113 { 114 $classes[] = $class; 115 } 116 } 117 return new \ArrayIterator( $classes ); 118 } 119 120 /** 121 * Adds a regular expected that will be used to filter out those files that 122 * should no be parsed. 123 * 124 * @param string $regexp A regular expression used to filter the result. 125 * 126 * @return \pdepend\reflection\queries\ReflectionDirectoryQuery 127 */ 128 public function exclude( $regexp ) 129 { 130 $this->_excludes[] = $regexp; 131 return $this; 132 } 133 134 /** 135 * This method returns a iterator with all files that could be found within 136 * the given source directory. 137 * 138 * @param string $directory The source directory that is the target of the 139 * class search. 140 * 141 * @return Iterator 142 */ 143 private function _createIterator( $directory ) 144 { 145 return new \RecursiveIteratorIterator( 146 new \RecursiveDirectoryIterator( $directory ) 147 ); 148 } 149 150 /** 151 * Will return <b>true</b> when the given file object should not be 152 * accepted. 153 * 154 * @param \SplFileInfo $fileInfo The currently parsed file info object. 155 * @param string $directory The context directory. 156 * 157 * @return boolean 158 */ 159 private function _isExcluded( \SplFileInfo $fileInfo, $directory ) 160 { 161 $pathName = substr( $fileInfo->getRealPath(), strlen( realpath( $directory ) ) ); 162 foreach ( $this->_excludes as $regexp ) 163 { 164 if ( preg_match( $regexp, $pathName ) > 0 ) 165 { 166 return true; 167 } 168 } 169 return false; 170 } 171} 172