perf(cache): update CI4 to use cache's deleteMatching method

add missing locale to category_options cache name
This commit is contained in:
Yassine Doghri 2021-04-20 13:43:38 +00:00
parent 05ace8cff2
commit 54b84f9684
No known key found for this signature in database
GPG Key ID: 3E7F89498B960C9F
31 changed files with 486 additions and 560 deletions

View File

@ -13,17 +13,18 @@
"color-highlight.markerType": "dot-before"
},
"extensions": [
"mikestead.dotenv",
"bmewburn.vscode-intelephense-client",
"streetsidesoftware.code-spell-checker",
"naumovs.color-highlight",
"heybourn.headwind",
"wayou.vscode-todo-highlight",
"esbenp.prettier-vscode",
"bradlc.vscode-tailwindcss",
"jamesbirtles.svelte-vscode",
"dbaeumer.vscode-eslint",
"stylelint.vscode-stylelint",
"wongjn.php-sniffer"
]
"mikestead.dotenv",
"bmewburn.vscode-intelephense-client",
"streetsidesoftware.code-spell-checker",
"naumovs.color-highlight",
"heybourn.headwind",
"wayou.vscode-todo-highlight",
"esbenp.prettier-vscode",
"bradlc.vscode-tailwindcss",
"jamesbirtles.svelte-vscode",
"dbaeumer.vscode-eslint",
"stylelint.vscode-stylelint",
"wongjn.php-sniffer",
"eamodio.gitlens"
]
}

View File

@ -50,15 +50,16 @@ Before uploading Castopod files to your web server:
PHP version 7.3 or higher is required, with the following extensions installed:
- [intl](http://php.net/manual/en/intl.requirements.php)
- [libcurl](http://php.net/manual/en/curl.requirements.php)
- [mbstring](http://php.net/manual/en/mbstring.installation.php)
- [intl](https://php.net/manual/en/intl.requirements.php)
- [libcurl](https://php.net/manual/en/curl.requirements.php)
- [mbstring](https://php.net/manual/en/mbstring.installation.php)
- [gd](https://www.php.net/manual/en/image.installation.php)
Additionally, make sure that the following extensions are enabled in your PHP:
- json (enabled by default - don't turn it off)
- xml (enabled by default - don't turn it off)
- [mysqlnd](http://php.net/manual/en/mysqlnd.install.php)
- [mysqlnd](https://php.net/manual/en/mysqlnd.install.php)
### MySQL compatible database

View File

@ -39,14 +39,15 @@ class PermissionModel extends \Myth\Auth\Authorization\PermissionModel
*/
public function getPermissionsForGroup(int $groupId): array
{
if (!($found = cache("group{$groupId}_permissions"))) {
$cacheName = "group{$groupId}_permissions";
if (!($found = cache($cacheName))) {
$groupPermissions = $this->db
->table('auth_groups_permissions')
->select('id, auth_permissions.name')
->join(
'auth_permissions',
'auth_permissions.id = permission_id',
'inner'
'inner',
)
->where('group_id', $groupId)
->get()
@ -57,7 +58,7 @@ class PermissionModel extends \Myth\Auth\Authorization\PermissionModel
$found[$row->id] = strtolower($row->name);
}
cache()->save("group{$groupId}_permissions", $found, 300);
cache()->save($cacheName, $found, 300);
}
return $found;

View File

@ -253,6 +253,8 @@ class App extends BaseConfig
* Set a cookie name prefix if you need to avoid collisions.
*
* @var string
*
* @deprecated use Config\Cookie::$prefix property instead.
*/
public $cookiePrefix = '';
@ -264,6 +266,8 @@ class App extends BaseConfig
* Set to `.your-domain.com` for site-wide cookies.
*
* @var string
*
* @deprecated use Config\Cookie::$domain property instead.
*/
public $cookieDomain = '';
@ -275,6 +279,8 @@ class App extends BaseConfig
* Typically will be a forward slash.
*
* @var string
*
* @deprecated use Config\Cookie::$path property instead.
*/
public $cookiePath = '/';
@ -286,19 +292,23 @@ class App extends BaseConfig
* Cookie will only be set if a secure HTTPS connection exists.
*
* @var boolean
*
* @deprecated use Config\Cookie::$secure property instead.
*/
public $cookieSecure = false;
/**
* --------------------------------------------------------------------------
* Cookie HTTP Only
* Cookie HttpOnly
* --------------------------------------------------------------------------
*
* Cookie will only be accessible via HTTP(S) (no JavaScript).
*
* @var boolean
*
* @deprecated use Config\Cookie::$httponly property instead.
*/
public $cookieHTTPOnly = false;
public $cookieHTTPOnly = true;
/**
* --------------------------------------------------------------------------
@ -311,11 +321,18 @@ class App extends BaseConfig
* - Strict
* - ''
*
* Defaults to `Lax` for compatibility with modern browsers. Setting `''`
* (empty string) means no SameSite attribute will be set on cookies. If
* set to `None`, `$cookieSecure` must also be set.
* Alternatively, you can use the constant names:
* - `Cookie::SAMESITE_NONE`
* - `Cookie::SAMESITE_LAX`
* - `Cookie::SAMESITE_STRICT`
*
* @var string 'Lax'|'None'|'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.
*
* @var string
*
* @deprecated use Config\Cookie::$samesite property instead.
*/
public $cookieSameSite = 'Lax';

119
app/Config/Cookie.php Normal file
View File

@ -0,0 +1,119 @@
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
use DateTimeInterface;
class Cookie extends BaseConfig
{
/**
* --------------------------------------------------------------------------
* Cookie Prefix
* --------------------------------------------------------------------------
*
* Set a cookie name prefix if you need to avoid collisions.
*
* @var string
*/
public $prefix = '';
/**
* --------------------------------------------------------------------------
* Cookie Expires Timestamp
* --------------------------------------------------------------------------
*
* Default expires timestamp for cookies. Setting this to `0` will mean the
* cookie will not have the `Expires` attribute and will behave as a session
* cookie.
*
* @var DateTimeInterface|integer|string
*/
public $expires = 0;
/**
* --------------------------------------------------------------------------
* Cookie Path
* --------------------------------------------------------------------------
*
* Typically will be a forward slash.
*
* @var string
*/
public $path = '/';
/**
* --------------------------------------------------------------------------
* Cookie Domain
* --------------------------------------------------------------------------
*
* Set to `.your-domain.com` for site-wide cookies.
*
* @var string
*/
public $domain = '';
/**
* --------------------------------------------------------------------------
* Cookie Secure
* --------------------------------------------------------------------------
*
* Cookie will only be set if a secure HTTPS connection exists.
*
* @var boolean
*/
public $secure = false;
/**
* --------------------------------------------------------------------------
* Cookie HTTPOnly
* --------------------------------------------------------------------------
*
* Cookie will only be accessible via HTTP(S) (no JavaScript).
*
* @var boolean
*/
public $httponly = 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`, `$secure` must also be set.
*
* @var string
*/
public $samesite = 'Lax';
/**
* --------------------------------------------------------------------------
* Cookie Raw
* --------------------------------------------------------------------------
*
* This flag allows setting a "raw" cookie, i.e., its name and value are
* not URL encoded using `rawurlencode()`.
*
* If this is set to `true`, cookie names should be compliant of RFC 2616's
* list of allowed characters.
*
* @var boolean
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes
* @see https://tools.ietf.org/html/rfc2616#section-2.2
*/
public $raw = false;
}

View File

@ -651,7 +651,7 @@ $routes->group('@(:podcastName)', function ($routes) {
// Other pages
$routes->get('/credits', 'Page::credits', ['as' => 'credits']);
$routes->get('/(:slug)', 'Page/$1', ['as' => 'page']);
$routes->get('/pages/(:slug)', 'Page/$1', ['as' => 'page']);
// interacting as an actor
$routes->post('interact-as-actor', 'Auth::attemptInteractAsActor', [

View File

@ -30,7 +30,7 @@ class EpisodePerson extends BaseController
if (count($params) > 1) {
if (
!($this->podcast = (new PodcastModel())->getPodcastById(
$params[0]
$params[0],
))
) {
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
@ -61,9 +61,9 @@ class EpisodePerson extends BaseController
$data = [
'episode' => $this->episode,
'podcast' => $this->podcast,
'episodePersons' => (new EpisodePersonModel())->getPersonsByEpisodeId(
'episodePersons' => (new EpisodePersonModel())->getEpisodePersons(
$this->podcast->id,
$this->episode->id
$this->episode->id,
),
'personOptions' => (new PersonModel())->getPersonOptions(),
'taxonomyOptions' => (new PersonModel())->getTaxonomyOptions(),
@ -92,7 +92,7 @@ class EpisodePerson extends BaseController
$this->podcast->id,
$this->episode->id,
$this->request->getPost('person'),
$this->request->getPost('person_group_role')
$this->request->getPost('person_group_role'),
);
return redirect()->back();
@ -103,7 +103,7 @@ class EpisodePerson extends BaseController
(new EpisodePersonModel())->removeEpisodePersons(
$this->podcast->id,
$this->episode->id,
$episodePersonId
$episodePersonId,
);
return redirect()->back();

View File

@ -24,7 +24,7 @@ class PodcastPerson extends BaseController
if (count($params) > 0) {
if (
!($this->podcast = (new PodcastModel())->getPodcastById(
$params[0]
$params[0],
))
) {
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
@ -43,8 +43,8 @@ class PodcastPerson extends BaseController
$data = [
'podcast' => $this->podcast,
'podcastPersons' => (new PodcastPersonModel())->getPersonsByPodcastId(
$this->podcast->id
'podcastPersons' => (new PodcastPersonModel())->getPodcastPersons(
$this->podcast->id,
),
'personOptions' => (new PersonModel())->getPersonOptions(),
'taxonomyOptions' => (new PersonModel())->getTaxonomyOptions(),
@ -71,7 +71,7 @@ class PodcastPerson extends BaseController
(new PodcastPersonModel())->addPodcastPersons(
$this->podcast->id,
$this->request->getPost('person'),
$this->request->getPost('person_group_role')
$this->request->getPost('person_group_role'),
);
return redirect()->back();
@ -81,7 +81,7 @@ class PodcastPerson extends BaseController
{
(new PodcastPersonModel())->removePodcastPersons(
$this->podcast->id,
$podcastPersonId
$podcastPersonId,
);
return redirect()->back();

View File

@ -47,7 +47,7 @@ class Episode extends BaseController
self::triggerWebpageHit($this->podcast->id);
$locale = service('request')->getLocale();
$cacheName = "page_podcast{$this->episode->podcast_id}_episode{$this->episode->id}_{$locale}";
$cacheName = "page_podcast#{$this->podcast->id}_episode{$this->episode->id}_{$locale}";
if (!($cachedView = cache($cacheName))) {
helper('persons');
@ -107,7 +107,7 @@ class Episode extends BaseController
$locale = service('request')->getLocale();
$cacheName = "page_podcast{$this->episode->podcast_id}_episode{$this->episode->id}_embeddable_player_{$theme}_{$locale}";
$cacheName = "page_podcast#{$this->podcast->id}_episode{$this->episode->id}_embeddable_player_{$theme}_{$locale}";
if (!($cachedView = cache($cacheName))) {
$theme = EpisodeModel::$themes[$theme];

View File

@ -26,7 +26,7 @@ class Feed extends Controller
$serviceSlug = '';
try {
$service = \Opawg\UserAgentsPhp\UserAgentsRSS::find(
$_SERVER['HTTP_USER_AGENT']
$_SERVER['HTTP_USER_AGENT'],
);
if ($service) {
$serviceSlug = $service['slug'];
@ -37,14 +37,14 @@ class Feed extends Controller
}
$cacheName =
"podcast{$podcast->id}_feed" . ($service ? "_{$serviceSlug}" : '');
"podcast#{$podcast->id}_feed" . ($service ? "_{$serviceSlug}" : '');
if (!($found = cache($cacheName))) {
$found = get_rss_feed($podcast, $serviceSlug);
// The page cache is set to expire after next episode publication or a decade by default so it is deleted manually upon podcast update
$secondsToNextUnpublishedEpisode = (new EpisodeModel())->getSecondsToNextUnpublishedEpisode(
$podcast->id
$podcast->id,
);
cache()->save(
@ -52,7 +52,7 @@ class Feed extends Controller
$found,
$secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE
: DECADE,
);
}
return $this->response->setXML($found);

View File

@ -36,37 +36,42 @@ class Page extends BaseController
public function index()
{
// The page cache is set to a decade so it is deleted manually upon page update
$this->cachePage(DECADE);
$cacheName = "page@{$this->page->slug}";
if (!($found = cache($cacheName))) {
$data = [
'page' => $this->page,
];
$data = [
'page' => $this->page,
];
return view('page', $data);
$found = view('page', $data);
// The page cache is set to a decade so it is deleted manually upon page update
cache()->save($cacheName, $found, DECADE);
}
return $found;
}
public function credits()
{
$locale = service('request')->getLocale();
$model = new PodcastModel();
$allPodcasts = $model->findAll();
$allPodcasts = (new PodcastModel())->findAll();
if (!($found = cache("credits_{$locale}"))) {
$cacheName = "paĝe_credits_{$locale}";
if (!($found = cache($cacheName))) {
$page = new \App\Entities\Page([
'title' => lang('Person.credits', [], $locale),
'slug' => 'credits',
'content' => '',
]);
$creditModel = (new CreditModel())->findAll();
$allCredits = (new CreditModel())->findAll();
// Unlike the carpenter, we make a tree from a table:
$person_group = null;
$person_id = null;
$person_role = null;
$credits = [];
foreach ($creditModel as $credit) {
foreach ($allCredits as $credit) {
if ($person_group !== $credit->person_group) {
$person_group = $credit->person_group;
$person_id = $credit->person_id;
@ -200,7 +205,7 @@ class Page extends BaseController
$found = view('credits', $data);
cache()->save("credits_{$locale}", $found, DECADE);
cache()->save($cacheName, $found, DECADE);
}
return $found;

View File

@ -68,7 +68,7 @@ class Podcast extends BaseController
$seasonQuery = $this->request->getGet('season');
if (!$yearQuery and !$seasonQuery) {
$defaultQuery = (new EpisodeModel())->getDefaultQuery(
$defaultQuery = (new PodcastModel())->getDefaultQuery(
$this->podcast->id,
);
if ($defaultQuery) {
@ -84,18 +84,19 @@ class Podcast extends BaseController
'_',
array_filter([
'page',
"podcast{$this->podcast->id}",
"podcast#{$this->podcast->id}",
$yearQuery ? 'year' . $yearQuery : null,
$seasonQuery ? 'season' . $seasonQuery : null,
service('request')->getLocale(),
can_user_interact() ? '_interact' : '',
]),
);
if (!($found = cache($cacheName))) {
// Build navigation array
$episodeModel = new EpisodeModel();
$years = $episodeModel->getYears($this->podcast->id);
$seasons = $episodeModel->getSeasons($this->podcast->id);
$podcastModel = new PodcastModel();
$years = $podcastModel->getYears($this->podcast->id);
$seasons = $podcastModel->getSeasons($this->podcast->id);
$episodesNavigation = [];
$activeQuery = null;
@ -155,7 +156,7 @@ class Podcast extends BaseController
'podcast' => $this->podcast,
'episodesNav' => $episodesNavigation,
'activeQuery' => $activeQuery,
'episodes' => $episodeModel->getPodcastEpisodes(
'episodes' => (new EpisodeModel())->getPodcastEpisodes(
$this->podcast->id,
$this->podcast->type,
$yearQuery,
@ -164,20 +165,20 @@ class Podcast extends BaseController
'persons' => $persons,
];
$secondsToNextUnpublishedEpisode = $episodeModel->getSecondsToNextUnpublishedEpisode(
$secondsToNextUnpublishedEpisode = (new EpisodeModel())->getSecondsToNextUnpublishedEpisode(
$this->podcast->id,
);
// if user is logged in then send to the authenticated episodes view
if (can_user_interact()) {
return view('podcast/episodes_authenticated', $data, [
$found = view('podcast/episodes_authenticated', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache_name' => $cacheName . '_authenticated',
'cache_name' => $cacheName,
]);
} else {
return view('podcast/episodes', $data, [
$found = view('podcast/episodes', $data, [
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,

View File

@ -385,7 +385,7 @@ class Episode extends Entity
}
if (empty($this->persons)) {
$this->persons = (new EpisodePersonModel())->getPersonsByEpisodeId(
$this->persons = (new EpisodePersonModel())->getEpisodePersons(
$this->podcast_id,
$this->id,
);

View File

@ -232,7 +232,7 @@ class Podcast extends Entity
}
if (empty($this->persons)) {
$this->persons = (new PodcastPersonModel())->getPersonsByPodcastId(
$this->persons = (new PodcastPersonModel())->getPodcastPersons(
$this->id,
);
}

View File

@ -39,7 +39,7 @@ return [
'cacheHandlerOptions' => [
'file' => 'File',
'redis' => 'Redis',
'memcached' => 'Memcached',
'predis' => 'Predis',
],
'next' => 'Next',
'submit' => 'Finish install',

View File

@ -7,8 +7,6 @@
*/
return [
'not_in_protected_slugs' =>
'The {field} field conflicts with one of the gateway routes (admin, auth or install).',
'min_dims' =>
'{field} is either not an image, or it is not wide or tall enough.',
'is_image_squared' =>

View File

@ -39,7 +39,7 @@ return [
'cacheHandlerOptions' => [
'file' => 'Fichiers',
'redis' => 'Redis',
'memcached' => 'Memcached',
'predis' => 'Predis',
],
'next' => 'Suivant',
'submit' => 'Terminer linstallation',

View File

@ -7,8 +7,6 @@
*/
return [
'not_in_protected_slugs' =>
'Le champ {field} est en conflit avec une des routes (admin, auth ou install).',
'min_dims' =>
'{field} nest pas une image ou na pas la taille minimale requise.',
'is_image_squared' =>

View File

@ -34,21 +34,24 @@ class CategoryModel extends Model
public function getCategoryOptions()
{
if (!($options = cache('category_options'))) {
$locale = service('request')->getLocale();
$cacheName = "category_options_{$locale}";
if (!($options = cache($cacheName))) {
$categories = $this->findAll();
$options = array_reduce(
$categories,
function ($result, $category) {
$result[$category->id] = lang(
'Podcast.category_options.' . $category->code
'Podcast.category_options.' . $category->code,
);
return $result;
},
[]
[],
);
cache()->save('category_options', $options, DECADE);
cache()->save($cacheName, $options, DECADE);
}
return $options;
@ -64,7 +67,7 @@ class CategoryModel extends Model
*/
public function setPodcastCategories($podcastId, $categories)
{
cache()->delete("podcasts{$podcastId}_categories");
cache()->delete("podcast#{$podcastId}_categories");
// Remove already previously set categories to overwrite them
$this->db
@ -83,7 +86,7 @@ class CategoryModel extends Model
return $result;
},
[]
[],
);
// Set podcast categories
@ -103,20 +106,17 @@ class CategoryModel extends Model
*/
public function getPodcastCategories($podcastId)
{
if (!($categories = cache("podcasts{$podcastId}_categories"))) {
$cacheName = "podcast#{$podcastId}_categories";
if (!($categories = cache($cacheName))) {
$categories = $this->select('categories.*')
->join(
'podcasts_categories',
'podcasts_categories.category_id = categories.id'
'podcasts_categories.category_id = categories.id',
)
->where('podcasts_categories.podcast_id', $podcastId)
->findAll();
cache()->save(
"podcasts{$podcastId}_categories",
$categories,
DECADE
);
cache()->save($cacheName, $categories, DECADE);
}
return $categories;

View File

@ -113,7 +113,8 @@ class EpisodeModel extends Model
*/
public function getEpisodeBySlug($podcastId, $episodeSlug)
{
if (!($found = cache("podcast@{$podcastId}_episode@{$episodeSlug}"))) {
$cacheName = "podcast#{$podcastId}_episode@{$episodeSlug}";
if (!($found = cache($cacheName))) {
$builder = $this->select('episodes.*')
->where('slug', $episodeSlug)
->where('`published_at` <= NOW()', null, false);
@ -130,11 +131,7 @@ class EpisodeModel extends Model
$found = $builder->first();
cache()->save(
"podcast{$podcastId}_episode@{$episodeSlug}",
$found,
DECADE,
);
cache()->save($cacheName, $found, DECADE);
}
return $found;
@ -142,14 +139,15 @@ class EpisodeModel extends Model
public function getEpisodeById($episodeId)
{
if (!($found = cache("podcast_episode{$episodeId}"))) {
$cacheName = "podcast_episode#{$episodeId}";
if (!($found = cache($cacheName))) {
$builder = $this->where([
'id' => $episodeId,
]);
$found = $builder->first();
cache()->save("podcast_episode{$episodeId}", $found, DECADE);
cache()->save($cacheName, $found, DECADE);
}
return $found;
@ -157,7 +155,8 @@ class EpisodeModel extends Model
public function getPublishedEpisodeById($episodeId, $podcastId = null)
{
if (!($found = cache("podcast{$podcastId}_episode{$episodeId}"))) {
$cacheName = "podcast_episode#{$episodeId}_published";
if (!($found = cache($cacheName))) {
$builder = $this->where([
'id' => $episodeId,
])->where('`published_at` <= NOW()', null, false);
@ -168,11 +167,7 @@ class EpisodeModel extends Model
$found = $builder->first();
cache()->save(
"podcast{$podcastId}_episode{$episodeId}",
$found,
DECADE,
);
cache()->save($cacheName, $found, DECADE);
}
return $found;
@ -195,7 +190,7 @@ class EpisodeModel extends Model
$cacheName = implode(
'_',
array_filter([
"podcast{$podcastId}",
"podcast#{$podcastId}",
$year,
$season ? 'season' . $season : null,
'episodes',
@ -243,106 +238,6 @@ class EpisodeModel extends Model
return $found;
}
public function getYears(int $podcastId): array
{
if (!($found = cache("podcast{$podcastId}_years"))) {
$found = $this->select(
'YEAR(published_at) as year, count(*) as number_of_episodes',
)
->where([
'podcast_id' => $podcastId,
'season_number' => null,
$this->deletedField => null,
])
->where('`published_at` <= NOW()', null, false)
->groupBy('year')
->orderBy('year', 'DESC')
->get()
->getResultArray();
$secondsToNextUnpublishedEpisode = $this->getSecondsToNextUnpublishedEpisode(
$podcastId,
);
cache()->save(
"podcast{$podcastId}_years",
$found,
$secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
);
}
return $found;
}
public function getSeasons(int $podcastId): array
{
if (!($found = cache("podcast{$podcastId}_seasons"))) {
$found = $this->select(
'season_number, count(*) as number_of_episodes',
)
->where([
'podcast_id' => $podcastId,
'season_number is not' => null,
$this->deletedField => null,
])
->where('`published_at` <= NOW()', null, false)
->groupBy('season_number')
->orderBy('season_number', 'ASC')
->get()
->getResultArray();
$secondsToNextUnpublishedEpisode = $this->getSecondsToNextUnpublishedEpisode(
$podcastId,
);
cache()->save(
"podcast{$podcastId}_seasons",
$found,
$secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
);
}
return $found;
}
/**
* Returns the default query for displaying the episode list on the podcast page
*
* @param int $podcastId
*
* @return array|null
*/
public function getDefaultQuery(int $podcastId)
{
if (!($defaultQuery = cache("podcast{$podcastId}_defaultQuery"))) {
$seasons = $this->getSeasons($podcastId);
if (!empty($seasons)) {
// get latest season
$defaultQuery = ['type' => 'season', 'data' => end($seasons)];
} else {
$years = $this->getYears($podcastId);
if (!empty($years)) {
// get most recent year
$defaultQuery = ['type' => 'year', 'data' => $years[0]];
} else {
$defaultQuery = null;
}
}
cache()->save(
"podcast{$podcastId}_defaultQuery",
$defaultQuery,
DECADE,
);
}
return $defaultQuery;
}
/**
* Returns the timestamp difference in seconds between the next episode to publish and the current timestamp
* Returns false if there's no episode to publish
@ -387,70 +282,37 @@ class EpisodeModel extends Model
);
// delete cache for rss feed
cache()->delete("podcast{$episode->podcast_id}_feed");
foreach (\Opawg\UserAgentsPhp\UserAgentsRSS::$db as $service) {
cache()->delete(
"podcast{$episode->podcast_id}_feed_{$service['slug']}",
);
}
cache()->deleteMatching("podcast#{$episode->podcast_id}_feed*");
// delete model requests cache
cache()->delete("podcast{$episode->podcast_id}_episodes");
cache()->delete("podcast#{$episode->podcast_id}_episodes");
cache()->deleteMatching("podcast_episode#{$episode->id}*");
cache()->delete(
"podcast{$episode->podcast_id}_episode@{$episode->slug}",
"podcast#{$episode->podcast_id}_episode@{$episode->slug}",
);
cache()->delete("podcast_episode{$episode->id}");
cache()->deleteMatching(
"page_podcast#{$episode->podcast_id}_episode#{$episode->id}_*",
);
cache()->deleteMatching('page_credits_*');
// delete episode lists cache per year / season for a podcast
// and localized pages
$episodeModel = new EpisodeModel();
$years = $episodeModel->getYears($episode->podcast_id);
$seasons = $episodeModel->getSeasons($episode->podcast_id);
$supportedLocales = config('App')->supportedLocales;
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$episode->podcast->id}_episode{$episode->id}_{$locale}",
if ($episode->season_number) {
cache()->deleteMatching("podcast#{$episode->podcast_id}_season*");
cache()->deleteMatching(
"page_podcast#{$episode->podcast_id}_season*",
);
cache()->delete("credits_{$locale}");
}
foreach ($years as $year) {
cache()->delete(
"podcast{$episode->podcast_id}_year{$year['year']}_episodes",
} else {
cache()->deleteMatching("podcast#{$episode->podcast_id}_year*");
cache()->deleteMatching(
"page_podcast#{$episode->podcast_id}_year*",
);
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$episode->podcast_id}_year{$year['year']}_{$locale}",
);
}
}
foreach ($seasons as $season) {
cache()->delete(
"podcast{$episode->podcast_id}_season{$season['season_number']}_episodes",
);
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$episode->podcast_id}_season{$season['season_number']}_{$locale}",
);
}
}
foreach (array_keys(self::$themes) as $themeKey) {
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$episode->podcast_id}_episode{$episode->id}_embeddable_player_{$themeKey}_{$locale}",
);
}
}
// delete query cache
cache()->delete("podcast{$episode->podcast_id}_defaultQuery");
cache()->delete("podcast{$episode->podcast_id}_years");
cache()->delete("podcast{$episode->podcast_id}_seasons");
cache()->delete("podcast#{$episode->podcast_id}_defaultQuery");
cache()->delete("podcast#{$episode->podcast_id}_years");
cache()->delete("podcast#{$episode->podcast_id}_seasons");
return $data;
}

View File

@ -38,27 +38,17 @@ class EpisodePersonModel extends Model
protected $afterInsert = ['clearCache'];
protected $beforeDelete = ['clearCache'];
public function getPersonsByEpisodeId($podcastId, $episodeId)
public function getEpisodePersons($episodeId)
{
if (
!($found = cache(
"podcast{$podcastId}_episodes{$episodeId}_persons"
))
) {
$cacheName = "podcast_episode#{$episodeId}_persons";
if (!($found = cache($cacheName))) {
$found = $this->select('episodes_persons.*')
->where('episode_id', $episodeId)
->join(
'persons',
'person_id=persons.id'
)
->join('persons', 'person_id=persons.id')
->orderby('full_name')
->findAll();
cache()->save(
"podcast{$podcastId}_episodes{$episodeId}_persons",
$found,
DECADE
);
cache()->save($cacheName, $found, DECADE);
}
return $found;
}
@ -81,11 +71,9 @@ class EpisodePersonModel extends Model
) {
if (!empty($persons)) {
$this->clearCache([
'id' => [
'podcast_id' => $podcastId,
'episode_id' => $episodeId,
],
'episode_id' => $episodeId,
]);
$data = [];
foreach ($persons as $person) {
if ($groups_roles) {
@ -126,23 +114,17 @@ class EpisodePersonModel extends Model
protected function clearCache(array $data)
{
$podcastId = null;
$episodeId = null;
if (
isset($data['id']['podcast_id']) &&
isset($data['id']['episode_id'])
) {
$podcastId = $data['id']['podcast_id'];
$episodeId = $data['id']['episode_id'];
if (isset($data['episode_id'])) {
$episodeId = $data['episode_id'];
} else {
$episodePerson = (new EpisodePersonModel())->find(
is_array($data['id']) ? $data['id']['id'] : $data['id']
$person = (new EpisodePersonModel())->find(
is_array($data['id']) ? $data['id']['id'] : $data['id'],
);
$podcastId = $episodePerson->podcast_id;
$episodeId = $episodePerson->episode_id;
$episodeId = $person->episode_id;
}
cache()->delete("podcast{$podcastId}_episodes{$episodeId}_persons");
cache()->delete("podcast_episode#{$episodeId}_persons");
(new EpisodeModel())->clearCache(['id' => $episodeId]);
return $data;

View File

@ -25,7 +25,7 @@ class PageModel extends Model
protected $validationRules = [
'title' => 'required',
'slug' =>
'required|regex_match[/^[a-zA-Z0-9\-]{1,191}$/]|is_unique[pages.slug,id,{id}]|not_in_protected_slugs',
'required|regex_match[/^[a-zA-Z0-9\-]{1,191}$/]|is_unique[pages.slug,id,{id}]',
'content' => 'required',
];
protected $validationMessages = [];
@ -37,46 +37,8 @@ class PageModel extends Model
protected function clearCache(array $data)
{
$page = (new PageModel())->find(
is_array($data['id']) ? $data['id'][0] : $data['id'],
);
// delete page cache
cache()->delete(md5($page->link));
// Clear the cache of all podcast and episode pages
$allPodcasts = (new PodcastModel())->findAll();
foreach ($allPodcasts as $podcast) {
// delete localized podcast and episode page cache
$episodeModel = new EpisodeModel();
$years = $episodeModel->getYears($podcast->id);
$seasons = $episodeModel->getSeasons($podcast->id);
$supportedLocales = config('App')->supportedLocales;
foreach ($years as $year) {
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcast->id}_year{$year['year']}_{$locale}",
);
}
}
foreach ($seasons as $season) {
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcast->id}_season{$season['season_number']}_{$locale}",
);
}
}
foreach ($podcast->episodes as $episode) {
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcast->id}_episode{$episode->id}_{$locale}",
);
}
}
}
// Clear the cache of all pages
cache()->deleteMatching('page*');
return $data;
}

View File

@ -48,9 +48,11 @@ class PersonModel extends Model
public function getPersonById($personId)
{
if (!($found = cache("person{$personId}"))) {
$cacheName = "person#{$personId}";
if (!($found = cache($cacheName))) {
$found = $this->find($personId);
cache()->save("person{$personId}", $found, DECADE);
cache()->save($cacheName, $found, DECADE);
}
return $found;
@ -99,7 +101,8 @@ class PersonModel extends Model
{
$options = [];
$locale = service('request')->getLocale();
if (!($options = cache("taxonomy_options_{$locale}"))) {
$cacheName = "taxonomy_options_{$locale}";
if (!($options = cache($cacheName))) {
foreach (lang('PersonsTaxonomy.persons') as $group_key => $group) {
foreach ($group['roles'] as $role_key => $role) {
$options[
@ -108,7 +111,7 @@ class PersonModel extends Model
}
}
cache()->save("taxonomy_options_{$locale}", $options, DECADE);
cache()->save($cacheName, $options, DECADE);
}
return $options;
@ -116,19 +119,15 @@ class PersonModel extends Model
protected function clearCache(array $data)
{
$person = (new PersonModel())->getPersonById(
$person = (new PersonModel())->find(
is_array($data['id']) ? $data['id'][0] : $data['id'],
);
cache()->delete('person_options');
cache()->delete("person{$person->id}");
cache()->delete("user{$person->created_by}_persons");
cache()->delete("person#{$person->id}");
$supportedLocales = config('App')->supportedLocales;
// clear cache for every credit page
foreach ($supportedLocales as $locale) {
cache()->delete("credit_{$locale}");
}
// clear cache for every credits page
cache()->deleteMatching('page_credits_*');
return $data;
}

View File

@ -45,9 +45,10 @@ class PlatformModel extends Model
public function getPlatform($slug)
{
if (!($found = cache("platform_$slug"))) {
$cacheName = "platform@{$slug}";
if (!($found = cache($cacheName))) {
$found = $this->where('slug', $slug)->first();
cache()->save("platform_$slug", $found, DECADE);
cache()->save($cacheName, $found, DECADE);
}
return $found;
}
@ -72,7 +73,9 @@ class PlatformModel extends Model
public function getPlatformsWithLinks($podcastId, $platformType)
{
if (
!($found = cache("podcast{$podcastId}_platforms_{$platformType}"))
!($found = cache(
"podcast#{$podcastId}_platforms_{$platformType}_withLinks",
))
) {
$found = $this->select(
'platforms.*, podcasts_platforms.link_url, podcasts_platforms.link_content, podcasts_platforms.is_visible, podcasts_platforms.is_on_embeddable_player',
@ -86,7 +89,7 @@ class PlatformModel extends Model
->findAll();
cache()->save(
"podcast{$podcastId}_platforms_{$platformType}",
"podcast#{$podcastId}_platforms_{$platformType}_withLinks",
$found,
DECADE,
);
@ -97,11 +100,8 @@ class PlatformModel extends Model
public function getPodcastPlatforms($podcastId, $platformType)
{
if (
!($found = cache(
"podcast{$podcastId}_podcastPlatforms_{$platformType}",
))
) {
$cacheName = "podcast#{$podcastId}_platforms_{$platformType}";
if (!($found = cache($cacheName))) {
$found = $this->select(
'platforms.*, podcasts_platforms.link_url, podcasts_platforms.link_content, podcasts_platforms.is_visible, podcasts_platforms.is_on_embeddable_player',
)
@ -113,11 +113,7 @@ class PlatformModel extends Model
->where('platforms.type', $platformType)
->findAll();
cache()->save(
"podcast{$podcastId}_podcastPlatforms_{$platformType}",
$found,
DECADE,
);
cache()->save($cacheName, $found, DECADE);
}
return $found;
@ -132,12 +128,14 @@ class PlatformModel extends Model
$podcastsPlatformsTable = $this->db->prefixTable('podcasts_platforms');
$platformsTable = $this->db->prefixTable('platforms');
$deleteJoinQuery = <<<EOD
$deleteJoinQuery = <<<SQL
DELETE $podcastsPlatformsTable
FROM $podcastsPlatformsTable
INNER JOIN $platformsTable ON $platformsTable.slug = $podcastsPlatformsTable.platform_slug
WHERE `podcast_id` = ? AND `type` = ?
EOD;
SQL;
$this->db->query($deleteJoinQuery, [$podcastId, $platformType]);
// Set podcastPlatforms
@ -168,51 +166,9 @@ class PlatformModel extends Model
public function clearCache($podcastId)
{
$podcast = (new PodcastModel())->getPodcastById($podcastId);
cache()->deleteMatching("podcast#{$podcastId}_platforms_*");
foreach (['podcasting', 'social', 'funding'] as $platformType) {
cache()->delete("podcast{$podcastId}_platforms_{$platformType}");
cache()->delete(
"podcast{$podcastId}_podcastPlatforms_{$platformType}",
);
}
// delete localized podcast page cache
$episodeModel = new EpisodeModel();
$years = $episodeModel->getYears($podcastId);
$seasons = $episodeModel->getSeasons($podcastId);
$supportedLocales = config('App')->supportedLocales;
foreach ($years as $year) {
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcastId}_year{$year['year']}_{$locale}",
);
}
}
foreach ($seasons as $season) {
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcastId}_season{$season['season_number']}_{$locale}",
);
}
}
// clear cache for every localized podcast episode page
foreach ($podcast->episodes as $episode) {
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcast->id}_episode{$episode->id}_{$locale}",
);
foreach (
array_keys(\App\Models\EpisodeModel::$themes)
as $themeKey
) {
cache()->delete(
"page_podcast{$podcast->id}_episode{$episode->id}_embeddable_player_{$themeKey}_{$locale}",
);
}
}
}
cache()->deleteMatching("page_podcast#{$podcastId}*");
}
}

View File

@ -83,7 +83,8 @@ class PodcastModel extends Model
public function getPodcastByName($podcastName)
{
if (!($found = cache("podcast@{$podcastName}"))) {
$cacheName = "podcast@{$podcastName}";
if (!($found = cache($cacheName))) {
$found = $this->where('name', $podcastName)->first();
cache()->save("podcast@{$podcastName}", $found, DECADE);
}
@ -93,10 +94,11 @@ class PodcastModel extends Model
public function getPodcastById($podcastId)
{
if (!($found = cache("podcast{$podcastId}"))) {
$cacheName = "podcast#{$podcastId}";
if (!($found = cache($cacheName))) {
$found = $this->find($podcastId);
cache()->save("podcast{$podcastId}", $found, DECADE);
cache()->save($cacheName, $found, DECADE);
}
return $found;
@ -111,7 +113,8 @@ class PodcastModel extends Model
*/
public function getUserPodcasts($userId)
{
if (!($found = cache("user{$userId}_podcasts"))) {
$cacheName = "user{$userId}_podcasts";
if (!($found = cache($cacheName))) {
$found = $this->select('podcasts.*')
->join(
'podcasts_users',
@ -120,7 +123,7 @@ class PodcastModel extends Model
->where('podcasts_users.user_id', $userId)
->findAll();
cache()->save("user{$userId}_podcasts", $found, DECADE);
cache()->save($cacheName, $found, DECADE);
}
return $found;
@ -128,7 +131,7 @@ class PodcastModel extends Model
public function addPodcastContributor($userId, $podcastId, $groupId)
{
cache()->delete("podcast{$podcastId}_contributors");
cache()->delete("podcast#{$podcastId}_contributors");
$data = [
'user_id' => (int) $userId,
@ -141,7 +144,7 @@ class PodcastModel extends Model
public function updatePodcastContributor($userId, $podcastId, $groupId)
{
cache()->delete("podcast{$podcastId}_contributors");
cache()->delete("podcast#{$podcastId}_contributors");
return $this->db
->table('podcasts_users')
@ -154,7 +157,7 @@ class PodcastModel extends Model
public function removePodcastContributor($userId, $podcastId)
{
cache()->delete("podcast{$podcastId}_contributors");
cache()->delete("podcast#{$podcastId}_contributors");
return $this->db
->table('podcasts_users')
@ -196,75 +199,122 @@ class PodcastModel extends Model
: false;
}
public function getYears(int $podcastId): array
{
$cacheName = "podcast#{$podcastId}_years";
if (!($found = cache($cacheName))) {
$episodeModel = new EpisodeModel();
$found = $episodeModel
->select(
'YEAR(published_at) as year, count(*) as number_of_episodes',
)
->where([
'podcast_id' => $podcastId,
'season_number' => null,
$episodeModel->deletedField => null,
])
->where('`published_at` <= NOW()', null, false)
->groupBy('year')
->orderBy('year', 'DESC')
->get()
->getResultArray();
$secondsToNextUnpublishedEpisode = $episodeModel->getSecondsToNextUnpublishedEpisode(
$podcastId,
);
cache()->save(
$cacheName,
$found,
$secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
);
}
return $found;
}
public function getSeasons(int $podcastId): array
{
$cacheName = "podcast#{$podcastId}_seasons";
if (!($found = cache($cacheName))) {
$episodeModel = new EpisodeModel();
$found = $episodeModel
->select('season_number, count(*) as number_of_episodes')
->where([
'podcast_id' => $podcastId,
'season_number is not' => null,
$episodeModel->deletedField => null,
])
->where('`published_at` <= NOW()', null, false)
->groupBy('season_number')
->orderBy('season_number', 'ASC')
->get()
->getResultArray();
$secondsToNextUnpublishedEpisode = $episodeModel->getSecondsToNextUnpublishedEpisode(
$podcastId,
);
cache()->save(
$cacheName,
$found,
$secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
);
}
return $found;
}
/**
* Returns the default query for displaying the episode list on the podcast page
*
* @param int $podcastId
*
* @return array|null
*/
public function getDefaultQuery(int $podcastId)
{
$cacheName = "podcast#{$podcastId}_defaultQuery";
if (!($defaultQuery = cache($cacheName))) {
$seasons = $this->getSeasons($podcastId);
if (!empty($seasons)) {
// get latest season
$defaultQuery = ['type' => 'season', 'data' => end($seasons)];
} else {
$years = $this->getYears($podcastId);
if (!empty($years)) {
// get most recent year
$defaultQuery = ['type' => 'year', 'data' => $years[0]];
} else {
$defaultQuery = null;
}
}
cache()->save($cacheName, $defaultQuery, DECADE);
}
return $defaultQuery;
}
public function clearCache(array $data)
{
$podcast = (new PodcastModel())->getPodcastById(
is_array($data['id']) ? $data['id'][0] : $data['id'],
);
$supportedLocales = config('App')->supportedLocales;
// delete cache for rss feed and podcast pages
cache()->delete("podcast{$podcast->id}_feed");
foreach (\Opawg\UserAgentsPhp\UserAgentsRSS::$db as $service) {
cache()->delete("podcast{$podcast->id}_feed_{$service['slug']}");
}
// delete cache all podcast pages
cache()->deleteMatching("page_podcast#{$podcast->id}_*");
// delete model requests cache
cache()->delete("podcast{$podcast->id}");
// delete model requests cache, includes feed / query / episode lists, etc.
cache()->deleteMatching("podcast#{$podcast->id}*");
cache()->delete("podcast@{$podcast->name}");
// clear cache for every localized podcast episode page
foreach ($podcast->episodes as $episode) {
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcast->id}_episode{$episode->id}_{$locale}",
);
foreach (
array_keys(\App\Models\EpisodeModel::$themes)
as $themeKey
) {
cache()->delete(
"page_podcast{$podcast->id}_episode{$episode->id}_embeddable_player_{$themeKey}_{$locale}",
);
}
}
}
// clear cache for every credit page
foreach ($supportedLocales as $locale) {
cache()->delete("credits_{$locale}");
}
// delete episode lists cache per year / season
// and localized pages
$episodeModel = new EpisodeModel();
$years = $episodeModel->getYears($podcast->id);
$seasons = $episodeModel->getSeasons($podcast->id);
foreach ($years as $year) {
cache()->delete(
"podcast{$podcast->id}_year{$year['year']}_episodes",
);
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcast->id}_year{$year['year']}_{$locale}",
);
}
}
foreach ($seasons as $season) {
cache()->delete(
"podcast{$podcast->id}_season{$season['season_number']}_episodes",
);
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcast->id}_season{$season['season_number']}_{$locale}",
);
}
}
// delete query cache
cache()->delete("podcast{$podcast->id}_defaultQuery");
cache()->delete("podcast{$podcast->id}_years");
cache()->delete("podcast{$podcast->id}_seasons");
cache()->deleteMatching('page_credits_*');
return $data;
}

View File

@ -37,20 +37,19 @@ class PodcastPersonModel extends Model
protected $afterInsert = ['clearCache'];
protected $beforeDelete = ['clearCache'];
public function getPersonsByPodcastId($podcastId)
public function getPodcastPersons($podcastId)
{
if (!($found = cache("podcast{$podcastId}_persons"))) {
$cacheName = "podcast#{$podcastId}_persons";
if (!($found = cache($cacheName))) {
$found = $this->select('podcasts_persons.*')
->where('podcast_id', $podcastId)
->join(
'persons',
'person_id=persons.id'
)
->join('persons', 'person_id=persons.id')
->orderby('full_name')
->findAll();
cache()->save("podcast{$podcastId}_persons", $found, DECADE);
cache()->save($cacheName, $found, DECADE);
}
return $found;
}
@ -66,7 +65,7 @@ class PodcastPersonModel extends Model
public function addPodcastPersons($podcastId, $persons, $groups_roles)
{
if (!empty($persons)) {
$this->clearCache(['id' => ['podcast_id' => $podcastId]]);
$this->clearCache(['podcast_id' => $podcastId]);
$data = [];
foreach ($persons as $person) {
if ($groups_roles) {
@ -102,16 +101,16 @@ class PodcastPersonModel extends Model
protected function clearCache(array $data)
{
$podcastId = null;
if (isset($data['id']['podcast_id'])) {
$podcastId = $data['id']['podcast_id'];
if (isset($data['podcast_id'])) {
$podcastId = $data['podcast_id'];
} else {
$person = (new PodcastPersonModel())->find(
is_array($data['id']) ? $data['id']['id'] : $data['id']
is_array($data['id']) ? $data['id']['id'] : $data['id'],
);
$podcastId = $person->podcast_id;
}
cache()->delete("podcast{$podcastId}_persons");
cache()->delete("podcast#{$podcastId}_persons");
(new PodcastModel())->clearCache(['id' => $podcastId]);
return $data;

View File

@ -56,14 +56,15 @@ class SoundbiteModel extends Model
*/
public function getEpisodeSoundbites(int $podcastId, int $episodeId): array
{
if (!($found = cache("episode{$episodeId}_soundbites"))) {
$cacheName = "podcast_episode#{$episodeId}_soundbites";
if (!($found = cache($cacheName))) {
$found = $this->where([
'episode_id' => $episodeId,
'podcast_id' => $podcastId,
])
->orderBy('start_time')
->findAll();
cache()->save("episode{$episodeId}_soundbites", $found, DECADE);
cache()->save($cacheName, $found, DECADE);
}
return $found;
}
@ -73,25 +74,18 @@ class SoundbiteModel extends Model
$episode = (new EpisodeModel())->find(
isset($data['data'])
? $data['data']['episode_id']
: $data['id']['episode_id']
: $data['id']['episode_id'],
);
cache()->delete("episode{$episode->id}_soundbites");
cache()->delete("podcast_episode#{$episode->id}_soundbites");
// delete cache for rss feed
cache()->delete("podcast{$episode->id}_feed");
foreach (\Opawg\UserAgentsPhp\UserAgentsRSS::$db as $service) {
cache()->delete(
"podcast{$episode->podcast->id}_feed_{$service['slug']}"
);
}
cache()->deleteMatching("podcast#{$episode->podcast_id}_feed*");
cache()->deleteMatching(
"page_podcast#{$episode->podcast_id}_episode#{$episode->id}_*",
);
$supportedLocales = config('App')->supportedLocales;
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$episode->podcast->id}_episode{$episode->id}_{$locale}"
);
}
return $data;
}
}

View File

@ -14,7 +14,8 @@ class UserModel extends \Myth\Auth\Models\UserModel
public function getPodcastContributors($podcastId)
{
if (!($found = cache("podcast{$podcastId}_contributors"))) {
$cacheName = "podcast#{$podcastId}_contributors";
if (!($found = cache($cacheName))) {
$found = $this->select('users.*, auth_groups.name as podcast_role')
->join('podcasts_users', 'podcasts_users.user_id = users.id')
->join(
@ -24,7 +25,7 @@ class UserModel extends \Myth\Auth\Models\UserModel
->where('podcasts_users.podcast_id', $podcastId)
->findAll();
cache()->save("podcast{$podcastId}_contributors", $found, DECADE);
cache()->save($cacheName, $found, DECADE);
}
return $found;

View File

@ -10,26 +10,6 @@ namespace App\Validation;
class Rules
{
/**
* Value should not be within the array of protected slugs (adminGateway, authGateway or installGateway)
*
* @param string $value
*
* @return boolean
*/
public function not_in_protected_slugs(string $value = null): bool
{
$appConfig = config('App');
$protectedSlugs = [
$appConfig->adminGateway,
$appConfig->authGateway,
$appConfig->installGateway,
];
return !in_array($value, $protectedSlugs, true);
}
//--------------------------------------------------------------------
/**
* Checks a URL to ensure it's formed correctly.
*

View File

@ -21,7 +21,7 @@
[
'file' => lang('Install.form.cacheHandlerOptions.file'),
'redis' => lang('Install.form.cacheHandlerOptions.redis'),
'memcached' => lang('Install.form.cacheHandlerOptions.memcached'),
'predis' => lang('Install.form.cacheHandlerOptions.predis'),
],
old('cache_handler', 'file'),
[

88
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0d419d654c43fa6e14f8a96b42258a91",
"content-hash": "b5d726bdc7252c80c0fd5a6f53de1948",
"packages": [
{
"name": "brick/math",
@ -68,12 +68,12 @@
"source": {
"type": "git",
"url": "https://github.com/codeigniter4/CodeIgniter4.git",
"reference": "425bca14c840c08b935d730c73da372f3d4bdef8"
"reference": "dfbc85af9ef408a6654cce6a462c8fdde3ee2446"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/codeigniter4/CodeIgniter4/zipball/425bca14c840c08b935d730c73da372f3d4bdef8",
"reference": "425bca14c840c08b935d730c73da372f3d4bdef8",
"url": "https://api.github.com/repos/codeigniter4/CodeIgniter4/zipball/dfbc85af9ef408a6654cce6a462c8fdde3ee2446",
"reference": "dfbc85af9ef408a6654cce6a462c8fdde3ee2446",
"shasum": ""
},
"require": {
@ -83,18 +83,18 @@
"ext-mbstring": "*",
"kint-php/kint": "^3.3",
"laminas/laminas-escaper": "^2.6",
"php": "^7.3||^8.0",
"php": "^7.3 || ^8.0",
"psr/log": "^1.1"
},
"require-dev": {
"codeigniter4/codeigniter4-standard": "^1.0",
"fakerphp/faker": "^1.9",
"johnkary/phpunit-speedtrap": "^3.3",
"mikey179/vfsstream": "^1.6",
"phpstan/phpstan": "0.12.82",
"nexusphp/tachycardia": "^1.0",
"phpstan/phpstan": "0.12.84",
"phpunit/phpunit": "^9.1",
"predis/predis": "^1.1",
"rector/rector": "^0.10",
"rector/rector": "0.10.6",
"squizlabs/php_codesniffer": "^3.3"
},
"suggest": {
@ -139,7 +139,7 @@
"slack": "https://codeigniterchat.slack.com",
"issues": "https://github.com/codeigniter4/CodeIgniter4/issues"
},
"time": "2021-03-25T19:47:47+00:00"
"time": "2021-04-20T08:40:30+00:00"
},
{
"name": "composer/ca-bundle",
@ -823,16 +823,16 @@
},
{
"name": "league/commonmark",
"version": "1.5.7",
"version": "1.5.8",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "11df9b36fd4f1d2b727a73bf14931d81373b9a54"
"reference": "08fa59b8e4e34ea8a773d55139ae9ac0e0aecbaf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/11df9b36fd4f1d2b727a73bf14931d81373b9a54",
"reference": "11df9b36fd4f1d2b727a73bf14931d81373b9a54",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/08fa59b8e4e34ea8a773d55139ae9ac0e0aecbaf",
"reference": "08fa59b8e4e34ea8a773d55139ae9ac0e0aecbaf",
"shasum": ""
},
"require": {
@ -920,7 +920,7 @@
"type": "tidelift"
}
],
"time": "2020-10-31T13:49:32+00:00"
"time": "2021-03-28T18:51:39+00:00"
},
{
"name": "league/html-to-markdown",
@ -1010,23 +1010,23 @@
},
{
"name": "maxmind-db/reader",
"version": "v1.10.0",
"version": "v1.10.1",
"source": {
"type": "git",
"url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
"reference": "07f84d969cfc527ce49388558a366ad376f1f35c"
"reference": "569bd44d97d30a4ec12c7793a33004a76d4caf18"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/07f84d969cfc527ce49388558a366ad376f1f35c",
"reference": "07f84d969cfc527ce49388558a366ad376f1f35c",
"url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/569bd44d97d30a4ec12c7793a33004a76d4caf18",
"reference": "569bd44d97d30a4ec12c7793a33004a76d4caf18",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"conflict": {
"ext-maxminddb": "<1.10.0,>=2.0.0"
"ext-maxminddb": "<1.10.1,>=2.0.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "*",
@ -1069,9 +1069,9 @@
],
"support": {
"issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues",
"source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.10.0"
"source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.10.1"
},
"time": "2021-02-09T17:52:47+00:00"
"time": "2021-04-14T17:49:35+00:00"
},
{
"name": "maxmind/web-service-common",
@ -1125,20 +1125,20 @@
},
{
"name": "michalsn/codeigniter4-uuid",
"version": "v1.0.0-beta2",
"version": "v1.0.0-beta3",
"source": {
"type": "git",
"url": "https://github.com/michalsn/codeigniter4-uuid.git",
"reference": "a5f9751570a3b27e81deaa7548eef507499be888"
"reference": "568aba8f315199b6cc87e76b8441cd03a2bba5b4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/michalsn/codeigniter4-uuid/zipball/a5f9751570a3b27e81deaa7548eef507499be888",
"reference": "a5f9751570a3b27e81deaa7548eef507499be888",
"url": "https://api.github.com/repos/michalsn/codeigniter4-uuid/zipball/568aba8f315199b6cc87e76b8441cd03a2bba5b4",
"reference": "568aba8f315199b6cc87e76b8441cd03a2bba5b4",
"shasum": ""
},
"require": {
"php": ">=7.2",
"php": ">=7.3",
"ramsey/uuid": "^4.0"
},
"require-dev": {
@ -1172,9 +1172,9 @@
],
"support": {
"issues": "https://github.com/michalsn/codeigniter4-uuid/issues",
"source": "https://github.com/michalsn/codeigniter4-uuid/tree/develop"
"source": "https://github.com/michalsn/codeigniter4-uuid/tree/v1.0.0-beta3"
},
"time": "2020-08-16T07:56:20+00:00"
"time": "2021-04-02T11:08:18+00:00"
},
{
"name": "myth/auth",
@ -1182,12 +1182,12 @@
"source": {
"type": "git",
"url": "https://github.com/lonnieezell/myth-auth.git",
"reference": "a11dc6369177c932add936f1be3844c30fe45ed4"
"reference": "eff9805d7f1d27326f14875b53ff4b3d2a6b72ee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/lonnieezell/myth-auth/zipball/a11dc6369177c932add936f1be3844c30fe45ed4",
"reference": "a11dc6369177c932add936f1be3844c30fe45ed4",
"url": "https://api.github.com/repos/lonnieezell/myth-auth/zipball/eff9805d7f1d27326f14875b53ff4b3d2a6b72ee",
"reference": "eff9805d7f1d27326f14875b53ff4b3d2a6b72ee",
"shasum": ""
},
"require": {
@ -1248,7 +1248,7 @@
"type": "patreon"
}
],
"time": "2021-03-23T03:55:24+00:00"
"time": "2021-04-12T22:34:12+00:00"
},
{
"name": "opawg/user-agents-php",
@ -1359,16 +1359,16 @@
},
{
"name": "phpseclib/phpseclib",
"version": "2.0.30",
"version": "2.0.31",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36"
"reference": "233a920cb38636a43b18d428f9a8db1f0a1a08f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/136b9ca7eebef78be14abf90d65c5e57b6bc5d36",
"reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/233a920cb38636a43b18d428f9a8db1f0a1a08f4",
"reference": "233a920cb38636a43b18d428f9a8db1f0a1a08f4",
"shasum": ""
},
"require": {
@ -1448,7 +1448,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/2.0.30"
"source": "https://github.com/phpseclib/phpseclib/tree/2.0.31"
},
"funding": [
{
@ -1464,7 +1464,7 @@
"type": "tidelift"
}
],
"time": "2020-12-17T05:42:04+00:00"
"time": "2021-04-06T13:56:45+00:00"
},
{
"name": "podlibre/ipcat",
@ -2761,16 +2761,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "9.2.5",
"version": "9.2.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1"
"reference": "f6293e1b30a2354e8428e004689671b83871edde"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1",
"reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde",
"reference": "f6293e1b30a2354e8428e004689671b83871edde",
"shasum": ""
},
"require": {
@ -2826,7 +2826,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6"
},
"funding": [
{
@ -2834,7 +2834,7 @@
"type": "github"
}
],
"time": "2020-11-28T06:44:49+00:00"
"time": "2021-03-28T07:26:59+00:00"
},
{
"name": "phpunit/php-file-iterator",