Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
87 / 87 |
|
100.00% |
5 / 5 |
CRAP | |
100.00% |
1 / 1 |
ReportService | |
100.00% |
87 / 87 |
|
100.00% |
5 / 5 |
13 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
referer | |
100.00% |
28 / 28 |
|
100.00% |
1 / 1 |
3 | |||
setReferrersCondition | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
4 | |||
hitDetails | |
100.00% |
31 / 31 |
|
100.00% |
1 / 1 |
4 | |||
addDateFilter | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace Drupal\visitors\Service; |
4 | |
5 | use Drupal\Core\Config\ConfigFactoryInterface; |
6 | use Drupal\Core\Database\Connection; |
7 | use Drupal\Core\Datetime\DateFormatterInterface; |
8 | use Drupal\Core\Entity\EntityTypeManagerInterface; |
9 | use Drupal\Core\Extension\ModuleHandlerInterface; |
10 | use Drupal\Core\Render\RendererInterface; |
11 | use Drupal\Core\StringTranslation\StringTranslationTrait; |
12 | use Drupal\visitors\VisitorsReportInterface; |
13 | use Symfony\Component\HttpFoundation\RequestStack; |
14 | use Drupal\visitors\VisitorsDateRangeInterface; |
15 | |
16 | /** |
17 | * Report data. |
18 | * |
19 | * @package visitors |
20 | */ |
21 | class ReportService implements VisitorsReportInterface { |
22 | use StringTranslationTrait; |
23 | |
24 | /** |
25 | * The database service. |
26 | * |
27 | * @var \Drupal\Core\Database\Connection |
28 | */ |
29 | protected $database; |
30 | |
31 | /** |
32 | * Items per page. |
33 | * |
34 | * @var int |
35 | */ |
36 | protected $itemsPerPage; |
37 | |
38 | /** |
39 | * The page number. |
40 | * |
41 | * @var int |
42 | */ |
43 | protected $page; |
44 | |
45 | /** |
46 | * The first day of week. |
47 | * |
48 | * @var int |
49 | */ |
50 | protected $firstDay; |
51 | |
52 | /** |
53 | * The renderer service. |
54 | * |
55 | * @var \Drupal\Core\Render\RendererInterface |
56 | */ |
57 | protected $renderer; |
58 | |
59 | /** |
60 | * The date service. |
61 | * |
62 | * @var \Drupal\Core\Datetime\DateFormatterInterface |
63 | */ |
64 | protected $date; |
65 | |
66 | /** |
67 | * The entity type manager service. |
68 | * |
69 | * @var \Drupal\Core\Entity\EntityTypeManagerInterface |
70 | */ |
71 | protected $entityTypeManager; |
72 | |
73 | /** |
74 | * The module handler service. |
75 | * |
76 | * @var \Drupal\Core\Extension\ModuleHandlerInterface |
77 | */ |
78 | protected $moduleHandler; |
79 | |
80 | /** |
81 | * The date range service. |
82 | * |
83 | * @var \Drupal\visitors\VisitorsDateRangeInterface |
84 | */ |
85 | protected $dateRange; |
86 | |
87 | /** |
88 | * Database Service Object. |
89 | * |
90 | * @param \Drupal\Core\Database\Connection $database |
91 | * The database service. |
92 | * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory |
93 | * The config factory service. |
94 | * @param \Symfony\Component\HttpFoundation\RequestStack $stack |
95 | * The request stack service. |
96 | * @param \Drupal\Core\Render\RendererInterface $renderer |
97 | * The renderer service. |
98 | * @param \Drupal\Core\Datetime\DateFormatterInterface $date |
99 | * The date service. |
100 | * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager |
101 | * The entity type manager service. |
102 | * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler |
103 | * The module handler service. |
104 | * @param \Drupal\visitors\VisitorsDateRangeInterface $date_range |
105 | * The date range service. |
106 | */ |
107 | public function __construct( |
108 | Connection $database, |
109 | ConfigFactoryInterface $config_factory, |
110 | RequestStack $stack, |
111 | RendererInterface $renderer, |
112 | DateFormatterInterface $date, |
113 | EntityTypeManagerInterface $entity_type_manager, |
114 | ModuleHandlerInterface $module_handler, |
115 | VisitorsDateRangeInterface $date_range, |
116 | ) { |
117 | |
118 | $this->database = $database; |
119 | $this->firstDay = $config_factory->get('system.date')->get('first_day') ?? 0; |
120 | $this->itemsPerPage = $config_factory->get('visitors.config')->get('items_per_page') ?? 10; |
121 | $this->page = $stack->getCurrentRequest()->query->get('page') ?? 0; |
122 | $this->renderer = $renderer; |
123 | $this->date = $date; |
124 | $this->entityTypeManager = $entity_type_manager; |
125 | $this->moduleHandler = $module_handler; |
126 | $this->dateRange = $date_range; |
127 | } |
128 | |
129 | /** |
130 | * {@inheritdoc} |
131 | */ |
132 | public function referer(array $header) { |
133 | /** @var \Drupal\Core\Database\Query\SelectInterface $query */ |
134 | $query = $this->database->select('visitors', 'v') |
135 | ->extend('Drupal\Core\Database\Query\PagerSelectExtender') |
136 | ->extend('Drupal\Core\Database\Query\TableSortExtender'); |
137 | $query->condition('bot', 1, '<>'); |
138 | $query->addExpression('COUNT(*)', 'count'); |
139 | $query->fields('v', ['visitors_referer']); |
140 | $this->addDateFilter($query); |
141 | $query = $this->setReferrersCondition($query); |
142 | $query->condition('visitors_referer', '', '<>'); |
143 | $query->groupBy('visitors_referer'); |
144 | $query->orderByHeader($header); |
145 | $query->limit($this->itemsPerPage); |
146 | |
147 | $count_query = $this->database->select('visitors', 'v'); |
148 | $count_query->condition('bot', 1, '<>'); |
149 | $count_query->condition('visitors_referer', '', '<>'); |
150 | $count_query->addExpression('COUNT(DISTINCT visitors_referer)'); |
151 | $this->addDateFilter($count_query); |
152 | $count_query = $this->setReferrersCondition($count_query); |
153 | $query->setCountQuery($count_query); |
154 | $results = $query->execute(); |
155 | |
156 | $rows = []; |
157 | $i = $this->page * $this->itemsPerPage; |
158 | foreach ($results as $data) { |
159 | |
160 | $rows[] = [ |
161 | empty($data->visitors_referer) ? $this->t('No Referer') : $data->visitors_referer, |
162 | $data->count, |
163 | ]; |
164 | } |
165 | return $rows; |
166 | } |
167 | |
168 | /** |
169 | * Build sql query from referer type value. |
170 | */ |
171 | protected function setReferrersCondition($query) { |
172 | switch ($_SESSION['referer_type']) { |
173 | case VisitorsReportInterface::REFERER_TYPE_INTERNAL_PAGES: |
174 | $query->condition( |
175 | 'visitors_referer', |
176 | sprintf('%%%s%%', $_SERVER['HTTP_HOST']), |
177 | 'LIKE' |
178 | ); |
179 | $query->condition('visitors_referer', '', '<>'); |
180 | break; |
181 | |
182 | case VisitorsReportInterface::REFERER_TYPE_EXTERNAL_PAGES: |
183 | $query->condition( |
184 | 'visitors_referer', |
185 | sprintf('%%%s%%', $_SERVER['HTTP_HOST']), |
186 | 'NOT LIKE' |
187 | ); |
188 | break; |
189 | |
190 | default: |
191 | break; |
192 | } |
193 | |
194 | return $query; |
195 | } |
196 | |
197 | /** |
198 | * {@inheritdoc} |
199 | */ |
200 | public function hitDetails($hit_id) { |
201 | $query = $this->database->select('visitors', 'v'); |
202 | |
203 | $query->fields('v'); |
204 | $query->condition('v.visitors_id', (int) $hit_id); |
205 | /** @var object|false $hit_details */ |
206 | $hit_details = $query->execute()->fetch(); |
207 | |
208 | $rows = []; |
209 | |
210 | if ($hit_details) { |
211 | $url = urldecode($hit_details->visitors_url); |
212 | $referer = $hit_details->visitors_referer; |
213 | $date = $this->date->format($hit_details->visitors_date_time, 'large'); |
214 | $ip = $hit_details->visitors_ip; |
215 | |
216 | $array = [ |
217 | $this->t('URL')->render() => $url, |
218 | $this->t('Title')->render() => ($hit_details->visitors_title ?? ''), |
219 | $this->t('Referer')->render() => $referer, |
220 | $this->t('Date')->render() => $date, |
221 | $this->t('Visitor')->render() => $hit_details->visitor_id, |
222 | $this->t('IP')->render() => $ip, |
223 | $this->t('User Agent')->render() => ($hit_details->visitors_user_agent ?? ''), |
224 | $this->t('Country')->render() => ($hit_details->location_country ?? ''), |
225 | ]; |
226 | |
227 | if ($this->moduleHandler->moduleExists('visitors_geoip')) { |
228 | $geoip_data_array = [ |
229 | $this->t('Region')->render() => ($hit_details->location_region ?? ''), |
230 | $this->t('City')->render() => ($hit_details->location_city ?? ''), |
231 | $this->t('Latitude')->render() => ($hit_details->location_latitude ?? ''), |
232 | $this->t('Longitude')->render() => ($hit_details->location_longitude ?? ''), |
233 | ]; |
234 | $array = array_merge($array, $geoip_data_array); |
235 | } |
236 | |
237 | foreach ($array as $key => $value) { |
238 | $rows[] = [['data' => $key, 'header' => TRUE], $value]; |
239 | } |
240 | } |
241 | |
242 | return $rows; |
243 | } |
244 | |
245 | /** |
246 | * Add date filter to the query. |
247 | * |
248 | * @param \Drupal\Core\Database\Query\SelectInterface $query |
249 | * The query object. |
250 | */ |
251 | protected function addDateFilter(&$query) { |
252 | |
253 | $from = $this->dateRange->getStartTimestamp(); |
254 | $to = $this->dateRange->getEndTimestamp(); |
255 | |
256 | $query->condition('visitors_date_time', [$from, $to], 'BETWEEN'); |
257 | } |
258 | |
259 | } |