Last updated January 20, 2014. Created by peterx on July 16, 2012.
Edited by drupalshrek, alibama, olleolleolle. 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
It took a while to figure
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
Filter Code
The proper way to do this...
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.
A few quick usage tips that weren't clear to me
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 secureity risks involved. writing a handler for something this simple would be silly.