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