xref: /plugin/combo/ComboStrap/HttpRequest.php (revision 70bbd7f1f72440223cc13f3495efdcb2b0a11514)
104fd306cSNickeau<?php
204fd306cSNickeau
304fd306cSNickeaunamespace ComboStrap;
404fd306cSNickeau
504fd306cSNickeau
604fd306cSNickeauuse ComboStrap\Web\Url;
704fd306cSNickeauuse ComboStrap\Web\UrlEndpoint;
804fd306cSNickeau
904fd306cSNickeau/**
1004fd306cSNickeau * A request to the application
1104fd306cSNickeau * It's now a wrapper around {@link \TestRequest}
1204fd306cSNickeau */
1304fd306cSNickeauclass HttpRequest
1404fd306cSNickeau{
1504fd306cSNickeau
1604fd306cSNickeau    const CANONICAL = "httpRequest";
1704fd306cSNickeau    const POST = "post";
1804fd306cSNickeau    const GET = "get";
1904fd306cSNickeau    private bool $withTestRequest = true;
2004fd306cSNickeau
2104fd306cSNickeau    private Url $url;
2204fd306cSNickeau    private HttpResponse $response;
2304fd306cSNickeau    private string $method = self::GET;
2404fd306cSNickeau    private bool $asAdmin = false;
2504fd306cSNickeau    private array $postData = [];
2604fd306cSNickeau
2704fd306cSNickeau
2804fd306cSNickeau    public function __construct(Url $url)
2904fd306cSNickeau    {
3004fd306cSNickeau        $this->url = $url;
3104fd306cSNickeau
3204fd306cSNickeau
3304fd306cSNickeau    }
3404fd306cSNickeau
3504fd306cSNickeau
3604fd306cSNickeau    /**
3704fd306cSNickeau     * @param string $wikiId
3804fd306cSNickeau     * @return HttpResponse
3904fd306cSNickeau     * With the path uri: '/doku.php'
4004fd306cSNickeau     */
4104fd306cSNickeau    public static function fetchXhtmlPageResponse(string $wikiId): HttpResponse
4204fd306cSNickeau    {
4304fd306cSNickeau
4404fd306cSNickeau
4504fd306cSNickeau        $url = FetcherPage::createPageFetcherFromId($wikiId)
4604fd306cSNickeau            ->getFetchUrl();
4704fd306cSNickeau
4804fd306cSNickeau
4904fd306cSNickeau        return HttpRequest::createRequest($url)
5004fd306cSNickeau            ->withTestRequest()
5104fd306cSNickeau            ->fetch();
5204fd306cSNickeau
5304fd306cSNickeau    }
5404fd306cSNickeau
5504fd306cSNickeau
5604fd306cSNickeau    private function withTestRequest(): HttpRequest
5704fd306cSNickeau    {
5804fd306cSNickeau        $this->withTestRequest = true;
5904fd306cSNickeau        return $this;
6004fd306cSNickeau    }
6104fd306cSNickeau
6204fd306cSNickeau    public static function createRequest(Url $url): HttpRequest
6304fd306cSNickeau    {
6404fd306cSNickeau        return new HttpRequest($url);
6504fd306cSNickeau    }
6604fd306cSNickeau
6704fd306cSNickeau
6804fd306cSNickeau    /**
6904fd306cSNickeau     * @param array $data - data post body as if it was from a form
7004fd306cSNickeau     * @return $this
7104fd306cSNickeau     */
7204fd306cSNickeau    public function post(array $data = array()): HttpRequest
7304fd306cSNickeau    {
7404fd306cSNickeau        $this->method = self::POST;
7504fd306cSNickeau        $this->postData = $data;
7604fd306cSNickeau        return $this;
7704fd306cSNickeau    }
7804fd306cSNickeau
7904fd306cSNickeau
8004fd306cSNickeau    public function fetch(): HttpResponse
8104fd306cSNickeau    {
8204fd306cSNickeau        if (!$this->withTestRequest) {
8304fd306cSNickeau
8404fd306cSNickeau            throw new ExceptionRuntime("Real HTTP fetch not yet implemented, only test fetch");
8504fd306cSNickeau
8604fd306cSNickeau        }
8704fd306cSNickeau
8804fd306cSNickeau        if (ExecutionContext::getActualOrCreateFromEnv()->response()->hasEnded()) {
8904fd306cSNickeau            /**
9004fd306cSNickeau             * As of today, the execution context is responsible to
9104fd306cSNickeau             * send back the response
9204fd306cSNickeau             * (There is no routing context, therefore for
9304fd306cSNickeau             * each http request, a new context needs to be created)
9404fd306cSNickeau             */
9504fd306cSNickeau            throw new ExceptionRuntimeInternal("The execution context has ended, you should reopen another one");
9604fd306cSNickeau        }
9704fd306cSNickeau
9804fd306cSNickeau        try {
9904fd306cSNickeau            $path = $this->url->getPath();
10004fd306cSNickeau            if (!in_array($path, UrlEndpoint::DOKU_ENDPOINTS)) {
10104fd306cSNickeau                throw new ExceptionRuntime("The url path is not a doku endpoint path");
10204fd306cSNickeau            }
10304fd306cSNickeau        } catch (ExceptionNotFound $e) {
10404fd306cSNickeau            throw new ExceptionRuntime("The path is mandatory");
10504fd306cSNickeau        }
10604fd306cSNickeau
10704fd306cSNickeau        $testRequest = new \TestRequest();
10804fd306cSNickeau        $testRequest->setServer('REQUEST_TIME', time());
10904fd306cSNickeau
11004fd306cSNickeau        if ($this->asAdmin) {
11104fd306cSNickeau            Identity::becomeSuperUser($testRequest);
11204fd306cSNickeau        }
11304fd306cSNickeau
114*70bbd7f1Sgerardnico        /**
115*70bbd7f1Sgerardnico         * Deprecation are going into the HTML
116*70bbd7f1Sgerardnico         * and break the parsing
117*70bbd7f1Sgerardnico         */
118*70bbd7f1Sgerardnico        $level = error_reporting(E_ALL ^ (E_DEPRECATED));
119*70bbd7f1Sgerardnico        try {
12004fd306cSNickeau            switch ($this->method) {
12104fd306cSNickeau                case self::GET:
12204fd306cSNickeau                    $query = $this->url->getQueryProperties();
12304fd306cSNickeau                    $response = $testRequest->get($query, $path);
12404fd306cSNickeau                    break;
12504fd306cSNickeau                case self::POST:
12604fd306cSNickeau                    $query = $this->url->getQueryProperties();
12704fd306cSNickeau                    foreach ($query as $queryKey => $queryValue) {
12804fd306cSNickeau                        $testRequest->setGet($queryKey, $queryValue);
12904fd306cSNickeau                    }
13004fd306cSNickeau                    $response = $testRequest->post($this->postData, $path);
13104fd306cSNickeau                    break;
13204fd306cSNickeau                default:
13304fd306cSNickeau                    throw new ExceptionRuntime("The method ({$this->method}) is not implemented");
13404fd306cSNickeau            }
135*70bbd7f1Sgerardnico        } finally {
136*70bbd7f1Sgerardnico            error_reporting($level);
137*70bbd7f1Sgerardnico        }
13804fd306cSNickeau
13904fd306cSNickeau
14004fd306cSNickeau        return HttpResponse::createFromDokuWikiResponse($response);
14104fd306cSNickeau    }
14204fd306cSNickeau
14304fd306cSNickeau    public function asAdmin(): HttpRequest
14404fd306cSNickeau    {
14504fd306cSNickeau        $this->asAdmin = true;
14604fd306cSNickeau        return $this;
14704fd306cSNickeau    }
14804fd306cSNickeau
14904fd306cSNickeau    public function get(): HttpRequest
15004fd306cSNickeau    {
15104fd306cSNickeau        $this->method = self::GET;
15204fd306cSNickeau        return $this;
15304fd306cSNickeau    }
15404fd306cSNickeau
15504fd306cSNickeau    public function fetchAndExcuteBodyAsHtml(int $waitTimeInSecondToComplete = 0): HttpResponse
15604fd306cSNickeau    {
15704fd306cSNickeau        return $this->fetch()->executeBodyAsHtmlPage($waitTimeInSecondToComplete);
15804fd306cSNickeau    }
15904fd306cSNickeau
16004fd306cSNickeau
16104fd306cSNickeau}
162