feat(cache): add podcast and episode pages to cache + clear them after insert or update

- throw not found page error if no podcast in podcast controller
- delete unnecessary unknownuseragents view
This commit is contained in:
Yassine Doghri 2020-07-02 10:08:32 +00:00
parent ac5f0c7328
commit da0f047281
9 changed files with 38 additions and 46 deletions

View File

@ -22,8 +22,8 @@ $routes->setDefaultMethod('index');
$routes->setTranslateURIDashes(false);
$routes->set404Override();
$routes->setAutoRoute(false);
$routes->addPlaceholder('podcastName', '[a-z0-9\_]{1,191}');
$routes->addPlaceholder('episodeSlug', '[a-z0-9\-]{1,191}');
$routes->addPlaceholder('podcastName', '[a-zA-Z0-9\_]{1,191}');
$routes->addPlaceholder('episodeSlug', '[a-zA-Z0-9\-]{1,191}');
/**
* --------------------------------------------------------------------

View File

@ -49,7 +49,7 @@ class Episode extends BaseController
'image' =>
'uploaded[image]|is_image[image]|ext_in[image,jpg,png]|permit_empty',
'title' => 'required',
'slug' => 'required',
'slug' => 'required|regex_match[[a-zA-Z0-9\-]{1,191}]',
'description' => 'required',
'type' => 'required',
])
@ -105,7 +105,7 @@ class Episode extends BaseController
'image' =>
'uploaded[image]|is_image[image]|ext_in[image,jpg,png]|permit_empty',
'title' => 'required',
'slug' => 'required',
'slug' => 'required|regex_match[[a-zA-Z0-9\-]{1,191}]',
'description' => 'required',
'type' => 'required',
])
@ -164,6 +164,9 @@ class Episode extends BaseController
public function view()
{
// The page cache is set to a decade so it is deleted manually upon podcast update
$this->cachePage(DECADE);
self::triggerWebpageHit($this->podcast->id);
$data = [

View File

@ -18,7 +18,12 @@ class Podcast extends BaseController
{
if (count($params) > 0) {
$podcast_model = new PodcastModel();
$this->podcast = $podcast_model->where('name', $params[0])->first();
if (
!($podcast = $podcast_model->where('name', $params[0])->first())
) {
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
}
$this->podcast = $podcast;
}
return $this->$method();
@ -32,7 +37,7 @@ class Podcast extends BaseController
if (
!$this->validate([
'title' => 'required',
'name' => 'required|regex_match[^[a-z0-9\_]{1,191}$]',
'name' => 'required|regex_match[[a-zA-Z0-9\_]{1,191}]',
'description' => 'required|max_length[4000]',
'image' =>
'uploaded[image]|is_image[image]|ext_in[image,jpg,png]',
@ -91,7 +96,7 @@ class Podcast extends BaseController
if (
!$this->validate([
'title' => 'required',
'name' => 'required|regex_match[^[a-z0-9\_]{1,191}$]',
'name' => 'required|regex_match[[a-zA-Z0-9\_]{1,191}]',
'description' => 'required|max_length[4000]',
'image' =>
'uploaded[image]|is_image[image]|ext_in[image,jpg,png]|permit_empty',
@ -150,6 +155,9 @@ class Podcast extends BaseController
public function view()
{
// The page cache is set to a decade so it is deleted manually upon podcast update
$this->cachePage(DECADE);
self::triggerWebpageHit($this->podcast->id);
$data = [

View File

@ -3,17 +3,10 @@ use CodeIgniter\Controller;
class UnknownUserAgents extends Controller
{
public function index($p_id = 0)
public function index($last_known_id = 0)
{
$model = new \App\Models\UnknownUserAgentsModel();
$data = [
'useragents' => $model->getUserAgents($p_id),
];
$this->response->setContentType('application/json');
$this->response->setStatusCode(\CodeIgniter\HTTP\Response::HTTP_OK);
echo view('json/unknownuseragents', $data);
return $this->response->setJSON($model->getUserAgents($last_known_id));
}
}

View File

@ -58,13 +58,6 @@ class AddEpisodes extends Migration
'comment' =>
'An episode description. Description is text containing one or more sentences describing your episode to potential listeners. You can specify up to 4000 characters. You can use rich text formatting and some HTML (<p>, <ol>, <ul>, <li>, <a>) if wrapped in the <CDATA> tag. To include links in your description or rich HTML, adhere to the following technical guidelines: enclose all portions of your XML that contain embedded HTML in a CDATA section to prevent formatting issues, and to ensure proper link functionality.',
],
'duration' => [
'type' => 'INT',
'constraint' => 10,
'unsigned' => true,
'comment' =>
'The duration of an episode. Different duration formats are accepted however it is recommended to convert the length of the episode into seconds.',
],
'image_uri' => [
'type' => 'VARCHAR',
'constraint' => 1024,
@ -90,7 +83,7 @@ class AddEpisodes extends Migration
'type' => 'INT',
'constraint' => 10,
'unsigned' => true,
'null' => true,
'default' => 1,
'comment' =>
'The episode season number. If an episode is within a season use this tag. Where season is a non-zero integer (1, 2, 3, etc.) representing your season number. To allow the season feature for shows containing a single season, if only one season exists in the RSS feed, Apple Podcasts doesnt display a season number. When you add a second season to the RSS feed, Apple Podcasts displays the season numbers.',
],
@ -136,9 +129,6 @@ class AddEpisodes extends Migration
$this->forge->addKey('id', true);
$this->forge->addUniqueKey(['podcast_id', 'slug']);
// FIXME: as season_number can be null, the unique key constraint is useless when it is
// the majority of RDBMS behave that way
// possible solution: remove the null constraint on the season_number and set a default
$this->forge->addUniqueKey(['podcast_id', 'season_number', 'number']);
$this->forge->addForeignKey('podcast_id', 'podcasts', 'id');
$this->forge->createTable('episodes');

View File

@ -39,14 +39,8 @@ class EpisodeModel extends Model
protected $useSoftDeletes = true;
protected $useTimestamps = true;
protected $afterInsert = [
'writeEnclosureMetadata',
'clearPodcastFeedCache',
];
protected $afterUpdate = [
'writeEnclosureMetadata',
'clearPodcastFeedCache',
];
protected $afterInsert = ['writeEnclosureMetadata', 'clearCache'];
protected $afterUpdate = ['writeEnclosureMetadata', 'clearCache'];
protected function writeEnclosureMetadata(array $data)
{
@ -61,7 +55,7 @@ class EpisodeModel extends Model
return $data;
}
protected function clearPodcastFeedCache(array $data)
protected function clearCache(array $data)
{
$episode = $this->find(
is_array($data['id']) ? $data['id'][0] : $data['id']
@ -69,6 +63,9 @@ class EpisodeModel extends Model
$cache = \Config\Services::cache();
// 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));
}
}

View File

@ -40,10 +40,10 @@ class PodcastModel extends Model
protected $useTimestamps = true;
protected $afterInsert = ['clearPodcastFeedCache'];
protected $afterUpdate = ['clearPodcastFeedCache'];
protected $afterInsert = ['clearCache'];
protected $afterUpdate = ['clearCache'];
protected function clearPodcastFeedCache(array $data)
protected function clearCache(array $data)
{
$podcast = $this->find(
is_array($data['id']) ? $data['id'][0] : $data['id']
@ -51,6 +51,12 @@ class PodcastModel extends Model
$cache = \Config\Services::cache();
// delete cache for rss feed and podcast pages
$cache->delete(md5($podcast->feed_url));
$cache->delete(md5($podcast->link));
// TODO: clear cache for every podcast's episode page?
// foreach ($podcast->episodes as $episode) {
// $cache->delete(md5($episode->link));
// }
}
}

View File

@ -16,8 +16,8 @@ class UnknownUserAgentsModel extends Model
protected $allowedFields = [];
public function getUserAgents($p_id = 0)
public function getUserAgents($last_known_id = 0)
{
return $this->where('id>', $p_id)->findAll();
return $this->where('id>', $last_known_id)->findAll();
}
}

View File

@ -1,5 +0,0 @@
<?php
if (!empty($useragents) && is_array($useragents)) {
echo json_encode($useragents);
}
?>