1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19:
20: class PresenterFactory implements IPresenterFactory
21: {
22:
23: public $caseSensitive = FALSE;
24:
25:
26: private $baseDir;
27:
28:
29: private $cache = array();
30:
31:
32: private $context;
33:
34:
35:
36: 37: 38:
39: public function __construct($baseDir, IContext $context)
40: {
41: $this->baseDir = $baseDir;
42: $this->context = $context;
43: }
44:
45:
46:
47: 48: 49: 50: 51:
52: public function createPresenter($name)
53: {
54: $class = $this->getPresenterClass($name);
55: $presenter = new $class;
56: $presenter->setContext($this->context);
57: return $presenter;
58: }
59:
60:
61:
62: 63: 64: 65: 66:
67: public function getPresenterClass(& $name)
68: {
69: if (isset($this->cache[$name])) {
70: list($class, $name) = $this->cache[$name];
71: return $class;
72: }
73:
74: if (!is_string($name) || !String::match($name, "#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*$#")) {
75: throw new InvalidPresenterException("Presenter name must be alphanumeric string, '$name' is invalid.");
76: }
77:
78: $class = $this->formatPresenterClass($name);
79:
80: if (!class_exists($class)) {
81: 82: $file = $this->formatPresenterFile($name);
83: if (is_file($file) && is_readable($file)) {
84: LimitedScope::load($file);
85: }
86:
87: if (!class_exists($class)) {
88: throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found in '$file'.");
89: }
90: }
91:
92: $reflection = new ClassReflection($class);
93: $class = $reflection->getName();
94:
95: if (!$reflection->implementsInterface('IPresenter')) {
96: throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is not IPresenter implementor.");
97: }
98:
99: if ($reflection->isAbstract()) {
100: throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is abstract.");
101: }
102:
103: 104: $realName = $this->unformatPresenterClass($class);
105: if ($name !== $realName) {
106: if ($this->caseSensitive) {
107: throw new InvalidPresenterException("Cannot load presenter '$name', case mismatch. Real name is '$realName'.");
108: } else {
109: $this->cache[$name] = array($class, $realName);
110: $name = $realName;
111: }
112: } else {
113: $this->cache[$name] = array($class, $realName);
114: }
115:
116: return $class;
117: }
118:
119:
120:
121: 122: 123: 124: 125:
126: public function formatPresenterClass($presenter)
127: {
128: return strtr($presenter, ':', '_') . 'Presenter';
129: return str_replace(':', 'Module\\', $presenter) . 'Presenter';
130: }
131:
132:
133:
134: 135: 136: 137: 138:
139: public function unformatPresenterClass($class)
140: {
141: return strtr(substr($class, 0, -9), '_', ':');
142: return str_replace('Module\\', ':', substr($class, 0, -9));
143: }
144:
145:
146:
147: 148: 149: 150: 151:
152: public function formatPresenterFile($presenter)
153: {
154: $path = '/' . str_replace(':', 'Module/', $presenter);
155: return $this->baseDir . substr_replace($path, '/presenters', strrpos($path, '/'), 0) . 'Presenter.php';
156: }
157:
158: }
159: