PageRenderTime 57ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/admin/tool/recyclebin/classes/course_bin.php

https://gitlab.com/unofficial-mirrors/moodle
PHP | 335 lines | 167 code | 55 blank | 113 comment | 11 complexity | 440a92946c986c5d90fae431ef935968 MD5 | raw file
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * The main interface for recycle bin methods.
  18. *
  19. * @package tool_recyclebin
  20. * @copyright 2015 University of Kent
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22. */
  23. namespace tool_recyclebin;
  24. defined('MOODLE_INTERNAL') || die();
  25. define('TOOL_RECYCLEBIN_COURSE_BIN_FILEAREA', 'recyclebin_course');
  26. /**
  27. * Represents a course's recyclebin.
  28. *
  29. * @package tool_recyclebin
  30. * @copyright 2015 University of Kent
  31. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32. */
  33. class course_bin extends base_bin {
  34. /**
  35. * @var int The course id.
  36. */
  37. protected $_courseid;
  38. /**
  39. * Constructor.
  40. *
  41. * @param int $courseid Course ID.
  42. */
  43. public function __construct($courseid) {
  44. $this->_courseid = $courseid;
  45. }
  46. /**
  47. * Is this recyclebin enabled?
  48. *
  49. * @return bool true if enabled, false if not.
  50. */
  51. public static function is_enabled() {
  52. return get_config('tool_recyclebin', 'coursebinenable');
  53. }
  54. /**
  55. * Returns an item from the recycle bin.
  56. *
  57. * @param int $itemid Item ID to retrieve.
  58. * @return \stdClass the item.
  59. */
  60. public function get_item($itemid) {
  61. global $DB;
  62. return $DB->get_record('tool_recyclebin_course', array(
  63. 'id' => $itemid
  64. ), '*', MUST_EXIST);
  65. }
  66. /**
  67. * Returns a list of items in the recycle bin for this course.
  68. *
  69. * @return array the list of items.
  70. */
  71. public function get_items() {
  72. global $DB;
  73. return $DB->get_records('tool_recyclebin_course', array(
  74. 'courseid' => $this->_courseid
  75. ));
  76. }
  77. /**
  78. * Store a course module in the recycle bin.
  79. *
  80. * @param \stdClass $cm Course module
  81. * @throws \moodle_exception
  82. */
  83. public function store_item($cm) {
  84. global $CFG, $DB;
  85. require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
  86. // Get more information.
  87. $modinfo = get_fast_modinfo($cm->course);
  88. if (!isset($modinfo->cms[$cm->id])) {
  89. return; // Can't continue without the module information.
  90. }
  91. $cminfo = $modinfo->cms[$cm->id];
  92. // Check backup/restore support.
  93. if (!plugin_supports('mod', $cminfo->modname , FEATURE_BACKUP_MOODLE2)) {
  94. return;
  95. }
  96. // Backup the activity.
  97. $user = get_admin();
  98. $controller = new \backup_controller(
  99. \backup::TYPE_1ACTIVITY,
  100. $cm->id,
  101. \backup::FORMAT_MOODLE,
  102. \backup::INTERACTIVE_NO,
  103. \backup::MODE_GENERAL,
  104. $user->id
  105. );
  106. $controller->execute_plan();
  107. // Grab the result.
  108. $result = $controller->get_results();
  109. if (!isset($result['backup_destination'])) {
  110. throw new \moodle_exception('Failed to backup activity prior to deletion.');
  111. }
  112. // Have finished with the controller, let's destroy it, freeing mem and resources.
  113. $controller->destroy();
  114. // Grab the filename.
  115. $file = $result['backup_destination'];
  116. if (!$file->get_contenthash()) {
  117. throw new \moodle_exception('Failed to backup activity prior to deletion (invalid file).');
  118. }
  119. // Record the activity, get an ID.
  120. $activity = new \stdClass();
  121. $activity->courseid = $cm->course;
  122. $activity->section = $cm->section;
  123. $activity->module = $cm->module;
  124. $activity->name = $cminfo->name;
  125. $activity->timecreated = time();
  126. $binid = $DB->insert_record('tool_recyclebin_course', $activity);
  127. // Create the location we want to copy this file to.
  128. $filerecord = array(
  129. 'contextid' => \context_course::instance($this->_courseid)->id,
  130. 'component' => 'tool_recyclebin',
  131. 'filearea' => TOOL_RECYCLEBIN_COURSE_BIN_FILEAREA,
  132. 'itemid' => $binid,
  133. 'timemodified' => time()
  134. );
  135. // Move the file to our own special little place.
  136. $fs = get_file_storage();
  137. if (!$fs->create_file_from_storedfile($filerecord, $file)) {
  138. // Failed, cleanup first.
  139. $DB->delete_records('tool_recyclebin_course', array(
  140. 'id' => $binid
  141. ));
  142. throw new \moodle_exception("Failed to copy backup file to recyclebin.");
  143. }
  144. // Delete the old file.
  145. $file->delete();
  146. // Fire event.
  147. $event = \tool_recyclebin\event\course_bin_item_created::create(array(
  148. 'objectid' => $binid,
  149. 'context' => \context_course::instance($cm->course)
  150. ));
  151. $event->trigger();
  152. }
  153. /**
  154. * Restore an item from the recycle bin.
  155. *
  156. * @param \stdClass $item The item database record
  157. * @throws \moodle_exception
  158. */
  159. public function restore_item($item) {
  160. global $CFG, $OUTPUT, $PAGE;
  161. require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
  162. $user = get_admin();
  163. // Grab the course context.
  164. $context = \context_course::instance($this->_courseid);
  165. // Get the files..
  166. $fs = get_file_storage();
  167. $files = $fs->get_area_files($context->id, 'tool_recyclebin', TOOL_RECYCLEBIN_COURSE_BIN_FILEAREA, $item->id,
  168. 'itemid, filepath, filename', false);
  169. if (empty($files)) {
  170. throw new \moodle_exception('Invalid recycle bin item!');
  171. }
  172. if (count($files) > 1) {
  173. throw new \moodle_exception('Too many files found!');
  174. }
  175. // Get the backup file.
  176. $file = reset($files);
  177. // Get a backup temp directory name and create it.
  178. $tempdir = \restore_controller::get_tempdir_name($context->id, $user->id);
  179. $fulltempdir = make_backup_temp_directory($tempdir);
  180. // Extract the backup to tempdir.
  181. $fb = get_file_packer('application/vnd.moodle.backup');
  182. $fb->extract_to_pathname($file, $fulltempdir);
  183. // Define the import.
  184. $controller = new \restore_controller(
  185. $tempdir,
  186. $this->_courseid,
  187. \backup::INTERACTIVE_NO,
  188. \backup::MODE_GENERAL,
  189. $user->id,
  190. \backup::TARGET_EXISTING_ADDING
  191. );
  192. // Prechecks.
  193. if (!$controller->execute_precheck()) {
  194. $results = $controller->get_precheck_results();
  195. // If errors are found then delete the file we created.
  196. if (!empty($results['errors'])) {
  197. fulldelete($fulltempdir);
  198. echo $OUTPUT->header();
  199. $backuprenderer = $PAGE->get_renderer('core', 'backup');
  200. echo $backuprenderer->precheck_notices($results);
  201. echo $OUTPUT->continue_button(new \moodle_url('/course/view.php', array('id' => $this->_courseid)));
  202. echo $OUTPUT->footer();
  203. exit();
  204. }
  205. }
  206. // Run the import.
  207. $controller->execute_plan();
  208. // Have finished with the controller, let's destroy it, freeing mem and resources.
  209. $controller->destroy();
  210. // Fire event.
  211. $event = \tool_recyclebin\event\course_bin_item_restored::create(array(
  212. 'objectid' => $item->id,
  213. 'context' => $context
  214. ));
  215. $event->add_record_snapshot('tool_recyclebin_course', $item);
  216. $event->trigger();
  217. // Cleanup.
  218. fulldelete($fulltempdir);
  219. $this->delete_item($item);
  220. }
  221. /**
  222. * Delete an item from the recycle bin.
  223. *
  224. * @param \stdClass $item The item database record
  225. */
  226. public function delete_item($item) {
  227. global $DB;
  228. // Grab the course context.
  229. $context = \context_course::instance($this->_courseid);
  230. // Delete the files.
  231. $fs = get_file_storage();
  232. $files = $fs->get_area_files($context->id, 'tool_recyclebin', TOOL_RECYCLEBIN_COURSE_BIN_FILEAREA, $item->id);
  233. foreach ($files as $file) {
  234. $file->delete();
  235. }
  236. // Delete the record.
  237. $DB->delete_records('tool_recyclebin_course', array(
  238. 'id' => $item->id
  239. ));
  240. // The course might have been deleted, check we have a context.
  241. $context = \context_course::instance($item->courseid, \IGNORE_MISSING);
  242. if (!$context) {
  243. return;
  244. }
  245. // Fire event.
  246. $event = \tool_recyclebin\event\course_bin_item_deleted::create(array(
  247. 'objectid' => $item->id,
  248. 'context' => $context
  249. ));
  250. $event->add_record_snapshot('tool_recyclebin_course', $item);
  251. $event->trigger();
  252. }
  253. /**
  254. * Can we view items in this recycle bin?
  255. *
  256. * @return bool returns true if they can view, false if not
  257. */
  258. public function can_view() {
  259. $context = \context_course::instance($this->_courseid);
  260. return has_capability('tool/recyclebin:viewitems', $context);
  261. }
  262. /**
  263. * Can we restore items in this recycle bin?
  264. *
  265. * @return bool returns true if they can restore, false if not
  266. */
  267. public function can_restore() {
  268. $context = \context_course::instance($this->_courseid);
  269. return has_capability('tool/recyclebin:restoreitems', $context);
  270. }
  271. /**
  272. * Can we delete this?
  273. *
  274. * @return bool returns true if they can delete, false if not
  275. */
  276. public function can_delete() {
  277. $context = \context_course::instance($this->_courseid);
  278. return has_capability('tool/recyclebin:deleteitems', $context);
  279. }
  280. }