BioTorrents.de’s version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

users.php 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <?php
  2. if (!list($Countries, $Rank, $CountryUsers, $CountryMax, $CountryMin, $LogIncrements) = $Cache->get_value('geodistribution')) {
  3. $DB->query('
  4. SELECT Code, Users
  5. FROM users_geodistribution');
  6. $Data = $DB->to_array();
  7. $Count = $DB->record_count() - 1;
  8. $CountryMinThreshold = Min($Count, 30);
  9. $CountryMax = ceil(log(Max(1, $Data[0][1])) / log(2)) + 1;
  10. $CountryMin = floor(log(Max(1, $Data[$CountryMinThreshold][1])) / log(2));
  11. $CountryRegions = array('RS' => array('RS-KM')); // Count Kosovo as Serbia as it doesn't have a TLD
  12. foreach ($Data as $Key => $Item) {
  13. list($Country, $UserCount) = $Item;
  14. $Countries[] = $Country;
  15. $CountryUsers[] = number_format((((log($UserCount) / log(2)) - $CountryMin) / ($CountryMax - $CountryMin)) * 100, 2);
  16. $Rank[] = round((1 - ($Key / $Count)) * 100);
  17. if (isset($CountryRegions[$Country])) {
  18. foreach ($CountryRegions[$Country] as $Region) {
  19. $Countries[] = $Region;
  20. $Rank[] = end($Rank);
  21. }
  22. }
  23. }
  24. reset($Rank);
  25. for ($i = $CountryMin; $i <= $CountryMax; $i++) {
  26. $LogIncrements[] = Format::human_format(pow(2, $i));
  27. }
  28. $Cache->cache_value('geodistribution', array($Countries, $Rank, $CountryUsers, $CountryMax, $CountryMin, $LogIncrements), 0);
  29. }
  30. if (!$ClassDistribution = $Cache->get_value('class_distribution')) {
  31. $DB->query("
  32. SELECT p.Name, COUNT(m.ID) AS Users
  33. FROM users_main AS m
  34. JOIN permissions AS p ON m.PermissionID = p.ID
  35. WHERE m.Enabled = '1'
  36. GROUP BY p.Name
  37. ORDER BY Users DESC");
  38. $ClassDistribution = $DB->to_array();
  39. $Cache->cache_value('class_distribution', $ClassDistribution, 3600 * 24 * 14);
  40. }
  41. if (!$PlatformDistribution = $Cache->get_value('platform_distribution')) {
  42. $DB->query("
  43. SELECT OperatingSystem, COUNT(DISTINCT UserID) AS Users
  44. FROM users_sessions
  45. GROUP BY OperatingSystem
  46. ORDER BY Users DESC");
  47. $PlatformDistribution = $DB->to_array();
  48. $Cache->cache_value('platform_distribution', $PlatformDistribution, 3600 * 24 * 14);
  49. }
  50. if (!$BrowserDistribution = $Cache->get_value('browser_distribution')) {
  51. $DB->query("
  52. SELECT Browser, COUNT(DISTINCT UserID) AS Users
  53. FROM users_sessions
  54. GROUP BY Browser
  55. ORDER BY Users DESC");
  56. $BrowserDistribution = $DB->to_array();
  57. $Cache->cache_value('browser_distribution', $BrowserDistribution, 3600 * 24 * 14);
  58. }
  59. // Timeline generation
  60. if (!list($Labels, $InFlow, $OutFlow) = $Cache->get_value('users_timeline')) {
  61. $DB->query("
  62. SELECT DATE_FORMAT(JoinDate,\"%b %Y\") AS Month, COUNT(UserID)
  63. FROM users_info
  64. GROUP BY Month
  65. ORDER BY JoinDate DESC
  66. LIMIT 1, 11");
  67. $TimelineIn = array_reverse($DB->to_array());
  68. $DB->query("
  69. SELECT DATE_FORMAT(BanDate,\"%b %Y\") AS Month, COUNT(UserID)
  70. FROM users_info
  71. WHERE BanDate > 0
  72. GROUP BY Month
  73. ORDER BY BanDate DESC
  74. LIMIT 1, 11");
  75. $TimelineOut = array_reverse($DB->to_array());
  76. $Labels = [];
  77. foreach ($TimelineIn as $Month) {
  78. list($Labels[], $InFlow[]) = $Month;
  79. }
  80. foreach ($TimelineOut as $Month) {
  81. list(, $OutFlow[]) = $Month;
  82. }
  83. $Cache->cache_value('users_timeline', array($Labels, $InFlow, $OutFlow), mktime(0, 0, 0, date('n') + 1, 2)); //Tested: fine for Dec -> Jan
  84. }
  85. // End timeline generation
  86. View::show_header('User Statistics', $JSIncludes = 'vendor/chart.min');
  87. ?>
  88. <h2 class="header">
  89. User Stats
  90. </h2>
  91. <h3>
  92. Flow
  93. </h3>
  94. <div class="box pad center">
  95. <canvas class="chart" id="chart_user_timeline"></canvas>
  96. <script>
  97. var ctx = document.getElementById('chart_user_timeline').getContext('2d');
  98. var myChart = new Chart(ctx, {
  99. type: 'line',
  100. data: {
  101. labels: <?= ' ["'.implode('","', $Labels).'"]'; ?> ,
  102. datasets: [{
  103. label: 'New Registrations',
  104. backgroundColor: 'rgba(179, 229, 252, 0.8)', // #B3E5FC
  105. borderColor: 'rgba(1, 87, 155, 0.8)', // #01579B
  106. data:
  107. <?= "[".implode(",", $InFlow)."]"; ?>
  108. },
  109. {
  110. label: 'Disabled Users',
  111. backgroundColor: 'rgba(255, 224, 178, 0.8)', // #FFE0B2
  112. borderColor: 'rgba(230, 81, 0, 0.8)', // #E65100
  113. data:
  114. <?= "[".implode(",", $OutFlow)."]"; ?>
  115. }
  116. ]
  117. }
  118. });
  119. </script>
  120. </div>
  121. <h3>
  122. Classes
  123. </h3>
  124. <div class="box pad center">
  125. <canvas class="chart" id="chart_user_classes"></canvas>
  126. <script>
  127. var ctx = document.getElementById('chart_user_classes').getContext('2d');
  128. var myChart = new Chart(ctx, {
  129. type: 'pie',
  130. data: {
  131. labels: <?= ' ["'.implode('","', array_column($ClassDistribution, 'Name')).'"]'; ?> ,
  132. datasets: [{
  133. data:
  134. <?= "[".implode(",", array_column($ClassDistribution, 'Users'))."]"; ?>
  135. ,
  136. backgroundColor: [
  137. 'rgba(241, 248, 233, 0.8)', // #F1F8E9
  138. 'rgba(220, 237, 200, 0.8)', // #DCEDC8
  139. 'rgba(197, 225, 165, 0.8)', // #C5E1A5
  140. 'rgba(174, 213, 129, 0.8)', // #AED581
  141. 'rgba(156, 204, 101, 0.8)', // #9CCC65
  142. 'rgba(139, 195, 74, 0.8)', // #8BC34A
  143. 'rgba(124, 179, 66, 0.8)', // #7CB342
  144. 'rgba(104, 159, 56, 0.8)', // #689F38
  145. 'rgba(85, 139, 47, 0.8)', // #558B2F
  146. 'rgba(51, 105, 30, 0.8)', // #33691E
  147. ]
  148. }]
  149. }
  150. });
  151. </script>
  152. </div>
  153. <h3>
  154. Platforms
  155. </h3>
  156. <div class="box pad center">
  157. <?php
  158. $AllPlatforms = array_column($PlatformDistribution, 'OperatingSystem');
  159. $SlicedPlatforms = (count($AllPlatforms) > 14) ? array_slice($AllPlatforms, 0, 13)+[13=>'Other'] : $AllPlatforms;
  160. $AllUsers = array_column($PlatformDistribution, 'Users');
  161. $SlicedUsers = (count($AllUsers) > 14) ? array_slice($AllUsers, 0, 13)+[13=>array_sum(array_slice($AllUsers, 13))] : $AllUsers;
  162. ?>
  163. <canvas class="chart" id="chart_user_platforms"></canvas>
  164. <script>
  165. var ctx = document.getElementById('chart_user_platforms').getContext('2d');
  166. var myChart = new Chart(ctx, {
  167. type: 'pie',
  168. data: {
  169. labels: [
  170. "<?=implode('","', $AllPlatforms)?>"
  171. ],
  172. datasets: [{
  173. data: [ <?=implode(",", $AllUsers)?> ],
  174. backgroundColor: [
  175. 'rgba(255, 205, 210, 0.8)', // #FFCDD2
  176. 'rgba(225, 190, 231, 0.8)', // #E1BEE7
  177. 'rgba(197, 202, 233, 0.8)', // #C5CAE9
  178. 'rgba(179, 229, 252, 0.8)', // #B3E5FC
  179. 'rgba(178, 223, 219, 0.8)', // #B2DFDB
  180. 'rgba(220, 237, 200, 0.8)', // #DCEDC8
  181. 'rgba(255, 249, 196, 0.8)', // #FFF9C4
  182. 'rgba(255, 224, 178, 0.8)', // #FFE0B2
  183. 'rgba(215, 204, 200, 0.8)', // #D7CCC8
  184. 'rgba(207, 216, 220, 0.8)', // #CFD8DC
  185. 'rgba(158, 158, 158, 0.8)', // #9E9E9E
  186. ]
  187. }]
  188. }
  189. });
  190. </script>
  191. </div>
  192. <h3>
  193. Browsers
  194. </h3>
  195. <div class="box pad center">
  196. <?php
  197. $AllBrowsers = array_column($BrowserDistribution, 'Browser');
  198. $SlicedBrowsers = (count($AllBrowsers) > 7) ? array_slice($AllBrowsers, 0, 6)+[6=>'Other'] : $AllBrowsers;
  199. $AllUsers = array_column($BrowserDistribution, 'Users');
  200. $SlicedUsers = (count($AllUsers) > 7) ? array_slice($AllUsers, 0, 6)+[6=>array_sum(array_slice($AllUsers, 6))] : $AllUsers;
  201. ?>
  202. <canvas class="chart" id="chart_user_browsers"></canvas>
  203. <script>
  204. var ctx = document.getElementById('chart_user_browsers').getContext('2d');
  205. var myChart = new Chart(ctx, {
  206. type: 'pie',
  207. data: {
  208. labels: [
  209. "<?=implode('","', $AllBrowsers)?>"
  210. ],
  211. datasets: [{
  212. data: [ <?=implode(",", $AllUsers)?> ],
  213. backgroundColor: [
  214. 'rgba(158, 158, 158, 0.8)', // #9E9E9E
  215. 'rgba(207, 216, 220, 0.8)', // #CFD8DC
  216. 'rgba(215, 204, 200, 0.8)', // #D7CCC8
  217. 'rgba(255, 224, 178, 0.8)', // #FFE0B2
  218. 'rgba(255, 249, 196, 0.8)', // #FFF9C4
  219. 'rgba(220, 237, 200, 0.8)', // #DCEDC8
  220. 'rgba(178, 223, 219, 0.8)', // #B2DFDB
  221. 'rgba(179, 229, 252, 0.8)', // #B3E5FC
  222. 'rgba(197, 202, 233, 0.8)', // #C5CAE9
  223. 'rgba(225, 190, 231, 0.8)', // #E1BEE7
  224. 'rgba(255, 205, 210, 0.8)', // #FFCDD2
  225. ]
  226. }]
  227. }
  228. });
  229. </script>
  230. </div>
  231. <?php View::show_footer();