Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/grade/grading/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 
00046 function get_grading_manager($context_or_areaid = null, $component = null, $area = null) {
00047     global $DB;
00048 
00049     $manager = new grading_manager();
00050 
00051     if (is_object($context_or_areaid)) {
00052         $context = $context_or_areaid;
00053     } else {
00054         $context = null;
00055 
00056         if (is_numeric($context_or_areaid)) {
00057             $manager->load($context_or_areaid);
00058             return $manager;
00059         }
00060     }
00061 
00062     if (!is_null($context)) {
00063         $manager->set_context($context);
00064     }
00065 
00066     if (!is_null($component)) {
00067         $manager->set_component($component);
00068     }
00069 
00070     if (!is_null($area)) {
00071         $manager->set_area($area);
00072     }
00073 
00074     return $manager;
00075 }
00076 
00089 class grading_manager {
00090 
00092     protected $context;
00093 
00095     protected $component;
00096 
00098     protected $area;
00099 
00101     private $areacache = null;
00102 
00106     public function get_context() {
00107         return $this->context;
00108     }
00109 
00115     public function set_context(stdClass $context) {
00116         $this->areacache = null;
00117         $this->context = $context;
00118     }
00119 
00123     public function get_component() {
00124         return $this->component;
00125     }
00126 
00132     public function set_component($component) {
00133         $this->areacache = null;
00134         list($type, $name) = normalize_component($component);
00135         $this->component = $type.'_'.$name;
00136     }
00137 
00141     public function get_area() {
00142         return $this->area;
00143     }
00144 
00150     public function set_area($area) {
00151         $this->areacache = null;
00152         $this->area = $area;
00153     }
00154 
00164     public function get_component_title() {
00165 
00166         $this->ensure_isset(array('context', 'component'));
00167 
00168         if ($this->get_context()->contextlevel == CONTEXT_SYSTEM) {
00169             if ($this->get_component() == 'core_grading') {
00170                 $title = ''; // we are in the bank UI
00171             } else {
00172                 throw new coding_exception('Unsupported component at the system context');
00173             }
00174 
00175         } else if ($this->get_context()->contextlevel >= CONTEXT_COURSE) {
00176             list($context, $course, $cm) = get_context_info_array($this->get_context()->id);
00177 
00178             if (!empty($cm->name)) {
00179                 $title = $cm->name;
00180             } else {
00181                 debugging('Gradable areas are currently supported at the course module level only', DEBUG_DEVELOPER);
00182                 $title = $this->get_component();
00183             }
00184 
00185         } else {
00186             throw new coding_exception('Unsupported gradable area context level');
00187         }
00188 
00189         return $title;
00190     }
00191 
00197     public function get_area_title() {
00198 
00199         if ($this->get_context()->contextlevel == CONTEXT_SYSTEM) {
00200             return '';
00201 
00202         } else if ($this->get_context()->contextlevel >= CONTEXT_COURSE) {
00203             $this->ensure_isset(array('context', 'component', 'area'));
00204             $areas = $this->get_available_areas();
00205             if (array_key_exists($this->get_area(), $areas)) {
00206                 return $areas[$this->get_area()];
00207             } else {
00208                 debugging('Unknown area!');
00209                 return '???';
00210             }
00211 
00212         } else {
00213             throw new coding_exception('Unsupported context level');
00214         }
00215     }
00216 
00222     public function load($areaid) {
00223         global $DB;
00224 
00225         $this->areacache = $DB->get_record('grading_areas', array('id' => $areaid), '*', MUST_EXIST);
00226         $this->context = get_context_instance_by_id($this->areacache->contextid, MUST_EXIST);
00227         $this->component = $this->areacache->component;
00228         $this->area = $this->areacache->areaname;
00229     }
00230 
00238     public static function available_methods($includenone = true) {
00239 
00240         if ($includenone) {
00241             $list = array('' => get_string('gradingmethodnone', 'core_grading'));
00242         } else {
00243             $list = array();
00244         }
00245 
00246         foreach (get_plugin_list('gradingform') as $name => $location) {
00247             $list[$name] = get_string('pluginname', 'gradingform_'.$name);
00248         }
00249 
00250         return $list;
00251     }
00252 
00264     public function get_available_methods($includenone = true) {
00265         $this->ensure_isset(array('context'));
00266         return self::available_methods($includenone);
00267     }
00268 
00278     public static function available_areas($component) {
00279         global $CFG;
00280 
00281         list($plugintype, $pluginname) = normalize_component($component);
00282 
00283         if ($component === 'core_grading') {
00284             return array();
00285 
00286         } else if ($plugintype === 'mod') {
00287             return plugin_callback('mod', $pluginname, 'grading', 'areas_list', null, array());
00288 
00289         } else {
00290             throw new coding_exception('Unsupported area location');
00291         }
00292     }
00293 
00294 
00302     public function get_available_areas() {
00303         global $CFG;
00304 
00305         $this->ensure_isset(array('context', 'component'));
00306 
00307         if ($this->get_context()->contextlevel == CONTEXT_SYSTEM) {
00308             if ($this->get_component() !== 'core_grading') {
00309                 throw new coding_exception('Unsupported component at the system context');
00310             } else {
00311                 return array();
00312             }
00313 
00314         } else if ($this->get_context()->contextlevel == CONTEXT_MODULE) {
00315             list($context, $course, $cm) = get_context_info_array($this->get_context()->id);
00316             return self::available_areas('mod_'.$cm->modname);
00317 
00318         } else {
00319             throw new coding_exception('Unsupported gradable area context level');
00320         }
00321     }
00322 
00328     public function get_active_method() {
00329         global $DB;
00330 
00331         $this->ensure_isset(array('context', 'component', 'area'));
00332 
00333         // get the current grading area record if it exists
00334         if (is_null($this->areacache)) {
00335             $this->areacache = $DB->get_record('grading_areas', array(
00336                 'contextid' => $this->context->id,
00337                 'component' => $this->component,
00338                 'areaname'  => $this->area),
00339             '*', IGNORE_MISSING);
00340         }
00341 
00342         if ($this->areacache === false) {
00343             // no area record yet
00344             return null;
00345         }
00346 
00347         return $this->areacache->activemethod;
00348     }
00349 
00356     public function set_active_method($method) {
00357         global $DB;
00358 
00359         $this->ensure_isset(array('context', 'component', 'area'));
00360 
00361         // make sure the passed method is empty or a valid plugin name
00362         if (empty($method)) {
00363             $method = null;
00364         } else {
00365             if ('gradingform_'.$method !== clean_param('gradingform_'.$method, PARAM_COMPONENT)) {
00366                 throw new moodle_exception('invalid_method_name', 'core_grading');
00367             }
00368             $available = $this->get_available_methods(false);
00369             if (!array_key_exists($method, $available)) {
00370                 throw new moodle_exception('invalid_method_name', 'core_grading');
00371             }
00372         }
00373 
00374         // get the current grading area record if it exists
00375         if (is_null($this->areacache)) {
00376             $this->areacache = $DB->get_record('grading_areas', array(
00377                 'contextid' => $this->context->id,
00378                 'component' => $this->component,
00379                 'areaname'  => $this->area),
00380             '*', IGNORE_MISSING);
00381         }
00382 
00383         $methodchanged = false;
00384 
00385         if ($this->areacache === false) {
00386             // no area record yet, create one with the active method set
00387             $area = array(
00388                 'contextid'     => $this->context->id,
00389                 'component'     => $this->component,
00390                 'areaname'      => $this->area,
00391                 'activemethod'  => $method);
00392             $DB->insert_record('grading_areas', $area);
00393             $methodchanged = true;
00394 
00395         } else {
00396             // update the existing record if needed
00397             if ($this->areacache->activemethod !== $method) {
00398                 $DB->set_field('grading_areas', 'activemethod', $method, array('id' => $this->areacache->id));
00399                 $methodchanged = true;
00400             }
00401         }
00402 
00403         $this->areacache = null;
00404 
00405         return $methodchanged;
00406     }
00407 
00417     public function extend_settings_navigation(settings_navigation $settingsnav, navigation_node $modulenode=null) {
00418 
00419         $this->ensure_isset(array('context', 'component'));
00420 
00421         $areas = $this->get_available_areas();
00422 
00423         if (empty($areas)) {
00424             // no money, no funny
00425             return;
00426 
00427         } else if (count($areas) == 1) {
00428             // make just a single node for the management screen
00429             $areatitle = reset($areas);
00430             $areaname  = key($areas);
00431             $this->set_area($areaname);
00432             $method = $this->get_active_method();
00433             $managementnode = $modulenode->add(get_string('gradingmanagement', 'core_grading'),
00434                 $this->get_management_url(), settings_navigation::TYPE_CUSTOM);
00435             if ($method) {
00436                 $controller = $this->get_controller($method);
00437                 $controller->extend_settings_navigation($settingsnav, $managementnode);
00438             }
00439 
00440         } else {
00441             // make management screen node for each area
00442             $managementnode = $modulenode->add(get_string('gradingmanagement', 'core_grading'),
00443                 null, settings_navigation::TYPE_CUSTOM);
00444             foreach ($areas as $areaname => $areatitle) {
00445                 $this->set_area($areaname);
00446                 $method = $this->get_active_method();
00447                 $node = $managementnode->add($areatitle,
00448                     $this->get_management_url(), settings_navigation::TYPE_CUSTOM);
00449                 if ($method) {
00450                     $controller = $this->get_controller($method);
00451                     $controller->extend_settings_navigation($settingsnav, $node);
00452                 }
00453             }
00454         }
00455     }
00456 
00466     public function extend_navigation(global_navigation $navigation, navigation_node $modulenode=null) {
00467         $this->ensure_isset(array('context', 'component'));
00468 
00469         $areas = $this->get_available_areas();
00470         foreach ($areas as $areaname => $areatitle) {
00471             $this->set_area($areaname);
00472             if ($controller = $this->get_active_controller()) {
00473                 $controller->extend_navigation($navigation, $modulenode);
00474             }
00475         }
00476     }
00477 
00484     public function get_controller($method) {
00485         global $CFG, $DB;
00486 
00487         $this->ensure_isset(array('context', 'component', 'area'));
00488 
00489         // make sure the passed method is a valid plugin name
00490         if ('gradingform_'.$method !== clean_param('gradingform_'.$method, PARAM_COMPONENT)) {
00491             throw new moodle_exception('invalid_method_name', 'core_grading');
00492         }
00493         $available = $this->get_available_methods(false);
00494         if (!array_key_exists($method, $available)) {
00495             throw new moodle_exception('invalid_method_name', 'core_grading');
00496         }
00497 
00498         // get the current grading area record if it exists
00499         if (is_null($this->areacache)) {
00500             $this->areacache = $DB->get_record('grading_areas', array(
00501                 'contextid' => $this->context->id,
00502                 'component' => $this->component,
00503                 'areaname'  => $this->area),
00504             '*', IGNORE_MISSING);
00505         }
00506 
00507         if ($this->areacache === false) {
00508             // no area record yet, create one
00509             $area = array(
00510                 'contextid' => $this->context->id,
00511                 'component' => $this->component,
00512                 'areaname'  => $this->area);
00513             $areaid = $DB->insert_record('grading_areas', $area);
00514             // reload the cache
00515             $this->areacache = $DB->get_record('grading_areas', array('id' => $areaid), '*', MUST_EXIST);
00516         }
00517 
00518         require_once($CFG->dirroot.'/grade/grading/form/'.$method.'/lib.php');
00519         $classname = 'gradingform_'.$method.'_controller';
00520 
00521         return new $classname($this->context, $this->component, $this->area, $this->areacache->id);
00522     }
00523 
00529     public function get_active_controller() {
00530         if ($gradingmethod = $this->get_active_method()) {
00531             $controller = $this->get_controller($gradingmethod);
00532             if ($controller->is_form_available()) {
00533                 return $controller;
00534             }
00535         }
00536         return null;
00537     }
00538 
00545     public function get_management_url(moodle_url $returnurl = null) {
00546 
00547         $this->ensure_isset(array('context', 'component'));
00548 
00549         if ($this->areacache) {
00550             $params = array('areaid' => $this->areacache->id);
00551         } else {
00552             $params = array('contextid' => $this->context->id, 'component' => $this->component);
00553             if ($this->area) {
00554                 $params['area'] = $this->area;
00555             }
00556         }
00557 
00558         if (!is_null($returnurl)) {
00559             $params['returnurl'] = $returnurl->out(false);
00560         }
00561 
00562         return new moodle_url('/grade/grading/manage.php', $params);
00563     }
00564 
00574     public function create_shared_area($method) {
00575         global $DB;
00576 
00577         // generate some unique random name for the new area
00578         $name = $method . '_' . sha1(rand().uniqid($method, true));
00579         // create new area record
00580         $area = array(
00581             'contextid'     => context_system::instance()->id,
00582             'component'     => 'core_grading',
00583             'areaname'      => $name,
00584             'activemethod'  => $method);
00585         return $DB->insert_record('grading_areas', $area);
00586     }
00587 
00595     public static function delete_all_for_context($contextid) {
00596         global $DB;
00597 
00598         $areaids = $DB->get_fieldset_select('grading_areas', 'id', 'contextid = ?', array($contextid));
00599         $methods = array_keys(self::available_methods(false));
00600 
00601         foreach($areaids as $areaid) {
00602             $manager = get_grading_manager($areaid);
00603             foreach ($methods as $method) {
00604                 $controller = $manager->get_controller($method);
00605                 $controller->delete_definition();
00606             }
00607         }
00608 
00609         $DB->delete_records_list('grading_areas', 'id', $areaids);
00610     }
00611 
00629     public static function tokenize($needle) {
00630 
00631         // check if we are searching for the exact phrase
00632         if (preg_match('/^[\s]*"[\s]*(.*?)[\s]*"[\s]*$/', $needle, $matches)) {
00633             $token = $matches[1];
00634             if ($token === '') {
00635                 return array();
00636             } else {
00637                 return array($token);
00638             }
00639         }
00640 
00641         // split the needle into smaller parts separated by non-word characters
00642         $tokens = preg_split("/\W/u", $needle);
00643         // keep just non-empty parts
00644         $tokens = array_filter($tokens);
00645         // distinct
00646         $tokens = array_unique($tokens);
00647         // drop one-letter tokens
00648         foreach ($tokens as $ix => $token) {
00649             if (strlen($token) == 1) {
00650                 unset($tokens[$ix]);
00651             }
00652         }
00653 
00654         return array_values($tokens);
00655     }
00656 
00658 
00665     private function ensure_isset(array $properties) {
00666         foreach ($properties as $property) {
00667             if (!isset($this->$property)) {
00668                 throw new coding_exception('The property "'.$property.'" is not set.');
00669             }
00670         }
00671     }
00672 }
 All Data Structures Namespaces Files Functions Variables Enumerations