diff --git a/app/Commands/EpisodesComputeDownloads.php b/app/Commands/EpisodesComputeDownloads.php new file mode 100644 index 00000000..1bdc7b2d --- /dev/null +++ b/app/Commands/EpisodesComputeDownloads.php @@ -0,0 +1,50 @@ +builder() + ->select('episodes.id as id, IFNULL(SUM(ape.hits),0) as downloads_count') + ->join('analytics_podcasts_by_episode ape', 'episodes.id=ape.episode_id', 'left') + ->groupBy('episodes.id'); + + $episodeModel2 = new EpisodeModel(); + $episodeModel2->builder() + ->setQueryAsData($query) + ->onConstraint('id') + ->updateBatch(); + } +} diff --git a/app/Config/Tasks.php b/app/Config/Tasks.php index 06dd531c..e78ebfc3 100644 --- a/app/Config/Tasks.php +++ b/app/Config/Tasks.php @@ -51,5 +51,9 @@ class Tasks extends BaseConfig $schedule->command('podcast:import') ->everyMinute() ->named('podcast-import'); + + $schedule->command('episodes:compute-downloads') + ->everyHour() + ->named('episodes:compute-downloads'); } } diff --git a/app/Database/Migrations/2024-05-29-100000_add_episode_download_count.php b/app/Database/Migrations/2024-05-29-100000_add_episode_download_count.php new file mode 100644 index 00000000..ec6a9023 --- /dev/null +++ b/app/Database/Migrations/2024-05-29-100000_add_episode_download_count.php @@ -0,0 +1,29 @@ + [ + 'type' => 'INT', + 'unsigned' => true, + 'default' => 0, + 'after' => 'is_published_on_hubs', + ], + ]; + + $this->forge->addColumn('episodes', $fields); + } + + public function down(): void + { + $this->forge->dropColumn('episodes', 'downloads_count'); + } +} diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php index e9e8bcfa..16e41d85 100644 --- a/app/Entities/Episode.php +++ b/app/Entities/Episode.php @@ -72,9 +72,9 @@ use RuntimeException; * @property string|null $location_geo * @property string|null $location_osm * @property bool $is_published_on_hubs + * @property int $downloads_count * @property int $posts_count * @property int $comments_count - * @property int $downloads * @property EpisodeComment[]|null $comments * @property bool $is_premium * @property int $created_by @@ -112,8 +112,6 @@ class Episode extends Entity protected ?Chapters $chapters = null; - protected int $downloads = 0; - /** * @var Person[]|null */ @@ -171,6 +169,7 @@ class Episode extends Entity 'location_geo' => '?string', 'location_osm' => '?string', 'is_published_on_hubs' => 'boolean', + 'downloads_count' => 'integer', 'posts_count' => 'integer', 'comments_count' => 'integer', 'is_premium' => 'boolean', diff --git a/app/Models/EpisodeModel.php b/app/Models/EpisodeModel.php index 69e3bf07..9ec14a54 100644 --- a/app/Models/EpisodeModel.php +++ b/app/Models/EpisodeModel.php @@ -88,6 +88,7 @@ class EpisodeModel extends UuidModel 'location_geo', 'location_osm', 'is_published_on_hubs', + 'downloads_count', 'posts_count', 'comments_count', 'is_premium', diff --git a/modules/Admin/Controllers/EpisodeController.php b/modules/Admin/Controllers/EpisodeController.php index f6f23088..c684754a 100644 --- a/modules/Admin/Controllers/EpisodeController.php +++ b/modules/Admin/Controllers/EpisodeController.php @@ -70,34 +70,25 @@ class EpisodeController extends BaseController // Use LIKE operator as a fallback. if (strlen($query) < 4) { $episodes = $episodeModel - ->select('episodes.*, IFNULL(SUM(ape.hits),0) as downloads') - ->join('analytics_podcasts_by_episode ape', 'episodes.id=ape.episode_id', 'left') - ->where('episodes.podcast_id', $podcast->id) + ->where('podcast_id', $podcast->id) ->like('title', $episodeModel->db->escapeLikeString($query)) ->orLike('description_markdown', $episodeModel->db->escapeLikeString($query)) ->orLike('slug', $episodeModel->db->escapeLikeString($query)) ->orLike('location_name', $episodeModel->db->escapeLikeString($query)) - ->groupBy('episodes.id') ->orderBy('-`published_at`', '', false) ->orderBy('created_at', 'desc'); } else { $episodes = $episodeModel - ->select('episodes.*, IFNULL(SUM(ape.hits),0) as downloads') - ->join('analytics_podcasts_by_episode ape', 'episodes.id=ape.episode_id', 'left') - ->where('episodes.podcast_id', $podcast->id) + ->where('podcast_id', $podcast->id) ->where( "MATCH (title, description_markdown, slug, location_name) AGAINST ('{$episodeModel->db->escapeString( $query )}')" - ) - ->groupBy('episodes.id'); + ); } } else { $episodes = $episodeModel - ->select('episodes.*, IFNULL(SUM(ape.hits),0) as downloads') - ->join('analytics_podcasts_by_episode ape', 'episodes.id=ape.episode_id', 'left') - ->where('episodes.podcast_id', $podcast->id) - ->groupBy('episodes.id') + ->where('podcast_id', $podcast->id) ->orderBy('-`published_at`', '', false) ->orderBy('created_at', 'desc'); } diff --git a/themes/cp_admin/episode/list.php b/themes/cp_admin/episode/list.php index 5ede63da..0662e8e7 100644 --- a/themes/cp_admin/episode/list.php +++ b/themes/cp_admin/episode/list.php @@ -92,7 +92,7 @@ data_table( [ 'header' => lang('Episode.list.downloads'), 'cell' => function ($episode): string { - return downloads_abbr($episode->downloads); + return downloads_abbr($episode->downloads_count); }, ], [