[support] PHP Allowed Values for CCK Field as Associative Array

Shai Gluskin shai at content2zero.com
Wed Jan 27 22:48:59 UTC 2010


Folks,

For anyone following this thread, the following code is safer and more
elegant (it uses William's suggestion of the drupal_map_assoc)... Now it
should work even if person is using a wysiwyg AND it will trim extra
carriage returns at end so that there aren't blank lines in the drop down.

It's prudent to put a warning on the node/x/edit page which houses the
options that changing the spelling of an option will not apply
retroactively. Nodes with the previously spelled item in the text field
would need to be updated one at a time or through a script or maybe Views
Bulk Operations. [Note that reordering items in node will not be a problem
since an associative array is being built in which key => label pair are the
same.]

Put the following code in to the "Use PHP to determine allowed values" field
in CCK for a text field using "Select".

$node = node_load(4247); // Replace "4247" with node id of node that
includes option list in body field.
$body = strip_tags(str_replace("\r\n","~",trim($node->body)));
$arr = explode("~",$body);
return drupal_map_assoc($arr);

Shai

On Wed, Jan 27, 2010 at 2:00 PM, Shai Gluskin <shai at content2zero.com> wrote:

> Review of what I wanted: desire to use the PHP field in the text field
> admin page to build the list of options for a select list. I wanted to grab
> those options from the a particular node body.
>
> The problem turned out to be that hard carriage returns ("\r") remained
> persistent after the explode() function. So just a bit of string replace did
> the job. Below is a copy of the code.
>
> Thanks much,
>
> Shai
>
> $node = node_load(4247); //replace "4247" with the node id that has the
> select items in its body field
>
> $arr = explode("\n",$node->body);
> foreach ($arr as $value){
> $trimmed = str_replace("\r"," ",$value);
>
>   $new_arr[$trimmed] = $trimmed;
> }
> return $new_arr;
>
>
>>> On Tue, Jan 26, 2010 at 8:14 PM, William Smith <william.darren at gmail.com
>>> > wrote:
>>>
>>>> Sorry if I misunderstand the problem, but could you not use
>>>> drupal_map_assoc right before you return your array?
>>>>
>>>>
>>>> $arr = explode("\n", $node->body);
>>>> return drupal_map_assoc($arr);
>>>>
>>>> On Tue, Jan 26, 2010 at 8:01 PM, Shai Gluskin <shai at content2zero.com>wrote:
>>>>
>>>>>  Support Folks,
>>>>>
>>>>> Need/Use-case: a very simple, lightweight UI for a customer to edit
>>>>> options on a select for a CCK field.
>>>>>
>>>>> Idea to solve it. Create an unpublished node (linked to via for the
>>>>> customer via a custom site-admin block) whose body field are the select-list
>>>>> options. One option per line.
>>>>>
>>>>> In the CCK field I'm using the PHP option to return an array to create
>>>>> the allowed options:
>>>>>
>>>>> This following code works... but is not quite what I want:
>>>>> (I know that the client input part should be sanitized for security...
>>>>> but I'm just trying to get it to work before I do that part.)
>>>>>
>>>>> $sql = "SELECT body FROM {node_revisions} WHERE nid=1274 ORDER BY
>>>>> timestamp DESC LIMIT 1";
>>>>> $res = db_query($sql);
>>>>> $node = db_fetch_object($res);
>>>>> $arr = explode("\n",$node->body);
>>>>> return $arr
>>>>>
>>>>> from a node body field that looks like:
>>>>>
>>>>> Cats
>>>>> Dogs
>>>>> Goats
>>>>>
>>>>> It returns an indexed array like
>>>>>
>>>>> Array
>>>>> (
>>>>>    [0] => Cats
>>>>>    [1] => Dogs
>>>>>    [2] => Goats
>>>>>
>>>>> )
>>>>>
>>>>> *Problem:* What gets stored in the database is the integer key from
>>>>> the indexed array created by explode(). The data integrity is thus
>>>>> completely dependent upon the order of the items listed. I don't want that.
>>>>> I want people entering the data to be able to change the order. *I
>>>>> want an associative array in which the keys and labels are the same.*
>>>>>
>>>>> Note that if, via the field configuration UI, I simply list the values
>>>>> in the allowed values box... Drupal turns that list into an associative
>>>>> array in which the keys and values are the same. Exactly what I want! But I
>>>>> don't know how to create that for the custom PHP value set. I'm putting the
>>>>> code here from CCK where this happens. I don't quite get it.
>>>>>
>>>>> Any hints would be most appreciated,
>>>>>
>>>>> Shai
>>>>>
>>>>> /**
>>>>> *  Create an array of the allowed values for this field.
>>>>> *
>>>>> *  Used by number and text fields, expects to find either
>>>>> *  PHP code that will return the correct value, or a string
>>>>> *  with keys and labels separated with '|' and with each
>>>>> *  new value on its own line.
>>>>> *
>>>>> * @param $field
>>>>> *   The field whose allowed values are requested.
>>>>> * @param $flatten
>>>>> *   Optional. Use TRUE to return a flattened array (default).
>>>>> *   FALSE can be used to support optgroups for select widgets
>>>>> *   when allowed values list is generated using PHP code.
>>>>> */
>>>>> function content_allowed_values($field, $flatten = TRUE) {
>>>>>  static $allowed_values;
>>>>>
>>>>>  $cid = $field['field_name'] .':'. ($flatten ? '1' : '0');
>>>>>  if (isset($allowed_values[$cid])) {
>>>>>    return $allowed_values[$cid];
>>>>>  }
>>>>>
>>>>>  $allowed_values[$cid] = array();
>>>>>
>>>>>  if (isset($field['allowed_values_php'])) {
>>>>>    ob_start();
>>>>>    $result = eval($field['allowed_values_php']);
>>>>>    if (is_array($result)) {
>>>>>      if ($flatten) {
>>>>>        $result = content_array_flatten($result);
>>>>>      }
>>>>>      $allowed_values[$cid] = $result;
>>>>>    }
>>>>>    ob_end_clean();
>>>>>  }
>>>>>
>>>>>  if (empty($allowed_values[$cid]) && isset($field['allowed_values'])) {
>>>>>    $list = explode("\n", $field['allowed_values']);
>>>>>    $list = array_map('trim', $list);
>>>>>    $list = array_filter($list, 'strlen');
>>>>>    foreach ($list as $opt) {
>>>>>      // Sanitize the user input with a permissive filter.
>>>>>      $opt = content_filter_xss($opt);
>>>>>      if (strpos($opt, '|') !== FALSE) {
>>>>>        list($key, $value) = explode('|', $opt);
>>>>>        $allowed_values[$cid][$key] = (isset($value) && $value !=='') ?
>>>>> $value : $key;
>>>>>      }
>>>>>      else {
>>>>>        $allowed_values[$cid][$opt] = $opt;
>>>>>      }
>>>>>    }
>>>>>    // Allow external modules to translate allowed values list.
>>>>>    drupal_alter('content_allowed_values', $allowed_values[$cid],
>>>>> $field);
>>>>>  }
>>>>>  return $allowed_values[$cid];
>>>>> }
>>>>>
>>>>> --
>>>>> [ Drupal support list | http://lists.drupal.org/ ]
>>>>>
>>>>
>>>>
>>>> --
>>>> [ Drupal support list | http://lists.drupal.org/ ]
>>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.drupal.org/pipermail/support/attachments/20100127/78d8c224/attachment-0001.html 


More information about the support mailing list