xref: /plugin/botmon/admin.php (revision fb281ca1a13fb0419ac09220cd216d20c52045d5)
1<?php
2
3use dokuwiki\Extension\AdminPlugin;
4
5/**
6 * Bot Monitoring Plugin
7*
8* @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
9* @author     Sascha Leib <ad@hominem.info>
10*/
11
12/**
13 * All DokuWiki plugins to extend the admin function
14 * need to inherit from this class
15**/
16class admin_plugin_botmon extends AdminPlugin {
17
18	/**
19	 * Return the path to the icon being displayed in the main admin menu.
20	 *
21	 * @return string full path to the icon file
22	**/
23	public function getMenuIcon() {
24		$plugin = $this->getPluginName();
25		return DOKU_PLUGIN . $plugin . '/img/admin.svg';
26	}
27
28	/**
29	 * output appropriate html
30	*/
31	public function html() {
32
33		global $conf;
34
35		// display GeoIP data?
36		$geoIPconf = $this->getConf('geoiplib');
37		$useCaptchaConf = ($this->getConf('useCaptcha') !== 'disabled');
38
39		$hasOldLogFiles = $this->hasOldLogFiles();
40
41		// spinner animation as SVG image:
42		$svg = '<svg width="12" height="12" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" id="botmon__today__busy"><defs><linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#666"></stop><stop offset="100%" stop-color="#666"></stop></linearGradient></defs><circle cx="25" cy="25" r="20" fill="none" stroke="url(#gradient)" stroke-width="8" stroke-dasharray="31.4 31.4"><animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s" repeatCount="indefinite"></animateTransform></circle></svg>';
43
44		$pluginPath = $conf['basedir'] . 'lib/plugins/' . $this->getPluginName();
45
46		/* Plugin Headline */
47		echo NL . '<div id="botmon__admin">
48	<h1>Bot Monitoring Plugin</h1>
49	<nav id="botmon__tabs">
50		<ul class="tabs" role="tablist">
51			<li role="presentation"><a role="tab" href="#botmon__latest" aria-controls="botmon__latest" id="botmon__tab1" aria-selected="true">Latest</a></li>
52			<li role="presentation"><a role="tab" href="#botmon__log" aria-controls="botmon__log" id="botmon__tab3" aria-selected="false">Log</a></li>
53		</ul>
54	</nav>
55	<article role="tabpanel" id="botmon__latest">
56		<script>
57			const BMSettings = {
58				showday: ' . json_encode($this->getConf('showday')) . ',
59				combineNets: ' . json_encode($this->getConf('combineNets')) . ',
60				useCaptcha: ' . json_encode($this->getConf('useCaptcha') !== 'disabled') . '
61			};
62		</script>
63		<h2 class="a11y">Latest data</h2>
64		<header id="botmon__today__title">Loading&nbsp;&hellip;</header>
65		<div id="botmon__today__content">
66			<details id="botmon__today__overview" open>
67				<summary>Bots overview</summary>
68				<div class="botmon_bots_grid" data-geoip="' . $geoIPconf  . '">
69					<dl id="botmon__today__botsvshumans"></dl>
70					<dl id="botmon__botslist"></dl>
71					<dl id="botmon__botips"></dl>
72					<dl id="botmon__botcountries"></dl>
73				</div>
74			</details>
75			<details id="botmon__today__webmetrics">
76				<summary>Humans overview</summary>
77				<div class="botmon_webmetrics_grid" data-geoip="' . $geoIPconf  . '">
78					<dl id="botmon__today__wm_overview"></dl>
79					<dl id="botmon__today__wm_clients"></dl>
80					<dl id="botmon__today__wm_platforms"></dl>
81					<dl id="botmon__today__wm_countries"></dl>
82				</div>
83			</details>
84			<details id="botmon__today__traffic">
85				<summary>Web traffic (humans only)</summary>
86				<div class="botmon_traffic_grid">
87					<dl id="botmon__today__wm_pages"></dl>
88					<dl id="botmon__today__wm_referers"></dl>
89				</div>
90			</details>' . NL;
91		if ($useCaptchaConf) {
92			echo '			<details id="botmon__today__captcha">
93				<summary>Captcha statistics</summary>
94				<div class="botmon_captcha_grid">
95					<dl id="botmon__today__cp_humans"></dl>
96					<dl id="botmon__today__cp_sus"></dl>
97					<dl id="botmon__today__cp_bots"></dl>
98				</div>
99			</details>' . NL;
100		}
101		echo '			<details id="botmon__today__visitors">
102				<summary>Visitor logs</summary>
103				<div id="botmon__today__visitorlists"></div>
104			</details>
105		</div>
106		<footer aria-live="polite">
107			<span>' . $svg . '</span>
108			<span id="botmon__today__status">Initialising&nbsp;&hellip;</span>
109		</footer>
110	</article>
111	<article role="tabpanel" id="botmon__log" hidden>
112		<h2 class="a11y">Process log</h2>
113		<ul id="botmon__loglist">' . NL;
114
115		/* proces old logs */
116		if ($hasOldLogFiles) {
117
118			$helper = $this->loadHelper('botmon', true);
119
120			$helper->cleanup();
121		} else {
122			echo DOKU_TAB . DOKU_TAB . DOKU_TAB . '<li>No files to process.</li>' . NL;
123		}
124
125		echo DOKU_TAB . DOKU_TAB . '</ul>' . NL . DOKU_TAB . '</article>' . NL;
126		echo '</div><!-- End of BotMon Admin Tool -->';
127
128	}
129
130	/**
131	 * Check if there are old log files to be handled
132	 *
133	 * @return bool true if there are old log files, false otherwise
134	 */
135	private function hasOldLogFiles() {
136
137		$today = gmdate('Y-m-d');
138		$yesterday = gmdate('Y-m-d', time() - 86400);
139
140		// scan the log directory and delete all files except for today and yesterday:
141		$dir = scandir(getcwd() . '/lib/plugins/botmon/logs');
142		foreach($dir as $file) {
143			$fName = pathinfo($file, PATHINFO_BASENAME);
144			$bName = strtok($fName, '.');
145
146			if ($bName == '' || $bName == 'logfiles' || $bName == 'empty' || $fName == '.htaccess') {
147				// ignore
148			} else if ($bName == $today || $bName == $yesterday) {
149				// skip
150			} else {
151				return true;
152			}
153		}
154		return false;
155	}
156}