Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
controller.php
1<?php
2
3namespace Bitrix\Vote\Base;
4
7use \Bitrix\Main\ErrorCollection;
8use \Bitrix\Main\Error;
9use \Bitrix\Main\Application;
10use \Bitrix\Main\Context;
14use \Bitrix\Main\Localization\Loc;
15use \Bitrix\Main\Web\Json;
16use Bitrix\Tasks\AccessDeniedException;
17
18Loc::loadMessages(__FILE__);
19
20abstract class Controller
21{
22 const EVENT_ON_BEFORE_ACTION = 'onBeforeAction';
23
24 const ERROR_REQUIRED_PARAMETER = 'VOTE_CONTROLLER_22001';
25 const ERROR_UNKNOWN_ACTION = 'VOTE_CONTROLLER_22002';
26
27 const STATUS_SUCCESS = 'success';
28 const STATUS_DENIED = 'denied';
29 const STATUS_ERROR = 'error';
30 const STATUS_NEED_AUTH = 'need_auth';
31
33 protected $action;
37 protected $realActionName;
41 protected $request;
42
43 private $collectDebugInfo = 1;
44
48 public function __construct()
49 {
50 try
51 {
52 $this->errorCollection = new ErrorCollection;
53 $this->request = Context::getCurrent()->getRequest();
54
55 $this->init();
56 }
57 catch(\Exception $e)
58 {
59 $this->errorCollection->add(array(new Error($e->getMessage())));
60 }
61
62 if (!$this->errorCollection->isEmpty())
63 {
64 $this->sendJsonErrorResponse();
65 }
66 }
67
73 protected function init()
74 {}
75
81 protected function end()
82 {
83 $this->logDebugInfo();
84
86 \CMain::finalActions();
87 die;
88 }
89
95 public function exec()
96 {
97 try
98 {
99 $this->collectDebugInfo();
100 $this->resolveAction();
101 $this->checkAction();
102 if ($this->prepareParams() && $this->errorCollection->isEmpty() && $this->processBeforeAction($this->getAction()) === true)
103 {
104 $this->runAction();
105 }
106 $this->logDebugInfo();
107 }
108 catch(\Exception $e)
109 {
110 $this->errorCollection->add(array(new Error($e->getMessage())));
111 }
112
113 if (!$this->errorCollection->isEmpty())
114 {
115 $this->sendJsonErrorResponse();
116 }
117 }
118
123 protected function collectDebugInfo()
124 {
125 if($this->collectDebugInfo)
126 {
127 Diag::getInstance()->collectDebugInfo(get_called_class());
128 }
129 }
130
136 protected function logDebugInfo()
137 {
138 if($this->collectDebugInfo)
139 {
140 Diag::getInstance()->logDebugInfo(get_called_class(), get_called_class() . ':' . $this->getAction());
141 }
142 }
143
148 protected function getUser()
149 {
150 global $USER;
151
152 return $USER;
153 }
154
161 protected function sendJsonResponse($response, $params = null)
162 {
163 if(!defined('PUBLIC_AJAX_MODE'))
164 {
165 define('PUBLIC_AJAX_MODE', true);
166 }
167
168 global $APPLICATION;
169 $APPLICATION->restartBuffer();
170
171 if(!empty($params['http_status']) && $params['http_status'] == 403)
172 {
173 header('HTTP/1.0 403 Forbidden', true, 403);
174 }
175 if(!empty($params['http_status']) && $params['http_status'] == 500)
176 {
177 header('HTTP/1.0 500 Internal Server Error', true, 500);
178 }
179 if(!empty($params['http_status']) && $params['http_status'] == 510)
180 {
181 header('HTTP/1.0 510 Not Extended', true, 510);
182 }
183
184 header('Content-Type:application/json; charset=UTF-8');
185 echo Json::encode($response);
186
187 $this->end();
188 }
189
194 protected function sendJsonErrorResponse()
195 {
196 $errors = array();
197 foreach($this->getErrors() as $error)
198 {
200 $errors[] = array(
201 'message' => $error->getMessage(),
202 'code' => $error->getCode(),
203 );
204 }
205 unset($error);
206 $this->sendJsonResponse(array(
207 'status' => self::STATUS_ERROR,
208 'errors' => $errors,
209 ));
210 }
211
217 protected function sendJsonAccessDeniedResponse($message = '')
218 {
219 $this->sendJsonResponse(array(
220 'status' => self::STATUS_DENIED,
221 'message' => $message,
222 ));
223 }
224
230 protected function sendJsonSuccessResponse(array $response = array())
231 {
232 $response['status'] = self::STATUS_SUCCESS;
233 $this->sendJsonResponse($response);
234 }
235
242 protected function sendResponse($response)
243 {
244 $this->logDebugInfo();
245
246 global $APPLICATION;
247 $APPLICATION->restartBuffer();
248
249 echo $response;
250
251 $this->end();
252 }
253
258 public function getErrors()
259 {
260 return $this->errorCollection->toArray();
261 }
262
263
269 public function getErrorByCode($code)
270 {
271 return $this->errorCollection->getErrorByCode($code);
272 }
273
279 protected function resolveAction()
280 {
281 $listOfActions = array_change_key_case($this->listActions(), CASE_LOWER);
282 $action = mb_strtolower($this->action);
283
284 if(!isset($listOfActions[$action]))
286 'VOTE_CONTROLLER_ERROR_UNKNOWN_ACTION',
287 array('#ACTION#' => $this->sanitizeActionName($action))
288 ));
289
290 $this->realActionName = $action;
291 $description = $this->normalizeActionDescription($action, $listOfActions[$this->realActionName]);
292
293 $this->setAction($description['name'], $description);
294
295 return $this;
296 }
297
298 private function sanitizeActionName($actionName)
299 {
300 if(!preg_match('/^[a-zA-Z0-9]+$/i', $actionName))
301 {
302 return 'unknown';
303 }
304
305 return $actionName;
306 }
307
323 protected function normalizeActionDescription($action, $description)
324 {
325 $description = array_merge(
326 array(
327 'method' => array('GET'),
328 'name' => (is_string($description) && $description <> '' ? $description : $action),
329 'need_auth' => true,
330 'check_sessid' => true,
331 'redirect_on_auth' => true
332 ),
333 (is_array($description) ? $description : array())
334 );
335 $description["method"] = array_intersect(is_array($description["method"]) ? $description["method"] : array($description["method"]), array("GET", "POST"));
336 return $description;
337 }
338
344 protected function checkAction()
345 {
346 $description = $this->getActionDescription();
347
348 if ($description["need_auth"] && (!$this->getUser() || !$this->getUser()->getId()))
349 {
350 if ($description["redirect_on_auth"])
351 {
352 LocalRedirect(SITE_DIR . 'auth/?backurl=' . urlencode(Application::getInstance()->getContext()->getRequest()->getRequestUri()));
353 }
354 else
355 {
356 throw new AccessDeniedException();
357 }
358 }
359
360 if (!in_array($this->request->getRequestMethod(), $description['method']))
361 throw new ArgumentException("Request method is not supported by ".$this->getAction()." operation.");
362
363 if ($description['check_sessid'] && !check_bitrix_sessid())
364 throw new ArgumentException("Bad sessid.");
365
366 return true;
367 }
368
383 protected function listActions()
384 {
385 return array();
386 }
387
392 public function getAction()
393 {
394 return $this->action;
395 }
396
401 public function getActionDescription()
402 {
403 return $this->actionDescription;
404 }
405
412 public function setAction($action, array $description)
413 {
414 $this->action = $action;
415 $this->actionDescription = $description;
416 return $this;
417 }
418
424 public function setActionName($action)
425 {
426 $this->action = $action;
427 return $this;
428 }
429
434 protected function prepareParams()
435 {
436 return true;
437 }
438
444 protected function processBeforeAction($actionName)
445 {
446 return true;
447 }
448
454 protected function runAction()
455 {
456 if (! method_exists($this, 'processAction' . $this->getAction()))
457 throw new InvalidOperationException('processAction' . $this->getAction());
458 return call_user_func(array($this, 'processAction' . $this->getAction()));
459 }
460
461
466 protected function getApplication()
467 {
468 global $APPLICATION;
469 return $APPLICATION;
470 }
471
479 protected function checkRequiredInputParams(array $inputParams, array $required)
480 {
481 foreach ($required as $item)
482 {
483 if(!isset($inputParams[$item]) || (!$inputParams[$item] && !(is_string($inputParams[$item]) && mb_strlen($inputParams[$item]))))
484 {
485 $this->errorCollection->add(array(new Error(Loc::getMessage('VOTE_CONTROLLER_ERROR_REQUIRED_PARAMETER', array('#PARAM#' => $item)), self::ERROR_REQUIRED_PARAMETER)));
486 return false;
487 }
488 }
489
490 return true;
491 }
492
499 protected function checkRequiredPostParams(array $required)
500 {
501 $params = array();
502 foreach($required as $item)
503 {
504 $params[$item] = $this->request->getPost($item);
505 }
506 unset($item);
507
508 return $this->checkRequiredInputParams($params, $required);
509 }
510
517 protected function checkRequiredGetParams(array $required)
518 {
519 $params = array();
520 foreach($required as $item)
521 {
522 $params[$item] = $this->request->getQuery($item);
523 }
524 unset($item);
525
526 return $this->checkRequiredInputParams($params, $required);
527 }
528
535 protected function checkRequiredFilesParams(array $required)
536 {
537 $params = array();
538 foreach($required as $item)
539 {
540 $params[$item] = $this->request->getFile($item);
541 }
542 unset($item);
543
544 return $this->checkRequiredInputParams($params, $required);
545 }
546
551 protected function isAjaxRequest()
552 {
553 return $this->request->isAjaxRequest();
554 }
555}
static getCurrent()
Definition context.php:241
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
sendJsonSuccessResponse(array $response=array())
checkRequiredFilesParams(array $required)
setAction($action, array $description)
sendJsonResponse($response, $params=null)
normalizeActionDescription($action, $description)
checkRequiredPostParams(array $required)
checkRequiredGetParams(array $required)
checkRequiredInputParams(array $inputParams, array $required)
sendJsonAccessDeniedResponse($message='')