Initial project files: BESCMS full source

This commit is contained in:
bes
2026-08-13 23:37:46 +08:00
parent fa6cddb540
commit 2e26f85723
2166 changed files with 396625 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
<?php
+284
View File
@@ -0,0 +1,284 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Config;
use CodeIgniter\Autoloader\FileLocatorInterface;
use CodeIgniter\Exceptions\ConfigException;
use CodeIgniter\Exceptions\RuntimeException;
use Config\Encryption;
use Config\Modules;
use ReflectionClass;
use ReflectionException;
/**
* Class BaseConfig
*
* Not intended to be used on its own, this class will attempt to
* automatically populate the child class' properties with values
* from the environment.
*
* These can be set within the .env file.
*
* @phpstan-consistent-constructor
* @see \CodeIgniter\Config\BaseConfigTest
*/
class BaseConfig
{
/**
* An optional array of classes that will act as Registrars
* for rapidly setting config class properties.
*
* @var array
*/
public static $registrars = [];
/**
* Whether to override properties by Env vars and Registrars.
*/
public static $override = true;
/**
* Has module discovery completed?
*
* @var bool
*/
protected static $didDiscovery = false;
/**
* Is module discovery running or not?
*/
protected static $discovering = false;
/**
* The processing Registrar file for error message.
*/
protected static $registrarFile = '';
/**
* The modules configuration.
*
* @var Modules|null
*/
protected static $moduleConfig;
public static function __set_state(array $array)
{
static::$override = false;
$obj = new static();
static::$override = true;
$properties = array_keys(get_object_vars($obj));
foreach ($properties as $property) {
$obj->{$property} = $array[$property];
}
return $obj;
}
/**
* @internal For testing purposes only.
* @testTag
*/
public static function setModules(Modules $modules): void
{
static::$moduleConfig = $modules;
}
/**
* @internal For testing purposes only.
* @testTag
*/
public static function reset(): void
{
static::$registrars = [];
static::$override = true;
static::$didDiscovery = false;
static::$moduleConfig = null;
}
/**
* Will attempt to get environment variables with names
* that match the properties of the child class.
*
* The "shortPrefix" is the lowercase-only config class name.
*/
public function __construct()
{
if (! static::$override) {
return;
}
$this->registerProperties();
$properties = array_keys(get_object_vars($this));
$prefix = static::class;
$slashAt = strrpos($prefix, '\\');
$shortPrefix = strtolower(substr($prefix, $slashAt === false ? 0 : $slashAt + 1));
foreach ($properties as $property) {
$this->initEnvValue($this->{$property}, $property, $prefix, $shortPrefix);
if ($this instanceof Encryption && $property === 'key') {
if (str_starts_with($this->{$property}, 'hex2bin:')) {
// Handle hex2bin prefix
$this->{$property} = hex2bin(substr($this->{$property}, 8));
} elseif (str_starts_with($this->{$property}, 'base64:')) {
// Handle base64 prefix
$this->{$property} = base64_decode(substr($this->{$property}, 7), true);
}
}
}
}
/**
* Initialization an environment-specific configuration setting
*
* @param array|bool|float|int|string|null $property
*
* @return void
*/
protected function initEnvValue(&$property, string $name, string $prefix, string $shortPrefix)
{
if (is_array($property)) {
foreach (array_keys($property) as $key) {
$this->initEnvValue($property[$key], "{$name}.{$key}", $prefix, $shortPrefix);
}
} elseif (($value = $this->getEnvValue($name, $prefix, $shortPrefix)) !== false && $value !== null) {
if ($value === 'false') {
$value = false;
} elseif ($value === 'true') {
$value = true;
}
if (is_bool($value)) {
$property = $value;
return;
}
$value = trim($value, '\'"');
if (is_int($property)) {
$value = (int) $value;
} elseif (is_float($property)) {
$value = (float) $value;
}
// If the default value of the property is `null` and the type is not
// `string`, TypeError will happen.
// So cannot set `declare(strict_types=1)` in this file.
$property = $value;
}
}
/**
* Retrieve an environment-specific configuration setting
*
* @return string|null
*/
protected function getEnvValue(string $property, string $prefix, string $shortPrefix)
{
$shortPrefix = ltrim($shortPrefix, '\\');
$underscoreProperty = str_replace('.', '_', $property);
switch (true) {
case array_key_exists("{$shortPrefix}.{$property}", $_ENV):
return $_ENV["{$shortPrefix}.{$property}"];
case array_key_exists("{$shortPrefix}_{$underscoreProperty}", $_ENV):
return $_ENV["{$shortPrefix}_{$underscoreProperty}"];
case array_key_exists("{$shortPrefix}.{$property}", $_SERVER):
return $_SERVER["{$shortPrefix}.{$property}"];
case array_key_exists("{$shortPrefix}_{$underscoreProperty}", $_SERVER):
return $_SERVER["{$shortPrefix}_{$underscoreProperty}"];
case array_key_exists("{$prefix}.{$property}", $_ENV):
return $_ENV["{$prefix}.{$property}"];
case array_key_exists("{$prefix}_{$underscoreProperty}", $_ENV):
return $_ENV["{$prefix}_{$underscoreProperty}"];
case array_key_exists("{$prefix}.{$property}", $_SERVER):
return $_SERVER["{$prefix}.{$property}"];
case array_key_exists("{$prefix}_{$underscoreProperty}", $_SERVER):
return $_SERVER["{$prefix}_{$underscoreProperty}"];
default:
$value = getenv("{$shortPrefix}.{$property}");
$value = $value === false ? getenv("{$shortPrefix}_{$underscoreProperty}") : $value;
$value = $value === false ? getenv("{$prefix}.{$property}") : $value;
$value = $value === false ? getenv("{$prefix}_{$underscoreProperty}") : $value;
return $value === false ? null : $value;
}
}
/**
* Provides external libraries a simple way to register one or more
* options into a config file.
*
* @return void
*
* @throws ReflectionException
*/
protected function registerProperties()
{
if (! static::$didDiscovery) {
// Discovery must be completed before the first instantiation of any Config class.
if (static::$discovering) {
throw new ConfigException(
'During Auto-Discovery of Registrars,'
. ' "' . static::class . '" executes Auto-Discovery again.'
. ' "' . clean_path(static::$registrarFile) . '" seems to have bad code.'
);
}
static::$discovering = true;
static::$didDiscovery = true;
static::$discovering = false;
}
$shortName = (new ReflectionClass($this))->getShortName();
// Check the registrar class for a method named after this class' shortName
foreach (static::$registrars as $callable) {
// ignore non-applicable registrars
if (! method_exists($callable, $shortName)) {
continue; // @codeCoverageIgnore
}
$properties = $callable::$shortName();
if (! is_array($properties)) {
throw new RuntimeException('Registrars must return an array of properties and their values.');
}
foreach ($properties as $property => $value) {
if (isset($this->{$property}) && is_array($this->{$property}) && is_array($value)) {
$this->{$property} = array_merge($this->{$property}, $value);
} else {
$this->{$property} = $value;
}
}
}
}
}
+405
View File
@@ -0,0 +1,405 @@
<?php
declare(strict_types=1);
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Config;
use CodeIgniter\Autoloader\Autoloader;
use CodeIgniter\Autoloader\FileLocator;
use CodeIgniter\Autoloader\FileLocatorCached;
use CodeIgniter\Autoloader\FileLocatorInterface;
use CodeIgniter\Cache\CacheInterface;
use CodeIgniter\Cache\ResponseCache;
use CodeIgniter\CLI\Commands;
use CodeIgniter\CodeIgniter;
use CodeIgniter\Database\ConnectionInterface;
use CodeIgniter\Database\MigrationRunner;
use CodeIgniter\Debug\Exceptions;
use CodeIgniter\Debug\Iterator;
use CodeIgniter\Debug\Timer;
use CodeIgniter\Debug\Toolbar;
use CodeIgniter\Email\Email;
use CodeIgniter\Encryption\EncrypterInterface;
use CodeIgniter\Exceptions\InvalidArgumentException;
use CodeIgniter\Filters\Filters;
use CodeIgniter\Format\Format;
use CodeIgniter\Honeypot\Honeypot;
use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\ContentSecurityPolicy;
use CodeIgniter\HTTP\CURLRequest;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\Negotiate;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\Request;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\SiteURIFactory;
use CodeIgniter\HTTP\URI;
use CodeIgniter\Images\Handlers\BaseHandler;
use CodeIgniter\Language\Language;
use CodeIgniter\Log\Logger;
use CodeIgniter\Pager\Pager;
use CodeIgniter\Router\RouteCollection;
use CodeIgniter\Router\RouteCollectionInterface;
use CodeIgniter\Router\Router;
use CodeIgniter\Security\Security;
use CodeIgniter\Session\Session;
use CodeIgniter\Superglobals;
use CodeIgniter\Throttle\Throttler;
use CodeIgniter\Typography\Typography;
use CodeIgniter\Validation\ValidationInterface;
use CodeIgniter\View\Cell;
use CodeIgniter\View\Parser;
use CodeIgniter\View\RendererInterface;
use CodeIgniter\View\View;
use Config\App;
use Config\Autoload;
use Config\Cache;
use Config\ContentSecurityPolicy as CSPConfig;
use Config\Encryption;
use Config\Exceptions as ConfigExceptions;
use Config\Filters as ConfigFilters;
use Config\Format as ConfigFormat;
use Config\Honeypot as ConfigHoneyPot;
use Config\Images;
use Config\Migrations;
use Config\Modules;
use Config\Optimize;
use Config\Pager as ConfigPager;
use CodeIgniter\Config\Services as AppServices;
use Config\Session as ConfigSession;
use Config\Toolbar as ConfigToolbar;
use Config\Validation as ConfigValidation;
use Config\View as ConfigView;
/**
* Services Configuration file.
*
* Services are simply other classes/libraries that the system uses
* to do its job. This is used by CodeIgniter to allow the core of the
* framework to be swapped out easily without affecting the usage within
* the rest of your application.
*
* This is used in place of a Dependency Injection container primarily
* due to its simplicity, which allows a better long-term maintenance
* of the applications built on top of CodeIgniter. A bonus side-effect
* is that IDEs are able to determine what class you are calling
* whereas with DI Containers there usually isn't a way for them to do this.
*
* Warning: To allow overrides by service providers do not use static calls,
* instead call out to \Config\Services (imported as AppServices).
*
* @see http://blog.ircmaxell.com/2015/11/simple-easy-risk-and-change.html
* @see http://www.infoq.com/presentations/Simple-Made-Easy
*
* @method static CacheInterface cache(Cache $config = null, $getShared = true)
* @method static CLIRequest clirequest(App $config = null, $getShared = true)
* @method static CodeIgniter codeigniter(App $config = null, $getShared = true)
* @method static Commands commands($getShared = true)
* @method static void createRequest(App $config, bool $isCli = false)
* @method static ContentSecurityPolicy csp(CSPConfig $config = null, $getShared = true)
* @method static CURLRequest curlrequest($options = [], ResponseInterface $response = null, App $config = null, $getShared = true)
* @method static Email email($config = null, $getShared = true)
* @method static EncrypterInterface encrypter(Encryption $config = null, $getShared = false)
* @method static Exceptions exceptions(ConfigExceptions $config = null, $getShared = true)
* @method static Filters filters(ConfigFilters $config = null, $getShared = true)
* @method static Format format(ConfigFormat $config = null, $getShared = true)
* @method static Honeypot honeypot(ConfigHoneyPot $config = null, $getShared = true)
* @method static BaseHandler image($handler = null, Images $config = null, $getShared = true)
* @method static IncomingRequest incomingrequest(?App $config = null, bool $getShared = true)
* @method static Iterator iterator($getShared = true)
* @method static Language language($locale = null, $getShared = true)
* @method static Logger logger($getShared = true)
* @method static MigrationRunner migrations(Migrations $config = null, ConnectionInterface $db = null, $getShared = true)
* @method static Negotiate negotiator(RequestInterface $request = null, $getShared = true)
* @method static Pager pager(ConfigPager $config = null, RendererInterface $view = null, $getShared = true)
* @method static Parser parser($viewPath = null, ConfigView $config = null, $getShared = true)
* @method static RedirectResponse redirectresponse(App $config = null, $getShared = true)
* @method static View renderer($viewPath = null, ConfigView $config = null, $getShared = true)
* @method static IncomingRequest|CLIRequest request(App $config = null, $getShared = true)
* @method static ResponseInterface response(App $config = null, $getShared = true)
* @method static ResponseCache responsecache(?Cache $config = null, ?CacheInterface $cache = null, bool $getShared = true)
* @method static Router router(RouteCollectionInterface $routes = null, Request $request = null, $getShared = true)
* @method static RouteCollection routes($getShared = true)
* @method static Security security(App $config = null, $getShared = true)
* @method static Session session(ConfigSession $config = null, $getShared = true)
* @method static SiteURIFactory siteurifactory(App $config = null, Superglobals $superglobals = null, $getShared = true)
* @method static Superglobals superglobals(array $server = null, array $get = null, bool $getShared = true)
* @method static Throttler throttler($getShared = true)
* @method static Timer timer($getShared = true)
* @method static Toolbar toolbar(ConfigToolbar $config = null, $getShared = true)
* @method static Typography typography($getShared = true)
* @method static URI uri($uri = null, $getShared = true)
* @method static ValidationInterface validation(ConfigValidation $config = null, $getShared = true)
* @method static Cell viewcell($getShared = true)
*/
class BaseService
{
/**
* Cache for instance of any services that
* have been requested as a "shared" instance.
* Keys should be lowercase service names.
*
* @var array<string, object> [key => instance]
*/
protected static $instances = [];
/**
* Factory method list.
*
* @var array<string, (callable(mixed ...$params): object)> [key => callable]
*/
protected static array $factories = [];
/**
* Mock objects for testing which are returned if exist.
*
* @var array<string, object> [key => instance]
*/
protected static $mocks = [];
/**
* Have we already discovered other Services?
*
* @var bool
*/
protected static $discovered = false;
/**
* A cache of other service classes we've found.
*
* @var array
*
* @deprecated 4.5.0 No longer used.
*/
protected static $services = [];
/**
* A cache of the names of services classes found.
*
* @var list<string>
*/
private static array $serviceNames = [];
/**
* Simple method to get an entry fast.
*
* @param string $key Identifier of the entry to look for.
*
* @return object|null Entry.
*/
public static function get(string $key): ?object
{
return static::$instances[$key] ?? static::__callStatic($key, []);
}
/**
* Sets an entry.
*
* @param string $key Identifier of the entry.
*/
public static function set(string $key, object $value): void
{
if (isset(static::$instances[$key])) {
throw new InvalidArgumentException('The entry for "' . $key . '" is already set.');
}
static::$instances[$key] = $value;
}
/**
* Overrides an existing entry.
*
* @param string $key Identifier of the entry.
*/
public static function override(string $key, object $value): void
{
static::$instances[$key] = $value;
}
/**
* Returns a shared instance of any of the class' services.
*
* $key must be a name matching a service.
*
* @param array|bool|float|int|object|string|null ...$params
*
* @return object
*/
protected static function getSharedInstance(string $key, ...$params)
{
$key = strtolower($key);
// Returns mock if exists
if (isset(static::$mocks[$key])) {
return static::$mocks[$key];
}
if (! isset(static::$instances[$key])) {
// Make sure $getShared is false
$params[] = false;
static::$instances[$key] = AppServices::$key(...$params);
}
return static::$instances[$key];
}
/**
* The Autoloader class is the central class that handles our
* spl_autoload_register method, and helper methods.
*
* @return Autoloader
*/
public static function autoloader(bool $getShared = true)
{
if ($getShared) {
if (empty(static::$instances['autoloader'])) {
static::$instances['autoloader'] = new Autoloader();
}
return static::$instances['autoloader'];
}
return new Autoloader();
}
/**
* The file locator provides utility methods for looking for non-classes
* within namespaced folders, as well as convenience methods for
* loading 'helpers', and 'libraries'.
*
* @return FileLocatorInterface
*/
public static function locator(bool $getShared = true)
{
if ($getShared) {
if (empty(static::$instances['locator'])) {
$cacheEnabled = class_exists(Optimize::class)
&& (new Optimize())->locatorCacheEnabled;
if ($cacheEnabled) {
static::$instances['locator'] = new FileLocatorCached(new FileLocator(static::autoloader()));
} else {
static::$instances['locator'] = new FileLocator(static::autoloader());
}
}
return static::$mocks['locator'] ?? static::$instances['locator'];
}
return new FileLocator(static::autoloader());
}
/**
* Provides the ability to perform case-insensitive calling of service
* names.
*
* @return object|null
*/
public static function __callStatic(string $name, array $arguments)
{
if (isset(static::$factories[$name])) {
return static::$factories[$name](...$arguments);
}
$service = static::serviceExists($name);
if ($service === null) {
return null;
}
return $service::$name(...$arguments);
}
/**
* Check if the requested service is defined and return the declaring
* class. Return null if not found.
*/
public static function serviceExists(string $name): ?string
{
static::buildServicesCache();
$services = array_merge(self::$serviceNames, [Services::class]);
$name = strtolower($name);
foreach ($services as $service) {
if (method_exists($service, $name)) {
static::$factories[$name] = [$service, $name];
return $service;
}
}
return null;
}
/**
* Reset shared instances and mocks for testing.
*
* @return void
*
* @testTag only available to test code
*/
public static function reset(bool $initAutoloader = true)
{
static::$mocks = [];
static::$instances = [];
static::$factories = [];
if ($initAutoloader) {
static::autoloader()->initialize(new Autoload(), new Modules());
}
}
/**
* Resets any mock and shared instances for a single service.
*
* @return void
*
* @testTag only available to test code
*/
public static function resetSingle(string $name)
{
$name = strtolower($name);
unset(static::$mocks[$name], static::$instances[$name]);
}
/**
* Inject mock object for testing.
*
* @param object $mock
*
* @return void
*
* @testTag only available to test code
*/
public static function injectMock(string $name, $mock)
{
static::$instances[$name] = $mock;
static::$mocks[strtolower($name)] = $mock;
}
/**
* Resets the service cache.
*/
public static function resetServicesCache(): void
{
self::$serviceNames = [];
static::$discovered = false;
}
protected static function buildServicesCache(): void
{
}
}
+191
View File
@@ -0,0 +1,191 @@
<?php namespace Config;
/**
* {{www.xunruicms.com}}
* {{迅睿内容管理框架系统}}
* 本文件是框架系统文件,二次开发时不可以修改本文件
**/
use CodeIgniter\Cache\CacheInterface;
use CodeIgniter\Cache\Handlers\DummyHandler;
use CodeIgniter\Cache\Handlers\FileHandler;
use CodeIgniter\Cache\Handlers\MemcachedHandler;
use CodeIgniter\Cache\Handlers\PredisHandler;
use CodeIgniter\Cache\Handlers\RedisHandler;
use CodeIgniter\Cache\Handlers\WincacheHandler;
use CodeIgniter\Config\BaseConfig;
class Cache extends BaseConfig
{
/*
|--------------------------------------------------------------------------
| Primary Handler
|--------------------------------------------------------------------------
|
| The name of the preferred handler that should be used. If for some reason
| it is not available, the $backupHandler will be used in its place.
|
*/
public $handler = SYS_CACHE_TYPE == 1 ? 'memcached' : (SYS_CACHE_TYPE == 2 ? 'redis' : 'file');
/*
|--------------------------------------------------------------------------
| Backup Handler
|--------------------------------------------------------------------------
|
| The name of the handler that will be used in case the first one is
| unreachable. Often, 'file' is used here since the filesystem is
| always available, though that's not always practical for the app.
|
*/
public $backupHandler = 'file';
/*
|--------------------------------------------------------------------------
| Cache Directory Path
|--------------------------------------------------------------------------
|
| The path to where cache files should be stored, if using a file-based
| system.
|
*/
public $storePath = WRITEPATH.'file/';
/*
|--------------------------------------------------------------------------
| Cache Include Query String
|--------------------------------------------------------------------------
|
| Whether to take the URL query string into consideration when generating
| output cache files. Valid options are:
|
| false = Disabled
| true = Enabled, take all query parameters into account.
| Please be aware that this may result in numerous cache
| files generated for the same page over and over again.
| array('q') = Enabled, but only take into account the specified list
| of query parameters.
|
*/
public $cacheQueryString = false;
/*
|--------------------------------------------------------------------------
| Key Prefix
|--------------------------------------------------------------------------
|
| This string is added to all cache item names to help avoid collisions
| if you run multiple applications with the same cache engine.
|
*/
public string $prefix = '';
/**
* --------------------------------------------------------------------------
* Default TTL
* --------------------------------------------------------------------------
*
* The default number of seconds to save items when none is specified.
*
* WARNING: This is not used by framework handlers where 60 seconds is
* hard-coded, but may be useful to projects and modules. This will replace
* the hard-coded value in a future release.
*
* @var integer
*/
public int $ttl = 600;
/**
* --------------------------------------------------------------------------
* Reserved Characters
* --------------------------------------------------------------------------
*
* A string of reserved characters that will not be allowed in keys or tags.
* Strings that violate this restriction will cause handlers to throw.
* Default: {}()/\@:
* Note: The default set is required for PSR-6 compliance.
*
* @var string
*/
public string $reservedCharacters = '{}()/\@:';
/**
* --------------------------------------------------------------------------
* File settings
* --------------------------------------------------------------------------
* Your file storage preferences can be specified below, if you are using
* the File driver.
*
* @var array<string, int|string|null>
*/
public array $file = [
'storePath' => WRITEPATH . 'file/',
'mode' => 0640,
];
/*
| -------------------------------------------------------------------------
| Memcached settings
| -------------------------------------------------------------------------
| Your Memcached servers can be specified below, if you are using
| the Memcached drivers.
|
| See: https://codeigniter.com/user_guide/libraries/caching.html#memcached
|
*/
public array $memcached = [
'host' => '127.0.0.1',
'port' => 11211,
'weight' => 1,
'raw' => false,
];
/*
| -------------------------------------------------------------------------
| Redis settings
| -------------------------------------------------------------------------
| Your Redis server can be specified below, if you are using
| the Redis or Predis drivers.
|
*/
public array $redis = [
'host' => '127.0.0.1',
'password' => null,
'port' => 6379,
'timeout' => 0,
'database' => 0,
];
/*
|--------------------------------------------------------------------------
| Available Cache Handlers
|--------------------------------------------------------------------------
|
| This is an array of cache engine alias' and class names. Only engines
| that are listed here are allowed to be used.
|
*/
public array $validHandlers = [
'dummy' => DummyHandler::class,
'file' => FileHandler::class,
'memcached' => MemcachedHandler::class,
'predis' => PredisHandler::class,
'redis' => RedisHandler::class,
'wincache' => WincacheHandler::class,
];
public function __construct()
{
parent::__construct();
if (is_file(CONFIGPATH.'redis.php')) {
$this->redis = require CONFIGPATH.'redis.php';
} elseif (is_file(ROOTPATH.'config/redis.php')) {
$this->redis = require ROOTPATH.'config/redis.php';
}
if (is_file(CONFIGPATH.'memcached.php')) {
$this->memcached = require CONFIGPATH.'memcached.php';
} elseif (is_file(ROOTPATH.'config/memcached.php')) {
$this->memcached = require ROOTPATH.'config/memcached.php';
}
$this->prefix = substr(SYS_KEY, 0, 10).'-';
}
}
+142
View File
@@ -0,0 +1,142 @@
<?php namespace Config;
/**
* {{www.xunruicms.com}}
* {{迅睿内容管理框架系统}}
* 本文件是框架系统文件,二次开发时不可以修改本文件
**/
use CodeIgniter\Database\Config;
/**
* Database Configuration
*/
class Database extends Config
{
/**
* The directory that holds the Migrations
* and Seeds directories.
* @var string
*/
public $filesPath = WRITEPATH.'database/';
/**
* Lets you choose which connection group to
* use if no other is specified.
*
* @var string
*/
public $defaultGroup = 'default';
/**
* The default database connection.
*
* @var array
*/
public $default = [
'DSN' => '',
'hostname' => 'localhost',
'username' => '',
'password' => '',
'database' => '',
'DBDriver' => 'MySQLi',
'DBPrefix' => '',
'pConnect' => false,
'DBDebug' => true,
'cacheOn' => true,
'cacheDir' => WRITEPATH.'database/',
'charset' => 'utf8mb4',
'DBCollat' => 'utf8mb4_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'foreignKeys' => true,
'numberNative' => false,
'failover' => []
];
public $db1 = [];
public $db2 = [];
public $db3 = [];
public $db4 = [];
public $db5 = [];
public $db6 = [];
public $db7 = [];
public $db8 = [];
public $db9 = [];
private $mykey = 1;
private $mydb = [];
//--------------------------------------------------------------------
public function __construct()
{
parent::__construct();
if (!is_file(CONFIGPATH.'database.php')) {
return $this;
}
$db = [];
require CONFIGPATH.'database.php';
if (isset($db['failover']) && $db['failover']) {
// 备用库
$this->default['failover'] = $db['failover'];
unset($db['failover']);
}
foreach ($this->default as $p => $t) {
foreach ($db as $name => $v) {
if (isset($this->$name)) {
// 默认库
$this->$name[$p] = isset($v[$p]) ? $v[$p] : $t;
} else {
// 自定义库
$key = $this->_get_key($name);
if ($key) {
$this->$key[$p] = isset($v[$p]) ? $v[$p] : $t;
}
}
}
}
// 判断数据库名称的规范性(SQLite3 为文件路径,允许 .db 等扩展名)
$driver = isset($this->default['DBDriver']) ? (string) $this->default['DBDriver'] : 'MySQLi';
if (strcasecmp($driver, 'SQLite3') !== 0) {
if (is_numeric($this->default['database'])) {
exit('数据库名称不能是数字');
} elseif (strpos((string) $this->default['database'], '.') !== false) {
exit('数据库名称不能存在.号');
}
} else {
// SQLite 默认等待写锁,降低 database is locked 概率
if (!isset($this->default['busyTimeout'])) {
$this->default['busyTimeout'] = 10000;
}
}
}
private function _get_key($name) {
if (isset($this->mydb[$name])) {
return $this->mydb[$name];
} else {
$this->mydb[$name] = 'db'.$this->mykey;
$this->mykey++;
}
return $this->mydb[$name];
}
public function get_group($name) {
if (isset($this->mydb[$name])) {
return $this->mydb[$name];
}
return 'default';
}
//--------------------------------------------------------------------
}
+1
View File
@@ -0,0 +1 @@
<?php
+106
View File
@@ -0,0 +1,106 @@
<?php namespace Config;
/**
* {{www.xunruicms.com}}
* {{迅睿内容管理框架系统}}
* 本文件是框架系统文件,二次开发时不可以修改本文件
**/
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Debug\ExceptionHandler;
use CodeIgniter\Debug\ExceptionHandlerInterface;
use Throwable;
/**
* Setup how the exception handler works.
*/
class Exceptions extends BaseConfig
{
/**
* --------------------------------------------------------------------------
* LOG EXCEPTIONS?
* --------------------------------------------------------------------------
* If true, then exceptions will be logged
* through Services::Log.
*
* Default: true
*/
public bool $log = true;
/**
* --------------------------------------------------------------------------
* DO NOT LOG STATUS CODES
* --------------------------------------------------------------------------
* Any status codes here will NOT be logged if logging is turned on.
* By default, only 404 (Page Not Found) exceptions are ignored.
*/
public array $ignoreCodes = [404];
/**
* --------------------------------------------------------------------------
* Error Views Path
* --------------------------------------------------------------------------
* This is the path to the directory that contains the 'cli' and 'html'
* directories that hold the views used to generate errors.
*
* Default: APPPATH.'Views/errors'
*/
public $errorViewPath = FRAMEPATH . 'Exceptions/Views';
/**
* --------------------------------------------------------------------------
* HIDE FROM DEBUG TRACE
* --------------------------------------------------------------------------
* Any data that you would like to hide from the debug trace.
* In order to specify 2 levels, use "/" to separate.
* ex. ['server', 'setup/password', 'secret_token']
*/
public array $sensitiveDataInTrace = [];
/**
* --------------------------------------------------------------------------
* LOG DEPRECATIONS INSTEAD OF THROWING?
* --------------------------------------------------------------------------
* By default, CodeIgniter converts deprecations into exceptions. Also,
* starting in PHP 8.1 will cause a lot of deprecated usage warnings.
* Use this option to temporarily cease the warnings and instead log those.
* This option also works for user deprecations.
*/
public bool $logDeprecations = true;
/**
* --------------------------------------------------------------------------
* LOG LEVEL THRESHOLD FOR DEPRECATIONS
* --------------------------------------------------------------------------
* If `$logDeprecations` is set to `true`, this sets the log level
* to which the deprecation will be logged. This should be one of the log
* levels recognized by PSR-3.
*
* The related `Config\Logger::$threshold` should be adjusted, if needed,
* to capture logging the deprecations.
*/
public string $deprecationLogLevel = 'warning';
/*
* DEFINE THE HANDLERS USED
* --------------------------------------------------------------------------
* Given the HTTP status code, returns exception handler that
* should be used to deal with this error. By default, it will run CodeIgniter's
* default handler and display the error information in the expected format
* for CLI, HTTP, or AJAX requests, as determined by is_cli() and the expected
* response format.
*
* Custom handlers can be returned if you want to handle one or more specific
* error codes yourself like:
*
* if (in_array($statusCode, [400, 404, 500])) {
* return new \App\Libraries\MyExceptionHandler();
* }
* if ($exception instanceOf PageNotFoundException) {
* return new \App\Libraries\MyExceptionHandler();
* }
*/
public function handler(int $statusCode, Throwable $exception): ExceptionHandlerInterface
{
return new ExceptionHandler($this);
}
}
+539
View File
@@ -0,0 +1,539 @@
<?php
declare(strict_types=1);
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Config;
use CodeIgniter\Autoloader\FileLocatorInterface;
use CodeIgniter\Database\ConnectionInterface;
use CodeIgniter\Exceptions\InvalidArgumentException;
use CodeIgniter\Model;
/**
* Factories for creating instances.
*
* Factories allow dynamic loading of components by their path
* and name. The "shared instance" implementation provides a
* large performance boost and helps keep code clean of lengthy
* instantiation checks.
*
* @method static BaseConfig|null config(...$arguments)
* @method static Model|null models(string $alias, array $options = [], ?ConnectionInterface &$conn = null)
* @see \CodeIgniter\Config\FactoriesTest
*/
final class Factories
{
/**
* Store of component-specific options, usually
* from CodeIgniter\Config\Factory.
*
* @var array<string, array<string, bool|string|null>>
*/
private static $options = [];
/**
* Explicit options for the Config
* component to prevent logic loops.
*
* @var array<string, bool|string|null>
*/
private static $configOptions = [
'component' => 'config',
'path' => 'Config',
'instanceOf' => null,
'getShared' => true,
'preferApp' => true,
];
/**
* Mapping of class aliases to their true Fully Qualified Class Name (FQCN).
*
* Class aliases can be:
* - FQCN. E.g., 'App\Lib\SomeLib'
* - short classname. E.g., 'SomeLib'
* - short classname with sub-directories. E.g., 'Sub/SomeLib'
*
* [component => [alias => FQCN]]
*
* @var array<string, array<string, class-string>>
*/
private static $aliases = [];
/**
* Store for instances of any component that
* has been requested as "shared".
*
* A multi-dimensional array with components as
* keys to the array of name-indexed instances.
*
* [component => [FQCN => instance]]
*
* @var array<string, array<class-string, object>>
*/
private static $instances = [];
/**
* Whether the component instances are updated?
*
* @var array<string, true> [component => true]
*
* @internal For caching only
*/
private static $updated = [];
/**
* Define the class to load. You can *override* the concrete class.
*
* @param string $component Lowercase, plural component name
* @param string $alias Class alias. See the $aliases property.
* @param class-string $classname FQCN to be loaded
*/
public static function define(string $component, string $alias, string $classname): void
{
$component = strtolower($component);
if (isset(self::$aliases[$component][$alias])) {
if (self::$aliases[$component][$alias] === $classname) {
return;
}
$message = 'Already defined in Factories: ' . $component . ' ' . $alias . ' -> ' . self::$aliases[$component][$alias];
throw new InvalidArgumentException($message);
}
if (! class_exists($classname)) {
throw new InvalidArgumentException('No such class: ' . $classname);
}
// Force a configuration to exist for this component.
// Otherwise, getOptions() will reset the component.
self::getOptions($component);
self::$aliases[$component][$alias] = $classname;
self::$updated[$component] = true;
}
/**
* Loads instances based on the method component name. Either
* creates a new instance or returns an existing shared instance.
*
* @return object|null
*/
public static function __callStatic(string $component, array $arguments)
{
$component = strtolower($component);
// First argument is the class alias, second is options
$alias = trim(array_shift($arguments), '\\ ');
$options = array_shift($arguments) ?? [];
// Determine the component-specific options
$options = array_merge(self::getOptions($component), $options);
if (! $options['getShared']) {
if (isset(self::$aliases[$options['component']][$alias])) {
$class = self::$aliases[$options['component']][$alias];
return new $class(...$arguments);
}
// Try to locate the class
$class = self::locateClass($options, $alias);
if ($class !== null) {
return new $class(...$arguments);
}
return null;
}
// Check for an existing definition
$instance = self::getDefinedInstance($options, $alias, $arguments);
if ($instance !== null) {
return $instance;
}
// Try to locate the class
if (($class = self::locateClass($options, $alias)) === null) {
return null;
}
self::createInstance($options['component'], $class, $arguments);
self::setAlias($options['component'], $alias, $class);
return self::$instances[$options['component']][$class];
}
/**
* Simple method to get the shared instance fast.
*/
public static function get(string $component, string $alias): ?object
{
if (isset(self::$aliases[$component][$alias])) {
$class = self::$aliases[$component][$alias];
if (isset(self::$instances[$component][$class])) {
return self::$instances[$component][$class];
}
}
return self::__callStatic($component, [$alias]);
}
/**
* Gets the defined instance. If not exists, creates new one.
*
* @return object|null
*/
private static function getDefinedInstance(array $options, string $alias, array $arguments)
{
// The alias is already defined.
if (isset(self::$aliases[$options['component']][$alias])) {
$class = self::$aliases[$options['component']][$alias];
// Need to verify if the shared instance matches the request
if (self::verifyInstanceOf($options, $class)) {
// Check for an existing instance
if (isset(self::$instances[$options['component']][$class])) {
return self::$instances[$options['component']][$class];
}
self::createInstance($options['component'], $class, $arguments);
return self::$instances[$options['component']][$class];
}
}
// Try to locate the class
if (($class = self::locateClass($options, $alias)) === null) {
return null;
}
// Check for an existing instance for the class
if (isset(self::$instances[$options['component']][$class])) {
self::setAlias($options['component'], $alias, $class);
return self::$instances[$options['component']][$class];
}
return null;
}
/**
* Creates the shared instance.
*/
private static function createInstance(string $component, string $class, array $arguments): void
{
self::$instances[$component][$class] = new $class(...$arguments);
self::$updated[$component] = true;
}
/**
* Sets alias
*/
private static function setAlias(string $component, string $alias, string $class): void
{
self::$aliases[$component][$alias] = $class;
self::$updated[$component] = true;
// If a short classname is specified, also register FQCN to share the instance.
if (! isset(self::$aliases[$component][$class]) && ! self::isNamespaced($alias)) {
self::$aliases[$component][$class] = $class;
}
}
/**
* Is the component Config?
*
* @param string $component Lowercase, plural component name
*/
private static function isConfig(string $component): bool
{
return $component === 'config';
}
/**
* Finds a component class
*
* @param array $options The array of component-specific directives
* @param string $alias Class alias. See the $aliases property.
*/
private static function locateClass(array $options, string $alias): ?string
{
// Check for low-hanging fruit
if (
class_exists($alias, false)
&& self::verifyPreferApp($options, $alias)
&& self::verifyInstanceOf($options, $alias)
) {
return $alias;
}
// Determine the relative class names we need
$basename = self::getBasename($alias);
$appname = self::isConfig($options['component'])
? 'Config\\' . $basename
: rtrim(APP_NAMESPACE, '\\') . '\\' . $options['path'] . '\\' . $basename;
// If an App version was requested then see if it verifies
if (
// preferApp is used only for no namespaced class.
! self::isNamespaced($alias)
&& $options['preferApp'] && class_exists($appname)
&& self::verifyInstanceOf($options, $alias)
) {
return $appname;
}
// If we have ruled out an App version and the class exists then try it
if (class_exists($alias) && self::verifyInstanceOf($options, $alias)) {
return $alias;
}
return null;
}
/**
* Is the class alias namespaced or not?
*
* @param string $alias Class alias. See the $aliases property.
*/
private static function isNamespaced(string $alias): bool
{
return str_contains($alias, '\\');
}
/**
* Verifies that a class & config satisfy the "preferApp" option
*
* @param array $options The array of component-specific directives
* @param string $alias Class alias. See the $aliases property.
*/
private static function verifyPreferApp(array $options, string $alias): bool
{
// Anything without that restriction passes
if (! $options['preferApp']) {
return true;
}
// Special case for Config since its App namespace is actually \Config
if (self::isConfig($options['component'])) {
return str_starts_with($alias, 'Config');
}
return str_starts_with($alias, APP_NAMESPACE);
}
/**
* Verifies that a class & config satisfy the "instanceOf" option
*
* @param array $options The array of component-specific directives
* @param string $alias Class alias. See the $aliases property.
*/
private static function verifyInstanceOf(array $options, string $alias): bool
{
// Anything without that restriction passes
if (! $options['instanceOf']) {
return true;
}
return is_a($alias, $options['instanceOf'], true);
}
/**
* Returns the component-specific configuration
*
* @param string $component Lowercase, plural component name
*
* @return array<string, bool|string|null>
*
* @internal For testing only
* @testTag
*/
public static function getOptions(string $component): array
{
$component = strtolower($component);
// Check for a stored version
if (isset(self::$options[$component])) {
return self::$options[$component];
}
$values = self::isConfig($component)
// Handle Config as a special case to prevent logic loops
? self::$configOptions
// Load values from the best Factory configuration (will include Registrars)
: config('Factory')->{$component} ?? [];
// The setOptions() reset the component. So getOptions() may reset
// the component.
return self::setOptions($component, $values);
}
/**
* Normalizes, stores, and returns the configuration for a specific component
*
* @param string $component Lowercase, plural component name
* @param array $values option values
*
* @return array<string, bool|string|null> The result after applying defaults and normalization
*/
public static function setOptions(string $component, array $values): array
{
$component = strtolower($component);
// Allow the config to replace the component name, to support "aliases"
$values['component'] = strtolower($values['component'] ?? $component);
// Reset this component so instances can be rediscovered with the updated config
self::reset($values['component']);
// If no path was available then use the component
$values['path'] = trim($values['path'] ?? ucfirst($values['component']), '\\ ');
// Add defaults for any missing values
$values = array_merge(Factory::$default, $values);
// Store the result to the supplied name and potential alias
self::$options[$component] = $values;
self::$options[$values['component']] = $values;
return $values;
}
/**
* Resets the static arrays, optionally just for one component
*
* @param string|null $component Lowercase, plural component name
*
* @return void
*/
public static function reset(?string $component = null)
{
if ($component !== null) {
unset(
self::$options[$component],
self::$aliases[$component],
self::$instances[$component],
self::$updated[$component]
);
return;
}
self::$options = [];
self::$aliases = [];
self::$instances = [];
self::$updated = [];
}
/**
* Helper method for injecting mock instances
*
* @param string $component Lowercase, plural component name
* @param string $alias Class alias. See the $aliases property.
*
* @return void
*
* @internal For testing only
* @testTag
*/
public static function injectMock(string $component, string $alias, object $instance)
{
$component = strtolower($component);
// Force a configuration to exist for this component
self::getOptions($component);
//$class = $instance::class;
$class = get_class($instance);
self::$instances[$component][$class] = $instance;
self::$aliases[$component][$alias] = $class;
if (self::isConfig($component)) {
if (self::isNamespaced($alias)) {
self::$aliases[$component][self::getBasename($alias)] = $class;
} else {
self::$aliases[$component]['Config\\' . $alias] = $class;
}
}
}
/**
* Gets a basename from a class alias, namespaced or not.
*
* @internal For testing only
* @testTag
*/
public static function getBasename(string $alias): string
{
// Determine the basename
if ($basename = strrchr($alias, '\\')) {
return substr($basename, 1);
}
return $alias;
}
/**
* Gets component data for caching.
*
* @return array{
* options: array<string, bool|string|null>,
* aliases: array<string, class-string>,
* instances: array<class-string, object>,
* }
*
* @internal For caching only
*/
public static function getComponentInstances(string $component): array
{
if (! isset(self::$aliases[$component])) {
return [
'options' => [],
'aliases' => [],
'instances' => [],
];
}
return [
'options' => self::$options[$component],
'aliases' => self::$aliases[$component],
'instances' => self::$instances[$component],
];
}
/**
* Sets component data
*
* @internal For caching only
*/
public static function setComponentInstances(string $component, array $data): void
{
self::$options[$component] = $data['options'];
self::$aliases[$component] = $data['aliases'];
self::$instances[$component] = $data['instances'];
unset(self::$updated[$component]);
}
/**
* Whether the component instances are updated?
*
* @internal For caching only
*/
public static function isUpdated(string $component): bool
{
return isset(self::$updated[$component]);
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Config;
/**
* Factories Configuration file.
*
* Provides overriding directives for how
* Factories should handle discovery and
* instantiation of specific components.
* Each property should correspond to the
* lowercase, plural component name.
*/
class Factory extends BaseConfig
{
/**
* Supplies a default set of options to merge for
* all unspecified factory components.
*
* @var array
*/
public static $default = [
'component' => null,
'path' => null,
'instanceOf' => null,
'getShared' => true,
'preferApp' => true,
];
/**
* Specifies that Models should always favor child
* classes to allow easy extension of module Models.
*
* @var array
*/
public $models = [
'preferApp' => true,
];
}
+1
View File
@@ -0,0 +1 @@
<?php
+117
View File
@@ -0,0 +1,117 @@
<?php
declare(strict_types=1);
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Config;
/**
* Describes foreign characters for transliteration with the text helper.
*/
class ForeignCharacters
{
/**
* The list of foreign characters.
*
* @var array<string, string>
*/
public $characterList = [
'/ä|æ|ǽ/' => 'ae',
'/ö|œ/' => 'oe',
'/ü/' => 'ue',
'/Ä/' => 'Ae',
'/Ü/' => 'Ue',
'/Ö/' => 'Oe',
'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ|А/' => 'A',
'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ|а/' => 'a',
'/Б/' => 'B',
'/б/' => 'b',
'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
'/ç|ć|ĉ|ċ|č/' => 'c',
'/Д/' => 'D',
'/д/' => 'd',
'/Ð|Ď|Đ|Δ/' => 'Dj',
'/ð|ď|đ|δ/' => 'dj',
'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E',
'/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e',
'/Ф/' => 'F',
'/ф/' => 'f',
'/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G',
'/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g',
'/Ĥ|Ħ/' => 'H',
'/ĥ|ħ/' => 'h',
'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I',
'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i',
'/Ĵ/' => 'J',
'/ĵ/' => 'j',
'/Ķ|Κ|К/' => 'K',
'/ķ|κ|к/' => 'k',
'/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ|Л/' => 'L',
'/ĺ|ļ|ľ|ŀ|ł|λ|л/' => 'l',
'/М/' => 'M',
'/м/' => 'm',
'/Ñ|Ń|Ņ|Ň|Ν|Н/' => 'N',
'/ñ|ń|ņ|ň|ʼn|ν|н/' => 'n',
'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ|Ỏ|Ọ|Ồ|Ố|Ỗ|Ổ|Ộ|Ờ|Ớ|Ỡ|Ở|Ợ|О/' => 'O',
'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ|ỏ|ọ|ồ|ố|ỗ|ổ|ộ|ờ|ớ|ỡ|ở|ợ|о/' => 'o',
'/П/' => 'P',
'/п/' => 'p',
'/Ŕ|Ŗ|Ř|Ρ|Р/' => 'R',
'/ŕ|ŗ|ř|ρ|р/' => 'r',
'/Ś|Ŝ|Ş|Ș|Š|Σ|С/' => 'S',
'/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's',
'/Ț|Ţ|Ť|Ŧ|τ|Т/' => 'T',
'/ț|ţ|ť|ŧ|т/' => 't',
'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U',
'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u',
'/Ƴ|Ɏ|Ỵ|Ẏ|Ӳ|Ӯ|Ў|Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y',
'/ẙ|ʏ|ƴ|ɏ|ỵ|ẏ|ӳ|ӯ|ў|ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y',
'/В/' => 'V',
'/в/' => 'v',
'/Ŵ/' => 'W',
'/ŵ/' => 'w',
'/Ź|Ż|Ž|Ζ|З/' => 'Z',
'/ź|ż|ž|ζ|з/' => 'z',
'/Æ|Ǽ/' => 'AE',
'/ß/' => 'ss',
'/IJ/' => 'IJ',
'/ij/' => 'ij',
'/Œ/' => 'OE',
'/ƒ/' => 'f',
'/ξ/' => 'ks',
'/π/' => 'p',
'/β/' => 'v',
'/μ/' => 'm',
'/ψ/' => 'ps',
'/Ё/' => 'Yo',
'/ё/' => 'yo',
'/Є/' => 'Ye',
'/є/' => 'ye',
'/Ї/' => 'Yi',
'/Ж/' => 'Zh',
'/ж/' => 'zh',
'/Х/' => 'Kh',
'/х/' => 'kh',
'/Ц/' => 'Ts',
'/ц/' => 'ts',
'/Ч/' => 'Ch',
'/ч/' => 'ch',
'/Ш/' => 'Sh',
'/ш/' => 'sh',
'/Щ/' => 'Shch',
'/щ/' => 'shch',
'/Ъ|ъ|Ь|ь/' => '',
'/Ю/' => 'Yu',
'/ю/' => 'yu',
'/Я/' => 'Ya',
'/я/' => 'ya',
];
}
+44
View File
@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Config;
/**
* Publisher Configuration
*
* Defines basic security restrictions for the Publisher class
* to prevent abuse by injecting malicious files into a project.
*/
class Publisher extends BaseConfig
{
/**
* A list of allowed destinations with a (pseudo-)regex
* of allowed files for each destination.
* Attempts to publish to directories not in this list will
* result in a PublisherException. Files that do no fit the
* pattern will cause copy/merge to fail.
*
* @var array<string, string>
*/
public $restrictions = [
ROOTPATH => '*',
FCPATH => '#\.(?css|js|map|htm?|xml|json|webmanifest|tff|eot|woff?|gif|jpe?g|tiff?|png|webp|bmp|ico|svg)$#i',
];
/**
* Disables Registrars to prevent modules from altering the restrictions.
*/
final protected function registerProperties(): void
{
}
}
+81
View File
@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Config;
use CodeIgniter\Cache\CacheFactory;
use CodeIgniter\Cache\CacheInterface;
use CodeIgniter\Debug\Exceptions;
use Config\Cache;
use Config\Exceptions as ExceptionsConfig;
/**
* Services Configuration file.
*
* Services are simply other classes/libraries that the system uses
* to do its job. This is used by CodeIgniter to allow the core of the
* framework to be swapped out easily without affecting the usage within
* the rest of your application.
*
* This is used in place of a Dependency Injection container primarily
* due to its simplicity, which allows a better long-term maintenance
* of the applications built on top of CodeIgniter. A bonus side-effect
* is that IDEs are able to determine what class you are calling
* whereas with DI Containers there usually isn't a way for them to do this.
*
* @see http://blog.ircmaxell.com/2015/11/simple-easy-risk-and-change.html
* @see http://www.infoq.com/presentations/Simple-Made-Easy
* @see \CodeIgniter\Config\ServicesTest
*/
class Services extends BaseService
{
/**
* The cache class provides a simple way to store and retrieve
* complex data for later.
*
* @return CacheInterface
*/
public static function cache(?Cache $config = null, bool $getShared = true)
{
if ($getShared) {
return static::getSharedInstance('cache', $config);
}
$config ??= config(Cache::class);
return CacheFactory::getHandler($config);
}
/**
* The Exceptions class holds the methods that handle:
*
* - set_exception_handler
* - set_error_handler
* - register_shutdown_function
*
* @return Exceptions
*/
public static function exceptions(
?ExceptionsConfig $config = null,
bool $getShared = true,
) {
if ($getShared) {
return static::getSharedInstance('exceptions', $config);
}
$config ??= config(ExceptionsConfig::class);
return new Exceptions($config);
}
}
+122
View File
@@ -0,0 +1,122 @@
<?php namespace Config;
/**
* {{www.xunruicms.com}}
* {{迅睿内容管理框架系统}}
* 本文件是框架系统文件,二次开发时不可以修改本文件
**/
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Debug\Toolbar\Collectors\Database;
use CodeIgniter\Debug\Toolbar\Collectors\Files;
use CodeIgniter\Debug\Toolbar\Collectors\Routes;
use CodeIgniter\Debug\Toolbar\Collectors\Views;
/**
* --------------------------------------------------------------------------
* Debug Toolbar
* --------------------------------------------------------------------------
*
* The Debug Toolbar provides a way to see information about the performance
* and state of your application during that page display. By default it will
* NOT be displayed under production environments, and will only display if
* `CI_DEBUG` is true, since if it's not, there's not much to display anyway.
*/
class Toolbar extends BaseConfig
{
/**
* --------------------------------------------------------------------------
* Toolbar Collectors
* --------------------------------------------------------------------------
*
* List of toolbar collectors that will be called when Debug Toolbar
* fires up and collects data from.
*
* @var string[]
*/
public $collectors = [
Database::class,
Views::class,
Files::class,
Routes::class
];
/**
* --------------------------------------------------------------------------
* Max History
* --------------------------------------------------------------------------
*
* `$maxHistory` sets a limit on the number of past requests that are stored,
* helping to conserve file space used to store them. You can set it to
* 0 (zero) to not have any history stored, or -1 for unlimited history.
*
* @var integer
*/
public $maxHistory = 20;
/**
* --------------------------------------------------------------------------
* Toolbar Views Path
* --------------------------------------------------------------------------
*
* The full path to the the views that are used by the toolbar.
* This MUST have a trailing slash.
*
* @var string
*/
public $viewsPath = FRAMEPATH . 'Debug/Toolbar/Views/';
/**
* --------------------------------------------------------------------------
* Max Queries
* --------------------------------------------------------------------------
*
* If the Database Collector is enabled, it will log every query that the
* the system generates so they can be displayed on the toolbar's timeline
* and in the query log. This can lead to memory issues in some instances
* with hundreds of queries.
*
* `$maxQueries` defines the maximum amount of queries that will be stored.
*
* @var integer
*/
public $maxQueries = 100;
/**
* --------------------------------------------------------------------------
* Collect Var Data
* --------------------------------------------------------------------------
*
* If set to false var data from the views will not be colleted. Usefull to
* avoid high memory usage when there are lots of data passed to the view.
*
* @var bool
*/
public $collectVarData = true;
/**
* --------------------------------------------------------------------------
* Watched Directories
* --------------------------------------------------------------------------
*
* Contains an array of directories that will be watched for changes and
* used to determine if the hot-reload feature should reload the page or not.
* We restrict the values to keep performance as high as possible.
*
* NOTE: The ROOTPATH will be prepended to all values.
*/
public $watchedDirectories = [
'app',
];
/**
* --------------------------------------------------------------------------
* Watched File Extensions
* --------------------------------------------------------------------------
*
* Contains an array of file extensions that will be watched for changes and
* used to determine if the hot-reload feature should reload the page or not.
*/
public $watchedExtensions = [
'php', 'css', 'js', 'html', 'svg', 'json', 'env',
];
}