summaryrefslogtreecommitdiff
path: root/inc/mailgun/php-http/curl-client/src/CurlPromise.php
blob: 68a775ce1ed7a73542fa2a2129895c246958a848 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
namespace Http\Client\Curl;

use Http\Promise\Promise;

/**
 * Promise represents a response that may not be available yet, but will be resolved at some point
 * in future. It acts like a proxy to the actual response.
 *
 * This interface is an extension of the promises/a+ specification https://promisesaplus.com/
 * Value is replaced by an object where its class implement a Psr\Http\Message\RequestInterface.
 * Reason is replaced by an object where its class implement a Http\Client\Exception.
 *
 * @license http://opensource.org/licenses/MIT MIT
 *
 * @author  Михаил Красильников <m.krasilnikov@yandex.ru>
 */
class CurlPromise implements Promise
{
    /**
     * Shared promise core
     *
     * @var PromiseCore
     */
    private $core;

    /**
     * Requests runner
     *
     * @var MultiRunner
     */
    private $runner;

    /**
     * Create new promise.
     *
     * @param PromiseCore $core   Shared promise core
     * @param MultiRunner $runner Simultaneous requests runner
     */
    public function __construct(PromiseCore $core, MultiRunner $runner)
    {
        $this->core = $core;
        $this->runner = $runner;
    }

    /**
     * Add behavior for when the promise is resolved or rejected.
     *
     * If you do not care about one of the cases, you can set the corresponding callable to null
     * The callback will be called when the response or exception arrived and never more than once.
     *
     * @param callable $onFulfilled Called when a response will be available.
     * @param callable $onRejected  Called when an error happens.
     *
     * You must always return the Response in the interface or throw an Exception.
     *
     * @return Promise Always returns a new promise which is resolved with value of the executed
     *                 callback (onFulfilled / onRejected).
     */
    public function then(callable $onFulfilled = null, callable $onRejected = null)
    {
        if ($onFulfilled) {
            $this->core->addOnFulfilled($onFulfilled);
        }
        if ($onRejected) {
            $this->core->addOnRejected($onRejected);
        }

        return new self($this->core, $this->runner);
    }

    /**
     * Get the state of the promise, one of PENDING, FULFILLED or REJECTED.
     *
     * @return string
     */
    public function getState()
    {
        return $this->core->getState();
    }

    /**
     * Wait for the promise to be fulfilled or rejected.
     *
     * When this method returns, the request has been resolved and the appropriate callable has terminated.
     *
     * When called with the unwrap option
     *
     * @param bool $unwrap Whether to return resolved value / throw reason or not
     *
     * @return \Psr\Http\Message\ResponseInterface|null Resolved value, null if $unwrap is set to false
     *
     * @throws \Http\Client\Exception The rejection reason.
     */
    public function wait($unwrap = true)
    {
        $this->runner->wait($this->core);

        if ($unwrap) {
            if ($this->core->getState() === self::REJECTED) {
                throw $this->core->getException();
            }

            return $this->core->getResponse();
        }
        return null;
    }
}