Test Failed
Push — master ( dfd167...06d4ad )
by Emil
02:23
created

CommentController   B

Complexity

Total Complexity 41

Size/Duplication

Total Lines 288
Duplicated Lines 8.33 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 16.38%

Importance

Changes 0
Metric Value
wmc 41
lcom 1
cbo 2
dl 24
loc 288
ccs 29
cts 177
cp 0.1638
rs 8.2769
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 10 1
B showComments() 9 31 4
B replyComment() 9 40 6
B editComment() 3 46 6
B deleteComment() 3 39 6
B voteComment() 0 22 5
A getComments() 0 11 2
A sortBy() 0 6 2
A buildCommentTree() 0 18 4
B sortBranchComments() 0 21 5

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like CommentController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CommentController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Emsa\Comment;
4
5
use \Anax\DI\InjectionAwareInterface;
6
use \Anax\DI\InjectionAwareTrait;
7
use \LRC\Form\ModelForm as Modelform;
8
9
/**
10
 * A controller for the comment system.
11
 */
12
class CommentController implements InjectionAwareInterface
13
{
14
    use InjectionAwareTrait;
15
16
17
18
    /**
19
     * @var \LRC\Repository\SoftDbRepository  Comment repository.
20
     */
21
    private $comments;
22
23
24
25
    /**
26
     * Configuration.
27
     */
28
    public function init()
29
    {
30
        $commentRepository = $this->di->manager->createRepository(Comment::class, [
31
            'db' => $this->di->db,
32
            'type' => 'db-soft',
33
            'table' => 'rv1_Comment'
34
        ]);
35
        $this->comments = $commentRepository;
36
        return $commentRepository;
37
    }
38
39
40
41
    public function showComments($postid)
42
    {
43
        $newForm = new ModelForm('new-comment-form', Comment::class);
44
        $loggedInUser = $this->di->userController->getLoggedInUserId();
45
46 View Code Duplication
        if ($this->di->request->getMethod() == 'POST' && $this->di->session->has("username")) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
47
            $comment = $newForm->populateModel();
48
            $newForm->validate();
49
            if ($newForm->isValid()) {
50
                $comment->user = $loggedInUser;
51
                $this->comments->save($comment);
52
                $this->di->response->redirect("comment/$postid#{$comment->id}");
53
            }
54
        }
55
56
        $comments = $this->getComments($postid, $loggedInUser);
57
        $sortBy = $this->sortBy();
58
        $sortedComments = $this->buildCommentTree($comments, $sortBy);
59
60
        $viewData = [
61
            "comments" => $sortedComments,
62
            "textfilter" => $this->di->textfilter,
63
            "postid" => $postid,
64
            "action" => "",
65
            "actionID" => "",
66
            "newForm" => $newForm,
67
            "isLoggedIn" => $this->di->session->has("username")
68
        ];
69
70
        $this->di->view->add("comment/comment-section", $viewData, "main", 2);
71
    }
72
73
74
75
    public function replyComment($postid)
76
    {
77
        $actionID = (int)$this->di->request->getGet("id");
78
        $loggedInUser = $this->di->userController->getLoggedInUserId();
79
80
        if ($this->di->request->getMethod() == 'GET' && (!$this->comments->find('id', $actionID) || !$this->di->session->has("username"))) {
81
            $this->di->response->redirect("comment/$postid");
82
        }
83
84
        $replyForm = new ModelForm('reply-comment-form', Comment::class);
85
86 View Code Duplication
        if ($this->di->request->getMethod() == 'POST') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
            $comment = $replyForm->populateModel();
88
            $replyForm->validate();
89
            if ($replyForm->isValid()) {
90
                $comment->user = $loggedInUser;
91
                $this->comments->save($comment);
92
                $this->di->response->redirect("comment/$postid#{$comment->id}");
93
            }
94
        }
95
96
        $newForm = new ModelForm('new-comment-form', Comment::class);
97
98
        $comments = $this->getComments($postid, $loggedInUser);
99
        $sortBy = $this->sortBy();
100
        $sortedComments = $this->buildCommentTree($comments, $sortBy);
101
102
        $viewData = [
103
            "comments" => $sortedComments,
104
            "textfilter" => $this->di->textfilter,
105
            "postid" => $postid,
106
            "action" => "reply",
107
            "actionID" => $actionID,
108
            "newForm" => $newForm,
109
            "replyForm" => $replyForm,
110
            "isLoggedIn" => $this->di->session->has("username")
111
        ];
112
113
        $this->di->view->add("comment/comment-section", $viewData, "main", 2);
114
    }
115
116
117
118
    public function editComment($postid)
119
    {
120
        $actionID = (int)$this->di->request->getGet("id");
121
122
        $currentComment = $this->comments->findSoft('id', $actionID);
123
        if (!$currentComment) {
124
            $this->di->response->redirect("comment/$postid");
125
        }
126
127
        $loggedInUser = $this->di->userController->getLoggedInUserId();
128 View Code Duplication
        if ($loggedInUser != $currentComment->user && !$this->di->session->has("admin")) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
129
            $this->di->response->redirect("comment/$postid");
130
        }
131
132
        $editForm = new ModelForm('edit-comment-form', $currentComment);
133
134
        if ($this->di->request->getMethod() == 'POST') {
135
            $comment = $editForm->populateModel(null, ['id', 'post_id', 'parent_id']);
136
            //Prevent edited column from being set to NULL
137
            unset($comment->edited);
138
            $editForm->validate();
139
            if ($editForm->isValid()) {
140
                $this->comments->save($comment);
141
                $this->di->response->redirect("comment/$postid#{$comment->id}");
142
            }
143
        }
144
145
        $newForm = new ModelForm('new-comment-form', Comment::class);
146
147
        $comments = $this->getComments($postid, $loggedInUser);
148
        $sortBy = $this->sortBy();
149
        $sortedComments = $this->buildCommentTree($comments, $sortBy);
150
151
        $viewData = [
152
            "comments" => $sortedComments,
153
            "textfilter" => $this->di->textfilter,
154
            "postid" => $postid,
155
            "action" => "edit",
156
            "actionID" => $actionID,
157
            "newForm" => $newForm,
158
            "editForm" => $editForm,
159
            "isLoggedIn" => $this->di->session->has("username")
160
        ];
161
162
        $this->di->view->add("comment/comment-section", $viewData, "main", 2);
163
    }
164
165
166
167
    public function deleteComment($postid)
168
    {
169
        $actionID = (int)$this->di->request->getGet("id");
170
171
        $currentComment = $this->comments->findSoft('id', $actionID);
172
        if (!$currentComment) {
173
            $this->di->response->redirect("comment/$postid");
174
        }
175
176
        $loggedInUser = $this->di->userController->getLoggedInUserId();
177 View Code Duplication
        if ($loggedInUser != $currentComment->user && !$this->di->session->has("admin")) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
178
            $this->di->response->redirect("comment/$postid");
179
        }
180
181
        if ($this->di->request->getMethod() == 'POST') {
182
            if ($this->di->request->getPost('delete') == 'Ja') {
183
                $this->comments->deleteSoft($currentComment);
184
            }
185
            $this->di->response->redirect("comment/$postid#{$currentComment->id}");
186
        }
187
188
        $newForm = new ModelForm('new-comment-form', Comment::class);
189
190
        $comments = $this->getComments($postid, $loggedInUser);
191
        $sortBy = $this->sortBy();
192
        $sortedComments = $this->buildCommentTree($comments, $sortBy);
193
194
        $viewData = [
195
            "comments" => $sortedComments,
196
            "textfilter" => $this->di->textfilter,
197
            "postid" => $postid,
198
            "action" => "delete",
199
            "actionID" => $actionID,
200
            "newForm" => $newForm,
201
            "isLoggedIn" => $this->di->session->has("username")
202
        ];
203
204
        $this->di->view->add("comment/comment-section", $viewData, "main", 2);
205
    }
206
207
208
209
    public function voteComment($postid)
210
    {
211
        $actionID = (int)$this->di->request->getGet("id");
212
213
        $comment = $this->comments->findSoft('id', $actionID);
214
        if (!$comment) {
215
            $this->di->response->redirect("comment/$postid");
216
        }
217
218
        if (!$this->di->session->has("username")) {
219
            $this->di->response->redirect("comment/$postid");
220
        }
221
222
        if ($this->di->request->getPost("upvote")) {
223
            $comment->upvote += 1;
224
        } elseif ($this->di->request->getPost("downvote")) {
225
            $comment->downvote += 1;
226
        }
227
228
        $this->comments->save($comment);
229
        $this->di->response->redirect("comment/$postid#{$comment->id}");
230
    }
231
232
233
234
    public function getComments($postid, $loggedInUser)
235
    {
236
        $comments = $this->comments->getAll('post_id = ?', [$postid]);
237
238
        foreach ($comments as $comment) {
239
            $comment->isUserOwner = ($loggedInUser == $comment->userObject->id);
240
            $comment->isUserAdmin = $this->di->session->has("admin");
241
        }
242
243 1
        return $comments;
244
    }
245 1
246
247 1
248 1
    public function sortBy()
249 1
    {
250 1
        $sortRequest = $this->di->request->getGet("sort");
251 1
        $sortRules = ["best", "old", "new"];
252 1
        return in_array($sortRequest, $sortRules) ? $sortRequest : "best";
253 1
    }
254
255
256 1
257 1
    public function buildCommentTree(array &$elements, $sortBy, $parentId = 0)
258 1
    {
259 1
        $branch = array();
260
261
        foreach ($elements as $element) {
262
            if ($element->parent_id == $parentId) {
263
                $children = $this->buildCommentTree($elements, $sortBy, $element->id);
264 2
                if (!empty($children)) {
265
                    $element->children = $children;
266 2
                }
267 2
                $branch[$element->id] = $element;
268 2
                // Ingen aning varför jag haft unset tidigare, och nu funkar det inte som tidigare heller
269
                // unset($elements[$element->id]);
270 2
            }
271 1
        }
272
        $this->sortBranchComments($branch, $sortBy);
273 2
        return $branch;
274 1
    }
275 1
276 2
277
278 2
    public function sortBranchComments(array &$branch, $sortBy = "best")
279 2
    {
280 2
        $sortOrder = SORT_DESC;
281
        $sortArray = array();
282 2
        foreach ($branch as $key => $comment) {
283 2
            switch ($sortBy) {
284 2
                case 'old':
285
                    $sortOrder = SORT_ASC;
286
                    //Intentional fall through
287
                case 'new':
288
                    $sortArray[$key] = $comment->created;
289
                    break;
290
                case 'best':
291
                    //Intentional fall through
292
                default:
293
                    $sortArray[$key] = ($comment->upvote - $comment->downvote);
294
                    break;
295
            }
296
        }
297
        array_multisort($sortArray, $sortOrder, $branch);
298
    }
299
}
300