getIsInitialized()) { return false; } foreach ( [ 'app', 'db' => 'database', 'errors', 'input', 'locale', 'request', 'router', 'security', 'view', ] as $key => $component ) { $key = is_int($key) ? $component : $key; $this->$key = $this->$key ?? bff($component); } $this->setIsInitialized(); return true; } /** * Инициализирован ли компонент * @return bool */ public function getIsInitialized(): bool { return $this->initialized; } /** * Помечаем инициализацию компонента * @param bool $initialized * @return void */ public function setIsInitialized(bool $initialized = true) { $this->initialized = $initialized; } /** * Получение настроек компонента * @param string|string[] $keys * @param mixed $default * @return array|mixed */ public function getSettings($keys, $default = null) { if (is_array($keys)) { $res = []; foreach ($keys as $key) { if (isset($this->sett[$key])) { $res[$key] = $this->sett[$key]; } } return $res; } elseif (is_string($keys)) { if (isset($this->sett[$keys])) { return $this->sett[$keys]; } if (property_exists($this, $keys)) { return $this->$keys; } return $default; } return $this->sett; } /** * Установка настроек компонента * @param array|string $keys * @param mixed $value * @param array $opts * @return void */ public function setSettings($keys, $value = false, array $opts = []) { if (! is_array($keys)) { $keys = [$keys => $value]; } if (! empty($opts['skip'])) { $keys = array_diff_key($keys, array_flip( is_array($opts['skip']) ? $opts['skip'] : [$opts['skip']] )); } foreach ($keys as $key => $val) { if (($opts['props'] ?? true) && property_exists($this, $key)) { $this->$key = $val; } $this->sett[$key] = $val; } } /** * Handle new request * @param Request $request */ public function onNewRequest($request) { $this->setRequest($request); } /** * Set current request instance * @param Request $request */ public function setRequest(Request $request) { $this->request = $request; $this->input = $request->input(); } /** * Get the current request instance * @return Request */ public function getRequest() { return $this->request ?? $this->app->request(); } /** * Проверка соответствия метода текущего запроса GET запросу * @return bool */ public function isGET(): bool { return $this->request->isGET(); } /** * Проверка соответствия метода текущего запроса POST запросу * @return bool */ public function isPOST(): bool { return $this->request->isPOST(); } /** * Проверка соответствия метода текущего запроса AJAX запросу * @param string|null $requestMethod тип запроса: 'POST', 'GET', null - не выполнять проверку типа * @return bool */ public function isAJAX(?string $requestMethod = 'POST'): bool { return $this->request->isAJAX($requestMethod); } /** * Determine if the application is running in the frontend context. * @return bool */ public function isFrontend(): bool { return $this->app->frontend(); } /** * Determine if the application is running in the admin panel context. * @return bool */ public function isAdminPanel(): bool { return $this->app->adminPanel(); } /** * Determine if admin developers mode is enabled. * @return bool */ public function isAdminFordev(): bool { return $this->app->adminFordev(); } /** * Determine if the application is running in cron context. * @return bool */ public function isCron(): bool { return $this->app->cron(); } /** * Determine if debug mode is enabled. * @return bool */ public function isDebug(): bool { return $this->app->isDebug(); } /** * Формируем ответ на ajax-запрос * Если data=0,1,2 - это не ключ ошибки, а просто краткий ответ * @param mixed $data response data * @param mixed $format response type; 0|false - raw echo, 1|true - json echo, 2 - json echo + errors * @param bool $nativeJsonEncode использовать json_encode * @param bool $escapeHTML енкодить html теги, при возвращении результата в iframe * @return \bff\http\Response */ protected function ajaxResponse($data, $format = 2, $nativeJsonEncode = false, $escapeHTML = false) { if ($format === 2) { $response = [ 'data' => $data, 'errors' => [], ]; if ($this->errors->no()) { if (is_int($data) && $data > 2) { $this->errors->set($data); $response['errors'] = $this->errors->get(true); $response['data'] = ''; } } else { $response['errors'] = $this->errors->get(true); } if ($this->isDebug()) { $log = $this->app->logger()->consoleLogs(); if (! empty($log)) { $response['console'] = $log; } } $result = ($nativeJsonEncode ? json_encode($response) : func::php2js($response)); } elseif ($format === true || $format === 1) { $result = ($nativeJsonEncode ? json_encode($data) : func::php2js($data)); } else { $result = $data; $rawData = true; } if ($escapeHTML) { $result = htmlspecialchars($result, ENT_NOQUOTES); } $response = Response::text($result); if (! isset($rawData)) { $response = $response->withHeader('Content-Type', 'application/json; charset=utf-8'); } return $response; } /** * Формируем ответ на ajax-запрос (для формы) * @param array $data response data * @param mixed $format response type; 0|false - raw echo, 1|true - json echo, 2 - json echo + errors * @param bool $nativeJsonEncode использовать json_encode * @param bool $escapeHTML енкодить html теги, при возвращении результата в iframe * @return \bff\http\Response */ protected function ajaxResponseForm(array $data = [], $format = 2, $nativeJsonEncode = false, $escapeHTML = false) { $data['success'] = $this->errors->no(); $data['fields'] = $this->errors->fields(); foreach (['list','html'] as $key) { if (isset($data[$key]) && is_string($data[$key])) { $data[$key] = $this->app->tagsProcess($data[$key]); } } return $this->ajaxResponse($data, $format, $nativeJsonEncode, $escapeHTML); } /** * Формируем ответ на ajax-запрос (для формы отправленной через bff.iframeSubmit) * @param array $data response data * @return \bff\http\Response */ protected function iframeResponseForm(array $data = []) { return $this->ajaxResponseForm($data, 2, false, true); } /** * Config data * @param string $key * @param mixed $default * @param mixed $opts TYPE_UINT, ... * @return mixed */ public function config($key, $default = '', $opts = []) { return config::sysAdmin($key, $default, ($opts === [] ? false : $opts)); } /** * Log message * @param string|array $message message(s) text * @param mixed $opts * array - context * int - level * true - console message * Closure - function(){ return [ * 'context' => array, * 'console' => bool, * 'level' => int, * ]; } * @param mixed $to * @return void */ public function log($message, $opts = [], $to = null) { if (is_scalar($message)) { $message = static::class . ': ' . strval($message); } if (is_array($opts)) { $opts = ['context' => $opts]; if (is_int($to)) { $opts['level'] = $to; $to = null; } } elseif (is_int($opts)) { $opts = ['level' => $opts]; if (is_array($to)) { $opts['context'] = $to; $to = null; } } elseif (is_bool($opts)) { $opts = ['console' => true]; if (is_array($to)) { $opts['context'] = $to; } elseif (is_int($to)) { $opts['level'] = $to; } } elseif ($opts instanceof Closure) { $opts = $opts(); } $opts = $this->defaults((is_array($opts) ? $opts : []), [ 'context' => [], 'console' => false, 'level' => Logger::ERROR, ]); $this->app->log($message, ($opts['console'] ? true : $opts['level']), $to ?? Logger::DEFAULT_FILE, $opts['context']); } }