Computed Field Module And How it Can Simplify Your Views

Sometimes, the node data that you want is not exposed to Views in the way that you want. Computed Field is a module that, with a little bit of raw PHP code, can help you bridge those gaps.

The CCK Computed Field module (http://drupal.org/project/computed_field) is a module that allows a developer to use PHP code to determine the value of a CCK field.

Tobby Hagler, Director of Engineering
#Development | Posted

Sometimes, the node data that you want is not exposed to Views in the way that you want. Computed Field is a module that, with a little bit of raw PHP code, can help you bridge those gaps.

The CCK Computed Field module (http://drupal.org/project/computed_field) is a module that allows a developer to use PHP code to determine the value of a CCK field. The results of the PHP code are stored in the database, so the computation only needs to happen once.

What it is

Computed Field is a module for CCK that allows a developer extra flexibility by essentially providing a field for PHP. The results are stored with the node, and the field can be indexed.

What it is not

Computed field is not a macro builder. It doesn’t offer any forms to the user creating a node, so there’s no way to override or set what is stored manually.

Examples of Problems it Solves

Merging Data Fields for Display in Views

I once had a project where a table was generated by Views that displayed a variety of job listings. There were a number of fields for things like department, salary grades, and job codes as separate CCK fields.

However, these were to be displayed in the listings table like “AA-BBB-001”. It’s possible to theme the view to merge those fields, but that gets overly complex real fast, and (possibly, depending on circumstances) may require a new template for every view created.

With Computed Field, I created a fourth field that contained a text value of this job code by merging the other three fields. The PHP code looked something like this:

  1. <span style="color: #000000;"><span style="color: #0000bb;"><?php
  2. $node_field</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] =
  3. </span><span style="color: #0000bb;">$node</span><span style="color: #007700;">-></span><span style="color: #0000bb;">field_dept</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">]  . </span><span style="color: #dd0000;">'—' </span><span style="color: #007700;">.
  4. </span><span style="color: #0000bb;">$node</span><span style="color: #007700;">-></span><span style="color: #0000bb;">field_grade</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] . </span><span style="color: #dd0000;">'—' </span><span style="color: #007700;">.
  5. </span><span style="color: #0000bb;">$node</span><span style="color: #007700;">-></span><span style="color: #0000bb;">field_code</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">];
  6. </span><span style="color: #0000bb;">?></span></span>

In my table view, I simply hid the original three fields, and added this field to the display. By hiding the fields, rather than removing them, I can still use an exposed filter to allow users to filter by those fields.

Sortable Columns of Taxonomy Terms

When you have a large table of data generated by Views, it’s nice to be able to sort the various columns. One issue I’ve always had with this though, is that Taxonomy terms can’t be sortable. Computed Field can help.

I created a computed field that stored the value of my taxonomy term. The computed code looked like this:

  1. <code><span style="color: #000000;"><span style="color: #0000bb;"><?php
  2. </span><span style="color: #ff8000;">// Assuming the vid is a conf array element in settings.php
  3. </span><span style="color: #0000bb;">$vid </span><span style="color: #007700;">= </span><span style="color: #0000bb;">variable_get</span><span style="color: #007700;">(</span><span style="color: #dd0000;">'some_vocabulary_vid'</span><span style="color: #007700;">, </span><span style="color: #0000bb;">0</span><span style="color: #007700;">);</span></span>

 

  1. <code><span style="color: #000000;"><span style="color: #0000bb;">$terms </span><span style="color: #007700;">= </span><span style="color: #0000bb;">taxonomy_node_get_terms</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$node</span><span style="color: #007700;">);
  2. foreach (</span><span style="color: #0000bb;">$terms </span><span style="color: #007700;">as </span><span style="color: #0000bb;">$tid </span><span style="color: #007700;">=> </span><span style="color: #0000bb;">$term</span><span style="color: #007700;">) {
  3. if (</span><span style="color: #0000bb;">$term</span><span style="color: #007700;">-></span><span style="color: #0000bb;">vid </span><span style="color: #007700;">== </span><span style="color: #0000bb;">$vid</span><span style="color: #007700;">) {
  4. </span><span style="color: #0000bb;">$status </span><span style="color: #007700;">= </span><span style="color: #0000bb;">taxonomy_get_term</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$tid</span><span style="color: #007700;">);</span></span>

 

  1. <span style="color: #000000;"><span style="color: #ff8000;">// You might use a different loop to populate more node_field values
  2. </span><span style="color: #0000bb;">$node_field</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] = </span><span style="color: #0000bb;">$status</span><span style="color: #007700;">-></span><span style="color: #0000bb;">name</span><span style="color: #007700;">;
  3. break; </span><span style="color: #ff8000;">// In this example, I just want the one.
  4. </span><span style="color: #007700;">}
  5. }
  6. </span><span style="color: #0000bb;">?></span></span>

In my view, I edited the table configuration for the display I wanted to allow this new column to be sorted. You can even go so far as to rewrite the output of that field to use the original field’s value.

Additional Values for Sorting

In Views, there are times when you need to sort based on certain conditions, such as whether or not a value is present. Sometimes, the typical ascending/descending paradigm isn’t enough. For instance, based on “completeness” of a node (how many fields a user has filled out), you can have a computed field that generates a number from 1 to 10. With this field, you can now sort the view on node completeness.

You may also wish to sort on binary conditions, where the case is TRUE if one or more of several fields has a value, and FALSE if none have a value. The computed field code might look like this:

  1. <span style="color: #000000;"><span style="color: #0000bb;"><?php
  2. </span><span style="color: #007700;">if (</span><span style="color: #0000bb;">$node</span><span style="color: #007700;">-></span><span style="color: #0000bb;">field_a</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] != </span><span style="color: #dd0000;">''</span><span style="color: #007700;">) {
  3. </span><span style="color: #0000bb;">$node_field</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] = </span><span style="color: #0000bb;">TRUE</span><span style="color: #007700;">;
  4. } elseif(</span><span style="color: #0000bb;">$node</span><span style="color: #007700;">-></span><span style="color: #0000bb;">field_b</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] != </span><span style="color: #dd0000;">''</span><span style="color: #007700;">) {
  5. </span><span style="color: #0000bb;">$node_field</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] = </span><span style="color: #0000bb;">TRUE</span><span style="color: #007700;">;
  6. } elseif(</span><span style="color: #0000bb;">$node</span><span style="color: #007700;">-></span><span style="color: #0000bb;">field_c</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] != </span><span style="color: #dd0000;">''</span><span style="color: #007700;">) {
  7. </span><span style="color: #0000bb;">$node_field</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] = </span><span style="color: #0000bb;">TRUE</span><span style="color: #007700;">;
  8. } else {
  9. </span><span style="color: #0000bb;">$node_field</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">][</span><span style="color: #dd0000;">'value'</span><span style="color: #007700;">] = </span><span style="color: #0000bb;">FALSE</span><span style="color: #007700;">;
  10. }
  11. </span><span style="color: #0000bb;">?></span></span>

There are countless other uses for computed field. For more recipes, see: http://drupal.org/node/149228

Downsides

Since the stored value computed field is only computed when the node is saved, your nodes need to be re-saved to allow for code changes. If you change the content type’s field, you may need to re-save all nodes of that type. If you have thousands of nodes, this can be troublesome. However, several modules (which are outside the scope of this post) can help, as can simple one-off scripts.

One obvious downside of using computed fields to store data that you already have in the node (such as taxonomy terms) is that you denormalize your data. This duplication of data may be problematic in certain situations, but the convenience does compensate.

Tobby Hagler

Director of Engineering