DiscussConversationForm   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 72
dl 0
loc 190
rs 10
c 1
b 0
f 0
wmc 15

4 Methods

Rating   Name   Duplication   Size   Complexity  
A rules() 0 18 2
A create() 0 45 3
A searchCategories() 0 11 1
B update() 0 39 9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Xetaravel\Livewire\Forms;
6
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Facades\Auth;
9
use Illuminate\Support\Facades\DB;
10
use Illuminate\Validation\Rule;
11
use Livewire\Form;
12
use Xetaio\Mentions\Parser\MentionParser;
13
use Xetaravel\Events\Discuss\CategoryWasChangedEvent;
14
use Xetaravel\Events\Discuss\ConversationWasCreatedEvent;
15
use Xetaravel\Events\Discuss\ConversationWasLockedEvent;
16
use Xetaravel\Events\Discuss\ConversationWasPinnedEvent;
17
use Xetaravel\Events\Discuss\TitleWasChangedEvent;
18
use Xetaravel\Models\DiscussCategory;
19
use Xetaravel\Models\DiscussConversation;
20
use Xetaravel\Models\DiscussPost;
21
use Xetaravel\Models\DiscussUser;
22
use Throwable;
23
24
class DiscussConversationForm extends Form
25
{
26
    /**
27
     * The conversation to update.
28
     *
29
     * @var DiscussConversation|null
30
     */
31
    public ?DiscussConversation $discussConversation = null;
32
33
    /**
34
     * The category of the conversation
35
     *
36
     * @var int|null
37
     */
38
    public ?int $category_id = null;
39
40
    /**
41
     * The title of the conversation.
42
     *
43
     * @var string|null
44
     */
45
    public ?string $title = null;
46
47
    /**
48
     * Whatever the conversation is pinned
49
     *
50
     * @var bool|null
51
     */
52
    public ?bool $is_pinned = false;
53
54
    /**
55
     * Whatever the conversation is locked.
56
     *
57
     * @var bool|null
58
     */
59
    public ?bool $is_locked = false;
60
61
    /**
62
     * The content of the post, only when creating.
63
     *
64
     * @var string|null
65
     */
66
    public ?string $content = null;
67
68
    /**
69
     * The categories used in choice.
70
     *
71
     * @var Collection|array
72
     */
73
    public Collection|array $categoriesSearchable = [];
74
75
    protected function rules(): array
76
    {
77
        $rules =  [
78
            'title' => 'required|min:5',
79
            'category_id' => [
80
                'required',
81
                'integer',
82
                Rule::in(DiscussCategory::pluckLocked('id')->toArray())
83
            ],
84
            'is_pinned' => 'boolean',
85
            'is_locked' => 'boolean'
86
        ];
87
88
        if (!$this->discussConversation?->exists) {
89
            $rules['content'] = 'required|min:10';
90
        }
91
92
        return $rules;
93
    }
94
95
    /**
96
     * Function to store the model.
97
     *
98
     * @return DiscussConversation
99
     *
100
     * @throws Throwable
101
     */
102
    public function create(): DiscussConversation
103
    {
104
        $properties = [
105
            'category_id',
106
            'title',
107
        ];
108
109
        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

109
        if (Auth::user()->/** @scrutinizer ignore-call */ hasPermissionTo('pin discuss conversation')) {
Loading history...
110
            $properties[] = 'is_pinned';
111
        }
112
        if (Auth::user()->hasPermissionTo('lock discuss conversation')) {
113
            $properties[] = 'is_locked';
114
        }
115
116
        return DB::transaction(function () use ($properties) {
117
            $discussConversation = DiscussConversation::create($this->only($properties));
118
119
            $discussPost = DiscussPost::create([
120
                'conversation_id' => $discussConversation->id,
0 ignored issues
show
Bug introduced by
The property id does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
121
                'content' => $this->content
122
            ]);
123
124
            DiscussUser::create([
125
                'conversation_id' => $discussConversation->id,
126
                'is_read' => 1
127
            ]);
128
129
            $discussConversation->first_post_id = $discussPost->id;
0 ignored issues
show
Bug introduced by
The property first_post_id does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
130
            $discussConversation->last_post_id = $discussPost->id;
0 ignored issues
show
Bug introduced by
The property last_post_id does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
131
            $discussConversation->save();
132
133
            $discussConversation->category->last_conversation_id = $discussConversation->getKey();
0 ignored issues
show
Bug introduced by
The property category does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
134
            $discussConversation->category->save();
135
136
            $parser = new MentionParser($discussPost, [
0 ignored issues
show
Bug introduced by
It seems like $discussPost can also be of type Illuminate\Database\Eloq...gHasThroughRelationship; 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

136
            $parser = new MentionParser(/** @scrutinizer ignore-type */ $discussPost, [
Loading history...
137
                'regex' => config('mentions.regex')
138
            ]);
139
            $content = $parser->parse($discussPost->content);
0 ignored issues
show
Bug introduced by
The property content does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
140
141
            $discussPost->content = $content;
142
            $discussPost->save();
143
144
            event(new ConversationWasCreatedEvent(Auth::user(), $discussConversation));
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

144
            event(new ConversationWasCreatedEvent(/** @scrutinizer ignore-type */ Auth::user(), $discussConversation));
Loading history...
Bug introduced by
It seems like $discussConversation can also be of type Illuminate\Database\Eloq...gHasThroughRelationship; however, parameter $discussConversation of Xetaravel\Events\Discuss...tedEvent::__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

144
            event(new ConversationWasCreatedEvent(Auth::user(), /** @scrutinizer ignore-type */ $discussConversation));
Loading history...
145
146
            return $discussConversation;
147
        });
148
    }
149
150
    /**
151
     * Function to update the conversation.
152
     *
153
     * @return DiscussConversation
154
     */
155
    public function update(): DiscussConversation
156
    {
157
        // The title has changed
158
        if ($this->discussConversation->title !== $this->title) {
159
            event(new TitleWasChangedEvent($this->discussConversation, $this->title, $this->discussConversation->title));
0 ignored issues
show
Bug introduced by
It seems like $this->title can also be of type null; however, parameter $title of Xetaravel\Events\Discuss...gedEvent::__construct() does only seem to accept string, 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

159
            event(new TitleWasChangedEvent($this->discussConversation, /** @scrutinizer ignore-type */ $this->title, $this->discussConversation->title));
Loading history...
Bug introduced by
It seems like $this->discussConversation can also be of type null; however, parameter $discussConversation of Xetaravel\Events\Discuss...gedEvent::__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

159
            event(new TitleWasChangedEvent(/** @scrutinizer ignore-type */ $this->discussConversation, $this->title, $this->discussConversation->title));
Loading history...
160
161
            $this->discussConversation->title = $this->title;
162
        }
163
164
        // The category has changed
165
        if ($this->discussConversation->category_id !== $this->category_id) {
166
            event(new CategoryWasChangedEvent($this->discussConversation, $this->category_id, $this->discussConversation->category_id));
0 ignored issues
show
Bug introduced by
It seems like $this->discussConversation can also be of type null; however, parameter $discussConversation of Xetaravel\Events\Discuss...gedEvent::__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

166
            event(new CategoryWasChangedEvent(/** @scrutinizer ignore-type */ $this->discussConversation, $this->category_id, $this->discussConversation->category_id));
Loading history...
Bug introduced by
It seems like $this->category_id can also be of type null; however, parameter $category of Xetaravel\Events\Discuss...gedEvent::__construct() does only seem to accept integer, 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

166
            event(new CategoryWasChangedEvent($this->discussConversation, /** @scrutinizer ignore-type */ $this->category_id, $this->discussConversation->category_id));
Loading history...
167
168
            $this->discussConversation->category_id = $this->category_id;
169
        }
170
171
        // The pinned status has changed
172
        if (Auth::user()->hasPermissionTo('pin discuss conversation')) {
173
            if ($this->discussConversation->is_pinned !== $this->is_pinned && $this->is_pinned === true) {
174
                event(new ConversationWasPinnedEvent($this->discussConversation));
0 ignored issues
show
Bug introduced by
It seems like $this->discussConversation can also be of type 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

174
                event(new ConversationWasPinnedEvent(/** @scrutinizer ignore-type */ $this->discussConversation));
Loading history...
175
            }
176
            $this->discussConversation->is_pinned = $this->is_pinned;
177
        }
178
179
        // The locked status has changed
180
        if (Auth::user()->hasPermissionTo('lock discuss conversation')) {
181
            if ($this->discussConversation->is_locked !== $this->is_locked && $this->is_locked === true) {
182
                event(new ConversationWasLockedEvent($this->discussConversation));
0 ignored issues
show
Bug introduced by
It seems like $this->discussConversation can also be of type 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

182
                event(new ConversationWasLockedEvent(/** @scrutinizer ignore-type */ $this->discussConversation));
Loading history...
183
            }
184
            $this->discussConversation->is_locked = $this->is_locked;
185
        }
186
187
        $this->discussConversation->is_edited = true;
188
        $this->discussConversation->edit_count++;
189
        $this->discussConversation->edited_user_id = Auth::id();
190
191
        $this->discussConversation->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

191
        $this->discussConversation->/** @scrutinizer ignore-call */ 
192
                                    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...
192
193
        return $this->discussConversation;
194
    }
195
196
    /**
197
     * Function to search categories.
198
     *
199
     * @param string $value
200
     *
201
     * @return void
202
     */
203
    public function searchCategories(string $value = ''): void
204
    {
205
        $selectedOption = DiscussCategory::where('id', $this->category_id)->get();
206
207
        $categories = DiscussCategory::query()
208
            ->where('title', 'like', "%$value%");
209
210
        $this->categoriesSearchable = $categories->take(10)
211
            ->orderBy('title')
0 ignored issues
show
Bug introduced by
'title' of type string is incompatible with the type Closure|Illuminate\Datab...\Database\Query\Builder expected by parameter $column of Illuminate\Database\Query\Builder::orderBy(). ( Ignorable by Annotation )

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

211
            ->orderBy(/** @scrutinizer ignore-type */ 'title')
Loading history...
212
            ->get()
213
            ->merge($selectedOption);
214
    }
215
}
216