Last updated July 30, 2014. Created on July 16, 2012.
Edited by Pasko, drupalshrek, peterx, alibama. Log in to edit this page.

Add PHP to your views. Use PHP to select rows from the results.

Here is an example of PHP code used in a view filter field.

<?php
 
$nid
= db_query('SELECT field_reference_nid FROM `field_data_field_reference` WHERE entity_id = ' . $data->nid)->fetchColumn();
if (!isset(
$static[$job_nid])) {
 
$uid = db_query('SELECT uid FROM `node` WHERE nid = ' . $nid)->fetchColumn();
 
$static[$nid] = $uid;
}
global
$user;
return
$user->uid != $static[$nid];
?>

Forget the quality of the code. It is just a quick example to test Views PHP.

See http://drupal.org/node/1678082 for information on how to access the PHP.

Open the Available variables section to see the data supplied to your code. You can add fields to the $row variable by adding them as fields in your view. If you do not want them displayed in your view, use the view option to exclude them from the display.

Use the $static variable to carry data from one row to another. In the example, I read the database once to get a uid from a related node and store each result for subsequence rows. In my test case, each entry is reused ten or more times.

db_query is officially the fastest way to read the database in D7 and you do not hog memory caching whole nodes. You might find this type of PHP faster than joins for some data lookups.

If you start using a lot of code like this to lookup the same data, you might want to add a module or a node reference or some other trick to automate the process instead of using PHP in views. This type of code is just a quick way to make stuff work. For my example, I will eventually converted it to a module providing a filter.

Available variables

Here is the list of available variables in my example filter before I added some fields.

  • $view: The view object.
  • $handler: The handler object.
  • $static: A variable that can be used to store reusable data per row.
  • $row: Contains the retrieved record from the database (e.g. $data->nid).
  • $row->title: Content: Title
  • $data: Contains the retrieved record from the database (e.g. $data->nid).

Here is the list of available variables in my example filter after I added some fields.

  • $view: The view object.
  • $handler: The handler object.
  • $static: A variable that can be used to store reusable data per row.
  • $row: Contains the retrieved record from the database (e.g. $data->nid).
  • $row->title: Content: Title
  • $row->field_name: Content: Name
  • $row->field_phone: Content: Phone
  • $row->field_text: Content: Text
  • $row->field_ref_number: Content: Ref. no
  • $row->field_short_description: Content: Short Description
  • $data: Contains the retrieved record from the database (e.g. $data->nid).

While in Drupal 6 the $row->field_goes_here would return the actual data of the field in Drupal 7 it returns the key value (ie nid, or tid) of the field. This may be confusing for some users used to using views php in D6. To delve in further it may help to test print_r($data); to see what values are generated. As noted in dalearyous's tutorial $data->field_your-field-goes-here['0']['raw']['value']; works pretty well. So if you have a field named field_account_name $data->field_field_account_name will return the value you expect.

Performance

If Views PHP retrieved all data before processing your code, your view would slow down and could slow down by a huge amount. The D7 version presents only the data read by the view and nothing else. You have the chance to be selective about the data you retrieve.

A node load might be efficient if you need all the data from the node. The node load could waste a lot of time for a content type with many fields when you need only a few fields. The entity functions give you a way to read only the data you need and are worth looking at as a way to retrieve the extra data you need.

An easier way to retrieve extra data is to select the data in the view and exclude the data from the display. Views takes care of retrieving the data. This works well when you need the data for every, or almost every row. If you need the extra data for only a small percentage of rows, look at the entity approach.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

nathangs’s picture

It took a while to figure this out, so I'm posting my code in case others may benefit. Quick explanation: I needed the search results view to filter out a specific content type if it's custom field (start date/expiration date) was not valid.

Setup Code Area

<?php
function checkForOutOfDateProgram($item) {
 
$thing = node_load($item->nid);  //this part was messing me up.  I assumed the $data value would have the contents of the node, but it apparently only contains the node id value, so you have to load the full node.
 
if ($thing ->type == 'program') {  //first I check to make sure that the result is the correct custom content type
   
if ($thing->field_program_start_program_expi['und'][0]['value'] > time()) {
      return
TRUE//if the program stars in the future, it shouldn't be displayed
   
} elseif ($thing->field_program_start_program_expi['und'][0]['value2'] < time()) {
      return
TRUE; //if the program ended in the past, it shouldn't be displayed
   
} else {
      return
FALSE//if the program doesn't meet either if statement, then it is valid and should be displayed
   
}
  } else {
    return
FALSE//if its not a program, it should be displayed
 
}
}
?>

Filter Code

<?php
return checkForOutOfDateProgram($data); //we call our setup code using the $data value
?>
ohthehugemanatee’s picture

Lots of people use views_php because it seems like writing a views handler is too hard or complicated. It isn't.

It's 24 lines of easy code, and then you write your PHP behavior just the way you were going to in Views. The difference being that your code is now in the codebase where it belongs, revisioned in git (or whatever you're using), easier to debug, and contributable.

I wrote a blog post walking through how to write a simple views handler as an alternative to using Views_php. Hope it's helpful to some people considering this module.

You never REALLY learn to swear until you own a computer.

sander-martijn’s picture

Took me a minute to figure this out, so maybe this will help someone:

- Value code outputs text (not html) and you use return to do it

- Output code outputs directly to the field, so if you need to output html, use this, but with print instead of return.

Other than that it's pretty straight forward.

And to respond to ohthehugemanatee - I will go through your tutorial at some point and do things that way, but there are uses for this module as well. In my case all I needed to do was output a url to a different view based on a submitted value from a webform, and couldn't find any other way to do it than this - here with a simple if/else the problem was solved with no security risks involved. writing a handler for something this simple would be silly.

<?php
$url
='';
if(
$row->select_office_location == 'LDN'){
$url = 'http://mydomain.com/generatepdf-uk/' . $row->sid;
}else{
$url = 'http://mydomain.com/generatepdf-us/' . $row->sid;
}
print
'<a href="'.$url.'" target="_new">View PDF</a>';
?>
Max_Headroom’s picture

Link broken

Quentin Campbell

hubobbb’s picture

$data->field_your-field-goes-here['0']['raw']['value']; works REALLY pretty well. Thank you
case :$data->field_field_abc['0']['raw']['value']; is two 'field'.

you can print_r($data);

Tks Drupal and all programmers bros

shaisamuel’s picture

Follow your example I used the following code to access custom field of users:

global $user;
$user_fields = user_load($user->uid);
$amount = $user_fields->field_commitment_total_amount['0']['raw']['value'];
if ($amount > 0) {
  $entity_field[0]['value'] = $amount;
}

When update a user I get the following error:

Notice: Undefined offset: 0 in eval() (line 3 of /home/intinvgrp/public_html/sites/all/modules/computed_field/computed_field.module(394) : eval()'d code).
Notice: Undefined offset: 0 in eval() (line 3 of /home/intinvgrp/public_html/sites/all/modules/computed_field/computed_field.module(394) : eval()'d code).
Status message

Any idea?

vanvemden’s picture

For what it's worth after two months; try without single quotes around the 0 (zero) in
$amount = $user_fields->field_commitment_total_amount[0]['raw']['value'];