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: