PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/Tool/Framework/Client/AbstractClient.php

http://github.com/zendframework/zf2
PHP | 317 lines | 154 code | 57 blank | 106 comment | 24 complexity | 5a95185e8dfbb0ca3d07d886520483b2 MD5 | raw file
Possible License(s): BSD-3-Clause
  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-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /**
  22. * @namespace
  23. */
  24. namespace Zend\Tool\Framework\Client;
  25. use Zend\Log,
  26. Zend\Tool\Framework\Registry,
  27. Zend\Tool\Framework\RegistryEnabled;
  28. /**
  29. * @category Zend
  30. * @package Zend_Tool
  31. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  32. * @license http://framework.zend.com/license/new-bsd New BSD License
  33. */
  34. abstract class AbstractClient implements RegistryEnabled
  35. {
  36. /**
  37. * @var \Zend\Tool\Framework\Registry
  38. */
  39. protected $_registry = null;
  40. /**
  41. * @var callback|null
  42. */
  43. protected $_interactiveCallback = null;
  44. /**
  45. * @var bool
  46. */
  47. protected $_isInitialized = false;
  48. /**
  49. * @var Log\Logger
  50. */
  51. protected $_debugLogger = null;
  52. public function __construct($options = array())
  53. {
  54. // require autoloader
  55. $loader = new \Zend\Loader\StandardAutoloader();
  56. $loader->register();
  57. // this might look goofy, but this is setting up the
  58. // registry for dependency injection into the client
  59. $registry = new \Zend\Tool\Framework\Registry\FrameworkRegistry();
  60. $registry->setClient($this);
  61. // NOTE: at this moment, $this->_registry should contain the registry object
  62. if ($options) {
  63. $this->setOptions($options);
  64. }
  65. }
  66. public function setOptions(Array $options)
  67. {
  68. foreach ($options as $optionName => $optionValue) {
  69. $setMethodName = 'set' . $optionName;
  70. if (method_exists($this, $setMethodName)) {
  71. $this->{$setMethodName}($optionValue);
  72. }
  73. }
  74. }
  75. /**
  76. * getName() - Return the client name which can be used to
  77. * query the manifest if need be.
  78. *
  79. * @return string The client name
  80. */
  81. abstract public function getName();
  82. /**
  83. * initialized() - This will initialize the client for use
  84. *
  85. */
  86. public function initialize()
  87. {
  88. // if its already initialized, no need to initialize again
  89. if ($this->_isInitialized) {
  90. return;
  91. }
  92. // run any preInit
  93. $this->_preInit();
  94. $manifest = $this->_registry->getManifestRepository();
  95. $manifest->addManifest(new Manifest());
  96. // setup the debug log
  97. if (!$this->_debugLogger instanceof Log\Logger) {
  98. $this->_debugLogger = new Log\Logger(new Log\Writer\Null());
  99. }
  100. // let the loader load, then the repositories process whats been loaded
  101. $this->_registry->getLoader()->load();
  102. // process the action repository
  103. $this->_registry->getActionRepository()->process();
  104. // process the provider repository
  105. $this->_registry->getProviderRepository()->process();
  106. // process the manifest repository
  107. $this->_registry->getManifestRepository()->process();
  108. if ($this instanceof Interactive\InteractiveOutput) {
  109. $this->_registry->getResponse()->setContentCallback(array($this, 'handleInteractiveOutput'));
  110. }
  111. }
  112. /**
  113. * This method should be implemented by the client implementation to
  114. * construct and set custom inflectors, request and response objects.
  115. */
  116. protected function _preInit()
  117. {
  118. }
  119. /**
  120. * This method *must* be implemented by the client implementation to
  121. * parse out and setup the request objects action, provider and parameter
  122. * information.
  123. */
  124. abstract protected function _preDispatch();
  125. /**
  126. * This method should be implemented by the client implementation to
  127. * take the output of the response object and return it (in an client
  128. * specific way) back to the Tooling Client.
  129. */
  130. protected function _postDispatch()
  131. {
  132. }
  133. /**
  134. * setRegistry() - Required by the Zend\Tool\Framework\RegistryEnabled
  135. * interface which ensures proper registry dependency resolution
  136. *
  137. * @param \Zend\Tool\Framework\Registry $registry
  138. * @return \Zend\Tool\Framework\Client\AbstractClient
  139. */
  140. public function setRegistry(Registry $registry)
  141. {
  142. $this->_registry = $registry;
  143. return $this;
  144. }
  145. /**
  146. * getRegistry();
  147. *
  148. * @return \Zend\Tool\Framework\Registry
  149. */
  150. public function getRegistry()
  151. {
  152. return $this->_registry;
  153. }
  154. /**
  155. * hasInteractiveInput() - Convienence method for determining if this
  156. * client can handle interactive input, and thus be able to run the
  157. * promptInteractiveInput
  158. *
  159. * @return bool
  160. */
  161. public function hasInteractiveInput()
  162. {
  163. return ($this instanceof Interactive\InteractiveInput);
  164. }
  165. public function promptInteractiveInput($inputRequest)
  166. {
  167. if (!$this->hasInteractiveInput()) {
  168. throw new Exception\RuntimeException('promptInteractive() cannot be called on a non-interactive client.');
  169. }
  170. $inputHandler = new Interactive\InputHandler();
  171. $inputHandler->setClient($this);
  172. $inputHandler->setInputRequest($inputRequest);
  173. return $inputHandler->handle();
  174. }
  175. /**
  176. * This method should be called in order to "handle" a Tooling Client
  177. * request that has come to the client that has been implemented.
  178. */
  179. public function dispatch()
  180. {
  181. $this->initialize();
  182. try {
  183. $this->_preDispatch();
  184. if ($this->_registry->getRequest()->isDispatchable()) {
  185. if ($this->_registry->getRequest()->getActionName() == null) {
  186. throw new Exception\RuntimeException('Client failed to setup the action name.');
  187. }
  188. if ($this->_registry->getRequest()->getProviderName() == null) {
  189. throw new Exception\RuntimeException('Client failed to setup the provider name.');
  190. }
  191. $this->_handleDispatch();
  192. }
  193. } catch (\Exception $exception) {
  194. $this->_registry->getResponse()->setException($exception);
  195. }
  196. $this->_postDispatch();
  197. }
  198. public function convertToClientNaming($string)
  199. {
  200. return $string;
  201. }
  202. public function convertFromClientNaming($string)
  203. {
  204. return $string;
  205. }
  206. protected function _handleDispatch()
  207. {
  208. // get the provider repository
  209. $providerRepository = $this->_registry->getProviderRepository();
  210. $request = $this->_registry->getRequest();
  211. // get the dispatchable provider signature
  212. $providerSignature = $providerRepository->getProviderSignature($request->getProviderName());
  213. // get the actual provider
  214. $provider = $providerSignature->getProvider();
  215. // ensure that we can pretend if this is a pretend request
  216. if ($request->isPretend() && (!$provider instanceof \Zend\Tool\Framework\Provider\Pretendable)) {
  217. throw new Exception\RuntimeException('Dispatcher error - provider does not support pretend');
  218. }
  219. // get the action name
  220. $actionName = $this->_registry->getRequest()->getActionName();
  221. $specialtyName = $this->_registry->getRequest()->getSpecialtyName();
  222. if (!$actionableMethod = $providerSignature->getActionableMethodByActionName($actionName, $specialtyName)) {
  223. throw new Exception\RuntimeException('Dispatcher error - actionable method not found');
  224. }
  225. // get the actual method and param information
  226. $methodName = $actionableMethod['methodName'];
  227. $methodParameters = $actionableMethod['parameterInfo'];
  228. // get the provider params
  229. $requestParameters = $this->_registry->getRequest()->getProviderParameters();
  230. // @todo This seems hackish, determine if there is a better way
  231. $callParameters = array();
  232. foreach ($methodParameters as $methodParameterName => $methodParameterValue) {
  233. if (!array_key_exists($methodParameterName, $requestParameters) && $methodParameterValue['optional'] == false) {
  234. if ($this instanceof Interactive\InteractiveInput) {
  235. $promptSting = $this->getMissingParameterPromptString($provider, $actionableMethod['action'], $methodParameterValue['name']);
  236. $parameterPromptValue = $this->promptInteractiveInput($promptSting)->getContent();
  237. if ($parameterPromptValue == null) {
  238. throw new Exception\RuntimeException('Value supplied for required parameter "' . $methodParameterValue['name'] . '" is empty');
  239. }
  240. $callParameters[] = $parameterPromptValue;
  241. } else {
  242. throw new Exception\RuntimeException('A required parameter "' . $methodParameterValue['name'] . '" was not supplied.');
  243. }
  244. } else {
  245. $callParameters[] = (array_key_exists($methodParameterName, $requestParameters)) ? $requestParameters[$methodParameterName] : $methodParameterValue['default'];
  246. }
  247. }
  248. $this->_handleDispatchExecution($provider, $methodName, $callParameters);
  249. }
  250. protected function _handleDispatchExecution($class, $methodName, $callParameters)
  251. {
  252. if (method_exists($class, $methodName)) {
  253. call_user_func_array(array($class, $methodName), $callParameters);
  254. } elseif (method_exists($class, $methodName . 'Action')) {
  255. call_user_func_array(array($class, $methodName . 'Action'), $callParameters);
  256. } else {
  257. throw new Exception\RuntimeException('Not a supported method.');
  258. }
  259. }
  260. }