|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Tool |
|
17 * @subpackage Framework |
|
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 * @version $Id: Abstract.php 23204 2010-10-21 15:35:21Z ralph $ |
|
21 */ |
|
22 |
|
23 /** |
|
24 * @see Zend_Loader_Autoloader |
|
25 */ |
|
26 require_once 'Zend/Loader/Autoloader.php'; |
|
27 |
|
28 /** |
|
29 * @see Zend_Tool_Framework_Registry_EnabledInterface |
|
30 */ |
|
31 require_once 'Zend/Tool/Framework/Registry/EnabledInterface.php'; |
|
32 |
|
33 /** |
|
34 * @category Zend |
|
35 * @package Zend_Tool |
|
36 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
37 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
38 */ |
|
39 abstract class Zend_Tool_Framework_Client_Abstract implements Zend_Tool_Framework_Registry_EnabledInterface |
|
40 { |
|
41 |
|
42 /** |
|
43 * @var Zend_Tool_Framework_Registry |
|
44 */ |
|
45 protected $_registry = null; |
|
46 |
|
47 /** |
|
48 * @var callback|null |
|
49 */ |
|
50 protected $_interactiveCallback = null; |
|
51 |
|
52 /** |
|
53 * @var bool |
|
54 */ |
|
55 protected $_isInitialized = false; |
|
56 |
|
57 /** |
|
58 * @var Zend_Log |
|
59 */ |
|
60 protected $_debugLogger = null; |
|
61 |
|
62 public function __construct($options = array()) |
|
63 { |
|
64 // require autoloader |
|
65 Zend_Loader_Autoloader::getInstance(); |
|
66 |
|
67 // this might look goofy, but this is setting up the |
|
68 // registry for dependency injection into the client |
|
69 $registry = new Zend_Tool_Framework_Registry(); |
|
70 $registry->setClient($this); |
|
71 |
|
72 // NOTE: at this moment, $this->_registry should contain the registry object |
|
73 |
|
74 if ($options) { |
|
75 $this->setOptions($options); |
|
76 } |
|
77 } |
|
78 |
|
79 public function setOptions(Array $options) |
|
80 { |
|
81 foreach ($options as $optionName => $optionValue) { |
|
82 $setMethodName = 'set' . $optionName; |
|
83 if (method_exists($this, $setMethodName)) { |
|
84 $this->{$setMethodName}($optionValue); |
|
85 } |
|
86 } |
|
87 } |
|
88 |
|
89 /** |
|
90 * getName() - Return the client name which can be used to |
|
91 * query the manifest if need be. |
|
92 * |
|
93 * @return string The client name |
|
94 */ |
|
95 abstract public function getName(); |
|
96 |
|
97 /** |
|
98 * initialized() - This will initialize the client for use |
|
99 * |
|
100 */ |
|
101 public function initialize() |
|
102 { |
|
103 // if its already initialized, no need to initialize again |
|
104 if ($this->_isInitialized) { |
|
105 return; |
|
106 } |
|
107 |
|
108 // run any preInit |
|
109 $this->_preInit(); |
|
110 |
|
111 $manifest = $this->_registry->getManifestRepository(); |
|
112 $manifest->addManifest(new Zend_Tool_Framework_Client_Manifest()); |
|
113 |
|
114 // setup the debug log |
|
115 if (!$this->_debugLogger instanceof Zend_Log) { |
|
116 require_once 'Zend/Log.php'; |
|
117 require_once 'Zend/Log/Writer/Null.php'; |
|
118 $this->_debugLogger = new Zend_Log(new Zend_Log_Writer_Null()); |
|
119 } |
|
120 |
|
121 // let the loader load, then the repositories process whats been loaded |
|
122 $this->_registry->getLoader()->load(); |
|
123 |
|
124 // process the action repository |
|
125 $this->_registry->getActionRepository()->process(); |
|
126 |
|
127 // process the provider repository |
|
128 $this->_registry->getProviderRepository()->process(); |
|
129 |
|
130 // process the manifest repository |
|
131 $this->_registry->getManifestRepository()->process(); |
|
132 |
|
133 if ($this instanceof Zend_Tool_Framework_Client_Interactive_InputInterface) { |
|
134 require_once 'Zend/Tool/Framework/Client/Interactive/InputHandler.php'; |
|
135 } |
|
136 |
|
137 if ($this instanceof Zend_Tool_Framework_Client_Interactive_OutputInterface) { |
|
138 $this->_registry->getResponse()->setContentCallback(array($this, 'handleInteractiveOutput')); |
|
139 } |
|
140 |
|
141 } |
|
142 |
|
143 |
|
144 /** |
|
145 * This method should be implemented by the client implementation to |
|
146 * construct and set custom inflectors, request and response objects. |
|
147 */ |
|
148 protected function _preInit() |
|
149 { |
|
150 } |
|
151 |
|
152 /** |
|
153 * This method *must* be implemented by the client implementation to |
|
154 * parse out and setup the request objects action, provider and parameter |
|
155 * information. |
|
156 */ |
|
157 abstract protected function _preDispatch(); |
|
158 |
|
159 /** |
|
160 * This method should be implemented by the client implementation to |
|
161 * take the output of the response object and return it (in an client |
|
162 * specific way) back to the Tooling Client. |
|
163 */ |
|
164 protected function _postDispatch() |
|
165 { |
|
166 } |
|
167 |
|
168 /** |
|
169 * setRegistry() - Required by the Zend_Tool_Framework_Registry_EnabledInterface |
|
170 * interface which ensures proper registry dependency resolution |
|
171 * |
|
172 * @param Zend_Tool_Framework_Registry_Interface $registry |
|
173 * @return Zend_Tool_Framework_Client_Abstract |
|
174 */ |
|
175 public function setRegistry(Zend_Tool_Framework_Registry_Interface $registry) |
|
176 { |
|
177 $this->_registry = $registry; |
|
178 return $this; |
|
179 } |
|
180 |
|
181 /** |
|
182 * getRegistry(); |
|
183 * |
|
184 * @return Zend_Tool_Framework_Registry_Interface |
|
185 */ |
|
186 public function getRegistry() |
|
187 { |
|
188 return $this->_registry; |
|
189 } |
|
190 |
|
191 /** |
|
192 * hasInteractiveInput() - Convienence method for determining if this |
|
193 * client can handle interactive input, and thus be able to run the |
|
194 * promptInteractiveInput |
|
195 * |
|
196 * @return bool |
|
197 */ |
|
198 public function hasInteractiveInput() |
|
199 { |
|
200 return ($this instanceof Zend_Tool_Framework_Client_Interactive_InputInterface); |
|
201 } |
|
202 |
|
203 public function promptInteractiveInput($inputRequest) |
|
204 { |
|
205 if (!$this->hasInteractiveInput()) { |
|
206 require_once 'Zend/Tool/Framework/Client/Exception.php'; |
|
207 throw new Zend_Tool_Framework_Client_Exception('promptInteractive() cannot be called on a non-interactive client.'); |
|
208 } |
|
209 |
|
210 $inputHandler = new Zend_Tool_Framework_Client_Interactive_InputHandler(); |
|
211 $inputHandler->setClient($this); |
|
212 $inputHandler->setInputRequest($inputRequest); |
|
213 return $inputHandler->handle(); |
|
214 |
|
215 } |
|
216 |
|
217 /** |
|
218 * This method should be called in order to "handle" a Tooling Client |
|
219 * request that has come to the client that has been implemented. |
|
220 */ |
|
221 public function dispatch() |
|
222 { |
|
223 $this->initialize(); |
|
224 |
|
225 try { |
|
226 |
|
227 $this->_preDispatch(); |
|
228 |
|
229 if ($this->_registry->getRequest()->isDispatchable()) { |
|
230 |
|
231 if ($this->_registry->getRequest()->getActionName() == null) { |
|
232 require_once 'Zend/Tool/Framework/Client/Exception.php'; |
|
233 throw new Zend_Tool_Framework_Client_Exception('Client failed to setup the action name.'); |
|
234 } |
|
235 |
|
236 if ($this->_registry->getRequest()->getProviderName() == null) { |
|
237 require_once 'Zend/Tool/Framework/Client/Exception.php'; |
|
238 throw new Zend_Tool_Framework_Client_Exception('Client failed to setup the provider name.'); |
|
239 } |
|
240 |
|
241 $this->_handleDispatch(); |
|
242 |
|
243 } |
|
244 |
|
245 } catch (Exception $exception) { |
|
246 $this->_registry->getResponse()->setException($exception); |
|
247 } |
|
248 |
|
249 $this->_postDispatch(); |
|
250 } |
|
251 |
|
252 public function convertToClientNaming($string) |
|
253 { |
|
254 return $string; |
|
255 } |
|
256 |
|
257 public function convertFromClientNaming($string) |
|
258 { |
|
259 return $string; |
|
260 } |
|
261 |
|
262 protected function _handleDispatch() |
|
263 { |
|
264 // get the provider repository |
|
265 $providerRepository = $this->_registry->getProviderRepository(); |
|
266 |
|
267 $request = $this->_registry->getRequest(); |
|
268 |
|
269 // get the dispatchable provider signature |
|
270 $providerSignature = $providerRepository->getProviderSignature($request->getProviderName()); |
|
271 |
|
272 // get the actual provider |
|
273 $provider = $providerSignature->getProvider(); |
|
274 |
|
275 // ensure that we can pretend if this is a pretend request |
|
276 if ($request->isPretend() && (!$provider instanceof Zend_Tool_Framework_Provider_Pretendable)) { |
|
277 require_once 'Zend/Tool/Framework/Client/Exception.php'; |
|
278 throw new Zend_Tool_Framework_Client_Exception('Dispatcher error - provider does not support pretend'); |
|
279 } |
|
280 |
|
281 // get the action name |
|
282 $actionName = $this->_registry->getRequest()->getActionName(); |
|
283 $specialtyName = $this->_registry->getRequest()->getSpecialtyName(); |
|
284 |
|
285 if (!$actionableMethod = $providerSignature->getActionableMethodByActionName($actionName, $specialtyName)) { |
|
286 require_once 'Zend/Tool/Framework/Client/Exception.php'; |
|
287 throw new Zend_Tool_Framework_Client_Exception('Dispatcher error - actionable method not found'); |
|
288 } |
|
289 |
|
290 // get the actual method and param information |
|
291 $methodName = $actionableMethod['methodName']; |
|
292 $methodParameters = $actionableMethod['parameterInfo']; |
|
293 |
|
294 // get the provider params |
|
295 $requestParameters = $this->_registry->getRequest()->getProviderParameters(); |
|
296 |
|
297 // @todo This seems hackish, determine if there is a better way |
|
298 $callParameters = array(); |
|
299 foreach ($methodParameters as $methodParameterName => $methodParameterValue) { |
|
300 if (!array_key_exists($methodParameterName, $requestParameters) && $methodParameterValue['optional'] == false) { |
|
301 if ($this instanceof Zend_Tool_Framework_Client_Interactive_InputInterface) { |
|
302 $promptSting = $this->getMissingParameterPromptString($provider, $actionableMethod['action'], $methodParameterValue['name']); |
|
303 $parameterPromptValue = $this->promptInteractiveInput($promptSting)->getContent(); |
|
304 if ($parameterPromptValue == null) { |
|
305 require_once 'Zend/Tool/Framework/Client/Exception.php'; |
|
306 throw new Zend_Tool_Framework_Client_Exception('Value supplied for required parameter "' . $methodParameterValue['name'] . '" is empty'); |
|
307 } |
|
308 $callParameters[] = $parameterPromptValue; |
|
309 } else { |
|
310 require_once 'Zend/Tool/Framework/Client/Exception.php'; |
|
311 throw new Zend_Tool_Framework_Client_Exception('A required parameter "' . $methodParameterValue['name'] . '" was not supplied.'); |
|
312 } |
|
313 } else { |
|
314 $callParameters[] = (array_key_exists($methodParameterName, $requestParameters)) ? $requestParameters[$methodParameterName] : $methodParameterValue['default']; |
|
315 } |
|
316 } |
|
317 |
|
318 $this->_handleDispatchExecution($provider, $methodName, $callParameters); |
|
319 } |
|
320 |
|
321 protected function _handleDispatchExecution($class, $methodName, $callParameters) |
|
322 { |
|
323 if (method_exists($class, $methodName)) { |
|
324 call_user_func_array(array($class, $methodName), $callParameters); |
|
325 } elseif (method_exists($class, $methodName . 'Action')) { |
|
326 call_user_func_array(array($class, $methodName . 'Action'), $callParameters); |
|
327 } else { |
|
328 require_once 'Zend/Tool/Framework/Client/Exception.php'; |
|
329 throw new Zend_Tool_Framework_Client_Exception('Not a supported method.'); |
|
330 } |
|
331 } |
|
332 |
|
333 } |