PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/admin/cohorts.php

https://github.com/whale2/users
PHP | 276 lines | 218 code | 56 blank | 2 comment | 41 complexity | 02e8ca6bb5a35db71630f336859f7a9e MD5 | raw file
  1. <?php
  2. require_once(dirname(__FILE__).'/admin.php');
  3. $ADMIN_SECTION = 'cohorts';
  4. require_once(dirname(__FILE__).'/header.php');
  5. ?>
  6. <form action="" name="activities" style="margin: 1em 0">
  7. <div>
  8. Pick activity:
  9. <select name="activityid" onchange="document.activities.submit();">
  10. <?php
  11. // sorting by point-value of activities
  12. function mostpoints($a, $b) {
  13. if (UserConfig::$activities[$a][1] > UserConfig::$activities[$b][1]) {
  14. return -1;
  15. } else if (UserConfig::$activities[$a][1] < UserConfig::$activities[$b][1]) {
  16. return 1;
  17. }
  18. return strcmp(UserConfig::$activities[$a][0], UserConfig::$activities[$b][0]);
  19. }
  20. uksort(UserConfig::$activities, 'mostpoints');
  21. $stats = User::getActivityStatistics();
  22. $selectedactivityid = null;
  23. if (array_key_exists('activityid', $_REQUEST) && is_numeric($_REQUEST['activityid'])) {
  24. $selectedactivityid = $_REQUEST['activityid'];
  25. }
  26. $firstactivityid = null; // most popular one, first on the list
  27. foreach (UserConfig::$activities as $id => $activity) {
  28. if (!array_key_exists($id, $stats)) {
  29. continue;
  30. }
  31. if (is_null($firstactivityid)) {
  32. $firstactivityid = $id;
  33. }
  34. ?>
  35. <option value="<?php echo $id ?>"<?php echo $selectedactivityid == $id ? ' selected="yes"' : '' ?>><?php echo $activity[0] ?> (<?php echo $activity[1] ?> points)</option>
  36. <?php } ?>
  37. </select>
  38. <?php
  39. $boxes = !array_key_exists('boxes', $_REQUEST) || $_REQUEST['boxes'] !== 'set';
  40. $zoom = array_key_exists('zoom', $_REQUEST);
  41. ?>
  42. <input type="hidden" name="boxes" value="set"/>
  43. <span style="padding-left: 1em"><input type="checkbox" id="boxes" name="boxes"<?php if ($boxes) {?> checked<?php } ?> onchange="document.activities.submit();"/><?php if (!$boxes && $zoom) {?><input type="hidden" name="zoom" value="on"/><?php } ?> <label for="boxes">Show Boxes</label></span>
  44. <span style="padding-left: 1em" title="Zoom in to fit maximum velue into the box"><input type="checkbox"<?php if ($boxes) {?> id="zoom" name="zoom"<?php } else { ?> disabled<?php } ?><?php if ($boxes && $zoom) {?> checked<?php } ?> onchange="document.activities.submit();"/> <label for="zoom">Zoom in</label></span>
  45. <div>
  46. How to drop users into cohorts:
  47. <select name="cohorts" onchange="document.activities.submit();">
  48. <?php
  49. $requested_cohort_provider = null;
  50. if (array_key_exists('cohorts', $_REQUEST)) {
  51. $requested_cohort_provider = $_REQUEST['cohorts'];
  52. }
  53. $cohort_provider = null;
  54. foreach (UserConfig::$cohort_providers as $provider) {
  55. $id = $provider->getID();
  56. $selected = false;
  57. if ($id == $requested_cohort_provider) {
  58. $cohort_provider = $provider;
  59. $selected = true;
  60. }
  61. ?><option value="<?php echo UserTools::escape($id) ?>"<?php if ($selected) { ?> selected="yes"<?php } ?>>
  62. <?php echo UserTools::escape($provider->getTitle()) ?>
  63. </option><?php
  64. }
  65. if (is_null($cohort_provider)) {
  66. $cohort_provider = UserConfig::$cohort_providers[0];
  67. }
  68. ?>
  69. </select>
  70. </div>
  71. </form>
  72. </div>
  73. <?php
  74. $cohort_lookup = array();
  75. $cohorts = $cohort_provider->getCohorts();
  76. foreach ($cohorts as $cohort) {
  77. $cohort_lookup[$cohort->getID()] = $cohort;
  78. }
  79. $aggregates = null;
  80. if (is_null($selectedactivityid)) {
  81. $selectedactivityid = $firstactivityid;
  82. }
  83. $selectedactivity = UserConfig::$activities[$selectedactivityid];
  84. $actperiodtype = 'Month';
  85. $actperiodlength = 30;
  86. $aggregates = $cohort_provider->getActivityRate($selectedactivityid, $actperiodlength);
  87. $minactperiod = 0;
  88. $maxactperiod = $minactperiod;
  89. $maxvalue = 0;
  90. foreach (array_keys($aggregates) as $cohort_id) {
  91. foreach (array_keys($aggregates[$cohort_id]) as $actperiod) {
  92. if ($actperiod < $minactperiod) {
  93. continue;
  94. }
  95. if ($actperiod > $maxactperiod) {
  96. $maxactperiod = $actperiod;
  97. }
  98. $rate = $aggregates[$cohort_id][$actperiod] / $cohort_lookup[$cohort_id]->getTotal();
  99. if ($rate > $maxvalue) {
  100. $maxvalue = $rate;
  101. }
  102. }
  103. }
  104. $total = 0;
  105. if (!is_null($aggregates)) {
  106. $squaresize = 70;
  107. ?>
  108. <style>
  109. .outerbox {
  110. width: <?php echo $squaresize + 4 ?>px;
  111. height: <?php echo $squaresize + 4 ?>px;
  112. border: 1px dashed black;
  113. position: relative;
  114. padding: 2px;
  115. }
  116. .emptybox {
  117. width: <?php echo $squaresize + 4 ?>px;
  118. height: <?php echo $squaresize + 4 ?>px;
  119. border: 1px dashed silver;
  120. padding: 2px;
  121. }
  122. .innerbox {
  123. background-color: #759ff9;
  124. border: 2px solid #4269d6;
  125. color: black;
  126. position: absolute;
  127. bottom: 2px;
  128. left: 2px;
  129. }
  130. .ratebox {
  131. text-align: right;
  132. font-size: <?php echo ceil($squaresize / 4) ?>px;
  133. font-weight: bold;
  134. position: absolute;
  135. right: 2px;
  136. top: 2px;
  137. }
  138. .up {
  139. color: green;
  140. font-size: <?php echo ceil($squaresize / 6) ?>px;
  141. }
  142. .down {
  143. color: red;
  144. font-size: <?php echo ceil($squaresize / 6) ?>px;
  145. }
  146. .numbers {
  147. font-size: <?php echo ceil($squaresize / 7) ?>px;
  148. }
  149. </style>
  150. <table cellpadding="5" cellspacing="0" border="0">
  151. <tr>
  152. <th><?php echo $cohort_provider->getDimensionTitle() ?></th>
  153. <?php
  154. for ($period = $minactperiod; $period <= $maxactperiod; $period ++) {
  155. ?> <th><?php echo $actperiodtype.' '.$period ?></th><?php
  156. }
  157. ?>
  158. </tr>
  159. <?php
  160. for ($cohort_number = 0; $cohort_number < count($cohorts); $cohort_number += 1) {
  161. $cohort = $cohorts[$cohort_number];
  162. $total_cohort_users = $cohort->getTotal();
  163. ?><tr><th><?php echo $cohort->getTitle() ?></th><?php
  164. for ($actperiod = $minactperiod; $actperiod <= $maxactperiod; $actperiod++) {
  165. $cohort_id = $cohort->getID();
  166. ?><td><?php
  167. if (array_key_exists($cohort_id, $aggregates)
  168. && array_key_exists($actperiod, $aggregates[$cohort_id]))
  169. {
  170. $rate = $aggregates[$cohort_id][$actperiod] / $total_cohort_users;
  171. $ratepercent = round($rate * 100, 2);
  172. if ($zoom) {
  173. $boxsize = ceil(sqrt($squaresize * $squaresize * $rate / $maxvalue));
  174. } else {
  175. $boxsize = ceil(sqrt($squaresize * $squaresize * $rate));
  176. }
  177. ?><div class="outerbox"<?php echo $boxes ? 'title="'.$ratepercent.'% ('.$aggregates[$cohort_id][$actperiod].' out of total '.$total_cohort_users.' users in this cohort)"' : ''; ?>><?php
  178. if ($boxes) {
  179. ?>
  180. <div class="innerbox" style="width: <?php echo $boxsize ?>px; height: <?php echo $boxsize ?>px"></div>
  181. <?php
  182. }
  183. ?><div class="ratebox"><?php
  184. echo $ratepercent?>%<?php
  185. if ($cohort_provider->canCompareToPreviousCohort()
  186. && $cohort_number < (count($cohorts) - 1))
  187. {
  188. $prevrate = 0;
  189. $next_cohort = $cohorts[$cohort_number + 1];
  190. $next_cohort_id = $next_cohort->getID();
  191. if (array_key_exists($next_cohort_id, $aggregates) &&
  192. array_key_exists($actperiod, $aggregates[$next_cohort_id]))
  193. {
  194. $prevrate = $aggregates[$next_cohort_id][$actperiod]
  195. / $next_cohort->getTotal();
  196. }
  197. $diff = $rate - $prevrate;
  198. if ($diff > 0) {
  199. ?> <div class="up">+<?php echo round($diff * 100, 2) ?>%</div><?php
  200. } else if ($diff < 0) {
  201. ?> <div class="down"><?php echo round($diff * 100, 2) ?>%</div><?php
  202. }
  203. }
  204. ?><div class="numbers"><?php echo $aggregates[$cohort_id][$actperiod] ?> / <?php echo $total_cohort_users ?></div>
  205. </div>
  206. </div>
  207. <?php
  208. } else {
  209. ?><div class="emptybox" /><?php
  210. # echo '<span style="color: silver">0</span>';
  211. }
  212. ?></td><?php
  213. }
  214. ?></tr><?php
  215. }
  216. ?>
  217. </table>
  218. <?php
  219. }
  220. require_once(dirname(__FILE__).'/footer.php');