PageRenderTime 58ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/concrete/vendor/zendframework/zend-json/src/Server/Smd/Service.php

https://gitlab.com/koodersmiikka/operaatio-terveys
PHP | 453 lines | 380 code | 13 blank | 60 comment | 7 complexity | 53e56808f3ff94c9a21dc8ad882eb498 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-2014 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Json\Server\Smd;
  10. use Zend\Json\Server;
  11. use Zend\Json\Server\Exception\InvalidArgumentException;
  12. use Zend\Json\Server\Smd;
  13. /**
  14. * Create Service Mapping Description for a method
  15. *
  16. * @todo Revised method regex to allow NS; however, should SMD be revised to strip PHP NS instead when attaching functions?
  17. */
  18. class Service
  19. {
  20. /**#@+
  21. * Service metadata
  22. * @var string
  23. */
  24. protected $envelope = Smd::ENV_JSONRPC_1;
  25. protected $name;
  26. protected $return;
  27. protected $target;
  28. protected $transport = 'POST';
  29. /**#@-*/
  30. /**
  31. * Allowed envelope types
  32. * @var array
  33. */
  34. protected $envelopeTypes = array(
  35. Smd::ENV_JSONRPC_1,
  36. Smd::ENV_JSONRPC_2,
  37. );
  38. /**
  39. * Regex for names
  40. * @var string
  41. */
  42. protected $nameRegex = '/^[a-z][a-z0-9.\\\\_]+$/i';
  43. /**
  44. * Parameter option types
  45. * @var array
  46. */
  47. protected $paramOptionTypes = array(
  48. 'name' => 'is_string',
  49. 'optional' => 'is_bool',
  50. 'default' => null,
  51. 'description' => 'is_string',
  52. );
  53. /**
  54. * Service params
  55. * @var array
  56. */
  57. protected $params = array();
  58. /**
  59. * Mapping of parameter types to JSON-RPC types
  60. * @var array
  61. */
  62. protected $paramMap = array(
  63. 'any' => 'any',
  64. 'arr' => 'array',
  65. 'array' => 'array',
  66. 'assoc' => 'object',
  67. 'bool' => 'boolean',
  68. 'boolean' => 'boolean',
  69. 'dbl' => 'float',
  70. 'double' => 'float',
  71. 'false' => 'boolean',
  72. 'float' => 'float',
  73. 'hash' => 'object',
  74. 'integer' => 'integer',
  75. 'int' => 'integer',
  76. 'mixed' => 'any',
  77. 'nil' => 'null',
  78. 'null' => 'null',
  79. 'object' => 'object',
  80. 'string' => 'string',
  81. 'str' => 'string',
  82. 'struct' => 'object',
  83. 'true' => 'boolean',
  84. 'void' => 'null',
  85. );
  86. /**
  87. * Allowed transport types
  88. * @var array
  89. */
  90. protected $transportTypes = array(
  91. 'POST',
  92. );
  93. /**
  94. * Constructor
  95. *
  96. * @param string|array $spec
  97. * @throws InvalidArgumentException if no name provided
  98. */
  99. public function __construct($spec)
  100. {
  101. if (is_string($spec)) {
  102. $this->setName($spec);
  103. } elseif (is_array($spec)) {
  104. $this->setOptions($spec);
  105. }
  106. if (null == $this->getName()) {
  107. throw new InvalidArgumentException('SMD service description requires a name; none provided');
  108. }
  109. }
  110. /**
  111. * Set object state
  112. *
  113. * @param array $options
  114. * @return Service
  115. */
  116. public function setOptions(array $options)
  117. {
  118. $methods = get_class_methods($this);
  119. foreach ($options as $key => $value) {
  120. if ('options' == strtolower($key)) {
  121. continue;
  122. }
  123. $method = 'set' . ucfirst($key);
  124. if (in_array($method, $methods)) {
  125. $this->$method($value);
  126. }
  127. }
  128. return $this;
  129. }
  130. /**
  131. * Set service name
  132. *
  133. * @param string $name
  134. * @return Service
  135. * @throws InvalidArgumentException
  136. */
  137. public function setName($name)
  138. {
  139. $name = (string) $name;
  140. if (!preg_match($this->nameRegex, $name)) {
  141. throw new InvalidArgumentException("Invalid name '{$name} provided for service; must follow PHP method naming conventions");
  142. }
  143. $this->name = $name;
  144. return $this;
  145. }
  146. /**
  147. * Retrieve name
  148. *
  149. * @return string
  150. */
  151. public function getName()
  152. {
  153. return $this->name;
  154. }
  155. /**
  156. * Set Transport
  157. *
  158. * Currently limited to POST
  159. *
  160. * @param string $transport
  161. * @throws InvalidArgumentException
  162. * @return Service
  163. */
  164. public function setTransport($transport)
  165. {
  166. if (!in_array($transport, $this->transportTypes)) {
  167. throw new InvalidArgumentException("Invalid transport '{$transport}'; please select one of (" . implode(', ', $this->transportTypes) . ')');
  168. }
  169. $this->transport = $transport;
  170. return $this;
  171. }
  172. /**
  173. * Get transport
  174. *
  175. * @return string
  176. */
  177. public function getTransport()
  178. {
  179. return $this->transport;
  180. }
  181. /**
  182. * Set service target
  183. *
  184. * @param string $target
  185. * @return Service
  186. */
  187. public function setTarget($target)
  188. {
  189. $this->target = (string) $target;
  190. return $this;
  191. }
  192. /**
  193. * Get service target
  194. *
  195. * @return string
  196. */
  197. public function getTarget()
  198. {
  199. return $this->target;
  200. }
  201. /**
  202. * Set envelope type
  203. *
  204. * @param string $envelopeType
  205. * @throws InvalidArgumentException
  206. * @return Service
  207. */
  208. public function setEnvelope($envelopeType)
  209. {
  210. if (!in_array($envelopeType, $this->envelopeTypes)) {
  211. throw new InvalidArgumentException("Invalid envelope type '{$envelopeType}'; please specify one of (" . implode(', ', $this->envelopeTypes) . ')');
  212. }
  213. $this->envelope = $envelopeType;
  214. return $this;
  215. }
  216. /**
  217. * Get envelope type
  218. *
  219. * @return string
  220. */
  221. public function getEnvelope()
  222. {
  223. return $this->envelope;
  224. }
  225. /**
  226. * Add a parameter to the service
  227. *
  228. * @param string|array $type
  229. * @param array $options
  230. * @param int|null $order
  231. * @throws InvalidArgumentException
  232. * @return Service
  233. */
  234. public function addParam($type, array $options = array(), $order = null)
  235. {
  236. if (is_string($type)) {
  237. $type = $this->_validateParamType($type);
  238. } elseif (is_array($type)) {
  239. foreach ($type as $key => $paramType) {
  240. $type[$key] = $this->_validateParamType($paramType);
  241. }
  242. } else {
  243. throw new InvalidArgumentException('Invalid param type provided');
  244. }
  245. $paramOptions = array(
  246. 'type' => $type,
  247. );
  248. foreach ($options as $key => $value) {
  249. if (in_array($key, array_keys($this->paramOptionTypes))) {
  250. if (null !== ($callback = $this->paramOptionTypes[$key])) {
  251. if (!$callback($value)) {
  252. continue;
  253. }
  254. }
  255. $paramOptions[$key] = $value;
  256. }
  257. }
  258. $this->params[] = array(
  259. 'param' => $paramOptions,
  260. 'order' => $order,
  261. );
  262. return $this;
  263. }
  264. /**
  265. * Add params
  266. *
  267. * Each param should be an array, and should include the key 'type'.
  268. *
  269. * @param array $params
  270. * @return Service
  271. */
  272. public function addParams(array $params)
  273. {
  274. ksort($params);
  275. foreach ($params as $options) {
  276. if (!is_array($options)) {
  277. continue;
  278. }
  279. if (!array_key_exists('type', $options)) {
  280. continue;
  281. }
  282. $type = $options['type'];
  283. $order = (array_key_exists('order', $options)) ? $options['order'] : null;
  284. $this->addParam($type, $options, $order);
  285. }
  286. return $this;
  287. }
  288. /**
  289. * Overwrite all parameters
  290. *
  291. * @param array $params
  292. * @return Service
  293. */
  294. public function setParams(array $params)
  295. {
  296. $this->params = array();
  297. return $this->addParams($params);
  298. }
  299. /**
  300. * Get all parameters
  301. *
  302. * Returns all params in specified order.
  303. *
  304. * @return array
  305. */
  306. public function getParams()
  307. {
  308. $params = array();
  309. $index = 0;
  310. foreach ($this->params as $param) {
  311. if (null === $param['order']) {
  312. if (array_search($index, array_keys($params), true)) {
  313. ++$index;
  314. }
  315. $params[$index] = $param['param'];
  316. ++$index;
  317. } else {
  318. $params[$param['order']] = $param['param'];
  319. }
  320. }
  321. ksort($params);
  322. return $params;
  323. }
  324. /**
  325. * Set return type
  326. *
  327. * @param string|array $type
  328. * @throws InvalidArgumentException
  329. * @return Service
  330. */
  331. public function setReturn($type)
  332. {
  333. if (is_string($type)) {
  334. $type = $this->_validateParamType($type, true);
  335. } elseif (is_array($type)) {
  336. foreach ($type as $key => $returnType) {
  337. $type[$key] = $this->_validateParamType($returnType, true);
  338. }
  339. } else {
  340. throw new InvalidArgumentException("Invalid param type provided ('" . gettype($type) . "')");
  341. }
  342. $this->return = $type;
  343. return $this;
  344. }
  345. /**
  346. * Get return type
  347. *
  348. * @return string|array
  349. */
  350. public function getReturn()
  351. {
  352. return $this->return;
  353. }
  354. /**
  355. * Cast service description to array
  356. *
  357. * @return array
  358. */
  359. public function toArray()
  360. {
  361. $envelope = $this->getEnvelope();
  362. $target = $this->getTarget();
  363. $transport = $this->getTransport();
  364. $parameters = $this->getParams();
  365. $returns = $this->getReturn();
  366. $name = $this->getName();
  367. if (empty($target)) {
  368. return compact('envelope', 'transport', 'name', 'parameters', 'returns');
  369. }
  370. return compact('envelope', 'target', 'transport', 'name', 'parameters', 'returns');
  371. }
  372. /**
  373. * Return JSON encoding of service
  374. *
  375. * @return string
  376. */
  377. public function toJson()
  378. {
  379. $service = array($this->getName() => $this->toArray());
  380. return \Zend\Json\Json::encode($service);
  381. }
  382. /**
  383. * Cast to string
  384. *
  385. * @return string
  386. */
  387. public function __toString()
  388. {
  389. return $this->toJson();
  390. }
  391. /**
  392. * Validate parameter type
  393. *
  394. * @param string $type
  395. * @param bool $isReturn
  396. * @return string
  397. * @throws InvalidArgumentException
  398. */
  399. protected function _validateParamType($type, $isReturn = false)
  400. {
  401. if (!is_string($type)) {
  402. throw new InvalidArgumentException("Invalid param type provided ('{$type}')");
  403. }
  404. if (!array_key_exists($type, $this->paramMap)) {
  405. $type = 'object';
  406. }
  407. $paramType = $this->paramMap[$type];
  408. if (!$isReturn && ('null' == $paramType)) {
  409. throw new InvalidArgumentException("Invalid param type provided ('{$type}')");
  410. }
  411. return $paramType;
  412. }
  413. }