Skip to content
Open
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
10 changes: 8 additions & 2 deletions includes/factory/class-message.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use DateTime;
use WP\Notifications\Framework;
use WP\Notifications\Helper;
use WP\Notifications\Model;

/**
Expand All @@ -31,10 +32,10 @@ class Message extends Framework\Factory {
* @type ?string $accept_message Optional label of the accept action.
* @type ?string $channel_title Optional human-readable title of the channel
* the message was emitted from.
* @type ?DateTime $created_at Optional datetime at which a message was created.
* @type string|DateTime|null $created_at Optional datetime at which a message was created.
* Default `'null'`
* @type ?string $dismiss_label Optional label of the dismiss action.
* @type ?DateTime $expires_at Optional datetime at which a message expires.
* @type string|DateTime|null $expires_at Optional datetime at which a message expires.
* Default `'null'`
* @type ?string $icon Optional icon of the message. Default `null`
* @type ?int $id Optional database ID of the message. Default `null`
Expand Down Expand Up @@ -67,6 +68,11 @@ public function make( $args = array() ): Model\Message {
$severity = array_key_exists( 'severity', $parsed ) ? $parsed['severity'] : null;
$title = array_key_exists( 'title', $parsed ) ? $parsed['title'] : '';

// Deserialize MySQL datetime strings.

$created_at = Helper\Serde::maybe_deserialize_mysql_date( $created_at );
$expires_at = Helper\Serde::maybe_deserialize_mysql_date( $expires_at );

return new Model\Message(
$message,
$accept_label,
Expand Down
94 changes: 85 additions & 9 deletions includes/persistence/class-wpdb-notification-repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,74 @@
use DateTimeInterface;

use WP\Notifications;
use WP\Notifications\Factory;
use WP\Notifications\Model;

class Wpdb_Notification_Repository extends Abstract_Notification_Repository {

/**
* Find a notification by ID.
* Find a user's notification by message ID.
*
* @param int $id ID to look for.
* @param int $message_id Message ID.
* @param int $user_id User who owns the notification.
*
* @return Notifications\Notification|false Notification that matches the ID, or
* false if not found.
* @return array{notification: Model\Notification, message: Model\Message}|null
* The notification and its message, or null if not found.
*/
public function find_by_id( $id ) {
if ( ! is_int( $id ) ) {
return false;
public function find_by_id( int $message_id, int $user_id ): ?array {
global $wpdb;

$row = $wpdb->get_row(
$wpdb->prepare(
"SELECT m.*, q.user_id, q.dismissed_at, q.displayed_at
FROM {$wpdb->prefix}notifications_queue AS q
INNER JOIN {$wpdb->prefix}notifications_messages AS m ON m.id = q.message_id
WHERE q.message_id = %d AND q.user_id = %d
LIMIT 1",
$message_id,
$user_id
),
ARRAY_A
);

if ( null === $row ) {
return null;
}

// TODO: Implement query.
return false;
$meta = json_decode( (string) $row['meta'], true );

// Table columns win over the same keys in meta.
$message = ( new Factory\Message() )->make(
array_merge(
is_array( $meta ) ? $meta : array(),
array(
'channel_title' => $row['channel_title'],
'created_at' => $row['created_at'],
'expires_at' => $row['expires_at'],
'id' => (int) $row['id'],
'message' => $row['message'],
'severity' => $row['severity'],
'title' => $row['title'],
)
)
);

$notification = ( new Factory\Notification() )->make(
array(
'channel_name' => $row['channel_name'],
'message_id' => (int) $row['id'],
'user_id' => (int) $row['user_id'],
'created_at' => $row['created_at'],
'dismissed_at' => $row['dismissed_at'],
'displayed_at' => $row['displayed_at'],
'expires_at' => $row['expires_at'],
)
);

return array(
'notification' => $notification,
'message' => $message,
);
}

/**
Expand Down Expand Up @@ -62,4 +112,30 @@ public function add( Notifications\Notification $notification ) {
// TODO: Implement query.
return -1;
}

/**
* Remove a user's notification.
*
* Only the user's queue row is removed, the message itself can still
* belong to other users.
*
* @param int $message_id Message ID.
* @param int $user_id User who owns the notification.
*
* @return bool Whether a notification was removed.
*/
public function remove( int $message_id, int $user_id ): bool {
global $wpdb;

$deleted = $wpdb->delete(
$wpdb->prefix . 'notifications_queue',
array(
'message_id' => $message_id,
'user_id' => $user_id,
),
array( '%d', '%d' )
);

return ! empty( $deleted );
}
}
22 changes: 17 additions & 5 deletions includes/persistence/interface-notification-repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
use DateTimeInterface;

use WP\Notifications;
use WP\Notifications\Model;


interface Notification_Repository {

/**
* Find a notification by ID.
* Find a user's notification by message ID.
*
* @param int $id ID to look for.
* @param int $message_id Message ID.
* @param int $user_id User who owns the notification.
*
* @return Notifications\Notification|false Notification that matches the ID, or
* false if not found.
* @return array{notification: Model\Notification, message: Model\Message}|null
* The notification and its message, or null if not found.
*/
public function find_by_id( $id );
public function find_by_id( int $message_id, int $user_id ): ?array;

/**
* Find all notifications for a given date period.
Expand Down Expand Up @@ -70,4 +72,14 @@ public function find_latest(
* @return int ID that the notification was stored under.
*/
public function add( Notifications\Notification $notification );

/**
* Remove a user's notification.
*
* @param int $message_id Message ID.
* @param int $user_id User who owns the notification.
*
* @return bool Whether a notification was removed.
*/
public function remove( int $message_id, int $user_id ): bool;
}
Loading
Loading