DiscussPostForm::createPost()   B
last analyzed

Complexity

Conditions 7
Paths 9

Size

Total Lines 31
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 16
c 1
b 0
f 0
nc 9
nop 1
dl 0
loc 31
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Xetaravel\Livewire\Forms;
6
7
use Illuminate\Support\Facades\Auth;
8
use Illuminate\Support\Facades\DB;
9
use Livewire\Attributes\Locked;
10
use Livewire\Attributes\Validate;
11
use Livewire\Form;
12
use Xetaio\Mentions\Parser\MentionParser;
13
use Xetaravel\Events\Discuss\ConversationWasLockedEvent;
14
use Xetaravel\Events\Discuss\ConversationWasPinnedEvent;
15
use Xetaravel\Events\Discuss\PostWasCreatedEvent;
16
use Xetaravel\Models\DiscussConversation;
17
use Xetaravel\Models\DiscussPost;
18
use Xetaravel\Models\DiscussUser;
19
use Throwable;
20
21
class DiscussPostForm extends Form
22
{
23
    /**
24
     * The post to update.
25
     *
26
     * @var DiscussPost|null
27
     */
28
    public ?DiscussPost $discussPost = null;
29
30
    /**
31
     * The conversation id where the post belong to.
32
     *
33
     * @var int|null
34
     */
35
    #[Locked]
36
    public ?int $conversation_id = null;
37
38
    /**
39
     * The content of the post.
40
     *
41
     * @var string|null
42
     */
43
    #[Validate('required|min:10')]
44
    public ?string $content = null;
45
46
    /**
47
     * Whatever the conversation is pinned
48
     *
49
     * @var bool|null
50
     */
51
    #[Validate('boolean')]
52
    public ?bool $is_pinned = false;
53
54
    /**
55
     * Whatever the conversation is locked
56
     *
57
     * @var bool|null
58
     */
59
    #[Validate('boolean')]
60
    public ?bool $is_locked = false;
61
62
    private function createPost(array $properties): DiscussPost
63
    {
64
        $post = DiscussPost::create([
65
            'conversation_id' => $properties['conversation_id'],
66
            'content' => $properties['content'],
67
            // For unknown reason, DiscussPostObserver is not triggered
68
            'user_id' => Auth::id(),
69
        ]);
70
71
72
        $conversation = DiscussConversation::find($properties['conversation_id']);
73
74
        if (Auth::user()->hasPermissionTo('pin discuss conversation')) {
0 ignored issues
show
Bug introduced by
The method hasPermissionTo() does not exist on Illuminate\Contracts\Auth\Authenticatable. It seems like you code against a sub-type of said class. However, the method does not exist in Illuminate\Auth\GenericUser. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

74
        if (Auth::user()->/** @scrutinizer ignore-call */ hasPermissionTo('pin discuss conversation')) {
Loading history...
75
            if ($conversation->is_pinned !== $properties['is_pinned'] && $properties['is_pinned'] === true) {
0 ignored issues
show
Bug introduced by
The property is_pinned does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
76
                event(new ConversationWasPinnedEvent($conversation));
0 ignored issues
show
Bug introduced by
It seems like $conversation can also be of type Illuminate\Database\Eloq...gHasThroughRelationship and null; however, parameter $discussConversation of Xetaravel\Events\Discuss...nedEvent::__construct() does only seem to accept Xetaravel\Models\DiscussConversation, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

76
                event(new ConversationWasPinnedEvent(/** @scrutinizer ignore-type */ $conversation));
Loading history...
77
            }
78
            $conversation->is_pinned = $properties['is_pinned'];
79
        }
80
81
        if (Auth::user()->hasPermissionTo('lock discuss conversation')) {
82
            if ($conversation->is_locked !== $properties['is_locked'] && $properties['is_locked'] === true) {
0 ignored issues
show
Bug introduced by
The property is_locked does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
83
                event(new ConversationWasLockedEvent($conversation));
0 ignored issues
show
Bug introduced by
It seems like $conversation can also be of type Illuminate\Database\Eloq...gHasThroughRelationship and null; however, parameter $discussConversation of Xetaravel\Events\Discuss...kedEvent::__construct() does only seem to accept Xetaravel\Models\DiscussConversation, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

83
                event(new ConversationWasLockedEvent(/** @scrutinizer ignore-type */ $conversation));
Loading history...
84
            }
85
            $conversation->is_locked = $properties['is_locked'];
86
        }
87
88
        $conversation->last_post_id = $post->getKey();
0 ignored issues
show
Bug introduced by
The property last_post_id does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
89
90
        $conversation->save();
91
92
        return $post;
93
    }
94
95
    private function createUser(array $properties): void
96
    {
97
        DiscussUser::updateOrCreate(
98
            [
99
                'user_id' => Auth::id(),
100
                'conversation_id' => $properties['conversation_id']
101
            ],
102
            [
103
                'conversation_id' => $properties['conversation_id']
104
            ]
105
        );
106
    }
107
108
    /**
109
     * Function to create the post.
110
     *
111
     * @return DiscussPost
112
     *
113
     * @throws Throwable
114
     */
115
    public function create(): DiscussPost
116
    {
117
        $properties = [
118
            'conversation_id',
119
            'content'
120
        ];
121
122
        if (Auth::user()->hasPermissionTo('pin discuss conversation')) {
123
            $properties[] = 'is_pinned';
124
        }
125
        if (Auth::user()->hasPermissionTo('lock discuss conversation')) {
126
            $properties[] = 'is_locked';
127
        }
128
129
        return DB::transaction(function () use ($properties) {
130
            $discussPost = $this->createPost($this->only($properties));
131
            $this->createUser($this->only($properties));
132
133
            $parser = new MentionParser($discussPost, [
134
                'regex' => config('mentions.regex')
135
            ]);
136
            $content = $parser->parse($discussPost->content);
137
138
            $discussPost->content = $content;
139
            $discussPost->save();
140
141
            event(new PostWasCreatedEvent(Auth::user(), $discussPost));
0 ignored issues
show
Bug introduced by
It seems like Illuminate\Support\Facades\Auth::user() can also be of type null; however, parameter $user of Xetaravel\Events\Discuss...tedEvent::__construct() does only seem to accept Xetaravel\Models\User, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

141
            event(new PostWasCreatedEvent(/** @scrutinizer ignore-type */ Auth::user(), $discussPost));
Loading history...
142
143
            return $discussPost;
144
        });
145
    }
146
147
    /**
148
     * Function to update the post.
149
     *
150
     * @return DiscussPost
151
     */
152
    public function update(): DiscussPost
153
    {
154
        $parser = new MentionParser($this->discussPost, [
0 ignored issues
show
Bug introduced by
It seems like $this->discussPost can also be of type null; however, parameter $model of Xetaio\Mentions\Parser\M...onParser::__construct() does only seem to accept Illuminate\Database\Eloquent\Model, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

154
        $parser = new MentionParser(/** @scrutinizer ignore-type */ $this->discussPost, [
Loading history...
155
            'regex' => config('mentions.regex')
156
        ]);
157
        $content = $parser->parse($this->content);
158
159
        $this->discussPost->content = $content;
160
        $this->discussPost->save();
0 ignored issues
show
Bug introduced by
The method save() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

160
        $this->discussPost->/** @scrutinizer ignore-call */ 
161
                            save();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
161
162
        return $this->discussPost;
163
    }
164
}
165