PageRenderTime 37ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/mod/workshop/allocation/scheduled/lib.php

https://gitlab.com/unofficial-mirrors/moodle
PHP | 287 lines | 162 code | 53 blank | 72 comment | 23 complexity | 8607c48997332a55a381f2ccdf694aba 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. * Scheduled allocator that internally executes the random allocation later
  18. *
  19. * @package workshopallocation_scheduled
  20. * @subpackage mod_workshop
  21. * @copyright 2012 David Mudrak <david@moodle.com>
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. defined('MOODLE_INTERNAL') || die();
  25. require_once(__DIR__ . '/../lib.php'); // interface definition
  26. require_once(__DIR__ . '/../../locallib.php'); // workshop internal API
  27. require_once(__DIR__ . '/../random/lib.php'); // random allocator
  28. require_once(__DIR__ . '/settings_form.php'); // our settings form
  29. /**
  30. * Allocates the submissions randomly in a cronjob task
  31. */
  32. class workshop_scheduled_allocator implements workshop_allocator {
  33. /** workshop instance */
  34. protected $workshop;
  35. /** workshop_scheduled_allocator_form with settings for the random allocator */
  36. protected $mform;
  37. /**
  38. * @param workshop $workshop Workshop API object
  39. */
  40. public function __construct(workshop $workshop) {
  41. $this->workshop = $workshop;
  42. }
  43. /**
  44. * Save the settings for the random allocator to execute it later
  45. */
  46. public function init() {
  47. global $PAGE, $DB;
  48. $result = new workshop_allocation_result($this);
  49. $customdata = array();
  50. $customdata['workshop'] = $this->workshop;
  51. $current = $DB->get_record('workshopallocation_scheduled',
  52. array('workshopid' => $this->workshop->id), '*', IGNORE_MISSING);
  53. $customdata['current'] = $current;
  54. $this->mform = new workshop_scheduled_allocator_form($PAGE->url, $customdata);
  55. if ($this->mform->is_cancelled()) {
  56. redirect($this->workshop->view_url());
  57. } else if ($settings = $this->mform->get_data()) {
  58. if (empty($settings->enablescheduled)) {
  59. $enabled = false;
  60. } else {
  61. $enabled = true;
  62. }
  63. if (empty($settings->reenablescheduled)) {
  64. $reset = false;
  65. } else {
  66. $reset = true;
  67. }
  68. $settings = workshop_random_allocator_setting::instance_from_object($settings);
  69. $this->store_settings($enabled, $reset, $settings, $result);
  70. if ($enabled) {
  71. $msg = get_string('resultenabled', 'workshopallocation_scheduled');
  72. } else {
  73. $msg = get_string('resultdisabled', 'workshopallocation_scheduled');
  74. }
  75. $result->set_status(workshop_allocation_result::STATUS_CONFIGURED, $msg);
  76. return $result;
  77. } else {
  78. // this branch is executed if the form is submitted but the data
  79. // doesn't validate and the form should be redisplayed
  80. // or on the first display of the form.
  81. if ($current !== false) {
  82. $data = workshop_random_allocator_setting::instance_from_text($current->settings);
  83. $data->enablescheduled = $current->enabled;
  84. $this->mform->set_data($data);
  85. }
  86. $result->set_status(workshop_allocation_result::STATUS_VOID);
  87. return $result;
  88. }
  89. }
  90. /**
  91. * Returns the HTML code to print the user interface
  92. */
  93. public function ui() {
  94. global $PAGE;
  95. $output = $PAGE->get_renderer('mod_workshop');
  96. $out = $output->container_start('scheduled-allocator');
  97. // the nasty hack follows to bypass the sad fact that moodle quickforms do not allow to actually
  98. // return the HTML content, just to display it
  99. ob_start();
  100. $this->mform->display();
  101. $out .= ob_get_contents();
  102. ob_end_clean();
  103. $out .= $output->container_end();
  104. return $out;
  105. }
  106. /**
  107. * Executes the allocation
  108. *
  109. * @return workshop_allocation_result
  110. */
  111. public function execute() {
  112. global $DB;
  113. $result = new workshop_allocation_result($this);
  114. // make sure the workshop itself is at the expected state
  115. if ($this->workshop->phase != workshop::PHASE_SUBMISSION) {
  116. $result->set_status(workshop_allocation_result::STATUS_FAILED,
  117. get_string('resultfailedphase', 'workshopallocation_scheduled'));
  118. return $result;
  119. }
  120. if (empty($this->workshop->submissionend)) {
  121. $result->set_status(workshop_allocation_result::STATUS_FAILED,
  122. get_string('resultfaileddeadline', 'workshopallocation_scheduled'));
  123. return $result;
  124. }
  125. if ($this->workshop->submissionend > time()) {
  126. $result->set_status(workshop_allocation_result::STATUS_VOID,
  127. get_string('resultvoiddeadline', 'workshopallocation_scheduled'));
  128. return $result;
  129. }
  130. $current = $DB->get_record('workshopallocation_scheduled',
  131. array('workshopid' => $this->workshop->id, 'enabled' => 1), '*', IGNORE_MISSING);
  132. if ($current === false) {
  133. $result->set_status(workshop_allocation_result::STATUS_FAILED,
  134. get_string('resultfailedconfig', 'workshopallocation_scheduled'));
  135. return $result;
  136. }
  137. if (!$current->enabled) {
  138. $result->set_status(workshop_allocation_result::STATUS_VOID,
  139. get_string('resultdisabled', 'workshopallocation_scheduled'));
  140. return $result;
  141. }
  142. if (!is_null($current->timeallocated) and $current->timeallocated >= $this->workshop->submissionend) {
  143. $result->set_status(workshop_allocation_result::STATUS_VOID,
  144. get_string('resultvoidexecuted', 'workshopallocation_scheduled'));
  145. return $result;
  146. }
  147. // so now we know that we are after the submissions deadline and either the scheduled allocation was not
  148. // executed yet or it was but the submissions deadline has been prolonged (and hence we should repeat the
  149. // allocations)
  150. $settings = workshop_random_allocator_setting::instance_from_text($current->settings);
  151. $randomallocator = $this->workshop->allocator_instance('random');
  152. $randomallocator->execute($settings, $result);
  153. // store the result in the instance's table
  154. $update = new stdClass();
  155. $update->id = $current->id;
  156. $update->timeallocated = $result->get_timeend();
  157. $update->resultstatus = $result->get_status();
  158. $update->resultmessage = $result->get_message();
  159. $update->resultlog = json_encode($result->get_logs());
  160. $DB->update_record('workshopallocation_scheduled', $update);
  161. return $result;
  162. }
  163. /**
  164. * Delete all data related to a given workshop module instance
  165. *
  166. * @see workshop_delete_instance()
  167. * @param int $workshopid id of the workshop module instance being deleted
  168. * @return void
  169. */
  170. public static function delete_instance($workshopid) {
  171. // TODO
  172. return;
  173. }
  174. /**
  175. * Stores the pre-defined random allocation settings for later usage
  176. *
  177. * @param bool $enabled is the scheduled allocation enabled
  178. * @param bool $reset reset the recent execution info
  179. * @param workshop_random_allocator_setting $settings settings form data
  180. * @param workshop_allocation_result $result logger
  181. */
  182. protected function store_settings($enabled, $reset, workshop_random_allocator_setting $settings, workshop_allocation_result $result) {
  183. global $DB;
  184. $data = new stdClass();
  185. $data->workshopid = $this->workshop->id;
  186. $data->enabled = $enabled;
  187. $data->submissionend = $this->workshop->submissionend;
  188. $data->settings = $settings->export_text();
  189. if ($reset) {
  190. $data->timeallocated = null;
  191. $data->resultstatus = null;
  192. $data->resultmessage = null;
  193. $data->resultlog = null;
  194. }
  195. $result->log($data->settings, 'debug');
  196. $current = $DB->get_record('workshopallocation_scheduled', array('workshopid' => $data->workshopid), '*', IGNORE_MISSING);
  197. if ($current === false) {
  198. $DB->insert_record('workshopallocation_scheduled', $data);
  199. } else {
  200. $data->id = $current->id;
  201. $DB->update_record('workshopallocation_scheduled', $data);
  202. }
  203. }
  204. }
  205. /**
  206. * Regular jobs to execute via cron
  207. */
  208. function workshopallocation_scheduled_cron() {
  209. global $CFG, $DB;
  210. $sql = "SELECT w.*
  211. FROM {workshopallocation_scheduled} a
  212. JOIN {workshop} w ON a.workshopid = w.id
  213. WHERE a.enabled = 1
  214. AND w.phase = 20
  215. AND w.submissionend > 0
  216. AND w.submissionend < ?
  217. AND (a.timeallocated IS NULL OR a.timeallocated < w.submissionend)";
  218. $workshops = $DB->get_records_sql($sql, array(time()));
  219. if (empty($workshops)) {
  220. mtrace('... no workshops awaiting scheduled allocation. ', '');
  221. return;
  222. }
  223. mtrace('... executing scheduled allocation in '.count($workshops).' workshop(s) ... ', '');
  224. // let's have some fun!
  225. require_once($CFG->dirroot.'/mod/workshop/locallib.php');
  226. foreach ($workshops as $workshop) {
  227. $cm = get_coursemodule_from_instance('workshop', $workshop->id, $workshop->course, false, MUST_EXIST);
  228. $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
  229. $workshop = new workshop($workshop, $cm, $course);
  230. $allocator = $workshop->allocator_instance('scheduled');
  231. $result = $allocator->execute();
  232. // todo inform the teachers about the results
  233. }
  234. }