/libraries/Zend/Json/Server/Smd.php

https://github.com/kiranatama/sagalaya · PHP · 461 lines · 218 code · 47 blank · 196 comment · 15 complexity · 69ca43fd385d69e185c948411e06ed0f MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Json
  9. */
  10. namespace Zend\Json\Server;
  11. use Zend\Json\Server\Exception\InvalidArgumentException;
  12. use Zend\Json\Server\Exception\RuntimeException;
  13. /**
  14. * @category Zend
  15. * @package Zend_Json
  16. * @subpackage Server
  17. */
  18. class Smd
  19. {
  20. const ENV_JSONRPC_1 = 'JSON-RPC-1.0';
  21. const ENV_JSONRPC_2 = 'JSON-RPC-2.0';
  22. const SMD_VERSION = '2.0';
  23. /**
  24. * Content type
  25. * @var string
  26. */
  27. protected $_contentType = 'application/json';
  28. /**
  29. * Content type regex
  30. * @var string
  31. */
  32. protected $_contentTypeRegex = '#[a-z]+/[a-z][a-z-]+#i';
  33. /**
  34. * Service description
  35. * @var string
  36. */
  37. protected $_description;
  38. /**
  39. * Generate Dojo-compatible SMD
  40. * @var bool
  41. */
  42. protected $_dojoCompatible = false;
  43. /**
  44. * Current envelope
  45. * @var string
  46. */
  47. protected $_envelope = self::ENV_JSONRPC_1;
  48. /**
  49. * Allowed envelope types
  50. * @var array
  51. */
  52. protected $_envelopeTypes = array(
  53. self::ENV_JSONRPC_1,
  54. self::ENV_JSONRPC_2,
  55. );
  56. /**
  57. * Service id
  58. * @var string
  59. */
  60. protected $_id;
  61. /**
  62. * Services offerred
  63. * @var array
  64. */
  65. protected $_services = array();
  66. /**
  67. * Service target
  68. * @var string
  69. */
  70. protected $_target;
  71. /**
  72. * Global transport
  73. * @var string
  74. */
  75. protected $_transport = 'POST';
  76. /**
  77. * Allowed transport types
  78. * @var array
  79. */
  80. protected $_transportTypes = array('POST');
  81. /**
  82. * Set object state via options
  83. *
  84. * @param array $options
  85. * @return Zend\Json\Server\Smd
  86. */
  87. public function setOptions(array $options)
  88. {
  89. foreach ($options as $key => $value) {
  90. $method = 'set' . ucfirst($key);
  91. if (method_exists($this, $method)) {
  92. $this->$method($value);
  93. }
  94. }
  95. return $this;
  96. }
  97. /**
  98. * Set transport
  99. *
  100. * @param string $transport
  101. * @return Zend\Json\Server\Smd
  102. */
  103. public function setTransport($transport)
  104. {
  105. if (!in_array($transport, $this->_transportTypes)) {
  106. throw new InvalidArgumentException("Invalid transport '{$transport}' specified");
  107. }
  108. $this->_transport = $transport;
  109. return $this;
  110. }
  111. /**
  112. * Get transport
  113. *
  114. * @return string
  115. */
  116. public function getTransport()
  117. {
  118. return $this->_transport;
  119. }
  120. /**
  121. * Set envelope
  122. *
  123. * @param string $envelopeType
  124. * @return Zend\Json\Server\Smd
  125. */
  126. public function setEnvelope($envelopeType)
  127. {
  128. if (!in_array($envelopeType, $this->_envelopeTypes)) {
  129. throw new InvalidArgumentException("Invalid envelope type '{$envelopeType}'");
  130. }
  131. $this->_envelope = $envelopeType;
  132. return $this;
  133. }
  134. /**
  135. * Retrieve envelope
  136. *
  137. * @return string
  138. */
  139. public function getEnvelope()
  140. {
  141. return $this->_envelope;
  142. }
  143. // Content-Type of response; default to application/json
  144. /**
  145. * Set content type
  146. *
  147. * @param string $type
  148. * @return Zend\Json\Server\Smd
  149. */
  150. public function setContentType($type)
  151. {
  152. if (!preg_match($this->_contentTypeRegex, $type)) {
  153. throw new InvalidArgumentException("Invalid content type '{$type}' specified");
  154. }
  155. $this->_contentType = $type;
  156. return $this;
  157. }
  158. /**
  159. * Retrieve content type
  160. *
  161. * @return string
  162. */
  163. public function getContentType()
  164. {
  165. return $this->_contentType;
  166. }
  167. /**
  168. * Set service target
  169. *
  170. * @param string $target
  171. * @return Zend\Json\Server\Smd
  172. */
  173. public function setTarget($target)
  174. {
  175. $this->_target = (string) $target;
  176. return $this;
  177. }
  178. /**
  179. * Retrieve service target
  180. *
  181. * @return string
  182. */
  183. public function getTarget()
  184. {
  185. return $this->_target;
  186. }
  187. /**
  188. * Set service ID
  189. *
  190. * @param string $Id
  191. * @return Zend\Json\Server\Smd
  192. */
  193. public function setId($id)
  194. {
  195. $this->_id = (string) $id;
  196. return $this->_id;
  197. }
  198. /**
  199. * Get service id
  200. *
  201. * @return string
  202. */
  203. public function getId()
  204. {
  205. return $this->_id;
  206. }
  207. /**
  208. * Set service description
  209. *
  210. * @param string $description
  211. * @return Zend\Json\Server\Smd
  212. */
  213. public function setDescription($description)
  214. {
  215. $this->_description = (string) $description;
  216. return $this->_description;
  217. }
  218. /**
  219. * Get service description
  220. *
  221. * @return string
  222. */
  223. public function getDescription()
  224. {
  225. return $this->_description;
  226. }
  227. /**
  228. * Indicate whether or not to generate Dojo-compatible SMD
  229. *
  230. * @param bool $flag
  231. * @return Zend\Json\Server\Smd
  232. */
  233. public function setDojoCompatible($flag)
  234. {
  235. $this->_dojoCompatible = (bool) $flag;
  236. return $this;
  237. }
  238. /**
  239. * Is this a Dojo compatible SMD?
  240. *
  241. * @return bool
  242. */
  243. public function isDojoCompatible()
  244. {
  245. return $this->_dojoCompatible;
  246. }
  247. /**
  248. * Add Service
  249. *
  250. * @param Zend\Json\Server\Smd\Service|array $service
  251. * @return void
  252. */
  253. public function addService($service)
  254. {
  255. if ($service instanceof Smd\Service) {
  256. $name = $service->getName();
  257. } elseif (is_array($service)) {
  258. $service = new Smd\Service($service);
  259. $name = $service->getName();
  260. } else {
  261. throw new InvalidArgumentException('Invalid service passed to addService()');
  262. }
  263. if (array_key_exists($name, $this->_services)) {
  264. throw new RuntimeException('Attempt to register a service already registered detected');
  265. }
  266. $this->_services[$name] = $service;
  267. return $this;
  268. }
  269. /**
  270. * Add many services
  271. *
  272. * @param array $services
  273. * @return Zend\Json\Server\Smd
  274. */
  275. public function addServices(array $services)
  276. {
  277. foreach ($services as $service) {
  278. $this->addService($service);
  279. }
  280. return $this;
  281. }
  282. /**
  283. * Overwrite existing services with new ones
  284. *
  285. * @param array $services
  286. * @return Zend\Json\Server\Smd
  287. */
  288. public function setServices(array $services)
  289. {
  290. $this->_services = array();
  291. return $this->addServices($services);
  292. }
  293. /**
  294. * Get service object
  295. *
  296. * @param string $name
  297. * @return false|Zend\Json\Server\Smd\Service
  298. */
  299. public function getService($name)
  300. {
  301. if (array_key_exists($name, $this->_services)) {
  302. return $this->_services[$name];
  303. }
  304. return false;
  305. }
  306. /**
  307. * Return services
  308. *
  309. * @return array
  310. */
  311. public function getServices()
  312. {
  313. return $this->_services;
  314. }
  315. /**
  316. * Remove service
  317. *
  318. * @param string $name
  319. * @return boolean
  320. */
  321. public function removeService($name)
  322. {
  323. if (array_key_exists($name, $this->_services)) {
  324. unset($this->_services[$name]);
  325. return true;
  326. }
  327. return false;
  328. }
  329. /**
  330. * Cast to array
  331. *
  332. * @return array
  333. */
  334. public function toArray()
  335. {
  336. if ($this->isDojoCompatible()) {
  337. return $this->toDojoArray();
  338. }
  339. $transport = $this->getTransport();
  340. $envelope = $this->getEnvelope();
  341. $contentType = $this->getContentType();
  342. $SMDVersion = self::SMD_VERSION;
  343. $service = compact('transport', 'envelope', 'contentType', 'SMDVersion');
  344. if (null !== ($target = $this->getTarget())) {
  345. $service['target'] = $target;
  346. }
  347. if (null !== ($id = $this->getId())) {
  348. $service['id'] = $id;
  349. }
  350. $services = $this->getServices();
  351. if (!empty($services)) {
  352. $service['services'] = array();
  353. foreach ($services as $name => $svc) {
  354. $svc->setEnvelope($envelope);
  355. $service['services'][$name] = $svc->toArray();
  356. }
  357. $service['methods'] = $service['services'];
  358. }
  359. return $service;
  360. }
  361. /**
  362. * Export to DOJO-compatible SMD array
  363. *
  364. * @return array
  365. */
  366. public function toDojoArray()
  367. {
  368. $SMDVersion = '.1';
  369. $serviceType = 'JSON-RPC';
  370. $service = compact('SMDVersion', 'serviceType');
  371. $target = $this->getTarget();
  372. $services = $this->getServices();
  373. if (!empty($services)) {
  374. $service['methods'] = array();
  375. foreach ($services as $name => $svc) {
  376. $method = array(
  377. 'name' => $name,
  378. 'serviceURL' => $target,
  379. );
  380. $params = array();
  381. foreach ($svc->getParams() as $param) {
  382. $paramName = array_key_exists('name', $param) ? $param['name'] : $param['type'];
  383. $params[] = array(
  384. 'name' => $paramName,
  385. 'type' => $param['type'],
  386. );
  387. }
  388. if (!empty($params)) {
  389. $method['parameters'] = $params;
  390. }
  391. $service['methods'][] = $method;
  392. }
  393. }
  394. return $service;
  395. }
  396. /**
  397. * Cast to JSON
  398. *
  399. * @return string
  400. */
  401. public function toJson()
  402. {
  403. return \Zend\Json\Json::encode($this->toArray());
  404. }
  405. /**
  406. * Cast to string (JSON)
  407. *
  408. * @return string
  409. */
  410. public function __toString()
  411. {
  412. return $this->toJson();
  413. }
  414. }