demo/app/Modules/Thread/Actions/StoreAction.php
2023-03-23 18:50:47 +01:00

134 lines
4.2 KiB
PHP

<?php
namespace LaraBB\Thread\Actions;
use Illuminate\Database\Connection;
use LaraBB\Forum\Tasks\Forum\UpdateTask as UpdateForumTask;
use App\Traits\PivotData;
use Illuminate\Support\Str;
use LaraBB\Forum\Models\Forum;
use LaraBB\Post\Models\Post;
use LaraBB\Post\Tasks\StoreTask as StorePostTask;
use LaraBB\Thread\Models\Thread;
use LaraBB\Thread\Tasks\DestroyTask as DestroyThreadTask;
use LaraBB\Thread\Tasks\FindTask as FindThreadTask;
use LaraBB\Thread\Tasks\StoreTask as StoreThreadTask;
use LaraBB\Thread\Tasks\UpdateTask as UpdateThreadTask;
use LaraBB\Thread\UI\Web\Requests\Store;
use Throwable;
/**
* Class StoreAction
* @package LaraBB\Thread\Actions
*/
class StoreAction
{
use PivotData;
/**
* @var Thread|null
*/
private ?Thread $thread;
/**
* StoreAction constructor.
* @param FindThreadTask $getThreadTask
* @param UpdateForumTask $updateForumTask
* @param UpdateThreadTask $updateThreadTask
* @param StoreThreadTask $storeThreadTask
* @param StorePostTask $storePostTask
* @param DestroyThreadTask $destroyThreadTask
* @param Connection $connection
*/
public function __construct(
private readonly FindThreadTask $getThreadTask,
private readonly UpdateForumTask $updateForumTask,
private readonly UpdateThreadTask $updateThreadTask,
private readonly StoreThreadTask $storeThreadTask,
private readonly StorePostTask $storePostTask,
private readonly DestroyThreadTask $destroyThreadTask,
private readonly Connection $connection
) {
}
/**
* @param Store $request
* @return false|Thread|null
*/
public function run(Store $request): bool|Thread|null
{
try {
$this->connection->transaction(function() use($request) {
$this->thread = $this->storeThreadTask->run($this->prepareThreadData($request));
if(is_null($this->thread)) {
throw new Exception('The thread could not be created');
}
$post = $this->storePostTask->run($this->preparePostData($this->thread, $request));
$this->updateThreadTask->run($this->thread, [
'slug' => $this->thread->slug . '-' . $this->thread->id,
'lastpost_uuid' => $post->uuid,
'firstpost_uuid' => $post->uuid
]);
$this->updateForumTask->run($request->forum, $this->prepareForumData($request->forum, $post));
});
} catch (Throwable $t) {
return false;
}
return $this->thread;
}
/**
* @param Store $request
* @return array
*/
private function prepareThreadData(Store $request): array
{
return [
'created_uuid' => $request->user()->uuid,
'updated_uuid' => $request->user()->uuid,
'forum_uuid' => $request->post('forum_uuid'),
'prefix_uuid' => $request->post('prefix'),
'title' => $request->post('title'),
'slug' => Str::slug($request->post('title')),
'users' => $this->preparePivotData($request, 'users'),
'groups' => $this->preparePivotData($request, 'groups'),
];
}
/**
* @param Thread $thread
* @param Store $request
* @return array
*/
private function preparePostData(Thread $thread, Store $request): array
{
return [
'created_uuid' => $request->user()->uuid,
'updated_uuid' => $request->user()->uuid,
'thread_uuid' => $thread->uuid,
'title' => $request->post('title'),
'content' => $request->post('content'),
'users' => $this->preparePivotData($request, 'users'),
'groups' => $this->preparePivotData($request, 'groups'),
];
}
/**
* @param Forum $forum
* @param Post $post
* @return array
*/
private function prepareForumData(Forum $forum, Post $post): array
{
return [
'thread_count' => $forum->thread_count + 1,
'posting_count' => $forum->posting_count + 1,
'lastpost_uuid' => $post->uuid
];
}
}