fix(cache): add locale for podcast and episode pages + clear some persisting cache in models

fixes #42, #61
This commit is contained in:
Yassine Doghri 2020-10-20 10:31:40 +00:00
parent a354940e5e
commit 9cec8a81cc
6 changed files with 209 additions and 106 deletions

View File

@ -44,11 +44,10 @@ class Episode extends BaseController
{
self::triggerWebpageHit($this->episode->podcast_id);
if (
!($cachedView = cache(
"page_podcast{$this->episode->podcast_id}_episode{$this->episode->id}"
))
) {
$locale = service('request')->getLocale();
$cacheName = "page_podcast{$this->episode->podcast_id}_episode{$this->episode->id}_{$locale}";
if (!($cachedView = cache($cacheName))) {
$previousNextEpisodes = (new EpisodeModel())->getPreviousNextEpisodes(
$this->episode,
$this->podcast->type
@ -64,7 +63,7 @@ class Episode extends BaseController
// The page cache is set to a decade so it is deleted manually upon podcast update
return view('episode', $data, [
'cache' => DECADE,
'cache_name' => "page_podcast{$this->episode->podcast_id}_episode{$this->episode->id}",
'cache_name' => $cacheName,
]);
}

View File

@ -58,15 +58,13 @@ class Podcast extends BaseController
"podcast{$this->podcast->id}",
$yearQuery,
$seasonQuery ? 'season' . $seasonQuery : null,
service('request')->getLocale(),
])
);
if (!($found = cache($cacheName))) {
// The page cache is set to a decade so it is deleted manually upon podcast update
// $this->cachePage(DECADE);
$episodeModel = new EpisodeModel();
// Build navigation array
$episodeModel = new EpisodeModel();
$years = $episodeModel->getYears($this->podcast->id);
$seasons = $episodeModel->getSeasons($this->podcast->id);

View File

@ -76,54 +76,6 @@ class EpisodeModel extends Model
return $data;
}
protected function clearCache(array $data)
{
$episodeModel = new EpisodeModel();
$episode = $episodeModel->find(
is_array($data['id']) ? $data['id'][0] : $data['id']
);
// delete cache for rss feed, podcast and episode pages
cache()->delete(md5($episode->podcast->feed_url));
cache()->delete(md5($episode->podcast->link));
cache()->delete(md5($episode->link));
// delete model requests cache
cache()->delete("podcast{$episode->podcast_id}_episodes");
// delete episode lists cache per year / season
$years = $episodeModel->getYears($episode->podcast_id);
$seasons = $episodeModel->getSeasons($episode->podcast_id);
foreach ($years as $year) {
cache()->delete(
"podcast{$episode->podcast_id}_{$year['year']}_episodes"
);
cache()->delete(
"page_podcast{$episode->podcast_id}_{$year['year']}"
);
}
foreach ($seasons as $season) {
cache()->delete(
"podcast{$episode->podcast_id}_season{$season['season_number']}_episodes"
);
cache()->delete(
"page_podcast{$episode->podcast_id}_season{$season['season_number']}"
);
}
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}_episode@{$episode->slug}"
);
return $data;
}
public function getEpisodeBySlug($podcastId, $episodeSlug)
{
if (!($found = cache("podcast{$podcastId}_episode@{$episodeSlug}"))) {
@ -142,6 +94,47 @@ class EpisodeModel extends Model
return $found;
}
/**
* Returns the previous episode based on episode ordering
*/
public function getPreviousNextEpisodes($episode, $podcastType)
{
$sortNumberField =
$podcastType == 'serial'
? 'if(isnull(season_number),0,season_number)*1000+number'
: 'if(isnull(season_number),0,season_number)*100000000000000+published_at';
$sortNumberValue =
$podcastType == 'serial'
? (empty($episode->season_number)
? 0
: $episode->season_number) *
1000 +
$episode->number
: (empty($episode->season_number)
? ''
: $episode->season_number) .
date('YmdHis', strtotime($episode->published_at));
$previousData = $this->orderBy('(' . $sortNumberField . ') DESC')
->where([
'podcast_id' => $episode->podcast_id,
$sortNumberField . ' <' => $sortNumberValue,
])
->first();
$nextData = $this->orderBy('(' . $sortNumberField . ') ASC')
->where([
'podcast_id' => $episode->podcast_id,
$sortNumberField . ' >' => $sortNumberValue,
])
->first();
return [
'previous' => $previousData,
'next' => $nextData,
];
}
/**
* Gets all episodes for a podcast ordered according to podcast type
* Filtered depending on year or season
@ -239,6 +232,10 @@ class EpisodeModel extends Model
/**
* Returns the default query for displaying the episode list on the podcast page
*
* @param int $podcastId
*
* @return array
*/
public function getDefaultQuery(int $podcastId)
{
@ -267,44 +264,62 @@ class EpisodeModel extends Model
return $defaultQuery;
}
/**
* Returns the previous episode based on episode ordering
*/
public function getPreviousNextEpisodes($episode, $podcastType)
protected function clearCache(array $data)
{
$sortNumberField =
$podcastType == 'serial'
? 'if(isnull(season_number),0,season_number)*1000+number'
: 'if(isnull(season_number),0,season_number)*100000000000000+published_at';
$sortNumberValue =
$podcastType == 'serial'
? (empty($episode->season_number)
? 0
: $episode->season_number) *
1000 +
$episode->number
: (empty($episode->season_number)
? ''
: $episode->season_number) .
date('YmdHis', strtotime($episode->published_at));
$episodeModel = new EpisodeModel();
$episode = (new EpisodeModel())->find(
is_array($data['id']) ? $data['id'][0] : $data['id']
);
$previousData = $this->orderBy('(' . $sortNumberField . ') DESC')
->where([
'podcast_id' => $episode->podcast_id,
$sortNumberField . ' <' => $sortNumberValue,
])
->first();
// delete cache for rss feed
cache()->delete(md5($episode->podcast->feed_url));
$nextData = $this->orderBy('(' . $sortNumberField . ') ASC')
->where([
'podcast_id' => $episode->podcast_id,
$sortNumberField . ' >' => $sortNumberValue,
])
->first();
// delete model requests cache
cache()->delete("podcast{$episode->podcast_id}_episodes");
return [
'previous' => $previousData,
'next' => $nextData,
];
cache()->delete(
"podcast{$episode->podcast_id}_episode@{$episode->slug}"
);
// delete episode lists cache per year / season for a podcast
// and localized pages
$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}"
);
}
foreach ($years as $year) {
cache()->delete(
"podcast{$episode->podcast_id}_{$year['year']}_episodes"
);
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$episode->podcast_id}_{$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}"
);
}
}
// delete query cache
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

@ -30,7 +30,8 @@ class PageModel extends Model
];
protected $validationMessages = [];
// Before update because slug might change
// Before update because slug or title might change
protected $afterInsert = ['clearCache'];
protected $beforeUpdate = ['clearCache'];
protected $beforeDelete = ['clearCache'];
@ -44,8 +45,38 @@ class PageModel extends Model
cache()->delete(md5($page->link));
// Clear the cache of all podcast and episode pages
// TODO: change the logic of page caching to prevent clearing all cache every time
// cache()->clean();
$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']}_{$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}"
);
}
}
}
return $data;
}

View File

@ -76,8 +76,7 @@ class PlatformModel extends Model
public function savePlatformLinks($podcastId, $platformLinksData)
{
cache()->delete("podcast{$podcastId}_platforms");
cache()->delete("podcast{$podcastId}_platformLinks");
$this->clearCache($podcastId);
// Remove already previously set platforms to overwrite them
$this->db
@ -109,12 +108,39 @@ class PlatformModel extends Model
public function removePlatformLink($podcastId, $platformId)
{
cache()->delete("podcast{$podcastId}_platforms");
cache()->delete("podcast{$podcastId}_platformLinks");
$this->clearCache($podcastId);
return $this->db->table('platform_links')->delete([
'podcast_id' => $podcastId,
'platform_id' => $platformId,
]);
}
public function clearCache($podcastId)
{
cache()->delete("podcast{$podcastId}_platforms");
cache()->delete("podcast{$podcastId}_platformLinks");
// 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']}_{$locale}"
);
}
}
foreach ($seasons as $season) {
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcastId}_season{$season['season_number']}_{$locale}"
);
}
}
}
}

View File

@ -170,20 +170,54 @@ class PodcastModel extends Model
$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(md5($podcast->feed_url));
cache()->delete(md5($podcast->link));
// clear cache for every podcast's episode page?
foreach ($podcast->episodes as $episode) {
cache()->delete(md5($episode->link));
}
// delete model requests cache
cache()->delete("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}"
);
}
}
// 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']}_episodes");
foreach ($supportedLocales as $locale) {
cache()->delete(
"page_podcast{$podcast->id}_{$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");
return $data;
}
}