telemetry_db.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. <?php
  2. require_once 'idObfuscation.php';
  3. define('TELEMETRY_SETTINGS_FILE', 'telemetry_settings.php');
  4. /**
  5. * @return PDO|false
  6. */
  7. function getPdo($returnErrorMessage = false)
  8. {
  9. if (
  10. !file_exists(TELEMETRY_SETTINGS_FILE)
  11. || !is_readable(TELEMETRY_SETTINGS_FILE)
  12. ) {
  13. if($returnErrorMessage){
  14. return 'missing TELEMETRY_SETTINGS_FILE';
  15. }
  16. return false;
  17. }
  18. require TELEMETRY_SETTINGS_FILE;
  19. if (!isset($db_type)) {
  20. if($returnErrorMessage){
  21. return "db_type not set in '" . TELEMETRY_SETTINGS_FILE . "'";
  22. }
  23. return false;
  24. }
  25. $pdoOptions = [
  26. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
  27. ];
  28. try {
  29. if ('mssql' === $db_type) {
  30. if (!isset(
  31. $MsSql_server,
  32. $MsSql_databasename,
  33. $MsSql_WindowsAuthentication
  34. )) {
  35. if($returnErrorMessage){
  36. return "Required MSSQL database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
  37. }
  38. return false;
  39. }
  40. if (!$MsSql_WindowsAuthentication and
  41. !isset(
  42. $MsSql_username,
  43. $MsSql_password
  44. )
  45. ) {
  46. if($returnErrorMessage){
  47. return "Required MSSQL database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
  48. }
  49. return false;
  50. }
  51. $dsn = 'sqlsrv:'
  52. .'server='.$MsSql_server
  53. .';Database='.$MsSql_databasename;
  54. if($MsSql_TrustServerCertificate === true){
  55. $dsn = $dsn . ';TrustServerCertificate=1';
  56. }
  57. if($MsSql_TrustServerCertificate === false){
  58. $dsn = $dsn . ';TrustServerCertificate=0';
  59. }
  60. if($MsSql_WindowsAuthentication){
  61. return new PDO($dsn, "", "", $pdoOptions);
  62. } else {
  63. return new PDO($dsn, $MySql_username, $MySql_password, $pdoOptions);
  64. }
  65. }
  66. if ('mysql' === $db_type) {
  67. if (!isset(
  68. $MySql_hostname,
  69. $MySql_port,
  70. $MySql_databasename,
  71. $MySql_username,
  72. $MySql_password
  73. )) {
  74. if($returnErrorMessage){
  75. return "Required mysql database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
  76. }
  77. return false;
  78. }
  79. $dsn = 'mysql:'
  80. .'host='.$MySql_hostname
  81. .';port='.$MySql_port
  82. .';dbname='.$MySql_databasename;
  83. return new PDO($dsn, $MySql_username, $MySql_password, $pdoOptions);
  84. }
  85. if ('sqlite' === $db_type) {
  86. if (!isset($Sqlite_db_file)) {
  87. if($returnErrorMessage){
  88. return "Required sqlite database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
  89. }
  90. return false;
  91. }
  92. $pdo = new PDO('sqlite:'.$Sqlite_db_file, null, null, $pdoOptions);
  93. # TODO: Why create table only in sqlite mode?
  94. $pdo->exec('
  95. CREATE TABLE IF NOT EXISTS `speedtest_users` (
  96. `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  97. `ispinfo` text,
  98. `extra` text,
  99. `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  100. `ip` text NOT NULL,
  101. `ua` text NOT NULL,
  102. `lang` text NOT NULL,
  103. `dl` text,
  104. `ul` text,
  105. `ping` text,
  106. `jitter` text,
  107. `log` longtext
  108. );
  109. ');
  110. return $pdo;
  111. }
  112. if ('postgresql' === $db_type) {
  113. if (!isset(
  114. $PostgreSql_hostname,
  115. $PostgreSql_databasename,
  116. $PostgreSql_username,
  117. $PostgreSql_password
  118. )) {
  119. if($returnErrorMessage){
  120. return "Required postgresql database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
  121. }
  122. return false;
  123. }
  124. $dsn = 'pgsql:'
  125. .'host='.$PostgreSql_hostname
  126. .';dbname='.$PostgreSql_databasename;
  127. return new PDO($dsn, $PostgreSql_username, $PostgreSql_password, $pdoOptions);
  128. }
  129. } catch (Exception $e) {
  130. if($returnErrorMessage){
  131. return $e->getMessage();
  132. }
  133. return false;
  134. }
  135. if($returnErrorMessage){
  136. return "db_type '" . $db_type . "' not supported";
  137. }
  138. return false;
  139. }
  140. /**
  141. * @return bool
  142. */
  143. function isObfuscationEnabled()
  144. {
  145. require TELEMETRY_SETTINGS_FILE;
  146. return
  147. isset($enable_id_obfuscation)
  148. && true === $enable_id_obfuscation;
  149. }
  150. /**
  151. * @return string|false returns the id of the inserted column or false on error if returnErrorMessage is false or a error message if returnErrorMessage is true
  152. */
  153. function insertSpeedtestUser($ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping, $jitter, $log, $returnExceptionOnError = false)
  154. {
  155. $pdo = getPdo();
  156. if (!($pdo instanceof PDO)) {
  157. if($returnExceptionOnError){
  158. return new Exception("Failed to get database connection object");
  159. }
  160. return false;
  161. }
  162. try {
  163. $stmt = $pdo->prepare(
  164. 'INSERT INTO speedtest_users
  165. (ip,ispinfo,extra,ua,lang,dl,ul,ping,jitter,log)
  166. VALUES (?,?,?,?,?,?,?,?,?,?)'
  167. );
  168. $stmt->execute([
  169. $ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping, $jitter, $log
  170. ]);
  171. $id = $pdo->lastInsertId();
  172. } catch (Exception $e) {
  173. if($returnExceptionOnError){
  174. return $e;
  175. }
  176. return false;
  177. }
  178. if (isObfuscationEnabled()) {
  179. return obfuscateId($id);
  180. }
  181. return $id;
  182. }
  183. /**
  184. * @param int|string $id
  185. *
  186. * @return array|null|false|exception returns the speedtest data as array, null
  187. * if no data is found for the given id or
  188. * false or an exception if there was an error (based on returnExceptionOnError)
  189. *
  190. * @throws RuntimeException
  191. */
  192. function getSpeedtestUserById($id,$returnExceptionOnError = false)
  193. {
  194. $pdo = getPdo();
  195. if (!($pdo instanceof PDO)) {
  196. if($returnExceptionOnError){
  197. return new Exception("Failed to get database connection object");
  198. }
  199. return false;
  200. }
  201. if (isObfuscationEnabled()) {
  202. $id = deobfuscateId($id);
  203. }
  204. try {
  205. $stmt = $pdo->prepare(
  206. 'SELECT
  207. id, timestamp, ip, ispinfo, ua, lang, dl, ul, ping, jitter, log, extra
  208. FROM speedtest_users
  209. WHERE id = :id'
  210. );
  211. $stmt->bindValue(':id', $id, PDO::PARAM_INT);
  212. $stmt->execute();
  213. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  214. } catch (Exception $e) {
  215. if($returnExceptionOnError){
  216. return $e;
  217. }
  218. return false;
  219. }
  220. if (!is_array($row)) {
  221. return null;
  222. }
  223. $row['id_formatted'] = $row['id'];
  224. if (isObfuscationEnabled()) {
  225. $row['id_formatted'] = obfuscateId($row['id']).' (deobfuscated: '.$row['id'].')';
  226. }
  227. return $row;
  228. }
  229. /**
  230. * @return array|false
  231. */
  232. function getLatestSpeedtestUsers()
  233. {
  234. $pdo = getPdo();
  235. if (!($pdo instanceof PDO)) {
  236. return false;
  237. }
  238. require TELEMETRY_SETTINGS_FILE;
  239. try {
  240. $sql = 'SELECT ';
  241. if('mssql' === $db_type) {$sql .= ' TOP(100) ';}
  242. $sql .= ' id, timestamp, ip, ispinfo, ua, lang, dl, ul, ping, jitter, log, extra
  243. FROM speedtest_users
  244. ORDER BY timestamp DESC ';
  245. if('mssql' !== $db_type) {$sql .= ' LIMIT 100 ';}
  246. $stmt = $pdo->query($sql);
  247. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  248. foreach ($rows as $i => $row) {
  249. $rows[$i]['id_formatted'] = $row['id'];
  250. if (isObfuscationEnabled()) {
  251. $rows[$i]['id_formatted'] = obfuscateId($row['id']).' (deobfuscated: '.$row['id'].')';
  252. }
  253. }
  254. } catch (Exception $e) {
  255. return false;
  256. }
  257. return $rows;
  258. }