Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
application.php
1<?php
2
10namespace Bitrix\Main;
11
23
27abstract class Application
28{
30 const JOB_PRIORITY_LOW = 50;
31
35 protected static $instance;
36 protected bool $initialized = false;
37 protected bool $terminating = false;
43 protected $context;
45 protected $router;
47 protected $currentRoute;
52 protected $connectionPool;
57 protected $managedCache;
62 protected $taggedCache;
64 protected $session;
66 protected $kernelSession;
71 /*
72 * @var \SplPriorityQueue
73 */
74 protected $backgroundJobs;
76 protected $license;
77
81 protected function __construct()
82 {
83 ServiceLocator::getInstance()->registerByGlobalSettings();
84 $this->backgroundJobs = new \SplPriorityQueue();
86 $this->initializeCache();
88 }
89
95 public static function getInstance()
96 {
97 if (!isset(static::$instance))
98 {
99 static::$instance = new static();
100 }
101 return static::$instance;
102 }
103
107 public static function hasInstance()
108 {
109 return isset(static::$instance);
110 }
111
116 public function initializeBasicKernel()
117 {
118 }
119
125 public function initializeExtendedKernel(array $params)
126 {
127 $this->initializeContext($params);
128
129 if (!$this->initialized)
130 {
131 $this->initializeSessions();
132 $this->initializeSessionLocalStorage();
133
134 $this->initialized = true;
135 }
136 }
137
138 private function initializeSessions()
139 {
140 $resolver = new SessionConfigurationResolver(Configuration::getInstance());
141 $resolver->resolve();
142
143 $this->session = $resolver->getSession();
144 $this->kernelSession = $resolver->getKernelSession();
145
146 $this->compositeSessionManager = new CompositeSessionManager(
147 $this->kernelSession,
148 $this->session
149 );
150 }
151
152 private function initializeSessionLocalStorage()
153 {
154 $cacheEngine = Data\Cache::createCacheEngine();
155 if ($cacheEngine instanceof Data\LocalStorage\Storage\CacheEngineInterface)
156 {
157 $localSessionStorage = new Data\LocalStorage\Storage\CacheStorage($cacheEngine);
158 }
159 else
160 {
161 $localSessionStorage = new Data\LocalStorage\Storage\NativeSessionStorage(
162 $this->getSession()
163 );
164 }
165
166 $this->sessionLocalStorageManager = new Data\LocalStorage\SessionLocalStorageManager($localSessionStorage);
167 $configLocalStorage = Config\Configuration::getValue("session_local_storage") ?: [];
168 if (isset($configLocalStorage['ttl']))
169 {
170 $this->sessionLocalStorageManager->setTtl($configLocalStorage['ttl']);
171 }
172 }
173
177 public function getRouter(): Router
178 {
179 if ($this->router === null)
180 {
181 $this->router = $this->initializeRouter();
182 }
183
184 return $this->router;
185 }
186
190 public function setRouter(Router $router): void
191 {
192 $this->router = $router;
193 }
194
198 public function getCurrentRoute(): Route
199 {
200 return $this->currentRoute;
201 }
202
203 public function hasCurrentRoute(): bool
204 {
205 return isset($this->currentRoute);
206 }
207
211 public function setCurrentRoute(Route $currentRoute): void
212 {
213 $this->currentRoute = $currentRoute;
214 }
215
216 protected function initializeRouter()
217 {
218 $routes = new RoutingConfigurator();
219 $router = new Router();
220 $routes->setRouter($router);
221
222 $this->setRouter($router);
223
224 // files with routes
225 $files = [];
226
227 // user files
228 $routingConfig = Configuration::getInstance()->get('routing');
229 $documentRoot = $this->context->getServer()->getDocumentRoot();
230
231 if (!empty($routingConfig['config']))
232 {
233 $fileNames = $routingConfig['config'];
234
235 foreach ($fileNames as $fileName)
236 {
237 foreach (['local', 'bitrix'] as $vendor)
238 {
239 $filename = $documentRoot . '/' . $vendor . '/routes/' . basename($fileName);
240
241 if (file_exists($filename))
242 {
243 $files[] = $filename;
244 }
245 }
246 }
247 }
248
249 // system files
250 if (file_exists($documentRoot . '/bitrix/routes/web_bitrix.php'))
251 {
252 $files[] = $documentRoot . '/bitrix/routes/web_bitrix.php';
253 }
254
255 foreach ($files as $file)
256 {
257 $callback = include $file;
258 $callback($routes);
259 }
260
261 $router->releaseRoutes();
262
263 // cache for route compiled data
265
266 return $router;
267 }
268
274 abstract protected function initializeContext(array $params);
275
280 abstract public function start();
281
288 public function run()
289 {
290 }
291
302 public function end($status = 0, Response $response = null)
303 {
304 if ($response === null)
305 {
306 //use default response
307 $response = $this->context->getResponse();
308
309 //it's possible to have open buffers
310 $content = '';
311 $n = ob_get_level();
312 while (($c = ob_get_clean()) !== false && $n > 0)
313 {
314 $content .= $c;
315 $n--;
316 }
317
318 if ($content <> '')
319 {
320 $response->appendContent($content);
321 }
322 }
323
324 $this->handleResponseBeforeSend($response);
325
326 //this is the last point of output - all output below will be ignored
327 $response->send();
328
329 $this->terminate($status);
330 }
331
332 protected function handleResponseBeforeSend(Response $response): void
333 {
335 if (!($kernelSession instanceof KernelSessionProxy) && $kernelSession->isStarted())
336 {
337 //save session data in cookies
338 $handler = $kernelSession->getSessionHandler();
339 if ($handler instanceof CookieSessionHandler)
340 {
341 if ($response instanceof HttpResponse)
342 {
343 $handler->setResponse($response);
344 }
345 }
346 $kernelSession->save();
347 }
348 }
349
357 public function terminate($status = 0)
358 {
359 if ($this->terminating)
360 {
361 // recursion control
362 return;
363 }
364
365 $this->terminating = true;
366
367 //old kernel staff
368 \CMain::RunFinalActionsInternal();
369
370 //Release session
371 session_write_close();
372
373 $pool = $this->getConnectionPool();
374
375 $pool->useMasterOnly(true);
376
377 $this->runBackgroundJobs();
378
379 $pool->useMasterOnly(false);
380
381 Data\ManagedCache::finalize();
382
383 $pool->disconnect();
384
385 exit($status);
386 }
387
413 protected function initializeExceptionHandler()
414 {
415 $exceptionHandler = new Diag\ExceptionHandler();
416
417 $exceptionHandling = Config\Configuration::getValue("exception_handling");
418 if ($exceptionHandling == null)
419 {
420 $exceptionHandling = [];
421 }
422
423 if (!isset($exceptionHandling["debug"]) || !is_bool($exceptionHandling["debug"]))
424 {
425 $exceptionHandling["debug"] = false;
426 }
427 $exceptionHandler->setDebugMode($exceptionHandling["debug"]);
428
429 if (!empty($exceptionHandling['track_modules']) && is_array($exceptionHandling['track_modules']))
430 {
431 $exceptionHandler->setTrackModules($exceptionHandling['track_modules']);
432 }
433
434 if (isset($exceptionHandling["handled_errors_types"]) && is_int($exceptionHandling["handled_errors_types"]))
435 {
436 $exceptionHandler->setHandledErrorsTypes($exceptionHandling["handled_errors_types"]);
437 }
438
439 if (isset($exceptionHandling["exception_errors_types"]) && is_int($exceptionHandling["exception_errors_types"]))
440 {
441 $exceptionHandler->setExceptionErrorsTypes($exceptionHandling["exception_errors_types"]);
442 }
443
444 if (isset($exceptionHandling["ignore_silence"]) && is_bool($exceptionHandling["ignore_silence"]))
445 {
446 $exceptionHandler->setIgnoreSilence($exceptionHandling["ignore_silence"]);
447 }
448
449 if (isset($exceptionHandling["assertion_throws_exception"]) && is_bool($exceptionHandling["assertion_throws_exception"]))
450 {
451 $exceptionHandler->setAssertionThrowsException($exceptionHandling["assertion_throws_exception"]);
452 }
453
454 if (isset($exceptionHandling["assertion_error_type"]) && is_int($exceptionHandling["assertion_error_type"]))
455 {
456 $exceptionHandler->setAssertionErrorType($exceptionHandling["assertion_error_type"]);
457 }
458
459 $exceptionHandler->initialize(
460 [$this, "createExceptionHandlerOutput"],
461 [$this, "createExceptionHandlerLog"]
462 );
463
464 ServiceLocator::getInstance()->addInstance('exceptionHandler', $exceptionHandler);
465 }
466
468 {
469 $exceptionHandling = Config\Configuration::getValue("exception_handling");
470
471 if (!is_array($exceptionHandling) || !isset($exceptionHandling["log"]) || !is_array($exceptionHandling["log"]))
472 {
473 return null;
474 }
475
476 $options = $exceptionHandling["log"];
477
478 $log = null;
479
480 if (!empty($options["class_name"]))
481 {
482 if (!empty($options["extension"]) && !extension_loaded($options["extension"]))
483 {
484 return null;
485 }
486
487 if (!empty($options["required_file"]) && ($requiredFile = Loader::getLocal($options["required_file"])) !== false)
488 {
489 require_once($requiredFile);
490 }
491
492 $className = $options["class_name"];
493 if (!class_exists($className))
494 {
495 return null;
496 }
497
498 $log = new $className();
499 }
500 elseif (isset($options["settings"]) && is_array($options["settings"]))
501 {
502 $log = new Diag\FileExceptionHandlerLog();
503 }
504 else
505 {
506 return null;
507 }
508
509 $log->initialize(
510 isset($options["settings"]) && is_array($options["settings"]) ? $options["settings"] : []
511 );
512
513 return $log;
514 }
515
517 {
518 return new Diag\ExceptionHandlerOutput();
519 }
520
524 protected function createDatabaseConnection()
525 {
526 $this->connectionPool = new Data\ConnectionPool();
527 }
528
529 protected function initializeCache()
530 {
531 //TODO: Should be transfered to where GET parameter is defined in future
532 //magic parameters: show cache usage statistics
533 $show_cache_stat = "";
534 if (isset($_GET["show_cache_stat"]))
535 {
536 $show_cache_stat = (strtoupper($_GET["show_cache_stat"]) == "Y" ? "Y" : "");
537 @setcookie("show_cache_stat", $show_cache_stat, false, "/");
538 }
539 elseif (isset($_COOKIE["show_cache_stat"]))
540 {
541 $show_cache_stat = $_COOKIE["show_cache_stat"];
542 }
543 Data\Cache::setShowCacheStat($show_cache_stat === "Y");
544
545 if (isset($_GET["clear_cache_session"]))
546 {
547 Data\Cache::setClearCacheSession($_GET["clear_cache_session"] === 'Y');
548 }
549 if (isset($_GET["clear_cache"]))
550 {
551 Data\Cache::setClearCache($_GET["clear_cache"] === 'Y');
552 }
553 }
554
558 public function getExceptionHandler()
559 {
560 return ServiceLocator::getInstance()->get('exceptionHandler');
561 }
562
568 public function getConnectionPool()
569 {
571 }
572
578 public function getContext()
579 {
580 return $this->context;
581 }
582
588 public function setContext(Context $context)
589 {
590 $this->context = $context;
591 }
592
593 public function getLicense(): License
594 {
595 if (!$this->license)
596 {
597 $this->license = new License();
598 }
599
600 return $this->license;
601 }
602
611 public static function getConnection($name = "")
612 {
613 $pool = Application::getInstance()->getConnectionPool();
614 return $pool->getConnection($name);
615 }
616
622 public function getCache()
623 {
624 return Data\Cache::createInstance();
625 }
626
632 public function getManagedCache()
633 {
634 if ($this->managedCache == null)
635 {
636 $this->managedCache = new Data\ManagedCache();
637 }
638
639 return $this->managedCache;
640 }
641
647 public function getTaggedCache()
648 {
649 if ($this->taggedCache == null)
650 {
651 $this->taggedCache = new Data\TaggedCache();
652 }
653
654 return $this->taggedCache;
655 }
656
657 final public function getSessionLocalStorageManager(): Data\LocalStorage\SessionLocalStorageManager
658 {
660 }
661
662 final public function getLocalSession($name): Data\LocalStorage\SessionLocalStorage
663 {
664 return $this->sessionLocalStorageManager->get($name);
665 }
666
667 final public function getKernelSession(): SessionInterface
668 {
670 }
671
672 final public function getSession(): SessionInterface
673 {
674 return $this->session;
675 }
676
681
687 public static function getUserTypeManager()
688 {
689 global $USER_FIELD_MANAGER;
690 return $USER_FIELD_MANAGER;
691 }
692
698 public static function isUtfMode()
699 {
700 static $isUtfMode = null;
701 if ($isUtfMode === null)
702 {
703 $isUtfMode = Config\Configuration::getValue("utf_mode");
704 if ($isUtfMode === null)
705 {
706 $isUtfMode = false;
707 }
708 }
709 return $isUtfMode;
710 }
711
717 public static function getDocumentRoot()
718 {
719 static $documentRoot = null;
720 if ($documentRoot != null)
721 {
722 return $documentRoot;
723 }
724
725 $context = Application::getInstance()->getContext();
726 if ($context != null)
727 {
728 $server = $context->getServer();
729 if ($server != null)
730 {
731 return $documentRoot = $server->getDocumentRoot();
732 }
733 }
734
736 }
737
743 public static function getPersonalRoot()
744 {
745 static $personalRoot = null;
746 if ($personalRoot != null)
747 {
748 return $personalRoot;
749 }
750
751 $context = Application::getInstance()->getContext();
752 if ($context != null)
753 {
754 $server = $context->getServer();
755 if ($server != null)
756 {
757 return $personalRoot = $server->getPersonalRoot();
758 }
759 }
760
761 return $_SERVER["BX_PERSONAL_ROOT"] ?? '/bitrix';
762 }
763
767 public static function resetAccelerator(string $filename = null)
768 {
769 if (defined("BX_NO_ACCELERATOR_RESET"))
770 {
771 return;
772 }
773
774 if (Config\Configuration::getValue("no_accelerator_reset"))
775 {
776 return;
777 }
778
779 if (function_exists("opcache_reset"))
780 {
781 if ($filename !== null)
782 {
783 opcache_invalidate($filename);
784 }
785 else
786 {
787 opcache_reset();
788 }
789 }
790 elseif (function_exists("wincache_refresh_if_changed"))
791 {
792 wincache_refresh_if_changed();
793 }
794 }
795
803 public function addBackgroundJob(callable $job, array $args = [], $priority = self::JOB_PRIORITY_NORMAL)
804 {
805 $this->backgroundJobs->insert([$job, $args], $priority);
806
807 return $this;
808 }
809
810 protected function runBackgroundJobs()
811 {
812 $lastException = null;
813 $exceptionHandler = $this->getExceptionHandler();
814
815 //jobs can be added from jobs
816 while ($this->backgroundJobs->valid())
817 {
818 //clear the queue
819 $jobs = [];
820 foreach ($this->backgroundJobs as $job)
821 {
822 $jobs[] = $job;
823 }
824
825 //do job
826 foreach ($jobs as $job)
827 {
828 try
829 {
830 call_user_func_array($job[0], $job[1]);
831 }
832 catch (\Throwable $exception)
833 {
834 $lastException = $exception;
835 $exceptionHandler->writeToLog($exception);
836 }
837 }
838 }
839
840 if ($lastException !== null)
841 {
842 throw $lastException;
843 }
844 }
845
850 public function isInitialized()
851 {
852 return $this->initialized;
853 }
854}
handleResponseBeforeSend(Response $response)
setContext(Context $context)
static resetAccelerator(string $filename=null)
setCurrentRoute(Route $currentRoute)
addBackgroundJob(callable $job, array $args=[], $priority=self::JOB_PRIORITY_NORMAL)
initializeContext(array $params)
setRouter(Router $router)
static getConnection($name="")
end($status=0, Response $response=null)
initializeExtendedKernel(array $params)
static getDocumentRoot()
Definition loader.php:254
static getLocal($path, $root=null)
Definition loader.php:529
static handle($files, $router)