1: <?php
  2: 
  3: /**
  4:  * Picon Framework
  5:  * http://code.google.com/p/picon-framework/
  6:  *
  7:  * Copyright (C) 2011-2012 Martin Cassidy <martin.cassidy@webquub.com>
  8: 
  9:  * Picon Framework is free software: you can redistribute it and/or modify
 10:  * it under the terms of the GNU General Public License as published by
 11:  * the Free Software Foundation, either version 3 of the License, or
 12:  * (at your option) any later version.
 13: 
 14:  * Picon Framework is distributed in the hope that it will be useful,
 15:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17:  *  General Public License for more details.
 18: 
 19:  * You should have received a copy of the GNU General Public License
 20:  * along with Picon Framework.  If not, see <http://www.gnu.org/licenses/>.
 21:  * */
 22: 
 23: namespace picon;
 24: 
 25: /**
 26:  * Scanner to find classes that match a given set of rules. 
 27:  * This expectes any classes that are to be scanned to have been declared
 28:  * 
 29:  * @author Martin Cassidy
 30:  * @package scanner
 31:  */
 32: class ClassScanner
 33: {
 34:     private $rules;
 35:     
 36:     /**
 37:      *
 38:      * @param mixed $rule Array of ClassScannerRule or a single ClassScannerRule
 39:      */
 40:     public function __construct($rules = array())
 41:     {
 42:         if(is_array($rules))
 43:         {
 44:             foreach($rules as $rule)
 45:             {
 46:                 if(!($rule instanceof ClassScannerRule))
 47:                 {
 48:                     throw new \InvalidArgumentException(sprintf("Expected an array of ClassScannerRule. %s is not a ClassScannerRulle", get_class($rule)));
 49:                 }
 50:             }
 51:             $this->rules = $rules;
 52:         }
 53:         else
 54:         {
 55:             if(!($rules instanceof ClassScannerRule))
 56:             {
 57:                 throw new \InvalidArgumentException(sprintf("Expected ClassScannerRule, actual %s", get_class($rules)));
 58:             }
 59:             $this->rules = array($rules);
 60:         }
 61:     }
 62:     
 63:     /**
 64:      * Add a new rule to the class scanner
 65:      * @param ClassScannerRule $rule The rule to add
 66:      */
 67:     public function addRule(ClassScannerRule $rule)
 68:     {
 69:         array_push($this->rules, $rule);
 70:     }
 71:     
 72:     /**
 73:      * Scan classes for those matching the rules that have been added
 74:      *
 75:      * @param Array $classesToScan A list of classes to scan, optional if not specified
 76:      * all declared classess will be scanned.
 77:      * @return Array An array of the class reflections which matched (ReflectionAnnotatedClass)
 78:      */
 79:     public function scanForReflection($classesToScan = null)
 80:     {
 81:         return array_values($this->scan($classesToScan));
 82:     }
 83: 
 84:     /**
 85:      * Scan classes for those matching the rules that have been added
 86:      *
 87:      * @param Array $classesToScan A list of classes to scan, optional if not specified
 88:      * all declared classess will be scanned.
 89:      * @return Array An array of the class names which matched
 90:      */
 91:     public function scanForName($classesToScan = null)
 92:     {
 93:         return array_keys($this->scan($classesToScan));
 94:     }
 95: 
 96:     private function scan($classesToScan = null)
 97:     {
 98:         $matchedClasses = array();
 99: 
100:         if($classesToScan==null)
101:         {
102:             $classesToScan = get_declared_classes();
103:         }
104: 
105:         foreach($classesToScan as $className)
106:         {
107:             $match = false;
108:             $reflection = new \ReflectionAnnotatedClass($className);
109:             foreach($this->rules as $rule)
110:             {
111:                 $match = $rule->matches($className, $reflection);
112: 
113:                 if($match)
114:                 {
115:                     $matchedClasses[$className] = $reflection;
116:                     break;
117:                 }
118:             }
119:         }
120: 
121:         return $matchedClasses;
122:     }
123: }
124: 
125: ?>
126: