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

Yanxi’s picture

Priority: Major » Critical

Changed it to critical.

stefan81’s picture

subscribe

drupalnesia’s picture

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

psisa.filin’s picture

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)
dpearcefl’s picture

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

Delphine Lepers’s picture

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 :

  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;

geerlingguy’s picture

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.

quickly’s picture

#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

codesmith’s picture

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;
josean’s picture

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.

fabrica77’s picture

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.

dankoB’s picture

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.

fabrica77’s picture

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

dankoB’s picture

In the Value code try:

$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:

print $value;

(adding or omitting the php tags where appropriate)

Delphine Lepers’s picture

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

fabrica77’s picture

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.

dankoB’s picture

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.

kaido.toomingas’s picture

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.

gamesfrager’s picture

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:

$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 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

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

Test it out and I hope this saves some frustration.

Vinoth M’s picture

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

Ronino’s picture

Note that wherever you would use

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

you need to put braces around the second comparison like

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).

lunk rat’s picture

Issue summary: View changes

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

yuseferi’s picture

if I expose php views sort, how can I get sort order?

kaido.toomingas’s picture

Title: Can't sort » Sort localized taxonomy terms by title/name

//Sort localized taxonomy terms by title/name
// views global PHP field: value code

global $language;
$lang_name = $language->language; // en
$term = taxonomy_term_load($row->tid_1);
return i18n_taxonomy_localize_terms($term)->name;

// Sort global PHP: Sort code

return $row1->php_1 < $row2->php_1 ? -1 : (int) ($row1->php_1 > $row2->php_1);
kaido.toomingas’s picture

Title: Sort localized taxonomy terms by title/name » Cant sort
hottaco’s picture

Ok, to be sure about how related this thread is for me. I've tried everything listed here in varying combinations. I have a view of a global view (products view which has the field I'm after).

I did do the test mentioned on #7.

return 'test'

In the value code box, and:

print $value

In the sort filter:

dpm($row1->php);

This works.
When i go to reference the field I need to sort on they are always NULL regardless if I put them in the Value or Output box.
The Global View (if I go to the source view) has the field I'm after; which is:

field_specfield1

So I followed #14

My value box contains:

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

My output box contains:
print $value;
With php tags.

My sort filter has:
dpm($row1->php < $row2->php ? -1 : (int)$row1->php > $row2->php);

What am I doing wrong?
Many thanks for any help

fizk’s picture

Status: Active » Closed (works as designed)

It seems this works as designed according to #4 and #7. Please reopen if there really is a bug here.

nehapandya55’s picture

Thank you psisa.filin for #4 - it helped me to sort by using global php.

spiderplant0’s picture

#9 worked for me. Thanks codesmith