The attached patch adds an additional option for allowed values to optionally be matched with regular expressions, allowed more complex validation of text fields.

CommentFileSizeAuthor
text.module_3.patch2.22 KBSqueeself

Comments

yched’s picture

Seems like a good idea.
See also this patch by grecmac

Maybe both eforts should be merged / coordinated ?

yched’s picture

I even found a third one :-)
http://drupal.org/node/76467

yched’s picture

I just marked the patch by gregmac as a duplicate of this one - his patch is a whole new regexp field, and for the time being I think it is better to plug this directly to text.module.

yched’s picture

I forgot the link - gregmac's patch is http://drupal.org/node/83841

mki’s picture

My all-purpose suggest is that we should have an opportunity to put into allowed values both exact and regular expression value. For example, in allowed values we can enter:

white
black
red
^#([a-fA-F0-9]){6}$

Where the last matches HTML Color strings like #FFFFFF is white and #000000 is black and #FF0000 is red and so on...
We need only a way to distinguish between regular expresions and exact values.

mki’s picture

I reach to the conclusion that we don't need special sign for regural expresions.
This is code what I suggest:

<?php
      $allowed_values = explode("\n", $field['allowed_values']);
      $allowed_values = array_map('trim', $allowed_values);
      $allowed_values = array_filter($allowed_values, 'strlen');

      if (is_array($items)) {
        foreach ($items as $delta => $item) {
          if ($item['value'] != '') {
            if (count($allowed_values) && !in_array($item['value'], $allowed_values)) {
              // We assume that not any allowed values match to current item value 
              $is_match = FALSE;
              foreach($allowed_values as $allowed_value) {
                // We use @ to escape E_WARNING if current allowed value isn't regular expression
                if (@preg_match($allowed_value, $item['value'])) {
                  // If current allowed value match to current item value, we are break and remember this
                  $is_match = TRUE;
                  break;
                }
              }
              // Now, when we check every allowed value, we can give the verdict
              if (!$is_match) {
                form_set_error($field['field_name'], t('Illegal value for %name.', array('%name' => t($field['widget']['label']))));
              }
            }
          }
        }
      }

?>
mki’s picture

Better version to prevent user enter regular expression as value. For example we have regular expression "/^cat$/" and so far user could enter "/^cat$/". Now first we check value against regular expresion and then we check it against exact value.

<?php
      $allowed_values = explode("\n", $field['allowed_values']);
      $allowed_values = array_map('trim', $allowed_values);
      $allowed_values = array_filter($allowed_values, 'strlen');

      if (is_array($items)) {
        foreach ($items as $delta => $item) {
          if ($item['value'] != '') {
            if (count($allowed_values)) {
              // We assume that not any allowed values match to current item value 
              $is_match = FALSE;
              foreach($allowed_values as $allowed_value) {
                // We use @ to escape E_WARNING if current allowed value isn't regular expression
                $match_result = @preg_match($allowed_value, $item['value']);
                // If current allowed value is regular expression and match
                if ($match_result == 1) {
                  $is_match = TRUE;
                  break;
                // If current allowed value isn't regular expression, but exact value match
                } elseif ($match_result === FALSE && $item['value'] == $allowed_value) {
                  $is_match = TRUE;
                  break;
                }
              }
              // Now, when we check every allowed value, we can give the verdict
              if (!$is_match) {
                form_set_error($field['field_name'], t('Illegal value for %name.', array('%name' => t($field['widget']['label']))));
              }
            }
          }
        }
      }
?>
mki’s picture

I regret that I have submited code three times, but this is more efficient version:

<?php
      $allowed_values = explode("\n", $field['allowed_values']);
      $allowed_values = array_map('trim', $allowed_values);
      $allowed_values = array_filter($allowed_values, 'strlen');

      if (is_array($items)) {
        foreach ($items as $delta => $item) {
          if ($item['value'] != '') {
            if (count($allowed_values)) {
              // We assume that not any allowed values match to current item value 
              $is_match = FALSE;
              foreach($allowed_values as $allowed_value) {
                // We use @ to escape E_WARNING if current allowed value isn't regular expression
                $match_result = @preg_match($allowed_value, $item['value']);
                // If (current allowed value is regular expression and match) or
                // (current allowed value isn't regular expression, but exact value match)
                if ($match_result == 1 || ($match_result === FALSE && $item['value'] == $allowed_value)) {
                  $is_match = TRUE;
                  break;
                }
              }
              // Now, when we check every allowed value, we can give the verdict
              if (!$is_match) {
                form_set_error($field['field_name'], t('Illegal value for %name.', array('%name' => t($field['widget']['label']))));
              }
            }
          }
        }
      }
?>
yched’s picture

Please note that a patch to add regexp "allowed values" will also need to take into account the Views filter that text.module currently define : "is / is not equal to " each allowed value (I think we won't be able to do that with regexp allowed values)

deepak@dipak.org’s picture

yched, are you ever going to commit the above patch? I would like to have the ability to add regular expression in the text field. If we don't do this now, new projects for this will keep popping up.

If you already made a commit, I take my above comments back.

yched’s picture

http://drupal.org/node/118417 has been marked duplicate.

We should really get this done. Unfortunately I have not been able to find the time lately

jereme.guenther’s picture

I agree this would be a super nice feature to have in the text field. It would essentially allow us to easily create validation for all field types that have not yet been created.

I implemented the patch and am really excited over the additional functionality. There are a couple minor problems with the patch, but once I fixed those I solved a problem I have been thinking about for the last several days. Namely, how am I going to write field types for all the different fields I need to validate. I absolutely love this and would really like to see it incorporated into the text field type in some manner or other.

By holding off on integrating this code it is forcing people like me to hack it into the module. Now I have to be extra careful in any upgrades I do that it doesn't break my existing functionality. Not a horrible thing, but it would be so easy to add and I don't see why an admin would care if someone who can administer the field can also write validation for it; presumably giving them the ability to administer the field means they are trustworthy.

Gidgidonihah’s picture

I went ahead and added the code from #8. It works beautifully. I don't know how to write a patch otherwise I would. I had to edit it by hand. I think this would be a perfect and much needed addition to the text module.

yched’s picture

Status: Needs review » Closed (duplicate)

A preferred (more generic, benefits all field types) approach is posted on http://drupal.org/node/212665

It was proposed as a GHOP task (a bit late - a few hours before the deadline for tasks claim) following a proposal from Crell, and is still available if anyone wants to tackle it outside GHOP.

Doesn't lowers the merits of the above patch, but now that a better idea was sketched, I really think we should aim at this instead.

In order to focus the efforts, I think it's best to mark this thread a duplicate (with a link back here, so that the work already done isn't lost). Thanks Squeeself and mki for this, sorry for not having given the required attention...

Gidgidonihah’s picture

A little update on my experience. The regex was allowing only the matched values to be allowed.
However, upon further building, I realized that my fields weren't showing up when viewing a node nor in views. Everything worked fine while editing but upon saving, once again not visible. Haven't looked deeply to figure out what the problem was, but as soon as I removed the regex from the allowed values, behavior returned to normal.

kenorb’s picture