1<?php 2/** 3 @file nobadbrowser/action.php 4 @brief Warn users of bad browsers. 5 @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 @author Luis Machuca Bezzaza <lambalicious [at] tuta [dot] io> 7**/ 8// must be run within Dokuwiki 9if(!defined('DOKU_INC')) die(); 10if(!defined('DW_LF')) define('DW_LF',"\n"); 11 12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 13define('THIS_PLUGIN', DOKU_PLUGIN.'nobadbrowser/'); 14require_once(DOKU_PLUGIN.'action.php'); 15require_once(DOKU_INC.'inc/confutils.php'); 16require_once(DOKU_INC.'inc/infoutils.php'); // for notify facilities 17 18/** 19 * All DokuWiki plugins to extend the admin function 20 * need to inherit from this class 21 */ 22class action_plugin_nobadbrowser extends DokuWiki_Action_Plugin { 23 24 // detected browser info 25 var $binfo = array(); 26 // the plugin's data object 27 var $cnf= array(); 28 29 function action_plugin_nobadbrowser () { 30 //global $ID; 31 //global $ACT; 32 global $bid; 33 $this->cnf= array(); 34 $this->binfo= []; 35 if (!extension_loaded('browscap')) { 36 $this->binfo= $this->get_browser_local($_SERVER['HTTP_USER_AGENT']); 37 $this->binfo['browscap']= false; 38 msg(<<<EOF 39nobadbrowser notice: This PHP installation seems to lack ''browscap'' support. Results may be inconclusive. 40EOF 41, 2); 42 } else { 43 $this->binfo= get_browser(null, true); 44 $this->binfo['browscap']= true; 45 } 46 $this->binfo['_UA']= $_SERVER['HTTP_USER_AGENT']; 47 //msg(print_r($this->binfo, true), 1); // FOR DEBUG 48 } 49 50 /*** 51 * Register its handlers with the DokuWiki's event controller 52 */ 53 function register (Doku_Event_Handler $controller) { 54 global $ACT; 55 if ($ACT != 'show') return; 56 $controller->register_hook('TPL_CONTENT_DISPLAY','BEFORE', $this, 'warning',array()); 57 } 58 59 60/* 61 rendering options (from getConf) 62 notify -> use the DokuWiki notification message area 63 splash -> use a JS+CSS splash screen (not available in this release) 64*/ 65 function warning (Doku_Event $event, $param) { 66 global $ACT; 67 static $done= false; 68 69 if ($ACT!='show') { 70 return; 71 } 72 if ($this->getConf['debug']) { 73 $this->render_debug($event, $param); 74 } 75 76 if ($this->whybadbrowser()) { 77 $parameter= $this->cnf['parameter']; 78 $reason= $this->cnf['reason']; 79 $see= $this->cnf['see']; 80 $mens = <<<EOF 81You seem to be using a bad browser. \\\\ 82You are at risk because __${parameter}__ is: __${reason}__. 83Visit [[${see}|nobadbrowser @ DokuWiki]] for more details. 84EOF; 85 $outp= p_render('xhtml', p_get_instructions($mens), $info); 86 msg(($outp), -1); 87 } 88 // end function 89 } 90 91 92/** 93 ******************************************************************* 94 * Helper Functions 95 */ 96 97 98 function whybadbrowser () { 99 if (preg_match('/\bIE/', $this->binfo['browser']) && intval($this->binfo['version'])< 10 ) { 100 $this->cnf= array( 101 'parameter' => 'Browser old age', 102 'reason' => $this->binfo['browser'] . " " . $this->binfo['version'] , 103 'see' => 'https://www.dokuwiki.org/plugin:nobadbrowser#internet_explorer' 104 ); 105 return true; 106 } 107 if (preg_match('/\b(Chrome)/', $this->binfo['browser'])) { 108 $this->cnf= array( 109 'reason' => $this->binfo['browser'] , 110 'parameter' => 'Browser', 111 'see' => 'https://www.dokuwiki.org/plugin:nobadbrowser#google_chrome' 112 ); 113 return true; 114 } 115 if (preg_match('/.*Google.*/', $this->binfo['renderingengine_maker']) || $this->binfo['renderingengine_name'] === 'Blink') { 116 $this->cnf= array( 117 'reason' => 'Chrome reskin' , 118 'parameter' => 'Browser type', 119 'see' => 'https://www.dokuwiki.org/plugin:nobadbrowser#google_chrome' 120 ); 121 return true; 122 } 123 if (preg_match('/^Google.*/', $this->binfo['browser_maker'])) { 124 $this->cnf= array( 125 'reason' => $this->binfo['browser_maker'] , 126 'parameter' => 'Browser creator', 127 'see' => 'https://www.dokuwiki.org/plugin:nobadbrowser#google_chrome' 128 ); 129 return true; 130 } 131 if (preg_match('/^Opera/', $this->binfo['browser']) && intval($this->binfo['version'])>12 ) { 132 $this->cnf= [ 133 'reason' => $this->binfo['browser'] . " " . $this->binfo['version'], 134 'parameter' => 'Browser version is a Chrome reskin', 135 'see' => 'https://www.dokuwiki.org/plugin:nobadbrowser#opera' 136 ]; 137 return true; 138 } 139 if (preg_match('/^Safari/', $this->binfo['browser']) || preg_match('/^Apple/', $this->binfo['browser_maker']) ) { 140 $this->cnf= [ 141 'reason' => $this->binfo['browser_maker'] , 142 'parameter' => 'Browser Ecosystem', 143 'see' => 'https://www.dokuwiki.org/plugin:nobadbrowser#apple' 144 ]; 145 return true; 146 } 147 return false; 148 } 149 150 /** 151 * This function is an alternative to get_browser when not available. 152 * It does some parsing of the user agent string to provide acceptable, not necessarily accurate results, focused on returning five primary keys about the browser which are to concern for nobadbrowser : 153 * * browser 154 * * version 155 * * browser_maker 156 * * renderingengine_name 157 * * renderingengine_maker 158 * 159 * Other keys that can also be of interest: 160 * 161 * * renderingengine_version 162 * * parent 163 * 164 * */ 165 function get_browser_local ($user_agent, $return_array=true) { 166 $ret= []; 167 // Internet Explorer 168 if (strpos($user_agent, 'MSIE') !== false) { 169 $ret['browser']= 'IE'; 170 $ret['browser_maker']= 'Microsoft Corporation'; 171 if (preg_match ('#MSIE ([0-9\.]+);#', $user_agent, $browserversion) ) { 172 $ret['version']= $browserversion[1]; 173 $ver= explode('.', $browserversion[1], 3); 174 list($ret['majorver'], $ret['minorver'])= $ver; 175 $ret['parent']= $ret['browser']. ' ' . $ret['majorver']; 176 } 177 $ret['renderingengine_name']= 'Trident'; 178 $ret['renderingengine_maker']= 'Microsoft Corporation'; 179 if (preg_match ('#Trident/([0-9\.]+)#', $user_agent, $rendererversion) ) { 180 $ret['renderingengine_version']= $rendererversion[1]; 181 } 182 } 183 // Google Chrome and its various derivations 184 if (preg_match_all( 185 '#AppleWebKit/[0-9\.]+.*\(.*KHTML.*like.*Gecko.*\) Chrome/([0-9]+\.[0-9]+).+Safari/[0-9\.]+\b(.*)$#' 186 , $user_agent, $chrome_info) ) { 187 $ret['browser']= 'Chrome'; 188 $ret['browser_maker']= 'Google Inc'; 189 $ret['version']= $chrome_info[1][0]; 190 $ret['parent']= 'Chrome'; 191 $ret['variants']= $chrome_info[2]; 192 $variants= trim($chrome_info[2]); 193 $variants= explode(' ', $variants); 194 //$ret['variant_match']= $chrome_info[2][0]; 195 if (count($variants) > 0 && (isset($variants[0]) ) && ($variants[0] != '') ) { 196 //$ret['variant']= 1; 197 $variant= explode('/', $variants[0]); 198 $variantname= trim($variant[0]); 199 $variantmaker= $ret['browser_maker']; 200 if ($variantname=='Edg') { $variantname= 'Edge'; } 201 else if ($variantname=='OPR') { $variantname= 'Opera'; $variantmaker= 'Opera Software ASA'; } 202 $variantversion= explode('.', $variant[1],3); 203 $variantversion= $variantversion[0].'.'.$variantversion[1]; 204 $ret['variant_found']= [ $variantname, $variantversion]; 205 $ret['browser']= $variantname; 206 $ret['version']= $variantversion; 207 $ret['browser_maker']= $variantmaker; 208 } 209 //list($ret['majorver'], $ret['minorver'])= explode('.', $chrome_info[1],3); 210 $ret['renderingengine_name']= 'Blink'; 211 $ret['renderingengine_maker']= 'Google Inc'; 212 $ret['renderingengine_version']= ''; 213 } 214 // Safari 215 if (preg_match_all( 216 '#AppleWebKit/[0-9\.]+.*\(.*KHTML.*like.*Gecko.*\) Version/([0-9]+\.[0-9]+).*Safari/([0-9]+\.[0-9]+).*#' 217 , $user_agent, $safari_info) ) { 218 $ret['browser']= 'Safari'; 219 $ret['browser_maker']= 'Apple Inc'; 220 $ret['version']= $safari_info[1][0]; 221 $ret['renderingengine_name']= 'WebKit'; 222 $ret['renderingengine_maker']= 'Apple Inc'; 223 $ret['renderingengine_version']= ''; 224 } 225 // Firefox and its variants 226 if (preg_match_all( 227 '#^Mozilla/[0-9\.]+.*Gecko/[0-9]+.+Firefox/([0-9]+\.[0-9]+).*$#' 228 , $user_agent, $firefox_info) ) { 229 $ret['browser']= 'Firefox'; 230 $ret['browser_maker']= 'Mozilla Foundation'; 231 $ret['version']= $firefox_info[1][0]; 232 $rendererversion= $ret['version']; 233 $ret['renderingengine_name']= 'Gecko'; 234 $ret['renderingengine_maker']= 'Mozilla Foundation'; 235 $ret['renderingengine_version']= $rendererversion; 236 } 237 return $ret; 238 } 239 240 function render_debug (Doku_Event $event, $param) { 241 $arr= array( 242 'browser' => $this->binfo['browser'] , 243 'browser_maker' => $this->binfo['browser_maker'] , 244 ); 245 $x = print_r($this->binfo, true); 246 $out= '<pre>'. htmlspecialchars($x). '</pre>'; 247 msg($out,-1); 248 } 249 250} 251