Completed
Push — master ( 2f69eb...4c50f1 )
by Mathieu
02:37
created

TopSearchWidget::setStartDate()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 17
Code Lines 11

Duplication

Lines 17
Ratio 100 %

Importance

Changes 0
Metric Value
dl 17
loc 17
rs 9.2
c 0
b 0
f 0
cc 4
eloc 11
nc 5
nop 1
1
<?php
2
3
namespace Charcoal\Admin\Widget\Search;
4
5
use \DateTime;
6
use \DateTimeInterface;
7
use \InvalidArgumentException;
8
use \PDO;
9
10
use \Pimple\Container;
11
12
use \Charcoal\Admin\AdminWidget;
13
14
use \Charcoal\Search\SearchLog;
15
16
/**
17
 * Search widget to show the latest searched-for terms and their results.
18
 */
19 View Code Duplication
class TopSearchWidget extends AdminWidget
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in 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...
20
{
21
    /**
22
     * @var DateTimeInterface $startDate
23
     */
24
    private $startDate;
25
26
    /**
27
     * @var DateTimeInterface $endDate
28
     */
29
    private $endDate;
30
31
    private $collectionLoader;
32
    private $topSearches;
33
34
    public function setDependencies(Container $container)
35
    {
36
        parent::setDependencies($container);
37
38
        $this->collectionLoader = $container['model/collection/loader'];
39
    }
40
41
    /**
42
     * @param string|DateTimeInterface|null $date The starting date-time.
43
     * @throws InvalidArgumentException If the date format is not valid.
44
     * @return TopSearchWidget Chainable
45
     */
46
    public function setStartDate($date)
47
    {
48
        if ($date === null) {
49
            $this->startDate = new DateTime('30 days ago');
50
            return $this;
51
        }
52
        if (is_string($date)) {
53
            $date = new DateTime($date);
54
        }
55
        if (!($date instanceof DateTimeInterface)) {
56
            throw new InvalidArgumentException(
57
                'Invalid "Start Date" value. Must be a date/time string or a DateTimeInterface object.'
58
            );
59
        }
60
        $this->startDate = $date;
61
        return $this;
62
    }
63
64
    /**
65
     * @return DateTimeInterface
66
     */
67
    public function startDate()
68
    {
69
        if ($this->startDate === null) {
70
            return new DateTime('30 days ago');
71
        }
72
        return $this->startDate;
73
    }
74
75
    /**
76
     * @param string|DateTimeInterface|null $date The ending date-time.
77
     * @throws InvalidArgumentException If the date format is not valid.
78
     * @return TopSearchWidget Chainable
79
     */
80
    public function setEndDate($date)
81
    {
82
        if ($date === null) {
83
            $this->endDate = new DateTime('now');
84
            return $this;
85
        }
86
        if (is_string($date)) {
87
            $date = new DateTime($date);
88
        }
89
        if (!($date instanceof DateTimeInterface)) {
90
            throw new InvalidArgumentException(
91
                'Invalid "End Date" value. Must be a date/time string or a DateTimeInterface object.'
92
            );
93
        }
94
        $this->endDate = $date;
95
        return $this;
96
    }
97
98
99
    /**
100
     * @return DateTimeInterface
101
     */
102
    public function endDate()
103
    {
104
        if ($this->endDate === null) {
105
            return new DateTime('now');
106
        }
107
        return $this->endDate;
108
    }
109
110
    public function topSearches()
111
    {
112
        if ($this->topSearches === null) {
113
            $this->topSearches = $this->loadTopSearches();
114
        }
115
116
        return $this->topSearches;
117
    }
118
119
    public function hasTopSearches()
120
    {
121
        $topSearches = $this->topSearches();
122
        return (count($topSearches) > 0);
123
    }
124
125
    public function loadTopSearches()
126
    {
127
        $proto = $this->modelFactory()->create(SearchLog::class);
128
        $source = $proto->source();
129
        $table = $source->table();
130
131
        $q = '
132
        SELECT
133
            `keyword`,
134
            COUNT(`keyword`) as num_searches,
135
            SUM(`num_results`) as num_results
136
        FROM
137
            `'.$table.'`
138
        WHERE
139
            `ts` > :start
140
        AND
141
            `ts` <= :end
142
        GROUP BY
143
            `keyword`
144
        ORDER BY
145
            num_searches DESC
146
        LIMIT
147
            20
148
        ';
149
150
        $sth = $source->dbQuery($q, [
151
            'start' =>$this->startDate()->format('Y-m-d H:i:s'),
152
            'end' => $this->endDate()->format('Y-m-d H:i:s')
153
        ]);
154
155
        $results = $sth->fetchAll(PDO::FETCH_ASSOC);
156
        return $results;
157
    }
158
}
159