From 31cea236afe5faca2d39868f71a0ff81e91f2cb6 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Wed, 28 Mar 2012 18:15:31 +0200 Subject: [PATCH] MDL-32235 improving the allocation results rendering The new renderable class workshop_allocation_result provides a cleaner interface between the allocator's init() method and the allocation.php script. --- mod/workshop/allocation.php | 11 +-- mod/workshop/allocation/lib.php | 111 +++++++++++++++++++++++++++++- mod/workshop/lang/en/workshop.php | 1 + mod/workshop/locallib.php | 60 +--------------- mod/workshop/renderer.php | 66 ++++++++++++++---- 5 files changed, 168 insertions(+), 81 deletions(-) diff --git a/mod/workshop/allocation.php b/mod/workshop/allocation.php index 4579a57384b..33842a8d6ac 100644 --- a/mod/workshop/allocation.php +++ b/mod/workshop/allocation.php @@ -74,13 +74,14 @@ if (!empty($allocators)) { $tabs[] = $row; print_tabs($tabs, $currenttab, $inactive, $activated); -if (!empty($initresult)) { - echo $output->container_start('allocator-init-results'); - echo $output->render(new workshop_allocation_init_result($initresult, $workshop->allocation_url($method))); - echo $output->container_end(); -} else { +if (is_null($initresult->get_status()) or $initresult->get_status() == workshop_allocation_result::STATUS_VOID) { echo $output->container_start('allocator-ui'); echo $allocator->ui(); echo $output->container_end(); +} else { + echo $output->container_start('allocator-init-results'); + echo $output->render($initresult); + echo $output->continue_button($workshop->allocation_url($method)); + echo $output->container_end(); } echo $output->footer(); diff --git a/mod/workshop/allocation/lib.php b/mod/workshop/allocation/lib.php index e8c8a996b83..b900142a2de 100644 --- a/mod/workshop/allocation/lib.php +++ b/mod/workshop/allocation/lib.php @@ -43,11 +43,10 @@ interface workshop_allocator { * * This method is called soon after the allocator is constructed and before any output * is generated. Therefore it may process any data submitted and do other tasks. - * It must not produce any output. The returned value is processed by - * {@see workshop_allocation_init_result} class and rendered. + * It must not produce any output. * * @throws moodle_exception - * @return void|string + * @return workshop_allocation_result */ public function init(); @@ -71,3 +70,109 @@ interface workshop_allocator { */ public static function delete_instance($workshopid); } + + +/** + * Stores the information about the allocation process + * + * Allocator's method init() returns instance of this class. + */ +class workshop_allocation_result implements renderable { + + /** the init() called successfully but no actual allocation was done */ + const STATUS_VOID = 0; + /** allocation was successfully executed */ + const STATUS_EXECUTED = 1; + /** a serious error has occurred during the allocation (as a hole) */ + const STATUS_FAILED = 2; + /** scheduled allocation was configured to be executed later */ + const STATUS_SCHEDULED_ON = 3; + /** scheduled allocation was disabled */ + const STATUS_SCHEDULED_OFF = 4; + + /** @var workshop_allocator the instance of the allocator that produced this result */ + protected $allocator; + /** @var null|int the status of the init() call */ + protected $status = null; + /** @var null|string optional result message to display */ + protected $message = null; + /** @var int the timestamp of when the allocation process started */ + protected $timestart = null; + /** @var int the timestamp of when the final status was set */ + protected $timeend = null; + /** @var array of log message objects, {@see self::log()} */ + protected $logs = array(); + + /** + * Creates new instance of the object + * + * @param workshop_allocator $allocator + */ + public function __construct(workshop_allocator $allocator) { + $this->allocator = $allocator; + $this->timestart = time(); + } + + /** + * Sets the result status of the allocation + * + * @param int $status the status code, eg {@link self::STATUS_OK} + * @param string $message optional status message + */ + public function set_status($status, $message = null) { + $this->status = $status; + $this->message = is_null($message) ? $this->message : $message; + $this->timeend = time(); + } + + /** + * @return int|null the result status + */ + public function get_status() { + return $this->status; + } + + /** + * @return string|null status message + */ + public function get_message() { + return $this->message; + } + + /** + * Appends a new message to the log + * + * The available levels are + * ok - success, eg. new allocation was created + * info - informational message + * error - error message, eg. no more peers available + * debug - debugging info + * + * @param string $message message text to display + * @param string $type the type of the message + * @param int $indent eventual indentation level (the message is related to the previous one with the lower indent) + */ + public function log($message, $type = 'ok', $indent = 0) { + $log = new stdClass(); + $log->message = $message; + $log->type = $type; + $log->indent = $indent; + + $this->logs[] = $log; + } + + /** + * Returns list of logged messages + * + * Each object in the list has public properties + * message string, text to display + * type string, the type of the message + * indent int, indentation level + * + * @see self::log() + * @return array of log objects + */ + public function get_logs() { + return $this->logs; + } +} diff --git a/mod/workshop/lang/en/workshop.php b/mod/workshop/lang/en/workshop.php index 844d0c7321c..5eae47aacf9 100644 --- a/mod/workshop/lang/en/workshop.php +++ b/mod/workshop/lang/en/workshop.php @@ -32,6 +32,7 @@ $string['allocatedetails'] = 'expected: {$a->expected}
submitted: {$a->subm $string['allocation'] = 'Submission allocation'; $string['allocationdone'] = 'Allocation done'; $string['allocationerror'] = 'Allocation error'; +$string['allocationscheduleconfigured'] = 'Scheduled allocation configured'; $string['allsubmissions'] = 'All submissions'; $string['alreadygraded'] = 'Already graded'; $string['areainstructauthors'] = 'Instructions for submission'; diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index 91e11d8ce9d..ca59e77a752 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -44,9 +44,8 @@ require_once($CFG->libdir . '/filelib.php'); */ class workshop { - /** return statuses of {@link add_allocation} to be passed to a workshop renderer method */ + /** error status of the {@link self::add_allocation()} */ const ALLOCATION_EXISTS = -9999; - const ALLOCATION_ERROR = -9998; /** the internal code of the workshop phases as are stored in the database */ const PHASE_SETUP = 10; @@ -965,7 +964,7 @@ class workshop { * @param int $reviewerid User ID * @param int $weight of the new assessment, from 0 to 16 * @param bool $bulk repeated inserts into DB expected - * @return int ID of the new assessment or an error code + * @return int ID of the new assessment or an error code {@link self::ALLOCATION_EXISTS} if the allocation already exists */ public function add_allocation(stdclass $submission, $reviewerid, $weight=1, $bulk=false) { global $DB; @@ -3011,61 +3010,6 @@ class workshop_message implements renderable { } } -/** - * Renderable output of submissions allocation process - */ -class workshop_allocation_init_result implements renderable { - - /** @var workshop_message */ - protected $message; - /** @var array of steps */ - protected $info = array(); - /** @var moodle_url */ - protected $continue; - - /** - * Supplied argument can be either integer status code or an array of string messages. Messages - * in a array can have optional prefix or prefixes, using '::' as delimiter. Prefixes determine - * the type of the message and may influence its visualisation. - * - * @param mixed $result int|array returned by {@see workshop_allocator::init()} - * @param moodle_url to continue - */ - public function __construct($result, moodle_url $continue) { - - if ($result === workshop::ALLOCATION_ERROR) { - $this->message = new workshop_message(get_string('allocationerror', 'workshop'), workshop_message::TYPE_ERROR); - } else { - $this->message = new workshop_message(get_string('allocationdone', 'workshop'), workshop_message::TYPE_OK); - if (is_array($result)) { - $this->info = $result; - } - } - - $this->continue = $continue; - } - - /** - * @return workshop_message instance to render - */ - public function get_message() { - return $this->message; - } - - /** - * @return array of strings with allocation process details - */ - public function get_info() { - return $this->info; - } - - /** - * @return moodle_url where the user shoudl continue - */ - public function get_continue_url() { - return $this->continue; - } -} /** * Renderable component containing all the data needed to display the grading report diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index b9daa8596c2..22dbab7d4fc 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -319,33 +319,69 @@ class mod_workshop_renderer extends plugin_renderer_base { /** * Renders the result of the submissions allocation process * - * @param workshop_allocation_init_result - * @return string html to be echoed + * @param workshop_allocation_result $result as returned by the allocator's init() method + * @return string HTML to be echoed */ - protected function render_workshop_allocation_init_result(workshop_allocation_init_result $result) { + protected function render_workshop_allocation_result(workshop_allocation_result $result) { + + $status = $result->get_status(); + + if (is_null($status) or $status == workshop_allocation_result::STATUS_VOID) { + debugging('Attempt to render workshop_allocation_result with empty status', DEBUG_DEVELOPER); + return ''; + } + + switch ($status) { + case workshop_allocation_result::STATUS_FAILED: + if ($message = $result->get_message()) { + $message = new workshop_message($message, workshop_message::TYPE_ERROR); + } else { + $message = new workshop_message(get_string('allocationerror', 'workshop'), workshop_message::TYPE_ERROR); + } + break; + + case workshop_allocation_result::STATUS_SCHEDULED_ON: + case workshop_allocation_result::STATUS_SCHEDULED_OFF: + if ($message = $result->get_message()) { + $message = new workshop_message($message, workshop_message::TYPE_INFO); + } else { + $message = new workshop_message(get_string('allocationscheduleconfigured', 'workshop'), workshop_message::TYPE_INFO); + } + break; + + case workshop_allocation_result::STATUS_EXECUTED: + if ($message = $result->get_message()) { + $message = new workshop_message($message, workshop_message::TYPE_OK); + } else { + $message = new workshop_message(get_string('allocationdone', 'workshop'), workshop_message::TYPE_OK); + } + break; + + default: + throw new coding_exception('Unknown allocation result status', $status); + } // start with the message - $o = $this->render($result->get_message()); + $o = $this->render($message); // display the details about the process if available - $info = $result->get_info(); - if (is_array($info) and !empty($info)) { + $logs = $result->get_logs(); + if (is_array($logs) and !empty($logs)) { $o .= html_writer::start_tag('ul', array('class' => 'allocation-init-results')); - foreach ($info as $message) { - $parts = explode('::', $message); - $text = array_pop($parts); - $class = implode(' ', $parts); - if (in_array('debug', $parts) && !debugging('', DEBUG_DEVELOPER)) { - // do not display allocation debugging messages + foreach ($logs as $log) { + if ($log->type == 'debug' and !debugging('', DEBUG_DEVELOPER)) { + // display allocation debugging messages for developers only continue; } - $o .= html_writer::tag('li', $text, array('class' => $class)) . "\n"; + $class = $log->type; + if ($log->indent) { + $class .= ' indent'; + } + $o .= html_writer::tag('li', $log->message, array('class' => $class)).PHP_EOL; } $o .= html_writer::end_tag('ul'); } - $o .= $this->output->continue_button($result->get_continue_url()); - return $o; }