Moodle开发笔记7-Activity module开发
来源:互联网 发布:淘宝主账号修改密码 编辑:程序博客网 时间:2024/06/06 08:57
Activity module是moodle里最复杂的module类型。Assignment, Quiz等module都属于activitymodule。
Activitymodule can support for gradebook connectivity, course groups, course reset,and backup and restore.
一个典型的Activity都应该包含下列文件
- mod_form.php - a form to set up or update an instance of this module
- version.php - defines some meta-info
- icon.gif - a 16x16 icon for the module
- db/install.xml - defines the structure of db tables for all database types. Is used during module installation
- db/upgrade.php - defines changes in the structure of db tables. Is used during module upgrade
- db/access.php - defines module capabilities
- index.php - a page to list all instances in a course
- view.php - a page to view a particular instance
- lib.php - any/all functions defined by the module should be in here. If the module name is called widget, then the required functions include:
· widget_install() -will be called during the installation of the module
· widget_add_instance()- code to add a new instance of widget
· widget_update_instance()- code to update an existing instance
· widget_delete_instance()- code to delete an instance
· widget_user_outline()- given an instance, return a summary of a user's contribution
· widget_user_complete()- given an instance, print details of a user's contribution
· widget_get_view_actions()/ widget_get_post_actions() - Used by the participation report(course/report/participation/index.php) to classify actions in the logs table.
· Other functionsavailable but not required are:
o widget_delete_course()- code to clean up anything that would be leftover after all instances aredeleted
o widget_process_options()- code to pre-process the form data from module settings
o widget_reset_course_form()and widget_delete_userdata() - used to implement Reset coursefeature.
· To avoid possibleconflict, any module functions should be named starting with widget_ and anyconstants you define should start with WIDGET_
- backuplib.php and restorelib.php (optional)
- settings.php or settingstree.php - (optional) a definition of an admin settings page for this module. mod/assignment/settings.php is a good simple example. mod/quiz/settingstree.php is a more complex example.
- defaults.php - lets you easily define default values for your configuration variables. It is included by upgrade_activity_modules in lib/adminlib.php. It should define an array $defaults. These values are then loaded into the config table. Alternatively, if you set $defaults['_use_config_plugins'] to true, the values are instead loaded into the config_plugins table, which is better practice. See mod/quiz/defaults.php for an example. (This apparently only works with moodle 2.x branch.)
- lang/en_utf8/widget.php - (optional) Lastly, each module will have some language files that contain strings for that module.
Moodle提供了一个activity template named NEWMODULE, you can download it at http://moodle.org/mod/data/view.php?d=13&rid=715&filter=1.当你开发activity时应该based onNEWMODULE。需要注意的是,NEWMODULE还是缺少了非常重要的功能没有涉及:backup and restore。少了这2个功能后果会很严重,很多moodle system不会安装缺少这2个function的activity module。
下面以开发一个最为简单的“Foo” activity为例。It includes following features
l gradebook connectivity
l course groups
l course reset
l backup and restore
Step 1 use NEWMODULE as template
1. 下载最新的NEWMODULE
2. rename “newmodule” folder toour module name “foo”
3. search目录下所有文件的内容,用”foo”替代”newmodule”
4. rename lang/en_utf8/newmodule.php to foo.php
5. copy the whole “foo” folder to<moodle home>/mod folder
Step 2 修改mod_form.php (important)
mod_form.php提供了当teacher create a newmodule instance时出现的forminterface,teacher可以在该form输入对该moduleinstance的setting。
mod_form.php要定义一个mod_<MODULE NAME>_mod_form class,该class需要extend moodleform_mod class.
require_once($CFG->dirroot.'/course/moodleform_mod.php');
classmod_foo_mod_form extends moodleform_mod {
在mod_foo_mod_form class里,需要定义“definition”function,并在该function里创建forminstance, and then add elements (activity instance name, instruction, dateselector and grade option ) to the form instance。需要注意的是:addedelement name必须和对应的field name in database相match!!
function definition() {
global$COURSE, $CFG;
//Create form instance
$mform =& $this->_form;
// creates the form header
$mform->addElement('header','general', get_string('general', 'form'));
//create text input
$mform->addElement('text', 'name',get_string('fooname', 'foo'), array('size'=>'64'));
//input element type is controlled by the valueof the setType element
$mform->setType('name', PARAM_TEXT);
//UI rules are defined by setting addRule
$mform->addRule('name',null, 'required', null, 'client');
// set instruction (html editor input)
$mform->addElement('htmleditor', 'instructions',get_string('instructions', 'foo'));
$mform->setType('instructions', PARAM_RAW);
$mform->addRule('instructions',get_string('required'), 'required', null, 'client');
//create html editor help button
$mform->setHelpButton('instructions',array('questions', 'richtext'), false, 'editorhelpbutton');
//create date available (date selector)
$mform->addElement('date_time_selector','timeavailable', get_string('timeavailable', 'foo'),array('optional'=>true));
$mform->setDefault('timeavailable', 0);
$mform->addElement('date_time_selector','timedue', get_string('timedue', 'foo'), array('optional'=>true));
$mform->setDefault('timedue',0);
// set grade (scale type input)
$mform->addElement('modgrade', 'scale',get_string('grade'), false);
$mform->disabledIf('scale','assessed', 'eq', 0);
//调用standard_coursemodule_elements方法为common module进行设置。
//比如是否support group等
//该方法同时也会controls the display of multiple form elements.
$features = array('groups'=>true, 'groupings'=>true,
'groupmembersonly'=>true,'outcomes'=>false, 'gradecat'=>false,'idnumber'=>false);
$this->standard_coursemodule_elements($features);
//add form buttons (cancel and submit)
$this->add_action_buttons();
}
Step 3 修改version.php
version.php用于manage database upgrades andenforce required versions of Moodle. upgrade.php会根据version.php的版本号来决定是否需要升级(例如upgrade related table in db)。该文件里定义了
l 该module的current verison
l Moodle的require version
l 以及cron
$module->version = 2009060103;
$module->requires= 2007101509;
$module->cron = 0;
Step 4 修改icon.gif
Step 5 修改install.xml
install.xml定义了the database structure for the module。你可以基于newmodule tempalte的install.xml来通过moodle XMLDB editortool or 自己写代码来定义该module的database structure。
每个activity module必须至少有一个dbtable,而且该table name必须和module name相同。例如fooactivity的table name is foo。该table最起码要包含下列fields:id, name, intro, and modifiedtime
Foo activity我们在foo table里多定义了一些fields:course, timeavailable, timedue, and scale。
另外,fooactivity还多定义了一个table“foo_responses”,该table包含了下列fields:id, fooid, userid, response, and timemodified。该table用于store one record for each user response in each foo activityinstance。
另外,在install.xml里,还定义了database statements that are used to store user log data for a user's interaction with the module。newmodule template by default对这部分是在log_display table定义了view, add, and update action for each module。你也可以添加更多的action type for logging。Activity module只是使用default的codes
<STATEMENTS>
<STATEMENT NAME="insert log_display" TYPE="insert" TABLE="log_display" COMMENT="Initial insert of records on tablelog_display">
<SENTENCES>
<SENTENCETEXT="(module, action, mtable, field) VALUES ('foo','view', 'foo', 'name')" />
<SENTENCETEXT="(module, action, mtable, field) VALUES ('foo', 'add', 'foo', 'name')" />
<SENTENCETEXT="(module, action, mtable, field) VALUES ('foo', 'update', 'foo', 'name')" />
??其实上面这段在table log_display里添加3个records有什么用?
对于install.xml,如果该activity module已经开始使用,而你又有对install.xml进行修改,那么就要同时修改version.php。如果你是对install.xml的database structure进行修改,那么还要配合upgrade.php来进行。
Step 6 修改db/access.php
access.php controls which capabilities can be assigned for user access. Fooactivity定义了2个capabilities:
l mod/foo:submit course student, teacher and admin areallowed
l mod/foo:viewall student roleis not allowed
<?php
//Define access capbilities
$mod_foo_capabilities = array(
'mod/foo:submit' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'legacy' => array(
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'admin' => CAP_ALLOW
)
),
'mod/foo:viewall' => array(
'captype' => 'view',
'contextlevel' => CONTEXT_MODULE,
'legacy' => array(
'student' => CAP_PREVENT,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'admin' => CAP_ALLOW
)
)
);
?>
Step 7 修改index.php (important)
index.php file 会lists all of the instances ofactivity that are present in the course以及当前logined user对所有activity的response。
//include moodleconfig file and foo activity lib.php
require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once(dirname(__FILE__).'/lib.php');
//get course id from requestparam
$id= required_param('id', PARAM_INT); // course
//如果global var$course与根据id从db获取的course不匹配,则error
if (! $course = get_record('course', 'id', $id)) {
error('Course ID is incorrect');
}
require_course_login($course);
add_to_log($course->id,'foo','viewall',"index.php?id=$course->id", '');
$strfoos= get_string('modulenameplural', 'foo');
$strfoo = get_string('modulename', 'foo');
///Print the header with navigation links
$navlinks= array();
$navlinks[]=array('name'=>$strfoos, 'link' => '', 'type' => 'activity');
$navigation= build_navigation($navlinks);
print_header_simple($strfoos,'', $navigation, '', '', true, '', navmenu($course));
//get all “foo” activity instance in the course
if (! $foos =get_all_instances_in_course('foo', $course)) {
//如果no instance, then call function notice to print msg and exit
notice(get_string('thereareno', 'moodle', $strfoos), "../../course/view.php?id=$course->id"); //changed
die;
}
//获取当前user在该course的所有foo activity instances的response
//返回一个以foo instance id为key,response record为value的array “responses”
$sql= "SELECT foo_a.*
FROM {$CFG->prefix}foo foo_b,
{$CFG->prefix}foo_responsesfoo_a
WHERE foo_a.fooid = foo_b.id AND
foo_b.course = $course->id AND foo_a.userid = $USER->id";
$responses= array () ;
if (isloggedin() and!isguestuser()
and $allresponses = get_records_sql($sql)) {
foreach ($allresponses as $ra) {
$responses[$ra->fooid] = $ra;
}
unset($allresponses);
}
$timenow = time();
$strname = get_string('name');
$strweek = get_string('week');
$strtopic= get_string('topic');
$userquery= get_string('userquery','foo');
$yes= get_string('yes','foo');
$no= get_string('no','foo');
//set table format accordingto course format
if ($course->format == 'weeks') {
$table->head = array ($strweek, $strname, $userquery);
$table->align = array ('center', 'left');
} else if ($course->format =='topics') {
$table->head = array ($strtopic, $strname,$userquery);
$table->align = array ('center', 'left', 'left', 'left');
} else {
$table->head = array ($strname,$userquery);
$table->align = array ('left', 'left', 'left');
}
//loop all foo instances in the course and print each fooinfo with response
foreach($foos as $foo) {
if (!empty($responses[$foo->id])) {
$response = $responses[$foo->id];
} else {
$response = "";
}
if (!empty($response->response)){
if( $response->response == "1" ) {
$fa = $yes;
}
else {
$fa = $no;
} $response->response;
} else {
$fa = $no;
}
// Courses are divided into sections,typically weeks or topics, depending on the course
//format selected. Following code deals with section display.
// $foo居然有一个element “section”包含了session info
$printsection= "";
if ($foo->section !== $currentsection) {
if ($foo->section) {
$printsection = $foo->section;
}
if ($currentsection !== "") {
$table->data[] = 'hr';
}
$currentsection = $foo->section;
}
//Calculate the href
if (!$foo->visible) { //check if the instance is hidden or visible
//Show dimmed if the mod is hidden
$tt_href = "<a class=/"dimmed/" href=/"view.php?id=$foo->coursemodule/">".format_string($foo->name,true)."</a>";
} else {
//Show normal if the mod is visible
$tt_href = "<a href=/"view.php?id=$foo->coursemodule/">".format_string($foo->name,true)."</a>";
}
if ($course->format == "weeks" || $course->format == "topics") {
$table->data[] = array ($printsection, $tt_href, $fa);
} else {
$table->data[] = array ($tt_href, $fa);
}
}
print_heading($strfoos);
print_table($table);
///Finish the page
print_footer($course);
Step 8 修改view.php (important)
view.php是当user (teacher or student) click 创建好的activityinstance的 link后出现的interface。
Foo activity的view.php会
l 显示一条问题
l 如果user答过这条问题,会显示他的response
l 处理当user在view.phpclick cancel button
l 处理当user在view.phpclick submit button
下面会讲解view.php里的一些重要代码
// submit_form.php定义了一个form class which extends moodleform,
//when user access fooactivity instance, provide a form to user to submit
// moodleform和之前所说的moodleform_mod用法相似。
require_once(dirname(__FILE__).'/submit_form.php');
//下面这部分代码是通过course module id or module instance id来获取对应的course module object ($cm) , course object($course) and foo instance object。
//!!Course module object是来自table “mdl
//注意:course module id和module instance id是不同的,但又是相关的。
//例如,当teacher create a foo activity instance时,就会同时在”mdl_foo”table和”mdl_course_modules”table各inserta record,其中”mdl_foo”table的”id”field就是moduleinstance id,而”mdl_course_modules”table的”id”field是该instance的course module id,而而”mdl_course_modules”table的”instance”field则是和”mdl_foo”table的”id”field匹配。你可以说”mdl_foo” table和”mdl_course_modules” table里的record是一对一关系。
// Course module object是来自table “mdl_course_modules”record,它包含有下列fields: id (course module id), course (course id), module(对应tablemdl_modules的id),instance (对应tablemdl_foo的id),section (所在course里的section id)
//如果你想通过instance id来获取course module record,可以调用get_coursemodule_from_instance function。如果你想通过coursemodule id来获取coursemodule record,可以调用get_coursemodule_from_id function
$id= optional_param('id', 0, PARAM_INT); // course_module ID, or
$a = optional_param('a', 0, PARAM_INT); // foo instance ID
if ($id) {
if (! $cm = get_coursemodule_from_id('foo', $id))
error('Course Module ID was incorrect');
if (! $course = get_record('course', 'id', $cm->course))
error('Course is misconfigured');
if (! $foo = get_record('foo', 'id', $cm->instance))
error('Course module is incorrect');
} else if ($a) {
if (! $foo = get_record('foo', 'id', $a))
error('Course module is incorrect');
if (! $course = get_record('course', 'id', $foo->course))
error('Course is misconfigured');
if (! $cm = get_coursemodule_from_instance('foo', $foo->id, $course->id))
error('Course Module ID was incorrect');
}
//print navigationlinks
$navlinks = array();
$navlinks[] = array('name' => $strfoos, 'link' => "index.php?id=$course->id", 'type' => 'activity');
$navlinks[] = array('name' => format_string($foo->name), 'link' => '', 'type' => 'activityinstance');
$navigation= build_navigation($navlinks);
print_header_simple(format_string($foo->name),'', $navigation, '', '', true,update_module_button($cm->id, $course->id, $strfoo),navmenu($course, $cm));
//获取该module instance的context!!
$context = get_context_instance(CONTEXT_MODULE,$cm->id);
//check当前user在该context里是否具有submit permission,如果没有permission,则不做任何事
if (has_capability('mod/foo:submit', $context)) {
//然后下面是具有submit permission要进行的操作,分为3 parts,一是当user刚进入该module instance时的代码,二是当user click cancel button,三是当userclick submit button。
//注意,无论是刚进入该instance,还是clickcancel or submit button,都由view.php处理。
$mform= new foo_submit_form("view.php?id=$cm->id");
if ($mform->is_cancelled()){//whenuser click cancel button
} else if ($fromform=$mform->get_data()){ //when user click submit button
add_to_log($course->id, "foo", "add response", "view.php?id=$cm->id", $foo->name, $cm->id);
$response = new object();
$response->response= $fromform->response;
$response->fooid= $foo->id;
$response->userid= $USER->id;
$response->timemodified= time();
//如果user之前曾经submit过,则update record
if ($old_response = get_record('foo_responses', 'fooid', $response->fooid,'userid', $USER->id)) {
$response->id = $old_response->id;
if(! update_record('foo_responses', $response)) {
echo get_string('errorupdateresponse','foo');
}
}
//如果user未曾submit过,则insert record
else {
if(!insert_record('foo_responses', $response)) echo get_string('errorinsertresponse','foo');
}
// Set grades,详见该例子的lib.php/foo_grade function
foo_grade($foo,$USER->id, $response->response);
} else {
}
//***显示user进入该instance时要显示的form***
$data =new stdClass();
$data->cmid= $cm->id;
//get response if already exists to preload in form
if ($old_response = get_record('foo_responses', 'fooid', $foo->id, 'userid', $USER->id)) {
$data->response = $old_response->response;
}
$mform->set_data($data);
$mform->display();
//**************************
echo('<strong>'.get_string('submissions','foo').'</strong><br>');
//!!显示user的response!!
//如果有viewall permission,则show allparticipant responses
if (has_capability('mod/foo:viewall', $context) && $participants = foo_get_participants($foo->id)) {
foreach ($participants as $id => $participant) {
//print_object($id->id);
$user = get_record( 'user', 'id', $id );
echo( '<br>'.$user->firstname." ".$user->lastname.': ' );
//call foo_user_complete function to look up their responses
foo_user_complete( $user, $foo );
echo( '</br>' );
}
}
//若没有viewall permission,则显示current user own response
else {
echo('<br>');
foo_user_complete( $USER, $foo);
//****下面部分是support moodle groupfeature*****
//如果enable group,那么就显示所在的group的其他partipantresponses
// see if groups are enabled for an activity
$groupmode = groups_get_activity_groupmode($cm);
if ($groupmode) {
groups_get_activity_group($cm, true);
groups_print_activity_menu($cm, 'view.php?id='.$id);
}
/// Get the current group
if ($groupmode > 0) {
$currentgroup = groups_get_activity_group($cm);
} else {
$currentgroup = 0;
}
/// Initialise the returned array, which is a matrix: $allresponses[responseid][userid] =responseobject
$allresponses = array();
/// First get all the users who have access here
/// To start with we assume they are all "unanswered" thenmove them later
// get a list of all of the group participantsand their user information
$allresponses[0] = get_users_by_capability($context, 'mod/foo:submit', 'u.id,u.picture, u.firstname, u.lastname, u.idnumber', 'u.firstname ASC', '', '', $currentgroup, '', false, true);
//get a complete list of all responses for this activity instance
//save this list in $rawresponses
$rawresponses = get_records('foo_responses', 'fooid', $foo->id);
if ($rawresponses) {
echo(get_string('your_groups_performance','foo'));
foreach ($rawresponses as $response) {
// This person is enrolled and in correct group
if (isset($allresponses[0][$response->userid])) {
$userid = $response->userid;
$user = get_record( 'user', 'id', $userid );
echo( '<br>'.$user->firstname." ".$user->lastname.': ' );
foo_user_complete( $user , $foo);
}
}
}
echo('</br>');
//**************************
}
Step 9 完成lib.php
lib.php file stores all of the basic functions used by theother files in the module
大部分moodle required的functions in lib.php都包含在newmodule template lib.php里。许多在newmodule的lib.php定义的function都可以不加改变的用在我们foo activity module里。你也可以添加function到lib.php来实现代码共享,例如本例添加了一个foo_grade function。
注意:你可以通过把你添加的functions放入locallib.php而不是lib.php里,从而达到提供代码的执行性能。这是因为core Moodle functions会包含module's lib.php file, 但不需要包含locally added functions. The Moodle core programmingguidelines state that it is only necessary to create a separate file if youmake significant additions.
下面讲解一些lib.php里的functions
l Function foo_add_instance
当一个foo activity instance被添加到course时,就会call foo_add_instancefunction。 The sample function provided by NEWMODULE is pretty complete, butit doesn't set the modification time. We add this line to set the modificationtime
$foo->timemodified= time();
l Function foo_delete_instance
当一个foo activity instance从course里被delete时,就会call foo_delete_instancefunction。We just need tomake one minor addition to the template. We need to deleteany 'child' records stored in our foo_responses table that are related to this instance
if(delete_records("foo_responses", "fooid","$foo->id")) {
$result =false;
}
l Function foo_user_outline
该function返回a smallobject with summary information about what a user has done with a givenparticular instance of this module。该function用于查看user activity reports.
返回的变量$result包含下列2个data
$return->time = the time they did it
$return->info = a short text description
l Function foo_user_complete
该function用于prints the user'ssubmission, if any, to the activity. This function isused by the core Moodle libraries, and also in activity Foo!'s view.php file. 该例的该function用于输出参数user的response,获取的response和function foo_user_outline的方法一样。
l Function foo_get_participants
This function returns a listof all of the users that have participated in the activity
l Function reset_course_form_definition
Newmoduletempalte并没有该function。该function用于当course被reset时。This is called by Moodle core to build the course reset formdisplayed to the user. 该例中,会往mform里添加2个elements
function foo_reset_course_form_definition(&$mform) {
$mform->addElement('header','fooheader', get_string('modulenameplural', 'foo'));
$mform->addElement('advcheckbox','reset_foo', get_string('removeresponses','foo'));
}
l Function foo_reset_course_form_defaults
This function is required toimplement the course reset. It enables the display of our module in the coursereset form
function foo_reset_course_form_defaults($course) {
returnarray('reset_foo'=>1);
}
l Function foo_reset_userdata
This function是真正的对该module的user data进行reset的function. It is called byMoodle core if a user selects the form value in the course reset。该例中,它会delete all the fooresponses for course $data->courseid.
该函数的参数为$data,它包含the data submitted from the reset course. 该函数返回的是status array。
functionfoo_reset_userdata($data) {
global $CFG;
$componentstr = get_string('modulenameplural', 'foo');
$status = array();
// First, check to see if reset_foo was selected
if (!empty($data->reset_foo)) {
//获取要reset的course所包含的foo instance records and delete them
$foossql = "SELECT f.id
FROM {$CFG->prefix}foof
WHERE f.course={$data->courseid}";
delete_records_select('foo_responses', "fooid IN ($foossql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('removeresponses', 'foo'), 'error'=>false);
}
/// updating dates - shift may be negative too
// resetthe date values by using the shift_course_mod_dates function from the Moodle core
if ($data->timeshift) {
shift_course_mod_dates('foo', array('timeopen', 'timeclose'), $data->timeshift, $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
}
return $status;
}
l Function foo_grade
该function用于insert grade record togradebook. It is called when user click submit button
该function演示了如何和moodlegradebook进行interaction。
该foo activity给分非常简化,如果答Yes,则给满分,如果答No,则给0分。
functionfoo_grade($foo, $userid, $response) {
global $CFG;
if (!function_exists('grade_update'))
//include grade lib file
require_once($CFG->libdir.'/gradelib.php');
if($response == 0)
$grade = 0;
else
$grade = $foo->scale; //$foo->scale即为满分
//assign aarray with both elements userid and rawgrade
$grades = array('userid'=>$userid,'rawgrade'=>$grade);
//assign some grading parameters
$params = array('itemname'=>$foo->name, 'idnumber'=>$foo->id);
//assign the grade type
if ( $foo->scale == 0) {
$params['gradetype'] = GRADE_TYPE_NONE;
} else if ($foo->scale > 0) {
$params['gradetype'] = GRADE_TYPE_VALUE;
$params['grademax'] = $foo->scale;
$params['grademin'] = 0;
} else if ($foo->scale < 0) {
$params['gradetype'] = GRADE_TYPE_SCALE;
$params['scaleid'] = -$foo->scale;
}
if ($grades === 'reset') {
$params['reset'] = true;
$grades = NULL;
}
//!最关键方法:insert/update grade record
return grade_update('mod/foo', $foo->course, 'mod', 'foo', $foo->id, 0, $grades,$params);
}
Step 10 upgrade.php
该file用于module upgrade。It is only necessary if we have deployed our module to users andsubsequently make updates that require the database to be changed.
最推荐的完成upgrade.php的方法是用moodle XMLDB editor tool。It provides a GUIthat you can use to update the database, including adding new tables. Theeditor will output both a complete new install.xml file and the PHP code needed for our upgrade.php file
下列代码是a sample section ofcode generated from the XMLDB editor,它讲解了当往foo table里添加一个scale field的代码
if ($result && $oldversion < 2009060103) {
///Define field scale to be added to foo
$table =new XMLDBTable('foo');
$field =new XMLDBField('scale');
$field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED,XMLDB_NOTNULL, null, null, null, '0', 'timemodified');
/// Launch add fieldscale
$result= $result && add_field($table, $field);
关于upgrade,详见
http://docs.moodle.org/en/Development:Installing_and_upgrading_plugin_database_tables
Step 10 Creatingbackup and restore support
Moodlecourse backup system使用XML format来保存activity data。当backup a course时,moodle会call所有module的backuplib.php file里的函数。
如果某个module并没有提供backuplib.php,那么backup course就不会backup该course里该module的任何相关data。而且在backup时,不会提示该module的data没有backup,只会在user restore course时才发现!
restorelib.php则包含了在restore moodle course时要调用的函数
注意:moodle 2.0重写了backup and restore的方法,但会向后兼容。
下面是foo activity backup xml example
<MOD>
<ID>80</ID>
<TYPE>foo</TYPE>
<INSTANCE>1</INSTANCE>
<ADDED>1250743636</ADDED>
<SCORE>0</SCORE>
<INDENT>0</INDENT>
<VISIBLE>1</VISIBLE>
<GROUPMODE>1</GROUPMODE>
<GROUPINGID>0</GROUPINGID>
<GROUPMEMBERSONLY>0</GROUPMEMBERSONLY>
<IDNUMBER>$@NULL@$</IDNUMBER>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</MOD>
下面是response保存到backup xml file的example
<RESPONSE>
<ID>1</ID>
<USERID>2</USERID>
<RESPONSE>1</RESPONSE>
<TIMEMODIFIED>1250743885</TIMEMODIFIED>
</RESPONSE>
Foo activity的backuplib.php file是基于moodle core 'choice'module,代码95%是一样的。只是通过search and replace “the module name”and database element。
The foo_responses structure is verysimilar to the choice_answers table. 'choice' actually has three tables, so a few items were removed.
下面是backuplib.php的functions(包括通用functions and only for foo module functions)
Common backup functions
Common backup functions should be implemented for every activitymodule.
l foo_backup_mods(): The main entry point for thebackup process. 它会为每一个activity instance in course都调用一次方法foo_backup_one_mod()
l foo_backup_one_mod(): Creates a backup for a single instance of theactivity. 在该例子里,它除了会backup该instance的basic info外,还会调用自定义函数backup_foo_responses()来备份response.
l foo_check_backup_mods(): 该函数被/backupfolder下的backup libraries调用。它用于生成由所有instance的setting info构成的string。
l foo_check_backup_mods_instances(): foo_check_backup_mods()会对每一个instance都调用该函数来生成该instance的settinginfo string。该函数还会调用自定义函数foo_response_ids_by_instance()来获取response count,并写入setting info string.
l foo_encode_content_links(): Necessary to support interactivity linking.Ensures that interactivity links stay intact between the backup and restoreprocesses.
l foo_ids(): Returns an array of all of the Foo! IDs for a course. Used by foo_check_backup_mods().
Backup functions only for foo module
l backup_foo_responses(): Creates the XML output tobackup the foo_responses table. Executed from the foo_backup_mods()function.
l foo_response_ids_by_course(): Uses an SQL query to return an array of IDs fromthe table foo_responses. Called by foo_check_backup_mods().
l foo_response_ids_by_instance(): Returns an array of IDs for a particular instanceof foo from the foo_responses table. Called by foo_check_backup_mods_instances().
下面是restorelib.php的functions(包括通用functions and only for foo module functions)
Common restore functions
Common restore functions should be implemented for every activitymodule.
l foo_restore_mods(): This is the main entry pointto the restore code for the module. It is called by core Moodle to performrestores. Calls the foo_responses_restore_mods() function to perform internalrestore functions.
l foo_decode_content_links_caller(): Reverses the link encoding from the backup process in order torestore the interactivity links. Iterates through all module content and calls foo_decode_content_links()function where needed to performthe decode. It's called from the restore_decode_content_links()function.
l foo_decode_content_links(): Performs the actual decoding of content in therestore file. Required to support interactivity linking.
l foo_restore_logs(): Returns a log record. Called by restore_log_module().
l foo_restore_wiki2markdown(): Converts instructions in FORMAT_WIKI to FORMAT_MARKDOWN.
Restore functions only for foo module
l foo_responses_restore_mods(): This function restores the foo_responses table entries and is called by the foo_restore_mods() function.
- Moodle开发笔记7-Activity module开发
- Moodle开发笔记1
- Moodle插件开发笔记
- Moodle开发笔记1-基础知识
- moodle的开发笔记2
- Moodle开发笔记2-Block开发
- Moodle开发笔记3-Filter开发
- Moodle开发笔记4-Theme开发
- Moodle开发笔记5-Course Format开发
- Moodle开发笔记6-Database操作
- 开发笔记:Python中的Module
- 开发笔记:Python中的Module
- 开发笔记:Python中的Module
- moodle开发——1开发总览
- Android开发笔记: Activity
- moodle 板块(block)开发流程小记
- Moodle笔记
- android开发学习笔记--activity
- 在VC中彻底玩转Excel(转)
- 一个ClassLoader的简单例子
- “云”是什么?
- 不要做浮躁的嵌入式工程师
- php mail函数 subject乱码
- Moodle开发笔记7-Activity module开发
- sort多列同时排序
- POJ 1085 Triangle War 极小极大值算法+α-β剪枝
- LKD 3rd 读书笔记——第1章/Linux Versus Classic Unix Kernels
- stl字符串使用
- 说明
- [Windows编程] 微软公开Office 文件(doc, xls, ppt) 格式
- C指针(二) - 内存泄露杯具现场及对策
- 移动通信USSD业务探讨