Skip to content

Commit

Permalink
Added new {ifprofile shortname ...}{/ifprofile} tags including:
Browse files Browse the repository at this point in the history
- {ifprofile shortname is value}...{/ifprofile}
- {ifprofile shortname not value}...{/ifprofile}
- {ifprofile shortname is empty}...{/ifprofile}
- {ifprofile shortname not empty}...{/ifprofile}
- {ifprofile shortname contains value}...{/ifprofile}
- {ifprofile shortname in value}...{/ifprofile}

Note: The **shortname** tags can be any visible custom profile fields,
unless the FilterCodes ifprofilefiedonlyvisible setting is unchecked,
as well as the core id, username, auth, idnumber, email, institution,
department, city, country, timezone, and lang core profile fields.
  • Loading branch information
michael-milette committed Jul 20, 2024
1 parent fa535c8 commit e3176c2
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 11 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Change Log
All notable changes to this project will be documented in this file.

## [2.5.2] 2024-07-18 (dev)
## [2.5.2] 2024-07-19 (dev)
### Added
- New {ifuser id|username}{/ifuser} tag.
- New {ifprofile shortname is value}...{/ifprofile} tag.
- New {ifprofile shortname is empty}...{/ifprofile} tag.
- New {ifprofile shortname not value}...{/ifprofile} tag.
- New {ifprofile shortname not empty}...{/ifprofile} tag. Similar to {ifprofile_field_shortname} tag but can't be nested.
- New {ifprofile shortname contains value}...{/ifprofile} tag.
- New {ifprofile shortname in value}...{/ifprofile} tag.
### Updated
- {categories0} tag now shows hidden categories if role has moodle/category:viewhiddencategories.
- {categories0menu} tag now shows hidden categories if role has moodle/category:viewhiddencategories.
Expand Down
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,16 +320,23 @@ Note: {if*rolename*} and {ifmin*rolename*} type tags are based on role archetype

#### Miscellanious

* {ifuser id|username}{/ifuser}: Will display the enclosed content if the the user matches the specified user ID or user name. Recommendation: Use the user's ID because you can rename a username.
* {ifdev}{/ifdev} : Will display the enclosed content only if the user is logged in as an administrator and developer debugging mode is enabled.
* {ifhome}{/ifhome} : Will display the enclosed content only if the user is on the Moodle Home Frontpage.
* {ifnothome}{/ifnothome} : Will not display the enclosed content if the user is on the Moodle Home Frontpage.
* {ifdashboard}{/ifdashboard} : Will display the enclosed content only if the user is on the Moodle Dashboard.
* {ifcourserequests}{/ifcourserequests} : Will display enclosed contents only if the Request a Course feature is enabled.
* {ifeditmode}{/ifeditmode} : Will display the enclosed content only if editing mode is turned on.
* {ifprofile_field_shortname}{/ifprofile_field_shortname} : Will display the enclosed content if the custom user profile field is not blank/zero.
* {iftheme themename}{/iftheme} : Will display enclosed content if the theme specified (theme's directory name) is the one currently used to render the page.
* {ifnottheme themename}{/ifnottheme} : Will display enclosed content if the theme specified (theme's directory name) is NOT the one currently used to render the page.
* {ifprofile_field_shortname}{/ifprofile_field_shortname} : Will display the enclosed content if the custom user profile field is not blank/zero. Only visible custom profile fields are supported unless the FilterCodes ifprofilefiedonlyvisible setting is unchecked. Does not include support for core profile fields like the {ifprofile...} tags mentioned above.
* {ifprofile shortname is value}{/ifprofile} : Will only display the enclosed content if the value of the specified user profile field matches the specified value.
* {ifprofile shortname not value}{/ifprofile} : Will display the specified user profile field is not equal to the specified value.
* {ifprofile shortname is empty}{/ifprofile} : Will only display the specified user profile field is empty. Note, 0 (zero) counts as empty. See note below.
* {ifprofile shortname not empty}{/ifprofile} : Will display the specified user profile field is not empty. Note, a 0 (zero) counts as empty. This is similar to the {ifprofile_field_shortname} tag but can't be nested. See note below.
* {ifprofile shortname contains value}{/ifprofile} : Will only display the enclosed content if the contents of the user profile field is an exact match to the specified value. See note below.
* {ifprofile shortname in value}{/ifprofile} : Will only display the enclosed content if the contents of the user profile field appears in the specified value. See note below.

Note: The **shortname** for {ifprofile **shortname**...} tags can be any visible custom profile fields, unless the FilterCodes ifprofilefiedonlyvisible setting is unchecked, as well as the core 'id', 'username', 'auth', 'idnumber', 'email', 'institution', 'department', 'city', 'country', 'timezone', or 'lang' core profile fields.

If the condition is not met in the particular context, the specified tag and its content will be removed.

Expand Down Expand Up @@ -1174,6 +1181,12 @@ Create a Page on your Moodle site, preferably in a course, so that those tags wo
* If you are logged in as a different user [{ifloggedinas}]: {ifloggedinas}You are logged in as a different user.{/ifloggedinas}
* If you are NOT logged in as a different user [{ifloggedinas}]: {ifnotloggedinas}You are logged in as yourself.{/ifnotloggedinas}
* If Editing mode activated (on) [{ifeditmode}]Don't forget to turn off editing mode![{/ifeditmode}]: {ifeditmode}Don't forget to turn off editing mode!{/ifeditmode}
* Welcome to our [{ifprofile country is CA}]Canadian[{/ifprofile}][{ifprofile country not CA}]international[{/ifprofile}] students. : Welcome to our {ifprofile country is CA}Canadian{/ifprofile}{ifprofile country not CA}international{/ifprofile} students.
* [{ifprofile city is empty}]You must specify a city in your profile.[{/ifprofile}] : {ifprofile city is empty}You must specify a city in your profile.{/ifprofile}
* [{ifprofile city not empty}]Thanks for filling out the city field in your profile.[{/ifprofile}] : {ifprofile city not empty}Thanks for filling out the city field in your profile{/ifprofile}
* [{ifprofile timezone contains 99}]You must set your local time zone field in your profile.[{/ifprofile}] : {ifprofile timezone contains 99}You must set your local time zone field in your profile{/ifprofile}
* [{ifprofile email contains @example.com}]We have additional courses available for example.com customers today.[{/ifprofile}] : {ifprofile email contains @example.com}We have additional courses available for example.com customers today.{/ifprofile}
* [{ifprofile country in CA,US,UK,AU,NZ}]We have many courses available in English[{/ifprofile}] : {ifprofile country in CA,US,UK,AU,NZ}We have many courses available in English{/ifprofile}
* If defined custom user profile field with a shortname called "iswoman" is not blank or zero [{ifprofile_field_iswoman}Female{/ifprofile_field_iswoman}]: {ifprofile_field_iswoman}Female{/ifprofile_field_iswoman}
* If Editing mode is deactivated (off) [{ifnoteditmode}]&lt;a href="{wwwroot}/course/view.php?id={courseid}&sesskey={sesskey}&edit=on"&gt;Turn edit mode on&lt;a/&gt;[{/ifnoteditmode}]: {ifnoteditmode}<a href="{wwwroot}/course/view.php?id={courseid}&sesskey={sesskey}&edit=on">Turn edit mode on</a>{/ifnoteditmode}
* If on the course enrolment page? [{ifenrolpage}]Yes[{/ifenrolpage}]: {ifenrolpage}Yes{/ifenrolpage}
Expand All @@ -1197,7 +1210,6 @@ Create a Page on your Moodle site, preferably in a course, so that those tags wo
* If Developer [{ifdev}]You are an administrator with debugging set to developer mode.[{/ifdev}]: {ifdev}You are an administrator with debugging set to developer mode.{/ifdev}
* If user has a parent custom role [{ifcustomrole parent}]You have a parent custom role in this context[{/ifcustomrole}]: {ifcustomrole parent}You have a parent custom role in this context{/ifcustomrole}.
* If user does not have a parent custom role [{ifnotcustomrole parent}]You do not have a parent custom role in this context[{/ifnotcustomrole}]: {ifnotcustomrole parent}You do not have a parent custom role in this context{/ifnotcustomrole}.
* If a specific user [{ifuser 2}]Hi Admin[{/ifuser}]: {ifuser 2}Hi Admin{/ifuser}.
* The current theme is [{iftheme boost}]Boost[{/iftheme}][{iftheme classic}]Classic[{/iftheme}]: {iftheme boost}Boost{/iftheme}{iftheme classic}Classic{/iftheme}
* The current theme is [{ifnottheme boost}]NOT [{/ifnottheme}]Boost: {ifnottheme boost}NOT {/ifnottheme} Boost.
* If on Home page [{ifhome}]You are on the Home Frontpage.[{/ifhome}]: {ifhome}You are on the Home Frontpage.{/ifhome}
Expand Down Expand Up @@ -1350,7 +1362,7 @@ Michael Milette - Author and Lead Developer

Big thank you to the following contributors. (Please let me know if I forgot to include you in the list):

* Premergency: New {ifuser} tag (2024).
* Premergency: New {ifprofile id is 999} tag (2024).
* suzyzan: Fixed deprecation notice relating to trim() function in PHP 8.1 (2023).
* richardvi/HZ University of Applied Sciences (premium supporter): Added support for locally assigned on module/activity custom roles to {ifcustomrole} (2023).
* alexmorrisnz: Add CSS class support for {details} tag (2022).
Expand Down
139 changes: 135 additions & 4 deletions filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,57 @@ private function getprofilepictureurl($user, $size = 'md') {
return $url;
}

/**
* Retrieves specified profile fields for a user.
*
* This method fetches and caches user profile fields from the database. If the fields have
* already been retrieved for the current request, the cached values are returned. This method
* supports fetching both core and custom user profile fields.
*
* @param object $user The user object whose profile fields are being retrieved.
* @param array $fields optional An array of field names to retrieve. If empty/not specified, only custom fields are retrieved.
* @return array An associative array of field names and their values for the specified user.
*/
private function getuserprofilefields($user, $fields = []) {
global $DB;

static $profilefields;
static $lastfields;

// If we have already cached the profile fields and data, return them.
if (isset($profilefields) && $lastfields == $fields) {
return $profilefields;
}

$profilefields = [];
if (!isloggedin()) {
return $profilefields;
}

// Get custom user profile fields, their value and visibilit. Only works for authenticated users.
$sql = "SELECT f.shortname, f.visible, f.datatype, COALESCE(d.data, '') AS value
FROM {user_info_field} f
LEFT JOIN {user_info_data} d ON f.id = d.fieldid AND d.userid = :userid
ORDER BY f.shortname;";
$params = ['userid' => $user->id];
// Determine if restricted to only visible fields.
if (!empty(get_config('filter_filtercodes', 'ifprofilefiedonlyvisible'))) {
$params['visible'] = 1;
}
$profilefields = $DB->get_records_sql($sql, $params);

// Add core user profile fields.
foreach ($fields as $field) {
// Skip fields that don't exist (likely a typo).
if (isset($user->$field)) {
$profilefields[$field] = (object)['shortname' => $field, 'visible' => '1', 'datatype' => 'text', 'value' => $user->$field];
}
}
$lastfields = $fields;

return $profilefields;
}

/**
* Determine if running on http or https. Same as Moodle's is_https() except that it is backwards compatible to Moodle 2.7.
*
Expand Down Expand Up @@ -3864,6 +3915,85 @@ function ($matches) use ($USER) {
}
}

// Tag: {ifprofile_shortname contains|is|in value}...{/ifprofile}.
// Description: Will display content if specified the User Profile Fields meets the specified condition.
//
// Parameter: shortname: Shortname of the custom user profile fields plus auth, idnumber, email, institution,
// department, city, country, timezone and lang.
// Parameter: contains|is|in: The comparison operator. Use:
// 'contains' to check if the field contains the text.
// 'is' to check if the field is an exact match for the value. 'empty' is a reserved words for value.
// 'not' to check fi the field does not contain the value. 'empty' is a reserved words for value.
// Meaning: empty is an empty string or "0". Not empty means the field contains something other than "0".
// 'in' to check if the value is in the fields content.
// Parameters: value: The text to compare the field against.
// Requires content between tags.
// Note:
if (stripos($text, '{/ifprofile}') !== false) {
// Retrieve all custom profile fields and specified core fields.
$corefields = ['id', 'username', 'auth', 'idnumber', 'email', 'institution', 'department', 'city', 'country', 'timezone', 'lang'];
$profilefields = $this->getuserprofilefields($USER, $corefields);

// Find all ifprofile tags.
$re = '/{ifprofile\s+(\w+)\s+(contains|is|not|in)\s+([^}]+)}(.*){\/ifprofile}/isuU';
$found = preg_match_all($re, $text, $matches);
if ($found > 0) {
foreach ($matches[1] as $key => $match) {
$string = $matches[0][$key];
$fieldname = $matches[1][$key];
$operator = $matches[2][$key];
$value = $matches[3][$key];

// Do not process tag if the specified profile field name does not exist.
if (!array_key_exists($fieldname, $profilefields)) {
continue;
}

$content = '';
switch ($operator) {
case 'contains':
// If the specified field contains the specified value.
// Example:{ifprofile email contains @example.com}...{/ifprofile}.
if (strpos($profilefields[$fieldname]->value, $value) !== false) {
$content = $matches[4][$key];
}
break;
case 'is':
// If the specified field is exactly the specified value.
// Example: {ifprofile country is CA}...{/ifprofile}.
// Example: {ifprofile city is empty}...{/ifprofile}.
// Note: "empty" is a reserved word meaning the specified field is an empty string or 0.
if (
($value === 'empty' && empty($profilefields[$fieldname]->value))
|| ($profilefields[$fieldname]->value === $value)
) {
$content = $matches[4][$key];
}
break;
case 'not':
// Example: {ifprofile country not CA}...{/ifprofile}.
// Example: {ifprofile institution not empty}...{/ifprofile}.
// Note: "empty" is a reserved word meaning the specified field is not 0 and not empty.
if (
($value === 'empty' && !empty($profilefields[$fieldname]->value))
|| $profilefields[$fieldname]->value !== $value
) {
$content = $matches[4][$key];
}
break;
case 'in':
// If the specified value contains the value specified in the field.
// Example: {ifprofile country in CA,US,UK,AU,NZ}...{/ifprofile}.
if (strpos($value, $profilefields[$fieldname]->value) !== false) {
$content = $matches[4][$key];
}
break;
}
$replace['/' . preg_quote($string, '/') . '/isuU'] = $content;
}
}
}

// Tag: {ifmobile}...{/ifmobile}.
// Description: Will display content if accessed from the mobile app.
// Parameters: None.
Expand Down Expand Up @@ -4618,17 +4748,18 @@ function ($matches) use ($mycohorts) {
}
}

// Tag: {ifuser id|username}...{/ifuser}.
// Description: Display content only for specified user id or username.
// Parameters: id or username number of user.
// DO NOT USE THIS TAG. IT WILL BE REMOVED SOON. Use {ifprofile id is 999} instead.
// Tag: {ifuser id}...{/ifuser}.
// Description: Display content only for specified user id.
// Parameters: id number of user.
// Requires content between tags.
if (stripos($text, '{ifuser') !== false) {
$re = '/{ifuser\s+(.*)\}(.*)\{\/ifuser\}/isuU';
$found = preg_match_all($re, $text, $matches);
if ($found > 0) {
foreach ($matches[1] as $user) {
$key = '/{ifuser\s+' . $user . '\}(.*)\{\/ifuser\}/isuU';
if ($user == $USER->id || $user == $USER->username) {
if ($user == $USER->id) {
// Just remove the tags.
$replace[$key] = '$1';
} else {
Expand Down
2 changes: 1 addition & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

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

$plugin->version = 2024071800; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2024061902; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014051200; // Requires Moodle version 2.7 or later.
$plugin->component = 'filter_filtercodes'; // Full name of the plugin (used for diagnostics).
$plugin->release = '2.5.2';
Expand Down

0 comments on commit e3176c2

Please sign in to comment.