Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/mod/workshop/form/comments/lib.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00027 defined('MOODLE_INTERNAL') || die();
00028 
00029 require_once(dirname(dirname(__FILE__)) . '/lib.php');  // interface definition
00030 require_once($CFG->libdir . '/gradelib.php');           // to handle float vs decimal issues
00031 
00032 function workshopform_comments_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload) {
00033     global $DB;
00034 
00035     if ($context->contextlevel != CONTEXT_MODULE) {
00036         return false;
00037     }
00038 
00039     require_login($course, true, $cm);
00040 
00041     if ($filearea !== 'description') {
00042         return false;
00043     }
00044 
00045     $itemid = (int)array_shift($args); // the id of the assessment form dimension
00046     if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) {
00047         send_file_not_found();
00048     }
00049 
00050     if (!$dimension = $DB->get_record('workshopform_comments', array('id' => $itemid ,'workshopid' => $workshop->id))) {
00051         send_file_not_found();
00052     }
00053 
00054     // TODO now make sure the user is allowed to see the file
00055     // (media embedded into the dimension description)
00056     $fs = get_file_storage();
00057     $relativepath = implode('/', $args);
00058     $fullpath = "/$context->id/workshopform_comments/$filearea/$itemid/$relativepath";
00059     if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
00060         return false;
00061     }
00062 
00063     // finally send the file
00064     send_stored_file($file);
00065 }
00066 
00070 class workshop_comments_strategy implements workshop_strategy {
00071 
00073     const MINDIMS = 3;
00074 
00076     const ADDDIMS = 2;
00077 
00079     protected $workshop;
00080 
00082     protected $dimensions = null;
00083 
00085     protected $descriptionopts;
00086 
00093     public function __construct(workshop $workshop) {
00094         $this->workshop         = $workshop;
00095         $this->dimensions       = $this->load_fields();
00096         $this->descriptionopts  = array('trusttext' => true, 'subdirs' => false, 'maxfiles' => -1);
00097     }
00098 
00104     public function get_edit_strategy_form($actionurl=null) {
00105         global $CFG;    // needed because the included files use it
00106         global $PAGE;
00107 
00108         require_once(dirname(__FILE__) . '/edit_form.php');
00109 
00110         $fields             = $this->prepare_form_fields($this->dimensions);
00111         $nodimensions       = count($this->dimensions);
00112         $norepeatsdefault   = max($nodimensions + self::ADDDIMS, self::MINDIMS);
00113         $norepeats          = optional_param('norepeats', $norepeatsdefault, PARAM_INT);    // number of dimensions
00114         $noadddims          = optional_param('noadddims', '', PARAM_ALPHA);                 // shall we add more?
00115         if ($noadddims) {
00116             $norepeats += self::ADDDIMS;
00117         }
00118 
00119         // Append editor context to editor options, giving preference to existing context.
00120         $this->descriptionopts = array_merge(array('context' => $PAGE->context), $this->descriptionopts);
00121 
00122         // prepare the embedded files
00123         for ($i = 0; $i < $nodimensions; $i++) {
00124             // prepare all editor elements
00125             $fields = file_prepare_standard_editor($fields, 'description__idx_'.$i, $this->descriptionopts,
00126                 $PAGE->context, 'workshopform_comments', 'description', $fields->{'dimensionid__idx_'.$i});
00127         }
00128 
00129         $customdata = array();
00130         $customdata['workshop'] = $this->workshop;
00131         $customdata['strategy'] = $this;
00132         $customdata['norepeats'] = $norepeats;
00133         $customdata['descriptionopts'] = $this->descriptionopts;
00134         $customdata['current']  = $fields;
00135         $attributes = array('class' => 'editstrategyform');
00136 
00137         return new workshop_edit_comments_strategy_form($actionurl, $customdata, 'post', '', $attributes);
00138     }
00139 
00152     public function save_edit_strategy_form(stdclass $data) {
00153         global $DB, $PAGE;
00154 
00155         $workshopid = $data->workshopid;
00156         $norepeats  = $data->norepeats;
00157 
00158         $data       = $this->prepare_database_fields($data);
00159         $records    = $data->comments;  // records to be saved into {workshopform_comments}
00160         $todelete   = array();              // dimension ids to be deleted
00161 
00162         for ($i=0; $i < $norepeats; $i++) {
00163             $record = $records[$i];
00164             if (0 == strlen(trim($record->description_editor['text']))) {
00165                 if (!empty($record->id)) {
00166                     // existing record with empty description - to be deleted
00167                     $todelete[] = $record->id;
00168                 }
00169                 continue;
00170             }
00171             if (empty($record->id)) {
00172                 // new field
00173                 $record->id         = $DB->insert_record('workshopform_comments', $record);
00174             } else {
00175                 // exiting field
00176                 $DB->update_record('workshopform_comments', $record);
00177             }
00178             // re-save with correct path to embedded media files
00179             $record = file_postupdate_standard_editor($record, 'description', $this->descriptionopts,
00180                                                       $PAGE->context, 'workshopform_comments', 'description', $record->id);
00181             $DB->update_record('workshopform_comments', $record);
00182         }
00183         $this->delete_dimensions($todelete);
00184     }
00185 
00195     public function get_assessment_form(moodle_url $actionurl=null, $mode='preview', stdclass $assessment=null, $editable=true, $options=array()) {
00196         global $CFG;    // needed because the included files use it
00197         global $PAGE;
00198         global $DB;
00199         require_once(dirname(__FILE__) . '/assessment_form.php');
00200 
00201         $fields         = $this->prepare_form_fields($this->dimensions);
00202         $nodimensions   = count($this->dimensions);
00203 
00204         // rewrite URLs to the embedded files
00205         for ($i = 0; $i < $nodimensions; $i++) {
00206             $fields->{'description__idx_'.$i} = file_rewrite_pluginfile_urls($fields->{'description__idx_'.$i},
00207                 'pluginfile.php', $PAGE->context->id, 'workshopform_comments', 'description', $fields->{'dimensionid__idx_'.$i});
00208         }
00209 
00210         if ('assessment' === $mode and !empty($assessment)) {
00211             // load the previously saved assessment data
00212             $grades = $this->get_current_assessment_data($assessment);
00213             $current = new stdclass();
00214             for ($i = 0; $i < $nodimensions; $i++) {
00215                 $dimid = $fields->{'dimensionid__idx_'.$i};
00216                 if (isset($grades[$dimid])) {
00217                     $current->{'gradeid__idx_'.$i}      = $grades[$dimid]->id;
00218                     $current->{'peercomment__idx_'.$i}  = $grades[$dimid]->peercomment;
00219                 }
00220             }
00221         }
00222 
00223         // set up the required custom data common for all strategies
00224         $customdata['strategy'] = $this;
00225         $customdata['workshop'] = $this->workshop;
00226         $customdata['mode']     = $mode;
00227         $customdata['options']  = $options;
00228 
00229         // set up strategy-specific custom data
00230         $customdata['nodims']   = $nodimensions;
00231         $customdata['fields']   = $fields;
00232         $customdata['current']  = isset($current) ? $current : null;
00233         $attributes = array('class' => 'assessmentform comments');
00234 
00235         return new workshop_comments_assessment_form($actionurl, $customdata, 'post', '', $attributes, $editable);
00236     }
00237 
00247     public function save_assessment(stdclass $assessment, stdclass $data) {
00248         global $DB;
00249 
00250         if (!isset($data->nodims)) {
00251             throw new coding_exception('You did not send me the number of assessment dimensions to process');
00252         }
00253         for ($i = 0; $i < $data->nodims; $i++) {
00254             $grade = new stdclass();
00255             $grade->id = $data->{'gradeid__idx_' . $i};
00256             $grade->assessmentid = $assessment->id;
00257             $grade->strategy = 'comments';
00258             $grade->dimensionid = $data->{'dimensionid__idx_' . $i};
00259             $grade->grade = 100.00000;
00260             $grade->peercomment = $data->{'peercomment__idx_' . $i};
00261             $grade->peercommentformat = FORMAT_MOODLE;
00262             if (empty($grade->id)) {
00263                 // new grade
00264                 $grade->id = $DB->insert_record('workshop_grades', $grade);
00265             } else {
00266                 // updated grade
00267                 $DB->update_record('workshop_grades', $grade);
00268             }
00269         }
00270         $this->workshop->set_peer_grade($assessment->id, 100.00000);
00271         return 100.0000;
00272     }
00273 
00279     public function form_ready() {
00280         if (count($this->dimensions) > 0) {
00281             return true;
00282         }
00283         return false;
00284     }
00285 
00289     public function get_assessments_recordset($restrict=null) {
00290         global $DB;
00291 
00292         $sql = 'SELECT s.id AS submissionid,
00293                        a.id AS assessmentid, a.weight AS assessmentweight, a.reviewerid, a.gradinggrade,
00294                        g.dimensionid, 100.00000 AS grade
00295                   FROM {workshop_submissions} s
00296                   JOIN {workshop_assessments} a ON (a.submissionid = s.id)
00297                   JOIN {workshop_grades} g ON (g.assessmentid = a.id AND g.strategy = :strategy)
00298                  WHERE s.example=0 AND s.workshopid=:workshopid'; // to be cont.
00299         $params = array('workshopid' => $this->workshop->id, 'strategy' => $this->workshop->strategy);
00300 
00301         if (is_null($restrict)) {
00302             // update all users - no more conditions
00303         } elseif (!empty($restrict)) {
00304             list($usql, $uparams) = $DB->get_in_or_equal($restrict, SQL_PARAMS_NAMED);
00305             $sql .= " AND a.reviewerid $usql";
00306             $params = array_merge($params, $uparams);
00307         } else {
00308             throw new coding_exception('Empty value is not a valid parameter here');
00309         }
00310 
00311         $sql .= ' ORDER BY s.id'; // this is important for bulk processing
00312 
00313         return $DB->get_recordset_sql($sql, $params);
00314     }
00315 
00319     public function get_dimensions_info() {
00320         global $DB;
00321 
00322         $params = array('workshopid' => $this->workshop->id);
00323         $dimrecords = $DB->get_records('workshopform_comments', array('workshopid' => $this->workshop->id), 'sort', 'id');
00324         $diminfo = array();
00325         foreach ($dimrecords as $dimid => $dimrecord) {
00326             $diminfo[$dimid] = new stdclass();
00327             $diminfo[$dimid]->id = $dimid;
00328             $diminfo[$dimid]->weight = 1;
00329             $diminfo[$dimid]->min = 100;
00330             $diminfo[$dimid]->max = 100;
00331         }
00332         return $diminfo;
00333     }
00334 
00344     public static function scale_used($scaleid, $workshopid=null) {
00345         return false;
00346     }
00347 
00355     public static function delete_instance($workshopid) {
00356         global $DB;
00357 
00358         $DB->delete_records('workshopform_comments', array('workshopid' => $workshopid));
00359     }
00360 
00362     // Internal methods                                                           //
00364 
00370     protected function load_fields() {
00371         global $DB;
00372         return $DB->get_records('workshopform_comments', array('workshopid' => $this->workshop->id), 'sort');
00373     }
00374 
00381     protected function prepare_form_fields(array $raw) {
00382 
00383         $formdata = new stdclass();
00384         $key = 0;
00385         foreach ($raw as $dimension) {
00386             $formdata->{'dimensionid__idx_' . $key}             = $dimension->id;
00387             $formdata->{'description__idx_' . $key}             = $dimension->description;
00388             $formdata->{'description__idx_' . $key.'format'}    = $dimension->descriptionformat;
00389             $key++;
00390         }
00391         return $formdata;
00392     }
00393 
00402     protected function delete_dimensions(array $ids) {
00403         global $DB, $PAGE;
00404 
00405         $fs = get_file_storage();
00406         foreach ($ids as $id) {
00407             if (!empty($id)) {   // to prevent accidental removal of all files in the area
00408                 $fs->delete_area_files($PAGE->context->id, 'workshopform_comments', 'description', $id);
00409             }
00410         }
00411         $DB->delete_records_list('workshopform_comments', 'id', $ids);
00412     }
00413 
00425     protected function prepare_database_fields(stdclass $raw) {
00426         global $PAGE;
00427 
00428         $cook               = new stdclass(); // to be returned
00429         $cook->comments = array();        // records to be stored in {workshopform_comments}
00430 
00431         for ($i = 0; $i < $raw->norepeats; $i++) {
00432             $cook->comments[$i]                     = new stdclass();
00433             $cook->comments[$i]->id                 = $raw->{'dimensionid__idx_'.$i};
00434             $cook->comments[$i]->workshopid         = $this->workshop->id;
00435             $cook->comments[$i]->sort               = $i + 1;
00436             $cook->comments[$i]->description_editor = $raw->{'description__idx_'.$i.'_editor'};
00437         }
00438         return $cook;
00439     }
00440 
00447     protected function get_current_assessment_data(stdclass $assessment) {
00448         global $DB;
00449 
00450         if (empty($this->dimensions)) {
00451             return array();
00452         }
00453         list($dimsql, $dimparams) = $DB->get_in_or_equal(array_keys($this->dimensions), SQL_PARAMS_NAMED);
00454         // beware! the caller may rely on the returned array is indexed by dimensionid
00455         $sql = "SELECT dimensionid, wg.*
00456                   FROM {workshop_grades} wg
00457                  WHERE assessmentid = :assessmentid AND strategy= :strategy AND dimensionid $dimsql";
00458         $params = array('assessmentid' => $assessment->id, 'strategy' => 'comments');
00459         $params = array_merge($params, $dimparams);
00460 
00461         return $DB->get_records_sql($sql, $params);
00462     }
00463 }
 All Data Structures Namespaces Files Functions Variables Enumerations