118 lines
2.9 KiB
PHP
118 lines
2.9 KiB
PHP
<?php
|
|
/**
|
|
* Chat repository for member communication.
|
|
*
|
|
* @package KGV\VereinManager
|
|
*/
|
|
|
|
namespace KGV\VereinManager\Repositories;
|
|
|
|
use KGV\VereinManager\Schema;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class ChatRepository extends AbstractRepository {
|
|
|
|
/**
|
|
* Resolve table name.
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function resolve_table() {
|
|
return Schema::table( 'chat_messages' );
|
|
}
|
|
|
|
/**
|
|
* Get recent chat messages for one room.
|
|
*
|
|
* @param string $room_key Room key.
|
|
* @param int $limit Maximum result count.
|
|
* @param int $after_id Optional lower ID boundary for polling.
|
|
* @return array
|
|
*/
|
|
public function get_recent_messages( $room_key, $limit = 60, $after_id = 0 ) {
|
|
$users = $this->wpdb->users;
|
|
$room_key = sanitize_key( $room_key );
|
|
$limit = max( 1, min( 200, absint( $limit ) ) );
|
|
$after_id = absint( $after_id );
|
|
|
|
if ( $after_id > 0 ) {
|
|
$sql = "SELECT m.*, u.display_name
|
|
FROM {$this->table} m
|
|
LEFT JOIN {$users} u ON u.ID = m.user_id
|
|
WHERE m.room_key = %s AND m.id > %d
|
|
ORDER BY m.id ASC
|
|
LIMIT %d";
|
|
|
|
return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $room_key, $after_id, $limit ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
|
}
|
|
|
|
$sql = "SELECT *
|
|
FROM (
|
|
SELECT m.*, u.display_name
|
|
FROM {$this->table} m
|
|
LEFT JOIN {$users} u ON u.ID = m.user_id
|
|
WHERE m.room_key = %s
|
|
ORDER BY m.id DESC
|
|
LIMIT %d
|
|
) recent_messages
|
|
ORDER BY id ASC";
|
|
|
|
return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $room_key, $limit ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
|
}
|
|
|
|
/**
|
|
* Store one new message.
|
|
*
|
|
* @param string $room_key Room key.
|
|
* @param int $user_id Sender user ID.
|
|
* @param string $message Message body.
|
|
* @return object|null
|
|
*/
|
|
public function save_message( $room_key, $user_id, $message ) {
|
|
$room_key = sanitize_key( $room_key );
|
|
$user_id = absint( $user_id );
|
|
$message = trim( sanitize_textarea_field( $message ) );
|
|
|
|
if ( '' === $room_key || $user_id < 1 || '' === $message ) {
|
|
return null;
|
|
}
|
|
|
|
$result = $this->wpdb->insert(
|
|
$this->table,
|
|
array(
|
|
'room_key' => $room_key,
|
|
'user_id' => $user_id,
|
|
'message' => $message,
|
|
'created_at' => $this->now(),
|
|
),
|
|
array( '%s', '%d', '%s', '%s' )
|
|
);
|
|
|
|
if ( false === $result ) {
|
|
return null;
|
|
}
|
|
|
|
return $this->find_with_author( (int) $this->wpdb->insert_id );
|
|
}
|
|
|
|
/**
|
|
* Find one message together with the author's display name.
|
|
*
|
|
* @param int $id Message ID.
|
|
* @return object|null
|
|
*/
|
|
private function find_with_author( $id ) {
|
|
$users = $this->wpdb->users;
|
|
$sql = "SELECT m.*, u.display_name
|
|
FROM {$this->table} m
|
|
LEFT JOIN {$users} u ON u.ID = m.user_id
|
|
WHERE m.id = %d
|
|
LIMIT 1";
|
|
|
|
return $this->wpdb->get_row( $this->wpdb->prepare( $sql, absint( $id ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
|
}
|
|
}
|