PageRenderTime 40ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

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

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