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