File modules/cms/output/BaseOutput.class.php

Last commit: Sat Oct 17 01:14:30 2026 +0200	Jan Dankert	New: Using a structured class for the API-Response. The output for GET-Requests is now without the "output" layer.
1 <?php 2 3 namespace cms\output; 4 5 use BadMethodCallException; 6 use cms\action\RequestParams; 7 use cms\action\Response; 8 use cms\api\APIResponse; 9 use cms\base\Language as L; 10 use cms\base\Startup; 11 use cms\Dispatcher; 12 use Exception; 13 use util\exception\ClientException; 14 use util\Http; 15 use logger\Logger; 16 use \util\exception\ObjectNotFoundException; 17 use util\exception\UIException; 18 use util\exception\SecurityException; 19 use util\Hydrator; 20 use util\Session; 21 22 23 /** 24 * base class for output. 25 */ 26 abstract class BaseOutput implements Output 27 { 28 /** 29 * Outputting the data to the client. 30 * Must be overwritten by subclasses. 31 * @param $request RequestParams 32 * @param $data array data array 33 * @return void 34 */ 35 abstract protected function outputData(RequestParams|null $request, array $data): void; 36 37 /** 38 * Calling the dispatcher. 39 */ 40 public function execute() 41 { 42 $request = new RequestParams(); 43 $response = new Response(); 44 45 try { 46 $this->beforeAction( $request ); 47 48 // special behaviour of UI actions, these are placed in a special package. 49 if ( in_array( $request->action,['index','tree','title','usergroup']) ) 50 $request->isUIAction = true; 51 52 $dispatcher = new Dispatcher(); 53 $dispatcher->setRequestAndResponse( $request,$response ); 54 55 $dispatcher->doAction(); // calling the action ... 56 57 if ( $contentType = $this->getContentType() ) 58 header('Content-Type: '.$contentType.'; charset='.Startup::CHARSET); 59 60 $response->setHTTPHeader(); 61 62 if ( $request->isAction ) { 63 64 $apiResponse = new APIResponse( 65 '', 66 $response->getNotices(), // notices 67 $response->getErrors(), // fieldnames with validation errors 68 $response->getStatus(), // notice status 69 $response->getStatus(), // same as above, historical reasons 70 $response->success, // success, true if there are no errors and no notices with status error. 71 new \cms\api\Session( 72 session_name(), 73 session_id(), 74 Session::token(), 75 ), 76 Startup::VERSION, 77 intval(Startup::API_LEVEL), 78 null, 79 ); 80 81 $this->outputData( $request,Hydrator::toArray($apiResponse ) ); // ... and output the data 82 } 83 else { 84 $this->outputData( $request,$response->getOutputData() ); // ... and output the data 85 } 86 87 } catch (BadMethodCallException $e) { 88 // Action-Method does not exist. 89 Logger::debug( $e ); 90 Http::notAcceptable(); 91 $this->setError("Method not found",$e); 92 } catch (ObjectNotFoundException $e) { 93 Logger::debug( $e ); // only debug, because this may happen on links to deleted objects. 94 Http::noContent(); 95 $this->setError("No content",$e); 96 } catch (UIException $e) { 97 Logger::warn( $e ); 98 $this->setError(L::lang($e->key,$e->params),$e); 99 } catch (SecurityException $e) { 100 Logger::info($e); 101 Http::forbidden(); 102 $this->setError("You are not allowed to execute this action.",$e); 103 } catch (ClientException $e) { 104 Logger::info($e); 105 Http::badRequest(); 106 $this->setError("Invalid data in request.",$e); 107 } catch (Exception $e) { 108 Logger::warn( $e ); 109 // Sorry, our service is currently unavailable 110 Http::serverError(); 111 $this->setError("Internal CMS error",$e); 112 } 113 } 114 115 116 /** 117 * This method is executed before the dispatcher is called. 118 * Subclasses may override this to prepare the response. 119 * @param $request RequestParams 120 * @return void 121 */ 122 protected function beforeAction( $request ) 123 { 124 } 125 126 127 /** 128 * Is called if an error is thrown. 129 * 130 * @param $text string a message 131 * @param $cause Exception 132 */ 133 abstract protected function setError(string $text, Exception $cause): void; 134 }
Download modules/cms/output/BaseOutput.class.php
History Sat, 17 Oct 2026 01:14:30 +0200 Jan Dankert New: Using a structured class for the API-Response. The output for GET-Requests is now without the "output" layer. Tue, 13 Oct 2026 22:52:59 +0200 Jan Dankert New: The UI is now able to send hierarchical form data and the server is converting it into an object. This is a very nice feature, because this enables a better OpenAPI interface. Mon, 6 Jan 2025 22:48:11 +0100 Jan Dankert New: Now it is possible to remove and create new login/api token for a user; new API authorization with the authorization scheme "api". Sat, 19 Mar 2022 01:29:19 +0100 dankert Fix: PreviewOutput should inherit from UIOutput. Sat, 19 Mar 2022 00:09:47 +0100 dankert Refactoring: Outputs are setting their content-type themself. Sun, 13 Feb 2022 23:35:26 +0100 dankert Refactoring: New class "Response" which stores all output information. Sun, 6 Feb 2022 21:56:52 +0100 dankert New CssOutput which outputs the CSS in a cleaner way. Wed, 2 Feb 2022 01:12:42 +0100 dankert Better support for API requests. Mon, 31 Jan 2022 00:00:48 +0100 dankert Some documentation... Sun, 30 Jan 2022 23:38:42 +0100 dankert Refactoring: Only 1 http-endpoint for both the UI and the API. Path "/api" is not available any more, all API data is served under "/".