I have a view with a few fields including 3 Global:PHP fields. I use first two PHP fields to return the counted result of votes by using some sql query, and use the third PHP field to sum up the first two. The output results of these three fields are displayed correctly in the preview, and I used print_r($data) to check and they did appear having correct value. But when I try to use Global:PHP to sort the result I failed.

My code in Sort code is:
return $row1->php_2 < $row2->php_2 ? -1 : (int)$row1->php_2 > $row2->php_2;
where php_2 is my third PHP field mentioned above.

I then put dsm($row1); before the above code. It turned out that 3 of my PHP fields have no value while the other fields have correct value. They appear to be: php(NULL) php_1(NULL) php_2(NULL). Any ideas?

Comments

Priority:Major» Critical

Changed it to critical.

subscribe

Read this http://drupal.org/node/1088832, I use his method and work fine!

About your problem, recently I had some sort of it - got solution.
I had used some Global PHP field, but always skipped the Value code textarea and did all logic/output in the Output code. If got empty (without return) Value code textarea the sort by global PHP wont work (all values will be NULL).
Solution for php field by wich You want to sort:

  • use Value code textarea - with "return"
  • Output code textarea - with your value ($value)

This works for displaying the field, but when you try to use this field as the sort field, sorting does not take place.

You must have got the explaination wrong dpearceMN, the solution of psisa works perfectly fine for me.
This is how I do it :

In my Global PHP field, in "value code" I enter my php condition ending with "return $output"
In the output area :

<?php
 
print $value;
?>

An finally this code in the PHP filter
return $row1->php_2 < $row2->php_2 ? -1 : (int)$row1->php_2 > $row2->php_2;

Version:6.x-1.x-dev» 7.x-1.x-dev

#4 seems to be correct, but just to clarify:

If you want to use any information from a Views PHP field in a Views PHP sort, you need to return the exact data you want to use from the Views PHP "Output" field (the "Value" field doesn't work at all).

So, in the Output field in your Views PHP field, put something like:

return 'test';

Now, in your Views PHP sort filter, you can do something like dpm($row1->php);, and you should see the text 'test' for the 'php' field.

What's annoying, though, is that I can't get the data I need in the Output field, only in the Value field, so I've had to resort to doing one extra db_query() per row on one of my views (just to get the value of a user referenced profile field), and the view takes much longer to load for thousands of records. Ugh.

#6 solved my problem with just a minor change... I used this in my sort code:
return $row1->php < $row2->php ? -1 : (int)$row1->php > $row2->php;
because I had only one php field...
Thank you @Delphine Lepers

A few more things that bit me while trying to sort. Seems like custom fields aren't handled well.

1) If using Global PHP to sort you can't add any other fields to sort. All your sorting logic will have to go in the one field. (ie. you can't sort first on Global PHP and then add the title field to sort alphabetically. Have to add in the title sorting into the Global PHP sort.)

2) You have to sort based on the Global PHP fields you're using in the Fields area. You can't sort on custom fields. Not all the $row->FIELD_NAME fields are populated correctly.

3) As per comment #4 - sorting is done on the results of the Value code. Not all the $row variable nor all the $data variable fields are populated correctly. I was trying to sort on a node's custom field and had to load the custom field data in the Value code like:

$val=node_load($data->nid);
return $val->field_featured['und'][0]['value'];

Example for #1 and #2 above - I added one Global PHP for sorting and then sorted on 3 custom fields and then the node title (which is populated correctly).

// sort by php field 1, desc
if ( $row1->php_1 > $row2->php_1 ) {
return -1;
}
if ( $row1->php_1 < $row2->php_1 ) {
return 1;
}
// then sort by php field 2, desc
if ( $row1->php_2 > $row2->php_2 ) {
return -1;
}
if ( $row1->php_2 < $row2->php_2 ) {
return 1;
}
// then sort by php field 3, asc
if ( $row1->php_3 < $row2->php_3 ) {
return -1;
}
if ( $row1->php_3 > $row2->php_3 ) {
return 1;
}
// then sort by node title, asc
if ( $row1->title < $row2->title ) {
return -1;
}
if ( $row1->title > $row2->title ) {
return 1;
}
// rows are the same for these fields, don't do anything
return 0;

Many thanks to codesmith in #9.
For me this little code has been very important:

// sort by php field 1, desc
if ( $row1->php_1 > $row2->php_1 ) {
return -1;
}
if ( $row1->php_1 < $row2->php_1 ) {
return 1;
}

And to put all logic in Output code instead than in Value code textarea, of course. In my case $data has nothing in Value code but is full in Output code.

Hi, i am new with drupal and i've been reading issues regarding Global Php fields and sorting.
I understand that i should move my code from the Output code field to the Value code field.
The problem i have is that the code i used in the Output code field to drill down the info from the fields i need to work with, doesn't work in the Value code field.

Here is what i'm using in the Output code field with the php tags before and after:

$uno = $data->field_field_new_subs2[0]['raw']['value'];
$due = $data->field_field_visits2[0]['raw']['value'];
$risultato = $uno / $due;
$risultato = $risultato *100;
print round($risultato, 2). '%';

Since i need to make it sortable i would need to move this code to the Value code field.
Can anyone help me please? I've been struggling for over 10 days with this since i'm not an advanced user with drupal/php.
Thank you.

I've struggled with this for a while. Evidently $row->field... doesn't work in the Output code box, but $data->field... does. Meanwhile, $data->field... doesn't work in the Value code box. What finally worked for me in the Value code box is the node_load method as described in #9.

The problem is, i need to display this info in a view and it's not working...

In the Value code try:

<?php
$val
=node_load($data->nid);
$uno = $val->field_new_subs2['und'][0]['value'];
$due = $val->field_visits2['und'][0]['value'];
$risultato = $uno / $due;
$risultato = $risultato *100;
return
round($risultato, 2). '%';
?>

Then in the Output code try:

<?php
print $value;
?>

(adding or omitting the php tags where appropriate)

The value field should return a value (return)
The output field allows you to output the returned value (print)

dankoB, #14 get's me almost there. but now i have another issue, one of the fileds in the view is an aggregated field with a SUM, if i replace this field's name in the code you provided, no output comes out. How can i access the value for an aggregated field?

By The way, thanx.

fabrica77, I'm glad I was able to help get you almost there. Unfortunately, I haven't any experience using aggregated fields. It seems that using them may throw off other Views features. I would probably try to just do it with PHP alone, without the aggregated fields, but hopefully someone else may have a better answer for you.

Something useful for some guys maybe..
Based on #10. Could use setup code but didn't..
Requirements where: List the products based on number witch I can find in title text (PT 1200 = 1200, PT 20192Sb = 20192).
And as these are numbers I can sort these..

preg_match_all('/\d{1,}/', $row1->title, $matches);
$row1->title = $matches[0][0];
preg_match_all('/\d{1,}/', $row2->title, $matches2);
$row2->title = $matches2[0][0];
if ( $row1->title > $row2->title ) {
return -1;
}
if ( $row1->title < $row2->title ) {
return 1;
}

Edit: I modified the system and added the value and sorting with computed field. This is less resource demanding and seems to be more beautiful way to handle this requirement.

Just to add to this mess my own solution to my case, I combined multiple solutions here on this thread to get the result I wanted.
I hope it will save you hours of changing values and trying different combinations. Here goes:

Setup:
- nodes with a field *SKU Number* using taxonomy reference
- all taxonomy terms are consisting of numbers (integer)

What I want:
- have those nodes be sorted according to the taxonomy term in that field *SKU Number*

Solution:
step 1:
- in your Fields add a Global PHP field
- in Value Code put the following PHP code WITHOUT the opening and closing PHP tags:

<?php
$val
= node_load($data->nid);
$term = taxonomy_term_load($val->field_sku_number['und'][0]['tid']);
return
$term->name;
?>

field_sku_number['und'][0]['tid'] is the filed that holds the Taxonomy Term ID NOT name in my node, from that we load the Taxonomy Term to get it's name
- in Output code use
<?php
echo $value;
?>

step 2:
- add a Global PHP field to your Sort Criteria
- in Sort Code put the following PHP code WITHOUT the PHP tags

<?php
return $row1->php < $row2->php ? -1 : (int)$row1->php > $row2->php;
?>

Test it out and I hope this saves some frustration.

Hi,
Im using Drupal 7. In my case I need to sort with date and title and another sort is taken by views php. I am using Better Exposed Filters for this sort where ajax change event triggered on select box. However a sort field will have one label with either ASC or DESC enabled. How this will work in my case

Thanks in advance

Note that wherever you would use

<?php
return $row1->php < $row2->php ? -1 : (int)$row1->php > $row2->php;
?>

you need to put braces around the second comparison like
<?php
return $row1->php < $row2->php ? -1 : (int) ($row1->php > $row2->php);
?>

Otherwise $row1->php is converted to an int before comparing which might lead to a wrong order (which it does for me in some cases).

Issue summary:View changes

Thank you psisa.filin for #4 - it helped me understand.