1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette;
13:
14: use Nette;
15:
16:
17:
18: 19: 20: 21: 22:
23: class Context extends FreezableObject implements IContext
24: {
25:
26: private $registry = array();
27:
28:
29: private $factories = array();
30:
31:
32:
33: 34: 35: 36: 37: 38: 39: 40:
41: public function addService($name, $service, $singleton = TRUE, array $options = NULL)
42: {
43: $this->updating();
44: if (!is_string($name) || $name === '') {
45: throw new \InvalidArgumentException("Service name must be a non-empty string, " . gettype($name) . " given.");
46: }
47:
48: $lower = strtolower($name);
49: if (isset($this->registry[$lower])) { 50: throw new AmbiguousServiceException("Service named '$name' has already been registered.");
51: }
52:
53: if (is_object($service) && !($service instanceof \Closure || $service instanceof Callback)) {
54: if (!$singleton || $options) {
55: throw new \InvalidArgumentException("Service named '$name' is an instantiated object and must therefore be singleton without options.");
56: }
57: $this->registry[$lower] = $service;
58:
59: } else {
60: if (!$service) {
61: throw new \InvalidArgumentException("Service named '$name' is empty.");
62: }
63: $this->factories[$lower] = array($service, $singleton, $options);
64: }
65: }
66:
67:
68:
69: 70: 71: 72:
73: public function removeService($name)
74: {
75: $this->updating();
76: if (!is_string($name) || $name === '') {
77: throw new \InvalidArgumentException("Service name must be a non-empty string, " . gettype($name) . " given.");
78: }
79:
80: $lower = strtolower($name);
81: unset($this->registry[$lower], $this->factories[$lower]);
82: }
83:
84:
85:
86: 87: 88: 89: 90: 91:
92: public function getService($name, array $options = NULL)
93: {
94: if (!is_string($name) || $name === '') {
95: throw new \InvalidArgumentException("Service name must be a non-empty string, " . gettype($name) . " given.");
96: }
97:
98: $lower = strtolower($name);
99:
100: if (isset($this->registry[$lower])) { 101: if ($options) {
102: throw new \InvalidArgumentException("Service named '$name' is singleton and therefore can not have options.");
103: }
104: return $this->registry[$lower];
105:
106: } elseif (isset($this->factories[$lower])) {
107: list($factory, $singleton, $defOptions) = $this->factories[$lower];
108:
109: if ($singleton && $options) {
110: throw new \InvalidArgumentException("Service named '$name' is singleton and therefore can not have options.");
111:
112: } elseif ($defOptions) {
113: $options = $options ? $options + $defOptions : $defOptions;
114: }
115:
116: if (is_string($factory) && strpos($factory, ':') === FALSE) { 117: if (!class_exists($factory)) {
118: throw new AmbiguousServiceException("Cannot instantiate service '$name', class '$factory' not found.");
119: }
120: $service = new $factory;
121: if ($options && method_exists($service, 'setOptions')) {
122: $service->setOptions($options); 123: }
124:
125: } else { 126: $factory = callback($factory);
127: if (!$factory->isCallable()) {
128: throw new \InvalidStateException("Cannot instantiate service '$name', handler '$factory' is not callable.");
129: }
130: $service = $factory($options);
131: if (!is_object($service)) {
132: throw new AmbiguousServiceException("Cannot instantiate service '$name', value returned by '$factory' is not object.");
133: }
134: }
135:
136: if ($singleton) {
137: $this->registry[$lower] = $service;
138: unset($this->factories[$lower]);
139: }
140: return $service;
141:
142: } else {
143: throw new \InvalidStateException("Service '$name' not found.");
144: }
145: }
146:
147:
148:
149: 150: 151: 152: 153: 154:
155: public function hasService($name, $created = FALSE)
156: {
157: if (!is_string($name) || $name === '') {
158: throw new \InvalidArgumentException("Service name must be a non-empty string, " . gettype($name) . " given.");
159: }
160:
161: $lower = strtolower($name);
162: return isset($this->registry[$lower]) || (!$created && isset($this->factories[$lower]));
163: }
164:
165: }
166:
167:
168:
169: 170: 171: 172: 173:
174: class AmbiguousServiceException extends \Exception
175: {
176: }
177: