Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
httpapplication.php
1<?php
8namespace Bitrix\Main;
9
20
25{
26 public const EXCEPTION_UNKNOWN_CONTROLLER = 221001;
27
33 protected function initializeContext(array $params)
34 {
35 $context = new HttpContext($this);
36
37 $server = new Server($params['server']);
38
39 $request = new HttpRequest(
40 $server,
41 $params['get'],
42 $params['post'],
43 $params['files'],
44 $params['cookie']
45 );
46
47 $response = new HttpResponse();
48
49 $context->initialize($request, $response, $server, ['env' => $params['env']]);
50
51 $this->setContext($context);
52 }
53
55 {
57 }
58
62 public function start()
63 {
64 $this->context->getRequest()->decodeJson();
65 }
66
70 public function finish()
71 {
72 }
73
74 private function getSourceParametersList()
75 {
76 if (!$this->context->getServer()->get('HTTP_BX_AJAX_QB'))
77 {
78 return array(
79 $this->context->getRequest()->getPostList(),
80 $this->context->getRequest()->getQueryList(),
81 );
82 }
83
84 return array(
85 Web\Json::decode($this->context->getRequest()->getPost('bx_data'))
86 );
87 }
88
94 public function run()
95 {
96 try
97 {
98 $router = new Router($this->context->getRequest());
99
102 [$controller, $actionName] = $router->getControllerAndAction();
103 if (!$controller)
104 {
105 throw new SystemException('Could not find controller for the request', self::EXCEPTION_UNKNOWN_CONTROLLER);
106 }
107
108 $this->runController($controller, $actionName);
109 }
110 catch (\Throwable $e)
111 {
112 $errorCollection = new ErrorCollection();
113
114 $this->processRunError($e, $errorCollection);
115 $this->finalizeControllerResult($controller ?? null, null, $errorCollection);
116 }
117 }
118
124 final public function runController($controller, $action): void
125 {
126 $result = null;
127 $errorCollection = new ErrorCollection();
128
129 try
130 {
131 if (is_string($controller))
132 {
133 $controller = ControllerBuilder::build($controller, [
134 'scope' => Controller::SCOPE_AJAX,
135 'currentUser' => CurrentUser::get(),
136 ]);
137 }
138
139 $this->registerAutoWirings();
140
141 $result = $controller->run($action, $this->getSourceParametersList());
142 $errorCollection->add($controller->getErrors());
143 }
144 catch (\Throwable $e)
145 {
146 $this->processRunError($e, $errorCollection);
147 }
148 finally
149 {
150 $this->finalizeControllerResult($controller, $result, $errorCollection);
151 }
152 }
153
159 private function finalizeControllerResult($controller, $result, ErrorCollection $errorCollection): void
160 {
161 $response = $this->buildResponse($result, $errorCollection);
162 $response = $this->context->getResponse()->copyHeadersTo($response);
163
164 if ($controller)
165 {
166 $controller->finalizeResponse($response);
167 }
168
169 $this->context->setResponse($response);
170
171 //todo exit code in Response?
172 $this->end(0, $response);
173 }
174
175 private function shouldWriteToLogException(\Throwable $e): bool
176 {
177 if ($e instanceof AutoWire\BinderArgumentException)
178 {
179 return false;
180 }
181
182 $unnecessaryCodes = [
184 Router::EXCEPTION_INVALID_COMPONENT_INTERFACE,
185 Router::EXCEPTION_INVALID_COMPONENT,
186 Router::EXCEPTION_INVALID_AJAX_MODE,
187 Router::EXCEPTION_NO_MODULE,
188 Router::EXCEPTION_INVALID_MODULE_NAME,
189 Router::EXCEPTION_INVALID_COMPONENT_NAME,
190 Router::EXCEPTION_NO_COMPONENT,
191 Router::EXCEPTION_NO_COMPONENT_AJAX_CLASS,
192 ];
193
194 if ($e instanceof SystemException && in_array($e->getCode(), $unnecessaryCodes, true))
195 {
196 return false;
197 }
198
199 return true;
200 }
201
202 private function processRunError(\Throwable $e, ErrorCollection $errorCollection): void
203 {
204 $errorCollection[] = new Error($e->getMessage(), $e->getCode());
205 $exceptionHandling = Configuration::getValue('exception_handling');
206 $debugMode = !empty($exceptionHandling['debug']);
207 if ($debugMode)
208 {
209 $errorCollection[] = new Error(Diag\ExceptionHandlerFormatter::format($e));
210 if ($e->getPrevious())
211 {
212 $errorCollection[] = new Error(Diag\ExceptionHandlerFormatter::format($e->getPrevious()));
213 }
214 }
215
216 if ($debugMode || $this->shouldWriteToLogException($e))
217 {
218 $this->getExceptionHandler()->writeToLog($e);
219 }
220 }
221
222 private function registerAutoWirings()
223 {
224 AutoWire\Binder::registerGlobalAutoWiredParameter(new AutoWire\Parameter(
225 PageNavigation::class,
226 static function() {
227 $pageNavigation = new PageNavigation('nav');
228 $pageNavigation
229 ->setPageSizes(range(1, 50))
230 ->initFromUri()
231 ;
232
233 return $pageNavigation;
234 }
235 ));
236
237 AutoWire\Binder::registerGlobalAutoWiredParameter(new AutoWire\Parameter(
238 JsonPayload::class,
239 static function() {
240 return new JsonPayload();
241 }
242 ));
243
244 AutoWire\Binder::registerGlobalAutoWiredParameter(new AutoWire\Parameter(
245 CurrentUser::class,
246 static function() {
247 return CurrentUser::get();
248 }
249 ));
250 }
251
261 private function buildResponse($actionResult, ErrorCollection $errorCollection)
262 {
263 if ($actionResult instanceof HttpResponse)
264 {
265 return $actionResult;
266 }
267
268 if (!$errorCollection->isEmpty())
269 {
270 //todo There is opportunity to create DenyError() and recognize AjaxJson::STATUS_DENIED by this error.
271
272 return new AjaxJson(
273 $actionResult,
274 AjaxJson::STATUS_ERROR,
275 $errorCollection
276 );
277 }
278
279 return new AjaxJson($actionResult);
280 }
281}
setContext(Context $context)
end($status=0, Response $response=null)
runController($controller, $action)