Oppaitime'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 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?
  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(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(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 = array();
  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('Detailed User Statistics', 'chart');
  87. ?>
  88. <h3 id="User_Flow"><a href="#User_Flow">User Flow</a></h3>
  89. <div class="box pad center">
  90. <canvas class="chart" id="chart_user_timeline"></canvas>
  91. <script>
  92. new Chart($('#chart_user_timeline').raw().getContext('2d'), {
  93. type: 'line',
  94. data: {
  95. labels: <? print '["'.implode('","',$Labels).'"]'; ?>,
  96. datasets: [ {
  97. label: "New Registrations",
  98. backgroundColor: "rgba(0,0,255,0.2)",
  99. borderColor: "rgba(0,0,255,0.8)",
  100. data: <? print "[".implode(",",$InFlow)."]"; ?>
  101. }, {
  102. label: "Disabled Users",
  103. backgroundColor: "rgba(255,0,0,0.2)",
  104. borderColor: "rgba(255,0,0,0.8)",
  105. data: <? print "[".implode(",",$OutFlow)."]"; ?>
  106. }]
  107. }
  108. })
  109. </script>
  110. </div>
  111. <br />
  112. <h3 id="User_Classes"><a href="#User_Classes">User Classes</a></h3>
  113. <div class="box pad center">
  114. <canvas class="chart" id="chart_user_classes"></canvas>
  115. <script>
  116. new Chart($('#chart_user_classes').raw().getContext('2d'), {
  117. type: 'pie',
  118. data: {
  119. labels: <? print '["'.implode('","', array_column($ClassDistribution, 'Name')).'"]'; ?>,
  120. datasets: [ {
  121. data: <? print "[".implode(",", array_column($ClassDistribution, 'Users'))."]"; ?>,
  122. backgroundColor: ['#8a00b8','#a944cb','#be71d8','#e8ccf1', '#f3e3f9', '#fbf6fd', '#ffffff']
  123. }]
  124. }
  125. })
  126. </script>
  127. </div>
  128. <br />
  129. <h3 id="User_Platforms"><a href="#User_Platforms">User Platforms</a></h3>
  130. <div class="box pad center">
  131. <canvas class="chart" id="chart_user_platforms"></canvas>
  132. <?
  133. $AllPlatforms = array_column($PlatformDistribution, 'OperatingSystem');
  134. $SlicedPlatforms = (count($AllPlatforms) > 14) ? array_slice($AllPlatforms,0,13)+[13=>'Other'] : $AllPlatforms;
  135. $AllUsers = array_column($PlatformDistribution, 'Users');
  136. $SlicedUsers = (count($AllUsers) > 14) ? array_slice($AllUsers,0,13)+[13=>array_sum(array_slice($AllUsers,13))] : $AllUsers;
  137. $Colors = [];
  138. $Palette = ["blue"=>['#46B','#34A','#239','#128','#117','#006'],"red"=>['#B45','#A34','#923'],"green"=>['#3B3','#2A2','#191','#080'],"purple"=>['#B3B','#A2A','#919','#808','#707','#606','#505','#404']];
  139. $Counts = [0,0,0,0];
  140. for ($i = 0; $i < count($SlicedPlatforms); $i++) {
  141. if (preg_match('/Windows/i', $SlicedPlatforms[$i])) {
  142. $Colors[] = $Palette["blue"][$Counts[0]];
  143. $Counts[0]++;
  144. } else if (preg_match('/Mac|OS ?X/i', $SlicedPlatforms[$i])) {
  145. $Colors[] = $Palette["red"][$Counts[1]];
  146. $Counts[1]++;
  147. } else if (preg_match('/Linux|Ubuntu|Fedora/i', $SlicedPlatforms[$i])) {
  148. $Colors[] = $Palette["green"][$Counts[2]];
  149. $Counts[2]++;
  150. } else {
  151. $Colors[] = $Palette["purple"][$Counts[3]];
  152. $Counts[3]++;
  153. }
  154. }
  155. ?>
  156. <script>
  157. new Chart($('#chart_user_platforms').raw().getContext('2d'), {
  158. type: 'pie',
  159. data: {
  160. labels: ["<?=implode('","', $SlicedPlatforms)?>"],
  161. datasets: [ {
  162. data: [<?=implode(",", $SlicedUsers)?>],
  163. backgroundColor: ["<?=implode('","', $Colors)?>"]
  164. }]
  165. }
  166. })
  167. </script>
  168. </div>
  169. <br />
  170. <h3 id="User_Browsers"><a href="#User_Browsers">User Browsers</a></h3>
  171. <div class="box pad center">
  172. <canvas class="chart" id="chart_user_browsers"></canvas>
  173. <?
  174. $AllBrowsers = array_column($BrowserDistribution, 'Browser');
  175. $SlicedBrowsers = (count($AllBrowsers) > 7) ? array_slice($AllBrowsers,0,6)+[6=>'Other'] : $AllBrowsers;
  176. $AllUsers = array_column($BrowserDistribution, 'Users');
  177. $SlicedUsers = (count($AllUsers) > 7) ? array_slice($AllUsers,0,6)+[6=>array_sum(array_slice($AllUsers,6))] : $AllUsers;
  178. $Colors = [];
  179. $Palette = ["blue"=>['#46B','#34A'],"orange"=>['#F53','#E42'],"green"=>['#3B3','#2A2'],"purple"=>['#B3B','#A2A','#919','#808','#707','#606','#505','#404']];
  180. $Counts = [0,0,0,0];
  181. for ($i = 0; $i < count($SlicedBrowsers); $i++) {
  182. if (preg_match('/Chrome/i', $SlicedBrowsers[$i])) {
  183. $Colors[] = $Palette["green"][$Counts[0]];
  184. $Counts[0]++;
  185. } else if (preg_match('/Firefox/i', $SlicedBrowsers[$i])) {
  186. $Colors[] = $Palette["orange"][$Counts[1]];
  187. $Counts[1]++;
  188. } else if (preg_match('/Safari/i', $SlicedBrowsers[$i])) {
  189. $Colors[] = $Palette["blue"][$Counts[2]];
  190. $Counts[2]++;
  191. } else {
  192. $Colors[] = $Palette["purple"][$Counts[3]];
  193. $Counts[3]++;
  194. }
  195. }
  196. ?>
  197. <script>
  198. new Chart($('#chart_user_browsers').raw().getContext('2d'), {
  199. type: 'pie',
  200. data: {
  201. labels: ["<?=implode('","', $SlicedBrowsers)?>"],
  202. datasets: [ {
  203. data: [<?=implode(",", $SlicedUsers)?>],
  204. backgroundColor: ["<?=implode('","', $Colors)?>"],
  205. }]
  206. }
  207. })
  208. </script>
  209. </div>
  210. <br />
  211. <h3 id="Geo_Dist_Map"><a href="#Geo_Dist_Map">Geographical Distribution Map</a></h3>
  212. <div class="box center">
  213. <img src="<?=ImageTools::process('https://chart.googleapis.com/chart?cht=map:fixed=-55,-180,73,180&chs=440x220&chd=t:'.implode(',', $Rank).'&chco=FFFFFF,EDEDED,1F0066&chld='.implode('|', $Countries).'&chf=bg,s,CCD6FF')?>" alt="Geographical Distribution Map - Worldwide" />
  214. <img src="<?=ImageTools::process('https://chart.googleapis.com/chart?cht=map:fixed=37,-26,65,67&chs=440x220&chs=440x220&chd=t:'.implode(',', $Rank).'&chco=FFFFFF,EDEDED,1F0066&chld='.implode('|', $Countries).'&chf=bg,s,CCD6FF')?>" alt="Geographical Distribution Map - Europe" />
  215. <br />
  216. <img src="<?=ImageTools::process('https://chart.googleapis.com/chart?cht=map:fixed=-46,-132,24,21.5&chs=440x220&chd=t:'.implode(',', $Rank).'&chco=FFFFFF,EDEDED,1F0066&chld='.implode('|', $Countries).'&chf=bg,s,CCD6FF')?>" alt="Geographical Distribution Map - South America" />
  217. <img src="<?=ImageTools::process('https://chart.googleapis.com/chart?cht=map:fixed=-11,22,50,160&chs=440x220&chd=t:'.implode(',', $Rank).'&chco=FFFFFF,EDEDED,1F0066&chld='.implode('|', $Countries).'&chf=bg,s,CCD6FF')?>" alt="Geographical Distribution Map - Asia" />
  218. <br />
  219. <img src="<?=ImageTools::process('https://chart.googleapis.com/chart?cht=map:fixed=-36,-57,37,100&chs=440x220&chd=t:'.implode(',', $Rank).'&chco=FFFFFF,EDEDED,1F0066&chld='.implode('|', $Countries).'&chf=bg,s,CCD6FF')?>" alt="Geographical Distribution Map - Africa" />
  220. <img src="<?=ImageTools::process('https://chart.googleapis.com/chart?cht=map:fixed=14.8,15,45,86&chs=440x220&chd=t:'.implode(',', $Rank).'&chco=FFFFFF,EDEDED,1F0066&chld='.implode('|', $Countries).'&chf=bg,s,CCD6FF')?>" alt="Geographical Distribution Map - Middle East" />
  221. <br />
  222. <img src="<?=ImageTools::process('https://chart.googleapis.com/chart?chxt=y,x&chg=0,-1,1,1&chxs=0,h&cht=bvs&chco=76A4FB&chs=880x300&chd=t:'.implode(',', array_slice($CountryUsers, 0, 31)).'&chxl=1:|'.implode('|', array_slice($Countries, 0, 31)).'|0:|'.implode('|', $LogIncrements).'&chf=bg,s,FFFFFF00')?>" alt="Number of users by country" />
  223. </div>
  224. <?
  225. View::show_footer();