/** * Initialize internal customfield data - records, SELECT fragments, and additional joins. * * @return bool Success/Failure */ protected function init_customfield_data() { global $DB; if (!empty($this->customfield_data)) { return true; } $fieldids = array(); foreach ($this->enabled_fields as $field => $name) { if (strpos($field, 'field_') === 0) { $fieldid = substr($field, strlen('field_')); if (is_numeric($fieldid)) { $fieldids[] = $fieldid; } } } if (!empty($fieldids)) { $select = 'id IN (' . implode(',', array_fill(0, count($fieldids), '?')) . ')'; $this->customfield_data = $DB->get_records_select(field::TABLE, $select, $fieldids); } foreach ($this->customfield_data as $fieldid => $record) { $field = new field($record); $multivaluestatus = $this->init_multivalue_status_for_field($record->id, $record->multivalued); // Add joins and select entries, if field is enabled. if (isset($this->enabled_fields['field_' . $fieldid])) { if ($multivaluestatus === static::MULTIVALUE_NONE) { // Extra columns we'll need to display profile field values. $this->sql_select[] = "custom_data_{$field->id}.data AS custom_field_{$field->id}"; // Extra joins we'll need to display profile field values. $field_data_table = "field_data_" . $field->data_type(); $this->sql_joins[] = "LEFT JOIN {" . $field_data_table::TABLE . "} custom_data_{$field->id}\n ON custom_data_{$field->id}.fieldid = {$field->id}\n AND " . static::FIELDSET_NAME . "_ctx.id = custom_data_{$field->id}.contextid\n AND custom_data_{$field->id}.contextid IS NOT NULL"; } else { // Extra columns we'll need to display profile field values. $this->sql_select[] = "'' AS custom_field_{$field->id}"; } } } return true; }
/** * Get custom fields * * This function returns an array of custom field names to labels, and has a few side effects * that set up data to use the custom fields later. The side effects reduce the number of * database lookups required to generate the form. * * @param array $fields An array of db records representing custom fields * @return array Custom field names mapped to labels. */ function get_custom_fields($group, $fields) { $yesno = array(1 => get_string('yes'), 0 => get_string('no')); // Array $xoptions to append to existing options['choices'] $options = array(); if (!$fields instanceof Iterator) { $fields = array(); } foreach ($fields as $field) { $field = new field($field); if (!isset($field->owners['manual'])) { error_log("multifilter.php::get_custom_fields() - no field->owners['manual'] for {$field->name} ({$field_identifier})"); continue; } $field_identifier = 'customfield-' . $field->id; $this->_fields[$group][$field_identifier] = $field; $this->record_short_field_name($field_identifier); $this->labels[$group][$field_identifier] = $field->name; $options[$field_identifier] = $field->name; $owner = new field_owner($field->owners['manual']); $params = unserialize($owner->params); //error_log("multifilter.php::get_custom_fields(): {$field_identifier} => {$params['control']} ({$this->datatypemap[$params['control']]})"); $this->fieldtofiltermap[$group][$field_identifier] = $this->datatypemap[$params['control']]; switch ($params['control']) { case 'datetime': // TBD - options required for datetime fields? $this->_choices[$field_identifier] = array('startyear' => $params['startyear'], 'stopyear' => $params['stopyear'], 'inctime' => isset($params['inctime']) ? $params['inctime'] : false); break; case 'checkbox': $this->_choices[$field_identifier] = $yesno; break; case 'menu': $choices = $owner->get_menu_options(); if (!empty($choices)) { $this->_choices[$field_identifier] = array(); foreach ($choices as $key => $choice) { $choice = trim($choice); // preserve anyvalue key => '' //$key = ($key === '') ? $key : $choice; $this->_choices[$field_identifier][$key] = $choice; } } else { error_log("multifilter::get_custom_fields() - empty menu options for fieldid = {$field->id} ... using: Yes, No"); $this->_choices[$field_identifier] = $yesno; } break; case 'text': // fall-thru case! // fall-thru case! case 'textarea': // no options required for text fields break; default: error_log("multifilter.php:: control = {$params['control']}, datatype = {$field->data_type()} not supported"); break; } } $this->sections[$group]['custom'] = $options; }
/** * Validate that multivalue functionality is suppored for all data types when using the * "menu of choices" UI / input type * * @dataProvider data_type_provider * @param string $uitype The string value representing a data type * @param string $data The multi-valued custom field value to use as input * @param array $expected The values to expect in the databaes */ public function test_multivalue_field_data_supports_all_data_types_for_menu_of_choices($datatype, $data, $expected) { global $CFG, $DB; require_once $CFG->dirroot . '/local/elisprogram/lib/setup.php'; require_once elis::lib('data/customfield.class.php'); require_once elispm::lib('data/user.class.php'); // Set up the custom field, category, context association, and owner. // Use "expected" as list of available options. $fieldid = $this->create_test_field('user', $datatype, 'menu', true, $expected, null, null); // Reset the field list. $temp = new user(); $temp->reset_custom_field_list(); // Run the entity create action. $record = array('action' => 'create', 'idnumber' => 'testuseridnumber', 'username' => 'testuserusername', 'password' => 'testuserpassword', 'firstname' => 'testuserfirstname', 'lastname' => 'testuserlastname', 'email' => '*****@*****.**', 'city' => 'testusercity', 'country' => 'CA', 'testfieldshortname' => $data); $importplugin = rlip_dataplugin_factory::factory('dhimport_version1elis'); $importplugin->fslogger = new silent_fslogger(null); $importplugin->process_record('user', (object) $record, 'bogus'); // Validation. $instance = new field(array('datatype' => $datatype)); $realtype = $instance->data_type(); $realdataclass = "field_data_{$realtype}"; $this->assert_field_values('user', user::TABLE, $realdataclass::TABLE, $fieldid, $expected); }