fix: update Router to include latest CI changes with alternate-content logic
This commit is contained in:
parent
7ff1dbe903
commit
ae57601c83
|
@ -5,7 +5,6 @@ declare(strict_types=1);
|
||||||
namespace Config;
|
namespace Config;
|
||||||
|
|
||||||
use CodeIgniter\Config\BaseConfig;
|
use CodeIgniter\Config\BaseConfig;
|
||||||
use CodeIgniter\Session\Handlers\FileHandler;
|
|
||||||
|
|
||||||
class App extends BaseConfig
|
class App extends BaseConfig
|
||||||
{
|
{
|
||||||
|
@ -138,191 +137,6 @@ class App extends BaseConfig
|
||||||
*/
|
*/
|
||||||
public bool $forceGlobalSecureRequests = true;
|
public bool $forceGlobalSecureRequests = true;
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Session Driver
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* The session storage driver to use:
|
|
||||||
* - `CodeIgniter\Session\Handlers\FileHandler`
|
|
||||||
* - `CodeIgniter\Session\Handlers\DatabaseHandler`
|
|
||||||
* - `CodeIgniter\Session\Handlers\MemcachedHandler`
|
|
||||||
* - `CodeIgniter\Session\Handlers\RedisHandler`
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Session::$driver instead.
|
|
||||||
*/
|
|
||||||
public string $sessionDriver = FileHandler::class;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Session Cookie Name
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* The session cookie name, must contain only [0-9a-z_-] characters
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Session::$cookieName instead.
|
|
||||||
*/
|
|
||||||
public string $sessionCookieName = 'ci_session';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Session Expiration
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* The number of SECONDS you want the session to last.
|
|
||||||
* Setting to 0 (zero) means expire when the browser is closed.
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Session::$expiration instead.
|
|
||||||
*/
|
|
||||||
public int $sessionExpiration = 7200;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Session Save Path
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* The location to save sessions to and is driver dependent.
|
|
||||||
*
|
|
||||||
* For the 'files' driver, it's a path to a writable directory.
|
|
||||||
* WARNING: Only absolute paths are supported!
|
|
||||||
*
|
|
||||||
* For the 'database' driver, it's a table name.
|
|
||||||
* Please read up the manual for the format with other session drivers.
|
|
||||||
*
|
|
||||||
* IMPORTANT: You are REQUIRED to set a valid save path!
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Session::$savePath instead.
|
|
||||||
*/
|
|
||||||
public string $sessionSavePath = WRITEPATH . 'session';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Session Match IP
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Whether to match the user's IP address when reading the session data.
|
|
||||||
*
|
|
||||||
* WARNING: If you're using the database driver, don't forget to update
|
|
||||||
* your session table's PRIMARY KEY when changing this setting.
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Session::$matchIP instead.
|
|
||||||
*/
|
|
||||||
public bool $sessionMatchIP = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Session Time to Update
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* How many seconds between CI regenerating the session ID.
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Session::$timeToUpdate instead.
|
|
||||||
*/
|
|
||||||
public int $sessionTimeToUpdate = 300;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Session Regenerate Destroy
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Whether to destroy session data associated with the old session ID
|
|
||||||
* when auto-regenerating the session ID. When set to FALSE, the data
|
|
||||||
* will be later deleted by the garbage collector.
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Session::$regenerateDestroy instead.
|
|
||||||
*/
|
|
||||||
public bool $sessionRegenerateDestroy = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Session Database Group
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* DB Group for the database session.
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Session::$DBGroup instead.
|
|
||||||
*/
|
|
||||||
public ?string $sessionDBGroup = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Cookie Prefix
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Set a cookie name prefix if you need to avoid collisions.
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Cookie::$prefix property instead.
|
|
||||||
*/
|
|
||||||
public string $cookiePrefix = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Cookie Domain
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Set to `.your-domain.com` for site-wide cookies.
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Cookie::$domain property instead.
|
|
||||||
*/
|
|
||||||
public string $cookieDomain = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Cookie Path
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Typically will be a forward slash.
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Cookie::$path property instead.
|
|
||||||
*/
|
|
||||||
public string $cookiePath = '/';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Cookie Secure
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Cookie will only be set if a secure HTTPS connection exists.
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Cookie::$secure property instead.
|
|
||||||
*/
|
|
||||||
public bool $cookieSecure = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Cookie HttpOnly
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Cookie will only be accessible via HTTP(S) (no JavaScript).
|
|
||||||
*
|
|
||||||
* @deprecated use Config\Cookie::$httponly property instead.
|
|
||||||
*/
|
|
||||||
public bool $cookieHTTPOnly = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Cookie SameSite
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Configure cookie SameSite setting. Allowed values are:
|
|
||||||
* - None
|
|
||||||
* - Lax
|
|
||||||
* - Strict
|
|
||||||
* - ''
|
|
||||||
*
|
|
||||||
* Alternatively, you can use the constant names:
|
|
||||||
* - `Cookie::SAMESITE_NONE`
|
|
||||||
* - `Cookie::SAMESITE_LAX`
|
|
||||||
* - `Cookie::SAMESITE_STRICT`
|
|
||||||
*
|
|
||||||
* Defaults to `Lax` for compatibility with modern browsers. Setting `''`
|
|
||||||
* (empty string) means default SameSite attribute set by browsers (`Lax`)
|
|
||||||
* will be set on cookies. If set to `None`, `$cookieSecure` must also be set.
|
|
||||||
*
|
|
||||||
* @deprecated `Config\Cookie` $samesite property is used.
|
|
||||||
*/
|
|
||||||
public ?string $cookieSameSite = 'Lax';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* --------------------------------------------------------------------------
|
* --------------------------------------------------------------------------
|
||||||
* Reverse Proxy IPs
|
* Reverse Proxy IPs
|
||||||
|
@ -346,91 +160,6 @@ class App extends BaseConfig
|
||||||
*/
|
*/
|
||||||
public array $proxyIPs = [];
|
public array $proxyIPs = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* CSRF Token Name
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* The token name.
|
|
||||||
*
|
|
||||||
* @deprecated Use `Config\Security` $tokenName property instead of using this property.
|
|
||||||
*/
|
|
||||||
public string $CSRFTokenName = 'csrf_test_name';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* CSRF Header Name
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* The header name.
|
|
||||||
*
|
|
||||||
* @deprecated Use `Config\Security` $headerName property instead of using this property.
|
|
||||||
*/
|
|
||||||
public string $CSRFHeaderName = 'X-CSRF-TOKEN';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* CSRF Cookie Name
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* The cookie name.
|
|
||||||
*
|
|
||||||
* @deprecated Use `Config\Security` $cookieName property instead of using this property.
|
|
||||||
*/
|
|
||||||
public string $CSRFCookieName = 'csrf_cookie_name';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* CSRF Expire
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* The number in seconds the token should expire.
|
|
||||||
*
|
|
||||||
* @deprecated Use `Config\Security` $expire property instead of using this property.
|
|
||||||
*/
|
|
||||||
public int $CSRFExpire = 7200;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* CSRF Regenerate
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Regenerate token on every submission?
|
|
||||||
*
|
|
||||||
* @deprecated Use `Config\Security` $regenerate property instead of using this property.
|
|
||||||
*/
|
|
||||||
public bool $CSRFRegenerate = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* CSRF Redirect
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Redirect to previous page with error on failure?
|
|
||||||
*
|
|
||||||
* @deprecated Use `Config\Security` $redirect property instead of using this property.
|
|
||||||
*/
|
|
||||||
public bool $CSRFRedirect = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* CSRF SameSite
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Setting for CSRF SameSite cookie token. Allowed values are:
|
|
||||||
* - None
|
|
||||||
* - Lax
|
|
||||||
* - Strict
|
|
||||||
* - ''
|
|
||||||
*
|
|
||||||
* Defaults to `Lax` as recommended in this link:
|
|
||||||
*
|
|
||||||
* @see https://portswigger.net/web-security/csrf/samesite-cookies
|
|
||||||
*
|
|
||||||
* @deprecated Use `Config\Security` $samesite property instead of using this property.
|
|
||||||
*/
|
|
||||||
public string $CSRFSameSite = 'Lax';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* --------------------------------------------------------------------------
|
* --------------------------------------------------------------------------
|
||||||
* Content Security Policy
|
* Content Security Policy
|
||||||
|
|
|
@ -18,5 +18,5 @@ class CURLRequest extends BaseConfig
|
||||||
* If true, all the options won't be reset between requests.
|
* If true, all the options won't be reset between requests.
|
||||||
* It may cause an error request with unnecessary headers.
|
* It may cause an error request with unnecessary headers.
|
||||||
*/
|
*/
|
||||||
public bool $shareOptions = true;
|
public bool $shareOptions = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,8 @@ class Cookie extends BaseConfig
|
||||||
* Defaults to `Lax` for compatibility with modern browsers. Setting `''`
|
* Defaults to `Lax` for compatibility with modern browsers. Setting `''`
|
||||||
* (empty string) means default SameSite attribute set by browsers (`Lax`)
|
* (empty string) means default SameSite attribute set by browsers (`Lax`)
|
||||||
* will be set on cookies. If set to `None`, `$secure` must also be set.
|
* will be set on cookies. If set to `None`, `$secure` must also be set.
|
||||||
|
*
|
||||||
|
* @phpstan-var 'None'|'Lax'|'Strict'|''
|
||||||
*/
|
*/
|
||||||
public string $samesite = 'Lax';
|
public string $samesite = 'Lax';
|
||||||
|
|
||||||
|
|
|
@ -27,23 +27,24 @@ class Database extends Config
|
||||||
* @var array<string, mixed>
|
* @var array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public array $default = [
|
public array $default = [
|
||||||
'DSN' => '',
|
'DSN' => '',
|
||||||
'hostname' => 'localhost',
|
'hostname' => 'localhost',
|
||||||
'username' => '',
|
'username' => '',
|
||||||
'password' => '',
|
'password' => '',
|
||||||
'database' => '',
|
'database' => '',
|
||||||
'DBDriver' => 'MySQLi',
|
'DBDriver' => 'MySQLi',
|
||||||
'DBPrefix' => 'cp_',
|
'DBPrefix' => 'cp_',
|
||||||
'pConnect' => false,
|
'pConnect' => false,
|
||||||
'DBDebug' => true,
|
'DBDebug' => true,
|
||||||
'charset' => 'utf8mb4',
|
'charset' => 'utf8mb4',
|
||||||
'DBCollat' => 'utf8mb4_unicode_ci',
|
'DBCollat' => 'utf8mb4_unicode_ci',
|
||||||
'swapPre' => '',
|
'swapPre' => '',
|
||||||
'encrypt' => false,
|
'encrypt' => false,
|
||||||
'compress' => false,
|
'compress' => false,
|
||||||
'strictOn' => false,
|
'strictOn' => false,
|
||||||
'failover' => [],
|
'failover' => [],
|
||||||
'port' => 3306,
|
'port' => 3306,
|
||||||
|
'numberNative' => false,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,6 +10,7 @@ use App\Models\EpisodeModel;
|
||||||
use CodeIgniter\Debug\Toolbar\Collectors\Database;
|
use CodeIgniter\Debug\Toolbar\Collectors\Database;
|
||||||
use CodeIgniter\Events\Events;
|
use CodeIgniter\Events\Events;
|
||||||
use CodeIgniter\Exceptions\FrameworkException;
|
use CodeIgniter\Exceptions\FrameworkException;
|
||||||
|
use CodeIgniter\HotReloader\HotReloader;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
|
@ -50,6 +51,13 @@ Events::on('pre_system', static function () {
|
||||||
if (CI_DEBUG && ! is_cli()) {
|
if (CI_DEBUG && ! is_cli()) {
|
||||||
Events::on('DBQuery', Database::class . '::collect');
|
Events::on('DBQuery', Database::class . '::collect');
|
||||||
Services::toolbar()->respond();
|
Services::toolbar()->respond();
|
||||||
|
|
||||||
|
// Hot Reload route - for framework use on the hot reloader.
|
||||||
|
if (ENVIRONMENT === 'development') {
|
||||||
|
Services::routes()->get('__hot-reload', static function (): void {
|
||||||
|
(new HotReloader())->run();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,10 @@ declare(strict_types=1);
|
||||||
namespace Config;
|
namespace Config;
|
||||||
|
|
||||||
use CodeIgniter\Config\BaseConfig;
|
use CodeIgniter\Config\BaseConfig;
|
||||||
|
use CodeIgniter\Debug\ExceptionHandler;
|
||||||
|
use CodeIgniter\Debug\ExceptionHandlerInterface;
|
||||||
use Psr\Log\LogLevel;
|
use Psr\Log\LogLevel;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup how the exception handler works.
|
* Setup how the exception handler works.
|
||||||
|
@ -80,4 +83,28 @@ class Exceptions extends BaseConfig
|
||||||
* to capture logging the deprecations.
|
* to capture logging the deprecations.
|
||||||
*/
|
*/
|
||||||
public string $deprecationLogLevel = LogLevel::WARNING;
|
public string $deprecationLogLevel = LogLevel::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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,15 +34,15 @@ class Fediverse extends FediverseBaseConfig
|
||||||
try {
|
try {
|
||||||
$appTheme = service('settings')
|
$appTheme = service('settings')
|
||||||
->get('App.theme');
|
->get('App.theme');
|
||||||
$defaultBanner = config('Images')
|
$defaultBanner = config(Images::class)
|
||||||
->podcastBannerDefaultPaths[$appTheme] ?? config('Images')->podcastBannerDefaultPaths['default'];
|
->podcastBannerDefaultPaths[$appTheme] ?? config(Images::class)->podcastBannerDefaultPaths['default'];
|
||||||
} catch (Exception) {
|
} catch (Exception) {
|
||||||
$defaultBanner = config('Images')
|
$defaultBanner = config(Images::class)
|
||||||
->podcastBannerDefaultPaths['default'];
|
->podcastBannerDefaultPaths['default'];
|
||||||
}
|
}
|
||||||
|
|
||||||
['dirname' => $dirname, 'extension' => $extension, 'filename' => $filename] = pathinfo(
|
['dirname' => $dirname, 'extension' => $extension, 'filename' => $filename] = pathinfo(
|
||||||
(string) $defaultBanner['path']
|
$defaultBanner['path']
|
||||||
);
|
);
|
||||||
$defaultBannerPath = $filename;
|
$defaultBannerPath = $filename;
|
||||||
if ($dirname !== '.') {
|
if ($dirname !== '.') {
|
||||||
|
|
|
@ -11,6 +11,8 @@ use CodeIgniter\Filters\DebugToolbar;
|
||||||
use CodeIgniter\Filters\Honeypot;
|
use CodeIgniter\Filters\Honeypot;
|
||||||
use CodeIgniter\Filters\InvalidChars;
|
use CodeIgniter\Filters\InvalidChars;
|
||||||
use CodeIgniter\Filters\SecureHeaders;
|
use CodeIgniter\Filters\SecureHeaders;
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
use Modules\Analytics\Config\Analytics;
|
||||||
use Modules\Auth\Filters\PermissionFilter;
|
use Modules\Auth\Filters\PermissionFilter;
|
||||||
|
|
||||||
class Filters extends BaseConfig
|
class Filters extends BaseConfig
|
||||||
|
@ -19,6 +21,7 @@ class Filters extends BaseConfig
|
||||||
* Configures aliases for Filter classes to make reading things nicer and simpler.
|
* Configures aliases for Filter classes to make reading things nicer and simpler.
|
||||||
*
|
*
|
||||||
* @var array<string, string>
|
* @var array<string, string>
|
||||||
|
* @phpstan-var array<string, class-string>
|
||||||
*/
|
*/
|
||||||
public array $aliases = [
|
public array $aliases = [
|
||||||
'csrf' => CSRF::class,
|
'csrf' => CSRF::class,
|
||||||
|
@ -32,7 +35,8 @@ class Filters extends BaseConfig
|
||||||
/**
|
/**
|
||||||
* List of filter aliases that are always applied before and after every request.
|
* List of filter aliases that are always applied before and after every request.
|
||||||
*
|
*
|
||||||
* @var array<string, mixed>
|
* @var array<string, array<string, array<string, string>>>|array<string, array<string>>
|
||||||
|
* @phpstan-var array<string, list<string>>|array<string, array<string, array<string, string>>>
|
||||||
*/
|
*/
|
||||||
public array $globals = [
|
public array $globals = [
|
||||||
'before' => [
|
'before' => [
|
||||||
|
@ -76,7 +80,7 @@ class Filters extends BaseConfig
|
||||||
|
|
||||||
$this->filters = [
|
$this->filters = [
|
||||||
'session' => [
|
'session' => [
|
||||||
'before' => [config('Admin')->gateway . '*', config('Analytics')->gateway . '*'],
|
'before' => [config(Admin::class)->gateway . '*', config(Analytics::class)->gateway . '*'],
|
||||||
],
|
],
|
||||||
'podcast-unlock' => [
|
'podcast-unlock' => [
|
||||||
'before' => ['*@*/episodes/*'],
|
'before' => ['*@*/episodes/*'],
|
||||||
|
|
|
@ -2,28 +2,10 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Config;
|
use CodeIgniter\Router\RouteCollection;
|
||||||
|
|
||||||
// Create a new instance of our RouteCollection class.
|
|
||||||
$routes = Services::routes();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* --------------------------------------------------------------------
|
* @var RouteCollection $routes
|
||||||
* Router Setup
|
|
||||||
* --------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
$routes->setDefaultNamespace('App\Controllers');
|
|
||||||
$routes->setDefaultController('Home');
|
|
||||||
$routes->setDefaultMethod('index');
|
|
||||||
$routes->setTranslateURIDashes(false);
|
|
||||||
$routes->set404Override();
|
|
||||||
|
|
||||||
// The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps
|
|
||||||
// where controller filters or CSRF protection are bypassed.
|
|
||||||
// If you don't want to define all routes, please use the Auto Routing (Improved).
|
|
||||||
// Set `$autoRoutesImproved` to true in `app/Config/Feature.php` and set the following to true.
|
|
||||||
$routes->setAutoRoute(false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
* Placeholder definitions
|
* Placeholder definitions
|
||||||
|
@ -69,23 +51,14 @@ $routes->get('.well-known/platforms', 'Platform');
|
||||||
|
|
||||||
// Podcast's Public routes
|
// Podcast's Public routes
|
||||||
$routes->group('@(:podcastHandle)', static function ($routes): void {
|
$routes->group('@(:podcastHandle)', static function ($routes): void {
|
||||||
$routes->get('/', 'PodcastController::activity/$1', [
|
|
||||||
'as' => 'podcast-activity',
|
|
||||||
]);
|
|
||||||
$routes->get('manifest.webmanifest', 'WebmanifestController::podcastManifest/$1', [
|
|
||||||
'as' => 'podcast-webmanifest',
|
|
||||||
]);
|
|
||||||
$routes->get('links', 'PodcastController::links/$1', [
|
|
||||||
'as' => 'podcast-links',
|
|
||||||
]);
|
|
||||||
// override default Fediverse Library's actor route
|
// override default Fediverse Library's actor route
|
||||||
$routes->options('/', 'ActivityPubController::preflight');
|
$routes->options('/', 'ActivityPubController::preflight');
|
||||||
$routes->get('/', 'PodcastController::activity/$1', [
|
$routes->get('/', 'PodcastController::activity/$1', [
|
||||||
'as' => 'actor',
|
'as' => 'podcast-activity',
|
||||||
'alternate-content' => [
|
'alternate-content' => [
|
||||||
'application/activity+json' => [
|
'application/activity+json' => [
|
||||||
'namespace' => 'Modules\Fediverse\Controllers',
|
'namespace' => 'Modules\Fediverse\Controllers',
|
||||||
'controller-method' => 'ActorController/$1',
|
'controller-method' => 'ActorController::index/$1',
|
||||||
],
|
],
|
||||||
'application/podcast-activity+json' => [
|
'application/podcast-activity+json' => [
|
||||||
'namespace' => 'App\Controllers',
|
'namespace' => 'App\Controllers',
|
||||||
|
@ -93,11 +66,17 @@ $routes->group('@(:podcastHandle)', static function ($routes): void {
|
||||||
],
|
],
|
||||||
'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
|
'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
|
||||||
'namespace' => 'Modules\Fediverse\Controllers',
|
'namespace' => 'Modules\Fediverse\Controllers',
|
||||||
'controller-method' => 'ActorController/$1',
|
'controller-method' => 'ActorController::index/$1',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'filter' => 'allow-cors',
|
'filter' => 'allow-cors',
|
||||||
]);
|
]);
|
||||||
|
$routes->get('manifest.webmanifest', 'WebmanifestController::podcastManifest/$1', [
|
||||||
|
'as' => 'podcast-webmanifest',
|
||||||
|
]);
|
||||||
|
$routes->get('links', 'PodcastController::links/$1', [
|
||||||
|
'as' => 'podcast-links',
|
||||||
|
]);
|
||||||
$routes->get('about', 'PodcastController::about/$1', [
|
$routes->get('about', 'PodcastController::about/$1', [
|
||||||
'as' => 'podcast-about',
|
'as' => 'podcast-about',
|
||||||
]);
|
]);
|
||||||
|
@ -106,12 +85,15 @@ $routes->group('@(:podcastHandle)', static function ($routes): void {
|
||||||
'as' => 'podcast-episodes',
|
'as' => 'podcast-episodes',
|
||||||
'alternate-content' => [
|
'alternate-content' => [
|
||||||
'application/activity+json' => [
|
'application/activity+json' => [
|
||||||
|
'namespace' => 'App\Controllers',
|
||||||
'controller-method' => 'PodcastController::episodeCollection/$1',
|
'controller-method' => 'PodcastController::episodeCollection/$1',
|
||||||
],
|
],
|
||||||
'application/podcast-activity+json' => [
|
'application/podcast-activity+json' => [
|
||||||
|
'namespace' => 'App\Controllers',
|
||||||
'controller-method' => 'PodcastController::episodeCollection/$1',
|
'controller-method' => 'PodcastController::episodeCollection/$1',
|
||||||
],
|
],
|
||||||
'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
|
'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
|
||||||
|
'namespace' => 'App\Controllers',
|
||||||
'controller-method' => 'PodcastController::episodeCollection/$1',
|
'controller-method' => 'PodcastController::episodeCollection/$1',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
@ -119,16 +101,19 @@ $routes->group('@(:podcastHandle)', static function ($routes): void {
|
||||||
]);
|
]);
|
||||||
$routes->group('episodes/(:slug)', static function ($routes): void {
|
$routes->group('episodes/(:slug)', static function ($routes): void {
|
||||||
$routes->options('/', 'ActivityPubController::preflight');
|
$routes->options('/', 'ActivityPubController::preflight');
|
||||||
$routes->get('/', 'EpisodeController/$1/$2', [
|
$routes->get('/', 'EpisodeController::index/$1/$2', [
|
||||||
'as' => 'episode',
|
'as' => 'episode',
|
||||||
'alternate-content' => [
|
'alternate-content' => [
|
||||||
'application/activity+json' => [
|
'application/activity+json' => [
|
||||||
|
'namespace' => 'App\Controllers',
|
||||||
'controller-method' => 'EpisodeController::episodeObject/$1/$2',
|
'controller-method' => 'EpisodeController::episodeObject/$1/$2',
|
||||||
],
|
],
|
||||||
'application/podcast-activity+json' => [
|
'application/podcast-activity+json' => [
|
||||||
|
'namespace' => 'App\Controllers',
|
||||||
'controller-method' => 'EpisodeController::episodeObject/$1/$2',
|
'controller-method' => 'EpisodeController::episodeObject/$1/$2',
|
||||||
],
|
],
|
||||||
'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
|
'application/ld+json; profile="https://www.w3.org/ns/activitystreams' => [
|
||||||
|
'namespace' => 'App\Controllers',
|
||||||
'controller-method' => 'EpisodeController::episodeObject/$1/$2',
|
'controller-method' => 'EpisodeController::episodeObject/$1/$2',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
@ -186,21 +171,21 @@ $routes->group('@(:podcastHandle)', static function ($routes): void {
|
||||||
],);
|
],);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$routes->head('feed.xml', 'FeedController/$1', [
|
$routes->head('feed.xml', 'FeedController::index/$1', [
|
||||||
'as' => 'podcast-rss-feed',
|
'as' => 'podcast-rss-feed',
|
||||||
]);
|
]);
|
||||||
$routes->get('feed.xml', 'FeedController/$1', [
|
$routes->get('feed.xml', 'FeedController::index/$1', [
|
||||||
'as' => 'podcast-rss-feed',
|
'as' => 'podcast-rss-feed',
|
||||||
]);
|
]);
|
||||||
$routes->head('feed', 'FeedController/$1');
|
$routes->head('feed', 'FeedController::index/$1');
|
||||||
$routes->get('feed', 'FeedController/$1');
|
$routes->get('feed', 'FeedController::index/$1');
|
||||||
});
|
});
|
||||||
|
|
||||||
// audio routes
|
// audio routes
|
||||||
$routes->head('audio/@(:podcastHandle)/(:slug).(:alphanum)', 'EpisodeAudioController/$1/$2', [
|
$routes->head('/audio/@(:podcastHandle)/(:slug).(:alphanum)', 'EpisodeAudioController::index/$1/$2', [
|
||||||
'as' => 'episode-audio',
|
'as' => 'episode-audio',
|
||||||
], );
|
], );
|
||||||
$routes->get('audio/@(:podcastHandle)/(:slug).(:alphanum)', 'EpisodeAudioController/$1/$2', [
|
$routes->get('/audio/@(:podcastHandle)/(:slug).(:alphanum)', 'EpisodeAudioController::index/$1/$2', [
|
||||||
'as' => 'episode-audio',
|
'as' => 'episode-audio',
|
||||||
], );
|
], );
|
||||||
|
|
||||||
|
@ -223,7 +208,7 @@ $routes->get('/map', 'MapController', [
|
||||||
$routes->get('/episodes-markers', 'MapController::getEpisodesMarkers', [
|
$routes->get('/episodes-markers', 'MapController::getEpisodesMarkers', [
|
||||||
'as' => 'episodes-markers',
|
'as' => 'episodes-markers',
|
||||||
]);
|
]);
|
||||||
$routes->get('/pages/(:slug)', 'PageController/$1', [
|
$routes->get('/pages/(:slug)', 'PageController::index/$1', [
|
||||||
'as' => 'page',
|
'as' => 'page',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -253,7 +238,7 @@ $routes->group('@(:podcastHandle)', static function ($routes): void {
|
||||||
'filter' => 'allow-cors',
|
'filter' => 'allow-cors',
|
||||||
]);
|
]);
|
||||||
$routes->options('replies', 'ActivityPubController::preflight');
|
$routes->options('replies', 'ActivityPubController::preflight');
|
||||||
$routes->get('replies', 'PostController/$1/$2', [
|
$routes->get('replies', 'PostController::index/$1/$2', [
|
||||||
'as' => 'post-replies',
|
'as' => 'post-replies',
|
||||||
'alternate-content' => [
|
'alternate-content' => [
|
||||||
'application/activity+json' => [
|
'application/activity+json' => [
|
||||||
|
@ -308,20 +293,3 @@ $routes->group('@(:podcastHandle)', static function ($routes): void {
|
||||||
'filter' => 'fediverse:verify-activitystream',
|
'filter' => 'fediverse:verify-activitystream',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
* --------------------------------------------------------------------
|
|
||||||
* Additional Routing
|
|
||||||
* --------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* There will often be times that you need additional routing and you
|
|
||||||
* need it to be able to override any defaults in this file. Environment
|
|
||||||
* based routes is one such time. require() additional route files here
|
|
||||||
* to make that happen.
|
|
||||||
*
|
|
||||||
* You will have access to the $routes object within that file without
|
|
||||||
* needing to reload it.
|
|
||||||
*/
|
|
||||||
if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) {
|
|
||||||
require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php';
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Config;
|
||||||
|
|
||||||
|
use CodeIgniter\Config\Routing as BaseRouting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routing configuration
|
||||||
|
*/
|
||||||
|
class Routing extends BaseRouting
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An array of files that contain route definitions.
|
||||||
|
* Route files are read in order, with the first match
|
||||||
|
* found taking precedence.
|
||||||
|
*
|
||||||
|
* Default: APPPATH . 'Config/Routes.php'
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public array $routeFiles = [
|
||||||
|
APPPATH . 'Config/Routes.php',
|
||||||
|
ROOTPATH . 'modules/Admin/Config/Routes.php',
|
||||||
|
ROOTPATH . 'modules/Analytics/Config/Routes.php',
|
||||||
|
ROOTPATH . 'modules/Api/Rest/V1/Config/Routes.php',
|
||||||
|
ROOTPATH . 'modules/Auth/Config/Routes.php',
|
||||||
|
ROOTPATH . 'modules/Fediverse/Config/Routes.php',
|
||||||
|
ROOTPATH . 'modules/Install/Config/Routes.php',
|
||||||
|
ROOTPATH . 'modules/Media/Config/Routes.php',
|
||||||
|
ROOTPATH . 'modules/PodcastImport/Config/Routes.php',
|
||||||
|
ROOTPATH . 'modules/PremiumPodcasts/Config/Routes.php',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default namespace to use for Controllers when no other
|
||||||
|
* namespace has been specified.
|
||||||
|
*
|
||||||
|
* Default: 'App\Controllers'
|
||||||
|
*/
|
||||||
|
public string $defaultNamespace = 'App\Controllers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default controller to use when no other controller has been
|
||||||
|
* specified.
|
||||||
|
*
|
||||||
|
* Default: 'Home'
|
||||||
|
*/
|
||||||
|
public string $defaultController = 'HomeController';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default method to call on the controller when no other
|
||||||
|
* method has been set in the route.
|
||||||
|
*
|
||||||
|
* Default: 'index'
|
||||||
|
*/
|
||||||
|
public string $defaultMethod = 'index';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to translate dashes in URIs to underscores.
|
||||||
|
* Primarily useful when using the auto-routing.
|
||||||
|
*
|
||||||
|
* Default: false
|
||||||
|
*/
|
||||||
|
public bool $translateURIDashes = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the class/method that should be called if routing doesn't
|
||||||
|
* find a match. It can be either a closure or the controller/method
|
||||||
|
* name exactly like a route is defined: Users::index
|
||||||
|
*
|
||||||
|
* This setting is passed to the Router class and handled there.
|
||||||
|
*
|
||||||
|
* If you want to use a closure, you will have to set it in the
|
||||||
|
* class constructor or the routes file by calling:
|
||||||
|
*
|
||||||
|
* $routes->set404Override(function() {
|
||||||
|
* // Do something here
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* public $override404 = 'App\Errors::show404';
|
||||||
|
*/
|
||||||
|
public ?string $override404 = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If TRUE, the system will attempt to match the URI against
|
||||||
|
* Controllers by matching each segment against folders/files
|
||||||
|
* in APPPATH/Controllers, when a match wasn't found against
|
||||||
|
* defined routes.
|
||||||
|
*
|
||||||
|
* If FALSE, will stop searching and do NO automatic routing.
|
||||||
|
*/
|
||||||
|
public bool $autoRoute = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If TRUE, will enable the use of the 'prioritize' option
|
||||||
|
* when defining routes.
|
||||||
|
*
|
||||||
|
* Default: false
|
||||||
|
*/
|
||||||
|
public bool $prioritize = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of URI segments and namespaces. For Auto Routing (Improved).
|
||||||
|
*
|
||||||
|
* The key is the first URI segment. The value is the controller namespace.
|
||||||
|
* E.g.,
|
||||||
|
* [
|
||||||
|
* 'blog' => 'Acme\Blog\Controllers',
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* @var array<string, string> [ uri_segment => namespace ]
|
||||||
|
*/
|
||||||
|
public array $moduleRoutes = [];
|
||||||
|
}
|
|
@ -6,7 +6,6 @@ namespace Config;
|
||||||
|
|
||||||
use App\Libraries\Breadcrumb;
|
use App\Libraries\Breadcrumb;
|
||||||
use App\Libraries\Negotiate;
|
use App\Libraries\Negotiate;
|
||||||
use App\Libraries\RouteCollection;
|
|
||||||
use App\Libraries\Router;
|
use App\Libraries\Router;
|
||||||
use CodeIgniter\Config\BaseService;
|
use CodeIgniter\Config\BaseService;
|
||||||
use CodeIgniter\HTTP\Request;
|
use CodeIgniter\HTTP\Request;
|
||||||
|
@ -44,21 +43,6 @@ class Services extends BaseService
|
||||||
return new Router($routes, $request);
|
return new Router($routes, $request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The Routes service is a class that allows for easily building
|
|
||||||
* a collection of routes.
|
|
||||||
*
|
|
||||||
* @return RouteCollection
|
|
||||||
*/
|
|
||||||
public static function routes(bool $getShared = true)
|
|
||||||
{
|
|
||||||
if ($getShared) {
|
|
||||||
return static::getSharedInstance('routes');
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RouteCollection(self::locator(), config('Modules'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Negotiate class provides the content negotiation features for working the request to determine correct
|
* The Negotiate class provides the content negotiation features for working the request to determine correct
|
||||||
* language, encoding, charset, and more.
|
* language, encoding, charset, and more.
|
||||||
|
|
|
@ -90,4 +90,31 @@ class Toolbar extends BaseConfig
|
||||||
* `$maxQueries` defines the maximum amount of queries that will be stored.
|
* `$maxQueries` defines the maximum amount of queries that will be stored.
|
||||||
*/
|
*/
|
||||||
public int $maxQueries = 100;
|
public int $maxQueries = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public array $watchedDirectories = ['app', 'modules', 'themes'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public array $watchedExtensions = ['php', 'css', 'js', 'html', 'svg', 'json', 'env'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace App\Controllers;
|
||||||
|
|
||||||
use CodeIgniter\Controller;
|
use CodeIgniter\Controller;
|
||||||
use CodeIgniter\HTTP\Response;
|
use CodeIgniter\HTTP\Response;
|
||||||
|
use Config\Colors;
|
||||||
|
|
||||||
class ColorsController extends Controller
|
class ColorsController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -28,7 +29,7 @@ class ColorsController extends Controller
|
||||||
if (
|
if (
|
||||||
! ($colorsCssBody = cache($cacheName))
|
! ($colorsCssBody = cache($cacheName))
|
||||||
) {
|
) {
|
||||||
$colorThemes = config('Colors')
|
$colorThemes = config(Colors::class)
|
||||||
->themes;
|
->themes;
|
||||||
|
|
||||||
$colorsCssBody = '';
|
$colorsCssBody = '';
|
||||||
|
|
|
@ -64,7 +64,7 @@ class EpisodeAudioController extends Controller
|
||||||
set_user_session_location();
|
set_user_session_location();
|
||||||
set_user_session_player();
|
set_user_session_player();
|
||||||
|
|
||||||
$this->analyticsConfig = config('Analytics');
|
$this->analyticsConfig = config(Analytics::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function _remap(string $method, string ...$params): mixed
|
public function _remap(string $method, string ...$params): mixed
|
||||||
|
|
|
@ -21,6 +21,8 @@ use CodeIgniter\Database\BaseBuilder;
|
||||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||||
use CodeIgniter\HTTP\Response;
|
use CodeIgniter\HTTP\Response;
|
||||||
use CodeIgniter\HTTP\ResponseInterface;
|
use CodeIgniter\HTTP\ResponseInterface;
|
||||||
|
use Config\Embed;
|
||||||
|
use Config\Images;
|
||||||
use Config\Services;
|
use Config\Services;
|
||||||
use Modules\Analytics\AnalyticsTrait;
|
use Modules\Analytics\AnalyticsTrait;
|
||||||
use Modules\Fediverse\Objects\OrderedCollectionObject;
|
use Modules\Fediverse\Objects\OrderedCollectionObject;
|
||||||
|
@ -104,8 +106,8 @@ class EpisodeController extends BaseController
|
||||||
// The page cache is set to a decade so it is deleted manually upon podcast update
|
// The page cache is set to a decade so it is deleted manually upon podcast update
|
||||||
return view('episode/comments', $data, [
|
return view('episode/comments', $data, [
|
||||||
'cache' => $secondsToNextUnpublishedEpisode
|
'cache' => $secondsToNextUnpublishedEpisode
|
||||||
? $secondsToNextUnpublishedEpisode
|
? $secondsToNextUnpublishedEpisode
|
||||||
: DECADE,
|
: DECADE,
|
||||||
'cache_name' => $cacheName,
|
'cache_name' => $cacheName,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -231,15 +233,15 @@ class EpisodeController extends BaseController
|
||||||
'author_url' => $this->podcast->link,
|
'author_url' => $this->podcast->link,
|
||||||
'html' => '<iframe src="' .
|
'html' => '<iframe src="' .
|
||||||
$this->episode->embed_url .
|
$this->episode->embed_url .
|
||||||
'" width="100%" height="' . config('Embed')->height . '" frameborder="0" scrolling="no"></iframe>',
|
'" width="100%" height="' . config(Embed::class)->height . '" frameborder="0" scrolling="no"></iframe>',
|
||||||
'width' => config('Embed')
|
'width' => config(Embed::class)
|
||||||
->width,
|
->width,
|
||||||
'height' => config('Embed')
|
'height' => config(Embed::class)
|
||||||
->height,
|
->height,
|
||||||
'thumbnail_url' => $this->episode->cover->og_url,
|
'thumbnail_url' => $this->episode->cover->og_url,
|
||||||
'thumbnail_width' => config('Images')
|
'thumbnail_width' => config(Images::class)
|
||||||
->podcastCoverSizes['og']['width'],
|
->podcastCoverSizes['og']['width'],
|
||||||
'thumbnail_height' => config('Images')
|
'thumbnail_height' => config(Images::class)
|
||||||
->podcastCoverSizes['og']['height'],
|
->podcastCoverSizes['og']['height'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -256,18 +258,20 @@ class EpisodeController extends BaseController
|
||||||
$oembed->addChild('author_name', $this->podcast->title);
|
$oembed->addChild('author_name', $this->podcast->title);
|
||||||
$oembed->addChild('author_url', $this->podcast->link);
|
$oembed->addChild('author_url', $this->podcast->link);
|
||||||
$oembed->addChild('thumbnail', $this->episode->cover->og_url);
|
$oembed->addChild('thumbnail', $this->episode->cover->og_url);
|
||||||
$oembed->addChild('thumbnail_width', (string) config('Images')->podcastCoverSizes['og']['width']);
|
$oembed->addChild('thumbnail_width', (string) config(Images::class)->podcastCoverSizes['og']['width']);
|
||||||
$oembed->addChild('thumbnail_height', (string) config('Images')->podcastCoverSizes['og']['height']);
|
$oembed->addChild('thumbnail_height', (string) config(Images::class)->podcastCoverSizes['og']['height']);
|
||||||
$oembed->addChild(
|
$oembed->addChild(
|
||||||
'html',
|
'html',
|
||||||
htmlspecialchars(
|
htmlspecialchars(
|
||||||
'<iframe src="' .
|
'<iframe src="' .
|
||||||
$this->episode->embed_url .
|
$this->episode->embed_url .
|
||||||
'" width="100%" height="' . config('Embed')->height . '" frameborder="0" scrolling="no"></iframe>',
|
'" width="100%" height="' . config(
|
||||||
|
Embed::class
|
||||||
|
)->height . '" frameborder="0" scrolling="no"></iframe>',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
$oembed->addChild('width', (string) config('Embed')->width);
|
$oembed->addChild('width', (string) config(Embed::class)->width);
|
||||||
$oembed->addChild('height', (string) config('Embed')->height);
|
$oembed->addChild('height', (string) config(Embed::class)->height);
|
||||||
|
|
||||||
// @phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
return $this->response->setXML($oembed);
|
return $this->response->setXML($oembed);
|
||||||
|
|
|
@ -14,6 +14,7 @@ use App\Models\PodcastModel;
|
||||||
use CodeIgniter\Database\Exceptions\DatabaseException;
|
use CodeIgniter\Database\Exceptions\DatabaseException;
|
||||||
use CodeIgniter\HTTP\RedirectResponse;
|
use CodeIgniter\HTTP\RedirectResponse;
|
||||||
use CodeIgniter\HTTP\ResponseInterface;
|
use CodeIgniter\HTTP\ResponseInterface;
|
||||||
|
use Config\Cache;
|
||||||
use Modules\Media\FileManagers\FileManagerInterface;
|
use Modules\Media\FileManagers\FileManagerInterface;
|
||||||
|
|
||||||
class HomeController extends BaseController
|
class HomeController extends BaseController
|
||||||
|
@ -53,7 +54,7 @@ class HomeController extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Can Castopod connect to the cache handler
|
// --- Can Castopod connect to the cache handler
|
||||||
if (config('Cache')->handler !== 'dummy' && cache()->getCacheInfo() === null) {
|
if (config(Cache::class)->handler !== 'dummy' && cache()->getCacheInfo() === null) {
|
||||||
$errors[] = 'Unable connect to the cache handler.';
|
$errors[] = 'Unable connect to the cache handler.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ use CodeIgniter\Files\File;
|
||||||
use CodeIgniter\HTTP\Files\UploadedFile;
|
use CodeIgniter\HTTP\Files\UploadedFile;
|
||||||
use CodeIgniter\I18n\Time;
|
use CodeIgniter\I18n\Time;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Config\Images;
|
||||||
use League\CommonMark\Environment\Environment;
|
use League\CommonMark\Environment\Environment;
|
||||||
use League\CommonMark\Extension\Autolink\AutolinkExtension;
|
use League\CommonMark\Extension\Autolink\AutolinkExtension;
|
||||||
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
||||||
|
@ -199,7 +200,7 @@ class Episode extends Entity
|
||||||
} else {
|
} else {
|
||||||
$cover = new Image([
|
$cover = new Image([
|
||||||
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $this->attributes['slug'] . '.' . $file->getExtension(),
|
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $this->attributes['slug'] . '.' . $file->getExtension(),
|
||||||
'sizes' => config('Images')
|
'sizes' => config(Images::class)
|
||||||
->podcastCoverSizes,
|
->podcastCoverSizes,
|
||||||
'uploaded_by' => $this->attributes['updated_by'],
|
'uploaded_by' => $this->attributes['updated_by'],
|
||||||
'updated_by' => $this->attributes['updated_by'],
|
'updated_by' => $this->attributes['updated_by'],
|
||||||
|
|
|
@ -14,6 +14,7 @@ use App\Models\PersonModel;
|
||||||
use CodeIgniter\Entity\Entity;
|
use CodeIgniter\Entity\Entity;
|
||||||
use CodeIgniter\Files\File;
|
use CodeIgniter\Files\File;
|
||||||
use CodeIgniter\HTTP\Files\UploadedFile;
|
use CodeIgniter\HTTP\Files\UploadedFile;
|
||||||
|
use Config\Images;
|
||||||
use Modules\Media\Entities\Image;
|
use Modules\Media\Entities\Image;
|
||||||
use Modules\Media\Models\MediaModel;
|
use Modules\Media\Models\MediaModel;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
@ -71,7 +72,7 @@ class Person extends Entity
|
||||||
} else {
|
} else {
|
||||||
$avatar = new Image([
|
$avatar = new Image([
|
||||||
'file_key' => 'persons/' . $this->attributes['unique_name'] . '.' . $file->getExtension(),
|
'file_key' => 'persons/' . $this->attributes['unique_name'] . '.' . $file->getExtension(),
|
||||||
'sizes' => config('Images')
|
'sizes' => config(Images::class)
|
||||||
->personAvatarSizes,
|
->personAvatarSizes,
|
||||||
'uploaded_by' => $this->attributes['updated_by'],
|
'uploaded_by' => $this->attributes['updated_by'],
|
||||||
'updated_by' => $this->attributes['updated_by'],
|
'updated_by' => $this->attributes['updated_by'],
|
||||||
|
|
|
@ -21,6 +21,7 @@ use CodeIgniter\Files\File;
|
||||||
use CodeIgniter\HTTP\Files\UploadedFile;
|
use CodeIgniter\HTTP\Files\UploadedFile;
|
||||||
use CodeIgniter\I18n\Time;
|
use CodeIgniter\I18n\Time;
|
||||||
use CodeIgniter\Shield\Entities\User;
|
use CodeIgniter\Shield\Entities\User;
|
||||||
|
use Config\Images;
|
||||||
use Exception;
|
use Exception;
|
||||||
use League\CommonMark\Environment\Environment;
|
use League\CommonMark\Environment\Environment;
|
||||||
use League\CommonMark\Extension\Autolink\AutolinkExtension;
|
use League\CommonMark\Extension\Autolink\AutolinkExtension;
|
||||||
|
@ -247,7 +248,7 @@ class Podcast extends Entity
|
||||||
} else {
|
} else {
|
||||||
$cover = new Image([
|
$cover = new Image([
|
||||||
'file_key' => 'podcasts/' . $this->attributes['handle'] . '/cover.' . $file->getExtension(),
|
'file_key' => 'podcasts/' . $this->attributes['handle'] . '/cover.' . $file->getExtension(),
|
||||||
'sizes' => config('Images')
|
'sizes' => config(Images::class)
|
||||||
->podcastCoverSizes,
|
->podcastCoverSizes,
|
||||||
'uploaded_by' => $this->attributes['updated_by'],
|
'uploaded_by' => $this->attributes['updated_by'],
|
||||||
'updated_by' => $this->attributes['updated_by'],
|
'updated_by' => $this->attributes['updated_by'],
|
||||||
|
@ -290,7 +291,7 @@ class Podcast extends Entity
|
||||||
} else {
|
} else {
|
||||||
$banner = new Image([
|
$banner = new Image([
|
||||||
'file_key' => 'podcasts/' . $this->attributes['handle'] . '/banner.' . $file->getExtension(),
|
'file_key' => 'podcasts/' . $this->attributes['handle'] . '/banner.' . $file->getExtension(),
|
||||||
'sizes' => config('Images')
|
'sizes' => config(Images::class)
|
||||||
->podcastBannerSizes,
|
->podcastBannerSizes,
|
||||||
'uploaded_by' => $this->attributes['updated_by'],
|
'uploaded_by' => $this->attributes['updated_by'],
|
||||||
'updated_by' => $this->attributes['updated_by'],
|
'updated_by' => $this->attributes['updated_by'],
|
||||||
|
|
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use App\Entities\Person;
|
use App\Entities\Person;
|
||||||
use App\Entities\Podcast;
|
use App\Entities\Podcast;
|
||||||
|
use Config\App;
|
||||||
|
use Config\Images;
|
||||||
use Modules\Media\Entities\Image;
|
use Modules\Media\Entities\Image;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +25,7 @@ if (! function_exists('get_browser_language')) {
|
||||||
function get_browser_language(?string $httpAcceptLanguage = null): string
|
function get_browser_language(?string $httpAcceptLanguage = null): string
|
||||||
{
|
{
|
||||||
if ($httpAcceptLanguage === null) {
|
if ($httpAcceptLanguage === null) {
|
||||||
return config('App')->defaultLocale;
|
return config(App::class)->defaultLocale;
|
||||||
}
|
}
|
||||||
|
|
||||||
$langs = explode(',', $httpAcceptLanguage);
|
$langs = explode(',', $httpAcceptLanguage);
|
||||||
|
@ -290,7 +292,7 @@ if (! function_exists('format_bytes')) {
|
||||||
if (! function_exists('get_site_icon_url')) {
|
if (! function_exists('get_site_icon_url')) {
|
||||||
function get_site_icon_url(string $size): string
|
function get_site_icon_url(string $size): string
|
||||||
{
|
{
|
||||||
if (config('App')->siteIcon['ico'] === service('settings')->get('App.siteIcon')['ico']) {
|
if (config(App::class)->siteIcon['ico'] === service('settings')->get('App.siteIcon')['ico']) {
|
||||||
// return default site icon url
|
// return default site icon url
|
||||||
return base_url(service('settings')->get('App.siteIcon')[$size]);
|
return base_url(service('settings')->get('App.siteIcon')[$size]);
|
||||||
}
|
}
|
||||||
|
@ -304,12 +306,12 @@ if (! function_exists('get_podcast_banner')) {
|
||||||
function get_podcast_banner_url(Podcast $podcast, string $size): string
|
function get_podcast_banner_url(Podcast $podcast, string $size): string
|
||||||
{
|
{
|
||||||
if (! $podcast->banner instanceof Image) {
|
if (! $podcast->banner instanceof Image) {
|
||||||
$defaultBanner = config('Images')
|
$defaultBanner = config(Images::class)
|
||||||
->podcastBannerDefaultPaths[service('settings')->get('App.theme')] ?? config(
|
->podcastBannerDefaultPaths[service('settings')->get('App.theme')] ?? config(
|
||||||
'Images'
|
Images::class
|
||||||
)->podcastBannerDefaultPaths['default'];
|
)->podcastBannerDefaultPaths['default'];
|
||||||
|
|
||||||
$sizes = config('Images')
|
$sizes = config(Images::class)
|
||||||
->podcastBannerSizes;
|
->podcastBannerSizes;
|
||||||
|
|
||||||
$sizeConfig = $sizes[$size];
|
$sizeConfig = $sizes[$size];
|
||||||
|
@ -330,7 +332,7 @@ if (! function_exists('get_podcast_banner_mimetype')) {
|
||||||
function get_podcast_banner_mimetype(Podcast $podcast, string $size): string
|
function get_podcast_banner_mimetype(Podcast $podcast, string $size): string
|
||||||
{
|
{
|
||||||
if (! $podcast->banner instanceof Image) {
|
if (! $podcast->banner instanceof Image) {
|
||||||
$sizes = config('Images')
|
$sizes = config(Images::class)
|
||||||
->podcastBannerSizes;
|
->podcastBannerSizes;
|
||||||
|
|
||||||
$sizeConfig = $sizes[$size];
|
$sizeConfig = $sizes[$size];
|
||||||
|
@ -338,7 +340,7 @@ if (! function_exists('get_podcast_banner_mimetype')) {
|
||||||
|
|
||||||
// return default site icon url
|
// return default site icon url
|
||||||
return array_key_exists('mimetype', $sizeConfig) ? $sizeConfig['mimetype'] : config(
|
return array_key_exists('mimetype', $sizeConfig) ? $sizeConfig['mimetype'] : config(
|
||||||
'Images'
|
Images::class
|
||||||
)->podcastBannerDefaultMimeType;
|
)->podcastBannerDefaultMimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,10 +353,10 @@ if (! function_exists('get_avatar_url')) {
|
||||||
function get_avatar_url(Person $person, string $size): string
|
function get_avatar_url(Person $person, string $size): string
|
||||||
{
|
{
|
||||||
if (! $person->avatar instanceof Image) {
|
if (! $person->avatar instanceof Image) {
|
||||||
$defaultAvatarPath = config('Images')
|
$defaultAvatarPath = config(Images::class)
|
||||||
->avatarDefaultPath;
|
->avatarDefaultPath;
|
||||||
|
|
||||||
$sizes = config('Images')
|
$sizes = config(Images::class)
|
||||||
->personAvatarSizes;
|
->personAvatarSizes;
|
||||||
|
|
||||||
$sizeConfig = $sizes[$size];
|
$sizeConfig = $sizes[$size];
|
||||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use App\Models\PageModel;
|
use App\Models\PageModel;
|
||||||
|
use Config\App;
|
||||||
|
|
||||||
if (! function_exists('render_page_links')) {
|
if (! function_exists('render_page_links')) {
|
||||||
/**
|
/**
|
||||||
|
@ -41,8 +42,8 @@ if (! function_exists('render_page_links')) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if set in .env, add legal notice link at the end of page links
|
// if set in .env, add legal notice link at the end of page links
|
||||||
if (config('App')->legalNoticeURL !== null) {
|
if (config(App::class)->legalNoticeURL !== null) {
|
||||||
$links .= anchor(config('App')->legalNoticeURL, lang('Common.legal_notice'), [
|
$links .= anchor(config(App::class)->legalNoticeURL, lang('Common.legal_notice'), [
|
||||||
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-accent',
|
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-accent',
|
||||||
'target' => '_blank',
|
'target' => '_blank',
|
||||||
'rel' => 'noopener noreferrer',
|
'rel' => 'noopener noreferrer',
|
||||||
|
|
|
@ -17,6 +17,7 @@ use Config\Mimes;
|
||||||
use Modules\Media\Entities\Chapters;
|
use Modules\Media\Entities\Chapters;
|
||||||
use Modules\Media\Entities\Transcript;
|
use Modules\Media\Entities\Transcript;
|
||||||
use Modules\PremiumPodcasts\Entities\Subscription;
|
use Modules\PremiumPodcasts\Entities\Subscription;
|
||||||
|
use Modules\WebSub\Config\WebSub;
|
||||||
|
|
||||||
if (! function_exists('get_rss_feed')) {
|
if (! function_exists('get_rss_feed')) {
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +52,7 @@ if (! function_exists('get_rss_feed')) {
|
||||||
$atomLink->addAttribute('type', 'application/rss+xml');
|
$atomLink->addAttribute('type', 'application/rss+xml');
|
||||||
|
|
||||||
// websub: add links to hubs defined in config
|
// websub: add links to hubs defined in config
|
||||||
$websubHubs = config('WebSub')
|
$websubHubs = config(WebSub::class)
|
||||||
->hubs;
|
->hubs;
|
||||||
foreach ($websubHubs as $websubHub) {
|
foreach ($websubHubs as $websubHub) {
|
||||||
$atomLinkHub = $channel->addChild('link', null, $atomNamespace);
|
$atomLinkHub = $channel->addChild('link', null, $atomNamespace);
|
||||||
|
|
|
@ -9,6 +9,8 @@ use App\Entities\EpisodeComment;
|
||||||
use App\Entities\Page;
|
use App\Entities\Page;
|
||||||
use App\Entities\Podcast;
|
use App\Entities\Podcast;
|
||||||
use App\Entities\Post;
|
use App\Entities\Post;
|
||||||
|
use Config\Embed;
|
||||||
|
use Config\Images;
|
||||||
use Melbahja\Seo\MetaTags;
|
use Melbahja\Seo\MetaTags;
|
||||||
use Melbahja\Seo\Schema;
|
use Melbahja\Seo\Schema;
|
||||||
use Melbahja\Seo\Schema\Thing;
|
use Melbahja\Seo\Schema\Thing;
|
||||||
|
@ -56,8 +58,8 @@ if (! function_exists('get_podcast_metatags')) {
|
||||||
->description(esc($podcast->description))
|
->description(esc($podcast->description))
|
||||||
->image((string) $podcast->cover->og_url)
|
->image((string) $podcast->cover->og_url)
|
||||||
->canonical((string) current_url())
|
->canonical((string) current_url())
|
||||||
->og('image:width', (string) config('Images')->podcastCoverSizes['og']['width'])
|
->og('image:width', (string) config(Images::class)->podcastCoverSizes['og']['width'])
|
||||||
->og('image:height', (string) config('Images')->podcastCoverSizes['og']['height'])
|
->og('image:height', (string) config(Images::class)->podcastCoverSizes['og']['height'])
|
||||||
->og('locale', $podcast->language_code)
|
->og('locale', $podcast->language_code)
|
||||||
->og('site_name', esc(service('settings')->get('App.siteName')))
|
->og('site_name', esc(service('settings')->get('App.siteName')))
|
||||||
->push('link', [
|
->push('link', [
|
||||||
|
@ -106,8 +108,8 @@ if (! function_exists('get_episode_metatags')) {
|
||||||
->image((string) $episode->cover->og_url, 'player')
|
->image((string) $episode->cover->og_url, 'player')
|
||||||
->canonical($episode->link)
|
->canonical($episode->link)
|
||||||
->og('site_name', esc(service('settings')->get('App.siteName')))
|
->og('site_name', esc(service('settings')->get('App.siteName')))
|
||||||
->og('image:width', (string) config('Images')->podcastCoverSizes['og']['width'])
|
->og('image:width', (string) config(Images::class)->podcastCoverSizes['og']['width'])
|
||||||
->og('image:height', (string) config('Images')->podcastCoverSizes['og']['height'])
|
->og('image:height', (string) config(Images::class)->podcastCoverSizes['og']['height'])
|
||||||
->og('locale', $episode->podcast->language_code)
|
->og('locale', $episode->podcast->language_code)
|
||||||
->og('audio', $episode->audio_opengraph_url)
|
->og('audio', $episode->audio_opengraph_url)
|
||||||
->og('audio:type', $episode->audio->file_mimetype)
|
->og('audio:type', $episode->audio->file_mimetype)
|
||||||
|
@ -116,8 +118,8 @@ if (! function_exists('get_episode_metatags')) {
|
||||||
->twitter('audio:partner', $episode->podcast->publisher ?? '')
|
->twitter('audio:partner', $episode->podcast->publisher ?? '')
|
||||||
->twitter('audio:artist_name', esc($episode->podcast->owner_name))
|
->twitter('audio:artist_name', esc($episode->podcast->owner_name))
|
||||||
->twitter('player', $episode->getEmbedUrl('light'))
|
->twitter('player', $episode->getEmbedUrl('light'))
|
||||||
->twitter('player:width', (string) config('Embed')->width)
|
->twitter('player:width', (string) config(Embed::class)->width)
|
||||||
->twitter('player:height', (string) config('Embed')->height)
|
->twitter('player:height', (string) config(Embed::class)->height)
|
||||||
->push('link', [
|
->push('link', [
|
||||||
'rel' => 'alternate',
|
'rel' => 'alternate',
|
||||||
'type' => 'application/activity+json',
|
'type' => 'application/activity+json',
|
||||||
|
|
|
@ -1,280 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This file extends the Router class from the CodeIgniter 4 framework.
|
|
||||||
*
|
|
||||||
* It introduces the alternate-content option for a route.
|
|
||||||
*
|
|
||||||
* @copyright 2023 Ad Aures
|
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
|
||||||
* @link https://castopod.org/
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Libraries;
|
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use CodeIgniter\Router\RouteCollection as CodeIgniterRouteCollection;
|
|
||||||
|
|
||||||
class RouteCollection extends CodeIgniterRouteCollection
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The current hostname from $_SERVER['HTTP_HOST']
|
|
||||||
*/
|
|
||||||
private ?string $httpHost = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does the heavy lifting of creating an actual route. You must specify
|
|
||||||
* the request method(s) that this route will work for. They can be separated
|
|
||||||
* by a pipe character "|" if there is more than one.
|
|
||||||
*
|
|
||||||
* @param array<int, mixed>|Closure|string $to
|
|
||||||
* @param array<string, mixed> $options
|
|
||||||
*/
|
|
||||||
protected function create(string $verb, string $from, $to, ?array $options = null): void
|
|
||||||
{
|
|
||||||
$overwrite = false;
|
|
||||||
$prefix = $this->group === null ? '' : $this->group . '/';
|
|
||||||
|
|
||||||
$from = esc(strip_tags($prefix . $from));
|
|
||||||
|
|
||||||
// While we want to add a route within a group of '/',
|
|
||||||
// it doesn't work with matching, so remove them...
|
|
||||||
if ($from !== '/') {
|
|
||||||
$from = trim($from, '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
// When redirecting to named route, $to is an array like `['zombies' => '\Zombies::index']`.
|
|
||||||
if (is_array($to) && count($to) === 2) {
|
|
||||||
$to = $this->processArrayCallableSyntax($from, $to);
|
|
||||||
}
|
|
||||||
|
|
||||||
$options = array_merge($this->currentOptions ?? [], $options ?? []);
|
|
||||||
|
|
||||||
// Route priority detect
|
|
||||||
if (isset($options['priority'])) {
|
|
||||||
$options['priority'] = abs((int) $options['priority']);
|
|
||||||
|
|
||||||
if ($options['priority'] > 0) {
|
|
||||||
$this->prioritizeDetected = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hostname limiting?
|
|
||||||
if (! empty($options['hostname'])) {
|
|
||||||
// @todo determine if there's a way to whitelist hosts?
|
|
||||||
if (! $this->checkHostname($options['hostname'])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$overwrite = true;
|
|
||||||
}
|
|
||||||
// Limiting to subdomains?
|
|
||||||
elseif (! empty($options['subdomain'])) {
|
|
||||||
// If we don't match the current subdomain, then
|
|
||||||
// we don't need to add the route.
|
|
||||||
if (! $this->checkSubdomains($options['subdomain'])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$overwrite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Are we offsetting the binds?
|
|
||||||
// If so, take care of them here in one
|
|
||||||
// fell swoop.
|
|
||||||
if (isset($options['offset']) && is_string($to)) {
|
|
||||||
// Get a constant string to work with.
|
|
||||||
$to = preg_replace('/(\$\d+)/', '$X', $to);
|
|
||||||
|
|
||||||
for ($i = (int) $options['offset'] + 1; $i < (int) $options['offset'] + 7; ++$i) {
|
|
||||||
$to = preg_replace_callback('/\$X/', static fn ($m): string => '$' . $i, $to, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace our regex pattern placeholders with the actual thing
|
|
||||||
// so that the Router doesn't need to know about any of this.
|
|
||||||
foreach ($this->placeholders as $tag => $pattern) {
|
|
||||||
$from = str_ireplace(':' . $tag, $pattern, $from);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If is redirect, No processing
|
|
||||||
if (! isset($options['redirect']) && is_string($to)) {
|
|
||||||
// If no namespace found, add the default namespace
|
|
||||||
if (strpos($to, '\\') === false || strpos($to, '\\') > 0) {
|
|
||||||
$namespace = $options['namespace'] ?? $this->defaultNamespace;
|
|
||||||
$to = trim((string) $namespace, '\\') . '\\' . $to;
|
|
||||||
}
|
|
||||||
// Always ensure that we escape our namespace so we're not pointing to
|
|
||||||
// \CodeIgniter\Routes\Controller::method.
|
|
||||||
$to = '\\' . ltrim($to, '\\');
|
|
||||||
}
|
|
||||||
|
|
||||||
$name = $options['as'] ?? $from;
|
|
||||||
|
|
||||||
helper('array');
|
|
||||||
|
|
||||||
// Don't overwrite any existing 'froms' so that auto-discovered routes
|
|
||||||
// do not overwrite any app/Config/Routes settings. The app
|
|
||||||
// routes should always be the "source of truth".
|
|
||||||
// this works only because discovered routes are added just prior
|
|
||||||
// to attempting to route the request.
|
|
||||||
|
|
||||||
// TODO: see how to overwrite routes differently
|
|
||||||
// restored change that broke Castopod routing with fediverse
|
|
||||||
// in CI4 v4.2.8 https://github.com/codeigniter4/CodeIgniter4/pull/6644
|
|
||||||
if (isset($this->routes[$verb][$name]) && ! $overwrite) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->routes[$verb][$name] = [
|
|
||||||
'route' => [
|
|
||||||
$from => $to,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->routesOptions[$verb][$from] = $options;
|
|
||||||
|
|
||||||
// Is this a redirect?
|
|
||||||
if (isset($options['redirect']) && is_numeric($options['redirect'])) {
|
|
||||||
$this->routes['*'][$name]['redirect'] = $options['redirect'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares the hostname passed in against the current hostname
|
|
||||||
* on this page request.
|
|
||||||
*
|
|
||||||
* @param string $hostname Hostname in route options
|
|
||||||
*/
|
|
||||||
private function checkHostname($hostname): bool
|
|
||||||
{
|
|
||||||
// CLI calls can't be on hostname.
|
|
||||||
if ($this->httpHost === null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return strtolower($this->httpHost) === strtolower($hostname);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<int, mixed> $to
|
|
||||||
*
|
|
||||||
* @return string|array<int, mixed>
|
|
||||||
*/
|
|
||||||
private function processArrayCallableSyntax(string $from, array $to): string | array
|
|
||||||
{
|
|
||||||
// [classname, method]
|
|
||||||
// eg, [Home::class, 'index']
|
|
||||||
if (is_callable($to, true, $callableName)) {
|
|
||||||
// If the route has placeholders, add params automatically.
|
|
||||||
$params = $this->getMethodParams($from);
|
|
||||||
|
|
||||||
return '\\' . $callableName . $params;
|
|
||||||
}
|
|
||||||
|
|
||||||
// [[classname, method], params]
|
|
||||||
// eg, [[Home::class, 'index'], '$1/$2']
|
|
||||||
if (
|
|
||||||
isset($to[0], $to[1])
|
|
||||||
&& is_callable($to[0], true, $callableName)
|
|
||||||
&& is_string($to[1])
|
|
||||||
) {
|
|
||||||
return '\\' . $callableName . '/' . $to[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $to;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares the subdomain(s) passed in against the current subdomain
|
|
||||||
* on this page request.
|
|
||||||
*
|
|
||||||
* @param string|string[] $subdomains
|
|
||||||
*/
|
|
||||||
private function checkSubdomains($subdomains): bool
|
|
||||||
{
|
|
||||||
// CLI calls can't be on subdomain.
|
|
||||||
if ($this->httpHost === null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->currentSubdomain === null) {
|
|
||||||
$this->currentSubdomain = $this->determineCurrentSubdomain();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! is_array($subdomains)) {
|
|
||||||
$subdomains = [$subdomains];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routes can be limited to any sub-domain. In that case, though,
|
|
||||||
// it does require a sub-domain to be present.
|
|
||||||
if (! empty($this->currentSubdomain) && in_array('*', $subdomains, true)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return in_array($this->currentSubdomain, $subdomains, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the method param string like `/$1/$2` for placeholders
|
|
||||||
*/
|
|
||||||
private function getMethodParams(string $from): string
|
|
||||||
{
|
|
||||||
preg_match_all('/\(.+?\)/', $from, $matches);
|
|
||||||
$count = is_countable($matches[0]) ? count($matches[0]) : 0;
|
|
||||||
|
|
||||||
$params = '';
|
|
||||||
|
|
||||||
for ($i = 1; $i <= $count; ++$i) {
|
|
||||||
$params .= '/$' . $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $params;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Examines the HTTP_HOST to get the best match for the subdomain. It
|
|
||||||
* won't be perfect, but should work for our needs.
|
|
||||||
*
|
|
||||||
* It's especially not perfect since it's possible to register a domain
|
|
||||||
* with a period (.) as part of the domain name.
|
|
||||||
*
|
|
||||||
* @return false|string the subdomain
|
|
||||||
*/
|
|
||||||
private function determineCurrentSubdomain()
|
|
||||||
{
|
|
||||||
// We have to ensure that a scheme exists
|
|
||||||
// on the URL else parse_url will mis-interpret
|
|
||||||
// 'host' as the 'path'.
|
|
||||||
$url = $this->httpHost;
|
|
||||||
if (strpos($url, 'http') !== 0) {
|
|
||||||
$url = 'http://' . $url;
|
|
||||||
}
|
|
||||||
|
|
||||||
$parsedUrl = parse_url($url);
|
|
||||||
|
|
||||||
$host = explode('.', $parsedUrl['host']);
|
|
||||||
|
|
||||||
if ($host[0] === 'www') {
|
|
||||||
unset($host[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rid of any domains, which will be the last
|
|
||||||
unset($host[count($host) - 1]);
|
|
||||||
|
|
||||||
// Account for .co.uk, .co.nz, etc. domains
|
|
||||||
if (end($host) === 'co') {
|
|
||||||
$host = array_slice($host, 0, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we only have 1 part left, then we don't have a sub-domain.
|
|
||||||
if (count($host) === 1) {
|
|
||||||
// Set it to false so we don't make it back here again.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_shift($host);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,9 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Libraries;
|
namespace App\Libraries;
|
||||||
|
|
||||||
|
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||||
use CodeIgniter\Router\Exceptions\RedirectException;
|
use CodeIgniter\Router\Exceptions\RedirectException;
|
||||||
|
use CodeIgniter\Router\Exceptions\RouterException;
|
||||||
use CodeIgniter\Router\Router as CodeIgniterRouter;
|
use CodeIgniter\Router\Router as CodeIgniterRouter;
|
||||||
use Config\Services;
|
use Config\Services;
|
||||||
|
|
||||||
|
@ -40,26 +42,14 @@ class Router extends CodeIgniterRouter
|
||||||
$uri = $uri === '/' ? $uri : trim($uri, '/ ');
|
$uri = $uri === '/' ? $uri : trim($uri, '/ ');
|
||||||
|
|
||||||
// Loop through the route array looking for wildcards
|
// Loop through the route array looking for wildcards
|
||||||
foreach ($routes as $routeKey => $val) {
|
foreach ($routes as $routeKey => $handler) {
|
||||||
// Reset localeSegment
|
|
||||||
$localeSegment = null;
|
|
||||||
|
|
||||||
$routeKey = $routeKey === '/' ? $routeKey : ltrim($routeKey, '/ ');
|
$routeKey = $routeKey === '/' ? $routeKey : ltrim($routeKey, '/ ');
|
||||||
|
|
||||||
$matchedKey = $routeKey;
|
$matchedKey = $routeKey;
|
||||||
|
|
||||||
// Are we dealing with a locale?
|
// Are we dealing with a locale?
|
||||||
if (str_contains($routeKey, '{locale}')) {
|
if (strpos($routeKey, '{locale}') !== false) {
|
||||||
$localeSegment = array_search(
|
$routeKey = str_replace('{locale}', '[^/]+', $routeKey);
|
||||||
'{locale}',
|
|
||||||
preg_split('~[\/]*((^[a-zA-Z0-9])|\(([^()]*)\))*[\/]+~m', $routeKey),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Replace it with a regex so it
|
|
||||||
// will actually match.
|
|
||||||
$routeKey = str_replace('/', '\/', $routeKey);
|
|
||||||
$routeKey = str_replace('{locale}', '[^\/]+', $routeKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does the RegEx match?
|
// Does the RegEx match?
|
||||||
|
@ -68,32 +58,51 @@ class Router extends CodeIgniterRouter
|
||||||
|
|
||||||
// Is this route supposed to redirect to another?
|
// Is this route supposed to redirect to another?
|
||||||
if ($this->collection->isRedirect($routeKey)) {
|
if ($this->collection->isRedirect($routeKey)) {
|
||||||
|
// replacing matched route groups with references: post/([0-9]+) -> post/$1
|
||||||
|
$redirectTo = preg_replace_callback('/(\([^\(]+\))/', static function (): string {
|
||||||
|
static $i = 1;
|
||||||
|
|
||||||
|
return '$' . $i++;
|
||||||
|
}, (string) (is_array($handler) ? key($handler) : $handler));
|
||||||
|
|
||||||
throw new RedirectException(
|
throw new RedirectException(
|
||||||
is_array($val) ? key($val) : $val,
|
preg_replace('#^' . $routeKey . '$#u', $redirectTo, $uri),
|
||||||
$this->collection->getRedirectCode($routeKey),
|
$this->collection->getRedirectCode($routeKey)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store our locale so CodeIgniter object can
|
// Store our locale so CodeIgniter object can
|
||||||
// assign it to the Request.
|
// assign it to the Request.
|
||||||
if (isset($localeSegment)) {
|
if (strpos($matchedKey, '{locale}') !== false) {
|
||||||
// The following may be inefficient, but doesn't upset NetBeans :-/
|
preg_match(
|
||||||
$temp = explode('/', $uri);
|
'#^' . str_replace('{locale}', '(?<locale>[^/]+)', $matchedKey) . '$#u',
|
||||||
$this->detectedLocale = $temp[$localeSegment];
|
$uri,
|
||||||
|
$matched
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($this->collection->shouldUseSupportedLocalesOnly()
|
||||||
|
&& ! in_array($matched['locale'], config(App::class)->supportedLocales, true)) {
|
||||||
|
// Throw exception to prevent the autorouter, if enabled,
|
||||||
|
// from trying to find a route
|
||||||
|
throw PageNotFoundException::forLocaleNotSupported($matched['locale']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->detectedLocale = $matched['locale'];
|
||||||
|
unset($matched);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we using Closures? If so, then we need
|
// Are we using Closures? If so, then we need
|
||||||
// to collect the params into an array
|
// to collect the params into an array
|
||||||
// so it can be passed to the controller method later.
|
// so it can be passed to the controller method later.
|
||||||
if (! is_string($val) && is_callable($val)) {
|
if (! is_string($handler) && is_callable($handler)) {
|
||||||
$this->controller = $val;
|
$this->controller = $handler;
|
||||||
|
|
||||||
// Remove the original string from the matches array
|
// Remove the original string from the matches array
|
||||||
array_shift($matches);
|
array_shift($matches);
|
||||||
|
|
||||||
$this->params = $matches;
|
$this->params = $matches;
|
||||||
|
|
||||||
$this->matchedRoute = [$matchedKey, $val];
|
$this->setMatchedRoute($matchedKey, $handler);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -123,62 +132,74 @@ class Router extends CodeIgniterRouter
|
||||||
$expectedContentType = $parsedHeader[0];
|
$expectedContentType = $parsedHeader[0];
|
||||||
foreach ($supported as $available) {
|
foreach ($supported as $available) {
|
||||||
if (
|
if (
|
||||||
$negotiate->callMatch($expectedContentType, $available, true)
|
! $negotiate->callMatch($expectedContentType, $available, true)
|
||||||
) {
|
) {
|
||||||
if (
|
continue;
|
||||||
array_key_exists(
|
|
||||||
'namespace',
|
|
||||||
$this->matchedRouteOptions[
|
|
||||||
'alternate-content'
|
|
||||||
][$available],
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
$this->collection->setDefaultNamespace(
|
|
||||||
$this->matchedRouteOptions[
|
|
||||||
'alternate-content'
|
|
||||||
][$available]['namespace'],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$val =
|
|
||||||
$this->collection->getDefaultNamespace() .
|
|
||||||
$this->directory .
|
|
||||||
$this->matchedRouteOptions['alternate-content'][
|
|
||||||
$available
|
|
||||||
]['controller-method'];
|
|
||||||
|
|
||||||
// no need to continue loop as $val has been overwritten
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
array_key_exists(
|
||||||
|
'namespace',
|
||||||
|
$this->matchedRouteOptions[
|
||||||
|
'alternate-content'
|
||||||
|
][$available],
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
$this->collection->setDefaultNamespace(
|
||||||
|
$this->matchedRouteOptions[
|
||||||
|
'alternate-content'
|
||||||
|
][$available]['namespace'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$handler =
|
||||||
|
$this->collection->getDefaultNamespace() .
|
||||||
|
$this->directory .
|
||||||
|
$this->matchedRouteOptions['alternate-content'][
|
||||||
|
$available
|
||||||
|
]['controller-method'];
|
||||||
|
|
||||||
|
// no need to continue loop as $handle has been overwritten
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we using the default method for back-references?
|
// Are we using Closures? If so, then we need
|
||||||
|
// to collect the params into an array
|
||||||
|
// so it can be passed to the controller method later.
|
||||||
|
if (! is_string($handler) && is_callable($handler)) {
|
||||||
|
$this->controller = $handler;
|
||||||
|
|
||||||
// Support resource route when function with subdirectory
|
// Remove the original string from the matches array
|
||||||
// ex: $routes->resource('Admin/Admins');
|
array_shift($matches);
|
||||||
if (
|
|
||||||
str_contains((string) $val, '$') &&
|
|
||||||
str_contains($routeKey, '(') &&
|
|
||||||
str_contains($routeKey, '/')
|
|
||||||
) {
|
|
||||||
$replacekey = str_replace('/(.*)', '', $routeKey);
|
|
||||||
$val = preg_replace('#^' . $routeKey . '$#u', (string) $val, $uri);
|
|
||||||
$val = str_replace($replacekey, str_replace('/', '\\', $replacekey), $val);
|
|
||||||
} elseif (str_contains((string) $val, '$') && str_contains($routeKey, '(')) {
|
|
||||||
$val = preg_replace('#^' . $routeKey . '$#u', (string) $val, $uri);
|
|
||||||
} elseif (str_contains((string) $val, '/')) {
|
|
||||||
[$controller, $method] = explode('::', (string) $val);
|
|
||||||
|
|
||||||
// Only replace slashes in the controller, not in the method.
|
$this->params = $matches;
|
||||||
$controller = str_replace('/', '\\', $controller);
|
|
||||||
|
|
||||||
$val = $controller . '::' . $method;
|
$this->setMatchedRoute($matchedKey, $handler);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setRequest(explode('/', (string) $val));
|
[$controller] = explode('::', (string) $handler);
|
||||||
|
|
||||||
$this->matchedRoute = [$matchedKey, $val];
|
// Checks `/` in controller name
|
||||||
|
if (strpos($controller, '/') !== false) {
|
||||||
|
throw RouterException::forInvalidControllerName($handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos((string) $handler, '$') !== false && strpos($routeKey, '(') !== false) {
|
||||||
|
// Checks dynamic controller
|
||||||
|
if (strpos($controller, '$') !== false) {
|
||||||
|
throw RouterException::forDynamicController($handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Using back-references
|
||||||
|
$handler = preg_replace('#^' . $routeKey . '$#u', (string) $handler, $uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setRequest(explode('/', (string) $handler));
|
||||||
|
|
||||||
|
$this->setMatchedRoute($matchedKey, $handler);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ class ComponentRenderer
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->config = config('ViewComponents');
|
$this->config = config(ViewComponents::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(string $output): string
|
public function render(string $output): string
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Theme
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->config = config('Themes');
|
$this->config = config(Themes::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,7 +85,7 @@ class Theme
|
||||||
{
|
{
|
||||||
$themes = [];
|
$themes = [];
|
||||||
|
|
||||||
$config = config('Themes');
|
$config = config(Themes::class);
|
||||||
|
|
||||||
foreach ($config->themes as $name => $folder) {
|
foreach ($config->themes as $name => $folder) {
|
||||||
$themes[] = [
|
$themes[] = [
|
||||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace Vite;
|
namespace Vite;
|
||||||
|
|
||||||
use ErrorException;
|
use ErrorException;
|
||||||
|
use Vite\Config\Vite as ViteConfig;
|
||||||
|
|
||||||
class Vite
|
class Vite
|
||||||
{
|
{
|
||||||
|
@ -20,7 +21,7 @@ class Vite
|
||||||
|
|
||||||
public function asset(string $path, string $type): string
|
public function asset(string $path, string $type): string
|
||||||
{
|
{
|
||||||
if (config('Vite')->environment !== 'production') {
|
if (config(ViteConfig::class)->environment !== 'production') {
|
||||||
return $this->loadDev($path, $type);
|
return $this->loadDev($path, $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +30,10 @@ class Vite
|
||||||
|
|
||||||
private function loadDev(string $path, string $type): string
|
private function loadDev(string $path, string $type): string
|
||||||
{
|
{
|
||||||
return $this->getHtmlTag(config('Vite')->baseUrl . config('Vite')->assetsRoot . "/{$path}", $type);
|
return $this->getHtmlTag(
|
||||||
|
config(ViteConfig::class)->baseUrl . config(ViteConfig::class)->assetsRoot . "/{$path}",
|
||||||
|
$type
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadProd(string $path, string $type): string
|
private function loadProd(string $path, string $type): string
|
||||||
|
@ -37,8 +41,8 @@ class Vite
|
||||||
if ($this->manifestData === null) {
|
if ($this->manifestData === null) {
|
||||||
$cacheName = 'vite-manifest';
|
$cacheName = 'vite-manifest';
|
||||||
if (! ($cachedManifest = cache($cacheName))) {
|
if (! ($cachedManifest = cache($cacheName))) {
|
||||||
$manifestPath = config('Vite')
|
$manifestPath = config(ViteConfig::class)
|
||||||
->assetsRoot . '/' . config('Vite')
|
->assetsRoot . '/' . config(ViteConfig::class)
|
||||||
->manifestFile;
|
->manifestFile;
|
||||||
try {
|
try {
|
||||||
if (($manifestContents = file_get_contents($manifestPath)) !== false) {
|
if (($manifestContents = file_get_contents($manifestPath)) !== false) {
|
||||||
|
@ -62,7 +66,7 @@ class Vite
|
||||||
// import css dependencies if any
|
// import css dependencies if any
|
||||||
if (array_key_exists('css', $manifestElement)) {
|
if (array_key_exists('css', $manifestElement)) {
|
||||||
foreach ($manifestElement['css'] as $cssFile) {
|
foreach ($manifestElement['css'] as $cssFile) {
|
||||||
$html .= $this->getHtmlTag('/' . config('Vite')->assetsRoot . '/' . $cssFile, 'css');
|
$html .= $this->getHtmlTag('/' . config(ViteConfig::class)->assetsRoot . '/' . $cssFile, 'css');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,19 +77,27 @@ class Vite
|
||||||
// import css dependencies if any
|
// import css dependencies if any
|
||||||
if (array_key_exists('css', $this->manifestData[$importPath])) {
|
if (array_key_exists('css', $this->manifestData[$importPath])) {
|
||||||
foreach ($this->manifestData[$importPath]['css'] as $cssFile) {
|
foreach ($this->manifestData[$importPath]['css'] as $cssFile) {
|
||||||
$html .= $this->getHtmlTag('/' . config('Vite')->assetsRoot . '/' . $cssFile, 'css');
|
$html .= $this->getHtmlTag(
|
||||||
|
'/' . config(ViteConfig::class)->assetsRoot . '/' . $cssFile,
|
||||||
|
'css'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$html .= $this->getHtmlTag(
|
$html .= $this->getHtmlTag(
|
||||||
'/' . config('Vite')->assetsRoot . '/' . $this->manifestData[$importPath]['file'],
|
'/' . config(
|
||||||
|
ViteConfig::class
|
||||||
|
)->assetsRoot . '/' . $this->manifestData[$importPath]['file'],
|
||||||
'js'
|
'js'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$html .= $this->getHtmlTag('/' . config('Vite')->assetsRoot . '/' . $manifestElement['file'], $type);
|
$html .= $this->getHtmlTag(
|
||||||
|
'/' . config(ViteConfig::class)->assetsRoot . '/' . $manifestElement['file'],
|
||||||
|
$type
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace App\Models;
|
||||||
|
|
||||||
use App\Entities\Platform;
|
use App\Entities\Platform;
|
||||||
use CodeIgniter\Model;
|
use CodeIgniter\Model;
|
||||||
|
use Config\App;
|
||||||
|
|
||||||
class PlatformModel extends Model
|
class PlatformModel extends Model
|
||||||
{
|
{
|
||||||
|
@ -53,7 +54,7 @@ class PlatformModel extends Model
|
||||||
public function getPlatforms(): array
|
public function getPlatforms(): array
|
||||||
{
|
{
|
||||||
if (! ($found = cache('platforms'))) {
|
if (! ($found = cache('platforms'))) {
|
||||||
$baseUrl = rtrim((string) config('app')->baseURL, '/');
|
$baseUrl = rtrim(config(App::class)->baseURL, '/');
|
||||||
$found = $this->select(
|
$found = $this->select(
|
||||||
"*, CONCAT('{$baseUrl}/assets/images/platforms/',`type`,'/',`slug`,'.svg') as icon",
|
"*, CONCAT('{$baseUrl}/assets/images/platforms/',`type`,'/',`slug`,'.svg') as icon",
|
||||||
)->findAll();
|
)->findAll();
|
||||||
|
|
|
@ -14,6 +14,7 @@ use App\Entities\Actor;
|
||||||
use App\Entities\Podcast;
|
use App\Entities\Podcast;
|
||||||
use CodeIgniter\HTTP\URI;
|
use CodeIgniter\HTTP\URI;
|
||||||
use CodeIgniter\Model;
|
use CodeIgniter\Model;
|
||||||
|
use Config\Fediverse;
|
||||||
use phpseclib\Crypt\RSA;
|
use phpseclib\Crypt\RSA;
|
||||||
|
|
||||||
class PodcastModel extends Model
|
class PodcastModel extends Model
|
||||||
|
@ -363,7 +364,7 @@ class PodcastModel extends Model
|
||||||
|
|
||||||
// delete all cache for podcast actor
|
// delete all cache for podcast actor
|
||||||
cache()
|
cache()
|
||||||
->deleteMatching(config('Fediverse') ->cachePrefix . "actor#{$podcast->actor_id}*");
|
->deleteMatching(config(Fediverse::class) ->cachePrefix . "actor#{$podcast->actor_id}*");
|
||||||
|
|
||||||
// delete model requests cache, includes feed / query / episode lists, etc.
|
// delete model requests cache, includes feed / query / episode lists, etc.
|
||||||
cache()
|
cache()
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1",
|
"php": "^8.1",
|
||||||
"codeigniter4/framework": "v4.3.8",
|
"codeigniter4/framework": "v4.4.0",
|
||||||
"james-heinrich/getid3": "^2.0.0-beta5",
|
"james-heinrich/getid3": "^2.0.0-beta5",
|
||||||
"whichbrowser/parser": "^v2.1.7",
|
"whichbrowser/parser": "^v2.1.7",
|
||||||
"geoip2/geoip2": "v2.13.0",
|
"geoip2/geoip2": "v2.13.0",
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "bf2ad79ae7e152da4c25f9dfa59e887f",
|
"content-hash": "4526c68d78e5abe8e5c86016356e15f9",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "adaures/ipcat-php",
|
"name": "adaures/ipcat-php",
|
||||||
|
@ -304,16 +304,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "codeigniter4/framework",
|
"name": "codeigniter4/framework",
|
||||||
"version": "v4.3.8",
|
"version": "v4.4.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/codeigniter4/framework.git",
|
"url": "https://github.com/codeigniter4/framework.git",
|
||||||
"reference": "10c23e96db99171bc7632184d0e986e6eecc242d"
|
"reference": "30008a0e3c342f2b6e5083927bec49feec95ed53"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/codeigniter4/framework/zipball/10c23e96db99171bc7632184d0e986e6eecc242d",
|
"url": "https://api.github.com/repos/codeigniter4/framework/zipball/30008a0e3c342f2b6e5083927bec49feec95ed53",
|
||||||
"reference": "10c23e96db99171bc7632184d0e986e6eecc242d",
|
"reference": "30008a0e3c342f2b6e5083927bec49feec95ed53",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -370,7 +370,7 @@
|
||||||
"slack": "https://codeigniterchat.slack.com",
|
"slack": "https://codeigniterchat.slack.com",
|
||||||
"source": "https://github.com/codeigniter4/CodeIgniter4"
|
"source": "https://github.com/codeigniter4/CodeIgniter4"
|
||||||
},
|
},
|
||||||
"time": "2023-08-25T01:47:10+00:00"
|
"time": "2023-08-25T07:02:01+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "codeigniter4/settings",
|
"name": "codeigniter4/settings",
|
||||||
|
@ -5427,16 +5427,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v6.3.2",
|
"version": "v6.3.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/console.git",
|
"url": "https://github.com/symfony/console.git",
|
||||||
"reference": "aa5d64ad3f63f2e48964fc81ee45cb318a723898"
|
"reference": "eca495f2ee845130855ddf1cf18460c38966c8b6"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/console/zipball/aa5d64ad3f63f2e48964fc81ee45cb318a723898",
|
"url": "https://api.github.com/repos/symfony/console/zipball/eca495f2ee845130855ddf1cf18460c38966c8b6",
|
||||||
"reference": "aa5d64ad3f63f2e48964fc81ee45cb318a723898",
|
"reference": "eca495f2ee845130855ddf1cf18460c38966c8b6",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -5488,7 +5488,7 @@
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"keywords": ["cli", "command-line", "console", "terminal"],
|
"keywords": ["cli", "command-line", "console", "terminal"],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/console/tree/v6.3.2"
|
"source": "https://github.com/symfony/console/tree/v6.3.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -5504,7 +5504,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-07-19T20:17:28+00:00"
|
"time": "2023-08-16T10:10:12+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/event-dispatcher",
|
"name": "symfony/event-dispatcher",
|
||||||
|
@ -6059,16 +6059,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v6.3.2",
|
"version": "v6.3.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/process.git",
|
"url": "https://github.com/symfony/process.git",
|
||||||
"reference": "c5ce962db0d9b6e80247ca5eb9af6472bd4d7b5d"
|
"reference": "0b5c29118f2e980d455d2e34a5659f4579847c54"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/process/zipball/c5ce962db0d9b6e80247ca5eb9af6472bd4d7b5d",
|
"url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54",
|
||||||
"reference": "c5ce962db0d9b6e80247ca5eb9af6472bd4d7b5d",
|
"reference": "0b5c29118f2e980d455d2e34a5659f4579847c54",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -6096,7 +6096,7 @@
|
||||||
"description": "Executes commands in sub-processes",
|
"description": "Executes commands in sub-processes",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/process/tree/v6.3.2"
|
"source": "https://github.com/symfony/process/tree/v6.3.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -6112,7 +6112,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-07-12T16:00:22+00:00"
|
"time": "2023-08-07T10:39:22+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/service-contracts",
|
"name": "symfony/service-contracts",
|
||||||
|
|
|
@ -7,7 +7,6 @@ namespace Modules\Admin\Config;
|
||||||
use CodeIgniter\Router\RouteCollection;
|
use CodeIgniter\Router\RouteCollection;
|
||||||
|
|
||||||
/** @var RouteCollection $routes */
|
/** @var RouteCollection $routes */
|
||||||
$routes = service('routes');
|
|
||||||
|
|
||||||
// video-clips scheduler
|
// video-clips scheduler
|
||||||
$routes->add('scheduled-video-clips', 'SchedulerController::generateVideoClips', [
|
$routes->add('scheduled-video-clips', 'SchedulerController::generateVideoClips', [
|
||||||
|
@ -16,8 +15,7 @@ $routes->add('scheduled-video-clips', 'SchedulerController::generateVideoClips',
|
||||||
|
|
||||||
// Admin area routes
|
// Admin area routes
|
||||||
$routes->group(
|
$routes->group(
|
||||||
config('Admin')
|
config(Admin::class)->gateway,
|
||||||
->gateway,
|
|
||||||
[
|
[
|
||||||
'namespace' => 'Modules\Admin\Controllers',
|
'namespace' => 'Modules\Admin\Controllers',
|
||||||
],
|
],
|
||||||
|
@ -161,7 +159,7 @@ $routes->group(
|
||||||
'filter' => 'permission:podcast#.delete',
|
'filter' => 'permission:podcast#.delete',
|
||||||
]);
|
]);
|
||||||
$routes->group('persons', static function ($routes): void {
|
$routes->group('persons', static function ($routes): void {
|
||||||
$routes->get('/', 'PodcastPersonController/$1', [
|
$routes->get('/', 'PodcastPersonController::index/$1', [
|
||||||
'as' => 'podcast-persons-manage',
|
'as' => 'podcast-persons-manage',
|
||||||
'filter' => 'permission:podcast#.manage-persons',
|
'filter' => 'permission:podcast#.manage-persons',
|
||||||
]);
|
]);
|
||||||
|
@ -457,7 +455,7 @@ $routes->group(
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
$routes->group('persons', static function ($routes): void {
|
$routes->group('persons', static function ($routes): void {
|
||||||
$routes->get('/', 'EpisodePersonController/$1/$2', [
|
$routes->get('/', 'EpisodePersonController::index/$1/$2', [
|
||||||
'as' => 'episode-persons-manage',
|
'as' => 'episode-persons-manage',
|
||||||
'filter' => 'permission:podcast#.episodes.manage-persons',
|
'filter' => 'permission:podcast#.episodes.manage-persons',
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||||
namespace Modules\Admin\Controllers;
|
namespace Modules\Admin\Controllers;
|
||||||
|
|
||||||
use CodeIgniter\HTTP\RedirectResponse;
|
use CodeIgniter\HTTP\RedirectResponse;
|
||||||
|
use Config\App;
|
||||||
use Config\Services;
|
use Config\Services;
|
||||||
|
|
||||||
class AboutController extends BaseController
|
class AboutController extends BaseController
|
||||||
|
@ -22,7 +23,7 @@ class AboutController extends BaseController
|
||||||
'version' => CP_VERSION,
|
'version' => CP_VERSION,
|
||||||
'php_version' => PHP_VERSION,
|
'php_version' => PHP_VERSION,
|
||||||
'os' => PHP_OS,
|
'os' => PHP_OS,
|
||||||
'languages' => implode(', ', config('App')->supportedLocales),
|
'languages' => implode(', ', config(App::class)->supportedLocales),
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('about', [
|
return view('about', [
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace Modules\Admin\Controllers;
|
||||||
use App\Models\EpisodeModel;
|
use App\Models\EpisodeModel;
|
||||||
use App\Models\PodcastModel;
|
use App\Models\PodcastModel;
|
||||||
use CodeIgniter\I18n\Time;
|
use CodeIgniter\I18n\Time;
|
||||||
|
use Config\App;
|
||||||
use Modules\Media\Models\MediaModel;
|
use Modules\Media\Models\MediaModel;
|
||||||
|
|
||||||
class DashboardController extends BaseController
|
class DashboardController extends BaseController
|
||||||
|
@ -50,7 +51,7 @@ class DashboardController extends BaseController
|
||||||
->get()
|
->get()
|
||||||
->getResultArray()[0];
|
->getResultArray()[0];
|
||||||
|
|
||||||
$appStorageLimit = config('App')
|
$appStorageLimit = config(App::class)
|
||||||
->storageLimit;
|
->storageLimit;
|
||||||
if ($appStorageLimit === null || $appStorageLimit < 0) {
|
if ($appStorageLimit === null || $appStorageLimit < 0) {
|
||||||
$storageLimitBytes = disk_total_space('./');
|
$storageLimitBytes = disk_total_space('./');
|
||||||
|
@ -70,7 +71,7 @@ class DashboardController extends BaseController
|
||||||
->id;
|
->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$bandwidthLimit = config('App')
|
$bandwidthLimit = config(App::class)
|
||||||
->bandwidthLimit;
|
->bandwidthLimit;
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
|
|
|
@ -32,6 +32,7 @@ use Modules\Analytics\Models\AnalyticsPodcastModel;
|
||||||
use Modules\Analytics\Models\AnalyticsWebsiteByBrowserModel;
|
use Modules\Analytics\Models\AnalyticsWebsiteByBrowserModel;
|
||||||
use Modules\Analytics\Models\AnalyticsWebsiteByEntryPageModel;
|
use Modules\Analytics\Models\AnalyticsWebsiteByEntryPageModel;
|
||||||
use Modules\Analytics\Models\AnalyticsWebsiteByRefererModel;
|
use Modules\Analytics\Models\AnalyticsWebsiteByRefererModel;
|
||||||
|
use Modules\Auth\Config\AuthGroups;
|
||||||
use Modules\Media\Entities\Image;
|
use Modules\Media\Entities\Image;
|
||||||
use Modules\Media\FileManagers\FileManagerInterface;
|
use Modules\Media\FileManagers\FileManagerInterface;
|
||||||
use Modules\Media\Models\MediaModel;
|
use Modules\Media\Models\MediaModel;
|
||||||
|
@ -255,7 +256,7 @@ class PodcastController extends BaseController
|
||||||
|
|
||||||
// generate podcast roles and permissions
|
// generate podcast roles and permissions
|
||||||
// before setting current user as podcast admin
|
// before setting current user as podcast admin
|
||||||
config('AuthGroups')
|
config(AuthGroups::class)
|
||||||
->generatePodcastAuthorizations($newPodcastId);
|
->generatePodcastAuthorizations($newPodcastId);
|
||||||
add_podcast_group(auth()->user(), (int) $newPodcastId, setting('AuthGroups.mostPowerfulPodcastGroup'));
|
add_podcast_group(auth()->user(), (int) $newPodcastId, setting('AuthGroups.mostPowerfulPodcastGroup'));
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,10 @@ use App\Models\EpisodeModel;
|
||||||
use App\Models\PodcastModel;
|
use App\Models\PodcastModel;
|
||||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||||
use CodeIgniter\HTTP\RedirectResponse;
|
use CodeIgniter\HTTP\RedirectResponse;
|
||||||
|
use Config\Colors;
|
||||||
use Modules\Media\Entities\Transcript;
|
use Modules\Media\Entities\Transcript;
|
||||||
use Modules\Media\Models\MediaModel;
|
use Modules\Media\Models\MediaModel;
|
||||||
|
use Modules\MediaClipper\Config\MediaClipper;
|
||||||
|
|
||||||
class VideoClipsController extends BaseController
|
class VideoClipsController extends BaseController
|
||||||
{
|
{
|
||||||
|
@ -144,8 +146,8 @@ class VideoClipsController extends BaseController
|
||||||
'title' => 'required',
|
'title' => 'required',
|
||||||
'start_time' => 'required|greater_than_equal_to[0]',
|
'start_time' => 'required|greater_than_equal_to[0]',
|
||||||
'duration' => 'required|greater_than[0]',
|
'duration' => 'required|greater_than[0]',
|
||||||
'format' => 'required|in_list[' . implode(',', array_keys(config('MediaClipper')->formats)) . ']',
|
'format' => 'required|in_list[' . implode(',', array_keys(config(MediaClipper::class)->formats)) . ']',
|
||||||
'theme' => 'required|in_list[' . implode(',', array_keys(config('Colors')->themes)) . ']',
|
'theme' => 'required|in_list[' . implode(',', array_keys(config(Colors::class)->themes)) . ']',
|
||||||
];
|
];
|
||||||
|
|
||||||
if (! $this->validate($rules)) {
|
if (! $this->validate($rules)) {
|
||||||
|
@ -156,7 +158,7 @@ class VideoClipsController extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
$themeName = $this->request->getPost('theme');
|
$themeName = $this->request->getPost('theme');
|
||||||
$themeColors = config('MediaClipper')
|
$themeColors = config(MediaClipper::class)
|
||||||
->themes[$themeName];
|
->themes[$themeName];
|
||||||
$theme = [
|
$theme = [
|
||||||
'name' => $themeName,
|
'name' => $themeName,
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'الرئيسية',
|
->gateway => 'الرئيسية',
|
||||||
'podcasts' => 'بودكاستات',
|
'podcasts' => 'بودكاستات',
|
||||||
'episodes' => 'حلقات',
|
'episodes' => 'حلقات',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'roll-istor',
|
'label' => 'roll-istor',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Degemer',
|
->gateway => 'Degemer',
|
||||||
'podcasts' => 'podkastoù',
|
'podcasts' => 'podkastoù',
|
||||||
'episodes' => 'rannoù',
|
'episodes' => 'rannoù',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'Ruta de navegació',
|
'label' => 'Ruta de navegació',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Inici',
|
->gateway => 'Inici',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodis',
|
'episodes' => 'episodis',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'brødkrumme',
|
'label' => 'brødkrumme',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Hjem',
|
->gateway => 'Hjem',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episoder',
|
'episodes' => 'episoder',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'Pfad',
|
'label' => 'Pfad',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Startseite',
|
->gateway => 'Startseite',
|
||||||
'podcasts' => 'Podcasts',
|
'podcasts' => 'Podcasts',
|
||||||
'episodes' => 'Folgen',
|
'episodes' => 'Folgen',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'διαδρομή (Breadcrumb)',
|
'label' => 'διαδρομή (Breadcrumb)',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Αρχική σελίδα',
|
->gateway => 'Αρχική σελίδα',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'επεισόδια',
|
'episodes' => 'επεισόδια',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'ruta de navegación',
|
'label' => 'ruta de navegación',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Inicio',
|
->gateway => 'Inicio',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodios',
|
'episodes' => 'episodios',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'Fil d’Ariane',
|
'label' => 'Fil d’Ariane',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Accueil',
|
->gateway => 'Accueil',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'épisodes',
|
'episodes' => 'épisodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'fil d’Ariane',
|
'label' => 'fil d’Ariane',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Accueil',
|
->gateway => 'Accueil',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'épisodes',
|
'episodes' => 'épisodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'menú',
|
'label' => 'menú',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Inicio',
|
->gateway => 'Inicio',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodios',
|
'episodes' => 'episodios',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodi',
|
'episodes' => 'episodi',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'kruimelpad',
|
'label' => 'kruimelpad',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Hoofdpagina',
|
->gateway => 'Hoofdpagina',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'afleveringen',
|
'episodes' => 'afleveringen',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'navigeringslenke',
|
'label' => 'navigeringslenke',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Heim',
|
->gateway => 'Heim',
|
||||||
'podcasts' => 'podkastar',
|
'podcasts' => 'podkastar',
|
||||||
'episodes' => 'episodar',
|
'episodes' => 'episodar',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'okruszki',
|
'label' => 'okruszki',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Początek',
|
->gateway => 'Początek',
|
||||||
'podcasts' => 'podcasty',
|
'podcasts' => 'podcasty',
|
||||||
'episodes' => 'odcinki',
|
'episodes' => 'odcinki',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Início',
|
->gateway => 'Início',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episódios',
|
'episodes' => 'episódios',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'навигационная цепочка',
|
'label' => 'навигационная цепочка',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Главная',
|
->gateway => 'Главная',
|
||||||
'podcasts' => 'подкасты',
|
'podcasts' => 'подкасты',
|
||||||
'episodes' => 'выпуски',
|
'episodes' => 'выпуски',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'omrvinky',
|
'label' => 'omrvinky',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Úvod',
|
->gateway => 'Úvod',
|
||||||
'podcasts' => 'podcasty',
|
'podcasts' => 'podcasty',
|
||||||
'episodes' => 'časti',
|
'episodes' => 'časti',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb polja',
|
'label' => 'breadcrumb polja',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Početna',
|
->gateway => 'Početna',
|
||||||
'podcasts' => 'podkasti',
|
'podcasts' => 'podkasti',
|
||||||
'episodes' => 'epizode',
|
'episodes' => 'epizode',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Hem',
|
->gateway => 'Hem',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'avsnitt',
|
'episodes' => 'avsnitt',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => 'breadcrumb',
|
'label' => 'breadcrumb',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => 'Home',
|
->gateway => 'Home',
|
||||||
'podcasts' => 'podcasts',
|
'podcasts' => 'podcasts',
|
||||||
'episodes' => 'episodes',
|
'episodes' => 'episodes',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2020 Ad Aures
|
* @copyright 2020 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
|
@ -10,7 +12,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => '面包屑导航',
|
'label' => '面包屑导航',
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway => '主页',
|
->gateway => '主页',
|
||||||
'podcasts' => '播客',
|
'podcasts' => '播客',
|
||||||
'episodes' => '剧集',
|
'episodes' => '剧集',
|
||||||
|
|
|
@ -2,13 +2,16 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use CodeIgniter\Router\RouteCollection;
|
||||||
|
use Modules\Analytics\Config\Analytics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2021 Ad Aures
|
* @copyright 2021 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
* @link https://castopod.org/
|
* @link https://castopod.org/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$routes = service('routes');
|
/** @var RouteCollection $routes */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analytics routes file
|
* Analytics routes file
|
||||||
|
@ -25,17 +28,17 @@ $routes->addPlaceholder(
|
||||||
$routes->group('', [
|
$routes->group('', [
|
||||||
'namespace' => 'Modules\Analytics\Controllers',
|
'namespace' => 'Modules\Analytics\Controllers',
|
||||||
], static function ($routes): void {
|
], static function ($routes): void {
|
||||||
$routes->group(config('Analytics')->gateway . '/(:num)/(:class)', static function ($routes): void {
|
$routes->group(config(Analytics::class)->gateway . '/(:num)/(:class)', static function ($routes): void {
|
||||||
$routes->get('/', 'AnalyticsController::getData/$1/$2', [
|
$routes->get('/', 'AnalyticsController::getData/$1/$2', [
|
||||||
'as' => 'analytics-full-data',
|
'as' => 'analytics-full-data',
|
||||||
'filter' => config('Analytics')
|
'filter' => config(Analytics::class)
|
||||||
->routeFilters[
|
->routeFilters[
|
||||||
'analytics-full-data'
|
'analytics-full-data'
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
$routes->get('(:filter)', 'AnalyticsController::getData/$1/$2/$3', [
|
$routes->get('(:filter)', 'AnalyticsController::getData/$1/$2/$3', [
|
||||||
'as' => 'analytics-data',
|
'as' => 'analytics-data',
|
||||||
'filter' => config('Analytics')
|
'filter' => config(Analytics::class)
|
||||||
->routeFilters['analytics-data'],
|
->routeFilters['analytics-data'],
|
||||||
]);
|
]);
|
||||||
$routes->get(
|
$routes->get(
|
||||||
|
@ -43,14 +46,14 @@ $routes->group('', [
|
||||||
'AnalyticsController::getData/$1/$2/$3/$4',
|
'AnalyticsController::getData/$1/$2/$3/$4',
|
||||||
[
|
[
|
||||||
'as' => 'analytics-filtered-data',
|
'as' => 'analytics-filtered-data',
|
||||||
'filter' => config('Analytics')
|
'filter' => config(Analytics::class)
|
||||||
->routeFilters[
|
->routeFilters[
|
||||||
'analytics-filtered-data'
|
'analytics-filtered-data'
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
$routes->get(config('Analytics')->gateway . '/(:class)/(:filter)', 'AnalyticsController::getData/$1/$2', [
|
$routes->get(config(Analytics::class)->gateway . '/(:class)/(:filter)', 'AnalyticsController::getData/$1/$2', [
|
||||||
'as' => 'analytics-data-instance',
|
'as' => 'analytics-data-instance',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -63,4 +66,4 @@ $routes->group('', [
|
||||||
|
|
||||||
// Show the Unknown UserAgents
|
// Show the Unknown UserAgents
|
||||||
$routes->get('.well-known/unknown-useragents', 'UnknownUserAgentsController');
|
$routes->get('.well-known/unknown-useragents', 'UnknownUserAgentsController');
|
||||||
$routes->get('.well-known/unknown-useragents/(:num)', 'UnknownUserAgentsController/$1');
|
$routes->get('.well-known/unknown-useragents/(:num)', 'UnknownUserAgentsController::index/$1');
|
||||||
|
|
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||||
use AdAures\Ipcat\IpDb;
|
use AdAures\Ipcat\IpDb;
|
||||||
use Config\Services;
|
use Config\Services;
|
||||||
use GeoIp2\Database\Reader;
|
use GeoIp2\Database\Reader;
|
||||||
|
use Modules\Analytics\Config\Analytics;
|
||||||
use Opawg\UserAgentsPhp\UserAgents;
|
use Opawg\UserAgentsPhp\UserAgents;
|
||||||
use WhichBrowser\Parser;
|
use WhichBrowser\Parser;
|
||||||
|
|
||||||
|
@ -260,7 +261,7 @@ if (! function_exists('podcast_hit')) {
|
||||||
? $_SERVER['HTTP_RANGE']
|
? $_SERVER['HTTP_RANGE']
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
$salt = config('Analytics')
|
$salt = config(Analytics::class)
|
||||||
->salt;
|
->salt;
|
||||||
// We create a sha1 hash for this Salt+Current_Date+IP_Address+User_Agent+Episode_ID (used to count only once multiple episode downloads):
|
// We create a sha1 hash for this Salt+Current_Date+IP_Address+User_Agent+Episode_ID (used to count only once multiple episode downloads):
|
||||||
$episodeListenerHashId =
|
$episodeListenerHashId =
|
||||||
|
|
|
@ -4,10 +4,12 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Modules\Api\Rest\V1\Config;
|
namespace Modules\Api\Rest\V1\Config;
|
||||||
|
|
||||||
$routes = service('routes');
|
use CodeIgniter\Router\RouteCollection;
|
||||||
|
|
||||||
|
/** @var RouteCollection $routes */
|
||||||
|
|
||||||
$routes->group(
|
$routes->group(
|
||||||
config('RestApi')
|
config(RestApi::class)
|
||||||
->gateway . 'podcasts',
|
->gateway . 'podcasts',
|
||||||
[
|
[
|
||||||
'namespace' => 'Modules\Api\Rest\V1\Controllers',
|
'namespace' => 'Modules\Api\Rest\V1\Controllers',
|
||||||
|
@ -21,7 +23,7 @@ $routes->group(
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->group(
|
$routes->group(
|
||||||
config('RestApi')
|
config(RestApi::class)
|
||||||
->gateway . 'episodes',
|
->gateway . 'episodes',
|
||||||
[
|
[
|
||||||
'namespace' => 'Modules\Api\Rest\V1\Controllers',
|
'namespace' => 'Modules\Api\Rest\V1\Controllers',
|
||||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace Modules\Api\Rest\V1\Config;
|
namespace Modules\Api\Rest\V1\Config;
|
||||||
|
|
||||||
use CodeIgniter\Config\BaseService;
|
use CodeIgniter\Config\BaseService;
|
||||||
|
use Config\Exceptions as ExceptionsConfig;
|
||||||
use Modules\Api\Rest\V1\Core\Exceptions;
|
use Modules\Api\Rest\V1\Core\Exceptions;
|
||||||
|
|
||||||
class Services extends BaseService
|
class Services extends BaseService
|
||||||
|
@ -15,6 +16,6 @@ class Services extends BaseService
|
||||||
return static::getSharedInstance('restApiExceptions');
|
return static::getSharedInstance('restApiExceptions');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Exceptions(config('Exceptions'), static::request(), static::response());
|
return new Exceptions(config(ExceptionsConfig::class), static::request(), static::response());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use App\Models\EpisodeModel;
|
||||||
use CodeIgniter\API\ResponseTrait;
|
use CodeIgniter\API\ResponseTrait;
|
||||||
use CodeIgniter\Controller;
|
use CodeIgniter\Controller;
|
||||||
use CodeIgniter\HTTP\Response;
|
use CodeIgniter\HTTP\Response;
|
||||||
|
use Modules\Api\Rest\V1\Config\RestApi;
|
||||||
use Modules\Api\Rest\V1\Config\Services;
|
use Modules\Api\Rest\V1\Config\Services;
|
||||||
|
|
||||||
class EpisodeController extends Controller
|
class EpisodeController extends Controller
|
||||||
|
@ -45,7 +46,7 @@ class EpisodeController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $builder->findAll(
|
$data = $builder->findAll(
|
||||||
(int) ($this->request->getGet('limit') ?? config('RestApi')->limit),
|
(int) ($this->request->getGet('limit') ?? config(RestApi::class)->limit),
|
||||||
(int) $this->request->getGet('offset')
|
(int) $this->request->getGet('offset')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class ApiFilter implements FilterInterface
|
||||||
public function before(RequestInterface $request, $arguments = null)
|
public function before(RequestInterface $request, $arguments = null)
|
||||||
{
|
{
|
||||||
/** @var RestApi $restApiConfig */
|
/** @var RestApi $restApiConfig */
|
||||||
$restApiConfig = config('RestApi');
|
$restApiConfig = config(RestApi::class);
|
||||||
|
|
||||||
if (! $restApiConfig->enabled) {
|
if (! $restApiConfig->enabled) {
|
||||||
throw PageNotFoundException::forPageNotFound();
|
throw PageNotFoundException::forPageNotFound();
|
||||||
|
|
|
@ -6,6 +6,8 @@ namespace Modules\Auth;
|
||||||
|
|
||||||
use CodeIgniter\Router\RouteCollection;
|
use CodeIgniter\Router\RouteCollection;
|
||||||
use CodeIgniter\Shield\Auth as ShieldAuth;
|
use CodeIgniter\Shield\Auth as ShieldAuth;
|
||||||
|
use Modules\Auth\Config\Auth as AuthConfig;
|
||||||
|
use Modules\Auth\Config\AuthRoutes;
|
||||||
|
|
||||||
class Auth extends ShieldAuth
|
class Auth extends ShieldAuth
|
||||||
{
|
{
|
||||||
|
@ -19,10 +21,10 @@ class Auth extends ShieldAuth
|
||||||
*/
|
*/
|
||||||
public function routes(RouteCollection &$routes, array $config = []): void
|
public function routes(RouteCollection &$routes, array $config = []): void
|
||||||
{
|
{
|
||||||
$authRoutes = config('AuthRoutes')
|
$authRoutes = config(AuthRoutes::class)
|
||||||
->routes;
|
->routes;
|
||||||
|
|
||||||
$routes->group(config('Auth')->gateway, [
|
$routes->group(config(AuthConfig::class)->gateway, [
|
||||||
'namespace' => 'Modules\Auth\Controllers',
|
'namespace' => 'Modules\Auth\Controllers',
|
||||||
], static function (RouteCollection $routes) use ($authRoutes, $config): void {
|
], static function (RouteCollection $routes) use ($authRoutes, $config): void {
|
||||||
foreach ($authRoutes as $name => $row) {
|
foreach ($authRoutes as $name => $row) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace Modules\Auth\Config;
|
||||||
use CodeIgniter\Shield\Authentication\Actions\ActionInterface;
|
use CodeIgniter\Shield\Authentication\Actions\ActionInterface;
|
||||||
use CodeIgniter\Shield\Authentication\Actions\Email2FA;
|
use CodeIgniter\Shield\Authentication\Actions\Email2FA;
|
||||||
use CodeIgniter\Shield\Config\Auth as ShieldAuth;
|
use CodeIgniter\Shield\Config\Auth as ShieldAuth;
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
use Modules\Auth\Models\UserModel;
|
use Modules\Auth\Models\UserModel;
|
||||||
|
|
||||||
class Auth extends ShieldAuth
|
class Auth extends ShieldAuth
|
||||||
|
@ -119,7 +120,7 @@ class Auth extends ShieldAuth
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$adminGateway = config('Admin')
|
$adminGateway = config(Admin::class)
|
||||||
->gateway;
|
->gateway;
|
||||||
|
|
||||||
$this->redirects = [
|
$this->redirects = [
|
||||||
|
|
|
@ -4,14 +4,19 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Modules\Auth\Config;
|
namespace Modules\Auth\Config;
|
||||||
|
|
||||||
$routes = service('routes');
|
use CodeIgniter\Router\RouteCollection;
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var RouteCollection $routes
|
||||||
|
*/
|
||||||
|
|
||||||
service('auth')
|
service('auth')
|
||||||
->routes($routes);
|
->routes($routes);
|
||||||
|
|
||||||
// Admin routes for users and podcast contributors
|
// Admin routes for users and podcast contributors
|
||||||
$routes->group(
|
$routes->group(
|
||||||
config('Admin')
|
config(Admin::class)
|
||||||
->gateway,
|
->gateway,
|
||||||
[
|
[
|
||||||
'namespace' => 'Modules\Auth\Controllers',
|
'namespace' => 'Modules\Auth\Controllers',
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace Modules\Auth\Config;
|
||||||
use CodeIgniter\Shield\Authentication\Authentication;
|
use CodeIgniter\Shield\Authentication\Authentication;
|
||||||
use Config\Services as BaseService;
|
use Config\Services as BaseService;
|
||||||
use Modules\Auth\Auth;
|
use Modules\Auth\Auth;
|
||||||
|
use Modules\Auth\Config\Auth as AuthConfig;
|
||||||
|
|
||||||
class Services extends BaseService
|
class Services extends BaseService
|
||||||
{
|
{
|
||||||
|
@ -16,10 +17,11 @@ class Services extends BaseService
|
||||||
public static function auth(bool $getShared = true): Auth
|
public static function auth(bool $getShared = true): Auth
|
||||||
{
|
{
|
||||||
if ($getShared) {
|
if ($getShared) {
|
||||||
|
/** @var Auth */
|
||||||
return self::getSharedInstance('auth');
|
return self::getSharedInstance('auth');
|
||||||
}
|
}
|
||||||
|
|
||||||
$config = config('Auth');
|
$config = config(AuthConfig::class);
|
||||||
|
|
||||||
return new Auth(new Authentication($config));
|
return new Auth(new Authentication($config));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use CodeIgniter\HTTP\RedirectResponse;
|
||||||
use CodeIgniter\HTTP\RequestInterface;
|
use CodeIgniter\HTTP\RequestInterface;
|
||||||
use CodeIgniter\HTTP\ResponseInterface;
|
use CodeIgniter\HTTP\ResponseInterface;
|
||||||
use CodeIgniter\Shield\Controllers\MagicLinkController as ShieldMagicLinkController;
|
use CodeIgniter\Shield\Controllers\MagicLinkController as ShieldMagicLinkController;
|
||||||
|
use Modules\Auth\Config\Auth;
|
||||||
use Modules\Auth\Models\UserModel;
|
use Modules\Auth\Models\UserModel;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use ViewThemes\Theme;
|
use ViewThemes\Theme;
|
||||||
|
@ -32,7 +33,7 @@ class MagicLinkController extends ShieldMagicLinkController
|
||||||
public function setPasswordView(): string | RedirectResponse
|
public function setPasswordView(): string | RedirectResponse
|
||||||
{
|
{
|
||||||
if (! session('magicLogin')) {
|
if (! session('magicLogin')) {
|
||||||
return redirect()->to(config('Auth')->loginRedirect());
|
return redirect()->to(config(Auth::class)->loginRedirect());
|
||||||
}
|
}
|
||||||
|
|
||||||
return view(setting('Auth.views')['magic-link-set-password']);
|
return view(setting('Auth.views')['magic-link-set-password']);
|
||||||
|
@ -70,7 +71,7 @@ class MagicLinkController extends ShieldMagicLinkController
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success!
|
// Success!
|
||||||
return redirect()->to(config('Auth')->loginRedirect())
|
return redirect()->to(config(Auth::class)->loginRedirect())
|
||||||
->with('message', lang('MyAccount.messages.passwordChangeSuccess'));
|
->with('message', lang('MyAccount.messages.passwordChangeSuccess'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use CodeIgniter\Router\RouteCollection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2021 Ad Aures
|
* @copyright 2021 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
* @link https://castopod.org/
|
* @link https://castopod.org/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$routes = service('routes');
|
/** @var RouteCollection $routes */
|
||||||
|
|
||||||
$routes->addPlaceholder('actorUsername', '[a-zA-Z0-9\_]{1,32}');
|
$routes->addPlaceholder('actorUsername', '[a-zA-Z0-9\_]{1,32}');
|
||||||
$routes->addPlaceholder(
|
$routes->addPlaceholder(
|
||||||
|
@ -35,7 +37,7 @@ $routes->group('', [
|
||||||
// Actor
|
// Actor
|
||||||
$routes->group('@(:actorUsername)', static function ($routes): void {
|
$routes->group('@(:actorUsername)', static function ($routes): void {
|
||||||
// Actor
|
// Actor
|
||||||
$routes->get('/', 'ActorController/$1', [
|
$routes->get('/', 'ActorController::index/$1', [
|
||||||
'as' => 'actor',
|
'as' => 'actor',
|
||||||
]);
|
]);
|
||||||
$routes->post('inbox', 'ActorController::inbox/$1', [
|
$routes->post('inbox', 'ActorController::inbox/$1', [
|
||||||
|
@ -61,10 +63,10 @@ $routes->group('', [
|
||||||
$routes->post('posts/new', 'PostController::attemptCreate/$1', [
|
$routes->post('posts/new', 'PostController::attemptCreate/$1', [
|
||||||
'as' => 'post-attempt-create',
|
'as' => 'post-attempt-create',
|
||||||
]);
|
]);
|
||||||
$routes->get('posts/(:uuid)', 'PostController/$1', [
|
$routes->get('posts/(:uuid)', 'PostController::index/$1', [
|
||||||
'as' => 'post',
|
'as' => 'post',
|
||||||
]);
|
]);
|
||||||
$routes->get('posts/(:uuid)/replies', 'PostController/$1', [
|
$routes->get('posts/(:uuid)/replies', 'PostController::index/$1', [
|
||||||
'as' => 'post-replies',
|
'as' => 'post-replies',
|
||||||
]);
|
]);
|
||||||
$routes->post(
|
$routes->post(
|
||||||
|
|
|
@ -35,7 +35,7 @@ class ActorController extends Controller
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->config = config('Fediverse');
|
$this->config = config(Fediverse::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function _remap(string $method, string ...$params): mixed
|
public function _remap(string $method, string ...$params): mixed
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace Modules\Fediverse\Controllers;
|
||||||
|
|
||||||
use CodeIgniter\Controller;
|
use CodeIgniter\Controller;
|
||||||
use CodeIgniter\HTTP\ResponseInterface;
|
use CodeIgniter\HTTP\ResponseInterface;
|
||||||
|
use Modules\Auth\Config\Auth;
|
||||||
|
|
||||||
class NodeInfo2Controller extends Controller
|
class NodeInfo2Controller extends Controller
|
||||||
{
|
{
|
||||||
|
@ -35,7 +36,7 @@ class NodeInfo2Controller extends Controller
|
||||||
'version' => CP_VERSION,
|
'version' => CP_VERSION,
|
||||||
],
|
],
|
||||||
'protocols' => ['activitypub'],
|
'protocols' => ['activitypub'],
|
||||||
'openRegistrations' => config('Auth')
|
'openRegistrations' => config(Auth::class)
|
||||||
->allowRegistration,
|
->allowRegistration,
|
||||||
'usage' => [
|
'usage' => [
|
||||||
'users' => [
|
'users' => [
|
||||||
|
|
|
@ -45,7 +45,7 @@ class PostController extends Controller
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->config = config('Fediverse');
|
$this->config = config(Fediverse::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function _remap(string $method, string ...$params): mixed
|
public function _remap(string $method, string ...$params): mixed
|
||||||
|
|
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||||
namespace Modules\Fediverse\Entities;
|
namespace Modules\Fediverse\Entities;
|
||||||
|
|
||||||
use CodeIgniter\Entity\Entity;
|
use CodeIgniter\Entity\Entity;
|
||||||
|
use Modules\Fediverse\Config\Fediverse;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +112,7 @@ class Actor extends Entity
|
||||||
public function getAvatarImageUrl(): string
|
public function getAvatarImageUrl(): string
|
||||||
{
|
{
|
||||||
if ($this->attributes['avatar_image_url'] === null) {
|
if ($this->attributes['avatar_image_url'] === null) {
|
||||||
return base_url(config('Fediverse')->defaultAvatarImagePath);
|
return base_url(config(Fediverse::class)->defaultAvatarImagePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->attributes['avatar_image_url'];
|
return $this->attributes['avatar_image_url'];
|
||||||
|
@ -120,7 +121,7 @@ class Actor extends Entity
|
||||||
public function getAvatarImageMimetype(): string
|
public function getAvatarImageMimetype(): string
|
||||||
{
|
{
|
||||||
if ($this->attributes['avatar_image_mimetype'] === null) {
|
if ($this->attributes['avatar_image_mimetype'] === null) {
|
||||||
return config('Fediverse')->defaultAvatarImageMimetype;
|
return config(Fediverse::class)->defaultAvatarImageMimetype;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->attributes['avatar_image_mimetype'];
|
return $this->attributes['avatar_image_mimetype'];
|
||||||
|
@ -129,7 +130,7 @@ class Actor extends Entity
|
||||||
public function getCoverImageUrl(): string
|
public function getCoverImageUrl(): string
|
||||||
{
|
{
|
||||||
if ($this->attributes['cover_image_url'] === null) {
|
if ($this->attributes['cover_image_url'] === null) {
|
||||||
return base_url(config('Fediverse')->defaultCoverImagePath);
|
return base_url(config(Fediverse::class)->defaultCoverImagePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->attributes['cover_image_url'];
|
return $this->attributes['cover_image_url'];
|
||||||
|
@ -138,7 +139,7 @@ class Actor extends Entity
|
||||||
public function getCoverImageMimetype(): string
|
public function getCoverImageMimetype(): string
|
||||||
{
|
{
|
||||||
if ($this->attributes['cover_image_mimetype'] === null) {
|
if ($this->attributes['cover_image_mimetype'] === null) {
|
||||||
return config('Fediverse')->defaultCoverImageMimetype;
|
return config(Fediverse::class)->defaultCoverImageMimetype;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->attributes['cover_image_mimetype'];
|
return $this->attributes['cover_image_mimetype'];
|
||||||
|
|
|
@ -14,6 +14,7 @@ use CodeIgniter\Database\BaseResult;
|
||||||
use CodeIgniter\I18n\Time;
|
use CodeIgniter\I18n\Time;
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
use Michalsn\Uuid\UuidModel;
|
use Michalsn\Uuid\UuidModel;
|
||||||
|
use Modules\Fediverse\Config\Fediverse;
|
||||||
use Modules\Fediverse\Entities\Activity;
|
use Modules\Fediverse\Entities\Activity;
|
||||||
|
|
||||||
class ActivityModel extends UuidModel
|
class ActivityModel extends UuidModel
|
||||||
|
@ -77,7 +78,7 @@ class ActivityModel extends UuidModel
|
||||||
public function getActivityById(string $activityId): ?Activity
|
public function getActivityById(string $activityId): ?Activity
|
||||||
{
|
{
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix . "activity#{$activityId}";
|
->cachePrefix . "activity#{$activityId}";
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$found = $this->find($activityId);
|
$found = $this->find($activityId);
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace Modules\Fediverse\Models;
|
||||||
|
|
||||||
use CodeIgniter\Events\Events;
|
use CodeIgniter\Events\Events;
|
||||||
use CodeIgniter\Model;
|
use CodeIgniter\Model;
|
||||||
|
use Modules\Fediverse\Config\Fediverse;
|
||||||
use Modules\Fediverse\Entities\Actor;
|
use Modules\Fediverse\Entities\Actor;
|
||||||
|
|
||||||
class ActorModel extends Model
|
class ActorModel extends Model
|
||||||
|
@ -98,7 +99,7 @@ class ActorModel extends Model
|
||||||
{
|
{
|
||||||
$hashedActorUri = md5($actorUri);
|
$hashedActorUri = md5($actorUri);
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix . "actor-{$hashedActorUri}";
|
->cachePrefix . "actor-{$hashedActorUri}";
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$found = $this->where('uri', $actorUri)
|
$found = $this->where('uri', $actorUri)
|
||||||
|
@ -117,7 +118,7 @@ class ActorModel extends Model
|
||||||
public function getFollowers(int $actorId): array
|
public function getFollowers(int $actorId): array
|
||||||
{
|
{
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix . "actor#{$actorId}_followers";
|
->cachePrefix . "actor#{$actorId}_followers";
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$found = $this->join('fediverse_follows', 'fediverse_follows.actor_id = id', 'inner')
|
$found = $this->join('fediverse_follows', 'fediverse_follows.actor_id = id', 'inner')
|
||||||
|
@ -150,7 +151,7 @@ class ActorModel extends Model
|
||||||
*/
|
*/
|
||||||
public function getBlockedActors(): array
|
public function getBlockedActors(): array
|
||||||
{
|
{
|
||||||
$cacheName = config('Fediverse')
|
$cacheName = config(Fediverse::class)
|
||||||
->cachePrefix . 'blocked_actors';
|
->cachePrefix . 'blocked_actors';
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$found = $this->where('is_blocked', 1)
|
$found = $this->where('is_blocked', 1)
|
||||||
|
@ -165,7 +166,7 @@ class ActorModel extends Model
|
||||||
|
|
||||||
public function blockActor(int $actorId): void
|
public function blockActor(int $actorId): void
|
||||||
{
|
{
|
||||||
$prefix = config('Fediverse')
|
$prefix = config(Fediverse::class)
|
||||||
->cachePrefix;
|
->cachePrefix;
|
||||||
cache()
|
cache()
|
||||||
->delete($prefix . 'blocked_actors');
|
->delete($prefix . 'blocked_actors');
|
||||||
|
@ -181,7 +182,7 @@ class ActorModel extends Model
|
||||||
|
|
||||||
public function unblockActor(int $actorId): void
|
public function unblockActor(int $actorId): void
|
||||||
{
|
{
|
||||||
$prefix = config('Fediverse')
|
$prefix = config(Fediverse::class)
|
||||||
->cachePrefix;
|
->cachePrefix;
|
||||||
cache()
|
cache()
|
||||||
->delete($prefix . 'blocked_actors');
|
->delete($prefix . 'blocked_actors');
|
||||||
|
@ -199,7 +200,7 @@ class ActorModel extends Model
|
||||||
{
|
{
|
||||||
helper('fediverse');
|
helper('fediverse');
|
||||||
|
|
||||||
$cacheName = config('Fediverse')
|
$cacheName = config(Fediverse::class)
|
||||||
->cachePrefix . 'blocked_actors';
|
->cachePrefix . 'blocked_actors';
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$result = $this->select('COUNT(*) as total_local_actors')
|
$result = $this->select('COUNT(*) as total_local_actors')
|
||||||
|
@ -220,10 +221,10 @@ class ActorModel extends Model
|
||||||
{
|
{
|
||||||
helper('fediverse');
|
helper('fediverse');
|
||||||
|
|
||||||
$cacheName = config('Fediverse')
|
$cacheName = config(Fediverse::class)
|
||||||
->cachePrefix . 'blocked_actors';
|
->cachePrefix . 'blocked_actors';
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$tablePrefix = config('Database')
|
$tablePrefix = config(Database::class)
|
||||||
->default['DBPrefix'];
|
->default['DBPrefix'];
|
||||||
$result = $this->select('COUNT(DISTINCT `cp_fediverse_actors`.`id`) as `total_active_actors`', false)
|
$result = $this->select('COUNT(DISTINCT `cp_fediverse_actors`.`id`) as `total_active_actors`', false)
|
||||||
->join(
|
->join(
|
||||||
|
@ -297,7 +298,7 @@ class ActorModel extends Model
|
||||||
|
|
||||||
public function clearCache(Actor $actor): void
|
public function clearCache(Actor $actor): void
|
||||||
{
|
{
|
||||||
$cachePrefix = config('Fediverse')
|
$cachePrefix = config(Fediverse::class)
|
||||||
->cachePrefix;
|
->cachePrefix;
|
||||||
$hashedActorUri = md5($actor->uri);
|
$hashedActorUri = md5($actor->uri);
|
||||||
$cacheDomain = str_replace(':', '', $actor->domain);
|
$cacheDomain = str_replace(':', '', $actor->domain);
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace Modules\Fediverse\Models;
|
||||||
use CodeIgniter\Database\BaseResult;
|
use CodeIgniter\Database\BaseResult;
|
||||||
use CodeIgniter\Events\Events;
|
use CodeIgniter\Events\Events;
|
||||||
use CodeIgniter\Model;
|
use CodeIgniter\Model;
|
||||||
|
use Modules\Fediverse\Config\Fediverse;
|
||||||
use Modules\Fediverse\Entities\BlockedDomain;
|
use Modules\Fediverse\Entities\BlockedDomain;
|
||||||
|
|
||||||
class BlockedDomainModel extends Model
|
class BlockedDomainModel extends Model
|
||||||
|
@ -56,7 +57,7 @@ class BlockedDomainModel extends Model
|
||||||
*/
|
*/
|
||||||
public function getBlockedDomains(): array
|
public function getBlockedDomains(): array
|
||||||
{
|
{
|
||||||
$cacheName = config('Fediverse')
|
$cacheName = config(Fediverse::class)
|
||||||
->cachePrefix . 'blocked_domains';
|
->cachePrefix . 'blocked_domains';
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$found = $this->findAll();
|
$found = $this->findAll();
|
||||||
|
@ -72,7 +73,7 @@ class BlockedDomainModel extends Model
|
||||||
{
|
{
|
||||||
$hashedDomainName = md5($name);
|
$hashedDomainName = md5($name);
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix .
|
->cachePrefix .
|
||||||
"domain#{$hashedDomainName}_isBlocked";
|
"domain#{$hashedDomainName}_isBlocked";
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
|
@ -88,7 +89,7 @@ class BlockedDomainModel extends Model
|
||||||
public function blockDomain(string $name): int | bool
|
public function blockDomain(string $name): int | bool
|
||||||
{
|
{
|
||||||
$hashedDomain = md5($name);
|
$hashedDomain = md5($name);
|
||||||
$prefix = config('Fediverse')
|
$prefix = config(Fediverse::class)
|
||||||
->cachePrefix;
|
->cachePrefix;
|
||||||
cache()
|
cache()
|
||||||
->delete($prefix . "domain#{$hashedDomain}_isBlocked");
|
->delete($prefix . "domain#{$hashedDomain}_isBlocked");
|
||||||
|
@ -120,7 +121,7 @@ class BlockedDomainModel extends Model
|
||||||
public function unblockDomain(string $name): BaseResult | bool
|
public function unblockDomain(string $name): BaseResult | bool
|
||||||
{
|
{
|
||||||
$hashedDomain = md5($name);
|
$hashedDomain = md5($name);
|
||||||
$prefix = config('Fediverse')
|
$prefix = config(Fediverse::class)
|
||||||
->cachePrefix;
|
->cachePrefix;
|
||||||
cache()
|
cache()
|
||||||
->delete($prefix . "domain#{$hashedDomain}_isBlocked");
|
->delete($prefix . "domain#{$hashedDomain}_isBlocked");
|
||||||
|
|
|
@ -20,6 +20,7 @@ use Modules\Fediverse\Activities\AnnounceActivity;
|
||||||
use Modules\Fediverse\Activities\CreateActivity;
|
use Modules\Fediverse\Activities\CreateActivity;
|
||||||
use Modules\Fediverse\Activities\DeleteActivity;
|
use Modules\Fediverse\Activities\DeleteActivity;
|
||||||
use Modules\Fediverse\Activities\UndoActivity;
|
use Modules\Fediverse\Activities\UndoActivity;
|
||||||
|
use Modules\Fediverse\Config\Fediverse;
|
||||||
use Modules\Fediverse\Entities\Actor;
|
use Modules\Fediverse\Entities\Actor;
|
||||||
use Modules\Fediverse\Entities\Post;
|
use Modules\Fediverse\Entities\Post;
|
||||||
use Modules\Fediverse\Objects\TombstoneObject;
|
use Modules\Fediverse\Objects\TombstoneObject;
|
||||||
|
@ -97,7 +98,7 @@ class PostModel extends UuidModel
|
||||||
{
|
{
|
||||||
$hashedPostUri = md5($postUri);
|
$hashedPostUri = md5($postUri);
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix . "post-{$hashedPostUri}";
|
->cachePrefix . "post-{$hashedPostUri}";
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$found = $this->where('uri', $postUri)
|
$found = $this->where('uri', $postUri)
|
||||||
|
@ -118,7 +119,7 @@ class PostModel extends UuidModel
|
||||||
public function getActorPublishedPosts(int $actorId): array
|
public function getActorPublishedPosts(int $actorId): array
|
||||||
{
|
{
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix .
|
->cachePrefix .
|
||||||
"actor#{$actorId}_published_posts";
|
"actor#{$actorId}_published_posts";
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
|
@ -167,7 +168,7 @@ class PostModel extends UuidModel
|
||||||
public function getPostReplies(string $postId, bool $withBlocked = false): array
|
public function getPostReplies(string $postId, bool $withBlocked = false): array
|
||||||
{
|
{
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix .
|
->cachePrefix .
|
||||||
"post#{$postId}_replies" .
|
"post#{$postId}_replies" .
|
||||||
($withBlocked ? '_withBlocked' : '');
|
($withBlocked ? '_withBlocked' : '');
|
||||||
|
@ -199,7 +200,7 @@ class PostModel extends UuidModel
|
||||||
public function getPostReblogs(string $postId): array
|
public function getPostReblogs(string $postId): array
|
||||||
{
|
{
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix . "post#{$postId}_reblogs";
|
->cachePrefix . "post#{$postId}_reblogs";
|
||||||
|
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
|
@ -276,7 +277,7 @@ class PostModel extends UuidModel
|
||||||
$post->uri = url_to('post', esc($post->actor->username), $newPostId);
|
$post->uri = url_to('post', esc($post->actor->username), $newPostId);
|
||||||
|
|
||||||
$createActivity = new CreateActivity();
|
$createActivity = new CreateActivity();
|
||||||
$noteObjectClass = config('Fediverse')
|
$noteObjectClass = config(Fediverse::class)
|
||||||
->noteObject;
|
->noteObject;
|
||||||
$createActivity
|
$createActivity
|
||||||
->set('actor', $post->actor->uri)
|
->set('actor', $post->actor->uri)
|
||||||
|
@ -591,7 +592,7 @@ class PostModel extends UuidModel
|
||||||
{
|
{
|
||||||
helper('fediverse');
|
helper('fediverse');
|
||||||
|
|
||||||
$cacheName = config('Fediverse')
|
$cacheName = config(Fediverse::class)
|
||||||
->cachePrefix . 'blocked_actors';
|
->cachePrefix . 'blocked_actors';
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$result = $this->select('COUNT(*) as total_local_posts')
|
$result = $this->select('COUNT(*) as total_local_posts')
|
||||||
|
@ -660,7 +661,7 @@ class PostModel extends UuidModel
|
||||||
|
|
||||||
public function clearCache(Post $post): void
|
public function clearCache(Post $post): void
|
||||||
{
|
{
|
||||||
$cachePrefix = config('Fediverse')
|
$cachePrefix = config(Fediverse::class)
|
||||||
->cachePrefix;
|
->cachePrefix;
|
||||||
|
|
||||||
$hashedPostUri = md5($post->uri);
|
$hashedPostUri = md5($post->uri);
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace Modules\Fediverse\Models;
|
||||||
|
|
||||||
use CodeIgniter\Database\BaseResult;
|
use CodeIgniter\Database\BaseResult;
|
||||||
use CodeIgniter\Model;
|
use CodeIgniter\Model;
|
||||||
|
use Modules\Fediverse\Config\Fediverse;
|
||||||
use Modules\Fediverse\Entities\PreviewCard;
|
use Modules\Fediverse\Entities\PreviewCard;
|
||||||
|
|
||||||
class PreviewCardModel extends Model
|
class PreviewCardModel extends Model
|
||||||
|
@ -57,7 +58,7 @@ class PreviewCardModel extends Model
|
||||||
{
|
{
|
||||||
$hashedPreviewCardUrl = md5($url);
|
$hashedPreviewCardUrl = md5($url);
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix .
|
->cachePrefix .
|
||||||
"preview_card-{$hashedPreviewCardUrl}";
|
"preview_card-{$hashedPreviewCardUrl}";
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
|
@ -73,7 +74,7 @@ class PreviewCardModel extends Model
|
||||||
public function getPostPreviewCard(string $postId): ?PreviewCard
|
public function getPostPreviewCard(string $postId): ?PreviewCard
|
||||||
{
|
{
|
||||||
$cacheName =
|
$cacheName =
|
||||||
config('Fediverse')
|
config(Fediverse::class)
|
||||||
->cachePrefix . "post#{$postId}_preview_card";
|
->cachePrefix . "post#{$postId}_preview_card";
|
||||||
if (! ($found = cache($cacheName))) {
|
if (! ($found = cache($cacheName))) {
|
||||||
$found = $this->join(
|
$found = $this->join(
|
||||||
|
@ -95,7 +96,7 @@ class PreviewCardModel extends Model
|
||||||
{
|
{
|
||||||
$hashedPreviewCardUrl = md5($url);
|
$hashedPreviewCardUrl = md5($url);
|
||||||
cache()
|
cache()
|
||||||
->delete(config('Fediverse') ->cachePrefix . "preview_card-{$hashedPreviewCardUrl}");
|
->delete(config(Fediverse::class) ->cachePrefix . "preview_card-{$hashedPreviewCardUrl}");
|
||||||
|
|
||||||
return $this->delete($id);
|
return $this->delete($id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,13 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Modules\Install\Config;
|
namespace Modules\Install\Config;
|
||||||
|
|
||||||
$routes = service('routes');
|
use CodeIgniter\Router\RouteCollection;
|
||||||
|
|
||||||
|
/** @var RouteCollection $routes */
|
||||||
|
|
||||||
// Install Wizard routes
|
// Install Wizard routes
|
||||||
$routes->group(
|
$routes->group(
|
||||||
config('Install')
|
config(Install::class)
|
||||||
->gateway,
|
->gateway,
|
||||||
[
|
[
|
||||||
'namespace' => 'Modules\Install\Controllers',
|
'namespace' => 'Modules\Install\Controllers',
|
||||||
|
|
|
@ -17,11 +17,13 @@ use CodeIgniter\HTTP\RedirectResponse;
|
||||||
use CodeIgniter\HTTP\RequestInterface;
|
use CodeIgniter\HTTP\RequestInterface;
|
||||||
use CodeIgniter\HTTP\ResponseInterface;
|
use CodeIgniter\HTTP\ResponseInterface;
|
||||||
use CodeIgniter\Shield\Entities\User;
|
use CodeIgniter\Shield\Entities\User;
|
||||||
|
use Config\App;
|
||||||
use Config\Database;
|
use Config\Database;
|
||||||
use Config\Services;
|
use Config\Services;
|
||||||
use Dotenv\Dotenv;
|
use Dotenv\Dotenv;
|
||||||
use Dotenv\Exception\ValidationException;
|
use Dotenv\Exception\ValidationException;
|
||||||
use Modules\Auth\Models\UserModel;
|
use Modules\Auth\Models\UserModel;
|
||||||
|
use Modules\Install\Config\Install;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use ViewThemes\Theme;
|
use ViewThemes\Theme;
|
||||||
|
@ -158,7 +160,9 @@ class InstallController extends Controller
|
||||||
|
|
||||||
if (! $this->validate($rules)) {
|
if (! $this->validate($rules)) {
|
||||||
return redirect()
|
return redirect()
|
||||||
->to((host_url() === null ? config('App') ->baseURL : host_url()) . config('Install')->gateway)
|
->to(
|
||||||
|
(host_url() === null ? config(App::class) ->baseURL : host_url()) . config(Install::class)->gateway
|
||||||
|
)
|
||||||
->withInput()
|
->withInput()
|
||||||
->with('errors', $this->validator->getErrors());
|
->with('errors', $this->validator->getErrors());
|
||||||
}
|
}
|
||||||
|
@ -176,7 +180,7 @@ class InstallController extends Controller
|
||||||
helper('text');
|
helper('text');
|
||||||
|
|
||||||
// redirect to full install url with new baseUrl input
|
// redirect to full install url with new baseUrl input
|
||||||
return redirect()->to(reduce_double_slashes($baseUrl . '/' . config('Install')->gateway));
|
return redirect()->to(reduce_double_slashes($baseUrl . '/' . config(Install::class)->gateway));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function databaseConfig(): string
|
public function databaseConfig(): string
|
||||||
|
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use CodeIgniter\Router\RouteCollection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright 2023 Ad Aures
|
* @copyright 2023 Ad Aures
|
||||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
||||||
* @link https://castopod.org/
|
* @link https://castopod.org/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$routes = service('routes');
|
/** @var RouteCollection $routes */
|
||||||
|
|
||||||
$routes->get('static/(:any)', 'MediaController::serve/$1', [
|
$routes->get('static/(:any)', 'MediaController::serve/$1', [
|
||||||
'as' => 'media-serve',
|
'as' => 'media-serve',
|
||||||
|
|
|
@ -27,8 +27,7 @@ class Services extends BaseService
|
||||||
return self::getSharedInstance('file_manager');
|
return self::getSharedInstance('file_manager');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var MediaConfig $config * */
|
$config = config(MediaConfig::class);
|
||||||
$config = config('Media');
|
|
||||||
$fileManagerClass = $config->fileManagers[$config->fileManager];
|
$fileManagerClass = $config->fileManagers[$config->fileManager];
|
||||||
|
|
||||||
$fileManager = new $fileManagerClass($config);
|
$fileManager = new $fileManagerClass($config);
|
||||||
|
|
|
@ -59,9 +59,9 @@ class BaseMedia extends Entity
|
||||||
/**
|
/**
|
||||||
* @param array<string, mixed> $data
|
* @param array<string, mixed> $data
|
||||||
*/
|
*/
|
||||||
public function setAttributes(array $data): self
|
public function injectRawData(array $data): static
|
||||||
{
|
{
|
||||||
parent::setAttributes($data);
|
parent::injectRawData($data);
|
||||||
|
|
||||||
$this->initFileProperties();
|
$this->initFileProperties();
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,9 @@ class Image extends BaseMedia
|
||||||
/**
|
/**
|
||||||
* @param array<string, string> $data
|
* @param array<string, string> $data
|
||||||
*/
|
*/
|
||||||
public function setAttributes(array $data): self
|
public function injectRawData(array $data): static
|
||||||
{
|
{
|
||||||
parent::setAttributes($data);
|
parent::injectRawData($data);
|
||||||
|
|
||||||
if ($this->attributes === []) {
|
if ($this->attributes === []) {
|
||||||
return $this;
|
return $this;
|
||||||
|
|
|
@ -150,6 +150,6 @@ class FS implements FileManagerInterface
|
||||||
|
|
||||||
$uri = trim($uri, '/');
|
$uri = trim($uri, '/');
|
||||||
|
|
||||||
return config('Media')->storage . '/' . config('Media')->root . '/' . $uri;
|
return config(MediaConfig::class)->storage . '/' . config(MediaConfig::class)->root . '/' . $uri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use CodeIgniter\CLI\BaseCommand;
|
||||||
use CodeIgniter\Files\File;
|
use CodeIgniter\Files\File;
|
||||||
use CodeIgniter\I18n\Time;
|
use CodeIgniter\I18n\Time;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Modules\Admin\Config\Admin;
|
||||||
use Modules\MediaClipper\VideoClipper;
|
use Modules\MediaClipper\VideoClipper;
|
||||||
|
|
||||||
class Generate extends BaseCommand
|
class Generate extends BaseCommand
|
||||||
|
@ -24,7 +25,7 @@ class Generate extends BaseCommand
|
||||||
// get number of running clips to prevent from having too much running in parallel
|
// get number of running clips to prevent from having too much running in parallel
|
||||||
// TODO: get the number of running ffmpeg processes directly from the machine?
|
// TODO: get the number of running ffmpeg processes directly from the machine?
|
||||||
$runningVideoClips = (new ClipModel())->getRunningVideoClipsCount();
|
$runningVideoClips = (new ClipModel())->getRunningVideoClipsCount();
|
||||||
if ($runningVideoClips >= config('Admin')->videoClipWorkers) {
|
if ($runningVideoClips >= config(Admin::class)->videoClipWorkers) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ use Exception;
|
||||||
use GdImage;
|
use GdImage;
|
||||||
use Modules\Media\Entities\Transcript;
|
use Modules\Media\Entities\Transcript;
|
||||||
use Modules\Media\FileManagers\FileManagerInterface;
|
use Modules\Media\FileManagers\FileManagerInterface;
|
||||||
|
use Modules\MediaClipper\Config\MediaClipper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: refactor this by splitting process modules into different classes (image generation, subtitles clip, video
|
* TODO: refactor this by splitting process modules into different classes (image generation, subtitles clip, video
|
||||||
|
@ -80,9 +81,9 @@ class VideoClipper
|
||||||
) {
|
) {
|
||||||
$this->duration = $end - $start;
|
$this->duration = $end - $start;
|
||||||
$this->episodeNumbering = $this->episodeNumbering($this->episode->number, $this->episode->season_number);
|
$this->episodeNumbering = $this->episodeNumbering($this->episode->number, $this->episode->season_number);
|
||||||
$this->dimensions = config('MediaClipper')
|
$this->dimensions = config(MediaClipper::class)
|
||||||
->formats[$format];
|
->formats[$format];
|
||||||
$this->colors = config('MediaClipper')
|
$this->colors = config(MediaClipper::class)
|
||||||
->themes[$theme];
|
->themes[$theme];
|
||||||
|
|
||||||
/** @var FileManagerInterface $fileManager */
|
/** @var FileManagerInterface $fileManager */
|
||||||
|
@ -238,7 +239,7 @@ class VideoClipper
|
||||||
) . ":text='%{pts\:gmtime\:{$this->start}\:%H\\\\\\\\\\:%M\\\\\\\\\\:%S\}':x={$this->dimensions['timestamp']['x']}:y={$this->dimensions['timestamp']['y']}:fontsize={$this->dimensions['timestamp']['fontsize']}:fontcolor=0x{$this->colors['timestampText']}:box=1:boxcolor=0x{$this->colors['timestampBg']}:boxborderw={$this->dimensions['timestamp']['padding']}[v3]",
|
) . ":text='%{pts\:gmtime\:{$this->start}\:%H\\\\\\\\\\:%M\\\\\\\\\\:%S\}':x={$this->dimensions['timestamp']['x']}:y={$this->dimensions['timestamp']['y']}:fontsize={$this->dimensions['timestamp']['fontsize']}:fontcolor=0x{$this->colors['timestampText']}:box=1:boxcolor=0x{$this->colors['timestampBg']}:boxborderw={$this->dimensions['timestamp']['padding']}[v3]",
|
||||||
"color=c=0x{$this->colors['progressbar']}:s={$this->dimensions['width']}x{$this->dimensions['progressbar']['height']}[progressbar]",
|
"color=c=0x{$this->colors['progressbar']}:s={$this->dimensions['width']}x{$this->dimensions['progressbar']['height']}[progressbar]",
|
||||||
"[v3][progressbar]overlay=-w+(w/{$this->duration})*t:0:shortest=1:format=rgb,subtitles={$this->subtitlesClipOutput}:fontsdir=" . config(
|
"[v3][progressbar]overlay=-w+(w/{$this->duration})*t:0:shortest=1:format=rgb,subtitles={$this->subtitlesClipOutput}:fontsdir=" . config(
|
||||||
'MediaClipper'
|
MediaClipper::class
|
||||||
)->fontsFolder . ":force_style='Fontname=" . self::FONTS['subtitles'] . ",Alignment=5,Fontsize={$this->dimensions['subtitles']['fontsize']},PrimaryColour=&H{$this->colors['subtitles']}&,BorderStyle=1,Outline=0,Shadow=0,MarginL={$this->dimensions['subtitles']['marginL']},MarginR={$this->dimensions['subtitles']['marginR']},MarginV={$this->dimensions['subtitles']['marginV']}'[outv]",
|
)->fontsFolder . ":force_style='Fontname=" . self::FONTS['subtitles'] . ",Alignment=5,Fontsize={$this->dimensions['subtitles']['fontsize']},PrimaryColour=&H{$this->colors['subtitles']}&,BorderStyle=1,Outline=0,Shadow=0,MarginL={$this->dimensions['subtitles']['marginL']},MarginR={$this->dimensions['subtitles']['marginR']},MarginV={$this->dimensions['subtitles']['marginV']}'[outv]",
|
||||||
"[6:v]scale={$this->dimensions['watermark']['width']}:{$this->dimensions['watermark']['height']}[watermark]",
|
"[6:v]scale={$this->dimensions['watermark']['width']}:{$this->dimensions['watermark']['height']}[watermark]",
|
||||||
"color=0x{$this->colors['watermarkBg']}:{$this->dimensions['watermark']['width']}x{$this->dimensions['watermark']['height']}[over]",
|
"color=0x{$this->colors['watermarkBg']}:{$this->dimensions['watermark']['width']}x{$this->dimensions['watermark']['height']}[over]",
|
||||||
|
@ -247,7 +248,7 @@ class VideoClipper
|
||||||
'[watermarked]scale=w=-1:h=-1:out_color_matrix=bt709[outfinal]',
|
'[watermarked]scale=w=-1:h=-1:out_color_matrix=bt709[outfinal]',
|
||||||
];
|
];
|
||||||
|
|
||||||
$watermark = config('MediaClipper')
|
$watermark = config(MediaClipper::class)
|
||||||
->watermark;
|
->watermark;
|
||||||
|
|
||||||
$videoClipCmd = [
|
$videoClipCmd = [
|
||||||
|
@ -402,7 +403,7 @@ class VideoClipper
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add quotes for subtitles
|
// Add quotes for subtitles
|
||||||
$quotes = imagecreatefrompng(config('MediaClipper')->quotesImage);
|
$quotes = imagecreatefrompng(config(MediaClipper::class)->quotesImage);
|
||||||
|
|
||||||
if (! $quotes) {
|
if (! $quotes) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -480,7 +481,7 @@ class VideoClipper
|
||||||
|
|
||||||
private function getFont(string $name): string
|
private function getFont(string $name): string
|
||||||
{
|
{
|
||||||
return config('MediaClipper')->fontsFolder . self::FONTS[$name];
|
return config(MediaClipper::class)->fontsFolder . self::FONTS[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateBackground(int $width, int $height): ?GdImage
|
private function generateBackground(int $width, int $height): ?GdImage
|
||||||
|
|
|
@ -21,6 +21,7 @@ use CodeIgniter\Shield\Entities\User;
|
||||||
use Config\Services;
|
use Config\Services;
|
||||||
use Exception;
|
use Exception;
|
||||||
use League\HTMLToMarkdown\HtmlConverter;
|
use League\HTMLToMarkdown\HtmlConverter;
|
||||||
|
use Modules\Auth\Config\AuthGroups;
|
||||||
use Modules\Auth\Models\UserModel;
|
use Modules\Auth\Models\UserModel;
|
||||||
use Modules\PodcastImport\Entities\PodcastImportTask;
|
use Modules\PodcastImport\Entities\PodcastImportTask;
|
||||||
use Modules\PodcastImport\Entities\TaskStatus;
|
use Modules\PodcastImport\Entities\TaskStatus;
|
||||||
|
@ -256,7 +257,7 @@ class PodcastImport extends BaseCommand
|
||||||
|
|
||||||
// set current user as podcast admin
|
// set current user as podcast admin
|
||||||
// 1. create new group
|
// 1. create new group
|
||||||
config('AuthGroups')
|
config(AuthGroups::class)
|
||||||
->generatePodcastAuthorizations($podcast->id);
|
->generatePodcastAuthorizations($podcast->id);
|
||||||
add_podcast_group($this->user, $podcast->id, 'admin');
|
add_podcast_group($this->user, $podcast->id, 'admin');
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue