@@ -14,6 +14,72 @@ use Nether\User;
1414////////////////////////////////////////////////////////////////
1515////////////////////////////////////////////////////////////////
1616
17+ class TrafficReport1
18+ extends Common\Prototype {
19+
20+ public string
21+ $ReportStart;
22+
23+ public string
24+ $ReportStop;
25+
26+ public string
27+ $Domain;
28+
29+ public int
30+ $TrafficTotal;
31+
32+ public int
33+ $VisitorUnique;
34+
35+ public float
36+ $VisitorAveragePageView;
37+
38+ public function
39+ ToArray():
40+ array {
41+
42+ $Data = [
43+ $this->ReportStart, $this->ReportStop, $this->Domain,
44+ $this->TrafficTotal, $this->VisitorUnique, $this->VisitorAveragePageView
45+ ];
46+
47+ return $Data;
48+ }
49+
50+ public function
51+ ToHeaders():
52+ array {
53+
54+ $Data = [
55+ 'ReportStart', 'ReportStop', 'Domain',
56+ 'TrafficTotal', 'VisitorUnique', 'VisitorAveragePageView'
57+ ];
58+
59+ return $Data;
60+ }
61+
62+ public function
63+ ToData():
64+ array {
65+
66+ return array_combine($this->ToHeaders(), $this->ToArray());
67+ }
68+
69+ public function
70+ ToCSV():
71+ string {
72+
73+ $Data = $this->ToArray();
74+
75+ return join(',', $Data);
76+ }
77+
78+ };
79+
80+ ////////////////////////////////////////////////////////////////
81+ ////////////////////////////////////////////////////////////////
82+
1783class TrafficTool
1884extends Atlantis\TerminalApp {
1985
@@ -185,6 +251,119 @@ extends Atlantis\TerminalApp {
185251 return 0;
186252 }
187253
254+ #[Console\Meta\Command('report1')]
255+ public function
256+ HandleReportV1():
257+ int {
258+
259+ // very rough draft implementation of the query i been manually running
260+ // in my sql client for years.
261+
262+ $Format = 'human';
263+
264+ if($this->GetOption('csv'))
265+ $Format = 'csv';
266+
267+ ////////
268+
269+ if($this->GetOption('month')) {
270+ if(!preg_match('/^\d{4}-\d{2}$/', $this->GetOption('month')))
271+ throw new Common\Error\FormatInvalid('--month=YYYY-MM');
272+
273+ $Today = Common\Date::FromDateString(sprintf('%s-01', $this->GetOption('month')));
274+ } else {
275+ $Today = Common\Date::FromDateString('now');
276+ }
277+
278+ $CurrentYear = $Today->Get('Y');
279+ $CurrentMonth = $Today->Get('m');
280+ $CurrentMonthEnd = $Today->Get('t');
281+
282+ $DateStart = sprintf(
283+ '%s-%s-01 00:00:00',
284+ $CurrentYear,
285+ $CurrentMonth
286+ );
287+
288+ $DateStop = sprintf(
289+ '%s-%s-%s 23:59:59',
290+ $CurrentYear,
291+ $CurrentMonth,
292+ $CurrentMonthEnd
293+ );
294+
295+ $DB = $this->App->Database->Get('Default');
296+ $Result = NULL;
297+ $Query = NULL;
298+ $Row = NULL;
299+ $Data = new Common\Datastore;
300+
301+ ////////
302+
303+ $DB->Query("BEGIN TRANSACTION;");
304+ $DB->Query("SET @TimeStart = UNIX_TIMESTAMP('{$DateStart}');");
305+ $DB->Query("SET @TimeStop = UNIX_TIMESTAMP('{$DateStop}');");
306+
307+ $Query = "
308+ SELECT
309+ FROM_UNIXTIME(@TimeStart) AS ReportStart,
310+ FROM_UNIXTIME(@TimeStop) AS ReportStop,
311+ TrafficTotal.Domain AS Domain,
312+ TrafficTotal.Hits AS TrafficTotal,
313+ UniqueVisitors.Hits AS VisitorUnique,
314+ (TrafficTotal.Hits / UniqueVisitors.Hits) AS VisitorAveragePageView
315+
316+ FROM
317+ (SELECT Domain, COUNT(*) AS Hits
318+ FROM TrafficRows WHERE (TimeCreated >= @TimeStart AND TimeCreated < @TimeStop)
319+ GROUP BY Domain) TrafficTotal
320+
321+ LEFT JOIN
322+ (SELECT Domain, COUNT(*) AS Hits FROM (
323+ SELECT Visitor, Domain, COUNT(*) AS Visits
324+ FROM TrafficRows
325+ WHERE (TimeCreated >= @TimeStart AND TimeCreated < @TimeStop)
326+ GROUP BY Visitor, Domain
327+ ) Q1 GROUP BY Q1.Domain) UniqueVisitors
328+ ON
329+ TrafficTotal.Domain=UniqueVisitors.Domain
330+
331+ ORDER BY Domain;
332+ ";
333+
334+ $DB->Query($Query);
335+ $DB->Query('COMMIT TRANSACTION');
336+
337+ $Result = $DB->Query($Query);
338+
339+ while($Row = $Result->Next()) {
340+ $Data->Push(new TrafficReport1($Row));
341+ continue;
342+ }
343+
344+ if(!$Data->Count()) {
345+ $this->PrintStatusWarning(sprintf('No data for %s to %s', $DateStart, $DateStop));
346+ return 0;
347+ }
348+
349+ if($Format === 'csv') {
350+ echo join(',', $Data[0]->ToHeaders()), PHP_EOL;
351+
352+ $Data->Each(
353+ fn($D)=> printf('%s%s', $D->ToCSV(), PHP_EOL)
354+ );
355+ }
356+
357+ else
358+ Console\Elements\Table::New(
359+ Client: $this,
360+ Headers: $Data[0]->ToHeaders(),
361+ Rows: $Data->Map(fn($D)=> $D->ToArray()),
362+ Print: 2
363+ );
364+
365+ return 0;
366+ }
188367
189368}
190369
0 commit comments