I have two text fields (first name and last name). I need the realname to be first name + last initial: John D. or Adam S. for example.

The following bit of PHP would work nicely, if only the "name pattern" allowed for input filters so that I could select the PHP filter.

  $first = '%1';
  $last = '%2';
  return $first .' '. $last[0] .'.';

The attached patch does just that!

First, it patches realname.admin.inc to collect and save the input format information. Pretty straight-forward. Nothing dangerous here.

Second, it patches realname.module to do the following:

  1. Escape all raw user input (the stuff that goes into $stuff) using htmlentities(<raw user input>, ENT_QUOTES).
    • This protects against dangerous attacks. For example, in the above PHP code, someone could do a lot of damage by doing something like Jo'; drupal_set_message('PHP Injection'); $dummy='hn as their first name. It would be interpreted as:
        $first = 'Jo'; drupal_set_message('PHP Injection'); $dummy='hn';
        $last = 'Doe';
        return $first .' '. $last[0] .'.';
      
    • In my tests, escaping the variables prevents any unwanted PHP injection:
        $first = 'Jo&amp;#039;; drupal_set_message(&amp;#039;PHP Injection&amp;#039;); $dummy=&amp;#039;hn';
        $last = 'Doe';
        return $first .' '. $last[0] .'.';
      
  2. After the replacement tags in $pattern are replaced with the now-escaped stuff from $stuff, run the desired input filter using check_markup.
  3. Now that the danger of a PHP injection attack is passed, un-escape the text using html_entity_decode(<escaped text>, ENT_QUOTES).
    • The username is still supposed to be plain text at this stage. There will be a check_plain() in this text's future, and if it's not un-escaped now, there will be problems with apostrophes and other special characters later. Our Irish friends would be most displeased to find their names turned into O&#039;Reilly and O&#039;Connor. Un-escape the username now, and the Irish will be very happy.

And finally, I believe this will also solve the occasionally continuing follow-up problems experienced in:
#338871: Display problems with name containing apostrophe
#616134: Special Characters
#666528: Display problems with name containing apostrophe

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sbandyopadhyay’s picture

Hmmm... now I'm second-guessing myself...

In step 1, is it better to use check_plain or htmlentities?

I used htmlentities because it's noted on php.net as the "opposite" to html_entity_decode, but check_plain might be faster...?

Anyone have any thoughts?

sbandyopadhyay’s picture

Re-rolling the patch against 6.x-1.x-dev

sbandyopadhyay’s picture

Title: Allow input filters (PHP execution, etc) in the name pattern » Allow PHP execution in the name pattern
FileSize
4.01 KB

My earlier patch causes spare <p> tags to be thrown into the username when in Filtered HTML or Full HTML mode, which is unintended. Since my entire purpose was just running PHP code, I figured that a better way to do it would be to simply borrow from Auto Nodetitle, since they've figured it out just fine. As it turns out, Auto Nodetitle does NOT use input formats at all, but simply adds a separate feature to allow PHP execution.

This new patch adapts Auto Nodetitle's approach to executing PHP in the pattern.

However, it needs to be accompanied with a critical warning (also adapted from Auto Nodetitle) about using %n replacement together with PHP execution, as it could open a security flaw. This patch adds the appropriate warning in the README file.

Actron’s picture

Updated my RealName installation with the latest patch.

Works fine for me and would solve my ticket:
#1630864: Omit parts of name pattern, if optional field is empty

I do support adding this feature to RealName.

ezra-g’s picture

Executing PHP entered in the UI would introduce a critical security vulnerability.

If you are comfortable writing PHP, why not implement hook_username_alter() instead of using Realname?

jzornig’s picture

Many modules (including one in core "block") allow php to be entered in settings. There are many cases where just the tiniest bit of logic e.g if then else, enables a vast array of functionality beyond a simple token replacement but without the hurdle of having to create a custom module. However in the case of realname is is quite easy to use the Computed Field module to get this functionality.

hass’s picture

Status: Needs review » Needs work
+++ b/realname.admin.inc
@@ -360,12 +360,17 @@ function realname_admin_fields() {
+    '#title' => t('Name Pattern'),

'Name pattern'

hass’s picture

Status: Needs work » Closed (outdated)