Call multiple external functions and return all responses.

@param array $requests List of requests.
@return array Responses.
@since Moodle 3.7
1165
public static function call_external_functions($requests) {
        global $SESSION;

        $params = self::validate_parameters(self::call_external_functions_parameters(), ['requests' => $requests]);

        // We need to check if the functions being called are included in the service of the current token.
        // This function only works when using mobile services via REST (this is intended).
        $webservicemanager = new \webservice;
        $token = $webservicemanager->get_user_ws_token(required_param('wstoken', PARAM_ALPHANUM));

        $settings = \external_settings::get_instance();
        $defaultlang = current_language();
        $responses = [];

        foreach ($params['requests'] as $request) {
            // Some external functions modify _GET or $_POST data, we need to restore the original data after each call.
            $originalget = fullclone($_GET);
            $originalpost = fullclone($_POST);

            // Set external settings and language.
            $settings->set_raw($request['settingraw']);
            $settings->set_filter($request['settingfilter']);
            $settings->set_fileurl($request['settingfileurl']);
            $settings->set_lang($request['settinglang']);
            $SESSION->lang = $request['settinglang'] ?: $defaultlang;

            // Parse arguments to an array, validation is done in external_api::call_external_function.
            $args = @json_decode($request['arguments'], true);
            if (!is_array($args)) {
                $args = [];
            }

            if ($webservicemanager->service_function_exists($request['function'], $token->externalserviceid)) {
                $response = external_api::call_external_function($request['function'], $args, false);
            } else {
                // Function not included in the service, return an access exception.
                $response = [
                    'error' => true,
                    'exception' => [
                        'errorcode' => 'accessexception',
                        'module' => 'webservice'
                    ]
                ];
                if (debugging('', DEBUG_DEVELOPER)) {
                    $response['exception']['debuginfo'] = 'Access to the function is not allowed.';
                }
            }

            if (isset($response['data'])) {
                $response['data'] = json_encode($response['data']);
            }
            if (isset($response['exception'])) {
                $response['exception'] = json_encode($response['exception']);
            }
            $responses[] = $response;

            // Restore original $_GET and $_POST.
            $_GET = $originalget;
            $_POST = $originalpost;

            if ($response['error']) {
                // Do not process the remaining requests.
                break;
            }
        }

        return ['responses' => $responses];
    }
253260
public function getResponses(): array
    {
        $responses = [];

        foreach ($this->responses as $request) {
            $responses[] = $this->responses[$request];
        }

        return $responses;
    }
973700
public function getHttpResponse(array $headers = [])
    {
        $client = new Client();
        $urls = $this->getUrl();

        return $client->request('GET', $urls[0], ['stream' => true, 'headers' => $headers]);
    }
1123829
public function resultAction(Request $request)
    {
        try {
            $this
                ->gestpayManager
                ->processResult($request->query->all());
        } catch (PaymentException $e) {
            $this
                ->logger
                ->log(
                    'error',
                    'Gestpay error "'.$e->getMessage(),
                    GestpayMethod::METHOD_NAME
                );
        }

        return new Response('OK');
    }
388237
public function send_batch_requests($requests){
		$client = new \GuzzleHttp\Client();

		$response = $client->post($this->api_endpoint.'batch', array(
		    'headers' =>  array('Authorization' => 'Token token="'.$this->getAPIKey().'"'),
		    'json' => array( "ops" => $requests, "sequential" => true )
		));

		$result = json_decode($response->getBody());

		return $result;
	}
1354421
protected function processRequest(array $parameters = [])
    {
        if ($this->nextToken) {
            $parameters['starting_after'] = $this->nextToken;
        }

        if (isset($parameters[0])) {
            $id = $parameters[0];

            unset($parameters[0]);

            if (isset($parameters[1])) {
                $parameters = $parameters[1];

                unset($parameters[1]);
            }

            $parameters = [ $id, $parameters ];
        } else {
            $parameters = [ $parameters ];
        }

        $result = call_user_func_array([ $this->api, 'all' ], $parameters);

        $this->nextToken = $result['has_more'] ? end($result['data'])['id'] : false;

        return $result['data'];
    }
403480
protected function call($request)
    {
        if(!isset($request['query']))
        {
            $request['query'] = [];
        }

        $method  = 'GET';
        $headers = $this->getHeaders();
        $query   = http_build_query($request['query']);
        $url     = "{$this->domain}/{$request['route']}?$query";

        try {
            $request = $this->getClient()->request($method, $url, [
                'headers' => $headers
            ]);

            $response = $request->getBody()->getContents();

            return json_decode($response, true);

        } catch (RequestException $e) {
            $response = $e->getResponse();
            $response = json_decode($response, true);
            return $response;
        } catch (\Exception $e) {
            return ['error' => $e->getCode(), 'error_description' => $e->getMessage()];
        }
    }
918145
public function execute(Request $request): Response
    {
        $method = $request->getMethod();
        list($resp, $grpcStatus) = $request->getClient()->$method(
            $request->getMessage(),
            $request->getMetadata(),
            $request->getOptions()
        )->wait();

        $headers = new HeaderCollection();

        if (is_null($grpcStatus)) { // in the very bad case even this fails to return
            $status = new Error\Status(\Grpc\STATUS_UNKNOWN, '', $headers);
        } else {
            $metadata = $grpcStatus->metadata;
            foreach ($metadata as $k => $v) {
                if (is_array($v)) {
                    foreach ($v as $v2) {
                        $headers->add($k, $v2);
                    }
                } else {
                    $headers->add($k, $v);
                }
            }
            $status = new Error\Status(intval($grpcStatus->code), strval($grpcStatus->details), $headers);
        }

        if (is_null($resp)) {
            $request->fail($status);
        }

        return $request->succeed($resp, $status);
    }
936759
public function makeAllRequests(array $requests = [])
    {
        if (empty($requests)) {
            $requests = $this->savedRequests;
        }
        list($channels, $multiHandle) = $this->createCurlMultiHandle($requests);

        // running all requests
        $isRunning = null;
        do {
            curl_multi_exec($multiHandle, $isRunning);
        } while ($isRunning);

        // get response and close all handles
        $retryRequests = [];
        $responses = [];
        $sleepDurations = 0;
        foreach ($channels as $id => $channel) {

            $content = curl_multi_getcontent($channel);
            $response = $this->parseResponse($channel, $content);

            if ($response->statusCode() === self::TOO_MANY_REQUESTS_HTTP_CODE && $requests[$id]['retryOnLimit']) {
                $headers = $response->headers(true);
                $sleepDurations = max($sleepDurations, $headers['X-Ratelimit-Reset'] - time());
                $requestData = [
                    'method' => $requests[$id]['method'],
                    'url' => $requests[$id]['url'],
                    'body' => $requests[$id]['body'],
                    'headers' => $headers,
                ];
                $retryRequests[] = $this->createSavedRequest($requestData, false);
            } else {
                $responses[] = $response;
            }

            curl_multi_remove_handle($multiHandle, $channel);
        }
        curl_multi_close($multiHandle);

        // retry requests
        if (!empty($retryRequests)) {
            sleep($sleepDurations > 0 ? $sleepDurations : 0);
            $responses = array_merge($responses, $this->makeAllRequests($retryRequests));
        }
        return $responses;
    }
698636
public function response(array $errors)
    {
        return $this->ajaxRequest
            ? $this->formatJsonErrorsResponse($errors)
            : parent::response($errors);
    }
66680
public function postRequestAsync( Request $request ) {
		$promise = $this->getClient()->requestAsync(
			'POST',
			$this->apiUrl,
			$this->getClientRequestOptions( $request, $this->getPostRequestEncoding( $request ) )
		);

		return $promise->then( function ( ResponseInterface $response ) {
			return call_user_func( [ $this, 'decodeResponse' ], $response );
		} );
	}
891752
protected function httpTransport($request)
    {

        try {
            $response = $this->client->send($request);
            $results = json_decode($response->getBody());
            return $results;
        } catch (RequestException $e) {
            Log::error(Psr7\str($e->getRequest()));
            if ($e->hasResponse()) {
                Log::error(Psr7\str($e->getResponse()));
            }
        }
    }
1071551
public static function call_external_functions_returns() {
        return new external_function_parameters([
            'responses' => new external_multiple_structure(
                new external_single_structure([
                    'error' => new external_value(PARAM_BOOL, 'Whether an exception was thrown.'),
                    'data' => new external_value(PARAM_RAW, 'JSON-encoded response data', VALUE_OPTIONAL),
                    'exception' => new external_value(PARAM_RAW, 'JSON-encoed exception info', VALUE_OPTIONAL),
                ])
             )
        ]);
    }
584971
protected function handleSources(array $sources)
    {
        $responses = array();

        foreach ($sources as $source) {
            list($adapter, $request) = $source;
            $responses[] = $this->handleSource($adapter, $request);
        }

        $iterator = new \AppendIterator();

        /** @var Response $response */
        foreach ($responses as $response) {
            $iterator->append($response->getIterator());
        }

        return $iterator;
    }
1255869
public static function listAllCancelOperationsAsync(array $parameters = [])
    {
        return self::listAllCancelOperationsAsyncWithHttpInfo($page, $size, $sort)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
973903
public function getAll(array $queryParams = [])
    {
        $response = $this->api->oauth2()->clients()->getAll($queryParams);

        return new ClientsResponse($response);
    }
774227
public function all(array $params = array())
    {
        $endpoint = '/admin/pages.json';
        $response = $this->request($endpoint, 'GET', $params);
        return $this->createCollection(Page::class, $response['pages']);
    }