Skip to content

Commit

Permalink
MDL-45469 Conditional availability: Restrict by text area broken
Browse files Browse the repository at this point in the history
It has never worked, because the data for text area fields is not
loaded into the $USER object.

Changing it so that the dropdown list does not include these types
of field.
  • Loading branch information
sammarshallou committed May 19, 2014
1 parent a929fd5 commit abdbfc7
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 3 deletions.
15 changes: 12 additions & 3 deletions availability/condition/profile/classes/condition.php
Expand Up @@ -292,14 +292,23 @@ protected static function is_field_condition_met($operator, $uservalue, $value)
* Gets data about custom profile fields. Cached statically in current
* request.
*
* This only includes fields which can be tested by the system (those whose
* data is cached in $USER object) - basically doesn't include textarea type
* fields.
*
* @return array Array of records indexed by shortname
*/
public static function get_custom_profile_fields() {
global $DB;
global $DB, $CFG;

if (self::$customprofilefields === null) {
self::$customprofilefields = $DB->get_records('user_info_field', null,
'id ASC', 'shortname, id, name, defaultdata');
// Get fields and store them indexed by shortname.
require_once($CFG->dirroot . '/user/profile/lib.php');
$fields = profile_get_custom_fields(true);
self::$customprofilefields = array();
foreach ($fields as $field) {
self::$customprofilefields[$field->shortname] = $field;
}
}
return self::$customprofilefields;
}
Expand Down
23 changes: 23 additions & 0 deletions availability/condition/profile/tests/condition_test.php
Expand Up @@ -317,6 +317,29 @@ public function test_is_available() {
$this->assertTrue($cond->is_available(false, $info, true, $user->id));
}

/**
* Tests what happens with custom fields that are text areas. These should
* not be offered in the menu because their data is not included in user
* object
*/
public function test_custom_textarea_field() {
global $USER, $SITE, $DB;
$this->setAdminUser();
$info = new \core_availability\mock_info();

// Add custom textarea type.
$DB->insert_record('user_info_field', array(
'shortname' => 'longtext', 'name' => 'Long text', 'categoryid' => 1,
'datatype' => 'textarea'));
$customfield = $DB->get_record('user_info_field',
array('shortname' => 'longtext'));

// The list of fields should include the text field added in setUp(),
// but should not include the textarea field added just now.
$fields = condition::get_custom_profile_fields();
$this->assertEquals(array('frogtype'), array_keys($fields));
}

/**
* Sets the custom profile field used for testing.
*
Expand Down
36 changes: 36 additions & 0 deletions user/profile/lib.php
Expand Up @@ -572,6 +572,42 @@ function profile_user_record($userid) {
return $usercustomfields;
}

/**
* Obtains a list of all available custom profile fields, indexed by id.
*
* Some profile fields are not included in the user object data (see
* profile_user_record function above). Optionally, you can obtain only those
* fields that are included in the user object.
*
* To be clear, this function returns the available fields, and does not
* return the field values for a particular user.
*
* @param bool $onlyinuserobject True if you only want the ones in $USER
* @return array Array of field objects from database (indexed by id)
* @since Moodle 2.7.1
*/
function profile_get_custom_fields($onlyinuserobject = false) {
global $DB, $CFG;

// Get all the fields.
$fields = $DB->get_records('user_info_field', null, 'id ASC');

// If only doing the user object ones, unset the rest.
if ($onlyinuserobject) {
foreach ($fields as $id => $field) {
require_once($CFG->dirroot . '/user/profile/field/' .
$field->datatype . '/field.class.php');
$newfield = 'profile_field_' . $field->datatype;
$formfield = new $newfield();
if (!$formfield->is_user_object_data()) {
unset($fields[$id]);
}
}
}

return $fields;
}

/**
* Load custom profile fields into user object
*
Expand Down
88 changes: 88 additions & 0 deletions user/profile/tests/profilelib_test.php
@@ -0,0 +1,88 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Unit tests for user/profile/lib.php.
*
* @package core_user
* @copyright 2014 The Open University
* @licensehttp://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();

global $CFG;
require_once($CFG->dirroot . '/user/profile/lib.php');

/**
* Unit tests for user/profile/lib.php.
*
* @package core_user
* @copyright 2014 The Open University
* @licensehttp://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_user_profilelib_testcase extends advanced_testcase {
/**
* Tests profile_get_custom_fields function and checks it is consistent
* with profile_user_record.
*/
public function test_get_custom_fields() {
global $DB;

$this->resetAfterTest();
$user = $this->getDataGenerator()->create_user();

// Check function with no custom fields.
$this->assertEquals(array(), profile_get_custom_fields());

// Check that profile_user_record returns same (no) fields.
$this->assertEquals(array(), array_keys((array)profile_user_record($user->id)));

// Add a custom field of textarea type.
$id1 = $DB->insert_record('user_info_field', array(
'shortname' => 'frogdesc', 'name' => 'Description of frog', 'categoryid' => 1,
'datatype' => 'textarea'));

// Check the field is returned.
$result = profile_get_custom_fields();
$this->assertEquals(array($id1), array_keys($result));
$this->assertEquals('frogdesc', $result[$id1]->shortname);

// Textarea types are not included in user data though, so if we
// use the 'only in user data' parameter, there is still nothing.
$this->assertEquals(array(), profile_get_custom_fields(true));

// Check that profile_user_record returns same (no) fields.
$this->assertEquals(array(), array_keys((array)profile_user_record($user->id)));

// Add another custom field, this time of normal text type.
$id2 = $DB->insert_record('user_info_field', array(
'shortname' => 'frogname', 'name' => 'Name of frog', 'categoryid' => 1,
'datatype' => 'text'));

// Check both are returned using normal option.
$result = profile_get_custom_fields();
$this->assertEquals(array($id1, $id2), array_keys($result));
$this->assertEquals('frogname', $result[$id2]->shortname);

// And check that only the one is returned the other way.
$result = profile_get_custom_fields(true);
$this->assertEquals(array($id2), array_keys($result));

// Check profile_user_record returns same field.
$this->assertEquals(array('frogname'), array_keys((array)profile_user_record($user->id)));
}
}

0 comments on commit abdbfc7

Please sign in to comment.