Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • adaures/castopod
  • mkljczk/castopod-host
  • spaetz/castopod-host
  • PatrykMis/castopod
  • jonas/castopod
  • ajeremias/castopod
  • misuzu/castopod
  • KrzysztofDomanczyk/castopod
  • Behel/castopod
  • nebulon/castopod
  • ewen/castopod
  • NeoluxConsulting/castopod
  • nateritter/castopod-og
  • prcutler/castopod
14 results
Show changes
Showing
with 1467 additions and 722 deletions
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
class Email extends BaseConfig class Email extends BaseConfig
{ {
/** public string $fromEmail = '';
* @var string
*/
public $fromEmail;
/** public string $fromName = 'Castopod';
* @var string
*/
public $fromName;
/** public string $recipients = '';
* @var string
*/
public $recipients;
/** /**
* The "user agent" * The "user agent"
*
* @var string
*/ */
public $userAgent = 'CodeIgniter'; public string $userAgent = 'Castopod/' . CP_VERSION;
/** /**
* The mail sending protocol: mail, sendmail, smtp * The mail sending protocol: mail, sendmail, smtp
*
* @var string
*/ */
public $protocol = 'mail'; public string $protocol = 'smtp';
/** /**
* The server path to Sendmail. * The server path to Sendmail.
*
* @var string
*/ */
public $mailPath = '/usr/sbin/sendmail'; public string $mailPath = '/usr/sbin/sendmail';
/** /**
* SMTP Server Address * SMTP Server Hostname
*
* @var string
*/ */
public $SMTPHost; public string $SMTPHost = '';
/** /**
* SMTP Username * SMTP Username
*
* @var string
*/ */
public $SMTPUser; public string $SMTPUser = '';
/** /**
* SMTP Password * SMTP Password
*
* @var string
*/ */
public $SMTPPass; public string $SMTPPass = '';
/** /**
* SMTP Port * SMTP Port
*
* @var integer
*/ */
public $SMTPPort = 25; public int $SMTPPort = 25;
/** /**
* SMTP Timeout (in seconds) * SMTP Timeout (in seconds)
*
* @var integer
*/ */
public $SMTPTimeout = 5; public int $SMTPTimeout = 5;
/** /**
* Enable persistent SMTP connections * Enable persistent SMTP connections
*
* @var boolean
*/ */
public $SMTPKeepAlive = false; public bool $SMTPKeepAlive = false;
/** /**
* SMTP Encryption. Either tls or ssl * SMTP Encryption.
* *
* @var string * @var string '', 'tls' or 'ssl'. 'tls' will issue a STARTTLS command
* to the server. 'ssl' means implicit SSL. Connection on port
* 465 should set this to ''.
*/ */
public $SMTPCrypto = 'tls'; public string $SMTPCrypto = 'tls';
/** /**
* Enable word-wrap * Enable word-wrap
*
* @var boolean
*/ */
public $wordWrap = true; public bool $wordWrap = true;
/** /**
* Character count to wrap at * Character count to wrap at
*
* @var integer
*/ */
public $wrapChars = 76; public int $wrapChars = 76;
/** /**
* Type of mail, either 'text' or 'html' * Type of mail, either 'text' or 'html'
*
* @var string
*/ */
public $mailType = 'text'; public string $mailType = 'html';
/** /**
* Character set (utf-8, iso-8859-1, etc.) * Character set (utf-8, iso-8859-1, etc.)
*
* @var string
*/ */
public $charset = 'UTF-8'; public string $charset = 'UTF-8';
/** /**
* Whether to validate the email address * Whether to validate the email address
*
* @var boolean
*/ */
public $validate = false; public bool $validate = false;
/** /**
* Email Priority. 1 = highest. 5 = lowest. 3 = normal * Email Priority. 1 = highest. 5 = lowest. 3 = normal
*
* @var integer
*/ */
public $priority = 3; public int $priority = 3;
/** /**
* Newline character. (Use “\r\n” to comply with RFC 822) * Newline character. (Use “\r\n” to comply with RFC 822)
*
* @var string
*/ */
public $CRLF = "\r\n"; public string $CRLF = "\r\n";
/** /**
* Newline character. (Use “\r\n” to comply with RFC 822) * Newline character. (Use “\r\n” to comply with RFC 822)
*
* @var string
*/ */
public $newline = "\r\n"; public string $newline = "\r\n";
/** /**
* Enable BCC Batch Mode. * Enable BCC Batch Mode.
*
* @var boolean
*/ */
public $BCCBatchMode = false; public bool $BCCBatchMode = false;
/** /**
* Number of emails in each BCC batch * Number of emails in each BCC batch
*
* @var integer
*/ */
public $BCCBatchSize = 200; public int $BCCBatchSize = 200;
/** /**
* Enable notify message from server * Enable notify message from server
*
* @var boolean
*/ */
public $DSN = false; public bool $DSN = false;
public function __construct()
{
parent::__construct();
$this->userAgent = 'Castopod/' . CP_VERSION . '; +' . base_url('', 'https');
}
} }
<?php
declare(strict_types=1);
namespace Config;
use CodeIgniter\Config\BaseConfig;
class Embed extends BaseConfig
{
/**
* --------------------------------------------------------------------------
* Embeddable player config
* --------------------------------------------------------------------------
*/
public int $width = 485;
public int $height = 112;
}
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
...@@ -7,30 +9,86 @@ use CodeIgniter\Config\BaseConfig; ...@@ -7,30 +9,86 @@ use CodeIgniter\Config\BaseConfig;
/** /**
* Encryption configuration. * Encryption configuration.
* *
* These are the settings used for encryption, if you don't pass a parameter * These are the settings used for encryption, if you don't pass a parameter array to the encrypter for
* array to the encrypter for creation/initialization. * creation/initialization.
*/ */
class Encryption extends BaseConfig class Encryption extends BaseConfig
{ {
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Encryption Key Starter * Encryption Key Starter
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| If you use the Encryption class you must set an encryption key (seed). * If you use the Encryption class you must set an encryption key (seed).
| You need to ensure it is long enough for the cipher and mode you plan to use. * You need to ensure it is long enough for the cipher and mode you plan to use.
| See the user guide for more info. * See the user guide for more info.
*/ */
public string $key = '';
public $key = '';
/**
/* * --------------------------------------------------------------------------
|-------------------------------------------------------------------------- * Encryption Driver to Use
| Encryption driver to use * --------------------------------------------------------------------------
|-------------------------------------------------------------------------- *
| * One of the supported encryption drivers.
| One of the supported drivers, eg 'OpenSSL' or 'Sodium'. *
| The default driver, if you don't specify one, is 'OpenSSL'. * Available drivers:
*/ * - OpenSSL
public $driver = 'OpenSSL'; * - Sodium
*/
public string $driver = 'OpenSSL';
/**
* --------------------------------------------------------------------------
* SodiumHandler's Padding Length in Bytes
* --------------------------------------------------------------------------
*
* This is the number of bytes that will be padded to the plaintext message
* before it is encrypted. This value should be greater than zero.
*
* See the user guide for more information on padding.
*/
public int $blockSize = 16;
/**
* --------------------------------------------------------------------------
* Encryption digest
* --------------------------------------------------------------------------
*
* HMAC digest to use, e.g. 'SHA512' or 'SHA256'. Default value is 'SHA512'.
*/
public string $digest = 'SHA512';
/**
* Whether the cipher-text should be raw. If set to false, then it will be base64 encoded.
* This setting is only used by OpenSSLHandler.
*
* Set to false for CI3 Encryption compatibility.
*/
public bool $rawData = true;
/**
* Encryption key info.
* This setting is only used by OpenSSLHandler.
*
* Set to 'encryption' for CI3 Encryption compatibility.
*/
public string $encryptKeyInfo = '';
/**
* Authentication key info.
* This setting is only used by OpenSSLHandler.
*
* Set to 'authentication' for CI3 Encryption compatibility.
*/
public string $authKeyInfo = '';
/**
* Cipher to use.
* This setting is only used by OpenSSLHandler.
*
* Set to 'AES-128-CBC' to decrypt encrypted data that encrypted
* by CI3 Encryption default configuration.
*/
public string $cipher = 'AES-256-CTR';
} }
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use App\Entities\Actor;
use App\Entities\Post;
use App\Models\EpisodeModel;
use CodeIgniter\Debug\Toolbar\Collectors\Database;
use CodeIgniter\Events\Events; use CodeIgniter\Events\Events;
use CodeIgniter\Exceptions\FrameworkException;
use CodeIgniter\HotReloader\HotReloader;
/* /*
* -------------------------------------------------------------------- * --------------------------------------------------------------------
...@@ -21,15 +29,17 @@ use CodeIgniter\Events\Events; ...@@ -21,15 +29,17 @@ use CodeIgniter\Events\Events;
* Events::on('create', [$myInstance, 'myMethod']); * Events::on('create', [$myInstance, 'myMethod']);
*/ */
Events::on('pre_system', function () { Events::on('pre_system', static function (): void {
if (ENVIRONMENT !== 'testing') { if (ENVIRONMENT !== 'testing') {
while (\ob_get_level() > 0) { if (ini_get('zlib.output_compression')) {
\ob_end_flush(); throw FrameworkException::forEnabledZlibOutputCompression();
}
while (ob_get_level() > 0) {
ob_end_flush();
} }
\ob_start(function ($buffer) { ob_start(static fn ($buffer) => $buffer);
return $buffer;
});
} }
/* /*
...@@ -38,11 +48,284 @@ Events::on('pre_system', function () { ...@@ -38,11 +48,284 @@ Events::on('pre_system', function () {
* -------------------------------------------------------------------- * --------------------------------------------------------------------
* If you delete, they will no longer be collected. * If you delete, they will no longer be collected.
*/ */
if (ENVIRONMENT !== 'production') { if (CI_DEBUG && ! is_cli()) {
Events::on( Events::on('DBQuery', Database::class . '::collect');
'DBQuery', service('toolbar')
'CodeIgniter\Debug\Toolbar\Collectors\Database::collect' ->respond();
);
Services::toolbar()->respond(); // Hot Reload route - for framework use on the hot reloader.
if (ENVIRONMENT === 'development') {
service('routes')->get('__hot-reload', static function (): void {
(new HotReloader())->run();
});
}
}
});
/*
* --------------------------------------------------------------------
* Fediverse events
* --------------------------------------------------------------------
*/
/**
* @param Actor $actor
* @param Actor $targetActor
*/
Events::on('on_follow', static function ($actor, $targetActor): void {
if ($actor->is_podcast) {
cache()
->deleteMatching("podcast#{$actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$actor->podcast->id}*");
}
if ($targetActor->is_podcast) {
cache()
->deleteMatching("podcast#{$targetActor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$targetActor->podcast->id}*");
}
});
/**
* @param Actor $actor
* @param Actor $targetActor
*/
Events::on('on_undo_follow', static function ($actor, $targetActor): void {
if ($actor->is_podcast) {
cache()
->deleteMatching("podcast#{$actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$actor->podcast->id}*");
}
if ($targetActor->is_podcast) {
cache()
->deleteMatching("podcast#{$targetActor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$targetActor->podcast->id}*");
}
});
/**
* @param Post $post
*/
Events::on('on_post_add', static function ($post): void {
model(EpisodeModel::class, false)->builder()
->where('id', $post->episode_id)
->increment('posts_count');
if ($post->actor->is_podcast) {
// Removing all of the podcast pages is a bit overkill, but works to avoid caching bugs
// same for other events below
cache()
->deleteMatching("podcast#{$post->actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
}
});
/**
* @param Post $post
*/
Events::on('on_post_remove', static function ($post): void {
if ($episodeId = $post->episode_id) {
model(EpisodeModel::class, false)->builder()
->where('id', $episodeId)
->decrement('posts_count');
}
if ($post->actor->is_podcast) {
cache()
->deleteMatching("podcast#{$post->actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
}
cache()
->deleteMatching("page_post#{$post->id}*");
});
/**
* @param Actor $actor
* @param Post $post
*/
Events::on('on_post_reblog', static function ($actor, $post): void {
if ($post->actor->is_podcast) {
cache()
->deleteMatching("podcast#{$post->actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
}
if ($actor->is_podcast) {
cache()->deleteMatching("podcast#{$actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$actor->podcast->id}*");
}
cache()
->deleteMatching("page_post#{$post->id}*");
if ($post->in_reply_to_id !== null) {
cache()->deleteMatching("page_post#{$post->in_reply_to_id}");
}
});
/**
* @param Post $reblogPost
*/
Events::on('on_post_undo_reblog', static function ($reblogPost): void {
$post = $reblogPost->reblog_of_post;
if ($post->actor->is_podcast) {
cache()
->deleteMatching("podcast#{$post->actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
}
cache()
->deleteMatching("page_post#{$post->id}*");
cache()
->deleteMatching("page_post#{$reblogPost->id}*");
if ($post->in_reply_to_id !== null) {
cache()->deleteMatching("page_post#{$post->in_reply_to_id}");
}
if ($reblogPost->actor->is_podcast) {
cache()
->deleteMatching("podcast#{$reblogPost->actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$reblogPost->actor->podcast->id}*");
}
});
/**
* @param Post $reply
*/
Events::on('on_post_reply', static function ($reply): void {
$post = $reply->reply_to_post;
if ($post->in_reply_to_id === null) {
model(EpisodeModel::class, false)->builder()
->where('id', $post->episode_id)
->increment('comments_count');
}
if ($post->actor->is_podcast) {
cache()
->deleteMatching("podcast-{$post->actor->podcast->handle}*");
cache()
->deleteMatching("podcast#{$post->actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
} }
cache()
->deleteMatching("page_post#{$post->id}*");
});
/**
* @param Post $reply
*/
Events::on('on_reply_remove', static function ($reply): void {
$post = $reply->reply_to_post;
if ($post->in_reply_to_id === null) {
model(EpisodeModel::class, false)->builder()
->where('id', $post->episode_id)
->decrement('comments_count');
}
if ($post->actor->is_podcast) {
cache()
->deleteMatching("podcast-{$post->actor->podcast->handle}*");
cache()
->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
cache()
->deleteMatching("podcast#{$post->actor->podcast->id}*");
}
cache()
->deleteMatching("page_post#{$post->id}*");
cache()
->deleteMatching("page_post#{$reply->id}*");
});
/**
* @param Actor $actor
* @param Post $post
*/
Events::on('on_post_favourite', static function ($actor, $post): void {
if ($post->actor->is_podcast) {
cache()
->deleteMatching("podcast#{$post->actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
}
cache()
->deleteMatching("page_post#{$post->id}*");
if ($post->in_reply_to_id !== null) {
cache()->deleteMatching("page_post#{$post->in_reply_to_id}*");
}
if ($actor->is_podcast) {
cache()->deleteMatching("podcast#{$actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$actor->podcast->id}*");
}
});
/**
* @param Actor $actor
* @param Post $post
*/
Events::on('on_post_undo_favourite', static function ($actor, $post): void {
if ($post->actor->is_podcast) {
cache()
->deleteMatching("podcast#{$post->actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
}
cache()
->deleteMatching("page_post#{$post->id}*");
if ($post->in_reply_to_id !== null) {
cache()->deleteMatching("page_post#{$post->in_reply_to_id}*");
}
if ($actor->is_podcast) {
cache()->deleteMatching("podcast#{$actor->podcast->id}*");
cache()
->deleteMatching("page_podcast#{$actor->podcast->id}*");
}
});
Events::on('on_block_actor', static function (int $actorId): void {
cache()->deleteMatching('page_podcast*');
cache()
->deleteMatching('podcast*');
cache()
->deleteMatching('page_post*');
});
Events::on('on_unblock_actor', static function (int $actorId): void {
cache()->deleteMatching('page_podcast*');
cache()
->deleteMatching('podcast*');
cache()
->deleteMatching('page_post*');
});
Events::on('on_block_domain', static function (string $domainName): void {
cache()->deleteMatching('page_podcast*');
cache()
->deleteMatching('podcast*');
cache()
->deleteMatching('page_post*');
});
Events::on('on_unblock_domain', static function (string $domainName): void {
cache()->deleteMatching('page_podcast*');
cache()
->deleteMatching('podcast*');
cache()
->deleteMatching('page_post*');
}); });
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Debug\ExceptionHandler;
use CodeIgniter\Debug\ExceptionHandlerInterface;
use Psr\Log\LogLevel;
use Throwable;
/** /**
* Setup how the exception handler works. * Setup how the exception handler works.
*
* @package Config
*/ */
class Exceptions extends BaseConfig
class Exceptions
{ {
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| LOG EXCEPTIONS? * LOG EXCEPTIONS?
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| If true, then exceptions will be logged * If true, then exceptions will be logged
| through Services::Log. * through Services::Log.
| *
| Default: true * Default: true
*/ */
public $log = true; public bool $log = true;
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| DO NOT LOG STATUS CODES * DO NOT LOG STATUS CODES
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Any status codes here will NOT be logged if logging is turned on. * Any status codes here will NOT be logged if logging is turned on.
| By default, only 404 (Page Not Found) exceptions are ignored. * By default, only 404 (Page Not Found) exceptions are ignored.
*
* @var list<int>
*/
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 $ignoreCodes = [404]; public string $errorViewPath = APPPATH . 'Views/errors';
/**
* --------------------------------------------------------------------------
* 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']
*
* @var list<string>
*/
public array $sensitiveDataInTrace = [];
/**
* --------------------------------------------------------------------------
* WHETHER TO THROW AN EXCEPTION ON DEPRECATED ERRORS
* --------------------------------------------------------------------------
* If set to `true`, DEPRECATED errors are only logged and no exceptions are
* thrown. 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 = LogLevel::WARNING;
/* /*
|-------------------------------------------------------------------------- * DEFINE THE HANDLERS USED
| Error Views Path * --------------------------------------------------------------------------
|-------------------------------------------------------------------------- * Given the HTTP status code, returns exception handler that
| This is the path to the directory that contains the 'cli' and 'html' * should be used to deal with this error. By default, it will run CodeIgniter's
| directories that hold the views used to generate errors. * 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
| Default: APPPATH.'Views/errors' * response format.
*/ *
public $errorViewPath = APPPATH . 'Views/errors'; * 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);
}
} }
<?php
declare(strict_types=1);
namespace Config;
use CodeIgniter\Config\BaseConfig;
/**
* Enable/disable backward compatibility breaking features.
*/
class Feature extends BaseConfig
{
/**
* Use improved new auto routing instead of the legacy version.
*/
public bool $autoRoutesImproved = true;
/**
* Use filter execution order in 4.4 or before.
*/
public bool $oldFilterOrder = false;
/**
* The behavior of `limit(0)` in Query Builder.
*
* If true, `limit(0)` returns all records. (the behavior of 4.4.x or before in version 4.x.)
* If false, `limit(0)` returns no records. (the behavior of 3.1.9 or later in version 3.x.)
*/
public bool $limitZeroAsAll = true;
/**
* Use strict location negotiation.
*
* By default, the locale is selected based on a loose comparison of the language code (ISO 639-1)
* Enabling strict comparison will also consider the region code (ISO 3166-1 alpha-2).
*/
public bool $strictLocaleNegotiation = false;
}
<?php
declare(strict_types=1);
/**
* @copyright 2022 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace Config;
use App\Libraries\NoteObject;
use Exception;
use Modules\Fediverse\Config\Fediverse as FediverseBaseConfig;
class Fediverse extends FediverseBaseConfig
{
/**
* --------------------------------------------------------------------
* ActivityPub Objects
* --------------------------------------------------------------------
*/
public string $noteObject = NoteObject::class;
public string $defaultAvatarImagePath = 'castopod-avatar_thumbnail.webp';
public string $defaultAvatarImageMimetype = 'image/webp';
public function __construct()
{
parent::__construct();
try {
$appTheme = service('settings')
->get('App.theme');
$defaultBanner = config('Images')
->podcastBannerDefaultPaths[$appTheme] ?? config('Images')->podcastBannerDefaultPaths['default'];
} catch (Exception) {
$defaultBanner = config('Images')
->podcastBannerDefaultPaths['default'];
}
['dirname' => $dirname, 'extension' => $extension, 'filename' => $filename] = pathinfo(
$defaultBanner['path'],
);
$defaultBannerPath = $filename;
if ($dirname !== '.') {
$defaultBannerPathList = [$dirname, $filename];
$defaultBannerPath = implode('/', $defaultBannerPathList);
}
helper('media');
$this->defaultCoverImagePath = $defaultBannerPath . '_federation.' . $extension;
$this->defaultCoverImageMimetype = $defaultBanner['mimetype'];
}
}
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use App\Filters\AllowCorsFilter;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Filters\CSRF;
use CodeIgniter\Filters\DebugToolbar;
use CodeIgniter\Filters\ForceHTTPS;
use CodeIgniter\Filters\Honeypot;
use CodeIgniter\Filters\InvalidChars;
use CodeIgniter\Filters\PageCache;
use CodeIgniter\Filters\PerformanceMetrics;
use CodeIgniter\Filters\SecureHeaders;
use Modules\Auth\Filters\PermissionFilter;
class Filters extends BaseConfig class Filters extends BaseConfig
{ {
// Makes reading things below nicer, /**
// and simpler to change out script that's used. * Configures aliases for Filter classes to make reading things nicer and simpler.
public $aliases = [ *
'csrf' => \CodeIgniter\Filters\CSRF::class, * @var array<string, class-string|list<class-string>>
'toolbar' => \CodeIgniter\Filters\DebugToolbar::class, *
'honeypot' => \CodeIgniter\Filters\Honeypot::class, * [filter_name => classname]
'login' => \Myth\Auth\Filters\LoginFilter::class, * or [filter_name => [classname1, classname2, ...]]
'role' => \Myth\Auth\Filters\RoleFilter::class, */
'permission' => \App\Filters\Permission::class, public array $aliases = [
'csrf' => CSRF::class,
'toolbar' => DebugToolbar::class,
'honeypot' => Honeypot::class,
'invalidchars' => InvalidChars::class,
'secureheaders' => SecureHeaders::class,
'allow-cors' => AllowCorsFilter::class,
'cors' => Cors::class,
'forcehttps' => ForceHTTPS::class,
'pagecache' => PageCache::class,
'performance' => PerformanceMetrics::class,
];
/**
* List of special required filters.
*
* The filters listed here are special. They are applied before and after
* other kinds of filters, and always applied even if a route does not exist.
*
* Filters set by default provide framework functionality. If removed,
* those functions will no longer work.
*
* @see https://codeigniter.com/user_guide/incoming/filters.html#provided-filters
*
* @var array{before: list<string>, after: list<string>}
*/
public array $required = [
'before' => [
'forcehttps', // Force Global Secure Requests
'pagecache', // Web Page Caching
],
'after' => [
'pagecache', // Web Page Caching
'performance', // Performance Metrics
'toolbar', // Debug Toolbar
],
]; ];
// Always applied before every request /**
public $globals = [ * List of filter aliases that are always applied before and after every request.
*
* @var array<string, array<string, array<string, string|array<string>>>>|array<string, list<string>>
*/
public array $globals = [
'before' => [ 'before' => [
//'honeypot' // 'honeypot',
// 'csrf', 'csrf' => [
'except' => [
'@[a-zA-Z0-9\_]{1,32}/inbox',
'api/rest/v1/episodes',
'api/rest/v1/episodes/[0-9]+/publish',
],
],
// 'invalidchars',
], ],
'after' => [ 'after' => [
'toolbar', // 'honeypot',
//'honeypot' // 'secureheaders',
], ],
]; ];
// Works on all of a particular HTTP method /**
// (GET, POST, etc) as BEFORE filters only * List of filter aliases that works on a particular HTTP method (GET, POST, etc.).
// like: 'post' => ['CSRF', 'throttle'], *
public $methods = []; * Example: 'POST' => ['foo', 'bar']
*
* If you use this, you should disable auto-routing because auto-routing permits any HTTP method to access a
* controller. Accessing the controller with a method you don’t expect could bypass the filter.
*
* @var array<string, list<string>>
*/
public array $methods = [];
// List filter aliases and any before/after uri patterns /**
// that they should run on, like: * List of filter aliases that should run on any before or after URI patterns.
// 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']], *
public $filters = []; * Example: 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']]
*
* @var array<string, array<string, list<string>>>
*/
public array $filters = [];
public function __construct() public function __construct()
{ {
parent::__construct(); parent::__construct();
$this->filters = [ $this->filters = [
'login' => ['before' => [config('App')->adminGateway . '*']], 'session' => [
'before' => [config('Admin')->gateway . '*', config('Analytics')->gateway . '*'],
],
'podcast-unlock' => [
'before' => ['*@*/episodes/*'],
],
]; ];
$this->aliases['permission'] = PermissionFilter::class;
} }
} }
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
class ForeignCharacters extends \CodeIgniter\Config\ForeignCharacters use CodeIgniter\Config\ForeignCharacters as BaseForeignCharacters;
/**
* @immutable
*/
class ForeignCharacters extends BaseForeignCharacters
{ {
} }
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Format\JSONFormatter;
use CodeIgniter\Format\XMLFormatter;
class Format extends BaseConfig class Format extends BaseConfig
{ {
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Available Response Formats * Available Response Formats
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| When you perform content negotiation with the request, these are the * When you perform content negotiation with the request, these are the
| available formats that your application supports. This is currently * available formats that your application supports. This is currently
| only used with the API\ResponseTrait. A valid Formatter must exist * only used with the API\ResponseTrait. A valid Formatter must exist
| for the specified format. * for the specified format.
| *
| These formats are only checked when the data passed to the respond() * These formats are only checked when the data passed to the respond()
| method is an array. * method is an array.
| *
*/ * @var list<string>
public $supportedResponseFormats = [ */
public array $supportedResponseFormats = [
'application/json', 'application/json',
'application/xml', // machine-readable XML 'application/xml', // machine-readable XML
'text/xml', // human-readable XML 'text/xml', // human-readable XML
]; ];
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Formatters * Formatters
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| Lists the class to use to format responses with of a particular type. * Lists the class to use to format responses with of a particular type.
| For each mime type, list the class that should be used. Formatters * For each mime type, list the class that should be used. Formatters
| can be retrieved through the getFormatter() method. * can be retrieved through the getFormatter() method.
| *
*/ * @var array<string, string>
public $formatters = [ */
'application/json' => \CodeIgniter\Format\JSONFormatter::class, public array $formatters = [
'application/xml' => \CodeIgniter\Format\XMLFormatter::class, 'application/json' => JSONFormatter::class,
'text/xml' => \CodeIgniter\Format\XMLFormatter::class, 'application/xml' => XMLFormatter::class,
'text/xml' => XMLFormatter::class,
]; ];
//--------------------------------------------------------------------
/** /**
* A Factory method to return the appropriate formatter for the given mime type. * --------------------------------------------------------------------------
* Formatters Options
* --------------------------------------------------------------------------
* *
* @param string $mime * Additional Options to adjust default formatters behaviour.
* For each mime type, list the additional options that should be used.
* *
* @return \CodeIgniter\Format\FormatterInterface * @var array<string, int>
*/ */
public function getFormatter(string $mime) public array $formatterOptions = [
{ 'application/json' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
if (!array_key_exists($mime, $this->formatters)) { 'application/xml' => 0,
throw new \InvalidArgumentException( 'text/xml' => 0,
'No Formatter defined for mime type: ' . $mime ];
);
}
$class = $this->formatters[$mime];
if (!class_exists($class)) {
throw new \BadMethodCallException(
$class . ' is not a valid Formatter.'
);
}
return new $class();
}
//--------------------------------------------------------------------
} }
<?php
declare(strict_types=1);
namespace Config;
use CodeIgniter\Config\BaseConfig;
class Generators extends BaseConfig
{
/**
* --------------------------------------------------------------------------
* Generator Commands' Views
* --------------------------------------------------------------------------
*
* This array defines the mapping of generator commands to the view files
* they are using. If you need to customize them for your own, copy these
* view files in your own folder and indicate the location here.
*
* You will notice that the views have special placeholders enclosed in
* curly braces `{...}`. These placeholders are used internally by the
* generator commands in processing replacements, thus you are warned
* not to delete them or modify the names. If you will do so, you may
* end up disrupting the scaffolding process and throw errors.
*
* YOU HAVE BEEN WARNED!
*
* @var array<string, string|array<string,string>>
*/
public array $views = [
'make:cell' => [
'class' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php',
'view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php',
],
'make:command' => 'CodeIgniter\Commands\Generators\Views\command.tpl.php',
'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php',
'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php',
'make:entity' => 'CodeIgniter\Commands\Generators\Views\entity.tpl.php',
'make:filter' => 'CodeIgniter\Commands\Generators\Views\filter.tpl.php',
'make:migration' => 'CodeIgniter\Commands\Generators\Views\migration.tpl.php',
'make:model' => 'CodeIgniter\Commands\Generators\Views\model.tpl.php',
'make:seeder' => 'CodeIgniter\Commands\Generators\Views\seeder.tpl.php',
'make:validation' => 'CodeIgniter\Commands\Generators\Views\validation.tpl.php',
'session:migration' => 'CodeIgniter\Commands\Generators\Views\migration.tpl.php',
];
}
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
...@@ -8,28 +10,35 @@ class Honeypot extends BaseConfig ...@@ -8,28 +10,35 @@ class Honeypot extends BaseConfig
{ {
/** /**
* Makes Honeypot visible or not to human * Makes Honeypot visible or not to human
*
* @var boolean
*/ */
public $hidden = true; public bool $hidden = true;
/** /**
* Honeypot Label Content * Honeypot Label Content
*
* @var string
*/ */
public $label = 'Fill This Field'; public string $label = 'Fill This Field';
/** /**
* Honeypot Field Name * Honeypot Field Name
*
* @var string
*/ */
public $name = 'honeypot'; public string $name = 'honeypot';
/** /**
* Honeypot HTML Template * Honeypot HTML Template
*/
public string $template = '<label>{label}</label><input type="text" name="{name}" value=""/>';
/**
* Honeypot container
*
* If you enabled CSP, you can remove `style="display:none"`.
*/
public string $container = '<div style="display:none">{template}</div>';
/**
* The id attribute for Honeypot container tag
* *
* @var string * Used when CSP is enabled.
*/ */
public $template = '<label>{label}</label><input type="text" name="{name}" value=""/>'; public string $containerId = 'hpc';
} }
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Images\Handlers\GDHandler;
use CodeIgniter\Images\Handlers\ImageMagickHandler;
class Images extends BaseConfig class Images extends BaseConfig
{ {
/** /**
* Default handler used if no other handler is specified. * Default handler used if no other handler is specified.
*
* @var string
*/ */
public $defaultHandler = 'gd'; public string $defaultHandler = 'gd';
/** /**
* The path to the image library. * The path to the image library. Required for ImageMagick, GraphicsMagick, or NetPBM.
* Required for ImageMagick, GraphicsMagick, or NetPBM.
*
* @var string
*/ */
public $libraryPath = '/usr/local/bin/convert'; public string $libraryPath = '/usr/local/bin/convert';
/** /**
* The available handler classes. * The available handler classes.
* *
* @var array * @var array<string, string>
*/ */
public $handlers = [ public array $handlers = [
'gd' => \CodeIgniter\Images\Handlers\GDHandler::class, 'gd' => GDHandler::class,
'imagick' => \CodeIgniter\Images\Handlers\ImageMagickHandler::class, 'imagick' => ImageMagickHandler::class,
]; ];
/** /*
* -------------------------------------------------------------------------- |--------------------------------------------------------------------------
* Uploaded images resizing sizes (in px) | Uploaded images sizes (in px)
* -------------------------------------------------------------------------- |--------------------------------------------------------------------------
* The sizes listed below determine the resizing of images when uploaded. | The sizes listed below determine the resizing of images when uploaded.
* All uploaded images are of 1:1 ratio (width and height are the same). */
*/
/** /**
* @var integer * Podcast cover image sizes
*/
public $thumbnailSize = 150;
/**
* @var integer
*/
public $mediumSize = 320;
/**
* @var integer
*/
public $largeSize = 1024;
/**
* Size of images linked in the rss feed (should be between 1400 and 3000)
* *
* @var integer * Uploaded podcast covers are of 1:1 ratio (width and height are the same).
*/
public $feedSize = 1400;
/**
* Size for ID3 tag cover art (should be between 300 and 800)
* *
* @var integer * Size of images linked in the rss feed (should be between 1400 and 3000). Size for ID3 tag cover art (should be
* between 300 and 800)
*
* Array values are as follows: 'name' => [width, height]
*
* @var array<string, array<string, int|string>>
*/ */
public $id3Size = 500; public array $podcastCoverSizes = [
'tiny' => [
'width' => 40,
'height' => 40,
'mimetype' => 'image/webp',
'extension' => 'webp',
],
'thumbnail' => [
'width' => 150,
'height' => 150,
'mimetype' => 'image/webp',
'extension' => 'webp',
],
'medium' => [
'width' => 320,
'height' => 320,
'mimetype' => 'image/webp',
'extension' => 'webp',
],
'large' => [
'width' => 1024,
'height' => 1024,
'mimetype' => 'image/webp',
'extension' => 'webp',
],
'feed' => [
'width' => 1400,
'height' => 1400,
],
'id3' => [
'width' => 500,
'height' => 500,
],
'og' => [
'width' => 1200,
'height' => 1200,
],
'federation' => [
'width' => 400,
'height' => 400,
],
'webmanifest192' => [
'width' => 192,
'height' => 192,
'mimetype' => 'image/png',
'extension' => 'png',
],
'webmanifest512' => [
'width' => 512,
'height' => 512,
'mimetype' => 'image/png',
'extension' => 'png',
],
];
/** /**
* -------------------------------------------------------------------------- * Podcast header cover image
* Uploaded images naming extensions *
* -------------------------------------------------------------------------- * Uploaded podcast header covers are of 3:1 ratio
* The properties listed below set the name extensions for the resized images *
* @var array<string, array<string, int|string>>
*/ */
public array $podcastBannerSizes = [
'small' => [
'width' => 320,
'height' => 128,
'mimetype' => 'image/webp',
'extension' => 'webp',
],
'medium' => [
'width' => 960,
'height' => 320,
'mimetype' => 'image/webp',
'extension' => 'webp',
],
'federation' => [
'width' => 1500,
'height' => 500,
],
];
/** public string $avatarDefaultPath = 'assets/images/castopod-avatar.jpg';
* @var string
*/
public $thumbnailExtension = '_thumbnail';
/** public string $avatarDefaultMimeType = 'image/jpg';
* @var string
*/
public $mediumExtension = '_medium';
/** /**
* @var string * @var array<string, array<string, string>>
*/ */
public $largeExtension = '_large'; public array $podcastBannerDefaultPaths = [
'default' => [
'path' => 'assets/images/castopod-banner-pine.jpg',
'mimetype' => 'image/jpeg',
],
'pine' => [
'path' => 'assets/images/castopod-banner-pine.jpg',
'mimetype' => 'image/jpeg',
],
'crimson' => [
'path' => 'assets/images/castopod-banner-crimson.jpg',
'mimetype' => 'image/jpeg',
],
'amber' => [
'path' => 'assets/images/castopod-banner-amber.jpg',
'mimetype' => 'image/jpeg',
],
'lake' => [
'path' => 'assets/images/castopod-banner-lake.jpg',
'mimetype' => 'image/jpeg',
],
'jacaranda' => [
'path' => 'assets/images/castopod-banner-jacaranda.jpg',
'mimetype' => 'image/jpeg',
],
'onyx' => [
'path' => 'assets/images/castopod-banner-onyx.jpg',
'mimetype' => 'image/jpeg',
],
];
/** public string $podcastBannerDefaultMimeType = 'image/jpeg';
* @var string
*/
public $feedExtension = '_feed';
/** /**
* @var string * Person image
*
* Uploaded person images are of 1:1 ratio (width and height are the same).
*
* Array values are as follows: 'name' => [width, height]
*
* @var array<string, array<string, int|string>>
*/ */
public $id3Extension = '_id3'; public array $personAvatarSizes = [
'federation' => [
'width' => 400,
'height' => 400,
],
'tiny' => [
'width' => 40,
'height' => 40,
'mimetype' => 'image/webp',
'extension' => 'webp',
],
'thumbnail' => [
'width' => 150,
'height' => 150,
'mimetype' => 'image/webp',
'extension' => 'webp',
],
'medium' => [
'width' => 320,
'height' => 320,
'mimetype' => 'image/webp',
'extension' => 'webp',
],
];
} }
<?php <?php
namespace Config; declare(strict_types=1);
use CodeIgniter\Config\BaseConfig; namespace Config;
use Kint\Renderer\Renderer;
class Kint extends BaseConfig use Kint\Parser\ConstructablePluginInterface;
use Kint\Renderer\Rich\TabPluginInterface;
use Kint\Renderer\Rich\ValuePluginInterface;
/**
* --------------------------------------------------------------------------
* --------------------------------------------------------------------------
*
* We use Kint's `RichRenderer` and `CLIRenderer`. This area contains options
* that you can set to customize how Kint works for you.
*
* @see https://kint-php.github.io/kint/ for details on these settings.
*/
class Kint
{ {
/*
|--------------------------------------------------------------------------
| Kint
|--------------------------------------------------------------------------
|
| We use Kint's RichRenderer and CLIRenderer. This area contains options
| that you can set to customize how Kint works for you.
|
| For details on these settings, see Kint's docs:
| https://kint-php.github.io/kint/
|
*/
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Global Settings | Global Settings
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
*/ */
public $plugins = null; /**
* @var list<class-string<ConstructablePluginInterface>|ConstructablePluginInterface>|null
*/
public ?array $plugins = [];
public $maxDepth = 6; public int $maxDepth = 6;
public $displayCalledFrom = true; public bool $displayCalledFrom = true;
public $expanded = false; public bool $expanded = false;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| RichRenderer Settings | RichRenderer Settings
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
*/ */
public $richTheme = 'aante-light.css';
public $richFolder = false; public string $richTheme = 'aante-light.css';
public $richSort = Renderer::SORT_FULL; public bool $richFolder = false;
public $richObjectPlugins = null; /**
* @var array<string, class-string<ValuePluginInterface>>|null
*/
public ?array $richObjectPlugins = [];
public $richTabPlugins = null; /**
* @var array<string, class-string<TabPluginInterface>>|null
*/
public ?array $richTabPlugins = [];
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| CLI Settings | CLI Settings
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
*/ */
public $cliColors = true;
public $cliForceUTF8 = false; public bool $cliColors = true;
public bool $cliForceUTF8 = false;
public $cliDetectWidth = true; public bool $cliDetectWidth = true;
public $cliMinWidth = 40; public int $cliMinWidth = 40;
} }
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Log\Handlers\FileHandler;
class Logger extends BaseConfig class Logger extends BaseConfig
{ {
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Error Logging Threshold * Error Logging Threshold
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| You can enable error logging by setting a threshold over zero. The * You can enable error logging by setting a threshold over zero. The
| threshold determines what gets logged. Any values below or equal to the * threshold determines what gets logged. Any values below or equal to the
| threshold will be logged. Threshold options are: * threshold will be logged.
| *
| 0 = Disables logging, Error logging TURNED OFF * Threshold options are:
| 1 = Emergency Messages - System is unusable *
| 2 = Alert Messages - Action Must Be Taken Immediately * - 0 = Disables logging, Error logging TURNED OFF
| 3 = Critical Messages - Application component unavailable, unexpected exception. * - 1 = Emergency Messages - System is unusable
| 4 = Runtime Errors - Don't need immediate action, but should be monitored. * - 2 = Alert Messages - Action Must Be Taken Immediately
| 5 = Warnings - Exceptional occurrences that are not errors. * - 3 = Critical Messages - Application component unavailable, unexpected exception.
| 6 = Notices - Normal but significant events. * - 4 = Runtime Errors - Don't need immediate action, but should be monitored.
| 7 = Info - Interesting events, like user logging in, etc. * - 5 = Warnings - Exceptional occurrences that are not errors.
| 8 = Debug - Detailed debug information. * - 6 = Notices - Normal but significant events.
| 9 = All Messages * - 7 = Info - Interesting events, like user logging in, etc.
| * - 8 = Debug - Detailed debug information.
| You can also pass an array with threshold levels to show individual error types * - 9 = All Messages
| *
| array(1, 2, 3, 8) = Emergency, Alert, Critical, and Debug messages * You can also pass an array with threshold levels to show individual error types
| *
| For a live site you'll usually enable Critical or higher (3) to be logged otherwise * array(1, 2, 3, 8) = Emergency, Alert, Critical, and Debug messages
| your log files will fill up very fast. *
| * For a live site you'll usually enable Critical or higher (3) to be logged otherwise
*/ * your log files will fill up very fast.
public $threshold = 3; *
* @var int|list<int>
/* */
|-------------------------------------------------------------------------- public int | array $threshold = (ENVIRONMENT === 'production') ? 4 : 9;
| Date Format for Logs
|--------------------------------------------------------------------------
|
| Each item that is logged has an associated date. You can use PHP date
| codes to set your own date formatting
|
*/
public $dateFormat = 'Y-m-d H:i:s';
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Log Handlers * Date Format for Logs
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| The logging system supports multiple actions to be taken when something * Each item that is logged has an associated date. You can use PHP date
| is logged. This is done by allowing for multiple Handlers, special classes * codes to set your own date formatting
| designed to write the log to their chosen destinations, whether that is */
| a file on the getServer, a cloud-based service, or even taking actions such public string $dateFormat = 'Y-m-d H:i:s';
| as emailing the dev team.
|
| Each handler is defined by the class name used for that handler, and it
| MUST implement the CodeIgniter\Log\Handlers\HandlerInterface interface.
|
| The value of each key is an array of configuration items that are sent
| to the constructor of each handler. The only required configuration item
| is the 'handles' element, which must be an array of integer log levels.
| This is most easily handled by using the constants defined in the
| Psr\Log\LogLevel class.
|
| Handlers are executed in the order defined in this array, starting with
| the handler on top and continuing down.
|
*/
public $handlers = [
//--------------------------------------------------------------------
// File Handler
//--------------------------------------------------------------------
'CodeIgniter\Log\Handlers\FileHandler' => [ /**
* --------------------------------------------------------------------------
* Log Handlers
* --------------------------------------------------------------------------
*
* The logging system supports multiple actions to be taken when something
* is logged. This is done by allowing for multiple Handlers, special classes
* designed to write the log to their chosen destinations, whether that is
* a file on the server, a cloud-based service, or even taking actions such
* as emailing the dev team.
*
* Each handler is defined by the class name used for that handler, and it
* MUST implement the `CodeIgniter\Log\Handlers\HandlerInterface` interface.
*
* The value of each key is an array of configuration items that are sent
* to the constructor of each handler. The only required configuration item
* is the 'handles' element, which must be an array of integer log levels.
* This is most easily handled by using the constants defined in the
* `Psr\Log\LogLevel` class.
*
* Handlers are executed in the order defined in this array, starting with
* the handler on top and continuing down.
*
* @var array<class-string, array<string, int|list<string>|string>>
*/
public array $handlers = [
/*
* --------------------------------------------------------------------
* File Handler
* --------------------------------------------------------------------
*/
FileHandler::class => [
/* /*
* The log levels that this handler will handle. * The log levels that this handler will handle.
*/ */
'handles' => [ 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'],
'critical',
'alert',
'emergency',
'debug',
'error',
'info',
'notice',
'warning',
],
/* /*
* The default filename extension for log files. * The default filename extension for log files.
...@@ -117,16 +115,31 @@ class Logger extends BaseConfig ...@@ -117,16 +115,31 @@ class Logger extends BaseConfig
'path' => '', 'path' => '',
], ],
/** /*
* The ChromeLoggerHandler requires the use of the Chrome web browser * The ChromeLoggerHandler requires the use of the Chrome web browser
* and the ChromeLogger extension. Uncomment this block to use it. * and the ChromeLogger extension. Uncomment this block to use it.
*/ */
// 'CodeIgniter\Log\Handlers\ChromeLoggerHandler' => [ // 'CodeIgniter\Log\Handlers\ChromeLoggerHandler' => [
// /* // /*
// * The log levels that this handler will handle. // * The log levels that this handler will handle.
// */ // */
// 'handles' => ['critical', 'alert', 'emergency', 'debug', // 'handles' => ['critical', 'alert', 'emergency', 'debug',
// 'error', 'info', 'notice', 'warning'], // 'error', 'info', 'notice', 'warning'],
// ] // ],
/*
* The ErrorlogHandler writes the logs to PHP's native `error_log()` function.
* Uncomment this block to use it.
*/
// 'CodeIgniter\Log\Handlers\ErrorlogHandler' => [
// /* The log levels this handler can handle. */
// 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'],
//
// /*
// * The message type where the error should go. Can be 0 or 4, or use the
// * class constants: `ErrorlogHandler::TYPE_OS` (0) or `ErrorlogHandler::TYPE_SAPI` (4)
// */
// 'messageType' => 0,
// ],
]; ];
} }
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
class Migrations extends BaseConfig class Migrations extends BaseConfig
{ {
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Enable/Disable Migrations * Enable/Disable Migrations
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| Migrations are enabled by default for security reasons. * Migrations are enabled by default.
| You should enable migrations whenever you intend to do a schema migration *
| and disable it back when you're done. * You should enable migrations whenever you intend to do a schema migration
| * and disable it back when you're done.
*/ */
public $enabled = true; public bool $enabled = true;
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Migrations table * Migrations Table
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| This is the name of the table that will store the current migrations state. * This is the name of the table that will store the current migrations state.
| When migrations runs it will store in a database table which migration * When migrations runs it will store in a database table which migration
| level the system is at. It then compares the migration level in this * files have already been run.
| table to the $config['migration_version'] if they are not the same it */
| will migrate up. This must be set. public string $table = 'migrations';
|
*/
public $table = 'migrations';
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Timestamp Format * Timestamp Format
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| This is the format that will be used when creating new migrations * This is the format that will be used when creating new migrations
| using the cli command: * using the CLI command:
| > php spark migrate:create * > php spark migrate:create
| *
| Typical formats: * Typical formats:
| YmdHis_ * - YmdHis_
| Y-m-d-His_ * - Y-m-d-His_
| Y_m_d_His_ * - Y_m_d_His_
| */
*/ public string $timestampFormat = 'Y-m-d-His_';
public $timestampFormat = 'Y-m-d-His_';
} }
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
/* /**
| ------------------------------------------------------------------- * This file contains an array of mime types. It is used by the Upload class to help identify allowed file types.
| MIME TYPES *
| ------------------------------------------------------------------- * When more than one variation for an extension exist (like jpg, jpeg, etc) the most common one should be first in the
| This file contains an array of mime types. It is used by the * array to aid the guess* methods. The same applies when more than one mime-type exists for a single extension.
| Upload class to help identify allowed file types. *
| * When working with mime types, please make sure you have the ´fileinfo´ extension enabled to reliably detect the
| When more than one variation for an extension exist (like jpg, jpeg, etc) * media types.
| the most common one should be first in the array to aid the guess* *
| methods. The same applies when more than one mime-type exists for a * @immutable
| single extension. */
|
*/
class Mimes class Mimes
{ {
/** /**
* Map of extensions to mime types. * Map of extensions to mime types.
* *
* @var array * @var array<string, list<string>|string>
*/ */
public static $mimes = [ public static $mimes = [
'hqx' => [ 'hqx' => [
...@@ -34,7 +34,6 @@ class Mimes ...@@ -34,7 +34,6 @@ class Mimes
'text/csv', 'text/csv',
'text/x-comma-separated-values', 'text/x-comma-separated-values',
'text/comma-separated-values', 'text/comma-separated-values',
'application/octet-stream',
'application/vnd.ms-excel', 'application/vnd.ms-excel',
'application/x-csv', 'application/x-csv',
'text/x-csv', 'text/x-csv',
...@@ -53,26 +52,24 @@ class Mimes ...@@ -53,26 +52,24 @@ class Mimes
'dms' => 'application/octet-stream', 'dms' => 'application/octet-stream',
'lha' => 'application/octet-stream', 'lha' => 'application/octet-stream',
'lzh' => 'application/octet-stream', 'lzh' => 'application/octet-stream',
'exe' => ['application/octet-stream', 'application/x-msdownload'], 'exe' => ['application/octet-stream',
'application/vnd.microsoft.portable-executable',
'application/x-dosexec',
'application/x-msdownload'],
'class' => 'application/octet-stream', 'class' => 'application/octet-stream',
'psd' => ['application/x-photoshop', 'image/vnd.adobe.photoshop'], 'psd' => ['application/x-photoshop', 'image/vnd.adobe.photoshop'],
'so' => 'application/octet-stream', 'so' => 'application/octet-stream',
'sea' => 'application/octet-stream', 'sea' => 'application/octet-stream',
'dll' => 'application/octet-stream', 'dll' => 'application/octet-stream',
'oda' => 'application/oda', 'oda' => 'application/oda',
'pdf' => [ 'pdf' => ['application/pdf', 'application/force-download', 'application/x-download'],
'application/pdf', 'ai' => ['application/pdf', 'application/postscript'],
'application/force-download', 'eps' => 'application/postscript',
'application/x-download', 'ps' => 'application/postscript',
'binary/octet-stream', 'smi' => 'application/smil',
], 'smil' => 'application/smil',
'ai' => ['application/pdf', 'application/postscript'], 'mif' => 'application/vnd.mif',
'eps' => 'application/postscript', 'xls' => [
'ps' => 'application/postscript',
'smi' => 'application/smil',
'smil' => 'application/smil',
'mif' => 'application/vnd.mif',
'xls' => [
'application/vnd.ms-excel', 'application/vnd.ms-excel',
'application/msexcel', 'application/msexcel',
'application/x-msexcel', 'application/x-msexcel',
...@@ -92,21 +89,17 @@ class Mimes ...@@ -92,21 +89,17 @@ class Mimes
'application/vnd.ms-office', 'application/vnd.ms-office',
'application/msword', 'application/msword',
], ],
'pptx' => [ 'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation'],
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/x-zip',
'application/zip',
],
'wbxml' => 'application/wbxml', 'wbxml' => 'application/wbxml',
'wmlc' => 'application/wmlc', 'wmlc' => 'application/wmlc',
'dcr' => 'application/x-director', 'dcr' => 'application/x-director',
'dir' => 'application/x-director', 'dir' => 'application/x-director',
'dxr' => 'application/x-director', 'dxr' => 'application/x-director',
'dvi' => 'application/x-dvi', 'dvi' => 'application/x-dvi',
'gtar' => 'application/x-gtar', 'gtar' => 'application/x-gtar',
'gz' => 'application/x-gzip', 'gz' => 'application/x-gzip',
'gzip' => 'application/x-gzip', 'gzip' => 'application/x-gzip',
'php' => [ 'php' => [
'application/x-php', 'application/x-php',
'application/x-httpd-php', 'application/x-httpd-php',
'application/php', 'application/php',
...@@ -114,45 +107,41 @@ class Mimes ...@@ -114,45 +107,41 @@ class Mimes
'text/x-php', 'text/x-php',
'application/x-httpd-php-source', 'application/x-httpd-php-source',
], ],
'php4' => 'application/x-httpd-php', 'php4' => 'application/x-httpd-php',
'php3' => 'application/x-httpd-php', 'php3' => 'application/x-httpd-php',
'phtml' => 'application/x-httpd-php', 'phtml' => 'application/x-httpd-php',
'phps' => 'application/x-httpd-php-source', 'phps' => 'application/x-httpd-php-source',
'js' => ['application/x-javascript', 'text/plain'], 'js' => ['application/x-javascript', 'text/plain'],
'swf' => 'application/x-shockwave-flash', 'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit', 'sit' => 'application/x-stuffit',
'tar' => 'application/x-tar', 'tar' => 'application/x-tar',
'tgz' => ['application/x-tar', 'application/x-gzip-compressed'], 'tgz' => ['application/x-tar', 'application/x-gzip-compressed'],
'z' => 'application/x-compress', 'z' => 'application/x-compress',
'xhtml' => 'application/xhtml+xml', 'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml', 'xht' => 'application/xhtml+xml',
'zip' => [ 'zip' => [
'application/x-zip', 'application/x-zip',
'application/zip', 'application/zip',
'application/x-zip-compressed', 'application/x-zip-compressed',
'application/s-compressed', 'application/s-compressed',
'multipart/x-zip', 'multipart/x-zip',
], ],
'rar' => [ 'rar' => ['application/vnd.rar', 'application/x-rar', 'application/rar', 'application/x-rar-compressed'],
'application/x-rar', 'mid' => 'audio/midi',
'application/rar',
'application/x-rar-compressed',
],
'mid' => 'audio/midi',
'midi' => 'audio/midi', 'midi' => 'audio/midi',
'mp3' => ['audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3', 'application/octet-stream'],
'mpga' => 'audio/mpeg', 'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg', 'mp2' => 'audio/mpeg',
'mp3' => ['audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'], 'aif' => ['audio/x-aiff', 'audio/aiff'],
'aif' => ['audio/x-aiff', 'audio/aiff'],
'aiff' => ['audio/x-aiff', 'audio/aiff'], 'aiff' => ['audio/x-aiff', 'audio/aiff'],
'aifc' => 'audio/x-aiff', 'aifc' => 'audio/x-aiff',
'ram' => 'audio/x-pn-realaudio', 'ram' => 'audio/x-pn-realaudio',
'rm' => 'audio/x-pn-realaudio', 'rm' => 'audio/x-pn-realaudio',
'rpm' => 'audio/x-pn-realaudio-plugin', 'rpm' => 'audio/x-pn-realaudio-plugin',
'ra' => 'audio/x-realaudio', 'ra' => 'audio/x-realaudio',
'rv' => 'video/vnd.rn-realvideo', 'rv' => 'video/vnd.rn-realvideo',
'wav' => ['audio/x-wav', 'audio/wave', 'audio/wav'], 'wav' => ['audio/x-wav', 'audio/wave', 'audio/wav'],
'bmp' => [ 'bmp' => [
'image/bmp', 'image/bmp',
'image/x-bmp', 'image/x-bmp',
'image/x-bitmap', 'image/x-bitmap',
...@@ -165,52 +154,48 @@ class Mimes ...@@ -165,52 +154,48 @@ class Mimes
'application/x-bmp', 'application/x-bmp',
'application/x-win-bitmap', 'application/x-win-bitmap',
], ],
'gif' => 'image/gif', 'gif' => 'image/gif',
'jpg' => ['image/jpeg', 'image/pjpeg'], 'jpg' => ['image/jpeg', 'image/pjpeg'],
'jpeg' => ['image/jpeg', 'image/pjpeg'], 'jpeg' => ['image/jpeg', 'image/pjpeg'],
'jpe' => ['image/jpeg', 'image/pjpeg'], 'jpe' => ['image/jpeg', 'image/pjpeg'],
'jp2' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'], 'jp2' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'],
'j2k' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'], 'j2k' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'],
'jpf' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'], 'jpf' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'],
'jpg2' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'], 'jpg2' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'],
'jpx' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'], 'jpx' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'],
'jpm' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'], 'jpm' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'],
'mj2' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'], 'mj2' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'],
'mjp2' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'], 'mjp2' => ['image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'],
'png' => ['image/png', 'image/x-png'], 'png' => ['image/png', 'image/x-png'],
'tif' => 'image/tiff', 'webp' => 'image/webp',
'tiff' => 'image/tiff', 'tif' => 'image/tiff',
'css' => ['text/css', 'text/plain'], 'tiff' => 'image/tiff',
'html' => ['text/html', 'text/plain'], 'css' => ['text/css', 'text/plain'],
'htm' => ['text/html', 'text/plain'], 'html' => ['text/html', 'text/plain'],
'htm' => ['text/html', 'text/plain'],
'shtml' => ['text/html', 'text/plain'], 'shtml' => ['text/html', 'text/plain'],
'txt' => 'text/plain', 'txt' => 'text/plain',
'text' => 'text/plain', 'text' => 'text/plain',
'log' => ['text/plain', 'text/x-log'], 'log' => ['text/plain', 'text/x-log'],
'rtx' => 'text/richtext', 'rtx' => 'text/richtext',
'rtf' => 'text/rtf', 'rtf' => 'text/rtf',
'xml' => ['application/xml', 'text/xml', 'text/plain'], 'xml' => ['application/xml', 'text/xml', 'text/plain'],
'xsl' => ['application/xml', 'text/xsl', 'text/xml'], 'xsl' => ['application/xml', 'text/xsl', 'text/xml'],
'mpeg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg', 'mpg' => 'video/mpeg',
'mpe' => 'video/mpeg', 'mpe' => 'video/mpeg',
'qt' => 'video/quicktime', 'qt' => 'video/quicktime',
'mov' => 'video/quicktime', 'mov' => 'video/quicktime',
'avi' => [ 'avi' => ['video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'],
'video/x-msvideo',
'video/msvideo',
'video/avi',
'application/x-troff-msvideo',
],
'movie' => 'video/x-sgi-movie', 'movie' => 'video/x-sgi-movie',
'doc' => ['application/msword', 'application/vnd.ms-office'], 'doc' => ['application/msword', 'application/vnd.ms-office'],
'docx' => [ 'docx' => [
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/zip', 'application/zip',
'application/msword', 'application/msword',
'application/x-zip', 'application/x-zip',
], ],
'dot' => ['application/msword', 'application/vnd.ms-office'], 'dot' => ['application/msword', 'application/vnd.ms-office'],
'dotx' => [ 'dotx' => [
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/zip', 'application/zip',
...@@ -223,66 +208,52 @@ class Mimes ...@@ -223,66 +208,52 @@ class Mimes
'application/msword', 'application/msword',
'application/x-zip', 'application/x-zip',
], ],
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
'word' => ['application/msword', 'application/octet-stream'], 'word' => ['application/msword', 'application/octet-stream'],
'xl' => 'application/excel', 'xl' => 'application/excel',
'eml' => 'message/rfc822', 'eml' => 'message/rfc822',
'json' => ['application/json', 'text/json'], 'json' => ['application/json', 'text/json', 'text/plain'],
'pem' => [ 'pem' => ['application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'],
'application/x-x509-user-cert', 'p10' => ['application/x-pkcs10', 'application/pkcs10'],
'application/x-pem-file', 'p12' => 'application/x-pkcs12',
'application/octet-stream', 'p7a' => 'application/x-pkcs7-signature',
], 'p7c' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'],
'p10' => ['application/x-pkcs10', 'application/pkcs10'], 'p7m' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'],
'p12' => 'application/x-pkcs12', 'p7r' => 'application/x-pkcs7-certreqresp',
'p7a' => 'application/x-pkcs7-signature', 'p7s' => 'application/pkcs7-signature',
'p7c' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'], 'crt' => ['application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'],
'p7m' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'], 'crl' => ['application/pkix-crl', 'application/pkcs-crl'],
'p7r' => 'application/x-pkcs7-certreqresp', 'der' => 'application/x-x509-ca-cert',
'p7s' => 'application/pkcs7-signature', 'kdb' => 'application/octet-stream',
'crt' => [ 'pgp' => 'application/pgp',
'application/x-x509-ca-cert', 'gpg' => 'application/gpg-keys',
'application/x-x509-user-cert', 'sst' => 'application/octet-stream',
'application/pkix-cert', 'csr' => 'application/octet-stream',
], 'rsa' => 'application/x-pkcs7',
'crl' => ['application/pkix-crl', 'application/pkcs-crl'], 'cer' => ['application/pkix-cert', 'application/x-x509-ca-cert'],
'der' => 'application/x-x509-ca-cert', '3g2' => 'video/3gpp2',
'kdb' => 'application/octet-stream', '3gp' => ['video/3gp', 'video/3gpp'],
'pgp' => 'application/pgp', 'mp4' => 'video/mp4',
'gpg' => 'application/gpg-keys', 'm4a' => ['audio/m4a', 'audio/x-m4a', 'application/octet-stream'],
'sst' => 'application/octet-stream', 'f4v' => ['video/mp4', 'video/x-f4v'],
'csr' => 'application/octet-stream', 'flv' => 'video/x-flv',
'rsa' => 'application/x-pkcs7',
'cer' => ['application/pkix-cert', 'application/x-x509-ca-cert'],
'3g2' => 'video/3gpp2',
'3gp' => ['video/3gp', 'video/3gpp'],
'mp4' => 'video/mp4',
'm4a' => 'audio/x-m4a',
'f4v' => ['video/mp4', 'video/x-f4v'],
'flv' => 'video/x-flv',
'webm' => 'video/webm', 'webm' => 'video/webm',
'aac' => 'audio/x-acc', 'aac' => 'audio/x-acc',
'm4u' => 'application/vnd.mpegurl', 'm4u' => 'application/vnd.mpegurl',
'm3u' => 'text/plain', 'm3u' => 'text/plain',
'xspf' => 'application/xspf+xml', 'xspf' => 'application/xspf+xml',
'vlc' => 'application/videolan', 'vlc' => 'application/videolan',
'wmv' => ['video/x-ms-wmv', 'video/x-ms-asf'], 'wmv' => ['video/x-ms-wmv', 'video/x-ms-asf'],
'au' => 'audio/x-au', 'au' => 'audio/x-au',
'ac3' => 'audio/ac3', 'ac3' => 'audio/ac3',
'flac' => 'audio/x-flac', 'flac' => 'audio/x-flac',
'ogg' => ['audio/ogg', 'video/ogg', 'application/ogg'], 'ogg' => ['audio/ogg', 'video/ogg', 'application/ogg'],
'kmz' => [ 'kmz' => ['application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'],
'application/vnd.google-earth.kmz', 'kml' => ['application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'],
'application/zip', 'ics' => 'text/calendar',
'application/x-zip',
],
'kml' => [
'application/vnd.google-earth.kml+xml',
'application/xml',
'text/xml',
],
'ics' => 'text/calendar',
'ical' => 'text/calendar', 'ical' => 'text/calendar',
'zsh' => 'text/x-scriptzsh', 'zsh' => 'text/x-scriptzsh',
'7zip' => [ '7zip' => [
'application/x-compressed', 'application/x-compressed',
'application/x-zip-compressed', 'application/x-zip-compressed',
...@@ -305,27 +276,24 @@ class Mimes ...@@ -305,27 +276,24 @@ class Mimes
'application/x-jar', 'application/x-jar',
'application/x-compressed', 'application/x-compressed',
], ],
'svg' => ['image/svg+xml', 'application/xml', 'text/xml'], 'svg' => ['image/svg+xml', 'image/svg', 'application/xml', 'text/xml'],
'vcf' => 'text/x-vcard', 'vcf' => 'text/x-vcard',
'srt' => ['text/srt', 'text/plain', 'application/octet-stream'], 'srt' => ['application/x-subrip', 'text/srt', 'text/plain', 'application/octet-stream'],
'vtt' => ['text/vtt', 'text/plain'], 'vtt' => ['text/vtt', 'text/plain'],
'ico' => ['image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'], 'ico' => ['image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'],
'stl' => ['application/sla', 'application/vnd.ms-pki.stl', 'application/x-navistyle'],
]; ];
//--------------------------------------------------------------------
/** /**
* Attempts to determine the best mime type for the given file extension. * Attempts to determine the best mime type for the given file extension.
* *
* @param string $extension
*
* @return string|null The mime type found, or none if unable to determine. * @return string|null The mime type found, or none if unable to determine.
*/ */
public static function guessTypeFromExtension(string $extension) public static function guessTypeFromExtension(string $extension): ?string
{ {
$extension = trim(strtolower($extension), '. '); $extension = trim(strtolower($extension), '. ');
if (!array_key_exists($extension, static::$mimes)) { if (! array_key_exists($extension, static::$mimes)) {
return null; return null;
} }
...@@ -334,48 +302,35 @@ class Mimes ...@@ -334,48 +302,35 @@ class Mimes
: static::$mimes[$extension]; : static::$mimes[$extension];
} }
//--------------------------------------------------------------------
/** /**
* Attempts to determine the best file extension for a given mime type. * Attempts to determine the best file extension for a given mime type.
* *
* @param string $type * @param string|null $proposedExtension - default extension (in case there is more than one with the same mime type)
* @param string $proposed_extension - default extension (in case there is more than one with the same mime type)
*
* @return string|null The extension determined, or null if unable to match. * @return string|null The extension determined, or null if unable to match.
*/ */
public static function guessExtensionFromType( public static function guessExtensionFromType(string $type, ?string $proposedExtension = null): ?string
string $type, {
?string $proposed_extension = null
) {
$type = trim(strtolower($type), '. '); $type = trim(strtolower($type), '. ');
$proposed_extension = trim(strtolower($proposed_extension)); $proposedExtension = trim(strtolower($proposedExtension ?? ''));
if ( if (
!is_null($proposed_extension) && $proposedExtension !== ''
array_key_exists($proposed_extension, static::$mimes) && && array_key_exists($proposedExtension, static::$mimes)
in_array( && in_array($type, (array) static::$mimes[$proposedExtension], true)
$type,
is_string(static::$mimes[$proposed_extension])
? [static::$mimes[$proposed_extension]]
: static::$mimes[$proposed_extension]
)
) { ) {
return $proposed_extension; // The detected mime type matches with the proposed extension.
return $proposedExtension;
} }
// Reverse check the mime type list if no extension was proposed.
// This search is order sensitive!
foreach (static::$mimes as $ext => $types) { foreach (static::$mimes as $ext => $types) {
if ( if (in_array($type, (array) $types, true)) {
(is_string($types) && $types === $type) ||
(is_array($types) && in_array($type, $types))
) {
return $ext; return $ext;
} }
} }
return null; return null;
} }
//--------------------------------------------------------------------
} }
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
// Cannot extend BaseConfig or looping resources occurs. use CodeIgniter\Modules\Modules as BaseModules;
class Modules
/**
* Modules Configuration.
*
* NOTE: This class is required prior to Autoloader instantiation,
* and does not extend BaseConfig.
*
* @immutable
*/
class Modules extends BaseModules
{ {
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Auto-Discovery Enabled? * Enable Auto-Discovery?
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| If true, then auto-discovery will happen across all elements listed in * If true, then auto-discovery will happen across all elements listed in
| $activeExplorers below. If false, no auto-discovery will happen at all, * $aliases below. If false, no auto-discovery will happen at all,
| giving a slight performance boost. * giving a slight performance boost.
*
* @var boolean
*/ */
public $enabled = true; public $enabled = true;
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Auto-Discovery Within Composer Packages Enabled? * Enable Auto-Discovery Within Composer Packages?
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| If true, then auto-discovery will happen across all namespaces loaded * If true, then auto-discovery will happen across all namespaces loaded
| by Composer, as well as the namespaces configured locally. * by Composer, as well as the namespaces configured locally.
*
* @var boolean
*/ */
public $discoverInComposer = true; public $discoverInComposer = true;
/* /**
|-------------------------------------------------------------------------- * The Composer package list for Auto-Discovery
| Auto-discover Rules * This setting is optional.
|-------------------------------------------------------------------------- *
| * E.g.:
| Lists the aliases of all discovery classes that will be active * [
| and used during the current application request. If it is not * 'only' => [
| listed here, only the base application elements will be used. * // List up all packages to auto-discover
*/ * 'codeigniter4/shield',
public $activeExplorers = ['events', 'registrars', 'routes', 'services']; * ],
* ]
* or
* [
* 'exclude' => [
* // List up packages to exclude.
* 'pestphp/pest',
* ],
* ]
*
* @var array{only?: list<string>, exclude?: list<string>}
*/
public $composerPackages = [];
/** /**
* Should the application auto-discover the requested resources. * --------------------------------------------------------------------------
* Auto-Discovery Rules
* --------------------------------------------------------------------------
* *
* Valid values are: * Aliases list of all discovery classes that will be active and used during
* - events * the current application request.
* - registrars
* - routes
* - services
* *
* @param string $alias * If it is not listed, only the base application elements will be used.
* *
* @return boolean * @var list<string>
*/ */
public function shouldDiscover(string $alias) public $aliases = ['events', 'filters', 'registrars', 'routes', 'services'];
{
if (!$this->enabled) {
return false;
}
$alias = strtolower($alias);
return in_array($alias, $this->activeExplorers);
}
} }
<?php
declare(strict_types=1);
namespace Config;
/**
* Optimization Configuration.
*
* NOTE: This class does not extend BaseConfig for performance reasons.
* So you cannot replace the property values with Environment Variables.
*
* @immutable
*/
class Optimize
{
/**
* --------------------------------------------------------------------------
* Config Caching
* --------------------------------------------------------------------------
*
* @see https://codeigniter.com/user_guide/concepts/factories.html#config-caching
*/
public bool $configCacheEnabled = false;
/**
* --------------------------------------------------------------------------
* Config Caching
* --------------------------------------------------------------------------
*
* @see https://codeigniter.com/user_guide/concepts/autoloader.html#file-locator-caching
*/
public bool $locatorCacheEnabled = false;
}
<?php <?php
declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
class Pager extends BaseConfig class Pager extends BaseConfig
{ {
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Templates * Templates
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| Pagination links are rendered out using views to configure their * Pagination links are rendered out using views to configure their
| appearance. This array contains aliases and the view names to * appearance. This array contains aliases and the view names to
| use when rendering the links. * use when rendering the links.
| *
| Within each view, the Pager object will be available as $pager, * Within each view, the Pager object will be available as $pager,
| and the desired group as $pagerGroup; * and the desired group as $pagerGroup;
| *
*/ * @var array<string, string>
public $templates = [ */
'default_full' => 'App\Views\pager\default_full', public array $templates = [
'default_full' => 'App\Views\pager\default_full',
'default_simple' => 'CodeIgniter\Pager\Views\default_simple', 'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
'default_head' => 'CodeIgniter\Pager\Views\default_head', 'default_head' => 'CodeIgniter\Pager\Views\default_head',
]; ];
/* /**
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| Items Per Page * Items Per Page
|-------------------------------------------------------------------------- * --------------------------------------------------------------------------
| *
| The default number of results shown in a single page. * The default number of results shown in a single page.
| */
*/ public int $perPage = 20;
public $perPage = 20;
} }