Add message model
This commit is contained in:
parent
46f80fbed2
commit
95adeca0ae
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Migrations;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Database\Migration\Migration;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* This migration creates the "messages" table and copies the existing "Messages" table records to the new one.
|
||||
*/
|
||||
class CreateMessagesTable extends Migration
|
||||
{
|
||||
use ChangesReferences;
|
||||
use Reference;
|
||||
|
||||
/**
|
||||
* Creates the "messages" table, copies the data and drops the "Message" table.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$hasPreviousMessagesTable = $this->schema->hasTable('Messages');
|
||||
|
||||
if ($hasPreviousMessagesTable) {
|
||||
// Rename because some SQL DBMS handle identifiers case insensitive
|
||||
$this->schema->rename('Messages', 'PreviousMessages');
|
||||
}
|
||||
|
||||
$this->createNewMessagesTable();
|
||||
|
||||
if ($hasPreviousMessagesTable) {
|
||||
$this->copyPreviousToNewMessagesTable();
|
||||
$this->changeReferences(
|
||||
'PreviousMessages',
|
||||
'ID',
|
||||
'messages',
|
||||
'id',
|
||||
'unsignedInteger'
|
||||
);
|
||||
$this->schema->drop('PreviousMessages');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreates the previous "Messages" table, copies back the data and drops the new "messages" table.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Rename as some SQL DBMS handle identifiers case insensitive
|
||||
$this->schema->rename('messages', 'new_messages');
|
||||
|
||||
$this->createPreviousMessagesTable();
|
||||
$this->copyNewToPreviousMessagesTable();
|
||||
$this->changeReferences(
|
||||
'new_messages',
|
||||
'id',
|
||||
'Messages',
|
||||
'ID',
|
||||
'unsignedInteger'
|
||||
);
|
||||
|
||||
$this->schema->drop('new_messages');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function createNewMessagesTable(): void
|
||||
{
|
||||
$this->schema->create(
|
||||
'messages',
|
||||
function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$this->references($table, 'users', 'user_id');
|
||||
$this->references($table, 'users', 'receiver_id');
|
||||
$table->boolean('read')->default(0);
|
||||
$table->text('text');
|
||||
$table->timestamps();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function copyPreviousToNewMessagesTable(): void
|
||||
{
|
||||
$connection = $this->schema->getConnection();
|
||||
/** @var stdClass[] $previousMessageRecords */
|
||||
$previousMessageRecords = $connection
|
||||
->table('PreviousMessages')
|
||||
->get();
|
||||
|
||||
foreach ($previousMessageRecords as $previousMessage) {
|
||||
$date = Carbon::createFromTimestamp($previousMessage->Datum);
|
||||
$connection->table('messages')->insert(
|
||||
[
|
||||
'id' => $previousMessage->id,
|
||||
'user_id' => $previousMessage->SUID,
|
||||
'receiver_id' => $previousMessage->RUID,
|
||||
'read' => $previousMessage->isRead === 'N' ? 0 : 1,
|
||||
'text' => $previousMessage->Text,
|
||||
'created_at' => $date,
|
||||
'updated_at' => $date,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function createPreviousMessagesTable(): void
|
||||
{
|
||||
$this->schema->create(
|
||||
'Messages',
|
||||
function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('Datum');
|
||||
$this->references($table, 'users', 'SUID');
|
||||
$this->references($table, 'users', 'RUID');
|
||||
$table->char('isRead')
|
||||
->default('N');
|
||||
$table->text('Text');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function copyNewToPreviousMessagesTable(): void
|
||||
{
|
||||
$connection = $this->schema->getConnection();
|
||||
/** @var Collection|stdClass[] $messageRecords */
|
||||
$messageRecords = $connection
|
||||
->table('new_messages')
|
||||
->get();
|
||||
|
||||
foreach ($messageRecords as $messageRecord) {
|
||||
$date = Carbon::createFromFormat('Y-m-d H:i:s', $messageRecord->created_at)
|
||||
->getTimestamp();
|
||||
|
||||
$connection->table('Messages')->insert(
|
||||
[
|
||||
'id' => $messageRecord->id,
|
||||
'Datum' => $date,
|
||||
'SUID' => $messageRecord->user_id,
|
||||
'RUID' => $messageRecord->receiver_id,
|
||||
'isRead' => $messageRecord->read === 0 ? 'N' : 'Y',
|
||||
'Text' => $messageRecord->text,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Models;
|
||||
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Models\User\UsesUserModel;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
/**
|
||||
* This class represents a message send trough the system.
|
||||
*
|
||||
* @property integer $id
|
||||
* @property integer $receiver_id
|
||||
* @property boolean $read
|
||||
* @property string $text
|
||||
* @property Carbon|null $created_at
|
||||
* @property Carbon|null $updated_at
|
||||
* @property-read User $receiver
|
||||
* @method static Builder|Message newModelQuery()
|
||||
* @method static Builder|Message newQuery()
|
||||
* @method static Builder|Message query()
|
||||
* @method static Builder|Message whereCreatedAt($value)
|
||||
* @method static Builder|Message whereId($value)
|
||||
* @method static Builder|Message whereRead($value)
|
||||
* @method static Builder|Message whereReceiverId($value)
|
||||
* @method static Builder|Message whereSenderId($value)
|
||||
* @method static Builder|Message whereText($value)
|
||||
* @method static Builder|Message whereUpdatedAt($value)
|
||||
*/
|
||||
class Message extends BaseModel
|
||||
{
|
||||
use UsesUserModel;
|
||||
|
||||
/** @var bool enable timestamps */
|
||||
public $timestamps = true;
|
||||
|
||||
/** @var string[] */
|
||||
protected $casts = [
|
||||
'user_id' => 'integer',
|
||||
'receiver_id' => 'integer',
|
||||
'read' => 'boolean',
|
||||
];
|
||||
|
||||
/** @var string[] */
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'receiver_id',
|
||||
'read',
|
||||
'text',
|
||||
];
|
||||
|
||||
/** @var array */
|
||||
protected $attributes = [
|
||||
'read' => false,
|
||||
];
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function receiver(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'receiver_id');
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ namespace Engelsystem\Models\User;
|
|||
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Models\BaseModel;
|
||||
use Engelsystem\Models\Message;
|
||||
use Engelsystem\Models\News;
|
||||
use Engelsystem\Models\NewsComment;
|
||||
use Engelsystem\Models\Question;
|
||||
|
@ -42,6 +43,9 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
|
|||
*
|
||||
* @property-read Collection|Question[] $questionsAsked
|
||||
* @property-read Collection|Question[] $questionsAnswered
|
||||
* @property-read Collection|Message[] $messagesReceived
|
||||
* @property-read Collection|Message[] $messagesSent
|
||||
* @property-read Collection|Message[] $messages
|
||||
*/
|
||||
class User extends BaseModel
|
||||
{
|
||||
|
@ -141,4 +145,38 @@ class User extends BaseModel
|
|||
return $this->hasMany(Question::class, 'answerer_id')
|
||||
->where('answerer_id', $this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany
|
||||
*/
|
||||
public function messagesSent(): HasMany
|
||||
{
|
||||
return $this->hasMany(Message::class, 'user_id')
|
||||
->orderBy('created_at', 'DESC')
|
||||
->orderBy('id', 'DESC');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany
|
||||
*/
|
||||
public function messagesReceived(): HasMany
|
||||
{
|
||||
return $this->hasMany(Message::class, 'receiver_id')
|
||||
->orderBy('read')
|
||||
->orderBy('created_at', 'DESC')
|
||||
->orderBy('id', 'DESC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a HasMany relation for all messages sent or received by the user.
|
||||
*
|
||||
* @return HasMany
|
||||
*/
|
||||
public function messages(): HasMany
|
||||
{
|
||||
return $this->messagesSent()
|
||||
->union($this->messagesReceived())
|
||||
->orderBy('read')
|
||||
->orderBy('id', 'DESC');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Test\Unit\Models;
|
||||
|
||||
use Engelsystem\Models\Message;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Test\Unit\HasDatabase;
|
||||
use Engelsystem\Test\Unit\TestCase;
|
||||
|
||||
/**
|
||||
* This class provides tests covering the Message model and its relations.
|
||||
*/
|
||||
class MessageTest extends TestCase
|
||||
{
|
||||
use HasDatabase;
|
||||
|
||||
/** @var User */
|
||||
private $user1;
|
||||
|
||||
/** @var User */
|
||||
private $user2;
|
||||
|
||||
/** @var Message */
|
||||
private $message1;
|
||||
|
||||
/** @var Message */
|
||||
private $message2;
|
||||
|
||||
/** @var Message */
|
||||
private $message3;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->initDatabase();
|
||||
|
||||
$this->user1 = User::create([
|
||||
'name' => 'user1',
|
||||
'password' => '',
|
||||
'email' => 'user1@example.com',
|
||||
'api_key' => '',
|
||||
]);
|
||||
|
||||
$this->user2 = User::create([
|
||||
'name' => 'user2',
|
||||
'password' => '',
|
||||
'email' => 'user2@example.com',
|
||||
'api_key' => '',
|
||||
]);
|
||||
|
||||
$this->message1 = Message::create([
|
||||
'user_id' => $this->user1->id,
|
||||
'receiver_id' => $this->user2->id,
|
||||
'text' => 'message1',
|
||||
]);
|
||||
|
||||
$this->message2 = Message::create([
|
||||
'user_id' => $this->user1->id,
|
||||
'receiver_id' => $this->user2->id,
|
||||
'read' => true,
|
||||
'text' => 'message2',
|
||||
]);
|
||||
|
||||
$this->message3 = Message::create([
|
||||
'user_id' => $this->user2->id,
|
||||
'receiver_id' => $this->user1->id,
|
||||
'text' => 'message3',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that loading Messages works.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLoad(): void
|
||||
{
|
||||
$message1 = Message::find($this->message1->id);
|
||||
$this->assertSame($this->message1->user_id, $message1->user_id);
|
||||
$this->assertSame($this->message1->receiver_id, $message1->receiver_id);
|
||||
$this->assertSame($this->message1->read, $message1->read);
|
||||
$this->assertSame($this->message1->text, $message1->text);
|
||||
|
||||
$message2 = Message::find($this->message2->id);
|
||||
$this->assertSame($this->message2->user_id, $message2->user_id);
|
||||
$this->assertSame($this->message2->receiver_id, $message2->receiver_id);
|
||||
$this->assertSame($this->message2->read, $message2->read);
|
||||
$this->assertSame($this->message2->text, $message2->text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the Messages have the correct senders.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSenders(): void
|
||||
{
|
||||
$this->assertSame($this->user1->id, $this->message1->user->id);
|
||||
$this->assertSame($this->user1->id, $this->message2->user->id);
|
||||
$this->assertSame($this->user2->id, $this->message3->user->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the Messages have the correct receivers.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReceivers(): void
|
||||
{
|
||||
$this->assertSame($this->user2->id, $this->message1->receiver->id);
|
||||
$this->assertSame($this->user2->id, $this->message2->receiver->id);
|
||||
$this->assertSame($this->user1->id, $this->message3->receiver->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the Users have the correct sent Messages.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testUserSentMessages(): void
|
||||
{
|
||||
$sentByUser1 = $this->user1->messagesSent->all();
|
||||
$this->assertCount(2, $sentByUser1);
|
||||
$this->assertSame($this->message2->id, $sentByUser1[0]->id);
|
||||
$this->assertSame($this->message1->id, $sentByUser1[1]->id);
|
||||
|
||||
$sentByUser2 = $this->user2->messagesSent->all();
|
||||
$this->assertCount(1, $sentByUser2);
|
||||
$this->assertSame($this->message3->id, $sentByUser2[0]->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the Users have the correct received Messages.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testUserReceivedMessages(): void
|
||||
{
|
||||
$receivedByUser1 = $this->user1->messagesReceived->all();
|
||||
$this->assertCount(1, $receivedByUser1);
|
||||
$this->assertSame($this->message3->id, $receivedByUser1[0]->id);
|
||||
|
||||
$receivedByUser2 = $this->user2->messagesReceived->all();
|
||||
$this->assertCount(2, $receivedByUser2);
|
||||
$this->assertSame($this->message1->id, $receivedByUser2[0]->id);
|
||||
$this->assertSame($this->message2->id, $receivedByUser2[1]->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the user have the correct Messages.
|
||||
*/
|
||||
public function testUserMessages(): void
|
||||
{
|
||||
$user1Messages = $this->user1->messages->all();
|
||||
$this->assertCount(3, $user1Messages);
|
||||
$this->assertSame($this->message3->id, $user1Messages[0]->id);
|
||||
$this->assertSame($this->message1->id, $user1Messages[1]->id);
|
||||
$this->assertSame($this->message2->id, $user1Messages[2]->id);
|
||||
|
||||
$user2Messages = $this->user2->messages->all();
|
||||
$this->assertCount(3, $user2Messages);
|
||||
$this->assertSame($this->message3->id, $user2Messages[0]->id);
|
||||
$this->assertSame($this->message1->id, $user2Messages[1]->id);
|
||||
$this->assertSame($this->message2->id, $user2Messages[2]->id);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue