/** * ELIS(TM): Enterprise Learning Intelligence Suite * Copyright (C) 2008-2012 Remote Learner.net Inc http://www.remote-learner.net * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * @package elis * @subpackage curriculummanagement * @author Remote-Learner.net Inc * @license http://www.gnu.org/copyleft/gpl.html GNU GPL * @copyright (C) 2008-2012 Remote Learner.net Inc http://www.remote-learner.net * */ function xmldb_crlm_cluster_classification_upgrade($oldversion = 0) { global $CFG, $THEME, $db; $result = true; if ($result && $oldversion < 2010080502) { /// Define table crlm_cluster_classification to be created $table = new XMLDBTable('crlm_cluster_classification'); /// Adding fields to table crlm_cluster_classification $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('params', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null); /// Adding keys to table crlm_cluster_classification $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addKeyInfo('shortname_idx', XMLDB_KEY_UNIQUE, array('shortname')); /// Launch create table for crlm_cluster_classification $result = $result && create_table($table); } if ($result && $oldversion < 2010080503) { require_once $CFG->dirroot . '/curriculum/lib/customfield.class.php'; require_once $CFG->dirroot . '/curriculum/plugins/cluster_classification/lib.php'; require_once $CFG->dirroot . '/curriculum/plugins/cluster_classification/clusterclassification.class.php'; $field = new field(field::get_for_context_level_with_name('cluster', CLUSTER_CLASSIFICATION_FIELD)); // make sure we're set as owner if (!isset($field->owners['cluster_classification'])) { $owner = new field_owner(); $owner->fieldid = $field->id; $owner->plugin = 'cluster_classification'; $owner->add(); } // make sure we have a default value set if (!field_data::get_for_context_and_field(NULL, $field)) { field_data::set_for_context_and_field(NULL, $field, 'regular'); } $default = new clusterclassification(); $default->shortname = 'regular'; $default->name = get_string('cluster', 'block_curr_admin'); $default->param_autoenrol_curricula = 1; $default->param_autoenrol_tracks = 1; $default->add(); } // make sure 'manual' is an owner if ($result && $oldversion < 2010080504) { require_once $CFG->dirroot . '/curriculum/lib/customfield.class.php'; require_once $CFG->dirroot . '/curriculum/plugins/cluster_classification/lib.php'; require_once $CFG->dirroot . '/curriculum/plugins/cluster_classification/clusterclassification.class.php'; $field = new field(field::get_for_context_level_with_name('cluster', CLUSTER_CLASSIFICATION_FIELD)); $owner = new field_owner(); $owner->fieldid = $field->id; $owner->plugin = 'manual'; $owner->param_view_capability = ''; $owner->param_edit_capability = 'moodle/user:update'; $owner->param_control = 'menu'; $owner->param_options_source = 'cluster_classifications'; $owner->add(); } return $result; }
/** * Install function for this plugin * * @return boolean true Returns true to satisfy install procedure */ function xmldb_elisprogram_usetclassify_install() { global $CFG, $DB; require_once elispm::lib('setup.php'); require_once elis::lib('data/customfield.class.php'); require_once elispm::file('plugins/usetclassify/usersetclassification.class.php'); // Migrate component. $oldcmp = 'pmplugins_userset_classification'; $newcmp = 'elisprogram_usetclassify'; $upgradestepfuncname = 'elisprogram_usetclassify_pre26upgradesteps'; $tablechanges = array('crlm_cluster_classification' => 'elisprogram_usetclassify'); $migrator = new \local_eliscore\install\migration\migrator($oldcmp, $newcmp, $upgradestepfuncname, $tablechanges); if ($migrator->old_component_installed() === true) { $migrator->migrate(); } $field = new field(); $field->shortname = USERSET_CLASSIFICATION_FIELD; $field->name = get_string('classification_field_name', 'elisprogram_usetclassify'); $field->datatype = 'char'; $category = new field_category(); $category->name = get_string('classification_category_name', 'elisprogram_usetclassify'); $field = field::ensure_field_exists_for_context_level($field, CONTEXT_ELIS_USERSET, $category); // make sure we're set as owner if (!isset($field->owners['userset_classifications'])) { $owner = new field_owner(); $owner->fieldid = $field->id; $owner->plugin = 'userset_classifications'; $owner->save(); } // make sure 'manual' is an owner if (!isset($field->owners['manual'])) { $owner = new field_owner(); $owner->fieldid = $field->id; $owner->plugin = 'manual'; $owner->param_view_capability = ''; $owner->param_edit_capability = 'moodle/user:update'; $owner->param_control = 'menu'; $owner->param_options_source = 'userset_classifications'; $owner->param_help_file = 'elisprogram_usetclassify/cluster_classification'; $owner->save(); } // make sure we have a default value set if (!field_data::get_for_context_and_field(NULL, $field)) { field_data::set_for_context_and_field(NULL, $field, 'regular'); } $regclassify = $DB->get_record(usersetclassification::TABLE, array('shortname' => 'regular')); if (empty($regclassify)) { $default = new usersetclassification(); $default->shortname = 'regular'; $default->name = get_string('cluster', 'local_elisprogram'); $default->param_autoenrol_curricula = 1; $default->param_autoenrol_tracks = 1; $default->save(); } return true; }
function cluster_classification_install() { global $CFG; require_once $CFG->dirroot . '/curriculum/config.php'; require_once CURMAN_DIRLOCATION . '/lib/customfield.class.php'; require_once CURMAN_DIRLOCATION . '/plugins/cluster_classification/clusterclassification.class.php'; $cluster_ctx_lvl = context_level_base::get_custom_context_level('cluster', 'block_curr_admin'); $field = new field(); $field->shortname = CLUSTER_CLASSIFICATION_FIELD; $field->name = get_string('classification_field_name', 'crlm_cluster_classification'); $field->datatype = 'char'; $category = new field_category(); $category->name = get_string('classification_category_name', 'crlm_cluster_classification'); $field = field::ensure_field_exists_for_context_level($field, 'cluster', $category); // make sure we're set as owner if (!isset($field->owners['cluster_classification'])) { $owner = new field_owner(); $owner->fieldid = $field->id; $owner->plugin = 'cluster_classification'; $owner->add(); } // make sure 'manual' is an owner if (!isset($field->owners['manual'])) { $owner = new field_owner(); $owner->fieldid = $field->id; $owner->plugin = 'manual'; $owner->param_view_capability = ''; $owner->param_edit_capability = 'moodle/user:update'; $owner->param_control = 'menu'; $owner->param_options_source = 'cluster_classifications'; $owner->add(); } // make sure we have a default value set if (!field_data::get_for_context_and_field(NULL, $field)) { field_data::set_for_context_and_field(NULL, $field, 'regular'); } $default = new clusterclassification(); $default->shortname = 'regular'; $default->name = get_string('cluster', 'block_curr_admin'); $default->param_autoenrol_curricula = 1; $default->param_autoenrol_tracks = 1; $default->add(); return true; }
/** * Determines if a paritcular cluster is set up for groupings * * @param int $clusterid The id of the cluster in question * @return boolean True if this grouping is allowed, otherwise false */ function cluster_groups_grouping_allowed($clusterid) { global $CFG, $CURMAN; if (empty($CFG->enablegroupings) || empty($CURMAN->config->cluster_groupings)) { return false; } //retrieve the config field if ($fieldid = get_field(FIELDTABLE, 'id', 'shortname', 'cluster_groupings')) { //get the cluster context level $context = context_level_base::get_custom_context_level('cluster', 'block_curr_admin'); //retrieve the cluster context instance $context_instance = get_context_instance($context, $clusterid); //construct the specific field $field = new field($fieldid); //retrieve the appropriate field's data for this cluster based on the context instance if ($field_data = field_data::get_for_context_and_field($context_instance, $field)) { //this should really only return one record, so return true of any have non-empty data foreach ($field_data as $field_datum) { if (!empty($field_datum->data)) { return true; } } } } return false; }
/** * Transforms a heading element displayed above the columns into a listing of such heading elements * * @param string array $grouping_current Mapping of field names to current values in the grouping * @param table_report_grouping $grouping Object containing all info about the current level of grouping * being handled * @param stdClass $datum The most recent record encountered * @param string $export_format The format being used to render the report * * @return string array Set of text entries to display */ function transform_grouping_header_label($grouping_current, $grouping, $datum, $export_format) { //TBD: dependencies for custom fields $labels = array(); //user fullname if ($export_format == table_report::$EXPORT_FORMAT_HTML) { //label for this grouping element $text_label = get_string('grouping_name', $this->languagefile); } else { //label for all groupings $text_label = get_string('grouping_name_csv', $this->languagefile); } $fullname_text = php_report::fullname($datum); $labels[] = $this->add_grouping_header($text_label, $fullname_text, $export_format); $filters = php_report_filtering_get_active_filter_values($this->get_report_shortname(), 'filter-detailheaders', $this->filter); $headers = $filters[0]['value']; $this->_userfieldids = array(); if (!empty($headers)) { foreach ($headers as $field => $active) { if ($active && substr($field, 0, 7) == 'custom_') { $fieldid = substr($field, 7); $this->_userfieldids[] = $fieldid; } } } //configured user custom fields if (!empty($this->_userfieldids)) { //only need to obtain the user information once $user = \local_elisprogram\context\user::instance($datum->userid); //add a row for each field foreach ($this->_userfieldids as $userfieldid) { $field = new field($userfieldid); //needed to store just the actual data value $rawdata = array(); if ($customdata = field_data::get_for_context_and_field($user, $field)) { //could potentially have multiple values foreach ($customdata as $customdatum) { if ($field->datatype == 'bool') { //special display handling for boolean values $rawdata[] = !empty($customdatum->data) ? get_string('yes') : get_string('no'); } else { if (isset($field->owners['manual']) && ($manual = new field_owner($field->owners['manual'])) && $manual->param_control == 'datetime') { //special display handling for datetime fields $rawdata[] = $this->userdate($customdatum->data, get_string(!empty($manual->param_inctime) ? 'customfield_datetime_format' : 'customfield_date_format', $this->languagefile)); } else { $rawdata[] = $customdatum->data; } } } } $labels[] = $this->add_grouping_header($field->name . ': ', implode(', ', $rawdata), $export_format); } } //user address if (!empty($headers['user_address'])) { $text_label = get_string('grouping_address', $this->languagefile); $address_text = get_string('grouping_address_format', $this->languagefile, $datum); $labels[] = $this->add_grouping_header($text_label, $address_text, $export_format); } //user city / town if (!empty($headers['user_city'])) { $text_label = get_string('grouping_city', $this->languagefile); $labels[] = $this->add_grouping_header($text_label, $datum->city, $export_format); } //user state / province if (!empty($headers['user_state'])) { $text_label = get_string('grouping_state', $this->languagefile); $labels[] = $this->add_grouping_header($text_label, $datum->state, $export_format); } //user email address if (!empty($headers['user_email'])) { $text_label = get_string('grouping_email', $this->languagefile); $labels[] = $this->add_grouping_header($text_label, $datum->email, $export_format); } // Get the credit total $num_credits = $this->get_total_credits($grouping_current, $grouping, $datum, $export_format); //create the header item $text_label = get_string('grouping_credits', $this->languagefile); $labels[] = $this->add_grouping_header($text_label, $num_credits, $export_format); return $labels; }
/** * Add an element to a form for a field. * * @param object $form the moodle form object we are adding the element to * @param object $mform the moodle quick form object belonging to the moodle form * @param mixed $context Moodle context * @param array $customdata any additional information to pass along to the element * @param object $field the custom field we are viewing / editing * @param boolean $checkrequired if true, add a required rule for this field * @param string $contexteditcap the edit capability to check if the field owner * is set up to use the "edit this context" option for editing * @param string $contextviewcap the view capability to check if the field owner * is set up to use the "view this context" option for viewing * @param int $entityid The id of the entity. Required only if an entity is passed. * @param string $entity optional entity/context name */ function manual_field_add_form_element($form, $mform, $context, $customdata, $field, $checkrequired = true, $contexteditcap = NULL, $contextviewcap = NULL, $entity = 'system', $entityid = 0) { $isvieworeditable = manual_field_is_view_or_editable($field, $context, $contexteditcap, $contextviewcap, $entity, $entityid); if ($isvieworeditable == MANUAL_FIELD_NO_VIEW_OR_EDIT) { return; } $elem = "field_{$field->shortname}"; $manual = new field_owner($field->owners['manual']); $control = $manual->param_control; require_once elis::plugin_file('elisfields_manual', "field_controls/{$control}.php"); call_user_func("{$control}_control_display", $form, $mform, $customdata, $field, false, $entity); $manualparams = unserialize($manual->params); // Set default data if no over-riding value set! if (!isset($customdata['obj']->{$elem})) { $defaultdata = field_data::get_for_context_and_field(NULL, $field); if (!empty($defaultdata)) { if ($field->multivalued) { $values = array(); foreach ($defaultdata as $defdata) { $values[] = $defdata->data; } $defaultdata = $values; // implode(',', $values) } else { foreach ($defaultdata as $defdata) { $defaultdata = $defdata->data; break; } } } // Format decimal numbers. if ($field->datatype == 'num' && $manualparams['control'] != 'menu') { $defaultdata = $field->format_number($defaultdata); } if (!is_null($defaultdata) && !is_object($defaultdata) && $defaultdata !== false) { if (is_string($defaultdata)) { $defaultdata = trim($defaultdata, "\r\n"); // Radio buttons! } $mform->setDefault($elem, $defaultdata); } } if ($isvieworeditable == MANUAL_FIELD_VIEWABLE) { // Have view but not edit permission. $mform->freeze($elem); } else { if ($checkrequired) { if (!empty($manualparams['required'])) { $mform->addRule($elem, null, 'required', null, 'client'); // TBD } } } }
/** * Validate that a single-value default is used when a user does not have data for a multi-value menu of choices field * * @param int $multivalued 1 if the custom field should be defined as multivalued, otherwise 0 * @param bool $multidataexists True if multi-valued data should exist for some other context, otherwise false * @dataProvider multivalue_setup_provider */ public function test_export_multivaluedata_menuofchoices_defaults($multivalued, $multidataexists) { global $CFG; // Setup. $this->load_csv_data(); // NOTE: always set multivalued at first so array of data can be set. $fieldid = $this->create_custom_field(); $this->create_field_mapping('testcustomfields', 'field_' . $fieldid); if ($multidataexists) { // Set up multi-valued data at some context. $field = new field($fieldid); $context = new stdClass(); $context->id = 9999; $values = array('value1', 'value2'); // Persist. field_data::set_for_context_and_field($context, $field, $values); } if ($multivalued === 0) { // Disable the multivalue setting. $field = new field($fieldid); $field->multivalued = 0; $field->save(); } // Obtain data. $data = $this->get_export_data(); // Validation. $this->assertEquals(3, count($data)); $header = $data[0]; $this->assertEquals('Header', $header[10]); $val = $multivalued === 1 && $multidataexists === false ? $data[1][10][0] : $data[1][10]; $this->assertEquals('option3', $val); }
public function update() { $result = parent::update(); if (isset($this->curriculum)) { $this->add_course_to_curricula($this->curriculum); } // Add moodle course template if (isset($this->location)) { $template = new coursetemplate($this->id); $template->location = $this->location; $template->templateclass = $this->templateclass; $template->courseid = $this->id; $template->data_update_record(true); } else { coursetemplate::delete_for_course($this->id); } $result = $result && field_data::set_for_context_from_datarecord('course', $this); return $result; }
/** * Determines if a paritcular cluster is set up for groupings * * @param int $clusterid The id of the cluster in question * @return boolean True if this grouping is allowed, otherwise false */ function userset_groups_grouping_allowed($clusterid) { global $CFG, $DB; $enabled = get_config('elisprogram_usetgroups', 'userset_groupings'); if (empty($enabled)) { return false; } //retrieve the config field if ($fieldid = $DB->get_field(field::TABLE, 'id', array('shortname' => 'userset_groupings'))) { //retrieve the cluster context instance $context_instance = \local_elisprogram\context\userset::instance($clusterid); //construct the specific field $field = new field($fieldid); //retrieve the appropriate field's data for this cluster based on the context instance if ($field_data = field_data::get_for_context_and_field($context_instance, $field)) { //this should really only return one record, so return true of any have non-empty data foreach ($field_data as $field_datum) { if (!empty($field_datum->data)) { return true; } } } } return false; }
static function get_for_cluster($cluster) { require_once CURMAN_DIRLOCATION . '/lib/customfield.class.php'; require_once CURMAN_DIRLOCATION . '/plugins/cluster_classification/lib.php'; if (is_object($cluster)) { $cluster = $cluster->id; } $context = get_context_instance(context_level_base::get_custom_context_level('cluster', 'block_curr_admin'), $cluster); $value = field_data::get_for_context_and_field($context, CLUSTER_CLASSIFICATION_FIELD); if (!empty($value)) { $value = array_shift($value); $name = addslashes($value->data); return new clusterclassification("shortname = '{$name}'"); } }
function display_editfield() { global $CFG, $DB; $level = $this->required_param('level', PARAM_ACTION); $ctxlvl = \local_eliscore\context\helper::get_level_from_name($level); if (!$ctxlvl) { print_error('invalid_context_level', 'local_elisprogram'); } $id = $this->optional_param('id', NULL, PARAM_INT); require_once elispm::file('form/customfieldform.class.php'); $tmppage = new customfieldpage(array('level' => $level, 'action' => 'editfield'), $this); $form = new customfieldform($tmppage->url, array('id' => $id, 'level' => $level, 'from' => optional_param('from', '', PARAM_CLEAN))); if ($form->is_cancelled()) { $tmppage = new customfieldpage(array('level' => $level)); redirect($tmppage->url, get_string('edit_cancelled', 'local_elisprogram')); } else { if ($data = $form->get_data()) { $src = !empty($data->manual_field_options_source) ? $data->manual_field_options_source : ''; // ELIS-8066: strip CRs "\r" from menu options & default data (below) if (!empty($data->manual_field_options)) { $data->manual_field_options = str_replace("\r", '', $data->manual_field_options); } switch ($data->manual_field_control) { case 'checkbox': if (!$data->multivalued && !empty($src)) { $elem = "defaultdata_radio_{$src}"; $data->defaultdata = isset($data->{$elem}) ? $data->{$elem} : ''; // radio buttons unset by default // error_log("/local/elisprogram/customfieldpage.class.php:: defaultdata->{$elem} = {$data->defaultdata}"); } else { if (!$data->multivalued && !empty($data->manual_field_options)) { $data->defaultdata = str_replace("\r", '', $data->defaultdata_radio); } else { $data->defaultdata = $data->defaultdata_checkbox; } } break; case 'menu': $elem = !empty($src) ? "defaultdata_menu_{$src}" : "defaultdata_menu"; $data->defaultdata = $data->{$elem}; if (empty($src)) { $data->defaultdata = str_replace("\r", '', $data->defaultdata); } break; case 'datetime': $data->defaultdata = $data->defaultdata_datetime; break; default: $data->defaultdata = $data->defaultdata_text; break; } $field = new field($data); if ($id) { $field->id = $id; $field->save(); } else { $field->save(); // assume each field only belongs to one context level (for now) $fieldcontext = new field_contextlevel(); $fieldcontext->fieldid = $field->id; $fieldcontext->contextlevel = $ctxlvl; $fieldcontext->save(); } //don't use !empty here because we might be storing a 0 or similar value if ($data->defaultdata != '') { // save the default value $defaultdata = $data->defaultdata; if ($field->multivalued && is_string($defaultdata)) { // parse as a CSV string // until we can use str_getcsv from PHP 5.3... $temp = fopen("php://memory", "rw"); fwrite($temp, $defaultdata); rewind($temp); $defaultdata = fgetcsv($temp); fclose($temp); } else { if (!$field->multivalued && is_array($defaultdata)) { foreach ($defaultdata as $val) { $defaultdata = $val; break; } } } field_data::set_for_context_and_field(NULL, $field, $defaultdata); } else { if ($field->multivalued) { field_data::set_for_context_and_field(NULL, $field, array()); } else { field_data::set_for_context_and_field(NULL, $field, NULL); } } $plugins = core_component::get_plugin_list('elisfields'); foreach ($plugins as $plugin => $dir) { if (is_readable($CFG->dirroot . '/local/eliscore/fields/' . $plugin . '/custom_fields.php')) { require_once elis::plugin_file('elisfields_' . $plugin, 'custom_fields.php'); if (function_exists("{$plugin}_field_save_form_data")) { call_user_func("{$plugin}_field_save_form_data", $form, $field, $data); } } } $tmppage = new customfieldpage(array('level' => $level)); redirect($tmppage->url, get_string('field_saved', 'local_elisprogram', $field)); } else { if (!empty($id)) { if ($this->optional_param('from', NULL, PARAM_CLEAN) == 'moodle' && $level == 'user') { $moodlefield = $DB->get_record('user_info_field', array('id' => $id)); if (!$moodlefield) { print_error('invalid_field_id', 'local_elisprogram'); } unset($moodlefield->id); $data = $moodlefield; $data_array = (array) $moodlefield; $data_array['datatype'] = 'text'; $data_array['manual_field_control'] = $moodlefield->datatype; switch ($moodlefield->datatype) { case field::CHECKBOX: $data_array['datatype'] = 'bool'; break; case field::DATETIME: $data_array['datatype'] = 'datetime'; $data_array['manual_field_startyear'] = $moodlefield->param1; $data_array['manual_field_stopyear'] = $moodlefield->param2; $data_array['manual_field_inctime'] = $moodlefield->param3; break; case field::MENU: $data_array['datatype'] = 'char'; $data_array['manual_field_options'] = $moodlefield->param1; break; case field::TEXTAREA: $data_array['manual_field_columns'] = $moodlefield->param1; $data_array['manual_field_rows'] = $moodlefield->param2; break; case field::TEXT: if ($moodlefield->param3) { $data_array['manual_field_control'] = 'password'; } $data_array['manual_field_columns'] = $moodlefield->param1; $data_array['manual_field_maxlength'] = $moodlefield->param2; break; } } else { $data = new field($id); $data->load(); $manual = new field_owner(!isset($field->owners) || !isset($field->owners['manual']) ? false : $field->owners['manual']); $menu_src = !empty($manual->options_source) ? $manual->options_source : 0; $data_array = $data->to_array(); $field_record = $DB->get_record(field::TABLE, array('id' => $id)); if (!empty($field_record)) { foreach ($field_record as $field_item => $field_value) { $data_array[$field_item] = $field_value; } } $defaultdata = field_data::get_for_context_and_field(NULL, $data); if (!empty($defaultdata)) { if ($data->multivalued) { $values = array(); foreach ($defaultdata as $defdata) { $values[] = $defdata->data; } $defaultdata = $values; } else { foreach ($defaultdata as $defdata) { $defaultdata = $defdata->data; break; } } } $field = new field(); // Format decimal numbers if ($data_array['datatype'] == 'num' && $manual->param_control != 'menu') { $defaultdata = $field->format_number($defaultdata); } if (!is_object($defaultdata)) { $data_array['defaultdata'] = $defaultdata; } $plugins = core_component::get_plugin_list('elisfields'); foreach ($plugins as $plugin => $dir) { if (is_readable($CFG->dirroot . '/local/eliscore/fields/' . $plugin . '/custom_fields.php')) { include_once $CFG->dirroot . '/local/eliscore/fields/' . $plugin . '/custom_fields.php'; if (function_exists("{$plugin}_field_get_form_data")) { $data_array += call_user_func("{$plugin}_field_get_form_data", $form, $data); } } } } if (isset($data_array['defaultdata'])) { // ELIS-6699 -- load the field to determine the data type used, $data may be a field_data_* or field object if (isset($data->fieldid)) { $field->id = $data->fieldid; $field->load(); } else { $field = $data; } $data_array['defaultdata_checkbox'] = !empty($data_array['defaultdata']); // ELIS-6699 -- If this is not a datetime field, then we can't use the default data value as a timestamp $data_array['defaultdata_datetime'] = $field->datatype == 'datetime' ? $data_array['defaultdata'] : time(); $data_array['defaultdata_text'] = strval($data_array['defaultdata']); $data_array[empty($menu_src) ? 'defaultdata_menu' : "defaultdata_menu_{$menu_src}"] = $data_array['defaultdata']; $data_array[empty($menu_src) ? 'defaultdata_radio' : "defaultdata_radio_{$menu_src}"] = $data_array['defaultdata']; } $form->set_data($data_array); } $form->display(); } } }
/** * ELIS-4797: Test Various Custom Field Operations */ public function test_customfieldoperations() { $contextlevels = \local_eliscore\context\helper::get_legacy_levels(); foreach ($contextlevels as $ctxname => $ctxlvl) { $category = $this->create_field_category($ctxlvl); $field = $this->create_field($category, $ctxlvl); $fieldsfetched = field::get_for_context_level($ctxlvl); $fieldfound = false; foreach ($fieldsfetched as $fieldfetched) { if ($fieldfetched->shortname === $field->shortname) { $fieldfound = true; } } $this->assertTrue($fieldfound); $fieldfetched = field::get_for_context_level_with_name($ctxlvl, $field->shortname); $this->assertEquals($field->shortname, $fieldfetched->shortname); $fieldfetched = field::ensure_field_exists_for_context_level($field, $ctxlvl, $category); $this->assertEquals($field->shortname, $fieldfetched->shortname); $catsfetched = field_category::get_for_context_level($ctxlvl); $catfound = false; foreach ($catsfetched as $catfetched) { if ($catfetched->id == $category->id) { $catfound = true; } } $this->assertTrue($catfound); if ($ctxlvl === CONTEXT_ELIS_PROGRAM) { $cur = $this->create_curriculum(); $fielddata = field_data::get_for_context_and_field(null, $field); $fielddata = $fielddata->current(); $res = $fielddata->set_for_context_from_datarecord($ctxlvl, $cur); $this->assertTrue($res); } } }
/** * Transforms a heading element displayed above the columns into a listing of such heading elements * * @param string array $grouping_current Mapping of field names to current values in the grouping * @param table_report_grouping $grouping Object containing all info about the current level of grouping * being handled * @param stdClass $datum The most recent record encountered * @param string $export_format The format being used to render the report * * @return string array Set of text entries to display */ function transform_grouping_header_label($grouping_current, $grouping, $datum, $export_format) { global $CFG; //dependencies for custom fields require_once $CFG->dirroot . '/curriculum/config.php'; require_once CURMAN_DIRLOCATION . '/lib/customfield.class.php'; $labels = array(); //user fullname if ($export_format == table_report::$EXPORT_FORMAT_HTML) { //label for this grouping element $text_label = get_string('grouping_name', $this->languagefile); } else { //label for all groupings $text_label = get_string('grouping_name_csv', $this->languagefile); } $fullname_text = fullname($datum); $labels[] = $this->add_grouping_header($text_label, $fullname_text, $export_format); $filters = php_report_filtering_get_active_filter_values($this->get_report_shortname(), 'filter-detailheaders'); $headers = $filters[0]['value']; foreach ($headers as $field => $active) { if ($active && substr($field, 0, 7) == 'custom_') { $fieldid = substr($field, 7); $this->_userfieldids[] = $fieldid; } } //configured user custom fields if (!empty($this->_userfieldids)) { //only need to obtain the user information once $user_context_level = context_level_base::get_custom_context_level('user', 'block_curr_admin'); $user = get_context_instance($user_context_level, $datum->userid); //add a row for each field foreach ($this->_userfieldids as $userfieldid) { $field = new field($userfieldid); //needed to store just the actual data value $rawdata = array(); if ($customdata = field_data::get_for_context_and_field($user, $field)) { //could potentially have multiple values foreach ($customdata as $customdatum) { if ($field->datatype == 'bool') { //special display handling for boolean values $rawdata[] = !empty($customdataum->data) ? get_string('yes') : get_string('no'); } else { $rawdata[] = $customdatum->data; } } } $labels[] = $this->add_grouping_header($field->name . ': ', implode(', ', $rawdata), $export_format); } } //user address if (!empty($headers['user_address'])) { $text_label = get_string('grouping_address', $this->languagefile); $address_text = get_string('grouping_address_format', $this->languagefile, $datum); $labels[] = $this->add_grouping_header($text_label, $address_text, $export_format); } //user city / town if (!empty($headers['user_city'])) { $text_label = get_string('grouping_city', $this->languagefile); $labels[] = $this->add_grouping_header($text_label, $datum->city, $export_format); } //user state / province if (!empty($headers['user_state'])) { $text_label = get_string('grouping_state', $this->languagefile); $labels[] = $this->add_grouping_header($text_label, $datum->state, $export_format); } //user email address if (!empty($headers['user_email'])) { $text_label = get_string('grouping_email', $this->languagefile); $labels[] = $this->add_grouping_header($text_label, $datum->email, $export_format); } // Get the credit total $num_credits = $this->get_total_credits($grouping_current, $grouping, $datum, $export_format); //create the header item $text_label = get_string('grouping_credits', $this->languagefile); $labels[] = $this->add_grouping_header($text_label, $num_credits, $export_format); return $labels; }
public function save() { parent::save(); if (isset($this->curriculum)) { $this->add_course_to_curricula($this->curriculum); } // Add moodle course template if (isset($this->location)) { $template = $this->coursetemplate->current(); $template->location = $this->location; $template->templateclass = $this->templateclass; $template->courseid = $this->id; $template->save(); } else { coursetemplate::delete_records(new field_filter('courseid', $this->id)); } field_data::set_for_context_from_datarecord(CONTEXT_ELIS_COURSE, $this); }
public function save() { $isnew = empty($this->id); parent::save(); if (!$isnew) { // If this setting is changed, we need to update the existing curriclum expiration values (ELIS-1172) if ($rs = $this->_db->get_recordset_select(curriculumstudent::TABLE, "timecompleted = 0 AND curriculumid = {$this->id}", null, 'id, userid')) { $timenow = time(); foreach ($rs as $rec) { $update = new stdClass(); $update->id = $rec->id; $update->timeexpired = calculate_curriculum_expiry(NULL, $this->id, $rec->userid); $update->timemodified = $timenow; $this->_db->update_record(curriculumstudent::TABLE, $update); } $rs->close(); } } field_data::set_for_context_from_datarecord(CONTEXT_ELIS_PROGRAM, $this); }
/** * Load the custom field values from the database. */ private function _load_field_data() { if (!empty($this->id) && !$this->_fields_loaded) { $this->_load_context(); $this->_load_fields(); $data = field_data::get_for_context($this->_context); foreach (self::$_fields[$this->_context->contextlevel] as $name => $field) { if (empty($this->_field_changed[$name]) && isset($data[$name])) { // only set the field data if it hasn't been changed $this->_field_data[$name] = $data[$name]; } } $this->_fields_loaded = true; } }
public function update() { $status = parent::update(); if ($this->moodlecourseid || $this->autocreate) { moodle_attach_class($this->id, $this->moodlecourseid, '', true, true, $this->autocreate); } if (!empty($this->oldmax) && $this->oldmax < $this->maxstudents && waitlist::count_records($this->id) > 0) { for ($i = $this->oldmax; $i < $this->maxstudents; $i++) { $next_student = waitlist::get_next($this->id); if (!empty($next_student)) { $next_student->enrol(); } else { break; } } } $status = $status && field_data::set_for_context_from_datarecord('class', $this); return $status; }
/** * Obtain the appropriate information regarding program courses as needed * by the dashboard * * @param boolean $tab_sensitive true if we need to be concerned about whether * we are on the current or archived tab, otherwise * false * @param boolean $show_archived specifies whether we're showing archived or non- * archived courses (ignored if tab_sensitive is false) * @param boolean $showcompleted specifies whether we're showing passed and failed * courses in addition to ones in progress * @param mixed $programid a specific program id to look for data related to, or * NULL for all * @return array a list of values, where the first entry is the user's course list, * the second is a mapping of programs to a course listing, the third * is a list of classes handled, and the fourth is the number of programs * handled, the fifth is a mapping of program ids to number of compelted * courses, the sixth is a mapping of program ids to total number of courses */ function get_dashboard_program_data($tab_sensitive, $show_archived, $showcompleted = false, $programid = NULL) { global $CFG, $DB; $archive_var = '_elis_program_archive'; $classids = array(); //track mapping of programs to course / class listings $curriculas = array(); $totalcurricula = 0; //map program ids to appropriate counts $completecoursesmap = array(); $totalcoursesmap = array(); $params = array($this->id); //set up a condition for when handling a specific program $program_condition = ''; if ($programid !== NULL) { $program_condition = 'AND cur.id = ?'; $params[] = $programid; } $sql = 'SELECT curstu.id, curstu.curriculumid as curid, cur.name as name FROM {' . curriculumstudent::TABLE . '} curstu JOIN {' . curriculum::TABLE . '} cur ON cur.id = curstu.curriculumid WHERE curstu.userid = ? ' . $program_condition . ' ORDER BY cur.priority ASC, cur.name ASC'; //mapping of completion status to display string $status_mapping = array(STUSTATUS_PASSED => get_string('passed', 'local_elisprogram'), STUSTATUS_FAILED => get_string('failed', 'local_elisprogram'), STUSTATUS_NOTCOMPLETE => get_string('n_completed', 'local_elisprogram')); if ($usercurs = $DB->get_records_sql($sql, $params)) { //^pre-ELIS-3615 WAS: if ($usercurs = curriculumstudent::get_curricula($this->id)) { foreach ($usercurs as $usercur) { // Check if this curricula is set as archived and whether we want to display it $crlm_context = \local_elisprogram\context\program::instance($usercur->curid); $data_array = field_data::get_for_context_and_field($crlm_context, $archive_var); $crlm_archived = 0; if (!empty($data_array) && is_object($data_array->rs) && !empty($data_array->rs)) { $crlm_archived = !empty($data_array->rs->current()->data) ? 1 : 0; } //being insensitive to which tab we're on gets us this listing "for free" if (!$tab_sensitive || $show_archived == $crlm_archived) { $totalcurricula++; $curriculas[$usercur->curid]['id'] = $usercur->curid; $curriculas[$usercur->curid]['name'] = $usercur->name; $data = array(); //count our totals per-program //note that "course" is really one enrolment, so this should //count each enrolment, plus one for each unenrolled program course $totalcourses = 0; $completecourses = 0; $courses = curriculumcourse_get_listing($usercur->curid, 'curcrs.position, crs.name', 'ASC'); foreach ($courses as $course) { $course_obj = new course($course->courseid); $coursedesc = $course_obj->syllabus; $cdata = student_get_class_from_course($course->courseid, $this->id); if ($cdata->valid() === true) { foreach ($cdata as $classdata) { //count each enrolment as one "course" $totalcourses++; if (!in_array($classdata->id, $classids)) { $classids[] = $classdata->id; } if ($classdata->completestatusid == STUSTATUS_PASSED || $classdata->completestatusid == STUSTATUS_FAILED) { //count completed enrolments $completecourses++; } if (!$showcompleted && ($classdata->completestatusid == STUSTATUS_PASSED || $classdata->completestatusid == STUSTATUS_FAILED)) { //not showing completed courses, so skip this course continue; } if ($mdlcrs = moodle_get_course($classdata->id)) { $coursename = '<a href="' . $CFG->wwwroot . '/course/view.php?id=' . $mdlcrs . '">' . $course->coursename . '</a>'; } else { $coursename = $course->coursename; } $data[] = array($coursename, $classdata->idnumber, $coursedesc, pm_display_grade($classdata->grade), $status_mapping[$classdata->completestatusid], $classdata->completestatusid == STUSTATUS_PASSED && !empty($classdata->completetime) ? userdate($classdata->completetime, get_string('pm_date_format', 'local_elisprogram')) : get_string('na', 'local_elisprogram')); } } else { //count this unenrolled course toward the total $totalcourses++; $data[] = array($course->coursename, get_string('dashboard_na', 'local_elisprogram'), $coursedesc, 0, get_string('not_enrolled', 'local_elisprogram'), get_string('na', 'local_elisprogram')); } unset($cdata); } unset($courses); $curriculas[$usercur->curid]['data'] = $data; //associate this program id with the appropriate counts $completecoursesmap[$usercur->curid] = $completecourses; $totalcoursesmap[$usercur->curid] = $totalcourses; } else { // Keep note of the classid's regardless if set archived or not for later use in determining non-curricula courses $courses = curriculumcourse_get_listing($usercur->curid, 'curcrs.position, crs.name', 'ASC'); foreach ($courses as $course) { $cdata = student_get_class_from_course($course->courseid, $this->id); foreach ($cdata as $classdata) { if (!in_array($classdata->id, $classids)) { $classids[] = $classdata->id; } } unset($cdata); } unset($courses); } } } return array($usercurs, $curriculas, $classids, $totalcurricula, $completecoursesmap, $totalcoursesmap); }
function update() { global $CFG; global $CURMAN; $old = new cluster($this->id); $parent_obj = new cluster($this->parent); $this->depth = empty($parent_obj->depth) ? 1 : $parent_obj->depth + 1; $result = parent::update(); if ($this->parent != $old->parent) { $cluster_context_level = context_level_base::get_custom_context_level('cluster', 'block_curr_admin'); $cluster_context_instance = get_context_instance($cluster_context_level, $this->id); // find all subclusters and adjust their depth $delta_depth = $this->depth - $old->depth; $sql = "UPDATE {$CURMAN->db->prefix_table(CLSTTABLE)}\n SET depth = depth + {$delta_depth}\n WHERE id IN (SELECT instanceid\n FROM {$CURMAN->db->prefix_table('context')}\n WHERE contextlevel = {$cluster_context_level}\n AND path LIKE '{$cluster_context_instance->path}/%')"; execute_sql($sql, false); // Blank out the depth and path for associated records and child records in context table $sql = "UPDATE {$CFG->prefix}context\n SET depth=0, path=NULL\n WHERE id={$cluster_context_instance->id} OR path LIKE '{$cluster_context_instance->path}/%'"; execute_sql($sql, false); // Rebuild any blanked out records in context table build_context_path(); } $plugins = cluster::get_plugins(); foreach ($plugins as $plugin) { require_once CURMAN_DIRLOCATION . '/cluster/' . $plugin . '/lib.php'; call_user_func('cluster_' . $plugin . '_update', $this); } $result = $result && field_data::set_for_context_from_datarecord('cluster', $this); events_trigger('crlm_cluster_updated', $this); return $result; }
public function save() { //add parent::save(); //add if ($this->autocreate) { $this->track_auto_create(); } $status = field_data::set_for_context_from_datarecord(CONTEXT_ELIS_TRACK, $this); return $status; }
/** * Create a user-level ELIS field from an existing Moodle user profile field. * * @param int $mfieldid The ID of a Moodle user profile field. * @param field_category $category An ELIS field_category object to add the new field to. * @param boolean $syncdir Data Sync Direction. * Possible values: * false = no syncing * pm_moodle_profile::sync_from_moodle = sync from moodle. * pm_moodle_profile::sync_to_moodle = sync to moodle. * @return field The new field object. */ public static function make_from_moodle_field($mfieldid, field_category $category, $syncdir = false) { require_once elis::file('eliscore/fields/manual/custom_fields.php'); require_once elis::file('eliscore/fields/moodleprofile/custom_fields.php'); global $DB; // Get moodle field information. $mfield = $DB->get_record('user_info_field', array('id' => $mfieldid)); if (empty($mfield)) { return null; } if (!defined('CONTEXT_ELIS_USER')) { return null; } // Initially elis field data is the same as moodle field data. $field = (array) $mfield; unset($field['id']); $field['datatype'] = 'text'; $field['categoryid'] = $category->id; // Manual field owner data. $fieldmanualowner = new field_owner(); $fieldmanualowner->plugin = 'manual'; $fieldmanualowner->param_control = $mfield->datatype; $fieldmanualowner->param_required = (bool) (int) $mfield->required; // Set data based on moodle field's datatype. switch ($mfield->datatype) { case static::CHECKBOX: $field['datatype'] = 'bool'; break; case static::DATETIME: $field['datatype'] = 'datetime'; $fieldmanualowner->param_startyear = $mfield->param1; $fieldmanualowner->param_stopyear = $mfield->param2; $fieldmanualowner->param_inctime = $mfield->param3; break; case static::MENU: $field['datatype'] = 'char'; $fieldmanualowner->param_options = $mfield->param1; break; case static::TEXTAREA: $fieldmanualowner->param_columns = !empty($mfield->param1) ? $mfield->param1 : 30; $fieldmanualowner->param_rows = !empty($mfield->param2) ? $mfield->param2 : 10; break; case static::TEXT: if ($mfield->param3) { $fieldmanualowner->param_control = 'password'; } $fieldmanualowner->param_columns = $mfield->param1; $fieldmanualowner->param_maxlength = $mfield->param2; break; } // Create field. $field = new field($field); $field->save(); // Create moodle profile owner. if ($syncdir === pm_moodle_profile::sync_from_moodle || $syncdir === pm_moodle_profile::sync_from_moodle) { $fieldmoodleprofileowner = new field_owner(array('fieldid' => $field->id, 'plugin' => 'moodle_profile', 'exclude' => $syncdir)); $fieldmoodleprofileowner->save(); } // Create manual owner. $fieldmanualowner->fieldid = $field->id; $fieldmanualowner->save(); // Update field context level. static::ensure_field_exists_for_context_level($field, CONTEXT_ELIS_USER, $category); // Reload field object. $field = new field($field->id); $field->load(); if ($syncdir === pm_moodle_profile::sync_from_moodle) { sync_profile_field_settings_from_moodle($field); } // Set default data. if (isset($mfield->defaultdata) && $mfield->defaultdata !== '') { field_data::set_for_context_and_field(null, $field, $mfield->defaultdata); } // Reload field object. $field = new field($field->id); $field->load(); return $field; }
/** * Validate that the field_data "get_for_context_and_field" method always excludes a custom field's default * data when some data exists for the appropriate context, regardless of the related parameter value. * * @param boolean $includedefault * @dataProvider include_default_provider */ public function test_get_for_context_and_field_excludes_default_value_when_data_exists($includedefault) { // Set up our custom field data. $field = $this->init_custom_field(); // Set up our data point. $fielddatachar = new field_data_char(array('fieldid' => $field->id, 'contextid' => self::CONTEXTID, 'data' => 'value3')); $fielddatachar->save(); // Run get_for_context_and_field to obtain our data set. $context = new stdClass(); $context->id = self::CONTEXTID; $data = field_data::get_for_context_and_field($context, $field, $includedefault); // Validate number of data records (one for specific context). $count = 0; $record = null; foreach ($data as $datum) { $count++; $record = $datum; } $this->assertEquals(1, $count); $this->assertEquals($field->id, $record->fieldid); $this->assertEquals('value3', $record->data); }
/** * Get the user dashboard report view. * * @uses $CFG, $CURMAN * @param none * @return string The HTML for the dashboard report. */ function get_dashboard() { global $CFG, $CURMAN; require_once CURMAN_DIRLOCATION . '/lib/curriculumstudent.class.php'; //needed for AJAX calls require_js(array('yui_yahoo', 'yui_dom', 'yui_event', 'yui_connection', "{$CFG->wwwroot}/curriculum/js/util.js", "{$CFG->wwwroot}/curriculum/js/dashboard.js"), true); if (optional_param('tab', '', PARAM_CLEAN) == 'archivedlp') { $tab = 'archivedlp'; $show_archived = 1; } else { $tab = 'currentlp'; $show_archived = 0; } $content = ''; $archive_var = '_elis_curriculum_archive'; $totalcourses = 0; $totalcurricula = 0; $completecourses = 0; $curriculas = array(); $classids = array(); $sql = 'SELECT curstu.id, curstu.curriculumid as curid, cur.name as name FROM ' . $CURMAN->db->prefix_table(CURASSTABLE) . ' curstu JOIN ' . $CURMAN->db->prefix_table(CURTABLE) . ' cur ON cur.id = curstu.curriculumid WHERE curstu.userid = \'' . $this->id . '\' ORDER BY cur.priority ASC, cur.name ASC'; if ($usercurs = get_records_sql($sql)) { foreach ($usercurs as $usercur) { // Check if this curricula is set as archived and whether we want to display it $crlm_context = get_context_instance(context_level_base::get_custom_context_level('curriculum', 'block_curr_admin'), $usercur->curid); $data_array = field_data::get_for_context_and_field($crlm_context, $archive_var); $crlm_archived = 0; if (is_array($data_array) && !empty($data_array)) { foreach ($data_array as $data_key => $data_obj) { $crlm_archived = !empty($data_obj->data) ? 1 : 0; } } if ($show_archived == $crlm_archived) { $totalcurricula++; $curriculas[$usercur->curid]['id'] = $usercur->curid; $curriculas[$usercur->curid]['name'] = $usercur->name; $data = array(); if ($courses = curriculumcourse_get_listing($usercur->curid, 'curcrs.position, crs.name', 'ASC')) { foreach ($courses as $course) { $totalcourses++; $course_obj = new course($course->courseid); $coursedesc = $course_obj->syllabus; if ($cdata = student_get_class_from_course($course->courseid, $this->id)) { foreach ($cdata as $classdata) { if (!in_array($classdata->id, $classids)) { $classids[] = $classdata->id; } if ($classdata->completestatusid == STUSTATUS_PASSED) { $completecourses++; } if ($mdlcrs = moodle_get_course($classdata->id)) { $coursename = '<a href="' . $CFG->wwwroot . '/course/view.php?id=' . $mdlcrs . '">' . $course->coursename . '</a>'; } else { $coursename = $course->coursename; } $data[] = array($coursename, $coursedesc, $classdata->grade, $classdata->completestatusid == STUSTATUS_PASSED ? get_string('yes') : get_string('no'), $classdata->completestatusid == STUSTATUS_PASSED && !empty($classdata->completetime) ? date('M j, Y', $classdata->completetime) : get_string('na', 'block_curr_admin')); } } else { $data[] = array($course->coursename, $coursedesc, 0, get_string('no'), get_string('na', 'block_curr_admin')); } } } $curriculas[$usercur->curid]['data'] = $data; } else { // Keep note of the classid's regardless if set archived or not for later use in determining non-curricula courses if ($courses = curriculumcourse_get_listing($usercur->curid, 'curcrs.position, crs.name', 'ASC')) { foreach ($courses as $course) { if ($cdata = student_get_class_from_course($course->courseid, $this->id)) { foreach ($cdata as $classdata) { if (!in_array($classdata->id, $classids)) { $classids[] = $classdata->id; } } } } } } } } // Show different css for IE below version 8 if (check_browser_version('MSIE', 7.0) && !check_browser_version('MSIE', 8.0)) { // IEs that are lower than version 8 do not get the float because it messes up the tabs at the top of the page for some reason $float_style = 'text-align:right;'; } else { // Sane browsers get the float tag $float_style = 'text-align:right; float:right;'; } // Tab header $field_exists = field::get_for_context_level_with_name('curriculum', $archive_var); if (!empty($field_exists)) { $tabrow = array(); $tabrow[] = new tabobject('currentlp', $CFG->wwwroot . '/curriculum/index.php?tab=currentlp', get_string('tab_current_learning_plans', 'block_curr_admin')); $tabrow[] = new tabobject('archivedlp', $CFG->wwwroot . '/curriculum/index.php?tab=archivedlp', get_string('tab_archived_learning_plans', 'block_curr_admin')); $tabrows = array($tabrow); print_tabs($tabrows, $tab); } $content .= print_heading_block(get_string('learningplanwelcome', 'block_curr_admin', fullname($this)), '', true); if ($totalcurricula === 0) { $blank_lang = $tab == 'archivedlp' ? 'noarchivedplan' : 'nolearningplan'; $content .= '<br /><center>' . get_string($blank_lang, 'block_curr_admin') . '</center>'; } // Load the user preferences for hide/show button states if ($collapsed = get_user_preferences('crlm_learningplan_collapsed_curricula')) { $collapsed_array = explode(',', $collapsed); } else { $collapsed = ''; $collapsed_array = array(); } $content .= '<input type="hidden" name="collapsed" id="collapsed" value="' . $collapsed . '">'; if (!empty($usercurs)) { foreach ($usercurs as $usercur) { if (!isset($curriculas[$usercur->curid])) { continue; } $curricula = $curriculas[$usercur->curid]; $table = new stdClass(); $table->head = array(get_string('class', 'block_curr_admin'), get_string('description', 'block_curr_admin'), get_string('score', 'block_curr_admin'), get_string('completed_label', 'block_curr_admin'), get_string('date', 'block_curr_admin')); $table->data = $curricula['data']; $curricula_name = empty($CURMAN->config->disablecoursecatalog) ? '<a href="index.php?s=crscat§ion=curr&showcurid=' . $curricula['id'] . '">' . $curricula['name'] . '</a>' : $curricula['name']; $header_curr_name = get_string('learningplanname', 'block_curr_admin', $curricula_name); if (in_array($curricula['id'], $collapsed_array)) { $button_label = get_string('showcourses', 'block_curr_admin'); $extra_class = ' hide'; } else { $button_label = get_string('hidecourses', 'block_curr_admin'); $extra_class = ''; } $heading = '<div class="clearfix"></div>' . '<div style="' . $float_style . '">' . '<script id="curriculum' . $curricula['id'] . 'script" type="text/javascript">toggleVisibleInitWithState("curriculum' . $curricula['id'] . 'script", "curriculum' . $curricula['id'] . 'button", "' . $button_label . '", "' . get_string('hidecourses', 'block_curr_admin') . '", "' . get_string('showcourses', 'block_curr_admin') . '", "curriculum-' . $curricula['id'] . '");</script></div>' . $header_curr_name; $content .= '<div class="dashboard_curricula_block">'; $content .= print_heading($heading, 'left', 2, 'main', true); $content .= '<div id="curriculum-' . $curricula['id'] . '" class="yui-skin-sam ' . $extra_class . '">'; if (empty($curricula['data'])) { $content .= get_string('nocourseassoc', 'block_curr_admin'); } else { $content .= print_table($table, true); } $content .= '</div>'; $content .= '</div>'; } } /// Completed non-curricula course data if ($tab != 'archivedlp') { if (!empty($classids)) { $sql = "SELECT stu.id, stu.classid, crs.name as coursename, stu.completetime, stu.grade, stu.completestatusid\n FROM " . $CURMAN->db->prefix_table(STUTABLE) . " stu\n INNER JOIN " . $CURMAN->db->prefix_table(CLSTABLE) . " cls ON cls.id = stu.classid\n INNER JOIN " . $CURMAN->db->prefix_table(CRSTABLE) . " crs ON crs.id = cls.courseid\n WHERE userid = {$this->id}\n AND classid " . (count($classids) == 1 ? "!= " . current($classids) : "NOT IN (" . implode(", ", $classids) . ")") . "\n ORDER BY crs.name ASC, stu.completetime ASC"; } else { $sql = "SELECT stu.id, stu.classid, crs.name as coursename, stu.completetime, stu.grade, stu.completestatusid\n FROM " . $CURMAN->db->prefix_table(STUTABLE) . " stu\n INNER JOIN " . $CURMAN->db->prefix_table(CLSTABLE) . " cls ON cls.id = stu.classid\n INNER JOIN " . $CURMAN->db->prefix_table(CRSTABLE) . " crs ON crs.id = cls.courseid\n WHERE userid = {$this->id}\n ORDER BY crs.name ASC, stu.completetime ASC"; } if ($classes = get_records_sql($sql)) { $table = new stdClass(); $table->head = array(get_string('class', 'block_curr_admin'), get_string('score', 'block_curr_admin'), get_string('completed_label', 'block_curr_admin'), get_string('date', 'block_curr_admin')); $table->data = array(); foreach ($classes as $class) { if ($mdlcrs = moodle_get_course($class->classid)) { $coursename = '<a href="' . $CFG->wwwroot . '/course/view.php?id=' . $mdlcrs . '">' . $class->coursename . '</a>'; } else { $coursename = $class->coursename; } $table->data[] = array($coursename, $class->grade, $class->completestatusid == STUSTATUS_PASSED ? get_string('yes') : get_string('no'), $class->completestatusid == STUSTATUS_PASSED && !empty($class->completetime) ? date('M j, Y', $class->completetime) : get_string('na', 'block_curr_admin')); } $header_curr_name = get_string('noncurriculacourses', 'block_curr_admin'); if (in_array('na', $collapsed_array)) { $button_label = get_string('showcourses', 'block_curr_admin'); $extra_class = ' hide'; } else { $button_label = get_string('hidecourses', 'block_curr_admin'); $extra_class = ''; } $heading = '<div class="clearfix"></div>' . '<div style="' . $float_style . '">' . '<script id="noncurriculascript" type="text/javascript">toggleVisibleInitWithState("noncurriculascript", "noncurriculabutton", "' . $button_label . '", "' . get_string('hidecourses', 'block_curr_admin') . '", "' . get_string('showcourses', 'block_curr_admin') . '", "curriculum-na");</script></div>' . $header_curr_name; $content .= '<div class="dashboard_curricula_block">'; $content .= print_heading($heading, 'left', 2, 'main', true); $content .= '<div id="curriculum-na" class="yui-skin-sam ' . $extra_class . '">'; $content .= print_table($table, true); $content .= '</div>'; $content .= '</div>'; } } return $content; }
/** * Get data for enable fields for a single record. * * @param object $record The current database record for the current row of data. * * @return array An array of additional data, indexed by field. */ public function get_data($record) { global $CFG; require_once $CFG->dirroot . '/local/elisprogram/lib/setup.php'; require_once elis::lib('data/customfield.class.php'); require_once elispm::file('accesslib.php'); $this->init_customfield_data(); $date_format = get_string('date_format', 'dhexport_version1elis'); $datetime_format = get_string('datetime_format', 'dhexport_version1elis'); $extra_data = array(); foreach ($this->customfield_data as $fieldid => $fieldrec) { $fieldkey = 'field_' . $fieldid; if (isset($this->enabled_fields[$fieldkey])) { $field_recparam = 'custom_field_' . $fieldid; if (isset($record->{$field_recparam}) || $record->{$field_recparam} === null) { $field = new field($fieldrec); $value = $record->{$field_recparam}; // Set field to default data if no data present. if ($value === null) { $value = $field->get_default(); } // Handle multivalue fields. if ($this->customfield_multivaluestatus[$field->id] !== static::MULTIVALUE_NONE) { $context = \local_elisprogram\context\user::instance($record->userid); $data = field_data::get_for_context_and_field($context, $field); if ($this->customfield_multivaluestatus[$field->id] == static::MULTIVALUE_ENABLED) { $parts = array(); foreach ($data as $datum) { $parts[] = $datum->data; } $value = implode(' / ', $parts); } else { $value = $data->current()->data; } } // Display datetime fields as formatted date/time. if ($field->owners['manual']->param_control === 'datetime') { if ($value == 0) { // Use a marker to indicate that it's not set. $value = get_string('nodatemarker', 'dhexport_version1elis'); } else { if ($field->owners['manual']->param_inctime) { // Date and time. $value = date($datetime_format, $value); } else { // Just date. $value = date($date_format, $value); } } } // Remove html from text. $control = $field->owners['manual']->param_control; if ($control === 'text' || $control === 'textarea') { $value = trim(html_to_text($value), "\n\r"); } $extra_data[$fieldkey] = $value; } } } return $extra_data; }
public function update() { $result = parent::update(); $result = $result && field_data::set_for_context_from_datarecord('curriculum', $this); // If this setting is changed, we need to update the existing curriclum expiration values (ELIS-1172) if ($rs = get_recordset_select(CURASSTABLE, "timeexpired != 0 AND curriculumid = {$this->id}", '', 'id, userid')) { $timenow = time(); while ($curass = rs_fetch_next_record($rs)) { $update = new stdClass(); $update->id = $curass->id; $update->timeexpired = calculate_curriculum_expiry(NULL, $this->id, $curass->userid); $update->timemodified = $timenow; update_record(CURASSTABLE, $update); } rs_close($rs); } return $result; }
/** * Convenience function for use by datarecord objects */ function set_for_context_from_datarecord($level, $record) { global $CURMAN; $contextlevel = context_level_base::get_custom_context_level($level, 'block_curr_admin'); if (!$contextlevel) { // context levels not set up -- we must be in initial installation, // so no fields set up return true; } $context = get_context_instance($contextlevel, $record->id); $fields = field::get_for_context_level($contextlevel); $fields = $fields ? $fields : array(); foreach ($fields as $field) { $fieldname = "field_{$field->shortname}"; if (isset($record->{$fieldname})) { field_data::set_for_context_and_field($context, new field($field), $record->{$fieldname}); } } return true; }
/** * Takes a record and transforms it into an appropriate format * This method is set up as a hook to be implented by actual report class * * @param stdClass $record The current report record * @param string $export_format The format being used to render the report * * @return stdClass The reformatted record */ function transform_record($record, $export_format) { $record->associatedcluster = empty($record->associatedcluster) ? get_string('no') : get_string('yes'); //make sure this is set to something so that the horizontal bar graph doesn't disappear if (empty($record->stucompletedprogress)) { $record->stucompletedprogress = 0; } if (isset($record->studentspassing) && isset($record->numstudents) && $record->numstudents > 0) { $record->studentspassing = round($record->studentspassing / $record->numstudents * 100) . '%'; } //TBD: following block doesn't appear to do anything!?!? $a = new stdClass(); if (isset($record->stucompletedprogress)) { $a->value = $record->stucompletedprogress; $a->total = $record->numprogress; } else { $a->value = 0; $a->total = 0; } // Check for unset fields for N/A display of progress or students passing if (!isset($record->studentspassing)) { $record->studentspassing = get_string('na', 'rlreport_course_progress_summary'); } // We must manually get multi-valued custom field data // Since report SQL requires COUNTs & SUMs $filter_params = php_report_filtering_get_active_filter_values($this->get_report_shortname(), 'field' . $this->get_report_shortname(), $this->filter); $filter_params = $filter_params[0]['value']; $filter_params = $filter_params ? explode(',', $filter_params) : array(); if (isset($filter_params) && is_array($filter_params)) { foreach ($filter_params as $custom_course_id) { $custom_course_field = new field($custom_course_id); if ($custom_course_field->multivalued) { $context = \local_elisprogram\context\course::instance($record->courseid); $field_data = "custom_data_{$custom_course_id}"; $record->{$field_data} = ''; $datarecs = field_data::get_for_context_and_field($context, $custom_course_field, false); foreach ($datarecs as $rec) { if (!empty($record->{$field_data})) { $record->{$field_data} .= $this->get_multivalued_separator($export_format); } $record->{$field_data} .= $rec->data; } if (empty($record->{$field_data})) { unset($record->{$field_data}); } } } } // Default values for custom fields IF not set foreach ($this->field_default as $key => $value) { // error_log("CPSR:transform_record(), checking default for {$key} => {$value}"); if (!isset($record->{$key})) { $record->{$key} = $this->format_default_data($value); } } return $record; }
function update() { $result = parent::update(); $result = $result && field_data::set_for_context_from_datarecord('track', $this); return $result; }
/** * Update environments and environment assignments to custom fields and * custom field data (run as a one-off during the elis program upgrade) * * If there are one or more entities (courses, classes) with environments * assigned to them, a new category and custom field is created, specific to the * appropriate context level. Then, that custom field is populated for each entity * that has and environment assigned (custom field is a single-select, where the options * are all the different environments on the site). */ function pm_migrate_environments() { global $DB; require_once elis::lib('data/customfield.class.php'); require_once elispm::lib('data/course.class.php'); require_once elispm::lib('data/pmclass.class.php'); //set up our contextlevel mapping $contextlevels = array(course::TABLE => 'course', pmclass::TABLE => 'class'); //lookup on all tags $environment_lookup = $DB->get_records('local_elisprogram_env', null, '', 'id, name'); foreach ($environment_lookup as $id => $environment) { $environment_lookup[$id] = $environment->name; } //go through each contextlevel and look for tags foreach ($contextlevels as $instancetable => $contextname) { //calculate the context level integer $contextlevel = \local_eliscore\context\helper::get_level_from_name($contextname); //make sure one or more environments are used at the current context level $select = 'environmentid != 0'; if ($DB->record_exists_select($instancetable, $select)) { //used to reference the category name $category = new field_category(array('name' => get_string('misc_category', 'local_elisprogram'))); //make sure our field for storing environments is created $field = new field(array('shortname' => "_19upgrade_{$contextname}_environment", 'name' => get_string('environment', 'local_elisprogram'), 'datatype' => 'char')); $field = field::ensure_field_exists_for_context_level($field, $contextlevel, $category); //determine environment options $options = array(); if ($records = $DB->get_recordset('local_elisprogram_env', null, 'name', 'DISTINCT name')) { foreach ($records as $record) { $options[] = $record->name; } } $options = implode("\n", $options); //set up our field owner field_owner::ensure_field_owner_exists($field, 'manual', array('control' => 'menu', 'options' => $options, 'edit_capability' => '', 'view_capability' => '')); //set up data for all relevant entries $sql = "SELECT id, environmentid\n FROM {{$instancetable}}\n WHERE environmentid != 0"; if ($records = $DB->get_recordset_sql($sql)) { foreach ($records as $record) { $contextlevel = \local_eliscore\context\helper::get_level_from_name($contextname); $contextclass = \local_eliscore\context\helper::get_class_for_level($contextlevel); $context = $contextclass::instance($record->id); $environmentid = $environment_lookup[$record->environmentid]; field_data::set_for_context_and_field($context, $field, $environmentid); } } } } }
function action_editfield() { global $CURMAN; $level = $this->required_param('level', PARAM_ACTION); $ctxlvl = context_level_base::get_custom_context_level($level, 'block_curr_admin'); if (!$ctxlvl) { print_error('invalid_context_level', 'block_curr_admin'); } $id = $this->optional_param('id', NULL, PARAM_INT); require_once CURMAN_DIRLOCATION . '/form/customfieldform.class.php'; $tmppage = new customfieldpage(array('level' => $level, 'action' => 'editfield'), $this); $form = new customfieldform($tmppage->get_moodle_url(), $this); if ($form->is_cancelled()) { $tmppage = new customfieldpage(array('level' => $level)); redirect($tmppage->get_url(), get_string('edit_cancelled', 'block_curr_admin')); } else { if ($data = $form->get_data()) { $field = new field($data); if ($id) { $field->id = $id; $field->update(); } else { $field->add(); // assume each field only belongs to one context level (for now) $fieldcontext = new field_contextlevel(); $fieldcontext->fieldid = $field->id; $fieldcontext->contextlevel = $ctxlvl; $fieldcontext->add(); } //don't use !empty here because we might be storing a 0 or similar value if ($data->defaultdata != '') { // save the default value $defaultdata = $data->defaultdata; if ($field->multivalued) { // parse as a CSV string // until we can use str_getcsv from PHP 5.3... $temp = fopen("php://memory", "rw"); fwrite($temp, $defaultdata); rewind($temp); $defaultdata = fgetcsv($temp); fclose($temp); } field_data::set_for_context_and_field(NULL, $field, $defaultdata); } else { if ($field->multivalued) { field_data::set_for_context_and_field(NULL, $field, array()); } else { field_data::set_for_context_and_field(NULL, $field, NULL); } } $plugins = get_list_of_plugins('curriculum/plugins'); foreach ($plugins as $plugin) { if (is_readable(CURMAN_DIRLOCATION . '/plugins/' . $plugin . '/custom_fields.php')) { include_once CURMAN_DIRLOCATION . '/plugins/' . $plugin . '/custom_fields.php'; if (function_exists("{$plugin}_field_save_form_data")) { call_user_func("{$plugin}_field_save_form_data", $form, $field, $data); } } } $tmppage = new customfieldpage(array('level' => $level)); redirect($tmppage->get_url(), get_string('field_saved', 'block_curr_admin', $field)); } else { if (!empty($id)) { if ($this->optional_param('from', NULL, PARAM_CLEAN) == 'moodle' && $level == 'user') { $moodlefield = $CURMAN->db->get_record('user_info_field', 'id', $id); if (!$moodlefield) { print_error('invalidfieldid', 'block_curr_admin'); } unset($moodlefield->id); $data_array = (array) $moodlefield; $data_array['datatype'] = 'text'; $data_array['manual_field_control'] = $moodlefield->datatype; switch ($moodlefield->datatype) { case field::checkbox: $data_array['datatype'] = 'bool'; break; case field::menu: $data_array['datatype'] = 'char'; $data_array['manual_field_options'] = $moodlefield->param1; break; case field::textarea: $data_array['manual_field_columns'] = $moodlefield->param1; $data_array['manual_field_rows'] = $moodlefield->param2; break; case field::text: if ($moodlefield->param3) { $data_array['manual_field_control'] = 'password'; } $data_array['manual_field_columns'] = $moodlefield->param1; $data_array['manual_field_maxlength'] = $moodlefield->param2; break; } } else { $data = new field($id); $data_array = $data->to_array(); $defaultdata = field_data::get_for_context_and_field(NULL, $data); if (!empty($defaultdata)) { if ($data->multivalued) { $values = array(); // extract the data foreach ($defaultdata as $data) { $values[] = $data->data; } // represent as a CSV string $fh = fopen("php://memory", "rw"); fputcsv($fh, $values); rewind($fh); $defaultdata = fgets($fh); fclose($fh); } else { $defaultdata = current($defaultdata); $defaultdata = $defaultdata->data; } } $data_array['defaultdata'] = $defaultdata; $plugins = get_list_of_plugins('curriculum/plugins'); foreach ($plugins as $plugin) { if (is_readable(CURMAN_DIRLOCATION . '/plugins/' . $plugin . '/custom_fields.php')) { include_once CURMAN_DIRLOCATION . '/plugins/' . $plugin . '/custom_fields.php'; if (function_exists("{$plugin}_field_get_form_data")) { $data_array += call_user_func("{$plugin}_field_get_form_data", $form, $data); } } } } $form->set_data($data_array); } $form->display(); } } }