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
321360
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
        );
    }
946565
public function createRequest($method = 'GET', $uri = null, $headers = null, $body = null, array $options = array())
    {
        $uri = '{+base_path}/' . ltrim($uri, '/');
        if ('GET' == $method && $this->usePostMethod($uri, $options)) {
            $method = 'POST';
            $body = $options['query'];
            unset($options['query']);
        }
        return parent::createRequest($method, $uri, $headers, $body, $options);
    }
13135
public function createRequest($method, $uri, array $headers = [], array $options = [])
    {
        $body = JsonRpc\json_encode($this->addIdToRequest($method, $options));

        return new Request('POST', $uri, $headers, $body === false ? null : $body);
    }
1163037
protected function createRequest($method)
    {
        $request = new Request();
        $uri = new Uri($this->getResourceUri());
        $uri = $uri->withUserInfo($this->apiKey);

        $request = $request->withMethod($method)
            ->withUri($uri);

        if (in_array($method, array(ClientInterface::METHOD_POST, ClientInterface::METHOD_PUT))) {
            $request = $request->withBody($this->createStringFromArray($this->params));
        }

        return $request;
    }
781881
public function request($requestParams, $url, $method, $requiredParams, $options)
    {
        $client = $this->getHttpClient();
        $url = $this->buildEndpoint($url);

        return $client->httpRequest($requestParams, $url, $method, $requiredParams, $options);
    }
1370859
public static function create($resource = '', array $options = []): StreamInterface
    {
        switch (gettype($resource)) {
            case 'string':
                $stream = fopen('php://temp', 'r+');
                if ($resource !== '') {
                    fwrite($stream, $resource);
                    fseek($stream, 0);
                }
                return new Stream($stream, $options);
            case 'resource':
                return new Stream($resource, $options);
            case 'object':
                if ($resource instanceof StreamInterface) {
                    return $resource;
                } elseif ($resource instanceof \Traversable) {
                    return new IteratorStream($resource, $options);
                } elseif (method_exists($resource, '__toString')) {
                    return static::createStream((string)$resource, $options);
                }
                break;
            case 'NULL':
                return new Stream('php://temp', 'r+');
        }

        throw new InvalidStreamException(
            'Invalid resource type: ' . gettype($resource)
        );
    }
351563
public function createOne($method, array $tokens, array $options, DataSource $annotation = null) {
        return new Request([
            'method'              => HttpMethod::create($method, $annotation),
            'url'                 => Url::createFromTokens($tokens, $options['host'], $annotation),
            'curlOptions'         => CurlOptions::create(array_merge($options['driverOptions'], HttpHeader::create($options['driverOptions'], $tokens))),
            'query'               => HttpQuery::create($tokens, $options['driverOptions']),
            'payload'             => Payload::create($tokens, $options),
            'expectedStatusCodes' => StatusCode::create($method, $annotation)
        ]);
    }
975053
function makeRequest(string $method, string $endpoint, array $options) {
        $request = new \CharlotteDunois\Yasmin\HTTP\APIRequest($this, $method, $endpoint, $options);
        return $this->add($request);
    }
248411
protected function prepare($method, $resource, $body, $params)
    {
        // Append the username parameter to the end of every resource URI.
        $resource = trim($resource, '/').'/'.$this->username;

        foreach ($params as $param) {
            $resource .= '/'.$param;
        }

        return new Request($method, $resource, [], $body);
    }
531991
public function request($method, $url, $token, array $options = [])
    {
        $request = $this->getAuthenticatedRequest(
            $method, $url, $token, $options
        );

        return $this->getResponse($request);
    }
1128559
public function send(string $method, string $url, array $options)
    {
        try {
            // Guzzle overwrites all query string values in the URI if queries are specified
            // in the 'query' option, so they need to be extracted first.
            $optionsPayload = $this->mergeOptions(
                ['query' => $this->parseQueryParams($url)],
                $options
            );

            $response = $this->buildClient()->request($method, $url, $optionsPayload);

            return $this->buildResponse($response);
        } catch (GuzzleException $exception) {
            // No "custom" exceptions, just rethrow whatever guzzle spits out.
            throw $exception;
        }
    }
346183
public function requestRaw(string $url, string $method = 'GET', array $options = [])
    {
        return Response::buildFromPsrResponse($this->request($url, $method, $options, true));
    }
1179912
protected function request($uri, $method = 'get', $options = array())
    {
        $this->clear();

        if (! in_array(strtolower($method), $this->methods)) {
            return $this->setError('Unknown request method: ' . $method);
        }

        $isAuthorized = $this->accessToken || $this->token ||
                        ($this->username && $this->password);

        if (! $isAuthorized) {
            return $this->setError('Please provide token or username and password');
        }

        // if uri is passed as array, create uri string from uri parts
        if (is_array($uri)) {
            $uri = implode('/', $uri);
        }

        // api request url
        $url = $this->endpoint . $uri;

        $handle = curl_init();

        if ($this->accessToken) {
            // Access token is used in OAuth2 flow
            $url .= '?access_token=' . $this->accessToken;
        } else if ($this->token) {
            // Auth token is taken from PG account
            $url .= '?auth_token=' . $this->token;
        } else {
            // if using username and password - pass them as curl option
            curl_setopt($handle, CURLOPT_USERPWD, $this->username . ':' . $this->password);
        }

        curl_setopt($handle, CURLOPT_URL, $url);
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($handle, CURLOPT_CUSTOMREQUEST, strtoupper($method));
        curl_setopt($handle, CURLOPT_HTTPHEADER, array(
            'Content-type: multipart/form-data;',
        ));

        // if request has additional options - add them to request
        if (! empty($options)) {

            // extract files, pass them separately
            $files = array();
            foreach ($options as $key => $value) {
                if (! empty($value) && ! is_array($value) && $value[0] === '@') {
                    $files[$key] = $this->toCurlFile($value);
                    unset($options[$key]);
                }
            }

            $data = $files;

            if (! empty($options)) {
                // original API requires data to be in json format
                $data = array_merge($data, array(
                    'data' => json_encode($options),
                ));
            }

            curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
        }

        $response = curl_exec($handle);

        if (curl_errno($handle)) {
            $this->setError(curl_error($handle));
            curl_close($handle);
            return false;
        }

        // get httd code to identify if request was successful
        $httpcode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
        $this->success = in_array($httpcode, $this->codes);

        curl_close($handle);

        $decoded = json_decode($response, true);

        // request may be successful, but also can have errors, for example, about keys
        if (isset($decoded['error']) && $error = $decoded['error']) {
            if (is_array($error)) {
                $error = $this->assocToString($error);
            }
            $this->setError($error);
        }

        if (! $this->success) {
            return false;
        }

        return $decoded;
    }
277892
public function requestAsync($method, $uri = null, array $options = [])
    {
        $options = $this->setRequestOptions($options);

        $query = parse_url($uri, PHP_URL_QUERY);
        if (!empty($query)) {
            $uri = substr($uri, 0, (strlen($query)+1) * -1);
            parse_str($query, $options['query']);
        }

        return parent::requestAsync($method, $uri, $options);
    }
966607
protected function getResourceName($resource, $method, $options)
    {
        if (isset($options['names'][$method])) {
            return $options['names'][$method];
        }

        // If a global prefix has been assigned to all names for this resource, we will
        // grab that so we can prepend it onto the name when we create this name for
        // the resource action. Otherwise we'll just use an empty string for here.
        $prefix = isset($options['as']) ? $options['as'] .'.' : '';

        if (! $this->router->hasGroupStack()) {
            return $prefix .$resource .'.' .$method;
        }

        return $this->getGroupResourceName($prefix, $resource, $method);
    }
1357776
public function requestAsync($method, $url, $options)
    {
        $request = $this->authClient->getAuthenticatedRequest($method, $url, $this->getAccessToken());

        return $this->httpClient->sendAsync($request, $options);
    }
991241
private function do_request( $resource, $method, $input ) {
		$called_url = $this->base_url . '/' . $resource;
		$ch = curl_init( $called_url );
		$auth_header = 'api-key:' . $this->api_key;
		$content_header = 'Content-Type:application/json';
		if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
			// Windows only over-ride
			curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
		}
		curl_setopt( $ch, CURLOPT_HTTPHEADER, array($auth_header, $content_header) );
		curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
		curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $method );
		curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
		curl_setopt( $ch, CURLOPT_HEADER, 0 );
		curl_setopt( $ch, CURLOPT_POSTFIELDS, $input );
		$data = curl_exec( $ch );
		if ( curl_errno( $ch ) ) {
			echo 'Curl error: ' . curl_error( $ch ) . '\n';
		}
		curl_close( $ch );
		return json_decode( $data, true );
	}