service = $this->loadServiceDefinition($servicePath); $this->resourceRoot = $resourceRoot; // Append service definition base path if bare apiEndpoint domain is given. if (isset($this->service['basePath'])) { $uriParts = \parse_url($baseUri) + ['path' => null]; if (!$uriParts['path'] || $uriParts['path'] === '/') { $uriParts['path'] = $this->service['basePath']; // Recreate the URI from its modified parts and ensure it ends in a single slash. $this->baseUri = \rtrim((string) Uri::fromParts($uriParts), '/') . '/'; return; } } $this->baseUri = \rtrim($baseUri, '/') . '/'; } /** * Build the request. * * @param string $resource * @param string $method * @param array $options [optional] * @return RequestInterface * @todo complexity high, revisit * @todo consider validating against the schemas */ public function build($resource, $method, array $options = []) { $root = $this->resourceRoot; \array_push($root, 'resources'); $root = \array_merge($root, \explode('.', $resource)); \array_push($root, 'methods', $method); $action = $this->service; foreach ($root as $rootItem) { if (!isset($action[$rootItem])) { throw new \InvalidArgumentException('Provided path item ' . $rootItem . ' does not exist.'); } $action = $action[$rootItem]; } $path = []; $query = []; $body = []; if (isset($action['parameters'])) { foreach ($action['parameters'] as $parameter => $parameterOptions) { if ($parameterOptions['location'] === 'path' && \array_key_exists($parameter, $options)) { $path[$parameter] = $options[$parameter]; unset($options[$parameter]); } if ($parameterOptions['location'] === 'query' && \array_key_exists($parameter, $options)) { $query[$parameter] = $options[$parameter]; } } } if (isset($this->service['parameters'])) { foreach ($this->service['parameters'] as $parameter => $parameterOptions) { if ($parameterOptions['location'] === 'query' && \array_key_exists($parameter, $options)) { $query[$parameter] = $options[$parameter]; } } } if (isset($action['request'])) { $schema = $action['request']['$ref']; foreach ($this->service['schemas'][$schema]['properties'] as $property => $propertyOptions) { if (\array_key_exists($property, $options)) { $body[$property] = $options[$property]; } } } $uri = $this->buildUriWithQuery($this->expandUri($this->baseUri . $action['path'], $path), $query); return new Request($action['httpMethod'], $uri, ['Content-Type' => 'application/json'], $body ? $this->jsonEncode($body) : null); } /** * @param string $servicePath * @return array */ private function loadServiceDefinition($servicePath) { return $this->jsonDecode(\file_get_contents($servicePath, \true), \true); } }