包含:登录失败锁定、90天密码有效期、30分钟会话超时、 强制改密、登录审计日志、屏幕水印、企业背景图、 备案信息固定底部、favicon、JS空集合保护、 会话过期体验优化(403 JSON)、display_errors 关闭、 固定 key 根治 Integrity check failed 等全部改动 注意:config.inc.php/.htaccess/.user.ini 含敏感信息, 通过 .gitignore 排除,勿推送到公开仓库。
137 lines
4.0 KiB
PHP
137 lines
4.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
namespace MRBS;
|
|
|
|
// Returns the full table name including schema and prefix for a given table.
|
|
// Needs to be dynamic rather than static in case we are running a multisite
|
|
// installation and want to switch sites, eg during a database upgrade.
|
|
|
|
use MRBS\DB\DB;
|
|
use MRBS\DB\DBFactory;
|
|
use MRBS\Errors\Errors;
|
|
use PDO;
|
|
|
|
function _tbl(string $short_name, bool $include_schema=true) : string
|
|
{
|
|
global $dbsys, $db_tbl_prefix, $db_schema;
|
|
|
|
// Do some sanity checking
|
|
if (!isset($short_name))
|
|
{
|
|
throw new \Exception('$short_name not set.');
|
|
}
|
|
|
|
$result = $db_tbl_prefix . $short_name;
|
|
|
|
// Prepend the schema name if set and form a qualified name for all databases
|
|
// other than MySQL, which is one of the few that doesn't support schemas.
|
|
// (Although in practice this means PostgreSQL at the moment, it's possible that
|
|
// in the future support for more databases may be added)
|
|
if ($include_schema && (mb_strpos($dbsys, 'mysql') === false) && isset($db_schema))
|
|
{
|
|
$result = $db_schema . '.' . $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
|
|
function get_table_short_name(string $table) : string
|
|
{
|
|
global $db_tbl_prefix;
|
|
|
|
// Get everything after the last '.', ie strip off any database
|
|
// and schema names
|
|
if (false !== ($pos = mb_strrpos($table, '.')))
|
|
{
|
|
$result = mb_substr($table, $pos + 1);
|
|
}
|
|
else
|
|
{
|
|
$result = $table;
|
|
}
|
|
|
|
// Strip the prefix off the table name
|
|
return mb_substr($result, mb_strlen($db_tbl_prefix));
|
|
}
|
|
|
|
|
|
// Convenience wrapper function to provide access to a DB object for
|
|
// default MRBS database
|
|
function db() : DB
|
|
{
|
|
global $db_persist, $db_host, $db_login, $db_password,
|
|
$db_database, $db_port, $dbsys, $db_options;
|
|
|
|
static $db_obj = null;
|
|
|
|
try
|
|
{
|
|
if (is_null($db_obj))
|
|
{
|
|
throw new \Exception("DB object not yet created");
|
|
}
|
|
// Check to see if the connection is still there. If it isn't - perhaps because it
|
|
// has been timed out, eg by MySQL's wait_timeout - then we throw an exception which
|
|
// will cause us to re-create a connection.
|
|
// (Note that we cannot try a "SELECT 1" query or something similar to check if the
|
|
// connection is still there, because if it is then the query will cause the last insert
|
|
// id to be lost.)
|
|
// TODO: sometimes the symptom of a lost connection is a warning of the form "Packets
|
|
// TODO: out of order. Expected 1 received 0. Packet size=145". Need to work out why
|
|
// TODO: this happens and do something about it.
|
|
if ($db_obj->getAttribute(PDO::ATTR_SERVER_INFO) == 'MySQL server has gone away')
|
|
{
|
|
// On most recent versions of PHP the call to getAttribute() on a lost connection will
|
|
// throw an exception anyway, but just in case it doesn't we'll throw one. See
|
|
// https://stackoverflow.com/questions/21595402/php-pdo-how-to-get-the-current-connection-status
|
|
throw new \Exception('MySQL server has gone away');
|
|
}
|
|
}
|
|
catch (\Exception $e)
|
|
{
|
|
try
|
|
{
|
|
$db_obj = DBFactory::create(
|
|
$dbsys,
|
|
$db_host,
|
|
$db_login,
|
|
$db_password,
|
|
$db_database,
|
|
(bool)$db_persist,
|
|
$db_port,
|
|
$db_options
|
|
);
|
|
}
|
|
catch (\Exception $e)
|
|
{
|
|
trigger_error($e->getMessage(), E_USER_WARNING);
|
|
Errors::fatalError(get_vocab('fatal_db_error'));
|
|
}
|
|
}
|
|
|
|
return $db_obj;
|
|
}
|
|
|
|
|
|
// Returns the db schema version as recorded in the database. If there is no version
|
|
// recorded then returns 0. If $local is true then the local db schema version is returned.
|
|
function db_schema_version(DB $handle, bool $local=false) : int
|
|
{
|
|
if ($handle->table_exists(_tbl('variables')))
|
|
{
|
|
$sql_params = [':variable_name' => ($local) ? 'local_db_version' : 'db_version'];
|
|
$sql = "SELECT variable_content
|
|
FROM " . _tbl('variables') . "
|
|
WHERE variable_name=:variable_name";
|
|
$result = $handle->query1($sql, $sql_params);
|
|
}
|
|
else
|
|
{
|
|
// Default version is 0, before we had schema versions
|
|
$result = 0;
|
|
}
|
|
|
|
return max($result, 0);
|
|
}
|