MDL-14460, fix get_context_instance, merged from MOODLE_19_STABLE, see tracker.
[moodle.git] / user / profile / lib.php
1 <?php //$Id$
3 /// Some constants
5 define ('PROFILE_VISIBLE_ALL',     '2'); // only visible for users with moodle/user:update capability
6 define ('PROFILE_VISIBLE_PRIVATE', '1'); // either we are viewing our own profile or we have moodle/user:update capability
7 define ('PROFILE_VISIBLE_NONE',    '0'); // only visible for moodle/user:update capability
11 /**
12  * Base class for the cusomisable profile fields.
13  */
14 class profile_field_base {
16     /// These 2 variables are really what we're interested in.
17     /// Everything else can be extracted from them
18     var $fieldid;
19     var $userid;
20     
21     var $field;
22     var $inputname;
23     var $data;
25     /**
26      * Constructor method.
27      * @param   integer   id of the profile from the user_info_field table
28      * @param   integer   id of the user for whom we are displaying data
29      */
30     function profile_field_base($fieldid=0, $userid=0) {
31         global $USER;
33         $this->set_fieldid($fieldid);
34         $this->set_userid($userid);
35         $this->load_data();
36     }
39 /***** The following methods must be overwritten by child classes *****/
41     /**
42      * Abstract method: Adds the profile field to the moodle form class
43      * @param  form  instance of the moodleform class
44      */
45     function edit_field_add(&$mform) {
46         print_error('This abstract method must be overriden');
47     }
49     
50 /***** The following methods may be overwritten by child classes *****/
52     /**
53      * Display the data for this field
54      */
55     function display_data() {
56         $options->para = false;
57         return format_text($this->data, FORMAT_MOODLE, $options);
58     }
59     
60     /**
61      * Print out the form field in the edit profile page
62      * @param   object   instance of the moodleform class
63      * $return  boolean
64      */
65     function edit_field(&$mform) {
67         if ($this->field->visible != PROFILE_VISIBLE_NONE
68           or has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM))) {
70             $this->edit_field_add($mform);
71             $this->edit_field_set_default($mform);
72             $this->edit_field_set_required($mform);
73             $this->edit_field_set_locked($mform);
74         }
75     }
77     /**
78      * Saves the data coming from form
79      * @param   mixed   data coming from the form
80      * @return  mixed   returns data id if success of db insert/update, false on fail, 0 if not permitted
81      */
82     function edit_save_data($usernew) {
84         if (!isset($usernew->{$this->inputname})) {
85             // field not present in form, probably locked and invisible - skip it
86             return;
87         }
88         
89         $usernew->{$this->inputname} = $this->edit_save_data_preprocess($usernew->{$this->inputname});
91         $data = new object();
92         $data->userid  = $usernew->id;
93         $data->fieldid = $this->field->id;
94         $data->data    = $usernew->{$this->inputname};
96         if ($dataid = get_field('user_info_data', 'id', 'userid', $data->userid, 'fieldid', $data->fieldid)) {
97             $data->id = $dataid;
98             if (!update_record('user_info_data', $data)) {
99                 print_error('Error updating custom profile field!');
100             }
101         } else {
102             insert_record('user_info_data', $data);
103         }
104     }
106     /**
107      * Validate the form field from profile page
108      * @return  string  contains error message otherwise NULL
109      **/
110     function edit_validate_field($usernew) {
111         //no errors by default
112         return array();
113     }
115     /**
116      * Sets the default data for the field in the form object
117      * @param   object   instance of the moodleform class
118      */
119     function edit_field_set_default(&$mform) {
120         if (!empty($default)) {
121             $mform->setDefault($this->inputname, $this->field->defaultdata);
122         }
123     }
125     /**
126      * Sets the required flag for the field in the form object
127      * @param   object   instance of the moodleform class
128      */
129     function edit_field_set_required(&$mform) {
130         if ($this->is_required() and !has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM))) {
131             $mform->addRule($this->inputname, get_string('required'), 'required', null, 'client');
132         }
133     }
135     /**
136      * HardFreeze the field if locked.
137      * @param   object   instance of the moodleform class
138      */
139     function edit_field_set_locked(&$mform) {
140         if ($this->is_locked() and !has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM))) {
141             $mform->hardFreeze($this->inputname);
142         }
143     }
145     /**
146      * Hook for child classess to process the data before it gets saved in database
147      * @param   mixed
148      * @return  mixed
149      */
150     function edit_save_data_preprocess($data) {
151         return $data;
152     }
154     /**
155      * Loads a user object with data for this field ready for the edit profile
156      * form
157      * @param   object   a user object
158      */
159     function edit_load_user_data(&$user) {
160         if ($this->data !== NULL) {
161             $user->{$this->inputname} = $this->data;
162         }
163     }
165     /**
166      * Check if the field data should be loaded into the user object
167      * By default it is, but for field types where the data may be potentially
168      * large, the child class should override this and return false
169      * @return boolean
170      */
171     function is_user_object_data() {
172         return true;
173     }
176 /***** The following methods generally should not be overwritten by child classes *****/
177    
178     /**
179      * Accessor method: set the userid for this instance
180      * @param   integer   id from the user table
181      */
182     function set_userid($userid) {
183         $this->userid = $userid;
184     }
186     /**
187      * Accessor method: set the fieldid for this instance
188      * @param   integer   id from the user_info_field table
189      */
190     function set_fieldid($fieldid) {
191         $this->fieldid = $fieldid;
192     }
194     /**
195      * Accessor method: Load the field record and user data associated with the
196      * object's fieldid and userid
197      */
198     function load_data() {
199         /// Load the field object
200         if (($this->fieldid == 0) or (!($field = get_record('user_info_field', 'id', $this->fieldid)))) {
201             $this->field = NULL;
202             $this->inputname = '';
203         } else {
204             $this->field = $field;
205             $this->inputname = 'profile_field_'.$field->shortname;
206         }
208         if (!empty($this->field)) {
209             if ($datafield = get_field('user_info_data', 'data', 'userid', $this->userid, 'fieldid', $this->fieldid)) {
210                 $this->data = $datafield;
211             } else {
212                 $this->data = $this->field->defaultdata;
213             }
214         } else {
215             $this->data = NULL;
216         }
217     }
219     /**
220      * Check if the field data is visible to the current user
221      * @return  boolean
222      */
223     function is_visible() {
224         global $USER;
226         switch ($this->field->visible) {
227             case PROFILE_VISIBLE_ALL:
228                 return true;
229             case PROFILE_VISIBLE_PRIVATE:
230                 return ($this->userid == $USER->id);
231             default:
232                 return has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM));
233         }
234     }
236     /**
237      * Check if the field data is considered empty
238      * return boolean
239      */
240     function is_empty() {
241         return ( ($this->data != '0') and empty($this->data));
242     }
244     /**
245      * Check if the field is required on the edit profile page
246      * @return   boolean
247      */
248     function is_required() {
249         return (boolean)$this->field->required;
250     }
252     /**
253      * Check if the field is locked on the edit profile page
254      * @return   boolean
255      */
256     function is_locked() {
257         return (boolean)$this->field->locked;
258     }
260     /**
261      * Check if the field data should be unique
262      * @return   boolean
263      */
264     function is_unique() {
265         return (boolean)$tihs->field->forceunique;
266     }
268     /**
269      * Check if the field should appear on the signup page
270      * @return   boolean
271      */
272     function is_signup_field() {
273         return (boolean)$this->field->signup;
274     }
275      
277 } /// End of class definition
280 /***** General purpose functions for customisable user profiles *****/
282 function profile_load_data(&$user) {
283     global $CFG;
285     if ($fields = get_records_select('user_info_field')) {
286         foreach ($fields as $field) {
287             require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
288             $newfield = 'profile_field_'.$field->datatype;
289             $formfield = new $newfield($field->id, $user->id);
290             $formfield->edit_load_user_data($user);
291         }
292     }
295 /**
296  * Print out the customisable categories and fields for a users profile
297  * @param  object   instance of the moodleform class
298  */
299 function profile_definition(&$mform) {
300     global $CFG;
302     if ($categories = get_records_select('user_info_category', '', 'sortorder ASC')) {
303         foreach ($categories as $category) {
304             if ($fields = get_records_select('user_info_field', "categoryid=$category->id", 'sortorder ASC')) {
305                 $mform->addElement('header', 'category_'.$category->id, format_string($category->name));
306                 foreach ($fields as $field) {
307                     require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
308                     $newfield = 'profile_field_'.$field->datatype;
309                     $formfield = new $newfield($field->id);
310                     $formfield->edit_field($mform);
312                 }
313             }
314         }
315     }
318 function profile_definition_after_data(&$mform) {
319     global $CFG;
320 /*
321     if ($fields = get_records('user_info_field')) {
322         foreach ($fields as $field) {
323             require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
324             $newfield = 'profile_field_'.$field->datatype;
325             $formfield = new $newfield($field->id);
326 //TODO add: method into field class
328         }
329     }*/
332 function profile_validation($usernew, $files) {
333     global $CFG;
335     $err = array();
336     if ($fields = get_records('user_info_field')) {
337         foreach ($fields as $field) {
338             require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
339             $newfield = 'profile_field_'.$field->datatype;
340             $formfield = new $newfield($field->id, $usernew->id);
341             $err += $formfield->edit_validate_field($usernew, $files);
342         }
343     }
344     return $err;
347 function profile_save_data($usernew) {
348     global $CFG;
350     if ($fields = get_records_select('user_info_field')) {
351         foreach ($fields as $field) {
352             require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
353             $newfield = 'profile_field_'.$field->datatype;
354             $formfield = new $newfield($field->id, $usernew->id);
355             $formfield->edit_save_data($usernew);
356         }
357     }
360 function profile_display_fields($userid) {
361     global $CFG, $USER;
363     if ($categories = get_records_select('user_info_category', '', 'sortorder ASC')) {
364         foreach ($categories as $category) {
365             if ($fields = get_records_select('user_info_field', "categoryid=$category->id", 'sortorder ASC')) {
366                 foreach ($fields as $field) {
367                     require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
368                     $newfield = 'profile_field_'.$field->datatype;
369                     $formfield = new $newfield($field->id, $userid);
370                     if ($formfield->is_visible() and !$formfield->is_empty()) {
371                         print_row(s($formfield->field->name.':'), $formfield->display_data());
372                     }
373                 }
374             }
375         }
376     }
379 /**
380  * Adds code snippet to a moodle form object for custom profile fields that
381  * should appear on the signup page
382  * @param  object  moodle form object
383  */
384 function profile_signup_fields(&$mform) {
385     global $CFG;
386     
387     if ($fields = get_records('user_info_field', 'signup', 1, 'sortorder ASC')) {
388         foreach ($fields as $field) {
389             require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
390             $newfield = 'profile_field_'.$field->datatype;
391             $formfield = new $newfield($field->id);
392             $formfield->edit_field($mform);
393         }
394     }
397 /**
398  * Returns an object with the custom profile fields set for the given user
399  * @param  integer  userid
400  * @return  object
401  */
402 function profile_user_record($userid) {
403     global $CFG;
405     $user = new object();
407     if ($fields = get_records_select('user_info_field')) {
408         foreach ($fields as $field) {
409             require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
410             $newfield = 'profile_field_'.$field->datatype;
411             $formfield = new $newfield($field->id, $userid);
412             if ($formfield->is_user_object_data()) $user->{$field->shortname} = $formfield->data;
413         }
414     }
416     return $user;
420 ?>