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