Passed
Push — fix_coverage_in_scrutinizer ( cd0379...a04ba4 )
by Herberto
13:22
created

BlogController::commentNew()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 36
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3.0593

Importance

Changes 0
Metric Value
dl 0
loc 36
ccs 13
cts 16
cp 0.8125
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 16
nc 2
nop 3
crap 3.0593
1
<?php
2
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace App\Controller;
13
14
use App\Entity\Comment;
15
use App\Entity\Post;
16
use App\Events;
17
use App\Form\CommentType;
18
use App\Repository\PostRepository;
19
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
20
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
21
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
22
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
23
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
24
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
25
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
26
use Symfony\Component\EventDispatcher\GenericEvent;
27
use Symfony\Component\HttpFoundation\Request;
28
use Symfony\Component\HttpFoundation\Response;
29
30
/**
31
 * Controller used to manage blog contents in the public part of the site.
32
 *
33
 * @Route("/blog")
34
 *
35
 * @author Ryan Weaver <[email protected]>
36
 * @author Javier Eguiluz <[email protected]>
37
 */
38
class BlogController extends AbstractController
39
{
40
    /**
41
     * @Route("/", defaults={"page": "1", "_format"="html"}, name="blog_index")
42
     * @Route("/rss.xml", defaults={"page": "1", "_format"="xml"}, name="blog_rss")
43
     * @Route("/page/{page}", defaults={"_format"="html"}, requirements={"page": "[1-9]\d*"}, name="blog_index_paginated")
44
     * @Method("GET")
45
     * @Cache(smaxage="10")
46
     *
47
     * NOTE: For standard formats, Symfony will also automatically choose the best
48
     * Content-Type header for the response.
49
     * See https://symfony.com/doc/current/quick_tour/the_controller.html#using-formats
50
     */
51 4
    public function index(int $page, string $_format, PostRepository $posts): Response
52
    {
53 4
        $latestPosts = $posts->findLatest($page);
54
55
        // Every template name also has two extensions that specify the format and
56
        // engine for that template.
57
        // See https://symfony.com/doc/current/templating.html#template-suffix
58 4
        return $this->render('blog/index.'.$_format.'.twig', ['posts' => $latestPosts]);
59
    }
60
61
    /**
62
     * @Route("/posts/{slug}", name="blog_post")
63
     * @Method("GET")
64
     *
65
     * NOTE: The $post controller argument is automatically injected by Symfony
66
     * after performing a database query looking for a Post with the 'slug'
67
     * value given in the route.
68
     * See https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
69
     */
70 2
    public function postShow(Post $post): Response
71
    {
72
        // Symfony's 'dump()' function is an improved version of PHP's 'var_dump()' but
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
73
        // it's not available in the 'prod' environment to prevent leaking sensitive information.
74
        // It can be used both in PHP files and Twig templates, but it requires to
75
        // have enabled the DebugBundle. Uncomment the following line to see it in action:
76
        //
77
        // dump($post, $this->getUser(), new \DateTime());
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
78
79 2
        return $this->render('blog/post_show.html.twig', ['post' => $post]);
80
    }
81
82
    /**
83
     * @Route("/comment/{postSlug}/new", name="comment_new")
84
     * @Method("POST")
85
     * @Security("is_granted('IS_AUTHENTICATED_FULLY')")
86
     * @ParamConverter("post", options={"mapping": {"postSlug": "slug"}})
87
     *
88
     * NOTE: The ParamConverter mapping is required because the route parameter
89
     * (postSlug) doesn't match any of the Doctrine entity properties (slug).
90
     * See https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html#doctrine-converter
91
     */
92 1
    public function commentNew(Request $request, Post $post, EventDispatcherInterface $eventDispatcher): Response
93
    {
94 1
        $comment = new Comment();
95 1
        $comment->setAuthor($this->getUser());
0 ignored issues
show
Documentation introduced by
$this->getUser() is of type null|object, but the function expects a object<App\Entity\User>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
96 1
        $post->addComment($comment);
97
98 1
        $form = $this->createForm(CommentType::class, $comment);
99 1
        $form->handleRequest($request);
100
101 1
        if ($form->isSubmitted() && $form->isValid()) {
102 1
            $em = $this->getDoctrine()->getManager();
103 1
            $em->persist($comment);
104 1
            $em->flush();
105
106
            // When triggering an event, you can optionally pass some information.
107
            // For simple applications, use the GenericEvent object provided by Symfony
108
            // to pass some PHP variables. For more complex applications, define your
109
            // own event object classes.
110
            // See https://symfony.com/doc/current/components/event_dispatcher/generic_event.html
111 1
            $event = new GenericEvent($comment);
112
113
            // When an event is dispatched, Symfony notifies it to all the listeners
114
            // and subscribers registered to it. Listeners can modify the information
115
            // passed in the event and they can even modify the execution flow, so
116
            // there's no guarantee that the rest of this controller will be executed.
117
            // See https://symfony.com/doc/current/components/event_dispatcher.html
118 1
            $eventDispatcher->dispatch(Events::COMMENT_CREATED, $event);
119
120 1
            return $this->redirectToRoute('blog_post', ['slug' => $post->getSlug()]);
121
        }
122
123
        return $this->render('blog/comment_form_error.html.twig', [
124
            'post' => $post,
125
            'form' => $form->createView(),
126
        ]);
127
    }
128
129
    /**
130
     * This controller is called directly via the render() function in the
131
     * blog/post_show.html.twig template. That's why it's not needed to define
132
     * a route name for it.
133
     *
134
     * The "id" of the Post is passed in and then turned into a Post object
135
     * automatically by the ParamConverter.
136
     */
137 1
    public function commentForm(Post $post): Response
138
    {
139 1
        $form = $this->createForm(CommentType::class);
140
141 1
        return $this->render('blog/_comment_form.html.twig', [
142 1
            'post' => $post,
143 1
            'form' => $form->createView(),
144
        ]);
145
    }
146
147
    /**
148
     * @Route("/search", name="blog_search")
149
     * @Method("GET")
150
     */
151
    public function search(Request $request, PostRepository $posts): Response
152
    {
153
        if (!$request->isXmlHttpRequest()) {
154
            return $this->render('blog/search.html.twig');
155
        }
156
157
        $query = $request->query->get('q', '');
158
        $limit = $request->query->get('l', 10);
159
        $foundPosts = $posts->findBySearchQuery($query, $limit);
160
161
        $results = [];
162
        foreach ($foundPosts as $post) {
163
            $results[] = [
164
                'title' => htmlspecialchars($post->getTitle()),
165
                'date' => $post->getPublishedAt()->format('M d, Y'),
166
                'author' => htmlspecialchars($post->getAuthor()->getFullName()),
167
                'summary' => htmlspecialchars($post->getSummary()),
168
                'url' => $this->generateUrl('blog_post', ['slug' => $post->getSlug()]),
169
            ];
170
        }
171
172
        return $this->json($results);
173
    }
174
}
175