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