From 70cade16e352469ebfbac366310d845c236f0a73 Mon Sep 17 00:00:00 2001 From: moodler Date: Mon, 2 Apr 2007 05:26:03 +0000 Subject: [PATCH] Complete port of Moodle 1.8 formslib.php back into 1.7 to aid development of any modules that may use formslib in 1.7 MDL-9159 --- course/edit2.php | 262 +++--- course/edit_form.php | 692 ++++++++------- lang/en_utf8/form.php | 36 +- lib/form/checkbox.php | 60 +- lib/form/dateselector.php | 152 +++- lib/form/file.php | 36 +- lib/form/group.php | 33 +- lib/form/hidden.php | 9 +- lib/form/htmleditor.php | 41 +- lib/form/password.php | 17 +- lib/form/radio.php | 23 +- lib/form/select.php | 95 +- lib/form/static.php | 22 +- lib/form/text.php | 62 +- lib/form/textarea.php | 48 +- lib/formslib.php | 1739 +++++++++++++++++++++++++++++++------ 16 files changed, 2415 insertions(+), 912 deletions(-) diff --git a/course/edit2.php b/course/edit2.php index f4b57fc4943..9311a25eb0b 100644 --- a/course/edit2.php +++ b/course/edit2.php @@ -1,177 +1,122 @@ libdir/blocklib.php"); - require_once("$CFG->dirroot/enrol/enrol.class.php"); + require_once('../config.php'); + require_once($CFG->dirroot.'/enrol/enrol.class.php'); + require_once($CFG->libdir.'/blocklib.php'); + require_once('lib.php'); + require_once('edit_form.php'); - include_once $CFG->libdir.'/formslib.php'; + $id = optional_param('id', 0, PARAM_INT); // course id + $categoryid = optional_param('category', 0, PARAM_INT); // course category - can be changed in edit form require_login(); - $mform =& new moodleform('edit_course', 'post', 'edit2.php'); - - $mform->acceptGet('id', 'category'); - - $id = $mform->optional_param('id', 0, PARAM_INT); // course id - $category = $mform->optional_param('category', 0, PARAM_INT); // possible default category - - - $disable_meta = false; - $focus = ""; - - if ($id) { - if (! $course = get_record("course", "id", $id)) { - error("Course ID was incorrect"); +/// basic access control checks + if ($id) { // editing course + if (!$course = get_record('course', 'id', $id)) { + error('Course ID was incorrect'); } + $category = get_record('course_categories', 'id', $course->category); + require_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id)); - $context = get_context_instance(CONTEXT_COURSE, $course->id); - - if (!has_capability('moodle/course:update', $context)) { - error("You do not currently have editing privileges!"); + } else if ($categoryid) { // creating new course in this category + $course = null; + if (!$category = get_record('course_categories', 'id', $categoryid)) { + error('Category ID was incorrect'); } - - if (course_in_meta($course)) { - $disable_meta = get_string('metaalreadyinmeta'); - } else if ($course->metacourse) { - if (count_records("course_meta","parent_course",$course->id) > 0) { - $disable_meta = get_string('metaalreadyhascourses'); - } - } else { - $managers = count(get_users_by_capability($context, 'moodle/course:managemetacourse')); - $participants = count(get_users_by_capability($context, 'moodle/course:view')); - if ($participants > $managers) { - $disable_meta = get_string('metaalreadyhasenrolments'); - } - } - } else { // Admin is creating a new course - - $context = get_context_instance(CONTEXT_SYSTEM, SITEID); - if (!has_capability('moodle/course:create',$context)) { - error("You do not currently have course creation privileges!"); - } - - $course = NULL; + require_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $category->id)); + } else { + error('Either course id or category must be specified'); } - if (! $site = get_site()) { - redirect("$CFG->wwwroot/$CFG->admin/index.php"); - } - - - - include("edit_form.php"); - - - -/// If data submitted, then process and store. -// data_submitted tries to validate form data and returns false if -// the user inputted data is invalid and the form should be redisplayed with -// feedback. - - if ($fromform=$mform->data_submitted()) { - - - if (!empty($fromform->enrolstartdisabled)){ - $fromform->enrolstartdate = 0; - } - - if (!empty($fromform->enrolenddisabled)) { - $fromform->enrolenddate = 0; - } +/// prepare course + if (!empty($course)) { $allowedmods = array(); - if (!empty($fromform->allowedmods)) { - $allowedmods = $fromform->allowedmods; - unset($fromform->allowedmods); - } - - $fromform->timemodified = time(); - - if ($fromform->defaultrole == -1) { // Just leave it however it is - unset($fromform->defaultrole); - } if (!empty($course)) { - // Test for and remove blocks which aren't appropriate anymore - $page = page_create_object(PAGE_COURSE_VIEW, $course->id); - blocks_remove_inappropriate($page); - - // Update with the new data - if (update_record('course', $fromform)) { - add_to_log($course->id, "course", "update", "edit.php?id=$id", ""); - if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM, SITEID))) { - $course->restrictmodules = $fromform->restrictmodules; - update_restricted_mods($course,$allowedmods); + if ($am = get_records('course_allowed_modules','course',$course->id)) { + foreach ($am as $m) { + $allowedmods[] = $m->module; } - fix_course_sortorder(); - // everything ok, no need to display any message in redirect - redirect("view.php?id=$course->id"); } else { - error("Serious Error! Could not update the course record! (id = $fromform->id)"); + if (empty($course->restrictmodules)) { + $allowedmods = explode(',',$CFG->defaultallowedmodules); + } // it'll be greyed out but we want these by default anyway. } - } else { - $fromform->timecreated = time(); - - // place at beginning of category - fix_course_sortorder(); - $fromform->sortorder = get_field_sql("SELECT min(sortorder)-1 FROM {$CFG->prefix}course WHERE category=$fromform->category"); - if (empty($fromform->sortorder)) { - $fromform->sortorder = 100; + $course->allowedmods = $allowedmods; + + if ($course->enrolstartdate){ + $course->enrolstartdisabled = 0; } - // fill in default teacher and student names to keep backwards compatibility - $fromform->teacher = addslashes(get_string('defaultcourseteacher')); - $fromform->teachers = addslashes(get_string('defaultcourseteachers')); - $fromform->student = addslashes(get_string('defaultcoursestudent')); - $fromform->students = addslashes(get_string('defaultcoursestudents')); - - if ($newcourseid = insert_record('course', $fromform)) { // Set up new course - - // Setup the blocks - $page = page_create_object(PAGE_COURSE_VIEW, $newcourseid); - blocks_repopulate_page($page); // Return value not checked because you can always edit later - - if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM, SITEID))) { - $course = get_record("course","id",$newcourseid); - update_restricted_mods($course,$allowedmods); - } - - $section = NULL; - $section->course = $newcourseid; // Create a default section. - $section->section = 0; - $section->id = insert_record("course_sections", $section); - - fix_course_sortorder(); - add_to_log(SITEID, "course", "new", "view.php?id=$newcourseid", "$fromform->fullname (ID $newcourseid)") ; - $context = get_context_instance(CONTEXT_COURSE, $newcourseid); - - if ($fromform->metacourse and has_capability('moodle/course:managemetacourse', $context)) { // Redirect users with metacourse capability to student import - redirect($CFG->wwwroot."/course/importstudents.php?id=$newcourseid"); - - } else if (has_capability('moodle/role:assign', $context)) { // Redirect users with assign capability to assign users to different roles - redirect($CFG->wwwroot."/$CFG->admin/roles/assign.php?contextid=$context->id"); - - } else { // Add current teacher and send to course - - // find a role with legacy:edittingteacher - if ($teacherroles = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW, $context)) { - // assign the role to this user - $teachereditrole = array_shift($teacherroles); - role_assign($teachereditrole->id, $USER->id, 0, $context->id); - } - - redirect("view.php?id=$newcourseid"); - } - - - } else { - error("Serious Error! Could not create the new course!"); + + if ($course->enrolenddate) { + $course->enrolenddisabled = 0; } } - die; } -//print the form +/// first create the form + $editform = new course_edit_form('edit.php', compact('course', 'category')); + // now override defaults if course already exists + if (!empty($course)) { + $editform->set_data($course); + } + if ($editform->is_cancelled()){ + if (empty($course)) { + redirect($CFG->wwwroot); + } else { + redirect($CFG->wwwroot.'/course/view.php?id='.$course->id); + } + + } else if ($data = $editform->get_data()) { + +/// process data if submitted + + //preprocess data + if ($data->enrolstartdisabled){ + $data->enrolstartdate = 0; + } + + if ($data->enrolenddisabled) { + $data->enrolenddate = 0; + } + + $data->timemodified = time(); + + if (empty($course)) { + if (!$course = create_course($data)) { + print_error('coursenotcreated'); + } + + $context = get_context_instance(CONTEXT_COURSE, $course->id); + + // assign default role to creator if not already having permission to manage course assignments + if (!has_capability('moodle/course:view', $context) or !has_capability('moodle/role:assign', $context)) { + role_assign($CFG->creatornewroleid, $USER->id, 0, $context->id); + } + + if ($data->metacourse and has_capability('moodle/course:managemetacourse', $context)) { + // Redirect users with metacourse capability to student import + redirect($CFG->wwwroot."/course/importstudents.php?id=$course->id"); + } else { + // Redirect to roles assignment + redirect($CFG->wwwroot."/$CFG->admin/roles/assign.php?contextid=$context->id"); + } + + } else { + if (!update_course($data)) { + print_error('coursenotupdated'); + } + + redirect($CFG->wwwroot."/course/view.php?id=$course->id"); + } + } + + +/// Print the form + + $site = get_site(); $streditcoursesettings = get_string("editcoursesettings"); $straddnewcourse = get_string("addnewcourse"); @@ -179,20 +124,19 @@ $strcategories = get_string("categories"); if (!empty($course)) { - print_header($streditcoursesettings, "$course->fullname", + print_header($streditcoursesettings, $course->fullname, "wwwroot/course/view.php?id=$course->id\">$course->shortname - -> $streditcoursesettings", $focus); + -> $streditcoursesettings", $editform->focus()); } else { - print_header("$site->shortname: $straddnewcourse", "$site->fullname", - "admin/index.php\">$stradministration -> ". - "$strcategories -> $straddnewcourse", $focus); + print_header("$site->shortname: $straddnewcourse", $site->fullname, + "wwwroot/$CFG->admin/index.php\">$stradministration -> ". + "$strcategories -> $straddnewcourse", $editform->focus()); } - print_heading($streditcoursesettings); - $mform->display(); - + $editform->display(); + print_footer($course); ?> diff --git a/course/edit_form.php b/course/edit_form.php index f1975e71965..6a5d1d2c883 100644 --- a/course/edit_form.php +++ b/course/edit_form.php @@ -1,392 +1,382 @@ -libdir.'/formslib.php'); - if (!empty($course)) { - //this is what we do if we are editing a record from the db - $toform = $course; - $toform->allowedmods = array(); - if ($am = get_records("course_allowed_modules","course",$course->id)) { - foreach ($am as $m) { - $toform->allowedmods[] = $m->module; +class course_edit_form extends moodleform { + + function definition() { + global $USER, $CFG; + + $mform =& $this->_form; + + $course = $this->_customdata['course']; + $category = $this->_customdata['category']; + + $systemcontext = get_context_instance(CONTEXT_SYSTEM); + $categorycontext = get_context_instance(CONTEXT_COURSECAT, $category->id); + + $disable_meta = false; // basic meta course state protection; server-side security checks not needed + + if (!empty($course)) { + $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); + $context = $coursecontext; + + if (course_in_meta($course)) { + $disable_meta = get_string('metaalreadyinmeta'); + + } else if ($course->metacourse) { + if (count_records('course_meta', 'parent_course', $course->id) > 0) { + $disable_meta = get_string('metaalreadyhascourses'); + } + + } else { + $managers = count(get_users_by_capability($coursecontext, 'moodle/course:managemetacourse')); + $participants = count(get_users_by_capability($coursecontext, 'moodle/course:view')); + if ($participants > $managers) { + $disable_meta = get_string('metaalreadyhasenrolments'); + } } } else { - if (empty($course->restrictmodules)) { - $toform->allowedmods = explode(',',$CFG->defaultallowedmodules); - } // it'll be greyed out but we want these by default anyway. - } - } else { - //this is a brand new course! - $toform->startdate = time() + 3600 * 24; - $toform->fullname = get_string("defaultcoursefullname"); - $toform->shortname = get_string("defaultcourseshortname"); - $toform->summary = get_string("defaultcoursesummary"); - $toform->format = "weeks"; - $toform->password = ""; - $toform->guest = 0; - $toform->numsections = 10; - $toform->idnumber = ''; - $toform->cost = ''; - $toform->currency = empty($CFG->enrol_currency) ? 'USD' : $CFG->enrol_currency; - $toform->newsitems = 5; - $toform->showgrades = 1; - $toform->groupmode = 0; - $toform->groupmodeforce = 0; - $toform->category = $category; - $toform->id = ""; - $toform->visible = 1; - $toform->allowedmods = array(); - if ($CFG->restrictmodulesfor == 'all') { - $toform->allowedmods = explode(',',$CFG->defaultallowedmodules); - if (!empty($CFG->restrictbydefault)) { - $toform->restrictmodules = 1; - } + $coursecontext = null; + $context = $categorycontext; } +/// form definition with new course defaults +//-------------------------------------------------------------------------------- + $mform->addElement('header','general', get_string('general', 'form')); - } + //must have create course capability in both categories in order to move course + if (has_capability('moodle/course:create', $categorycontext)) { + $displaylist = array(); + $parentlist = array(); + make_categories_list($displaylist, $parentlist); + foreach ($displaylist as $key=>$val) { + if (!has_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $key))) { + unset($displaylist[$key]); + } + } + $mform->addElement('select', 'category', get_string('category'), $displaylist); + } else { + $mform->addElement('hidden', 'category', null); + } + $mform->setHelpButton('category', array('coursecategory', get_string('category'))); + $mform->setDefault('category', $category->id); + $mform->setType('category', PARAM_INT); - $mform->addElement('header','general', get_string("general")); - if (has_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $toform->category))) { - $displaylist = array(); - $parentlist = array(); - make_categories_list($displaylist, $parentlist); - $mform->addElement('select', "category", get_string("category"), $displaylist ); - } - $mform->setDefault('fullname', $toform->fullname); - $mform->addElement('text','fullname', get_string("fullname"),'maxlength="254" size="50"'); - $mform->setDefault('shortname', $toform->shortname); - $mform->addElement('text','shortname', get_string("shortname"),'maxlength="15" size="10"'); - $mform->setDefault('idnumber', $toform->idnumber); - $mform->addElement('text','idnumber', get_string("idnumbercourse"),'maxlength="100" size="10"'); - $mform->setDefault('summary', $toform->summary); - $mform->addElement('htmleditor','summary', get_string("summary"), array('rows'=>'10', 'cols'=>'65')); + $mform->addElement('text','fullname', get_string('fullname'),'maxlength="254" size="50"'); + $mform->setHelpButton('fullname', array('coursefullname', get_string('fullname')), true); + $mform->setDefault('fullname', get_string('defaultcoursefullname')); + $mform->addRule('fullname', get_string('missingfullname'), 'required', null, 'client'); + $mform->setType('fullname', PARAM_MULTILANG); - $mform->setDefault('format', $toform->format); - $courseformats = get_list_of_plugins("course/format"); - $formcourseformats = array(); + $mform->addElement('text','shortname', get_string('shortname'),'maxlength="15" size="10"'); + $mform->setHelpButton('shortname', array('courseshortname', get_string('shortname')), true); + $mform->setDefault('shortname', get_string('defaultcourseshortname')); + $mform->addRule('shortname', get_string('missingshortname'), 'required', null, 'client'); + $mform->setType('shortname', PARAM_MULTILANG); - foreach ($courseformats as $courseformat) { - $formcourseformats["$courseformat"] = get_string("format$courseformat"); - } + $mform->addElement('text','idnumber', get_string('idnumbercourse'),'maxlength="100" size="10"'); + $mform->setHelpButton('idnumber', array('courseidnumber', get_string('idnumbercourse')), true); + $mform->setType('idnumber', PARAM_RAW); - $mform->addElement('select', 'format', get_string("format"), $formcourseformats ); + $mform->addElement('htmleditor','summary', get_string('summary'), array('rows'=> '10', 'cols'=>'65')); + $mform->setHelpButton('summary', array('text', get_string('helptext')), true); + $mform->setDefault('summary', get_string('defaultcoursesummary')); + $mform->addRule('summary', get_string('missingsummary'), 'required', null, 'client'); + $mform->setType('summary', PARAM_RAW); - $mform->setDefault('numsections', $toform->numsections); - for ($i=1; $i<=52; $i++) { - $sectionmenu[$i] = "$i"; - } - $mform->addElement('select', 'numsections', get_string("numberweeks"), $sectionmenu); - $mform->setDefault('startdate', $toform->startdate); - $mform->addElement('date_selector', 'startdate', get_string('startdate')); + $courseformats = get_list_of_plugins('course/format'); + $formcourseformats = array(); + foreach ($courseformats as $courseformat) { + $formcourseformats["$courseformat"] = get_string("format$courseformat","format_$courseformat"); + if($formcourseformats["$courseformat"]=="[[format$courseformat]]") { + $formcourseformats["$courseformat"] = get_string("format$courseformat"); + } + } + $mform->addElement('select', 'format', get_string('format'), $formcourseformats); + $mform->setHelpButton('format', array('courseformats', get_string('courseformats')), true); + $mform->setDefault('format', 'weeks'); - $mform->setDefault('hiddensections',(isset($toform->hiddensections))?$toform->hiddensections:0); - unset($choices); - $choices["0"] = get_string("hiddensectionscollapsed"); - $choices["1"] = get_string("hiddensectionsinvisible"); - $mform->addElement('select', 'hiddensections', get_string("hiddensections"), $choices); + for ($i=1; $i<=52; $i++) { + $sectionmenu[$i] = "$i"; + } + $mform->addElement('select', 'numsections', get_string('numberweeks'), $sectionmenu); + $mform->setDefault('numsections', 10); - $mform->setDefault('newsitems', $toform->newsitems); - $newsitem = get_string("newsitem"); - $newsitems = get_string("newsitems"); - $options = array("0" => "0 $newsitems", - "1" => "1 $newsitem", - "2" => "2 $newsitems", - "3" => "3 $newsitems", - "4" => "4 $newsitems", - "5" => "5 $newsitems", - "6" => "6 $newsitems", - "7" => "7 $newsitems", - "8" => "8 $newsitems", - "9" => "9 $newsitems", - "10" => "10 $newsitems"); - $mform->addElement('select', 'newsitems', get_string("newsitemsnumber"), $options); + $mform->addElement('date_selector', 'startdate', get_string('startdate')); + $mform->setHelpButton('startdate', array('coursestartdate', get_string('startdate')), true); + $mform->setDefault('startdate', time() + 3600 * 24); - $mform->setDefault('showgrades', $toform->showgrades); - unset($choices); - $choices["0"] = get_string("no"); - $choices["1"] = get_string("yes"); - $mform->addElement('select', 'showgrades', get_string("showgrades"), $choices); - unset($choices); - $mform->setDefault('showreports',(isset($toform->showreports))?$toform->showreports:0); - $choices["0"] = get_string("no"); - $choices["1"] = get_string("yes"); - $mform->addElement('select', 'showreports', get_string("showreports"), $choices); - $mform->setDefault('maxbytes',(isset($toform->maxbytes))?$toform->maxbytes:0); - $choices = get_max_upload_sizes($CFG->maxbytes); - $mform->addElement('select', 'maxbytes', get_string("maximumupload"), $choices); - if (!empty($CFG->allowcoursethemes)) { - $mform->setDefault('theme',(isset($toform->theme))?$toform->theme:''); - - $themes=array(); - $themes[''] = get_string("forceno"); - $themes += get_list_of_themes(); - $mform->addElement('select', 'theme', get_string("forcetheme"), $themes); - } - unset($choices); - $mform->setDefault('metacourse',(isset($toform->metacourse))?$toform->metacourse:0); + $choices = array(); + $choices['0'] = get_string('hiddensectionscollapsed'); + $choices['1'] = get_string('hiddensectionsinvisible'); + $mform->addElement('select', 'hiddensections', get_string('hiddensections'), $choices); + $mform->setHelpButton('hiddensections', array('coursehiddensections', get_string('hiddensections')), true); + $mform->setDefault('hiddensections', 0); + + $options = range(0, 10); + $mform->addElement('select', 'newsitems', get_string('newsitemsnumber'), $options); + $mform->setHelpButton('newsitems', array('coursenewsitems', get_string('newsitemsnumber')), true); + $mform->setDefault('newsitems', 5); + + $mform->addElement('selectyesno', 'showgrades', get_string('showgrades')); + $mform->setHelpButton('showgrades', array('coursegrades', get_string('grades')), true); + $mform->setDefault('showgrades', 1); + + $mform->addElement('selectyesno', 'showreports', get_string('showreports')); + $mform->setHelpButton('showreports', array('coursereports', get_string('activityreport')), true); + $mform->setDefault('showreports', 0); + + $choices = get_max_upload_sizes($CFG->maxbytes); + $mform->addElement('select', 'maxbytes', get_string('maximumupload'), $choices); + $mform->setHelpButton('maxbytes', array('courseuploadsize', get_string('maximumupload')), true); + + if (!empty($CFG->allowcoursethemes)) { + $themes=array(); + $themes[''] = get_string('forceno'); + $themes += get_list_of_themes(); + $mform->addElement('select', 'theme', get_string('forcetheme'), $themes); + } - if (empty($disable_meta)) { $meta=array(); $meta[0] = get_string('no'); $meta[1] = get_string('yes'); - $mform->addElement('select', 'metacourse', get_string("managemeta"), $meta); - }else{ - $mform->addElement('static', 'metacourse', get_string("managemeta"), - ((empty($toform->metacourse)) ? get_string("no") : get_string("yes")) - . " - $disable_meta "); - - } - - $mform->setDefault('defaultrole',(isset($toform->defaultrole))?$toform->defaultrole:0); - $roles = get_assignable_roles($context); - asort($roles); - $choices = array(); - - if ($sitedefaultrole = get_record('role', 'id', $CFG->defaultcourseroleid)) { - $choices[0] = get_string('sitedefault').' ('.$sitedefaultrole->name.')'; - } else { - $choices[0] = get_string('sitedefault'); - } - - $choices = $choices + $roles; - $defaultroleelement=$mform->addElement('select', 'defaultrole', get_string('defaultrole', 'role'), $choices ); - if ($mform->exportValue('defaultrole') && !isset($roles[$mform->exportValue('defaultrole')])) { // Existing setting is one we can't choose - if ($coursedefaultrole = get_record('role', 'id', $mform->exportValue('defaultrole'))) { - - $defaultroleelement->addOption(get_string('currentrole', 'role').' ('.$coursedefaultrole->name.')',-1); + if ($disable_meta === false) { + $mform->addElement('select', 'metacourse', get_string('managemeta'), $meta); + $mform->setHelpButton('metacourse', array('metacourse', get_string('metacourse')), true); + $mform->setDefault('metacourse', 0); } else { - $defaultroleelement->addOption(get_string('currentrole', 'role'),-1); + // no metacourse element - we do not want to change it anyway! + $mform->addElement('static', 'nometacourse', get_string('managemeta'), + ((empty($course->metacourse)) ? $meta[0] : $meta[1]) . " - $disable_meta "); + $mform->setHelpButton('nometacourse', array('metacourse', get_string('metacourse')), true); } - } - - $mform->addElement('header','enrolhdr', get_string("enrolment")); - $mform->setDefault('enrol',(isset($toform->enrol))?$toform->enrol:''); - - $modules = explode(',', $CFG->enrol_plugins_enabled); - foreach ($modules as $module) { - $name = get_string("enrolname", "enrol_$module"); - $plugin = enrolment_factory::factory($module); - if (method_exists($plugin, 'print_entry')) { - $choices[$name] = $module; + $roles = get_assignable_roles($context); + if (!empty($course)) { + // add current default role, so that it is selectable even when user can not assign it + if ($current_role = get_record('role', 'id', $course->defaultrole)) { + $roles[$current_role->id] = strip_tags(format_string($current_role->name, true)); + } } - } - asort($choices); - $choices = array_flip($choices); - $choices = array_merge(array('' => get_string('sitedefault').' ('.get_string("enrolname", "enrol_$CFG->enrol").')'), $choices); - $mform->addElement('select', 'enrol', get_string("enrolmentplugins"), $choices ); - - $mform->setDefault('enrollable',(isset($toform->enrollable))?$toform->enrollable:1); - $radio = array(); - $radio[] = &moodleform::createElement('radio', 'enrollable', null, get_string("no"), 0); - $radio[] = &moodleform::createElement('radio', 'enrollable', null, get_string("yes"), 1); - $radio[] = &moodleform::createElement('radio', 'enrollable', null, get_string("enroldate"), 2); - $mform->addGroup($radio, 'enrollable', get_string("enrollable"), ' ', false); - - $mform->setDefault('enrolstartdate',(isset($toform->enrolstartdate))?$toform->enrolstartdate:0); - $mform->setDefault('enrolstartdisabled', - (!isset($toform->enrolstartdate)|| - (isset($toform->enrolstartdate)&&!$toform->enrolstartdate) - ?1:0)); - $enroldatestartgrp = array(); - $enroldatestartgrp[] = &moodleform::createElement('date_selector', 'enrolstartdate'); - $enroldatestartgrp[] = &moodleform::createElement('checkbox', 'enrolstartdisabled', null, get_string('disable')); - $mform->addGroup($enroldatestartgrp, '', get_string('enrolstartdate'), ' ', false); - - $mform->setDefault('enrolenddate',(isset($toform->enrolenddate))?$toform->enrolenddate:0); - $mform->setDefault('enrolenddisabled', - (!isset($toform->enrolenddate)|| - (isset($toform->enrolenddate)&&!$toform->enrolenddate) - ?1:0)); - $enroldateendgrp = array(); - $enroldateendgrp[] = &moodleform::createElement('date_selector', 'enrolenddate'); - $enroldateendgrp[] = &moodleform::createElement('checkbox', 'enrolenddisabled', null, get_string('disable')); - $mform->addGroup($enroldateendgrp, 'enroldateendgrp', get_string('enrolenddate'), ' ', false); - - $mform->setDefault('enrolperiod',(isset($toform->enrolperiod))?$toform->enrolperiod:0); - $periodmenu=array(); - $periodmenu[0] = get_string('unlimited'); - for ($i=1; $i<=365; $i++) { - $seconds = $i * 86400; - $periodmenu[$seconds] = get_string('numdays', '', $i); - } - $mform->addElement('select', 'enrolperiod', get_string("enrolperiod"), $periodmenu); - - - $mform->addElement('header','expirynotifyhdr', get_string("expirynotify")); - - $mform->setDefault('expirynotify',(isset($toform->expirynotify))?$toform->expirynotify:0); - unset($choices); - $choices["0"] = get_string("no"); - $choices["1"] = get_string("yes"); - $mform->addElement('select', 'expirynotify', get_string("expirynotify"), $choices); - $mform->setDefault('notifystudents',(isset($toform->notifystudents))?$toform->notifystudents:0); - $mform->addElement('select', 'notifystudents', get_string("expirynotifystudents"), $choices); - $mform->setDefault('expirythreshold',(isset($toform->expirythreshold))?$toform->expirythreshold:10 * 86400); - $thresholdmenu=array(); - for ($i=1; $i<=30; $i++) { - $seconds = $i * 86400; - $thresholdmenu[$seconds] = get_string('numdays', '', $i); - } - $mform->addElement('select', 'expirythreshold', get_string("expirythreshold"), $thresholdmenu); - - - $mform->addElement('header','', get_string("groupmode")); + $choices = array(); + if ($sitedefaultrole = get_record('role', 'id', $CFG->defaultcourseroleid)) { + $choices[0] = get_string('sitedefault').' ('.$sitedefaultrole->name.')'; + } else { + $choices[0] = get_string('sitedefault'); + } + $choices = $choices + $roles; + $mform->addElement('select', 'defaultrole', get_string('defaultrole', 'role'), $choices); + $mform->setDefault('defaultrole', 0); - $mform->setDefault('groupmode', $toform->groupmode); - unset($choices); - $choices[NOGROUPS] = get_string("groupsnone"); - $choices[SEPARATEGROUPS] = get_string("groupsseparate"); - $choices[VISIBLEGROUPS] = get_string("groupsvisible"); - $mform->addElement('select', 'groupmode', get_string("groupmode"), $choices); - $mform->setDefault('groupmodeforce', $toform->groupmodeforce); - unset($choices); - $choices["0"] = get_string("no"); - $choices["1"] = get_string("yes"); - $mform->addElement('select', 'groupmodeforce', get_string("force"), $choices); +//-------------------------------------------------------------------------------- + $mform->addElement('header','enrolhdr', get_string('enrolments')); - $mform->addElement('header','', get_string("availability")); + $choices = array(); + $modules = explode(',', $CFG->enrol_plugins_enabled); + foreach ($modules as $module) { + $name = get_string('enrolname', "enrol_$module"); + $plugin = enrolment_factory::factory($module); + if (method_exists($plugin, 'print_entry')) { + $choices[$name] = $module; + } + } + asort($choices); + $choices = array_flip($choices); + $choices = array_merge(array('' => get_string('sitedefault').' ('.get_string('enrolname', "enrol_$CFG->enrol").')'), $choices); + $mform->addElement('select', 'enrol', get_string('enrolmentplugins'), $choices); + $mform->setHelpButton('enrol', array('courseenrolmentplugins', get_string('enrolmentplugins')), true); - $mform->setDefault('visible', $toform->visible); - unset($choices); - $choices["0"] = get_string("courseavailablenot"); - $choices["1"] = get_string("courseavailable"); - $mform->addElement('select', 'visible', get_string("availability"), $choices); - $mform->setDefault('password', $toform->password); - $mform->addElement('text', 'password', get_string("enrolmentkey"), 'size="25"'); - $mform->setDefault('guest', $toform->guest); - unset($choices); - $choices["0"] = get_string("guestsno"); - $choices["1"] = get_string("guestsyes"); - $choices["2"] = get_string("guestskey"); - $mform->addElement('select', 'guest', get_string("opentoguests"), $choices); - if (isset($course) && method_exists(enrolment_factory::factory($course->enrol), 'print_entry') && $course->enrol != 'manual') { - $mform->setDefault('cost', $toform->cost); - $mform->setDefault('currency', $toform->currency); - $costgroup=array(); - $currencies = get_list_of_currencies(); - $costgroup[]= &moodleform::createElement('text','cost', '', 'maxlength="6" size="6"'); - $costgroup[]= &moodleform::createElement('select', 'currency', '', $currencies); - $mform->addGroup($costgroup, 'costgrp', get_string("cost"), ' ', false); + $radio = array(); + $radio[] = &MoodleQuickForm::createElement('radio', 'enrollable', null, get_string('no'), 0); + $radio[] = &MoodleQuickForm::createElement('radio', 'enrollable', null, get_string('yes'), 1); + $radio[] = &MoodleQuickForm::createElement('radio', 'enrollable', null, get_string('enroldate'), 2); + $mform->addGroup($radio, 'enrollable', get_string('enrollable'), ' ', false); + $mform->setHelpButton('enrollable', array('courseenrollable', get_string('enrollable')), true); + $mform->setDefault('enrollable', 1); + + $enroldatestartgrp = array(); + $enroldatestartgrp[] = &MoodleQuickForm::createElement('date_selector', 'enrolstartdate'); + $enroldatestartgrp[] = &MoodleQuickForm::createElement('checkbox', 'enrolstartdisabled', null, get_string('disable')); + $mform->addGroup($enroldatestartgrp, 'enrolstartdategrp', get_string('enrolstartdate'), ' ', false); + $mform->setDefault('enrolstartdate', 0); + $mform->setDefault('enrolstartdisabled', 1); + $mform->disabledIf('enrolstartdategrp', 'enrolstartdisabled', 'checked'); + + $enroldateendgrp = array(); + $enroldateendgrp[] = &MoodleQuickForm::createElement('date_selector', 'enrolenddate'); + $enroldateendgrp[] = &MoodleQuickForm::createElement('checkbox', 'enrolenddisabled', null, get_string('disable')); + $mform->addGroup($enroldateendgrp, 'enroldateendgrp', get_string('enrolenddate'), ' ', false); + $mform->setDefault('enrolenddate', 0); + $mform->setDefault('enrolenddisabled', 1); + $mform->disabledIf('enroldateendgrp', 'enrolenddisabled', 'checked'); + + $periodmenu=array(); + $periodmenu[0] = get_string('unlimited'); + for ($i=1; $i<=365; $i++) { + $seconds = $i * 86400; + $periodmenu[$seconds] = get_string('numdays', '', $i); + } + $mform->addElement('select', 'enrolperiod', get_string('enrolperiod'), $periodmenu); + $mform->setDefault('enrolperiod', 0); + +//-------------------------------------------------------------------------------- + $mform->addElement('header','expirynotifyhdr', get_string('expirynotify')); + + $choices = array(); + $choices['0'] = get_string('no'); + $choices['1'] = get_string('yes'); + $mform->addElement('select', 'expirynotify', get_string('notify'), $choices); + $mform->setHelpButton('expirynotify', array('expirynotify', get_string('expirynotify')), true); + $mform->setDefault('expirynotify', 0); + + $mform->addElement('select', 'notifystudents', get_string('expirynotifystudents'), $choices); + $mform->setHelpButton('notifystudents', array('expirynotifystudents', get_string('expirynotifystudents')), true); + $mform->setDefault('notifystudents', 0); + + $thresholdmenu=array(); + for ($i=1; $i<=30; $i++) { + $seconds = $i * 86400; + $thresholdmenu[$seconds] = get_string('numdays', '', $i); + } + $mform->addElement('select', 'expirythreshold', get_string('expirythreshold'), $thresholdmenu); + $mform->setHelpButton('expirythreshold', array('expirythreshold', get_string('expirythreshold')), true); + $mform->setDefault('expirythreshold', 10 * 86400); + +//-------------------------------------------------------------------------------- + $mform->addElement('header','', get_string('groups', 'group')); + + $choices = array(); + $choices[NOGROUPS] = get_string('no'); + $choices[SEPARATEGROUPS] = get_string('separate'); + $choices[VISIBLEGROUPS] = get_string('visible'); + $mform->addElement('select', 'groupmode', get_string('groupmode'), $choices); + $mform->setHelpButton('groupmode', array('groupmode', get_string('groupmode')), true); + $mform->setDefault('groupmode', 0); + + $choices = array(); + $choices['0'] = get_string('no'); + $choices['1'] = get_string('yes'); + $mform->addElement('select', 'groupmodeforce', get_string('force'), $choices); + $mform->setHelpButton('groupmodeforce', array('groupmodeforce', get_string('groupmodeforce')), true); + $mform->setDefault('groupmodeforce', 0); + +//-------------------------------------------------------------------------------- + $mform->addElement('header','', get_string('availability')); + + $choices = array(); + $choices['0'] = get_string('courseavailablenot'); + $choices['1'] = get_string('courseavailable'); + $mform->addElement('select', 'visible', get_string('availability'), $choices); + $mform->setHelpButton('visible', array('courseavailability', get_string('availability')), true); + $mform->setDefault('visible', 1); + + $mform->addElement('text', 'password', get_string('enrolmentkey'), 'size="25"'); + $mform->setHelpButton('password', array('enrolmentkey', get_string('enrolmentkey')), true); + $mform->setDefault('password', ''); + $mform->setType('password', PARAM_RAW); + + $choices = array(); + $choices['0'] = get_string('guestsno'); + $choices['1'] = get_string('guestsyes'); + $choices['2'] = get_string('guestskey'); + $mform->addElement('select', 'guest', get_string('opentoguests'), $choices); + $mform->setHelpButton('guest', array('guestaccess', get_string('opentoguests')), true); + $mform->setDefault('guest', 0); + + if (!empty($course) && method_exists(enrolment_factory::factory($course->enrol), 'print_entry') && $course->enrol != 'manual') { + $costgroup=array(); + $currencies = get_list_of_currencies(); + $costgroup[]= &MoodleQuickForm::createElement('text','cost', '', 'maxlength="6" size="6"'); + $costgroup[]= &MoodleQuickForm::createElement('select', 'currency', '', $currencies); + $mform->addGroup($costgroup, 'costgrp', get_string('cost'), ' ', false); + //defining a rule for a form element within a group : + $costgrprules=array(); + //set the message to null to tell Moodle to use a default message + //available for most rules, fetched from language pack (err_{rulename}). + $costgrprules['cost'][]=array(null, 'numeric', null, 'client'); + $mform->addGroupRule('costgrp',$costgrprules); + $mform->setHelpButton('costgrp', array('cost', get_string('cost')), true); + $mform->setDefault('cost', ''); + $mform->setDefault('currency', empty($CFG->enrol_currency) ? 'USD' : $CFG->enrol_currency); + + } + +//-------------------------------------------------------------------------------- + $mform->addElement('header','', get_string('language')); + + $languages=array(); + $languages[''] = get_string('forceno'); + $languages += get_list_of_languages(); + $mform->addElement('select', 'lang', get_string('forcelanguage'), $languages); + +//-------------------------------------------------------------------------------- + if (has_capability('moodle/site:config', $systemcontext) && ((!empty($course->requested) && $CFG->restrictmodulesfor == 'requested') || $CFG->restrictmodulesfor == 'all')) { + $mform->addElement('header', '', get_string('restrictmodules')); + + $options = array(); + $options['0'] = get_string('no'); + $options['1'] = get_string('yes'); + $mform->addElement('select', 'restrictmodules', get_string('restrictmodules'), $options); + $mods = array(0=>get_string('allownone')); + $mods += get_records_menu('modules', '','','','id, name'); + + + $mform->addElement('select', 'allowedmods', get_string('to'), $mods, + array('multiple'=>'multiple', 'size'=>'10')); + $mform->disabledIf('allowedmods', 'restrictmodules', 'eq', 0); + } else { + $mform->addElement('hidden', 'restrictmodules', null); + } + if ($CFG->restrictmodulesfor == 'all') { + $mform->setDefault('allowedmods', explode(',',$CFG->defaultallowedmodules)); + if (!empty($CFG->restrictbydefault)) { + $mform->setDefault('restrictmodules', 1); + } + } + $mform->setType('restrictmodules', PARAM_INT); + +//-------------------------------------------------------------------------------- + $this->add_action_buttons(); +//-------------------------------------------------------------------------------- + $mform->addElement('hidden', 'id', null); + $mform->setType('id', PARAM_INT); + + // fill in default teacher and student names to keep backwards compatibility for a while + $mform->addElement('hidden', 'teacher', get_string('defaultcourseteacher')); + $mform->addElement('hidden', 'teachers', get_string('defaultcourseteachers')); + $mform->addElement('hidden', 'student', get_string('defaultcoursestudent')); + $mform->addElement('hidden', 'students', get_string('defaultcoursestudents')); } - $mform->addElement('header','', get_string("language")); - $mform->setDefault('lang',(isset($toform->lang))?$toform->lang:''); - $languages=array(); - $languages[''] = get_string("forceno"); - $languages += get_list_of_languages(); - $mform->addElement('select', 'lang', get_string("forcelanguage"), $languages); - if(!has_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $toform->category))) { - $mform->addElement('hidden', 'category', null); - } - $mform->addElement('hidden', 'id', null); - - $mform->setDefault('restrictmodules',(isset($toform->restrictmodules))?$toform->restrictmodules:0); - if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM, SITEID)) && ((!empty($course->requested) && $CFG->restrictmodulesfor == 'requested') || $CFG->restrictmodulesfor == 'all')) { - unset($options); - $options[0] = get_string("no"); - $options[1] = get_string("yes"); - $mform->addElement('header', '', get_string("restrictmodules")); - $mform->addElement('select', 'restrictmodules', get_string("restrictmodules"), $options, - array('onChange'=>"document.getElementById('id_allowedmods').disabled=". - "((this.selectedIndex==0)?true:false);")); - $mods = array(0=>get_string('allownone')); - $mods += get_records_menu("modules", '','','','id, name'); - $disabled=($mform->exportValue('restrictmodules')==1) ? array() :array('disabled' => 'disabled') ; - - - $mform->setDefault('allowedmods', $toform->allowedmods); - $mform->addElement('select', 'allowedmods', get_string("to"),$mods, - array('multiple'=>"multiple", 'size'=>"10", 'id'=>"allowedmods") - +$disabled); - }else { - $mform->addElement('hidden', 'restrictmodules', $toform->restrictmodules); - } - $mform->setHelpButtons(array('category'=>array("coursecategory", get_string("category")), - 'fullname'=>array("coursefullname", get_string("fullname")), - 'shortname'=>array("courseshortname", get_string("shortname")), - 'idnumber'=>array("courseidnumber", get_string("idnumbercourse")), - 'summary'=>array("text", get_string("helptext")), - 'format'=>array("courseformats", get_string("courseformats")), - 'summary'=>array("coursestartdate", get_string("startdate")), - 'enrol'=>array("courseenrolmentplugins", get_string("enrolmentplugins")), - 'enrollable'=>array("courseenrollable", get_string("enrollable")), - 'expirynotify'=>array("expirynotify", get_string("expirynotify")), - 'notifystudents'=>array("expirynotifystudents", get_string("expirynotifystudents")), - 'expirythreshold'=>array("expirythreshold", get_string("expirythreshold")), - 'groupmode'=>array("groupmode", get_string("groupmode")), - 'groupmodeforce'=>array("groupmodeforce", get_string("groupmodeforce")), - 'visible'=>array("courseavailability", get_string("availability")), - 'password'=>array("enrolmentkey", get_string("enrolmentkey")), - 'guest'=>array("guestaccess", get_string("opentoguests")), - 'costgrp'=>array("cost", get_string("cost")), - 'hiddensections'=>array("coursehiddensections", get_string("hiddensections")), - 'newsitems'=>array("coursenewsitems", get_string("newsitemsnumber")), - 'showgrades'=>array("coursegrades", get_string("grades")), - 'showreports'=>array("coursereports", get_string("activityreport")), - 'maxbytes'=>array("courseuploadsize", get_string("maximumupload")), - 'metacourse'=>array("metacourse", get_string("metacourse")), - 'defaultrole'=>array("coursedefaultrole", get_string("defaultrole", 'role'))), - true); - $mform->addElement('submit', 'submit', get_string("savechanges")); - - $mform->addRule('fullname', get_string("missingfullname"), 'required', null, 'client'); - $mform->addRule('shortname', get_string("missingshortname"), 'required', null, 'client'); - $mform->addRule('summary', get_string("missingsummary"), 'required', null, 'client'); - $mform->addRule('category', get_string("missingcategory"), 'required', null, 'client'); - - /** - * a Form rule check - if we need to create rules which involve the contents of more than one - * field this is the way to do it. We can do it all at once in one function or create several - * form rules. - * - * @param array $fields values from form without slashes - * @return mixed array of errors or true if passed check - */ - function form_check($fields){ - global $course; +/// perform some extra moodle validation + function validation($data){ $errors= array(); - if ($foundcourses = get_records("course", "shortname", addslashes($fields['shortname']))) { - if (!empty($course->id)) { - unset($foundcourses[$course->id]); + if ($foundcourses = get_records('course', 'shortname', $data['shortname'])) { + if (!empty($data['id'])) { + unset($foundcourses[$data['id']]); } if (!empty($foundcourses)) { foreach ($foundcourses as $foundcourse) { $foundcoursenames[] = $foundcourse->fullname; } - $foundcoursenamestring = addslashes(implode(',', $foundcoursenames)); - - $errors['shortname']= get_string("shortnametaken", "", $foundcoursenamestring); - - } - - - } - if (empty($fields['enrolenddisabled'])){ - $enrolenddate=make_timestamp($fields['enrolenddate']['year'], - $fields['enrolenddate']['month'], - $fields['enrolenddate']['day']); - $enrolstartdate=make_timestamp($fields['enrolstartdate']['year'], - $fields['enrolstartdate']['month'], - $fields['enrolstartdate']['day']); - if ($enrolenddate <= $enrolstartdate){ - $errors['enroldateendgrp']=get_string("enrolenddaterror"); + $foundcoursenamestring = implode(',', $foundcoursenames); + $errors['shortname']= get_string('shortnametaken', '', $foundcoursenamestring); } } - if (0==count($errors)){ + + if (empty($data['enrolenddisabled'])){ + if ($data['enrolenddate'] <= $data['enrolstartdate']){ + $errors['enroldateendgrp'] = get_string('enrolenddaterror'); + } + } + + if (0 == count($errors)){ return true; - }else { + } else { return $errors; } } - $mform->addFormRule('form_check'); - - $renderer =& $mform->defaultRenderer(); - $renderer->addStopFieldsetElements('submit'); -?> +} +?> \ No newline at end of file diff --git a/lang/en_utf8/form.php b/lang/en_utf8/form.php index 3382b5f3de3..7270fe45eec 100644 --- a/lang/en_utf8/form.php +++ b/lang/en_utf8/form.php @@ -1,10 +1,36 @@ -format characters here.'; +$string['err_minlength']='You must enter at least $a->format characters here.'; +$string['err_nopunctuation']='You must enter no punctuation characters here.'; +$string['err_nonzero']='You must enter a number not starting with a 0 here.'; +$string['err_numeric']='You must enter a number here.'; +$string['err_rangelength']='You must enter between {$a->format[0]} and {$a->format[1]} characters here.'; +$string['err_required']='You must supply a value here.'; $string['nomethodforaddinghelpbutton'] = 'There is no method for adding a help button to form element $a->name (class $a->classname)'; $string['nonexistentformelements'] = 'Trying to add help buttons to nonexistent form elements : $a'; -$string['requiredelement'] = 'Required field.'; +$string['requiredelement'] = 'Required field'; +$string['general'] = 'General'; +$string['optional'] = 'Optional'; +$string['modstandardels']='Common Module Settings'; +$string['miscellaneoussettings']='Miscellaneous Settings'; +$string['addfields']='Add $a fields to form'; +$string['day']='Day'; +$string['month']='Month'; +$string['year']='Year'; +$string['hour']='Hour'; +$string['minute']='Minute'; +$string['advancedelement']='Advanced Element'; +$string['hideadvanced']='Hide Advanced'; +$string['showadvanced']='Show Advanced'; + +$string['timing'] = 'Timing'; +$string['security'] = 'Security'; +$string['display'] = 'Display'; ?> diff --git a/lib/form/checkbox.php b/lib/form/checkbox.php index 0817ca9b26b..b62861b1de0 100644 --- a/lib/form/checkbox.php +++ b/lib/form/checkbox.php @@ -3,11 +3,11 @@ require_once('HTML/QuickForm/checkbox.php'); /** * HTML class for a checkbox type element - * + * * @author Jamie Pratt * @access public */ -class moodleform_checkbox extends HTML_QuickForm_checkbox{ +class MoodleQuickForm_checkbox extends HTML_QuickForm_checkbox{ /** * html for help button, if empty then no help * @@ -19,18 +19,21 @@ class moodleform_checkbox extends HTML_QuickForm_checkbox{ * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ if (!is_array($helpbuttonargs)){ $helpbuttonargs=array($helpbuttonargs); }else{ $helpbuttonargs=$helpbuttonargs; } - //we do this to to return html instead of printing it + //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - $defaultargs=array('', '', 'moodle', true, false, '', true); - $helpbuttonargs=$helpbuttonargs + $defaultargs ; - $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs); + if ('helpbutton' == $function){ + $defaultargs=array('', '', 'moodle', true, false, '', true); + $helpbuttonargs=$helpbuttonargs + $defaultargs ; + } + $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); } /** * get html for help button @@ -43,21 +46,58 @@ class moodleform_checkbox extends HTML_QuickForm_checkbox{ } /** * Automatically generates and assigns an 'id' attribute for the element. - * + * * Currently used to ensure that labels work on radio buttons and * checkboxes. Per idea of Alexander Radivanovich. * Overriden in moodleforms to remove qf_ prefix. * * @access private - * @return void + * @return void */ function _generateId() { static $idx = 1; if (!$this->getAttribute('id')) { - $this->updateAttributes(array('id' => substr(md5(microtime() . $idx++), 0, 6))); + $this->updateAttributes(array('id' => 'id_'.substr(md5(microtime() . $idx++), 0, 6))); } } // end func _generateId + /** + * Called by HTML_QuickForm whenever form event is made on this element + * + * @param string $event Name of event + * @param mixed $arg event arguments + * @param object $caller calling object + * @since 1.0 + * @access public + * @return void + */ + function onQuickFormEvent($event, $arg, &$caller) + { + //fixes bug in quickforms which lets previous set value override submitted value if checkbox is not checked + // and no value is submitted + switch ($event) { + case 'updateValue': + // constant values override both default and submitted ones + // default values are overriden by submitted + $value = $this->_findValue($caller->_constantValues); + if (null === $value) { + // if no boxes were checked, then there is no value in the array + // yet we don't want to display default value in this case + if ($caller->isSubmitted()) { + $value = $this->_findValue($caller->_submitValues); + } else { + + $value = $this->_findValue($caller->_defaultValues); + } + } + //fix here. setChecked should not be conditional + $this->setChecked($value); + break; + default: + parent::onQuickFormEvent($event, $arg, $caller); + } + return true; + } // end func onQuickFormEvent } ?> \ No newline at end of file diff --git a/lib/form/dateselector.php b/lib/form/dateselector.php index c3cefd0b2f3..aab42ccd417 100644 --- a/lib/form/dateselector.php +++ b/lib/form/dateselector.php @@ -5,25 +5,25 @@ require_once "$CFG->libdir/formslib.php"; /** * Class for a group of elements used to input a date. - * - * Emulates moodle print_date_selector function - * + * + * Emulates moodle print_date_selector function + * * @author Jamie Pratt * @access public */ -class moodleform_date_selector extends moodleform_group +class MoodleQuickForm_date_selector extends MoodleQuickForm_group { /** * Control the fieldnames for form elements * - * day => string day fieldname - * month => string month fieldname - * year => string year fieldname + * startyear => integer start of range of years that can be selected + * stopyear => integer last year that can be selected * timezone => float/string timezone * applydst => apply users daylight savings adjustment? + * optional => if true, show a checkbox beside the date to turn it on (or off) */ var $_options = array('startyear'=>1970, 'stopyear'=>2020, - 'timezone'=>99, 'applydst'=>true); + 'timezone'=>99, 'applydst'=>true, 'optional'=>false); /** * These complement separators, they are appended to the resultant HTML @@ -34,14 +34,14 @@ class moodleform_date_selector extends moodleform_group /** * Class constructor - * + * * @access public * @param string Element's name * @param mixed Label(s) for an element * @param array Options to control the element's display * @param mixed Either a typical HTML attribute string or an associative array */ - function moodleform_date_selector($elementName = null, $elementLabel = null, $options = array(), $attributes = null) + function MoodleQuickForm_date_selector($elementName = null, $elementLabel = null, $options = array(), $attributes = null) { $this->HTML_QuickForm_element($elementName, $elementLabel, $attributes); $this->_persistantFreeze = true; @@ -76,32 +76,82 @@ class moodleform_date_selector extends moodleform_group for ($i=$this->_options['startyear']; $i<=$this->_options['stopyear']; $i++) { $years[$i] = $i; } - $this->_elements[] =& moodleform::createElement('select', 'day', null, $days, $this->getAttributes(), true); - $this->_elements[] =& moodleform::createElement('select','month', null, $months, $this->getAttributes(), true); - $this->_elements[] =& moodleform::createElement('select','year', null, $years, $this->getAttributes(), true); + $this->_elements[] =& MoodleQuickForm::createElement('select', 'day', get_string('day', 'form'), $days, $this->getAttributes(), true); + $this->_elements[] =& MoodleQuickForm::createElement('select', 'month', get_string('month', 'form'), $months, $this->getAttributes(), true); + $this->_elements[] =& MoodleQuickForm::createElement('select', 'year', get_string('year', 'form'), $years, $this->getAttributes(), true); + // If optional we add a checkbox which the user can use to turn if on + if($this->_options['optional']) { + $this->_elements[] =& MoodleQuickForm::createElement('checkbox', 'off', null, get_string('disable'), $this->getAttributes(), true); + } + foreach ($this->_elements as $element){ + if (method_exists($element, 'setHiddenLabel')){ + $element->setHiddenLabel(true); + } + } } // }}} - // {{{ setValue() + // {{{ onQuickFormEvent() - function setValue($value) + /** + * Called by HTML_QuickForm whenever form event is made on this element + * + * @param string $event Name of event + * @param mixed $arg event arguments + * @param object $caller calling object + * @since 1.0 + * @access public + * @return void + */ + function onQuickFormEvent($event, $arg, &$caller) { - if (!($value)) { - $value = time(); + switch ($event) { + case 'updateValue': + // constant values override both default and submitted ones + // default values are overriden by submitted + $value = $this->_findValue($caller->_constantValues); + if (null === $value) { + // if no boxes were checked, then there is no value in the array + // yet we don't want to display default value in this case + if ($caller->isSubmitted()) { + $value = $this->_findValue($caller->_submitValues); + } else { + $value = $this->_findValue($caller->_defaultValues); + } + } + $requestvalue=$value; + if ($value == 0) { + $value = time(); + } + if (!is_array($value)) { + $currentdate = usergetdate($value); + $value = array( + 'day' => $currentdate['mday'], + 'month' => $currentdate['mon'], + 'year' => $currentdate['year']); + // If optional, default to off, unless a date was provided + if($this->_options['optional']) { + $value['off'] = ($requestvalue == 0) ? true : false; + } + } else { + $value['off'] = (isset($value['off'])) ? true : false; + } + if (null !== $value){ + $this->setValue($value); + } + break; + case 'createElement': + if($arg[2]['optional']) { + $caller->disabledIf($arg[0], $arg[0].'[off]', 'checked'); + } + return parent::onQuickFormEvent($event, $arg, $caller); + break; + default: + return parent::onQuickFormEvent($event, $arg, $caller); } - if (!is_array($value)) { - $currentdate = usergetdate($value); - $value = array( - 'day' => $currentdate['mday'], - 'month' => $currentdate['mon'], - 'year' => $currentdate['year']); - - } - parent::setValue($value); - } + } // end func onQuickFormEvent - // }}} // {{{ toHtml() function toHtml() @@ -122,16 +172,7 @@ class moodleform_date_selector extends moodleform_group } // }}} - // {{{ onQuickFormEvent() - function onQuickFormEvent($event, $arg, &$caller) - { - if ('updateValue' == $event) { - return HTML_QuickForm_element::onQuickFormEvent($event, $arg, $caller); - } else { - return parent::onQuickFormEvent($event, $arg, $caller); - } - } /** * Output a timestamp. Give it the name of the group. * @@ -142,16 +183,33 @@ class moodleform_date_selector extends moodleform_group function exportValue(&$submitValues, $assoc = false) { $value = null; - $valuearray = $this->_elements[0]->exportValue($submitValues[$this->getName()], true); - $valuearray +=$this->_elements[1]->exportValue($submitValues[$this->getName()], true); - $valuearray +=$this->_elements[2]->exportValue($submitValues[$this->getName()], true); - $value[$this->getName()]=make_timestamp($valuearray['year'], - $valuearray['month'], - $valuearray['day'], - 0,0,0, - $this->_options['timezone'], - $this->_options['applydst']); - return $value; + $valuearray = array(); + foreach ($this->_elements as $element){ + $thisexport = $element->exportValue($submitValues[$this->getName()], true); + if ($thisexport!=null){ + $valuearray += $thisexport; + } + } + if (count($valuearray)){ + if($this->_options['optional']) { + // If checkbox is on, the value is zero, so go no further + if(!empty($valuearray['off'])) { + $value[$this->getName()]=0; + return $value; + } + } + + $value[$this->getName()]=make_timestamp($valuearray['year'], + $valuearray['month'], + $valuearray['day'], + 0,0,0, + $this->_options['timezone'], + $this->_options['applydst']); + + return $value; + } else { + return null; + } } // }}} diff --git a/lib/form/file.php b/lib/form/file.php index f877f101d39..8c18830c6c6 100644 --- a/lib/form/file.php +++ b/lib/form/file.php @@ -3,11 +3,11 @@ require_once('HTML/QuickForm/file.php'); /** * HTML class for a form element to upload a file - * + * * @author Jamie Pratt * @access public */ -class moodleform_file extends HTML_QuickForm_file{ +class MoodleQuickForm_file extends HTML_QuickForm_file{ /** * html for help button, if empty then no help * @@ -19,27 +19,45 @@ class moodleform_file extends HTML_QuickForm_file{ * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ if (!is_array($helpbuttonargs)){ $helpbuttonargs=array($helpbuttonargs); }else{ $helpbuttonargs=$helpbuttonargs; } - //we do this to to return html instead of printing it + //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - $defaultargs=array('', '', 'moodle', true, false, '', true); - $helpbuttonargs=$helpbuttonargs + $defaultargs ; - $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs); + if ('helpbutton' == $function){ + $defaultargs=array('', '', 'moodle', true, false, '', true); + $helpbuttonargs=$helpbuttonargs + $defaultargs ; + } + $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); } /** - * get html for help button + * set html for help button * * @access public - * @return string html for help button + * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ function getHelpButton(){ return $this->_helpbutton; } + + /** + * Override createElement event to add max files + */ + function onQuickFormEvent($event, $arg, &$caller) + { + if ($event == 'createElement') { + $className = get_class($this); + $this->$className($arg[0], $arg[1].' ('.get_string('maxsize', '', display_size($caller->getMaxFileSize())).')', $arg[2]); + return true; + } + return parent::onQuickFormEvent($event, $arg, $caller); + } // end func onQuickFormEvent + } ?> \ No newline at end of file diff --git a/lib/form/group.php b/lib/form/group.php index f4fcc6e614b..af8be99528f 100644 --- a/lib/form/group.php +++ b/lib/form/group.php @@ -3,14 +3,14 @@ require_once("HTML/QuickForm/group.php"); /** * HTML class for a form element group - * + * * @author Adam Daniel * @author Bertrand Mansion * @version 1.0 * @since PHP4.04pl1 * @access public */ -class moodleform_group extends HTML_QuickForm_group{ +class MoodleQuickForm_group extends HTML_QuickForm_group{ /** * html for help button, if empty then no help * @@ -25,24 +25,28 @@ class moodleform_group extends HTML_QuickForm_group{ * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ if (!is_array($helpbuttonargs)){ $helpbuttonargs=array($helpbuttonargs); }else{ $helpbuttonargs=$helpbuttonargs; } - //we do this to to return html instead of printing it + //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - $defaultargs=array('', '', 'moodle', true, false, '', true); - $helpbuttonargs=$helpbuttonargs + $defaultargs ; - $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs); + if ('helpbutton' == $function){ + $defaultargs=array('', '', 'moodle', true, false, '', true); + $helpbuttonargs=$helpbuttonargs + $defaultargs ; + } + $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); } /** - * get html for help button + * set html for help button * * @access public - * @return string html for help button + * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ function getHelpButton(){ return $this->_helpbutton; @@ -50,4 +54,13 @@ class moodleform_group extends HTML_QuickForm_group{ function getElementTemplateType(){ return $this->_elementTemplateType; } -} \ No newline at end of file + function setElements($elements){ + parent::setElements($elements); + foreach ($this->_elements as $element){ + if (method_exists($element, 'setHiddenLabel')){ + $element->setHiddenLabel(true); + } + } + } +} +?> \ No newline at end of file diff --git a/lib/form/hidden.php b/lib/form/hidden.php index ab6ab0ac173..7e78b1b1fab 100644 --- a/lib/form/hidden.php +++ b/lib/form/hidden.php @@ -3,11 +3,11 @@ require_once('HTML/QuickForm/hidden.php'); /** * HTML class for a hidden type element - * + * * @author Jamie Pratt * @access public */ -class moodleform_hidden extends HTML_QuickForm_hidden{ +class MoodleQuickForm_hidden extends HTML_QuickForm_hidden{ /** * html for help button, if empty then no help * @@ -19,9 +19,10 @@ class moodleform_hidden extends HTML_QuickForm_hidden{ * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ - + function setHelpButton($helpbuttonargs, $function='helpbutton'){ + } /** * get html for help button diff --git a/lib/form/htmleditor.php b/lib/form/htmleditor.php index 0ecc1f8bed9..8d50419bb04 100644 --- a/lib/form/htmleditor.php +++ b/lib/form/htmleditor.php @@ -4,17 +4,17 @@ require_once("$CFG->libdir/form/textarea.php"); /** * HTML class for htmleditor type element - * + * * @author Jamie Pratt * @access public */ -class moodleform_htmleditor extends moodleform_textarea{ +class MoodleQuickForm_htmleditor extends MoodleQuickForm_textarea{ var $_type; var $_elementTemplateType='default'; var $_canUseHtmlEditor; - var $_options=array('canUseHtmlEditor'=>'detect','rows'=>10, 'cols'=>65, 'width'=>0,'height'=>0, 'course'=>0); - function moodleform_htmleditor($elementName=null, $elementLabel=null, $options=array(), $attributes=null){ - parent::moodleform_textarea($elementName, $elementLabel, $attributes); + var $_options=array('canUseHtmlEditor'=>'detect','rows'=>10, 'cols'=>45, 'width'=>0,'height'=>0, 'course'=>0); + function MoodleQuickForm_htmleditor($elementName=null, $elementLabel=null, $options=array(), $attributes=null){ + parent::MoodleQuickForm_textarea($elementName, $elementLabel, $attributes); // set the options, do not bother setting bogus ones if (is_array($options)) { foreach ($options as $name => $value) { @@ -36,14 +36,36 @@ class moodleform_htmleditor extends moodleform_textarea{ }else{ $this->_type='textarea'; } + $this->_canUseHtmlEditor = $this->_options['canUseHtmlEditor']; + } + /** + * set html for help button + * + * @access public + * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html + */ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ + if (!$this->_canUseHtmlEditor){ + if ('editorhelpbutton' == $function){ + $key = array_search('richtext', $helpbuttonargs); + if ($key !== FALSE){ + array_splice($helpbuttonargs, $key, 1, array('text', 'emoticons')); + } + } elseif ('helpbutton' == $function && $helpbuttonargs[0] == 'richtext' && ((!isset($helpbuttonargs[2])) || $helpbuttonargs[2] == 'moodle')){ + //replace single 'richtext' help button with text and emoticon button when htmleditor off. + return $this->setHelpButton(array('text', 'emoticons'), 'editorhelpbutton'); + } + } + return parent::setHelpButton($helpbuttonargs, $function); } function getElementTemplateType(){ return $this->_elementTemplateType; } function toHtml(){ - if ($this->_options['canUseHtmlEditor'] && !$this->_flagFrozen){ + if ($this->_canUseHtmlEditor && !$this->_flagFrozen){ ob_start(); - use_html_editor($this->getName()); + use_html_editor($this->getName(), '', $this->getAttribute('id')); $script=ob_get_clean(); } else { $script=''; @@ -52,7 +74,7 @@ class moodleform_htmleditor extends moodleform_textarea{ return $this->getFrozenHtml(); } else { return $this->_getTabs() . - print_textarea($this->_options['canUseHtmlEditor'], + print_textarea($this->_canUseHtmlEditor, $this->_options['rows'], $this->_options['cols'], $this->_options['width'], @@ -60,7 +82,8 @@ class moodleform_htmleditor extends moodleform_textarea{ $this->getName(), preg_replace("/(\r\n|\n|\r)/", ' ',$this->getValue()), $this->_options['course'], - true).$script; + true, + $this->getAttribute('id')).$script; } } //end func toHtml diff --git a/lib/form/password.php b/lib/form/password.php index d719da84860..9c0cc08aff0 100644 --- a/lib/form/password.php +++ b/lib/form/password.php @@ -3,11 +3,11 @@ require_once('HTML/QuickForm/password.php'); /** * HTML class for a password type element - * + * * @author Jamie Pratt * @access public */ -class moodleform_password extends HTML_QuickForm_password{ +class MoodleQuickForm_password extends HTML_QuickForm_password{ /** * html for help button, if empty then no help * @@ -19,18 +19,21 @@ class moodleform_password extends HTML_QuickForm_password{ * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ if (!is_array($helpbuttonargs)){ $helpbuttonargs=array($helpbuttonargs); }else{ $helpbuttonargs=$helpbuttonargs; } - //we do this to to return html instead of printing it + //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - $defaultargs=array('', '', 'moodle', true, false, '', true); - $helpbuttonargs=$helpbuttonargs + $defaultargs ; - $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs); + if ('helpbutton' == $function){ + $defaultargs=array('', '', 'moodle', true, false, '', true); + $helpbuttonargs=$helpbuttonargs + $defaultargs ; + } + $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); } /** * get html for help button diff --git a/lib/form/radio.php b/lib/form/radio.php index f87638e8009..9d305ee6a7b 100644 --- a/lib/form/radio.php +++ b/lib/form/radio.php @@ -3,11 +3,11 @@ require_once('HTML/QuickForm/radio.php'); /** * HTML class for a radio type element - * + * * @author Jamie Pratt * @access public */ -class moodleform_radio extends HTML_QuickForm_radio{ +class MoodleQuickForm_radio extends HTML_QuickForm_radio{ /** * html for help button, if empty then no help * @@ -19,18 +19,21 @@ class moodleform_radio extends HTML_QuickForm_radio{ * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ if (!is_array($helpbuttonargs)){ $helpbuttonargs=array($helpbuttonargs); }else{ $helpbuttonargs=$helpbuttonargs; } - //we do this to to return html instead of printing it + //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - $defaultargs=array('', '', 'moodle', true, false, '', true); - $helpbuttonargs=$helpbuttonargs + $defaultargs ; - $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs); + if ('helpbutton' == $function){ + $defaultargs=array('', '', 'moodle', true, false, '', true); + $helpbuttonargs=$helpbuttonargs + $defaultargs ; + } + $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); } /** * get html for help button @@ -43,20 +46,20 @@ class moodleform_radio extends HTML_QuickForm_radio{ } /** * Automatically generates and assigns an 'id' attribute for the element. - * + * * Currently used to ensure that labels work on radio buttons and * checkboxes. Per idea of Alexander Radivanovich. * Overriden in moodleforms to remove qf_ prefix. * * @access private - * @return void + * @return void */ function _generateId() { static $idx = 1; if (!$this->getAttribute('id')) { - $this->updateAttributes(array('id' => substr(md5(microtime() . $idx++), 0, 6))); + $this->updateAttributes(array('id' => 'id_'.substr(md5(microtime() . $idx++), 0, 6))); } } // end func _generateId } diff --git a/lib/form/select.php b/lib/form/select.php index 521ca17bc8c..e96d1f22160 100644 --- a/lib/form/select.php +++ b/lib/form/select.php @@ -3,34 +3,68 @@ require_once('HTML/QuickForm/select.php'); /** * HTML class for a select type element - * + * * @author Jamie Pratt * @access public */ -class moodleform_select extends HTML_QuickForm_select{ +class MoodleQuickForm_select extends HTML_QuickForm_select{ /** * html for help button, if empty then no help * * @var string */ var $_helpbutton=''; + var $_hiddenLabel=false; + function setHiddenLabel($hiddenLabel){ + $this->_hiddenLabel = $hiddenLabel; + } + function toHtml(){ + if ($this->_hiddenLabel){ + $this->_generateId(); + return ''.parent::toHtml(); + } else { + return parent::toHtml(); + } + } + /** + * Automatically generates and assigns an 'id' attribute for the element. + * + * Currently used to ensure that labels work on radio buttons and + * checkboxes. Per idea of Alexander Radivanovich. + * Overriden in moodleforms to remove qf_ prefix. + * + * @access private + * @return void + */ + function _generateId() + { + static $idx = 1; + + if (!$this->getAttribute('id')) { + $this->updateAttributes(array('id' => 'id_'. substr(md5(microtime() . $idx++), 0, 6))); + } + } // end func _generateId /** * set html for help button * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ if (!is_array($helpbuttonargs)){ $helpbuttonargs=array($helpbuttonargs); }else{ $helpbuttonargs=$helpbuttonargs; } - //we do this to to return html instead of printing it + //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - $defaultargs=array('', '', 'moodle', true, false, '', true); - $helpbuttonargs=$helpbuttonargs + $defaultargs ; - $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs); + if ('helpbutton' == $function){ + $defaultargs=array('', '', 'moodle', true, false, '', true); + $helpbuttonargs=$helpbuttonargs + $defaultargs ; + } + $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); } /** * get html for help button @@ -41,5 +75,52 @@ class moodleform_select extends HTML_QuickForm_select{ function getHelpButton(){ return $this->_helpbutton; } + /** + * Removes an OPTION from the SELECT + * + * @param string $value Value for the OPTION to remove + * @since 1.0 + * @access public + * @return void + */ + function removeOption($value) + { + $key=array_search($value, $this->_values); + if ($key!==FALSE || $key!==null) { + unset($this->_values[$key]); + } + foreach ($this->_options as $key=>$option){ + if ($option['attr']['value']==$value){ + unset($this->_options[$key]); + return; + } + } + } // end func removeOption + /** + * Removes all OPTIONs from the SELECT + * + * @param string $value Value for the OPTION to remove + * @since 1.0 + * @access public + * @return void + */ + function removeOptions() + { + $this->_options = array(); + } // end func removeOption + /** + * Slightly different container template when frozen. Don't want to use a label tag + * with a for attribute in that case for the element label but instead use a div. + * Templates are defined in renderer constructor. + * + * @return string + */ + function getElementTemplateType(){ + if ($this->_flagFrozen){ + return 'static'; + } else { + return 'default'; + } + } } ?> \ No newline at end of file diff --git a/lib/form/static.php b/lib/form/static.php index 82a6073433c..4e5503d08fb 100644 --- a/lib/form/static.php +++ b/lib/form/static.php @@ -3,11 +3,12 @@ require_once("HTML/QuickForm/static.php"); /** * HTML class for a text type element - * + * * @author Jamie Pratt * @access public */ -class moodleform_static extends HTML_QuickForm_static{ +class MoodleQuickForm_static extends HTML_QuickForm_static{ + var $_elementTemplateType='static'; /** * html for help button, if empty then no help * @@ -19,18 +20,21 @@ class moodleform_static extends HTML_QuickForm_static{ * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ if (!is_array($helpbuttonargs)){ $helpbuttonargs=array($helpbuttonargs); }else{ $helpbuttonargs=$helpbuttonargs; } - //we do this to to return html instead of printing it + //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - $defaultargs=array('', '', 'moodle', true, false, '', true); - $helpbuttonargs=$helpbuttonargs + $defaultargs ; - $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs); + if ('helpbutton' == $function){ + $defaultargs=array('', '', 'moodle', true, false, '', true); + $helpbuttonargs=$helpbuttonargs + $defaultargs ; + } + $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); } /** * get html for help button @@ -41,5 +45,9 @@ class moodleform_static extends HTML_QuickForm_static{ function getHelpButton(){ return $this->_helpbutton; } + + function getElementTemplateType(){ + return $this->_elementTemplateType; + } } ?> \ No newline at end of file diff --git a/lib/form/text.php b/lib/form/text.php index d1bf0c4d947..b0eccb4f897 100644 --- a/lib/form/text.php +++ b/lib/form/text.php @@ -3,34 +3,68 @@ require_once("HTML/QuickForm/text.php"); /** * HTML class for a text type element - * + * * @author Jamie Pratt * @access public */ -class moodleform_text extends HTML_QuickForm_text{ +class MoodleQuickForm_text extends HTML_QuickForm_text{ /** * html for help button, if empty then no help * * @var string */ var $_helpbutton=''; + var $_hiddenLabel=false; + function setHiddenLabel($hiddenLabel){ + $this->_hiddenLabel = $hiddenLabel; + } + function toHtml(){ + if ($this->_hiddenLabel){ + $this->_generateId(); + return ''.parent::toHtml(); + } else { + return parent::toHtml(); + } + } + /** + * Automatically generates and assigns an 'id' attribute for the element. + * + * Currently used to ensure that labels work on radio buttons and + * checkboxes. Per idea of Alexander Radivanovich. + * Overriden in moodleforms to remove qf_ prefix. + * + * @access private + * @return void + */ + function _generateId() + { + static $idx = 1; + + if (!$this->getAttribute('id')) { + $this->updateAttributes(array('id' => 'id_'. substr(md5(microtime() . $idx++), 0, 6))); + } + } // end func _generateId /** * set html for help button * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ if (!is_array($helpbuttonargs)){ $helpbuttonargs=array($helpbuttonargs); }else{ $helpbuttonargs=$helpbuttonargs; } - //we do this to to return html instead of printing it + //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - $defaultargs=array('', '', 'moodle', true, false, '', true); - $helpbuttonargs=$helpbuttonargs + $defaultargs ; - $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs); + if ('helpbutton' == $function){ + $defaultargs=array('', '', 'moodle', true, false, '', true); + $helpbuttonargs=$helpbuttonargs + $defaultargs ; + } + $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); } /** * get html for help button @@ -41,4 +75,18 @@ class moodleform_text extends HTML_QuickForm_text{ function getHelpButton(){ return $this->_helpbutton; } + /** + * Slightly different container template when frozen. Don't want to use a label tag + * with a for attribute in that case for the element label but instead use a div. + * Templates are defined in renderer constructor. + * + * @return string + */ + function getElementTemplateType(){ + if ($this->_flagFrozen){ + return 'static'; + } else { + return 'default'; + } + } } \ No newline at end of file diff --git a/lib/form/textarea.php b/lib/form/textarea.php index 2e3450a2887..348d3c039d9 100644 --- a/lib/form/textarea.php +++ b/lib/form/textarea.php @@ -3,11 +3,17 @@ require_once('HTML/QuickForm/textarea.php'); /** * HTML class for a textarea type element - * + * * @author Jamie Pratt * @access public */ -class moodleform_textarea extends HTML_QuickForm_textarea{ +class MoodleQuickForm_textarea extends HTML_QuickForm_textarea{ + /** + * Need to store id of form as we may need it for helpbutton + * + * @var string + */ + var $_formid = ''; /** * html for help button, if empty then no help * @@ -19,18 +25,27 @@ class moodleform_textarea extends HTML_QuickForm_textarea{ * * @access public * @param array $help array of arguments to make a help button + * @param string $function function name to call to get html */ - function setHelpButton($helpbuttonargs){ + function setHelpButton($helpbuttonargs, $function='helpbutton'){ + global $SESSION; if (!is_array($helpbuttonargs)){ $helpbuttonargs=array($helpbuttonargs); }else{ $helpbuttonargs=$helpbuttonargs; } - //we do this to to return html instead of printing it + //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - $defaultargs=array('', '', 'moodle', true, false, '', true); - $helpbuttonargs=$helpbuttonargs + $defaultargs ; - $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs); + if ('helpbutton' == $function){ + $defaultargs=array('', '', 'moodle', true, false, '', true); + $helpbuttonargs=$helpbuttonargs + $defaultargs ; + } elseif ('editorhelpbutton' == $function){ + if (in_array('emoticons', $helpbuttonargs)){ + $SESSION->inserttextform = $this->_formid; + $SESSION->inserttextfield = $this->getAttribute('name'); + } + } + $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); } /** * get html for help button @@ -41,5 +56,24 @@ class moodleform_textarea extends HTML_QuickForm_textarea{ function getHelpButton(){ return $this->_helpbutton; } + /** + * Called by HTML_QuickForm whenever form event is made on this element + * + * @param string $event Name of event + * @param mixed $arg event arguments + * @param object $caller calling object + * @since 1.0 + * @access public + * @return void + */ + function onQuickFormEvent($event, $arg, &$caller) + { + switch ($event) { + case 'createElement': + $this->_formid = $caller->getAttribute('id'); + break; + } + return parent::onQuickFormEvent($event, $arg, $caller); + } // end func onQuickFormEvent } ?> \ No newline at end of file diff --git a/lib/formslib.php b/lib/formslib.php index 7aa81515fa8..32604fa8e0d 100644 --- a/lib/formslib.php +++ b/lib/formslib.php @@ -1,7 +1,21 @@ -debug >= DEBUG_ALL){ - PEAR::setErrorHandling(PEAR_ERROR_PRINT); +require_once $CFG->libdir.'/uploadlib.php'; + +/** + * Callback called when PEAR throws an error + * + * @param PEAR_Error $error + */ +function pear_handle_error($error){ + echo ''.$error->GetMessage().' '.$error->getUserInfo(); + echo '
Backtrace :'; + print_object($error->backtrace); } -class moodleform extends HTML_QuickForm_DHTMLRulesTableless{ +if ($CFG->debug >= DEBUG_ALL){ + PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'pear_handle_error'); +} + + +/** + * Moodle specific wrapper that separates quickforms syntax from moodle code. You won't directly + * use this class you should write a class defintion which extends this class or a more specific + * subclass such a moodleform_mod for each form you want to display and/or process with formslib. + * + * You will write your own definition() method which performs the form set up. + */ +class moodleform { + var $_formname; // form name + /** + * quickform object definition + * + * @var MoodleQuickForm + */ + var $_form; + /** + * globals workaround + * + * @var array + */ + var $_customdata; + /** + * file upload manager + * + * @var upload_manager + */ + var $_upload_manager; // + + + + /** + * The constructor function calls the abstract function definition() and it will then + * process and clean and attempt to validate incoming data. + * + * It will call your custom validate method to validate data and will also check any rules + * you have specified in definition using addRule + * + * The name of the form (id attribute of the form) is automatically generated depending on + * the name you gave the class extending moodleform. You should call your class something + * like + * + * @param string $action the action attribute for the form. If empty defaults to auto detect the + * current url. + * @param array $customdata if your form defintion method needs access to data such as $course + * $cm, etc. to construct the form definition then pass it in this array. You can + * use globals for somethings. + * @param string $method if you set this to anything other than 'post' then _GET and _POST will + * be merged and used as incoming data to the form. + * @param string $target target frame for form submission. You will rarely use this. Don't use + * it if you don't need to as the target attribute is deprecated in xhtml + * strict. + * @param mixed $attributes you can pass a string of html attributes here or an array. + * @return moodleform + */ + function moodleform($action=null, $customdata=null, $method='post', $target='', $attributes=null) { + if (empty($action)){ + $action = strip_querystring(qualified_me()); + } + + $this->_formname = get_class($this); // '_form' suffix kept in order to prevent collisions of form id and other element + $this->_customdata = $customdata; + $this->_form =& new MoodleQuickForm($this->_formname, $method, $action, $target, $attributes); + $this->set_upload_manager(new upload_manager()); + + $this->definition(); + + $this->_form->addElement('hidden', 'sesskey', null); // automatic sesskey protection + $this->_form->setDefault('sesskey', sesskey()); + $this->_form->addElement('hidden', '_qf__'.$this->_formname, null); // form submission marker + $this->_form->setDefault('_qf__'.$this->_formname, 1); + $this->_form->_setDefaultRuleMessages(); + + // we have to know all input types before processing submission ;-) + $this->_process_submission($method); + + // update form definition based on final data + $this->definition_after_data(); + } + + /** + * To autofocus on first form element or first element with error. + * + * @param string $name if this is set then the focus is forced to a field with this name + * + * @return string javascript to select form element with first error or + * first element if no errors. Use this as a parameter + * when calling print_header + */ + function focus($name=NULL){ + $form =& $this->_form; + $elkeys=array_keys($form->_elementIndex); + if (isset($form->_errors) && 0 != count($form->_errors)){ + $errorkeys = array_keys($form->_errors); + $elkeys = array_intersect($elkeys, $errorkeys); + } + $names=null; + while (!$names){ + $el = array_shift($elkeys); + $names = $form->_getElNamesRecursive($el); + } + if (empty($name)) { + $name=array_shift($names); + } + $focus='forms[\''.$this->_form->getAttribute('id').'\'].elements[\''.$name.'\']'; + return $focus; + } + + /** + * Internal method. Alters submitted data to be suitable for quickforms processing. + * Must be called when the form is fully set up. + */ + function _process_submission($method) { + $submission = array(); + if ($method == 'post') { + if (!empty($_POST)) { + $submission = $_POST; + } + } else { + $submission = array_merge_recursive($_GET, $_POST); // emulate handling of parameters in xxxx_param() + } + + // following trick is needed to enable proper sesskey checks when using GET forms + // the _qf__.$this->_formname serves as a marker that form was actually submitted + if (array_key_exists('_qf__'.$this->_formname, $submission) and $submission['_qf__'.$this->_formname] == 1) { + if (!confirm_sesskey()) { + error('Incorrect sesskey submitted, form not accepted!'); + } + $files = $_FILES; + } else { + $submission = array(); + $files = array(); + } + + $this->_form->updateSubmission($submission, $files); + } + + /** + * Internal method. Validates all uploaded files. + */ + function _validate_files() { + if (empty($_FILES)) { + // we do not need to do any checks because no files were submitted + // TODO: find out why server side required rule does not work for uploaded files; + // testing is easily done by always returning true from this function and adding + // $mform->addRule('soubor', get_string('required'), 'required', null, 'server'); + // and submitting form without selected file + return true; + } + $errors = array(); + $mform =& $this->_form; + + // check the files + $status = $this->_upload_manager->preprocess_files(); + + // now check that we really want each file + foreach ($_FILES as $elname=>$file) { + if ($mform->elementExists($elname) and $mform->getElementType($elname)=='file') { + $required = $mform->isElementRequired($elname); + if (!empty($this->_upload_manager->files[$elname]['uploadlog']) and empty($this->_upload_manager->files[$elname]['clear'])) { + if (!$required and $file['error'] == UPLOAD_ERR_NO_FILE) { + // file not uploaded and not required - ignore it + continue; + } + $errors[$elname] = $this->_upload_manager->files[$elname]['uploadlog']; + } + } else { + error('Incorrect upload attempt!'); + } + } + + // return errors if found + if ($status and 0 == count($errors)){ + return true; + } else { + return $errors; + } + } + + /** + * Load in existing data as form defaults. Usually new entry defaults are stored directly in + * form definition (new entry form); this function is used to load in data where values + * already exist and data is being edited (edit entry form). + * + * @param mixed $default_values object or array of default values + * @param bool $slased true if magic quotes applied to data values + */ + function set_data($default_values, $slashed=false) { + if (is_object($default_values)) { + $default_values = (array)$default_values; + } + $filter = $slashed ? 'stripslashes' : NULL; + $this->_form->setDefaults($default_values, $filter); + //update form definition when data changed + $this->definition_after_data(); + } + + /** + * Set custom upload manager. + * Must be used BEFORE creating of file element! + * + * @param object $um - custom upload manager + */ + function set_upload_manager($um=false) { + if ($um === false) { + $um = new upload_manager(); + } + $this->_upload_manager = $um; + + $this->_form->setMaxFileSize($um->config->maxbytes); + } + + /** + * Check that form was submitted. Does not check validity of submitted data. + * + * @return bool true if form properly submitted + */ + function is_submitted() { + return $this->_form->isSubmitted(); + } + + function no_submit_button_pressed(){ + static $nosubmit = null; // one check is enough + if (!is_null($nosubmit)){ + return $nosubmit; + } + $mform =& $this->_form; + $nosubmit = false; + if (!$this->is_submitted()){ + return false; + } + foreach ($mform->_noSubmitButtons as $nosubmitbutton){ + if (optional_param($nosubmitbutton, 0, PARAM_RAW)){ + $nosubmit = true; + break; + } + } + return $nosubmit; + } + + + /** + * Check that form data is valid. + * + * @return bool true if form data valid + */ + function is_validated() { + static $validated = null; // one validation is enough + $mform =& $this->_form; + + if ($this->no_submit_button_pressed()){ + return false; + } elseif ($validated === null) { + $internal_val = $mform->validate(); + $moodle_val = $this->validation($mform->exportValues(null, true)); + if ($moodle_val !== true) { + if ((is_array($moodle_val) && count($moodle_val)!==0)) { + foreach ($moodle_val as $element=>$msg) { + $mform->setElementError($element, $msg); + } + $moodle_val = false; + } else { + $moodle_val = true; + } + } + $file_val = $this->_validate_files(); + if ($file_val !== true) { + if (!empty($file_val)) { + foreach ($file_val as $element=>$msg) { + $mform->setElementError($element, $msg); + } + } + $file_val = false; + } + $validated = ($internal_val and $moodle_val and $file_val); + } + return $validated; + } + + /** + * Return true if a cancel button has been pressed resulting in the form being submitted. + * + * @return boolean true if a cancel button has been pressed + */ + function is_cancelled(){ + $mform =& $this->_form; + if ($mform->isSubmitted()){ + foreach ($mform->_cancelButtons as $cancelbutton){ + if (optional_param($cancelbutton, 0, PARAM_RAW)){ + return true; + } + } + } + return false; + } + + /** + * Return submitted data if properly submitted or returns NULL if validation fails or + * if there is no submitted data. + * + * @param bool $slashed true means return data with addslashes applied + * @return object submitted data; NULL if not valid or not submitted + */ + function get_data($slashed=true) { + $mform =& $this->_form; + + if ($this->is_submitted() and $this->is_validated()) { + $data = $mform->exportValues(null, $slashed); + unset($data['sesskey']); // we do not need to return sesskey + unset($data['_qf__'.$this->_formname]); // we do not need the submission marker too + if (empty($data)) { + return NULL; + } else { + return (object)$data; + } + } else { + return NULL; + } + } + + /** + * Save verified uploaded files into directory. Upload process can be customised from definition() + * method by creating instance of upload manager and storing it in $this->_upload_form + * + * @param string $destination where to store uploaded files + * @return bool success + */ + function save_files($destination) { + if ($this->is_submitted() and $this->is_validated()) { + return $this->_upload_manager->save_files($destination); + } + return false; + } + + /** + * If we're only handling one file (if inputname was given in the constructor) + * this will return the (possibly changed) filename of the file. + * @return mixed false in case of failure, string if ok + */ + function get_new_filename() { + return $this->_upload_manager->get_new_filename(); + } + + /** + * Print html form. + */ + function display() { + $this->_form->display(); + } + + /** + * Abstract method - always override! + * + * If you need special handling of uploaded files, create instance of $this->_upload_manager here. + */ + function definition() { + error('Abstract form_definition() method in class '.get_class($this).' must be overriden, please fix the code.'); + } + + /** + * Dummy stub method - override if you need to setup the form depending on current + * values. This method is called after definition(), data submission and set_data(). + * All form setup that is dependent on form values should go in here. + */ + function definition_after_data(){ + } + + /** + * Dummy stub method - override if you needed to perform some extra validation. + * If there are errors return array of errors ("fieldname"=>"error message"), + * otherwise true if ok. + * + * @param array $data array of ("fieldname"=>value) of submitted data + * @return bool array of errors or true if ok + */ + function validation($data) { + return true; + } + + + + + + /** + * Method to add a repeating group of elements to a form. + * + * @param array $elementobjs Array of elements or groups of elements that are to be repeated + * @param integer $repeats no of times to repeat elements initially + * @param array $options Array of options to apply to elements. Array keys are element names. + * This is an array of arrays. The second sets of keys are the option types + * for the elements : + * 'default' - default value is value + * 'type' - PARAM_* constant is value + * 'helpbutton' - helpbutton params array is value + * 'disabledif' - last three moodleform::disabledIf() + * params are value as an array + * @param string $repeathiddenname name for hidden element storing no of repeats in this form + * @param string $addfieldsname name for button to add more fields + * @param int $addfieldsno how many fields to add at a time + * @param string $addstring name of button, {no} is replaced by no of blanks that will be added. + * @return int no of repeats of element in this page + */ + function repeat_elements($elementobjs, $repeats, $options, $repeathiddenname, $addfieldsname, $addfieldsno=5, $addstring=null){ + if ($addstring===null){ + $addstring = get_string('addfields', 'form', $addfieldsno); + } else { + $addstring = str_ireplace('{no}', $addfieldsno, $addstring); + } + $repeats = optional_param($repeathiddenname, $repeats, PARAM_INT); + $addfields = optional_param($addfieldsname, '', PARAM_TEXT); + if (!empty($addfields)){ + $repeats += $addfieldsno; + } + $mform =& $this->_form; + $mform->registerNoSubmitButton($addfieldsname); + $mform->addElement('hidden', $repeathiddenname, $repeats); + //value not to be overridden by submitted value + $mform->setConstants(array($repeathiddenname=>$repeats)); + for ($i=0; $i<$repeats; $i++) { + foreach ($elementobjs as $elementobj){ + $elementclone = clone($elementobj); + $name = $elementclone->getName(); + if (!empty($name)){ + $elementclone->setName($name."[$i]"); + } + if (is_a($elementclone, 'HTML_QuickForm_header')){ + $value=$elementclone->_text; + $elementclone->setValue(str_replace('{no}', ($i+1), $value)); + + } else { + $value=$elementclone->getLabel(); + $elementclone->setLabel(str_replace('{no}', ($i+1), $value)); + + } + + $mform->addElement($elementclone); + } + } + for ($i=0; $i<$repeats; $i++) { + foreach ($options as $elementname => $elementoptions){ + $pos=strpos($elementname, '['); + if ($pos!==FALSE){ + $realelementname = substr($elementname, 0, $pos+1)."[$i]"; + $realelementname .= substr($elementname, $pos+1); + }else { + $realelementname = $elementname."[$i]"; + } + foreach ($elementoptions as $option => $params){ + + switch ($option){ + case 'default' : + $mform->setDefault($realelementname, $params); + break; + case 'helpbutton' : + $mform->setHelpButton($realelementname, $params); + break; + case 'disabledif' : + $params = array_merge(array($realelementname), $params); + call_user_func_array(array(&$mform, 'disabledIf'), $params); + break; + case 'rule' : + if (is_string($params)){ + $params = array(null, $params, null, 'client'); + } + $params = array_merge(array($realelementname), $params); + call_user_func_array(array(&$mform, 'addRule'), $params); + break; + + } + } + } + } + $mform->addElement('submit', $addfieldsname, $addstring); + + $mform->closeHeaderBefore($addfieldsname); + + return $repeats; + } + /** + * Use this method to a cancel and submit button to the end of your form. Pass a param of false + * if you don't want a cancel button in your form. If you have a cancel button make sure you + * check for it being pressed using is_cancelled() and redirecting if it is true before trying to + * get data with get_data(). + * + * @param boolean $cancel whether to show cancel button, default true + * @param boolean $revert whether to show revert button, default true + * @param string $submitlabel label for submit button, defaults to get_string('savechanges') + */ + function add_action_buttons($cancel = true, $submitlabel=null){ + if (is_null($submitlabel)){ + $submitlabel = get_string('savechanges'); + } + $mform =& $this->_form; + if ($cancel){ + //when two elements we need a group + $buttonarray=array(); + $buttonarray[] = &$mform->createElement('submit', 'submitbutton', $submitlabel); + $buttonarray[] = &$mform->createElement('cancel'); + $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); + $mform->closeHeaderBefore('buttonar'); + } else { + //no group needed + $mform->addElement('submit', 'submitbutton', $submitlabel); + $mform->closeHeaderBefore('submitbutton'); + } + } +} + +/** + * You never extend this class directly. The class methods of this class are available from + * the private $this->_form property on moodleform and it's children. You generally only + * call methods on this class from within abstract methods that you override on moodleform such + * as definition and definition_after_data + * + */ +class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless { + var $_types = array(); + var $_dependencies = array(); + /** + * Array of buttons that if pressed do not result in the processing of the form. + * + * @var array + */ + var $_noSubmitButtons=array(); + /** + * Array of buttons that if pressed do not result in the processing of the form. + * + * @var array + */ + var $_cancelButtons=array(); + + /** + * Array whose keys are element names. If the key exists this is a advanced element + * + * @var array + */ + var $_advancedElements = array(); + + /** + * Whether to display advanced elements (on page load) + * + * @var boolean + */ + var $_showAdvanced = null; + + /** + * The form name is derrived from the class name of the wrapper minus the trailing form + * It is a name with words joined by underscores whereas the id attribute is words joined by + * underscores. + * + * @var unknown_type + */ + var $_formName = ''; + /** * Class constructor - same parameters as HTML_QuickForm_DHTMLRulesTableless * @param string $formName Form's name. @@ -30,218 +610,728 @@ class moodleform extends HTML_QuickForm_DHTMLRulesTableless{ * @param bool $trackSubmit (optional)Whether to track if the form was submitted by adding a special hidden field * @access public */ - function moodleform($formName='', $method='post', $action='', $target='', $attributes=null){ + function MoodleQuickForm($formName, $method, $action, $target='', $attributes=null){ global $CFG; - //we need to override the constructor, we don't call the parent constructor - //at all because it strips slashes depending on the magic quotes setting - //whereas Moodle already has added slashes whether magic quotes is on or not. - - //also added check for sesskey and added sesskey to all forms - //and told class to ask Moodle for the max upload file size - HTML_Common::HTML_Common($attributes); - $method = (strtoupper($method) == 'GET') ? 'get' : 'post'; - $action = ($action == '') ? $_SERVER['PHP_SELF'] : $action; - $target = empty($target) ? array() : array('target' => $target); - //no 'name' atttribute for form in xhtml strict : - $attributes = array('action'=>$action, 'method'=>$method, 'id'=>$formName) + $target; - $this->updateAttributes($attributes); - //check for sesskey for this form - //if it is not present then we don't accept any input - if (isset($_REQUEST['_qf__' . $formName])) { - $this->_submitValues = $this->_recursiveFilter('stripslashes', 'get' == $method? $_GET: $_POST); - foreach ($_FILES as $keyFirst => $valFirst) { - foreach ($valFirst as $keySecond => $valSecond) { - if ('name' == $keySecond) { - $this->_submitFiles[$keyFirst][$keySecond] = $this->_recursiveFilter('stripslashes', $valSecond); - } else { - $this->_submitFiles[$keyFirst][$keySecond] = $valSecond; - } - } - } - $this->_flagSubmitted = count($this->_submitValues) > 0 || count($this->_submitFiles) > 0; - } - - //check sesskey - if ($this->_flagSubmitted){ - confirm_sesskey($this->_submitValues['_qf__' . $formName]); - } - unset($this->_submitValues['_qf__' . $formName]); - //add sesskey to all forms - $this->addElement('hidden', '_qf__' . $formName, sesskey()); - - if (preg_match('/^([0-9]+)([a-zA-Z]*)$/', get_max_upload_file_size(), $matches)) { - // see http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes - switch (strtoupper($matches['2'])) { - case 'G': - $this->_maxFileSize = $matches['1'] * 1073741824; - break; - case 'M': - $this->_maxFileSize = $matches['1'] * 1048576; - break; - case 'K': - $this->_maxFileSize = $matches['1'] * 1024; - break; - default: - $this->_maxFileSize = $matches['1']; - } - } - //this is custom stuff for Moodle : + static $formcounter = 1; + + HTML_Common::HTML_Common($attributes); + $target = empty($target) ? array() : array('target' => $target); + $this->_formName = $formName; + //no 'name' atttribute for form in xhtml strict : + $attributes = array('action'=>$action, 'method'=>$method, 'id'=>'mform'.$formcounter) + $target; + $formcounter++; + $this->updateAttributes($attributes); + + //this is custom stuff for Moodle : $oldclass= $this->getAttribute('class'); if (!empty($oldclass)){ $this->updateAttributes(array('class'=>$oldclass.' mform')); }else { $this->updateAttributes(array('class'=>'mform')); } - $this->_helpImageURL="$CFG->wwwroot/lib/form/req.gif"; - $this->_reqHTML = - helpbutton('requiredelement', get_string('requiredelement', 'form'),'moodle', - true, false, '', true, ''.get_string('requiredelement', 'form').''); - $this->setRequiredNote(get_string('denotesreq', 'form', $this->getReqHTML())); + $this->_reqHTML = ''.get_string('requiredelement', 'form').''; + $this->_advancedHTML = ''.get_string('advancedelement', 'form').''; + $this->setRequiredNote(get_string('somefieldsrequired', 'form', ''.get_string('requiredelement', 'form').'')); + //(Help file doesn't add anything) helpbutton('requiredelement', get_string('requiredelement', 'form'), 'moodle', true, false, '', true)); } + + /** + * Use this method to indicate an element in a form is an advanced field. If items in a form + * are marked as advanced then 'Hide/Show Advanced' buttons will automatically be displayed in the + * form so the user can decide whether to display advanced form controls. + * + * If you set a header element to advanced then all elements it contains will also be set as advanced. + * + * @param string $elementName group or element name (not the element name of something inside a group). + * @param boolean $advanced default true sets the element to advanced. False removes advanced mark. + */ + function setAdvanced($elementName, $advanced=true){ + if ($advanced){ + $this->_advancedElements[$elementName]=''; + } elseif (isset($this->_advancedElements[$elementName])) { + unset($this->_advancedElements[$elementName]); + } + if ($advanced && $this->getElementType('mform_showadvanced_last')===false){ + $this->setShowAdvanced(); + $this->registerNoSubmitButton('mform_showadvanced'); + + $this->addElement('hidden', 'mform_showadvanced_last'); + } + } + /** + * Set whether to show advanced elements in the form on first displaying form. Default is not to + * display advanced elements in the form until 'Show Advanced' is pressed. + * + * You can get the last state of the form and possibly save it for this user by using + * value 'mform_showadvanced_last' in submitted data. + * + * @param boolean $showadvancedNow + */ + function setShowAdvanced($showadvancedNow = null){ + if ($showadvancedNow === null){ + if ($this->_showAdvanced !== null){ + return; + } else { //if setShowAdvanced is called without any preference + //make the default to not show advanced elements. + $showadvancedNow = get_user_preferences( + moodle_strtolower($this->_formName.'_showadvanced', 0)); + } + } + //value of hidden element + $hiddenLast = optional_param('mform_showadvanced_last', -1, PARAM_INT); + //value of button + $buttonPressed = optional_param('mform_showadvanced', 0, PARAM_RAW); + //toggle if button pressed or else stay the same + if ($hiddenLast == -1) { + $next = $showadvancedNow; + } elseif ($buttonPressed) { //toggle on button press + $next = !$hiddenLast; + } else { + $next = $hiddenLast; + } + $this->_showAdvanced = $next; + if ($showadvancedNow != $next){ + set_user_preference($this->_formName.'_showadvanced', $next); + } + $this->setConstants(array('mform_showadvanced_last'=>$next)); + } + function getShowAdvanced(){ + return $this->_showAdvanced; + } + + + /** + * Accepts a renderer + * + * @param HTML_QuickForm_Renderer An HTML_QuickForm_Renderer object + * @since 3.0 + * @access public + * @return void + */ + function accept(&$renderer) + { + if (method_exists($renderer, 'setAdvancedElements')){ + //check for visible fieldsets where all elements are advanced + //and mark these headers as advanced as well. + //And mark all elements in a advanced header as advanced + $stopFields = $renderer->getStopFieldSetElements(); + $lastHeader = null; + $lastHeaderAdvanced = false; + $anyAdvanced = false; + foreach (array_keys($this->_elements) as $elementIndex){ + $element =& $this->_elements[$elementIndex]; + if ($element->getType()=='header' || in_array($element->getName(), $stopFields)){ + if ($anyAdvanced && ($lastHeader!==null)){ + $this->setAdvanced($lastHeader->getName()); + } + $lastHeaderAdvanced = false; + } elseif ($lastHeaderAdvanced) { + $this->setAdvanced($element->getName()); + } + if ($element->getType()=='header'){ + $lastHeader =& $element; + $anyAdvanced = false; + $lastHeaderAdvanced = isset($this->_advancedElements[$element->getName()]); + } elseif (isset($this->_advancedElements[$element->getName()])){ + $anyAdvanced = true; + } + } + $renderer->setAdvancedElements($this->_advancedElements); + + } + parent::accept($renderer); + } + + + + function closeHeaderBefore($elementName){ + $renderer =& $this->defaultRenderer(); + $renderer->addStopFieldsetElements($elementName); + } + + /** + * Should be used for all elements of a form except for select, radio and checkboxes which + * clean their own data. + * + * @param string $elementname + * @param integer $paramtype use the constants PARAM_*. + * * PARAM_CLEAN is deprecated and you should try to use a more specific type. + * * PARAM_TEXT should be used for cleaning data that is expected to be plain text. + * It will strip all html tags. But will still let tags for multilang support + * through. + * * PARAM_RAW means no cleaning whatsoever, it is used mostly for data from the + * html editor. Data from the editor is later cleaned before display using + * format_text() function. PARAM_RAW can also be used for data that is validated + * by some other way or printed by p() or s(). + * * PARAM_INT should be used for integers. + * * PARAM_ACTION is an alias of PARAM_ALPHA and is used for hidden fields specifying + * form actions. + */ + function setType($elementname, $paramtype) { + $this->_types[$elementname] = $paramtype; + } + + /** + * See description of setType above. This can be used to set several types at once. + * + * @param array $paramtypes + */ + function setTypes($paramtypes) { + $this->_types = $paramtypes + $this->_types; + } + + function updateSubmission($submission, $files) { + $this->_flagSubmitted = false; + + if (empty($submission)) { + $this->_submitValues = array(); + } else { + foreach ($submission as $key=>$s) { + if (array_key_exists($key, $this->_types)) { + $submission[$key] = clean_param($s, $this->_types[$key]); + } + } + $this->_submitValues = $this->_recursiveFilter('stripslashes', $submission); + $this->_flagSubmitted = true; + } + + if (empty($files)) { + $this->_submitFiles = array(); + } else { + if (1 == get_magic_quotes_gpc()) { + foreach (array_keys($files) as $elname) { + // dangerous characters in filenames are cleaned later in upload_manager + $files[$elname]['name'] = stripslashes($files[$elname]['name']); + } + } + $this->_submitFiles = $files; + $this->_flagSubmitted = true; + } + + // need to tell all elements that they need to update their value attribute. + foreach (array_keys($this->_elements) as $key) { + $this->_elements[$key]->onQuickFormEvent('updateValue', null, $this); + } + } + function getReqHTML(){ return $this->_reqHTML; } - /** - * Class constructor - same parameters as HTML_QuickForm_DHTMLRulesTableless - * @param array $buttons An associative array representing help button to attach to - * to the form. keys of array correspond to names of elements in form. - * - * @access public - */ - function setHelpButtons($buttons, $suppresscheck=false){ - - foreach ($this->_elements as $no => $element){ - if (array_key_exists($element->getName(), $buttons)){ - if (method_exists($element, 'setHelpButton')){ - $this->_elements[$no]->setHelpButton($buttons[$element->getName()]); - }else{ - $a=new object(); - $a->name=$element->getName(); - $a->classname=get_class($element); - print_error('nomethodforaddinghelpbutton', 'form', '', $a); - } - unset($buttons[$element->getName()]); - } - - } - if (count($buttons)&& !$suppresscheck){ - print_error('nonexistentformelements', 'form', '', join(', ', array_keys($buttons))); - } + function getAdvancedHTML(){ + return $this->_advancedHTML; } - function acceptGet(){ - $names=func_get_args(); - foreach ($names as $name){ - //if no form data is submitted then the page has just beeen loaded - //so we get the page param value from $_GET - if (!$this->_flagSubmitted && isset($_GET[$name])){ - $this->_submitValues[$name]=$_GET[$name]; - } - } - } - function required_param($element, $paramtype){ - $value = $this->getSubmitValue($element); - if (null !== $value) { - if (false === strpos($element, '[')) { - return $this->_submitValues[$element] = $this->_clean_param($value, $paramtype); - } else { - $idx = "['" . str_replace(array(']', '['), array('', "']['"), $element) . "']"; - eval("return \$this->_submitValues{$idx} = \$this->_clean_param(\$value, \$paramtype);"); - } - }else{ - //could print name of param but better not to for security? - print_error('missingrequiredfield', 'error'); - } - } - function optional_param($element, $default, $paramtype){ - $value = $this->getSubmitValue($element); - if (null === $value) { - return $default; - } - if (false === strpos($element, '[')) { - return $this->_submitValues[$element] = $this->_clean_param($value, $paramtype); - } else { - $idx = "['" . str_replace(array(']', '['), array('', "']['"), $element) . "']"; - eval("return \$this->_submitValues{$idx} = \$this->_clean_param(\$value, \$paramtype);"); - } - } - function clean_param($elementList, $paramtype){ - $value = $this->getSubmitValue($element); - if (false === strpos($element, '[')) { - return $this->_submitValues[$element] = $this->_clean_param($value, $paramtype); - } else { - $idx = "['" . str_replace(array(']', '['), array('', "']['"), $element) . "']"; - eval("return \$this->_submitValues{$idx} = \$this->_clean_param(\$value, \$paramtype);"); - } - } - function _clean_param($value, $paramtype){ - //clean_param function in moodlelib expects vars with slashes - $value=$this->_recursiveFilter('addslashes', $value); - $value=clean_param($value, $paramtype); - return $this->_recursiveFilter('stripslashes', $value); - } - function exportValue($element, $addslashes=true){ - $unfiltered=parent::exportValue($element); - if ($addslashes){ - return $this->_recursiveFilter('addslashes',$unfiltered); - } else { - return $unfiltered; - } - } - function exportValues($elementList= null, $addslashes=true){ - $unfiltered=parent::exportValues($elementList); - if ($addslashes){ - return $this->_recursiveFilter('addslashes',$unfiltered); - } else { - return $unfiltered; - } - } /** - * Initializes a default form value + * Initializes a default form value. Used to specify the default for a new entry where + * no data is loaded in using moodleform::set_data() * * @param string $elementname element name * @param mixed $values values for that element name - * @param mixed $filter (optional) filter(s) to apply to default value + * @param bool $slashed the default value is slashed * @access public * @return void */ - function setDefault($elementName='', $defaultValue = null, $filter = null){ - $this->setDefaults(array($elementName =>$defaultValue), $filter); + function setDefault($elementName, $defaultValue, $slashed=false){ + $filter = $slashed ? 'stripslashes' : NULL; + $this->setDefaults(array($elementName=>$defaultValue), $filter); } // end func setDefault /** - * Returns 'safe' elements' values + * Add an array of buttons to the form + * @param array $buttons An associative array representing help button to attach to + * to the form. keys of array correspond to names of elements in form. * - * Unlike getSubmitValues(), this will return only the values - * corresponding to the elements present in the form. - * This function also runs validate() and returns false if the form doesn't validate - * - * @param mixed Array/string of element names, whose values we want. If not set then return all elements. - * @access public - * @return object An object with property values set to elements' values - * @throws HTML_QuickForm_Error - */ - function data_submitted($elementList = null, $addslashes=true){ - if (!$this->validate()){ - return false; - }else{ - return (object)$this->exportValues($elementList, $addslashes); + * @access public + */ + function setHelpButtons($buttons, $suppresscheck=false, $function='helpbutton'){ + + foreach ($buttons as $elementname => $button){ + $this->setHelpButton($elementname, $button, $suppresscheck, $function); } } + /** + * Add a single button. + * + * @param string $elementname name of the element to add the item to + * @param array $button - arguments to pass to function $function + * @param boolean $suppresscheck - whether to throw an error if the element + * doesn't exist. + * @param string $function - function to generate html from the arguments in $button + */ + function setHelpButton($elementname, $button, $suppresscheck=false, $function='helpbutton'){ + if (array_key_exists($elementname, $this->_elementIndex)){ + //_elements has a numeric index, this code accesses the elements by name + $element=&$this->_elements[$this->_elementIndex[$elementname]]; + if (method_exists($element, 'setHelpButton')){ + $element->setHelpButton($button, $function); + }else{ + $a=new object(); + $a->name=$element->getName(); + $a->classname=get_class($element); + print_error('nomethodforaddinghelpbutton', 'form', '', $a); + } + }elseif (!$suppresscheck){ + print_error('nonexistentformelements', 'form', '', $elementname); + } + } + + function exportValues($elementList= null, $addslashes=true){ + $unfiltered = array(); + if (null === $elementList) { + // iterate over all elements, calling their exportValue() methods + $emptyarray = array(); + foreach (array_keys($this->_elements) as $key) { + if ($this->_elements[$key]->isFrozen() && !$this->_elements[$key]->_persistantFreeze){ + $value = $this->_elements[$key]->exportValue($emptyarray, true); + } else { + $value = $this->_elements[$key]->exportValue($this->_submitValues, true); + } + + if (is_array($value)) { + // This shit throws a bogus warning in PHP 4.3.x + $unfiltered = HTML_QuickForm::arrayMerge($unfiltered, $value); + } + } + } else { + if (!is_array($elementList)) { + $elementList = array_map('trim', explode(',', $elementList)); + } + foreach ($elementList as $elementName) { + $value = $this->exportValue($elementName); + if (PEAR::isError($value)) { + return $value; + } + $unfiltered[$elementName] = $value; + } + } + + if ($addslashes){ + return $this->_recursiveFilter('addslashes', $unfiltered); + } else { + return $unfiltered; + } + } + /** + * Adds a validation rule for the given field + * + * If the element is in fact a group, it will be considered as a whole. + * To validate grouped elements as separated entities, + * use addGroupRule instead of addRule. + * + * @param string $element Form element name + * @param string $message Message to display for invalid data + * @param string $type Rule type, use getRegisteredRules() to get types + * @param string $format (optional)Required for extra rule data + * @param string $validation (optional)Where to perform validation: "server", "client" + * @param boolean $reset Client-side validation: reset the form element to its original value if there is an error? + * @param boolean $force Force the rule to be applied, even if the target form element does not exist + * @since 1.0 + * @access public + * @throws HTML_QuickForm_Error + */ + function addRule($element, $message, $type, $format=null, $validation='server', $reset = false, $force = false) + { + parent::addRule($element, $message, $type, $format, $validation, $reset, $force); + if ($validation == 'client') { + $this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_formName . '; } catch(e) { return true; } return myValidator(this);')); + } + + } // end func addRule + /** + * Adds a validation rule for the given group of elements + * + * Only groups with a name can be assigned a validation rule + * Use addGroupRule when you need to validate elements inside the group. + * Use addRule if you need to validate the group as a whole. In this case, + * the same rule will be applied to all elements in the group. + * Use addRule if you need to validate the group against a function. + * + * @param string $group Form group name + * @param mixed $arg1 Array for multiple elements or error message string for one element + * @param string $type (optional)Rule type use getRegisteredRules() to get types + * @param string $format (optional)Required for extra rule data + * @param int $howmany (optional)How many valid elements should be in the group + * @param string $validation (optional)Where to perform validation: "server", "client" + * @param bool $reset Client-side: whether to reset the element's value to its original state if validation failed. + * @since 2.5 + * @access public + * @throws HTML_QuickForm_Error + */ + function addGroupRule($group, $arg1, $type='', $format=null, $howmany=0, $validation = 'server', $reset = false) + { + parent::addGroupRule($group, $arg1, $type, $format, $howmany, $validation, $reset); + if (is_array($arg1)) { + foreach ($arg1 as $rules) { + foreach ($rules as $rule) { + $validation = (isset($rule[3]) && 'client' == $rule[3])? 'client': 'server'; + + if ('client' == $validation) { + $this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_formName . '; } catch(e) { return true; } return myValidator(this);')); + } + } + } + } elseif (is_string($arg1)) { + + if ($validation == 'client') { + $this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_formName . '; } catch(e) { return true; } return myValidator(this);')); + } + } + } // end func addGroupRule + + // }}} + /** + * Returns the client side validation script + * + * The code here was copied from HTML_QuickForm_DHTMLRulesTableless who copied it from HTML_QuickForm + * and slightly modified to run rules per-element + * Needed to override this because of an error with client side validation of grouped elements. + * + * @access public + * @return string Javascript to perform validation, empty string if no 'client' rules were added + */ + function getValidationScript() + { + if (empty($this->_rules) || empty($this->_attributes['onsubmit'])) { + return ''; + } + + include_once('HTML/QuickForm/RuleRegistry.php'); + $registry =& HTML_QuickForm_RuleRegistry::singleton(); + $test = array(); + $js_escape = array( + "\r" => '\r', + "\n" => '\n', + "\t" => '\t', + "'" => "\\'", + '"' => '\"', + '\\' => '\\\\' + ); + + foreach ($this->_rules as $elementName => $rules) { + foreach ($rules as $rule) { + if ('client' == $rule['validation']) { + unset($element); //TODO: find out how to properly initialize it + + $dependent = isset($rule['dependent']) && is_array($rule['dependent']); + $rule['message'] = strtr($rule['message'], $js_escape); + + if (isset($rule['group'])) { + $group =& $this->getElement($rule['group']); + // No JavaScript validation for frozen elements + if ($group->isFrozen()) { + continue 2; + } + $elements =& $group->getElements(); + foreach (array_keys($elements) as $key) { + if ($elementName == $group->getElementName($key)) { + $element =& $elements[$key]; + break; + } + } + } elseif ($dependent) { + $element = array(); + $element[] =& $this->getElement($elementName); + foreach ($rule['dependent'] as $elName) { + $element[] =& $this->getElement($elName); + } + } else { + $element =& $this->getElement($elementName); + } + // No JavaScript validation for frozen elements + if (is_object($element) && $element->isFrozen()) { + continue 2; + } elseif (is_array($element)) { + foreach (array_keys($element) as $key) { + if ($element[$key]->isFrozen()) { + continue 3; + } + } + } + // Fix for bug displaying errors for elements in a group + //$test[$elementName][] = $registry->getValidationScript($element, $elementName, $rule); + $test[$elementName][0][] = $registry->getValidationScript($element, $elementName, $rule); + $test[$elementName][1]=$element; + //end of fix + } + } + } + $js = ' +'; + return $js; + } // end func getValidationScript + function _setDefaultRuleMessages(){ + foreach ($this->_rules as $field => $rulesarr){ + foreach ($rulesarr as $key => $rule){ + if ($rule['message']===null){ + $a=new object(); + $a->format=$rule['format']; + $str=get_string('err_'.$rule['type'], 'form', $a); + if (strpos($str, '[[')!==0){ + $this->_rules[$field][$key]['message']=$str; + } + } + } + } + } + + function getLockOptionEndScript(){ + + $iname = $this->getAttribute('id').'items'; + $js = ''."\n"; + return $js; + } + + function _getElNamesRecursive($element, $group=null){ + if ($group==null){ + $el = $this->getElement($element); + } else { + $el = &$element; + } + if (is_a($el, 'HTML_QuickForm_group')){ + $group = $el; + $elsInGroup = $group->getElements(); + $elNames = array(); + foreach ($elsInGroup as $elInGroup){ + $elNames = array_merge($elNames, $this->_getElNamesRecursive($elInGroup, $group)); + } + }else{ + if ($group != null){ + $elNames = array($group->getElementName($el->getName())); + } elseif (is_a($el, 'HTML_QuickForm_header')) { + return null; + } elseif (is_a($el, 'HTML_QuickForm_hidden')) { + return null; + } elseif (method_exists($el, 'getPrivateName')) { + return array($el->getPrivateName()); + } else { + $elNames = array($el->getName()); + } + } + return $elNames; + + } + /** + * Adds a dependency for $elementName which will be disabled if $condition is met. + * If $condition = 'notchecked' (default) then the condition is that the $dependentOn element + * is not checked. If $condition = 'checked' then the condition is that the $dependentOn element + * is checked. If $condition is something else then it is checked to see if the value + * of the $dependentOn element is equal to $condition. + * + * @param string $elementName the name of the element which will be disabled + * @param string $dependentOn the name of the element whose state will be checked for + * condition + * @param string $condition the condition to check + * @param mixed $value used in conjunction with condition. + */ + function disabledIf($elementName, $dependentOn, $condition = 'notchecked', $value='1'){ + if (!array_key_exists($dependentOn, $this->_dependencies)) { + $this->_dependencies[$dependentOn] = array(); + } + if (!array_key_exists($condition, $this->_dependencies[$dependentOn])) { + $this->_dependencies[$dependentOn][$condition] = array(); + } + if (!array_key_exists($value, $this->_dependencies[$dependentOn][$condition])) { + $this->_dependencies[$dependentOn][$condition][$value] = array(); + } + $this->_dependencies[$dependentOn][$condition][$value][] = $elementName; + } + + function registerNoSubmitButton($buttonname){ + $this->_noSubmitButtons[]=$buttonname; + } + + function isNoSubmitButton($buttonname){ + return (array_search($buttonname, $this->_noSubmitButtons)!==FALSE); + } + + function _registerCancelButton($addfieldsname){ + $this->_cancelButtons[]=$addfieldsname; + } + /** + * Displays elements without HTML input tags. + * This method is different to freeze() in that it makes sure no hidden + * elements are included in the form. And a 'hardFrozen' element's submitted value is + * ignored. + * + * This function also removes all previously defined rules. + * + * @param mixed $elementList array or string of element(s) to be frozen + * @since 1.0 + * @access public + * @throws HTML_QuickForm_Error + */ + function hardFreeze($elementList=null) + { + if (!isset($elementList)) { + $this->_freezeAll = true; + $elementList = array(); + } else { + if (!is_array($elementList)) { + $elementList = preg_split('/[ ]*,[ ]*/', $elementList); + } + $elementList = array_flip($elementList); + } + + foreach (array_keys($this->_elements) as $key) { + $name = $this->_elements[$key]->getName(); + if ($this->_freezeAll || isset($elementList[$name])) { + $this->_elements[$key]->freeze(); + $this->_elements[$key]->setPersistantFreeze(false); + unset($elementList[$name]); + + // remove all rules + $this->_rules[$name] = array(); + // if field is required, remove the rule + $unset = array_search($name, $this->_required); + if ($unset !== false) { + unset($this->_required[$unset]); + } + } + } + + if (!empty($elementList)) { + return PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Nonexistant element(s): '" . implode("', '", array_keys($elementList)) . "' in HTML_QuickForm::freeze()", 'HTML_QuickForm_Error', true); + } + return true; + } // end func hardFreeze + + // }}} } + /** - * A renderer for moodleform that only uses XHTML and CSS and no + * A renderer for MoodleQuickForm that only uses XHTML and CSS and no * table tags, extends PEAR class HTML_QuickForm_Renderer_Tableless - * + * * Stylesheet is part of standard theme and should be automatically included. * * @author Jamie Pratt * @license gpl license */ -class moodleform_renderer extends HTML_QuickForm_Renderer_Tableless{ +class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{ /** * Element template array @@ -249,10 +1339,6 @@ class moodleform_renderer extends HTML_QuickForm_Renderer_Tableless{ * @access private */ var $_elementTemplates; - -// uncomment templates below and edit formslib.php for -// ol li containers for form items. - /** * Template used when opening a hidden fieldset * (i.e. a fieldset that is opened when there is no header element) @@ -260,59 +1346,102 @@ class moodleform_renderer extends HTML_QuickForm_Renderer_Tableless{ * @access private */ var $_openHiddenFieldsetTemplate = "\n\t
"; -// var $_openHiddenFieldsetTemplate = "\n\t
\n\t\t
    "; -// /** -// * Header Template string -// * @var string -// * @access private -// */ -// var $_headerTemplate = -// "\n\t\t{header}\n\t\t
      "; -// var $_headerTemplate = -// "\n\t\t{header}\n\t\t
        "; /** + * Header Template string + * @var string + * @access private + */ + var $_headerTemplate = + "\n\t\t{header}\n\t\t
        {advancedimg}{button}
        \n\t\t"; + + /** + * Template used when opening a fieldset + * @var string + * @access private + */ + var $_openFieldsetTemplate = "\n\t
        "; + + /** * Template used when closing a fieldset * @var string * @access private */ var $_closeFieldsetTemplate = "\n\t\t
        "; -// var $_closeFieldsetTemplate = "\n\t\t
      \n\t
"; /** * Required Note template string * @var string * @access private */ - var $_requiredNoteTemplate = - "\n\t\t
{requiredNote}
"; - function moodleform_renderer(){ + var $_requiredNoteTemplate = + "\n\t\t
{requiredNote}
"; + + var $_advancedElements = array(); + + /** + * Whether to display advanced elements (on page load) + * + * @var integer 1 means show 0 means hide + */ + var $_showAdvanced; + + function MoodleQuickForm_Renderer(){ // switch next two lines for ol li containers for form items. - // $this->_elementTemplates=array('default'=>"\n\t\t
  • error {type}\">{error}
    {element}
  • "); - $this->_elementTemplates=array('default'=>"\n\t\t
    error {type}\">{error}
    {element}
    ", - 'fieldset'=>"\n\t\t
    error {type}\">{error}
    {element}
    "); + // $this->_elementTemplates=array('default'=>"\n\t\t".'
  • {error}
    {element}
  • '); + $this->_elementTemplates = array( + 'default'=>"\n\t\t".'
    {help}
    {error}
    {element}
    ', + + 'fieldset'=>"\n\t\t".'
    {label}{req} {advancedimg}
    {help}
    {error}
    {element}
    ', + + 'static'=>"\n\t\t".'
    {label}{req} {advancedimg}
    {help}
    {error}
    {element}
    '); parent::HTML_QuickForm_Renderer_Tableless(); } + + function setAdvancedElements($elements){ + $this->_advancedElements = $elements; + } + + /** + * What to do when starting the form + * + * @param MoodleQuickForm $form + */ function startForm(&$form){ - $this->_reqHTML=$form->getReqHTML(); - $this->_elementTemplates=str_replace('{req}', $this->_reqHTML, $this->_elementTemplates); + $this->_reqHTML = $form->getReqHTML(); + $this->_elementTemplates = str_replace('{req}', $this->_reqHTML, $this->_elementTemplates); + $this->_advancedHTML = $form->getAdvancedHTML(); + $this->_showAdvanced = $form->getShowAdvanced(); parent::startForm($form); } + function startGroup(&$group, $required, $error){ if (method_exists($group, 'getElementTemplateType')){ $html = $this->_elementTemplates[$group->getElementTemplateType()]; }else{ $html = $this->_elementTemplates['default']; - + + } + if ($this->_showAdvanced){ + $advclass = ' advanced'; + } else { + $advclass = ' advanced hide'; + } + if (isset($this->_advancedElements[$group->getName()])){ + $html =str_replace(' {advanced}', $advclass, $html); + $html =str_replace('{advancedimg}', $this->_advancedHTML, $html); + } else { + $html =str_replace(' {advanced}', '', $html); + $html =str_replace('{advancedimg}', '', $html); } if (method_exists($group, 'getHelpButton')){ $html =str_replace('{help}', $group->getHelpButton(), $html); }else{ $html =str_replace('{help}', '', $html); - } + $html =str_replace('{name}', $group->getName(), $html); $html =str_replace('{type}', 'fgroup', $html); - + $this->_templates[$group->getName()]=$html; // Fix for bug in tableless quickforms that didn't allow you to stop a // fieldset before a group of elements. @@ -325,72 +1454,156 @@ class moodleform_renderer extends HTML_QuickForm_Renderer_Tableless{ } parent::startGroup($group, $required, $error); } + function renderElement(&$element, $required, $error){ - if (method_exists($element, 'getElementTemplateType')){ - $html = $this->_elementTemplates[$element->getElementTemplateType()]; - }else{ - $html = $this->_elementTemplates['default']; - - } - $html =str_replace('{type}', 'f'.$element->getType(), $html); - if (method_exists($element, 'getHelpButton')){ - $html=str_replace('{help}', $element->getHelpButton(), $html); - }else{ - $html=str_replace('{help}', '', $html); - - } - $this->_templates[$element->getName()]=$html; + //manipulate id of all elements before rendering if (!is_null($element->getAttribute('id'))) { $id = $element->getAttribute('id'); } else { $id = $element->getName(); } - $element->updateAttributes(array('id'=>'id_'.$id)); + //strip qf_ prefix and replace '[' with '_' and strip ']' + $id = preg_replace(array('/^qf_|\]/', '/\[/'), array('', '_'), $id); + if (strpos($id, 'id_') !== 0){ + $element->updateAttributes(array('id'=>'id_'.$id)); + } + + //adding stuff to place holders in template + if (method_exists($element, 'getElementTemplateType')){ + $html = $this->_elementTemplates[$element->getElementTemplateType()]; + }else{ + $html = $this->_elementTemplates['default']; + } + if ($this->_showAdvanced){ + $advclass = ' advanced'; + } else { + $advclass = ' advanced hide'; + } + if (isset($this->_advancedElements[$element->getName()])){ + $html =str_replace(' {advanced}', $advclass, $html); + } else { + $html =str_replace(' {advanced}', '', $html); + } + if (isset($this->_advancedElements[$element->getName()])||$element->getName() == 'mform_showadvanced'){ + $html =str_replace('{advancedimg}', $this->_advancedHTML, $html); + } else { + $html =str_replace('{advancedimg}', '', $html); + } + $html =str_replace('{type}', 'f'.$element->getType(), $html); + $html =str_replace('{name}', $element->getName(), $html); + if (method_exists($element, 'getHelpButton')){ + $html = str_replace('{help}', $element->getHelpButton(), $html); + }else{ + $html = str_replace('{help}', '', $html); + + } + + $this->_templates[$element->getName()] = $html; + parent::renderElement($element, $required, $error); } - + function finishForm(&$form){ + parent::finishForm($form); + // add a lockoptions script + if ('' != ($script = $form->getLockOptionEndScript())) { + $this->_html = $this->_html . "\n" . $script; + } + } + /** + * Called when visiting a header element + * + * @param object An HTML_QuickForm_header element being visited + * @access public + * @return void + */ + function renderHeader(&$header) { + $name = $header->getName(); + + $id = empty($name) ? '' : ' id="' . $name . '"'; + $id = preg_replace(array('/\]/', '/\[/'), array('', '_'), $id); + if (is_null($header->_text)) { + $header_html = ''; + } elseif (!empty($name) && isset($this->_templates[$name])) { + $header_html = str_replace('{header}', $header->toHtml(), $this->_templates[$name]); + } else { + $header_html = str_replace('{header}', $header->toHtml(), $this->_headerTemplate); + } + + if (isset($this->_advancedElements[$name])){ + $header_html =str_replace('{advancedimg}', $this->_advancedHTML, $header_html); + } else { + $header_html =str_replace('{advancedimg}', '', $header_html); + } + $elementName='mform_showadvanced'; + if ($this->_showAdvanced==0){ + $buttonlabel = get_string('showadvanced', 'form'); + } else { + $buttonlabel = get_string('hideadvanced', 'form'); + } + + if (isset($this->_advancedElements[$name])){ + $showtext="'".get_string('showadvanced', 'form')."'"; + $hidetext="'".get_string('hideadvanced', 'form')."'"; + //onclick returns false so if js is on then page is not submitted. + $onclick = 'return showAdvancedOnClick(this, '.$hidetext.', '.$showtext.');'; + $button = ''; + $header_html =str_replace('{button}', $button, $header_html); + } else { + $header_html =str_replace('{button}', '', $header_html); + } + + if ($this->_fieldsetsOpen > 0) { + $this->_html .= $this->_closeFieldsetTemplate; + $this->_fieldsetsOpen--; + } + + $openFieldsetTemplate = str_replace('{id}', $id, $this->_openFieldsetTemplate); + if ($this->_showAdvanced){ + $advclass = ' class="advanced"'; + } else { + $advclass = ' class="advanced hide"'; + } + if (isset($this->_advancedElements[$name])){ + $openFieldsetTemplate = str_replace('{advancedclass}', $advclass, $openFieldsetTemplate); + } else { + $openFieldsetTemplate = str_replace('{advancedclass}', '', $openFieldsetTemplate); + } + $this->_html .= $openFieldsetTemplate . $header_html; + $this->_fieldsetsOpen++; + } // end func renderHeader + + function getStopFieldsetElements(){ + return $this->_stopFieldsetElements; + } } -/*class moodleform_filter{ - var $paramtype; - var $default; - function moodleform_filter($paramtype, $default=NULL){ - $this->paramtype=$paramtype; - $this->default=$default; - } - function required_param($value){ - if (isset($value)) { - $param = $value; - } else { - error('A required parameter was missing'); - } - - return $this->clean_param($param); - } - function optional_param($value){ - if (!isset($value)) { - return $this->default; - } - return $this->clean_param($value); - } -} */ +$GLOBALS['_HTML_QuickForm_default_renderer'] =& new MoodleQuickForm_Renderer(); -$GLOBALS['_HTML_QuickForm_default_renderer']=& new moodleform_renderer(); - -moodleform::registerElementType('checkbox', "$CFG->libdir/form/checkbox.php", 'moodleform_checkbox'); -moodleform::registerElementType('file', "$CFG->libdir/form/file.php", 'moodleform_file'); -moodleform::registerElementType('group', "$CFG->libdir/form/group.php", 'moodleform_group'); -moodleform::registerElementType('password', "$CFG->libdir/form/password.php", 'moodleform_password'); -moodleform::registerElementType('radio', "$CFG->libdir/form/radio.php", 'moodleform_radio'); -moodleform::registerElementType('select', "$CFG->libdir/form/select.php", 'moodleform_select'); -moodleform::registerElementType('text', "$CFG->libdir/form/text.php", 'moodleform_text'); -moodleform::registerElementType('textarea', "$CFG->libdir/form/textarea.php", 'moodleform_textarea'); -moodleform::registerElementType('date_selector', "$CFG->libdir/form/dateselector.php", 'moodleform_date_selector'); -moodleform::registerElementType('htmleditor', "$CFG->libdir/form/htmleditor.php", 'moodleform_htmleditor'); -moodleform::registerElementType('static', "$CFG->libdir/form/static.php", 'moodleform_static'); -moodleform::registerElementType('hidden', "$CFG->libdir/form/hidden.php", 'moodleform_hidden'); - - -?> \ No newline at end of file +MoodleQuickForm::registerElementType('checkbox', "$CFG->libdir/form/checkbox.php", 'MoodleQuickForm_checkbox'); +MoodleQuickForm::registerElementType('file', "$CFG->libdir/form/file.php", 'MoodleQuickForm_file'); +MoodleQuickForm::registerElementType('group', "$CFG->libdir/form/group.php", 'MoodleQuickForm_group'); +MoodleQuickForm::registerElementType('password', "$CFG->libdir/form/password.php", 'MoodleQuickForm_password'); +MoodleQuickForm::registerElementType('radio', "$CFG->libdir/form/radio.php", 'MoodleQuickForm_radio'); +MoodleQuickForm::registerElementType('select', "$CFG->libdir/form/select.php", 'MoodleQuickForm_select'); +MoodleQuickForm::registerElementType('text', "$CFG->libdir/form/text.php", 'MoodleQuickForm_text'); +MoodleQuickForm::registerElementType('textarea', "$CFG->libdir/form/textarea.php", 'MoodleQuickForm_textarea'); +MoodleQuickForm::registerElementType('date_selector', "$CFG->libdir/form/dateselector.php", 'MoodleQuickForm_date_selector'); +MoodleQuickForm::registerElementType('date_time_selector', "$CFG->libdir/form/datetimeselector.php", 'MoodleQuickForm_date_time_selector'); +MoodleQuickForm::registerElementType('htmleditor', "$CFG->libdir/form/htmleditor.php", 'MoodleQuickForm_htmleditor'); +MoodleQuickForm::registerElementType('format', "$CFG->libdir/form/format.php", 'MoodleQuickForm_format'); +MoodleQuickForm::registerElementType('static', "$CFG->libdir/form/static.php", 'MoodleQuickForm_static'); +MoodleQuickForm::registerElementType('hidden', "$CFG->libdir/form/hidden.php", 'MoodleQuickForm_hidden'); +MoodleQuickForm::registerElementType('modvisible', "$CFG->libdir/form/modvisible.php", 'MoodleQuickForm_modvisible'); +MoodleQuickForm::registerElementType('modgroupmode', "$CFG->libdir/form/modgroupmode.php", 'MoodleQuickForm_modgroupmode'); +MoodleQuickForm::registerElementType('selectyesno', "$CFG->libdir/form/selectyesno.php", 'MoodleQuickForm_selectyesno'); +MoodleQuickForm::registerElementType('modgrade', "$CFG->libdir/form/modgrade.php", 'MoodleQuickForm_modgrade'); +MoodleQuickForm::registerElementType('cancel', "$CFG->libdir/form/cancel.php", 'MoodleQuickForm_cancel'); +MoodleQuickForm::registerElementType('button', "$CFG->libdir/form/button.php", 'MoodleQuickForm_button'); +MoodleQuickForm::registerElementType('choosecoursefile', "$CFG->libdir/form/choosecoursefile.php", 'MoodleQuickForm_choosecoursefile'); +MoodleQuickForm::registerElementType('header', "$CFG->libdir/form/header.php", 'MoodleQuickForm_header'); +MoodleQuickForm::registerElementType('submit', "$CFG->libdir/form/submit.php", 'MoodleQuickForm_submit'); +MoodleQuickForm::registerElementType('questioncategory', "$CFG->libdir/form/questioncategory.php", 'MoodleQuickForm_questioncategory'); +MoodleQuickForm::registerElementType('advcheckbox', "$CFG->libdir/form/advcheckbox.php", 'MoodleQuickForm_advcheckbox'); +?>