Files
shop-praktikum/shop/source/bootstrap.php
Nikolai Fesenko 8d227c9191 First upload
2025-02-02 13:37:56 +01:00

316 lines
11 KiB
PHP
Executable File

<?php
/**
* This file is part of O3-Shop.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE);
ini_set('display_errors', '0');
define('INSTALLATION_ROOT_PATH', dirname(__DIR__));
define('OX_BASE_PATH', INSTALLATION_ROOT_PATH . DIRECTORY_SEPARATOR . 'source' . DIRECTORY_SEPARATOR);
define('OX_LOG_FILE', OX_BASE_PATH . 'log' . DIRECTORY_SEPARATOR . 'oxideshop.log');
define('OX_OFFLINE_FILE', OX_BASE_PATH . 'offline.html');
define('VENDOR_PATH', INSTALLATION_ROOT_PATH . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR);
/**
* Provide a handler for catchable fatal errors, like failed requirement of files.
* No information about paths or file names must be disclosed to the frontend,
* as this would be a security problem on productive systems.
* This error handler is just a last resort for exceptions, which are not caught by the application.
*
* As this is the last resort no further errors must happen.
*/
register_shutdown_function(
function () {
$handledErrorTypes = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_RECOVERABLE_ERROR, E_USER_ERROR];
$sessionResetErrorTypes = [E_ERROR];
$error = error_get_last();
if ($error !== null && in_array($error['type'], $handledErrorTypes)) {
$errorType = array_flip(array_slice(get_defined_constants(true)['Core'], 0, 16, true))[$error['type']];
$errorMessage = $error['message'];
$unifiedNamespaceClassNotFound = preg_match(
'/^Class \'OxidEsales\\\\Eshop\\\\.*\' not found/',
$errorMessage,
$matches
);
if (1 === $unifiedNamespaceClassNotFound) {
$errorMessage .= '. Is an autogenerated class file missing? ' .
'Please run "composer oe:unified-namespace:generate" and double-check for errors. ' .
'Also double-check, if the class file for this very class was created.';
}
/** report the error */
$logMessage = "[uncaught error] [type $errorType] [file {$error['file']}] [line {$error['line']}] [code ]" .
" [message {$errorMessage}]";
/** write to log */
$time = microtime(true);
$micro = sprintf("%06d", ($time - floor($time)) * 1000000);
$date = new \DateTime(date('Y-m-d H:i:s.' . $micro, $time));
$timestamp = $date->format('d M H:i:s.u Y');
$message = "[$timestamp] " . $logMessage . PHP_EOL;
file_put_contents(OX_LOG_FILE, $message, FILE_APPEND);
$bootstrapConfigFileReader = new \BootstrapConfigFileReader();
if (!$bootstrapConfigFileReader->isDebugMode()) {
\oxTriggerOfflinePageDisplay();
}
if (in_array($error['type'], $sessionResetErrorTypes)) {
setcookie('sid', null, null, '/');
setcookie('admin_sid', null, null, '/');
}
}
}
);
// phpcs:disable
/**
* Helper for loading and getting the config file contents
*/
class BootstrapConfigFileReader
{
protected array $dynamicProperties = [];
/**
* @param string $name
* @param mixed $value
* @return void
*/
public function __set(string $name, $value): void
{
$this->dynamicProperties[$name] = $value;
}
/**
* @param string $name
* @return bool
*/
public function __isset(string $name): bool
{
return isset($this->dynamicProperties[$name]);
}
/**
* @param string $name
* @return mixed
*/
public function __get(string $name)
{
if (array_key_exists($name, $this->dynamicProperties)) {
return $this->dynamicProperties[$name];
}
$trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line']);
return null;
}
/**
* @param string $name
* @return void
*/
public function __unset(string $name): void
{
unset($this->dynamicProperties[$name]);
}
/**
* BootstrapConfigFileReader constructor.
*/
public function __construct()
{
include OX_BASE_PATH . "config.inc.php";
}
/**
* Check if debug mode is On.
*
* @return bool
*/
public function isDebugMode()
{
return (bool) $this->iDebug;
}
}
// phpcs:enable
/**
* Ensure shop config and autoload files are available.
*/
$configMissing = !is_readable(OX_BASE_PATH . "config.inc.php");
if ($configMissing || !is_readable(VENDOR_PATH . 'autoload.php')) {
if ($configMissing) {
$message = sprintf(
"Error: Config file '%s' could not be found! Please use '%s.dist' to make a copy.",
OX_BASE_PATH . "config.inc.php",
OX_BASE_PATH . "config.inc.php"
);
} else {
$message = "Error: Autoload file missing. Make sure you have ran the 'composer install' command.";
}
trigger_error($message, E_USER_ERROR);
}
unset($configMissing);
/**
* Turn on display errors for debug mode
*/
$bootstrapConfigFileReader = new \BootstrapConfigFileReader();
if ($bootstrapConfigFileReader->isDebugMode()) {
ini_set('display_errors', '1');
error_reporting(E_ALL & ~E_DEPRECATED);
}
unset($bootstrapConfigFileReader);
/**
* Register basic the autoloaders. In this phase we still do not want to use other shop classes to make autoloading
* as decoupled as possible.
*/
/*
* Require and register composer autoloader.
* This autoloader will load classes in the real existing namespace like '\OxidEsales\EshopCommunity\Core\UtilsObject'
* It will always come first, even if you move it after the other autoloaders as it registers itself with prepend = true
*/
require_once VENDOR_PATH . 'autoload.php';
/**
* Where CORE_AUTOLOADER_PATH points depends on how O3-Shop has been installed. If it is installed as part of a
* compilation, the directory 'Core', where the auto load classes are located, does not reside inside OX_BASE_PATH,
* but inside VENDOR_PATH.
*/
if (!is_dir(OX_BASE_PATH . 'Core')) {
define('CORE_AUTOLOADER_PATH', (new \OxidEsales\Facts\Facts())->getCommunityEditionSourcePath() .
DIRECTORY_SEPARATOR .
'Core' . DIRECTORY_SEPARATOR .
'Autoload' . DIRECTORY_SEPARATOR);
} else {
define('CORE_AUTOLOADER_PATH', OX_BASE_PATH . 'Core' . DIRECTORY_SEPARATOR . 'Autoload' . DIRECTORY_SEPARATOR);
}
/*
* Register the backwards compatibility autoloader.
* This autoloader will load classes for reasons of backwards compatibility like 'oxArticle'.
*/
require_once CORE_AUTOLOADER_PATH . 'BackwardsCompatibilityAutoload.php';
spl_autoload_register([OxidEsales\EshopCommunity\Core\Autoload\BackwardsCompatibilityAutoload::class, 'autoload']);
/**
* Register the module autoloader.
* It will load classes classes defined in the metadata key 'files'
* When this autoloader is called a database connection will be triggered
*/
require_once CORE_AUTOLOADER_PATH . 'ModuleAutoload.php';
spl_autoload_register([\OxidEsales\EshopCommunity\Core\Autoload\ModuleAutoload::class, 'autoload']);
/**
* Store the shop configuration in the Registry prior including the custom bootstrap functionality.
* Like this the shop configuration is available there.
*/
$configFile = new \OxidEsales\Eshop\Core\ConfigFile(OX_BASE_PATH . "config.inc.php");
\OxidEsales\Eshop\Core\Registry::set(\OxidEsales\Eshop\Core\ConfigFile::class, $configFile);
unset($configFile);
/**
* Set exception handler before including modules/functions.php so it can be overwritten easiliy by shop operators.
*/
$debugMode = (bool) \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\ConfigFile::class)->getVar('iDebug');
set_exception_handler(
[
new \OxidEsales\Eshop\Core\Exception\ExceptionHandler($debugMode),
'handleUncaughtException'
]
);
unset($debugMode);
/**
* Generic utility method file.
* The global object factory function oxNew is defined here.
*/
require_once OX_BASE_PATH . 'oxfunctions.php';
/**
* Custom bootstrap functionality.
*/
if (@is_readable(OX_BASE_PATH . 'modules/functions.php')) {
include OX_BASE_PATH . 'modules/functions.php';
}
/**
* The functions defined conditionally in this file may have been overwritten in 'modules/functions.php',
* so their functionality may have changed completely.
*/
require_once OX_BASE_PATH . 'overridablefunctions.php';
//sets default PHP ini params
ini_set('session.name', 'sid');
ini_set('session.use_cookies', 0);
ini_set('session.use_trans_sid', 0);
ini_set('url_rewriter.tags', '');
if (!function_exists('oxTriggerOfflinePageDisplay')) {
/**
* Bulletproof offline page loader
*/
function oxTriggerOfflinePageDisplay()
{
// Do not display the offline page, if this running in CLI mode
if ('cli' !== strtolower(php_sapi_name())) {
header("HTTP/1.1 500 Internal Server Error");
header("Connection: close");
/**
* Render an error message.
* If offline.php exists its content is displayed.
* Like this the error message is overridable within that file.
*/
if (is_readable(OX_OFFLINE_FILE)) {
echo file_get_contents(OX_OFFLINE_FILE);
};
}
}
}
/**
* @deprecated since v6.3 (2018-04-18); This method will be removed completely.
* Use OxidEsales\Eshop\Core\Registry::getLogger() in the future.
*
* @param string $message
*/
function writeToLog($message)
{
$time = microtime(true);
$micro = sprintf("%06d", ($time - floor($time)) * 1000000);
$date = new \DateTime(date('Y-m-d H:i:s.' . $micro, $time));
$timestamp = $date->format('d M H:i:s.u Y');
$message = "[$timestamp] " . $message . PHP_EOL;
file_put_contents(OX_LOG_FILE, $message, FILE_APPEND);
}