First upload
This commit is contained in:
315
shop/source/bootstrap.php
Executable file
315
shop/source/bootstrap.php
Executable file
@@ -0,0 +1,315 @@
|
||||
<?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);
|
||||
}
|
||||
Reference in New Issue
Block a user