Commit da0f0472 authored by Yassine Doghri's avatar Yassine Doghri
Browse files

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
parent ac5f0c73
......@@ -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}');
/**
* --------------------------------------------------------------------
......
......@@ -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 = [
......
......@@ -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 = [
......
......@@ -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));
}
}
......@@ -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 doesn’t 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');
......
......@@ -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));
}
}
......@@ -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));
// }
}
}
......@@ -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();
}
}
<?php
if (!empty($useragents) && is_array($useragents)) {
echo json_encode($useragents);
}
?>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment