xref: /plugin/combo/ComboStrap/HttpRequest.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1<?php
2
3namespace ComboStrap;
4
5
6use ComboStrap\Web\Url;
7use ComboStrap\Web\UrlEndpoint;
8
9/**
10 * A request to the application
11 * It's now a wrapper around {@link \TestRequest}
12 */
13class HttpRequest
14{
15
16    const CANONICAL = "httpRequest";
17    const POST = "post";
18    const GET = "get";
19    private bool $withTestRequest = true;
20
21    private Url $url;
22    private HttpResponse $response;
23    private string $method = self::GET;
24    private bool $asAdmin = false;
25    private array $postData = [];
26
27
28    public function __construct(Url $url)
29    {
30        $this->url = $url;
31
32
33    }
34
35
36    /**
37     * @param string $wikiId
38     * @return HttpResponse
39     * With the path uri: '/doku.php'
40     */
41    public static function fetchXhtmlPageResponse(string $wikiId): HttpResponse
42    {
43
44
45        $url = FetcherPage::createPageFetcherFromId($wikiId)
46            ->getFetchUrl();
47
48
49        return HttpRequest::createRequest($url)
50            ->withTestRequest()
51            ->fetch();
52
53    }
54
55
56    private function withTestRequest(): HttpRequest
57    {
58        $this->withTestRequest = true;
59        return $this;
60    }
61
62    public static function createRequest(Url $url): HttpRequest
63    {
64        return new HttpRequest($url);
65    }
66
67
68    /**
69     * @param array $data - data post body as if it was from a form
70     * @return $this
71     */
72    public function post(array $data = array()): HttpRequest
73    {
74        $this->method = self::POST;
75        $this->postData = $data;
76        return $this;
77    }
78
79
80    public function fetch(): HttpResponse
81    {
82        if (!$this->withTestRequest) {
83
84            throw new ExceptionRuntime("Real HTTP fetch not yet implemented, only test fetch");
85
86        }
87
88        if (ExecutionContext::getActualOrCreateFromEnv()->response()->hasEnded()) {
89            /**
90             * As of today, the execution context is responsible to
91             * send back the response
92             * (There is no routing context, therefore for
93             * each http request, a new context needs to be created)
94             */
95            throw new ExceptionRuntimeInternal("The execution context has ended, you should reopen another one");
96        }
97
98        try {
99            $path = $this->url->getPath();
100            if (!in_array($path, UrlEndpoint::DOKU_ENDPOINTS)) {
101                throw new ExceptionRuntime("The url path is not a doku endpoint path");
102            }
103        } catch (ExceptionNotFound $e) {
104            throw new ExceptionRuntime("The path is mandatory");
105        }
106
107        $testRequest = new \TestRequest();
108        $testRequest->setServer('REQUEST_TIME', time());
109
110        if ($this->asAdmin) {
111            Identity::becomeSuperUser($testRequest);
112        }
113
114        switch ($this->method) {
115            case self::GET:
116                $query = $this->url->getQueryProperties();
117                $response = $testRequest->get($query, $path);
118                break;
119            case self::POST:
120                $query = $this->url->getQueryProperties();
121                foreach ($query as $queryKey => $queryValue) {
122                    $testRequest->setGet($queryKey, $queryValue);
123                }
124                $response = $testRequest->post($this->postData, $path);
125                break;
126            default:
127                throw new ExceptionRuntime("The method ({$this->method}) is not implemented");
128        }
129
130
131        return HttpResponse::createFromDokuWikiResponse($response);
132    }
133
134    public function asAdmin(): HttpRequest
135    {
136        $this->asAdmin = true;
137        return $this;
138    }
139
140    public function get(): HttpRequest
141    {
142        $this->method = self::GET;
143        return $this;
144    }
145
146    public function fetchAndExcuteBodyAsHtml(int $waitTimeInSecondToComplete = 0): HttpResponse
147    {
148        return $this->fetch()->executeBodyAsHtmlPage($waitTimeInSecondToComplete);
149    }
150
151
152}
153