1<?php
2
3/**
4 * Class helper_plugin_loglog_report
5 */
6class helper_plugin_loglog_report extends DokuWiki_Plugin
7{
8    /**
9     * @var \helper_plugin_loglog_main
10     */
11    protected $mainHelper;
12
13    /**
14     * @var \helper_plugin_loglog_logging
15     */
16    protected $logHelper;
17
18    public function __construct()
19    {
20        $this->mainHelper = $this->loadHelper('loglog_main');
21        $this->logHelper = $this->loadHelper('loglog_logging');
22    }
23
24    /**
25     * Checks if the report has already been sent this month. If not, creates and
26     * sends the report, and records this action in the log.
27     */
28    public function handleReport()
29    {
30        $email = $this->getConf('report_email');
31        if (!$email) return;
32
33        // calculate cutoff dates
34        $lastMonthStart = mktime(0, 0, 0, date('n', strtotime('last month')), 1);
35        $currentMonthStart = mktime(0, 0, 0, date('n'), 1);
36
37        // check if the report is due
38        global $conf;
39        $statfile = $conf['cachedir'] . '/loglog.stat';
40        if (is_file($statfile) && filemtime($statfile) >= $currentMonthStart) {
41            return;
42        }
43
44        // calculate stat
45        $monthLines = $this->logHelper->readLines($lastMonthStart, $currentMonthStart);
46        $stats = $this->getStats($monthLines);
47
48        // email the report
49        $template = $this->localFN('report');
50        $text = file_get_contents($template);
51        // format access to admin pages
52        $adminPages = implode(
53            "\n",
54            array_map(
55                function ($page, $cnt) {
56                    return "  - $page: $cnt";
57                },
58                array_keys($stats['admin']),
59                $stats['admin']
60            )
61        );
62
63        $text = str_replace(
64            ['@@auth_ok@@', '@@auth_fail@@', '@@users@@', '@@admin_pages@@'],
65            [$stats['auth_success'], $stats['auth_failed'], $stats['users'], $adminPages],
66            $text
67        );
68
69        if (
70            $this->mainHelper->sendEmail(
71                $email,
72                $this->getLang('email_report_subject'),
73                $text
74            )
75        ) {
76            // log itself
77            $this->logHelper->writeLine('loglog - report', 'cron');
78            // touch statfile
79            touch($statfile);
80        }
81    }
82
83    /**
84     * Go through supplied log lines and aggregate basic activity statistics
85     *
86     * @param array $lines
87     * @return array
88     */
89    public function getStats(array $lines)
90    {
91        $authOk = 0;
92        $authFail = 0;
93        $users = [];
94        $pages = ['start' => 0];
95
96        foreach ($lines as $line) {
97            if (
98                strpos(
99                    $line['msg'],
100                    $this->mainHelper->getNotificationString(\helper_plugin_loglog_main::LOGTYPE_AUTH_OK, 'msgNeedle')
101                ) !== false
102            ) {
103                $authOk++;
104                if ($line['user']) $users[] = $line['user'];
105            } elseif (
106                strpos(
107                    $line['msg'],
108                    $this->mainHelper->getNotificationString(\helper_plugin_loglog_main::LOGTYPE_AUTH_FAIL, 'msgNeedle')
109                ) !== false
110            ) {
111                $authFail++;
112            } elseif (strpos($line['msg'], 'admin') !== false) {
113                list($action, $page) = explode(' - ', $line['msg']);
114                if ($page) {
115                    $pages[$page] = !isset($pages[$page]) ? 1 : $pages[$page] + 1;
116                } else {
117                    $pages['start']++;
118                }
119            }
120        }
121
122        return [
123            \helper_plugin_loglog_main::LOGTYPE_AUTH_OK => $authOk,
124            \helper_plugin_loglog_main::LOGTYPE_AUTH_FAIL => $authFail,
125            'users' => count(array_unique($users)),
126            'admin' => $pages
127        ];
128    }
129}
130