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