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 …</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 …</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}