Databases: Custom User Profile Field as a date (not text)

Databases: Custom User Profile Field as a date (not text)

by Iver Johnson -
Number of replies: 8
Has anyone added a field type to the default four types (checkbox, text, textarea, menu) for adding User Profile Fields? I need to have field type of date, so I can run queries on the data to find approaching or past expiration dates for certifications.

It appears the current four options are in the moodle/user/profile/field folder.

Any assistance would be greatly appreciated!
Average of ratings: -
In reply to Iver Johnson

Re: Databases: Custom User Profile Field as a date (not text)

by Mich P -
+1
In reply to Mich P

Re: Databases: Custom User Profile Field as a date (not text)

by Sean Farrell -
Iver, Mitch,

You mentioned on the moodle databases forum a while back that you were looking for a date field in the user profile.

I meant to get around to passing on some code for a date format field. I am currently using this field type to store, display and upload date information.

The code below allows the viewing format to be configured for each field. However , the editing/input format and csv/upload format is currently set to dd/mm/YYYY in the code. There are comments included on where it needs to be changed to suit other situations.

The processing of dates when uploaded as part of a bulk user upload into this field type also needs some attention to getting the date format right in the CSV file.

If you find it useful, or think it would be worth polishing up the field definition to make the input format more configurable then do let me know.

--
Sean Farrell

user/profile/field/date/define.class.php:

<?php //$Id$
// date format field v0.2
// Sean Farrell, Scottish Universities Physics Alliance, Aug 2008

class profile_define_date extends profile_define_base {

 function define_form_specific(&$form) {
 /// Default data
 $form->addElement('text', 'defaultdata', get_string('profiledefaultdata', 'admin'), 'size="50"');
 $form->setType('defaultdata', PARAM_MULTILANG);

 /// Param 1 date format for displaying the date

// change to "D d/m/Y H:i" for date/time hour:minute

 $form->addElement('text', 'param1', 'Date display format eg. "D d/m/Y" means dayname dd/mm/yyyy <a href="http://uk.php.net/date">syntax</a>', 'size="6"');
 $form->setDefault('param1', 'D d/m/Y');
 $form->setType('param1', PARAM_RAW);


 // TODO use this parameter to select input format eg. order of the dropdowns, and also the CSV upload format.
 // need to rewite a bit, perhaps a selection of dmY, mdY, Ymd etc.

 // at the moment this is hard coded to dd/mm/YYYY,
 // and to processing of uploaded stuff depends on a PHP5 function

 // $form->addElement('text', 'param2', 'Date entry order dmY mdY or Ymd. Also affects how dates are parsed on user upload', 'size="6"');
 // $form->setDefault('param2', '%d/%m/%Y');
 // $form->setType('param2', PARAM_INT);

 /// Param 3 for text type detemines if this is a password field or not
 $form->addElement('selectyesno', 'param2', 'Allow no-value "disable" checkbox');
 $form->setDefault('param2', 0); // defaults to 'no'
 $form->setType('param2', PARAM_INT);
 }

}

?>

field.class.php

<?php //$Id$
// date format field v0.2
// Sean Farrell, Scottish Universities Physics Alliance, Aug 2008

class profile_field_date extends profile_field_base {

 function edit_field_add(&$mform) {
 $dateformat = $this->field->param1;
 // $input = $this->field->param2;

 $fieldtype = 'date_selector'; // to include date and time, change to $fieldtype = 'date_time_selector';

 // TODO change the format depending on language
 // mm/dd/yyyy date format
 // $options = array('language'=>'en', 'format'=>'mdY', 'optional' => true, 'addEmptyOption' => true, 'optionIncrement'=>array('i'=>'5'));

 // dd/mm/yyyy date format
 $options = array('language'=>'en', 'format'=>'dmY', 'optional' => true, 'addEmptyOption' => true, 'optionIncrement'=>array('i'=>'5'));
 //$options = array('optional'=>true, 'off'=>($this->data==0))

 /// Create the form field
 $mform->addElement($fieldtype, $this->inputname, $this->field->name, $options);
 }

 /**
 * Display the data for this field
 */
 function display_data() {
 if (empty($this->data) || $this->data == 0 ) {
 return '(not set)';
 } else {
 return date($this->field->param1, $this->data) ;
 }
 }

 /**
 * Overwrites base class accessor method
 * @param integer the key returned from the select input in the form
 */
 function edit_save_data_preprocess($data) {
 // expect a numeric date from date field when the field is used
 // on the profile form. But it is possible that this function may
 // instead be passed a string when uploading from a CSV file

 // not sure what date format excel will pass - it seems to vary depending on local settings,
 // seems to generally be a string formatted in local short date format.

 // if you upload profile field as a number then it needs to be a
 // unix datetime value

 // TODO : give the user control of this in param 2


 if (!is_numeric($data)) {
 $datetime = false;
 // if passed a string try to parse the date using strtodate

 //$formats = array('%d/%m/%Y %H:%M:%S', '%d/%m/%Y', '%Y/%m/%d', '%m/%d/%Y');
 // TODO change this to pick up from param2 eg. dmY, mdY or Ymd


 // mm/dd/yyyy date format
 // $formats = array('%m/%d/%Y', '%m/%d/%y');


 // dd/mm/yyyy date format
 $formats = array('%d/%m/%Y', '%d/%m/%y');


 // TODO rewrite this so that it explodes the date into parts and
 // does this for a fixed list of date formats.

 // TODO do something so that this works in PHP4 ... there are some
 // functions which replace this where built in strptime is not available

 foreach ($formats as $format) {
 if ($datetime === false) {
 $dt = strptime($data, $format);
 if ($dt !== false) {
 if (is_array($dt) && $dt['unparsed']=='') {
 $datetime = mktime(
 $dt['tm_hour'],
 $dt['tm_min'],
 $dt['tm_sec'],
 $dt['tm_mon']+1,
 $dt['tm_mday'],
 $dt['tm_year']+1900);
 print_r($dt);
 } // else {
 // debugging:
 // print_r($dt);
 // trigger_error('unparsed != ""',E_USER_WARNING);
 // }

 }
 }
 }
 if ($datetime === false) {
 trigger_error('failed to parse date',E_USER_WARNING);
 $datetime = $data;
 }
 } else {
 $datetime = $data;
 }

 return $datetime;

 }

}


?>
Average of ratings: Useful (1)
In reply to Sean Farrell

Re: Databases: Custom User Profile Field as a date (not text)

by Iver Johnson -
This is a great start and exactly what we are looking for! Thank you!

I do think it would be worth while to clean this code up a bit and add the alternative formats. Then maybe it can be included in HEAD?
In reply to Sean Farrell

Re: Databases: Custom User Profile Field as a date (not text)

by Anthony Borrow -
Picture of Core developers Picture of Plugin developers Picture of Testers
Those interested in getting the custom user profile field data validated may want to watch, vote, and comment on MDL-12619. I have added a comment to that issue referencing this discussion thread. Peace - Anthony
In reply to Sean Farrell

Re: Databases: Custom User Profile Field as a date (not text)

by Aaron McEntire -
This is great! I'd love to use this but I have two issues. First, the year only goes back to 1970, and I'd like to go back farther and second, I can't seem to get the disable checkbox to default to unchecked despite the setting.

Any feedback would be appreciated!
In reply to Iver Johnson

Re: Databases: Custom User Profile Field as a date (not text)

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
I remember seeing something about this recently, but I can't remember what. Try asking Google.
In reply to Tim Hunt

Re: Databases: Custom User Profile Field as a date (not text)

by Iver Johnson -
I have searched Google, but haven't found any answers. Has anyone been able to do this?
In reply to Iver Johnson

Re: Databases: Custom User Profile Field as a date (not text)

by Anthony Borrow -
Picture of Core developers Picture of Plugin developers Picture of Testers
Iver - Currently there is not; however, it is related to MDL-12619 to allow such things. I came across a similar issue when creating the birthday block. Feel free to watch and/or vote on the issue in the tracker. Peace - Anthony