PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/report/coursesize/index.php

https://github.com/thepurpleblob/gumoodle
PHP | 211 lines | 176 code | 16 blank | 19 comment | 30 complexity | 11a40c62957adb77df288ab075894a02 MD5 | raw file
Possible License(s): Apache-2.0, GPL-3.0, BSD-3-Clause, LGPL-2.1, AGPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-3.0
  1. <?php
  2. require_once('../../config.php');
  3. require_once($CFG->libdir.'/adminlib.php');
  4. admin_externalpage_setup('reportcoursesize');
  5. if (!empty($CFG->filessize) && !empty($CFG->filessizeupdated) && ($CFG->filessizeupdated > time() - 2 * DAYSECS)) {
  6. // Total files usage has been recently calculated, and stored by another process - use that:
  7. $totalusage = $CFG->filessize;
  8. $totaldate = date("Y-m-d H:i", $CFG->filessizeupdated);
  9. } else {
  10. // Total files usage either hasn't been stored, or is out of date:
  11. $totaldate = date("Y-m-d H:i", time());
  12. $totalusage = du($CFG->dataroot);
  13. // TODO: check if CFG->pathtodu is set, and if so, use it
  14. // this will speed up linux systems.
  15. // for now, all OS are the same speed
  16. // TODO: Save this result in $CFG->filessize and $CFG->filessizeupdated
  17. // so that it's available for the next report hit
  18. }
  19. $totalusagereadable = number_format(ceil($totalusage/1048576)) . " MB";
  20. // TODO: display the sizes of directories (other than filedir) in dataroot
  21. // eg old 1.9 course dirs, temp, sessions etc
  22. // Generate a full list of context sitedata usage stats
  23. $subsql = 'SELECT f.contextid, sum(f.filesize) as filessize' .
  24. ' FROM {files} f';
  25. $wherebackup = ' WHERE component like \'backup\'';
  26. $groupby = ' GROUP BY f.contextid';
  27. $sizesql = 'SELECT cx.id, cx.contextlevel, cx.instanceid, cx.path, cx.depth, size.filessize, backupsize.filessize as backupsize' .
  28. ' FROM {context} cx ' .
  29. ' INNER JOIN ( ' . $subsql . $groupby . ' ) size on cx.id=size.contextid' .
  30. ' LEFT JOIN ( ' . $subsql . $wherebackup . $groupby . ' ) backupsize on cx.id=backupsize.contextid' .
  31. ' ORDER by cx.depth ASC, cx.path ASC';
  32. $cxsizes = $DB->get_records_sql($sizesql);
  33. $coursesizes = array(); // To track a mapping of courseid to filessize
  34. $coursebackupsizes = array(); // To track a mapping of courseid to backup filessize
  35. $usersizes = array(); // To track a mapping of users to filesize
  36. $systemsize = $systembackupsize = 0;
  37. $coursesql = 'SELECT cx.id, c.id as courseid ' .
  38. 'FROM {course} c ' .
  39. ' INNER JOIN {context} cx ON cx.instanceid=c.id AND cx.contextlevel = ' . CONTEXT_COURSE;
  40. $courselookup = $DB->get_records_sql($coursesql);
  41. $courses = $DB->get_records('course');
  42. $users = $DB->get_records('user');
  43. foreach($cxsizes as $cxid => $cxdata) {
  44. $contextlevel = $cxdata->contextlevel;
  45. $instanceid = $cxdata->instanceid;
  46. $contextsize = $cxdata->filessize;
  47. $contextbackupsize = (empty($cxdata->backupsize) ? 0 : $cxdata->backupsize);
  48. if ($contextlevel == CONTEXT_USER) {
  49. $usersizes[$instanceid] = $contextsize;
  50. $userbackupsizes[$instanceid] = $contextbackupsize;
  51. continue;
  52. }
  53. if ($contextlevel == CONTEXT_COURSE) {
  54. $coursesizes[$instanceid] = $contextsize;
  55. $coursebackupsizes[$instanceid] = $contextbackupsize;
  56. continue;
  57. }
  58. if (($contextlevel == CONTEXT_SYSTEM) || ($contextlevel == CONTEXT_COURSECAT)) {
  59. $systemsize = $contextsize;
  60. $systembackupsize = $contextbackupsize;
  61. continue;
  62. }
  63. // Not a course, user, system, category, see it it's something that should be listed under a course:
  64. // Modules & Blocks mostly:
  65. $path = explode('/', $cxdata->path);
  66. array_shift($path); // get rid of the leading (empty) array item
  67. array_pop($path); // Trim the contextid of the current context itself
  68. $success = false; // Course not yet found.
  69. // Look up through the parent contexts of this item until a course is found:
  70. while(count($path)) {
  71. $contextid = array_pop($path);
  72. if (isset($courselookup[$contextid])) {
  73. $success = true; //Course found
  74. // record the files for the current context against the course
  75. $courseid = $courselookup[$contextid]->courseid;
  76. if (!empty($coursesizes[$courseid])) {
  77. $coursesizes[$courseid] += $contextsize;
  78. $coursebackupsizes[$courseid] += $contextbackupsize;
  79. } else {
  80. $coursesizes[$courseid] = $contextsize;
  81. $coursebackupsizes[$courseid] = $contextbackupsize;
  82. }
  83. break;
  84. }
  85. }
  86. if (!$success) {
  87. // Didn't find a course
  88. // A module or block not under a course?
  89. $systemsize += $contextsize;
  90. $systembackupsize += $contextbackupsize;
  91. }
  92. }
  93. $coursetable = new html_table();
  94. $coursetable->align = array('right','right', 'right');
  95. $coursetable->head = array(get_string('course'),
  96. get_string('diskusage','report_coursesize'),
  97. get_string('backupsize', 'report_coursesize'));
  98. $coursetable->data=array();
  99. arsort($coursesizes);
  100. foreach ($coursesizes as $courseid => $size) {
  101. $backupsize = $coursebackupsizes[$courseid];
  102. $course = $courses[$courseid];
  103. $row = array();
  104. $row[] = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">' . $course->shortname . '</a>';
  105. $readablesize = number_format(ceil($size/1048576)) . "MB";
  106. $a = new stdClass;
  107. $a->bytes = $size;
  108. $a->shortname = $course->shortname;
  109. $a->backupbytes = $backupsize;
  110. $bytesused = get_string('coursebytes', 'report_coursesize', $a);
  111. $backupbytesused = get_string('coursebackupbytes', 'report_coursesize', $a);
  112. $row[] = "<span title=\"$bytesused\">$readablesize</span>";
  113. $row[] = "<span title=\"$backupbytesused\">" . number_format(ceil($backupsize/1048576)) . " MB</span>";
  114. $coursetable->data[] = $row;
  115. unset($courses[$courseid]);
  116. }
  117. // Now add the courses that had no sitedata into the table
  118. $a = new stdClass;
  119. $a->bytes = 0;
  120. $a->backupbytes = 0;
  121. foreach($courses as $cid => $course) {
  122. $a->shortname = $course->shortname;
  123. $bytesused = get_string('coursebytes', 'report_coursesize', $a);
  124. $bytesused = get_string('coursebackupbytes', 'report_coursesize', $a);
  125. $row = array();
  126. $row[] = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">' . $course->shortname . '</a>';
  127. $row[] = "<span title=\"$bytesused\">0 MB</span>";
  128. $row[] = "<span title=\"$bytesused\">0 MB</span>";
  129. $coursetable->data[] = $row;
  130. }
  131. if (!empty($usersizes)) {
  132. arsort($usersizes);
  133. $usertable = new html_table();
  134. $usertable->align = array('right','right');
  135. $usertable->head = array(get_string('user'),'Disk Usage');
  136. $usertable->data=array();
  137. foreach ($usersizes as $userid => $size) {
  138. $user = $users[$userid];
  139. $row = array();
  140. $row[] = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userid.'">' . fullname($user) . '</a>';
  141. $row[] = number_format(ceil($size/1048576)) . "MB";
  142. $usertable->data[] = $row;
  143. }
  144. }
  145. $systemsizereadable = number_format(ceil($systemsize/1048576)) . "MB";
  146. $systembackupreadable = number_format(ceil($systembackupsize/1048576)) . "MB";
  147. // All the processing done, the rest is just output stuff.
  148. print $OUTPUT->header();
  149. print $OUTPUT->heading(get_string("sitefilesusage", 'report_coursesize'));
  150. print get_string("totalsitedata", 'report_coursesize', $totalusagereadable) . "<br/>\n";
  151. print get_string("sizerecorded", "report_coursesize", $totaldate) . "<br/>\n";
  152. if (!empty($CFG->filessizelimit)) {
  153. print get_string("sizepermitted", 'report_coursesize', number_format($CFG->filessizelimit)). "<br/>\n";
  154. }
  155. print $OUTPUT->heading(get_string('coursesize', 'report_coursesize'));
  156. print html_writer::table($coursetable);
  157. print $OUTPUT->heading(get_string('users'));
  158. if (!isset($usertable)) {
  159. print get_string('nouserfiles', 'report_coursesize');
  160. } else {
  161. print html_writer::table($usertable);
  162. }
  163. print $OUTPUT->heading(get_string('system', 'report_coursesize'));
  164. print get_string('catsystemuse', 'report_coursesize', $systemsizereadable) . "<br/>";
  165. print get_string('catsystembackupuse', 'report_coursesize', $systembackupreadable) . "<br/>";
  166. print $OUTPUT->footer();
  167. function du ($dirname) {
  168. if (empty($dirname) || !is_dir($dirname)) {
  169. return 0;
  170. }
  171. $du = 0;
  172. $handle = opendir($dirname);
  173. if (!$handle) {
  174. return 0;
  175. }
  176. while ($item = readdir($handle)) {
  177. if (!$item) {
  178. continue;
  179. }
  180. if ($item == '.' || $item == '..') {
  181. // Ignore implied directories
  182. continue;
  183. }
  184. $path = $dirname . '/' . $item;
  185. $itemsize = filesize($path);
  186. $du += $itemsize;
  187. if (is_dir($path)) {
  188. $subdirsize = du($dirname . '/' . $item);
  189. $du += $subdirsize;
  190. }
  191. }
  192. closedir($handle);
  193. return $du;
  194. }
  195. ?>