CCK and Computed Fields

Filed under: Uncategorized. Tags: , ,

I’ve been using the great CCK module on a bunch of projects (including this blog, for my bikelog). It’s really cool in that it lets you construct custom content types within the Drupal admin interface, without having to touch any PHP code. It’s like having your own personal microformat manager - it could handle things like compound content on a web page (and generate the editing form so you just fill in the blanks - abstract, body, url for more info, email contact, etc…) and I think it could even handle something like a simplified LOM for a “learning object repository”.

One thing I wanted to do on my bikelog was to automatically calculate average speed. I have fields for “duration” and “distance” so entering a value for “average speed” is redundant. Better to just derive the value from the known values already entered.

Which is where the really cool Computed Field module comes in. It’s a contributed module for CCK, and lets you do all kinds of funky things by writing PHP code to perform operations to generate the value of a field. These operations can include calculations on the other fields, or even more complicated things like, I suppose, performing a lookup on wikipedia or something…

After adding the Computed Field module, I just edited my “bikeride” CCK content type to add a new “computed” field called “average speed”. It’s got a “computed code” value, which is executed whenever a value needs to be derived. I just used this:

$node_field[0]['value'] = ($node->field_distance[0]['value'] / $node->field_duration[0]['value']) * 60;

I gave it a data type of “float”, a length of “10,2″ and a default value of 0. I told the module to store the value in the database, so I can use the computed field with Views.module as well (in this case, it performs the computation on edit, and stores the result in a field just as any other CCK field would do). I also flagged the field as being sortable, in case that helped Views.module at all.

The end result is a tiny bit of work entering a simple PHP calculation, and then the module takes over the monotonous and redundant calculation work. All I do is enter the base data, and it can derive the rest from that.

I’d imagine this type of derived field could be really useful in an event manager - looking up the number of registrations and updating an “available seats” field, for instance. Or, in a store or inventory system to calculate prices and stock counts. It’s a really cool addition, and although the setup interface (manually entering PHP code) isn’t something you’d unleash on a noob, it’s simple enough to set up and forget about.

Comments

18 Responses to “CCK and Computed Fields”

  1. Litui on August 19th, 2006 12:58 am

    Off topic, but I think you'd be interested in knowing (if you don't subscribe to his feed already) that Michael Geist has started a wiki on DRM and copyright issues in Canada: http://www.michaelgeist.ca/wiki/

  2. Tim Vaughan on August 19th, 2006 12:44 pm

    Wow, good stuff.  How did you get Views to calculate the statistics for the trips together (average speed overall etc.)?

  3. dnorman on August 19th, 2006 12:58 pm

    ah… that’s a bit of custom PHP in the “header” section of the Views page section. It gets MySQL to perform the calculations itself for speed, and just displays some of the results.

  4. Tim Vaughan on August 19th, 2006 3:44 pm

    *Sigh*, I keep on finding stuff to learn about Views!  Any chance you could post the code?  I want to do something similar but with totalling financial transactions.

  5. dnorman on August 19th, 2006 4:08 pm

    Sure. I’ll try pasting it here… The input format for the View page header section is set to execute PHP.

    <?php
    $query = "SELECT
    	SUM( field_distance_value ) AS distance,
    	SUM( field_duration_value ) AS duration,
    	(SUM(field_distance_value) / SUM(field_duration_value) * 60) AS avgspeed,
    	count(*) as ridecount
    FROM `node_content_bikeride` ;";
    
    $result = db_query($query);
    
    $output = '';
    
    while ($resultline = db_fetch_object($result)) {
      $output .= "<div class='bikelog_summary'>Summary of ". $resultline->ridecount . " bike log entries:<br />";
      $output .= "total distance travelled: " . round($resultline->distance,2) . " km<br />";
      $output .= "total time spent riding: " . round($resultline->duration,2) . " minutes<br />";
      $output .= "average speed overall: " . round($resultline->avgspeed,2) . " km/h";
      $output .= "</div>";
    }
    
    print $output;
    ?>
  6. Justin Freeman on August 20th, 2006 5:25 am

    G’day D’arcy

    Great to hear that you found the Computed Field module useful. Any chance you can post back your use case & code as an example so that we can add to the project page (for the benefit of humankind)?

    http://drupal.org/user/59132/contact

    Cheers
    Justin

  7. Tim Vaughan on August 21st, 2006 1:16 pm

    Many thanks - looks really useful!

  8. Arto Bendiken on August 22nd, 2006 3:05 am

    Drupal with CCK is beginning to take on some of the power of Lotus Notes. We have custom content types, shared fields, computed fields. Now we just need a form layout designer and some nifty replication facilities, and we're all set for enterprise domination ;-)

  9. dnorman on August 22nd, 2006 8:29 am

    Arto - you might be onto something. First, though, we’d have to let the Drupal core code get really crusty and spaghetti-like, and let lots of silly bugs spread throughout it. Then, we’d start to approach Notes… ;-)

  10. Christoph the marketingfan on August 23rd, 2006 4:43 am

    Wow - good to see you use CCK already… I want to use that ASAP / as soon as I migrated all my wordpress and MT installations…

    BTW - do you use contemplate also??

    see http://weblog.cemper.com/a/200605/30-flexible-data-modelling-with-cck-contemplate-and-drupal-part-2-in-great-reasons-for-drupal.php

  11. dnorman on August 23rd, 2006 9:19 am

    I’m using contemplate on our Teaching & Learning Centre department website, and will be adding it here. I only started using Contemplate on Monday, but am really liking it. The CCK node template is coded in a .tpl.php file here, which is kind of nasty to edit remotely.

  12. sunny on August 25th, 2006 4:32 am

    How can we send a attached word document with a mail, which should be automatically generated at a particular time.

    Note; User will not run the script. The mail should reach at certain to the receiptent at particular time.
    And the mail is already predefined.

  13. dnorman on August 25th, 2006 8:07 am

    sunny - I have no idea what you’re asking.

  14. hk on November 20th, 2006 11:54 pm

    is there anyway to put some logic to check on the computed field? For example, in my CCK form, I ask the user to input a date in the future, and the computed field will calculate the difference (in days) between current date and the future date entered by the user. If the computed field result is more than, say 60 days, then there should be an error saying that the date can not be more than 2 months from today and prevent the submission. Possible with CCK+Computed field?

  15. Eep² on July 16th, 2007 3:17 am
  16. dnorman on July 16th, 2007 9:03 am

    @eep2: yeah. and it’ll likely stay that way - I switched from Drupal to WordPress several months ago, so had to dump that functionality because WordPress can’t do it (in the same way).

  17. solson on June 2nd, 2008 4:03 pm

    Why did you switch to WordPress?

  18. dnorman on June 3rd, 2008 1:01 pm

    @solson I switched because Drupal wasn’t the right tool for the job. I just need blogging, and while Drupal can do that, I was spending a fair amount of time fine tuning Drupal to make it behave like WordPress. Decided to just use WordPress for straight blogging. I still use Drupal for dozens of websites - it’s by far the best tool for that job. But for straight blogging, WordPress is the right tool…

Leave a Reply




Readers who viewed this page, also viewed:

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 Canada License.