Test Failed
Push — master ( e3fc4a...a3aea4 )
by Matt
05:14
created

ProblemController::regenerateProblems()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 7
rs 10
1
<?php
2
3
namespace App\Controller\Admin;
4
5
use App\Entity\Wander;
6
use App\Repository\ImageRepository;
7
use App\Repository\ProblemRepository;
8
use App\Repository\WanderRepository;
9
use App\Service\ProblemService;
10
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\Routing\Annotation\Route;
14
15
/**
16
 * @Route("/admin/problems", name="admin_problems_")
17
 */
18
class ProblemController extends AbstractController
19
{
20
    /**
21
     * @Route("/", name="index", methods={"GET"})
22
     */
23
    public function index(
24
        WanderRepository $wanderRepository,
25
        ImageRepository $imageRepository,
26
        ProblemRepository $problemRepository
27
        ): Response
28
    {
29
        // Problems that might take time/resources to find, that are
30
        // popped into a table on specific demand rather than every
31
        // time we load this page:
32
        $builtProblems = $problemRepository->findAll();
33
34
        // TODO: Might be sensible to do everything here into the problems
35
        // table, depending on how much we add to this.
36
        // Other issues, found on the fly:
37
        $qb = $wanderRepository->createQueryBuilder('w');
38
39
        // TODO: This doesn't work, as e.g. keywords being an empty array
40
        //
41
        $problems = $qb
42
            ->join('w.images', 'i')
43
            ->select('w AS wander')
44
            ->addSelect('COUNT(i) AS image_count')
45
            ->addSelect('SUM(CASE WHEN i.title IS NULL THEN 1 ELSE 0 END) AS no_title')
46
            ->addSelect('SUM(CASE WHEN i.latlng IS NULL THEN 1 ELSE 0 END) AS no_latlng')
47
            ->addSelect('SUM(CASE WHEN i.location IS NULL THEN 1 ELSE 0 END) AS no_location')
48
            ->addSelect('SUM(CASE WHEN i.rating IS NULL OR i.rating = 0 THEN 1 ELSE 0 END) AS no_rating')
49
            // TODO: This is a hideous bodge and will break when we finally give in and move
50
            // keywords and auto-tags to being related entities rather than a dirty PHP
51
            // array, but it's good enough for a problem admin page for now.
52
            ->addSelect("SUM(CASE WHEN i.keywords IS NULL OR i.keywords = 'a:0:{}' THEN 1 ELSE 0 END) AS no_keywords")
53
            ->addSelect("SUM(CASE WHEN i.auto_tags IS NULL OR i.auto_tags = 'a:0:{}' THEN 1 ELSE 0 END) AS no_auto_tags")
54
55
            ->addSelect(
56
                "(SUM(CASE WHEN i.title IS NULL THEN 1 ELSE 0 END)) + " .
57
                "(SUM(CASE WHEN i.latlng IS NULL THEN 1 ELSE 0 END)) + " .
58
                "(SUM(CASE WHEN i.location IS NULL THEN 1 ELSE 0 END)) + " .
59
                "(SUM(CASE WHEN i.rating IS NULL OR i.rating = 0 THEN 1 ELSE 0 END)) + " .
60
                "(SUM(CASE WHEN i.keywords IS NULL OR i.keywords = 'a:0:{}' THEN 1 ELSE 0 END)) AS total_problems_excl_auto")
61
            ->addSelect(
62
                "(SUM(CASE WHEN i.title IS NULL THEN 1 ELSE 0 END)) + " .
63
                "(10 * SUM(CASE WHEN i.latlng IS NULL THEN 1 ELSE 0 END)) + " .
64
                "(2 * SUM(CASE WHEN i.location IS NULL THEN 1 ELSE 0 END)) + " .
65
                "(5 * SUM(CASE WHEN i.rating IS NULL OR i.rating = 0 THEN 1 ELSE 0 END)) + " .
66
                "(0.01 * SUM(CASE WHEN i.keywords IS NULL OR i.keywords = 'a:0:{}' THEN 1 ELSE 0 END)) + " .
67
                "(0.001 * SUM(CASE WHEN i.auto_tags IS NULL OR i.auto_tags = 'a:0:{}' THEN 1 ELSE 0 END)) AS weighted_problem_score")
68
            ->addGroupBy('w')
69
            ->having('no_title > 0')
70
            ->orHaving('no_latlng > 0')
71
            ->orHaving('no_location > 0')
72
            ->orHaving('no_keywords > 0')
73
            ->orHaving('no_auto_tags > 0')
74
            ->orderBy('weighted_problem_score', 'desc')
75
            ->getQuery()
76
            ->getResult();
77
78
        $orphans = $imageRepository->findWithNoWander();
79
80
        return $this->render('/admin/problems/index.html.twig', [
81
            'problems' => $problems,
82
            'orphans' => $orphans,
83
            'built_problems' => $builtProblems
84
        ]);
85
    }
86
87
    /**
88
     * @Route("/regenerate", name="regenerate", methods={"POST"})
89
     */
90
    public function regenerateProblems(Request $request, ProblemService $problemService): Response
91
    {
92
        if ($this->isCsrfTokenValid('problems_regenerate', $request->request->get('_token'))) {
93
            $problemService->createProblemReport();
94
        }
95
96
        return $this->redirectToRoute('admin_problems_index');
97
    }
98
99
100
    // TODO: These all share a lot of things in common, but I'm not sure
101
    // how much this is going to get used, so I'm keeping it fairly brain-dead
102
    // for now. Revisit later.
103
104
    /**
105
     * @Route("/no_title/wander/{id}", name="no_title", methods={"GET"})
106
     */
107
    public function noTitle(Wander $wander): Response {
108
        return $this->render('/admin/problems/no_title.html.twig', [
109
            'wander' => $wander
110
        ]);
111
    }
112
    /**
113
     * @Route("/no_latlng/wander/{id}", name="no_latlng", methods={"GET"})
114
     */
115
    public function noLatlng(Wander $wander): Response {
116
        return $this->render('/admin/problems/no_latlng.html.twig', [
117
            'wander' => $wander
118
        ]);
119
    }
120
    /**
121
     * @Route("/no_location/wander/{id}", name="no_location", methods={"GET"})
122
     */
123
    public function noLocation(Wander $wander): Response {
124
        return $this->render('/admin/problems/no_location.html.twig', [
125
            'wander' => $wander
126
        ]);
127
    }
128
    /**
129
     * @Route("/no_rating/wander/{id}", name="no_rating", methods={"GET"})
130
     */
131
    public function noRating(Wander $wander): Response {
132
        return $this->render('/admin/problems/no_rating.html.twig', [
133
            'wander' => $wander
134
        ]);
135
    }
136
137
    /**
138
     * @Route("/broken_links", name="broken_links", methods={"GET"})
139
     */
140
    public function brokenLinks(ProblemRepository $problemRepository): Response {
141
        $problems = $problemRepository->findAll();
142
        return $this->render('/admin/problems/broken_links.html.twig', [
143
            'problems' => $problems
144
        ]);
145
    }
146
147
148
}
149