fix: set cache expiration to next note publish to show note on publication date

fix episode, podcast and persons forms + episode scheduling
This commit is contained in:
Yassine Doghri 2021-05-25 18:00:09 +00:00
parent fbc0967caa
commit 0a66de3e6c
No known key found for this signature in database
GPG Key ID: 3E7F89498B960C9F
14 changed files with 117 additions and 44 deletions

View File

@ -89,6 +89,8 @@ Events::on('on_note_add', function (Note $note): void {
// same for other events below
cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*");
cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*");
});
Events::on('on_note_remove', function (Note $note): void {
@ -108,6 +110,8 @@ Events::on('on_note_remove', function (Note $note): void {
cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*");
cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*");
cache()
->deleteMatching("page_note#{$note->id}*");
});
@ -125,6 +129,8 @@ Events::on('on_note_reblog', function (Actor $actor, Note $note): void {
cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*");
cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*");
cache()
->deleteMatching("page_note#{$note->id}*");
@ -147,6 +153,8 @@ Events::on('on_note_undo_reblog', function (Note $reblogNote): void {
cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*");
cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*");
cache()
->deleteMatching("page_note#{$note->id}*");
@ -169,6 +177,8 @@ Events::on('on_reply_remove', function (Note $reply): void {
cache()
->deleteMatching("page_podcast#{$note->actor->podcast->id}*");
cache()
->deleteMatching("podcast#{$note->actor->podcast->id}*");
cache()
->deleteMatching("page_note#{$note->id}*");
});
@ -182,6 +192,8 @@ Events::on('on_note_favourite', function (Actor $actor, Note $note): void {
cache()
->deleteMatching("page_podcast#{$actor->podcast->id}*");
cache()
->deleteMatching("podcast#{$actor->podcast->id}*");
cache()
->deleteMatching("page_note#{$note->id}*");
@ -199,6 +211,8 @@ Events::on('on_note_undo_favourite', function (Actor $actor, Note $note): void {
cache()
->deleteMatching("page_podcast#{$actor->podcast->id}*");
cache()
->deleteMatching("podcast#{$actor->podcast->id}*");
cache()
->deleteMatching("page_note#{$note->id}*");
@ -209,24 +223,32 @@ Events::on('on_note_undo_favourite', function (Actor $actor, Note $note): void {
Events::on('on_block_actor', function (int $actorId): void {
cache()->deleteMatching('page_podcast*');
cache()
->deleteMatching('podcast*');
cache()
->deleteMatching('page_note*');
});
Events::on('on_unblock_actor', function (int $actorId): void {
cache()->deleteMatching('page_podcast*');
cache()
->deleteMatching('podcast*');
cache()
->deleteMatching('page_note*');
});
Events::on('on_block_domain', function (string $domainName): void {
cache()->deleteMatching('page_podcast*');
cache()
->deleteMatching('podcast*');
cache()
->deleteMatching('page_note*');
});
Events::on('on_unblock_domain', function (string $domainName): void {
cache()->deleteMatching('page_podcast*');
cache()
->deleteMatching('podcast*');
cache()
->deleteMatching('page_note*');
});

View File

@ -9,6 +9,7 @@
namespace App\Controllers\Admin;
use App\Entities\Episode;
use App\Entities\Image;
use App\Entities\Location;
use App\Entities\Note;
use App\Entities\Podcast;
@ -118,6 +119,12 @@ class EpisodeController extends BaseController
->with('errors', $this->validator->getErrors());
}
$image = null;
$imageFile = $this->request->getFile('image');
if ($imageFile !== null && $imageFile->isValid()) {
$image = new Image($imageFile);
}
$newEpisode = new Episode([
'podcast_id' => $this->podcast->id,
'title' => $this->request->getPost('title'),
@ -125,7 +132,7 @@ class EpisodeController extends BaseController
'guid' => '',
'audio_file' => $this->request->getFile('audio_file'),
'description_markdown' => $this->request->getPost('description'),
'image' => $this->request->getFile('image'),
'image' => $image,
'location' => new Location($this->request->getPost('location_name'),),
'transcript' => $this->request->getFile('transcript'),
'chapters' => $this->request->getFile('chapters'),
@ -253,9 +260,9 @@ class EpisodeController extends BaseController
$this->episode->audio_file = $audioFile;
}
$image = $this->request->getFile('image');
if ($image !== null && $image->isValid()) {
$this->episode->image = $image;
$imageFile = $this->request->getFile('image');
if ($imageFile !== null && $imageFile->isValid()) {
$this->episode->image = new Image($imageFile);
}
$transcriptChoice = $this->request->getPost('transcript-choice');

View File

@ -66,7 +66,7 @@ class EpisodePersonController extends BaseController
public function attemptAdd(): RedirectResponse
{
$rules = [
'person' => 'required',
'persons' => 'required',
];
if (! $this->validate($rules)) {
@ -79,8 +79,8 @@ class EpisodePersonController extends BaseController
(new PersonModel())->addEpisodePersons(
$this->podcast->id,
$this->episode->id,
$this->request->getPost('person'),
$this->request->getPost('person_group_role'),
$this->request->getPost('persons'),
$this->request->getPost('roles') ?? [],
);
return redirect()->back();

View File

@ -230,7 +230,7 @@ class PodcastController extends BaseController
// set Podcast categories
(new CategoryModel())->setPodcastCategories(
(int) $newPodcastId,
$this->request->getPost('other_categories'),
$this->request->getPost('other_categories') ?? [],
);
// set interact as the newly created podcast actor
@ -320,7 +320,7 @@ class PodcastController extends BaseController
// set Podcast categories
(new CategoryModel())->setPodcastCategories(
$this->podcast->id,
$this->request->getPost('other_categories'),
$this->request->getPost('other_categories') ?? [],
);
$db->transComplete();

View File

@ -67,8 +67,15 @@ class PodcastController extends BaseController
helper('form');
return view('podcast/activity_authenticated', $data);
}
$secondsToNextUnpublishedEpisode = (new EpisodeModel())->getSecondsToNextUnpublishedEpisode(
$this->podcast->id,
);
return view('podcast/activity', $data, [
'cache' => DECADE,
'cache' => $secondsToNextUnpublishedEpisode
? $secondsToNextUnpublishedEpisode
: DECADE,
'cache_name' => $cacheName,
]);
}

View File

@ -192,7 +192,8 @@ class Episode extends Entity
return new Image(null, $imagePath, $this->attributes['image_mimetype'],);
}
return $this->podcast->image;
return $this->getPodcast()
->image;
}
/**

View File

@ -87,7 +87,7 @@ class Person extends Entity
$this->roles = (new PersonModel())->getPersonRoles(
$this->id,
$this->attributes['podcast_id'],
$this->episode_id
$this->attributes['episode_id'] ?? null
);
}

View File

@ -36,12 +36,12 @@ return [
'manage_section_subtitle' => 'Remove persons from this podcast',
'add_section_title' => 'Add persons to this podcast',
'add_section_subtitle' => 'You may pick several persons and roles.',
'person' => 'Persons',
'person_hint' =>
'persons' => 'Persons',
'persons_hint' =>
'You may select one or several persons with the same roles. You need to create the persons first.',
'group_role' => 'Groups and roles',
'group_role_hint' =>
'You may select none, one or several groups and roles for a person.',
'roles' => 'Roles',
'roles_hint' =>
'You may select none, one or several roles for a person.',
'submit_add' => 'Add person(s)',
'remove' => 'Remove',
],
@ -50,13 +50,13 @@ return [
'manage_section_title' => 'Management',
'manage_section_subtitle' => 'Remove persons from this episode',
'add_section_title' => 'Add persons to this episode',
'add_section_subtitle' => 'You may pick several persons and roles',
'person' => 'Persons',
'person_hint' =>
'add_section_subtitle' => 'You may pick several persons and roles.',
'persons' => 'Persons',
'persons_hint' =>
'You may select one or several persons with the same roles. You need to create the persons first.',
'group_role' => 'Groups and roles',
'group_role_hint' =>
'You may select none, one or several groups and roles for a person.',
'roles' => 'Roles',
'roles_hint' =>
'You may select none, one or several roles for a person.',
'submit_add' => 'Add person(s)',
'remove' => 'Remove',
],

View File

@ -138,13 +138,35 @@ class NoteModel extends UuidModel
->orderBy('published_at', 'DESC')
->findAll();
$secondsToNextUnpublishedNote = $this->getSecondsToNextUnpublishedNote($actorId,);
cache()
->save($cacheName, $found, DECADE);
->save($cacheName, $found, $secondsToNextUnpublishedNote ? $secondsToNextUnpublishedNote : DECADE,);
}
return $found;
}
/**
* Returns the timestamp difference in seconds between the next note to publish and the current timestamp. Returns
* false if there's no note to publish
*/
public function getSecondsToNextUnpublishedNote(int $actorId): int | false
{
$result = $this->select('TIMESTAMPDIFF(SECOND, NOW(), `published_at`) as timestamp_diff',)
->where([
'actor_id' => $actorId,
])
->where('`published_at` > NOW()', null, false)
->orderBy('published_at', 'asc')
->get()
->getResultArray();
return count($result) !== 0
? (int) $result[0]['timestamp_diff']
: false;
}
/**
* Retrieves all published replies for a given note. By default, it does not get replies from blocked actors.
*

View File

@ -34,7 +34,7 @@ trait AnalyticsTrait
? '- Direct -'
: parse_url($referer, PHP_URL_HOST);
parse_str(parse_url($referer, PHP_URL_QUERY), $queries);
$keywords = array_key_exists('q', $queries) ? $queries['q'] : null;
$keywords = $queries['q'] ?? null;
$procedureName = $db->prefixTable('analytics_website');
$db->query("call {$procedureName}(?,?,?,?,?,?)", [

View File

@ -316,12 +316,12 @@ class EpisodeModel extends Model
cache()
->delete("podcast_episode#{$episode->id}");
cache()
->deleteMatching("podcast#{$episode->podcast_id}_episode#{$episode->id}*",);
->deleteMatching("podcast#{$episode->podcast_id}_episode#{$episode->id}*");
cache()
->delete("podcast#{$episode->podcast_id}_episode-{$episode->slug}",);
->delete("podcast#{$episode->podcast_id}_episode-{$episode->slug}");
cache()
->deleteMatching("page_podcast#{$episode->podcast_id}_activity*",);
->deleteMatching("page_podcast#{$episode->podcast_id}_activity*");
cache()
->deleteMatching("page_podcast#{$episode->podcast_id}_episode#{$episode->id}_*",);
cache()

View File

@ -107,7 +107,7 @@ class PersonModel extends Model
*/
public function getPersonRoles(int $personId, int $podcastId, ?int $episodeId): array
{
if ($episodeId) {
if ($episodeId !== null) {
$cacheName = "podcast#{$podcastId}_episode#{$episodeId}_person#{$personId}_roles";
if (! ($found = cache($cacheName))) {
@ -212,7 +212,9 @@ class PersonModel extends Model
$cacheName = "podcast#{$podcastId}_episode#{$episodeId}_persons";
if (! ($found = cache($cacheName))) {
$found = $this
->select('persons.*, episodes_persons.podcast_id, episodes_persons.episode_id')
->select(
'persons.*, episodes_persons.podcast_id as podcast_id, episodes_persons.episode_id as episode_id'
)
->distinct()
->join('episodes_persons', 'persons.id = episodes_persons.person_id')
->where('episodes_persons.episode_id', $episodeId)
@ -321,6 +323,7 @@ class PersonModel extends Model
}
return $this->db->table('podcasts_persons')
->ignore(true)
->insertBatch($data);
}
@ -331,6 +334,10 @@ class PersonModel extends Model
*/
public function removePersonFromPodcast(int $podcastId, int $personId): string | bool
{
cache()->deleteMatching("podcast#{$podcastId}_person#{$personId}*");
cache()
->delete("podcast#{$podcastId}_persons");
return $this->db->table('podcasts_persons')
->delete([
'podcast_id' => $podcastId,
@ -353,6 +360,8 @@ class PersonModel extends Model
array $groupsRoles
): bool | int {
if ($personIds !== []) {
cache()
->delete("podcast#{$podcastId}_episode#{$episodeId}_persons");
(new EpisodeModel())->clearCache([
'id' => $episodeId,
]);
@ -379,6 +388,7 @@ class PersonModel extends Model
}
}
return $this->db->table('episodes_persons')
->ignore(true)
->insertBatch($data);
}
return 0;
@ -386,6 +396,10 @@ class PersonModel extends Model
public function removePersonFromEpisode(int $podcastId, int $episodeId, int $personId): bool | string
{
cache()->deleteMatching("podcast#{$podcastId}_episode#{$episodeId}_person#{$personId}*");
cache()
->delete("podcast#{$podcastId}_episode#{$episodeId}_persons");
return $this->db->table('episodes_persons')
->delete([
'podcast_id' => $podcastId,

View File

@ -96,29 +96,29 @@
) ?>
<?= form_label(
lang('Person.episode_form.person'),
'person',
lang('Person.episode_form.persons'),
'persons',
[],
lang('Person.episode_form.person_hint'),
lang('Person.episode_form.persons_hint'),
) ?>
<?= form_multiselect('person[]', $personOptions, old('person', []), [
'id' => 'person',
<?= form_multiselect('persons[]', $personOptions, old('persons', []), [
'id' => 'persons',
'class' => 'form-select mb-4',
'required' => 'required',
]) ?>
<?= form_label(
lang('Person.episode_form.group_role'),
'group_role',
lang('Person.episode_form.roles'),
'roles',
[],
lang('Person.episode_form.group_role_hint'),
lang('Person.episode_form.roles_hint'),
true,
) ?>
<?= form_multiselect(
'person_group_role[]',
'roles[]',
$taxonomyOptions,
old('person_group_role', []),
['id' => 'person_group_role', 'class' => 'form-select mb-4'],
old('roles', []),
['id' => 'roles', 'class' => 'form-select mb-4'],
) ?>

View File

@ -94,10 +94,10 @@
) ?>
<?= form_label(
lang('Person.podcast_form.person'),
'person',
lang('Person.podcast_form.persons'),
'persons',
[],
lang('Person.podcast_form.person_hint'),
lang('Person.podcast_form.persons_hint'),
) ?>
<?= form_multiselect('persons[]', $personOptions, old('persons', []), [
'id' => 'persons',