Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/controllers/Links.php
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ public function delete(Request $request): Response
return Response::found($from);
}

$user->unmark($link);
$link->remove();

return Response::found($from);
Expand Down
37 changes: 36 additions & 1 deletion src/models/UrlStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public static function markAsReadLater(User $user, Link|array $links): void
}

/**
* Mark the links as dismissed and remove them from the journal of the user.
* Mark the links as dismissed for the user.
*
* @param Link|Link[] $links
*/
Expand Down Expand Up @@ -213,6 +213,41 @@ public static function markAsDismissed(User $user, Link|array $links): void
$statement->execute($values);
}

/**
* Unmark the links for the user (aka remove the corresponding URL statuses).
*
* @param Link|Link[] $links
*/
public static function unmark(User $user, Link|array $links): void
{
if ($links instanceof Link) {
$links = [$links];
}

if (!$links) {
return;
}

$values_as_question_marks = [];
$values = [$user->id];

foreach ($links as $link) {
$values_as_question_marks[] = '?';
$values[] = $link->url_hash;
}
$values_placeholder = implode(", ", $values_as_question_marks);

$sql = <<<SQL
DELETE FROM url_statuses
WHERE user_id = ?
AND url_hash IN ({$values_placeholder})
SQL;

$database = Database::get();
$statement = $database->prepare($sql);
$statement->execute($values);
}

/**
* @see dao\BulkQueries::bulkInsertOnConflict
*
Expand Down
14 changes: 14 additions & 0 deletions src/models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,20 @@ public function markAsDismissed(Link|array $links): void
$news->removeLinks($links, sync_publication_frequency: false);
}

/**
* Unmark the links for the user (aka remove the corresponding URL statuses).
*
* @param Link|Link[] $links
*/
public function unmark(Link|array $links): void
{
if ($links instanceof Link) {
$links = [$links];
}

UrlStatus::unmark($this, $links);
}

/**
* Set the user password.
*/
Expand Down
9 changes: 7 additions & 2 deletions src/models/dao/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,13 @@ public static function listComputedByCollectionId(

$date_clause = '';
if ($options['published_date'] !== null) {
$date_clause = "AND date_trunc('day', lc.created_at) = :published_date";
$parameters[':published_date'] = $options['published_date']->format('Y-m-d');
$date_clause = "AND lc.created_at >= :published_start AND lc.created_at <= :published_end";

$start = $options['published_date']->modify('00:00:00');
$end = $start->modify('23:59:59');

$parameters[':published_start'] = $start->format(Database\Column::DATETIME_FORMAT);
$parameters[':published_end'] = $end->format(Database\Column::DATETIME_FORMAT);
}

$source = $options['source'];
Expand Down
13 changes: 11 additions & 2 deletions src/utils/LinksTimeline.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,20 @@ public function __construct(array $links)
continue;
}

$date_key = $link->published_at->format('Y-m-d');
// The key is formatted using translateDate (using IntlDateFormatter
// internally) because the output can differ from the format method
// of DateTimeInterface. This happens because of the timezone. For
// instance, a "2026-06-24 22:30:00" DateTime in UTC+2 would be
// formatted "2026-06-24" with DateTime::format, and "2026-06-25"
// with TwigExtension::translateDate. As we display the dates in
// the interface using the latter, the key MUST be coherent.
$date_key = \Minz\Template\TwigExtension::translateDate($link->published_at, 'Y-MM-dd');

if (isset($this->dates_groups[$date_key])) {
$date_group = $this->dates_groups[$date_key];
} else {
$date_group = new LinksTimeline\DateGroup($link->published_at);
$date = new \DateTimeImmutable($date_key);
$date_group = new LinksTimeline\DateGroup($date);
$this->dates_groups[$date_key] = $date_group;
}

Expand Down
3 changes: 3 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

\Minz\Engine::startSession();

// Make sure to set the locale.
\App\utils\Locale::setCurrentLocale('en_GB');

\Minz\Database::reset();
$schema = @file_get_contents(\App\Configuration::$schema_path);

Expand Down
4 changes: 4 additions & 0 deletions tests/controllers/LinksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -956,13 +956,17 @@ public function testDeleteDeletesLinkAndRedirects(): void
$link = LinkFactory::create([
'user_id' => $user->id,
]);
$user->markAsRead($link);

$this->assertTrue($user->hasRead($link));

$response = $this->appRun('POST', "/links/{$link->id}/delete", [
'csrf_token' => $this->csrfToken(forms\links\DeleteLink::class),
]);

$this->assertResponseCode($response, 302, '/');
$this->assertFalse(models\Link::exists($link->id));
$this->assertFalse($user->hasRead($link));
}

public function testDeleteRedirectsIfNotConnected(): void
Expand Down
6 changes: 3 additions & 3 deletions tests/utils/LinksTimelineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function testConstructGroupsLinksByDates(): void
$link2 = LinkFactory::create();
$link2->published_at = new \DateTimeImmutable('2024-03-22 12:00');
$link3 = LinkFactory::create();
$link3->published_at = new \DateTimeImmutable('2024-03-20 12:00');
$link3->published_at = new \DateTimeImmutable('2024-03-21 00:00+0200');
$links = [$link1, $link2, $link3];

$timeline = new LinksTimeline($links);
Expand All @@ -25,11 +25,11 @@ public function testConstructGroupsLinksByDates(): void
$this->assertSame(2, count($dates_groups));
$group1 = $dates_groups['2024-03-20'];
$group2 = $dates_groups['2024-03-22'];
$this->assertEquals($link1->published_at, $group1->date);
$this->assertEquals($link1->published_at->modify('00:00:00'), $group1->date);
$this->assertSame(2, count($group1->links));
$this->assertSame($link1->id, $group1->links[0]->id);
$this->assertSame($link3->id, $group1->links[1]->id);
$this->assertEquals($link2->published_at, $group2->date);
$this->assertEquals($link2->published_at->modify('00:00:00'), $group2->date);
$this->assertSame(1, count($group2->links));
$this->assertSame($link2->id, $group2->links[0]->id);
}
Expand Down
Loading