This issue overlaps with at least one other issue (http://drupal.org/node/362648 ), but has an additional part to it: being able to use PHP to set latitude/longitude from which the distance is calculated when using distance to filter or returning distance as one of the selected fields.
Like the patch in that other issue, this patch allows you to filter nodes by their distance from the user location (and allows a static fallback).
However, this patch also allows you to use PHP code to determine the coordinates, both for returning distance as a field returned by the view and the as criteria for filtering. It is possible to filter by distance and then just return that distance as a field (the 'tied' option).
For my own purpose and use case, this patch works, but I'm concerned that it may break some of the existing logic when the distance filter is exposed. Please feel free to test. If I'm convinced that the filtering logic for distance isn't damaged, I may be tempted to commit this patch myself.
-Ankur
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | location-718928-2.patch | 25.89 KB | rooby |
| #32 | location-718928-32.patch | 45.92 KB | rooby |
| #29 | location-718928-29.patch | 45.77 KB | rooby |
| #25 | location-718928-25.patch | 45.62 KB | rooby |
| #9 | location-718928-9.patch | 40.83 KB | rooby |
Comments
Comment #1
evanbarter commentedHi there. I wrote the patch in the issue you referenced. Haven't had time to give yours a good review, however I like the idea. Unfortunately it wouldn't cover my use case as users can have multiple locations in my app (I wrote it with the filter being exposed in mind). Any chance we'd be able to combine efforts on this?
I'd love to get his functionality committed, and, while it's a separate issue, I'd like to get http://drupal.org/node/606342#comment-2160156 cleaned up and committed too, as I think it'd bring a lot of functionality people are asking for.
Comment #2
rooby commentedLooks good.
I have made a few changes, let me know what you think (I got on a bit of a roll).
Changes are:
* Incorporates evan23's requirement of allowing users to choose which of their locations to use. similar to what he has in his patch in #362648: views distance filter by user location (only for the exposed form as it isn't useful otherwise) - Currently there isn't any niceness if a user has no locations, they will just get a blank select element, so that will need a little something.
* Merged the old 'Form mode' option form the proximity filter's exposed form with the new origin option.
* Changed the origin option on the proximity filter to be a select element. This is because it isn't part of the $form['value'] tree so it doesn't display nicely if it is taller than the operator option.
* Added option_definition for the new options.
* Added the postcode and country options for the sort and field handlers so they are more inline with the filter handler.
* Removed the units option from the sort handler as it is not required.
* Added support for distances that span the date line (same as in #606342: Views Argument Handler for Proximity).
* Added some missing descriptions on form elements.
* Added your PHP code option to the sort handler.
* When the use map option is selected it now gives a message that is can't display the map in live preview instead of trying to display the map and messing up the page.
* Removed duplicate commented lines from _location_convert_distance_to_meters() (thought I'd try sneak that one in while that function is being modified - pointless lines)
Seeing as it is very very late it'll need a few people's testing.
NOTE: With the merging of the old 'Form mode' option and the origin option old sites could definitely break, as you mentioned.
I should be able to do a little option migration in a hook_update_N to fix that without much trouble though. When I've had some sleep.
Comment #3
rooby commentedMarked #362648: views distance filter by user location as duplicate of this now that this patch as the exposed filter user location selection functionality.
Credit goes to evan23 for that part.
Comment #4
yesct commentedwow.
Comment #5
hutch commentedfilter, field and sort all working fine on my testrig ;-)
Only tested with static lat/lon
Comment #6
hutch commentedBack in April there was a patch that allowed the use of nid as an argument, this made it possible to create a views block showing links to 'nearby' nodes, really nice feature. I can't find the original thread but the patch is called "location_views_handler_filter_proximity.inc_.node_arg_0.patch" and is dated 11 April 2010
It would be very cool if that could be woven in to this patch. I tried to do it myself but it would not work.
Comment #7
rooby commentedI've seen that one around somewhere too. I'll have a look into it tonight.
I'll also update the patch in #606342: Views Argument Handler for Proximity with a couple of the changes in here so it is in line with the field/filter/sort handlers.
Comment #8
rooby commentedHere is an updated patch.
Changes are:
* Added hook_update_N() to update views that are currently using the distance/proximity filter. It moves the 'Form mode' setting into the 'Origin' setting. So people views should not break now.
* Removed the default setting for the old 'Form mode' setting.
The issue hutch referred to in #6 is #767946: Allow the proximity filter to use a node argument's location as a center.
I'll keep that one in it's own issue as it's functionality doesn't really overlap with this one, and i'll re-roll it to apply over this one.
Comment #9
rooby commentedI started working on #767946: Allow the proximity filter to use a node argument's location as a center and it got a bit messy and I found some other things to sort out.
So I ended up combining that issue in with this patch as it was easier to manage.
I know they shouldn't really all be in the same patch and it makes the large patch a bit harder to review so I can possibly split it out if anyone minds. It'll just be a bit of extra work.
So this update (should be the last unless people find problems) has:
* The node argument stuff from #767946: Allow the proximity filter to use a node argument's location as a center - Credit to those in that issue will be given.
* * I changed their patch so you can select which argument to use. This also allows selection of Global: Null arguments, which are probably the most useful for this functionality because they don't also limit your output.
* * I also added their functionality to the field & sort handlers.
* Put back in the tied origin option for the field and sort handlers. It must have been accidentally cut out in one of the previous patches.
* There are a lot of origin options now so I made it a select field. If anyone thinks they really should be radios it can be changed back.
* There are some similarities in the code between field, sort and filter handlers. I made these parts so they are the same in each. - As a side note, there is a lot of duplicate code across these handlers, it would be good to maybe make functions the can be used across handlers. That is less important though. Can be done any time.
The proximity handlers seem fairly complete now so I'll stop now :)
Comment #10
rooby commentedMarked #767946: Allow the proximity filter to use a node argument's location as a center as a duplicate of this as that functionality is now in this patch.
Comment #11
hutch commentedThank you rooby, I will test this over the next few days ;-)
Comment #12
hutch commentedI have tested the patch in #9 pretty thoroughly, on its own and with #606342: Views Argument Handler for Proximity and it works well with 'classic' Location. It does not work with CCK location, indeed I can't really see how it could.
I haven't tested the PHP code feature though.
Comment #13
yesct commentedI dont know if that scares me, or makes me sad. I use location cck exclusively....
Comment #14
hutch commentedThere probably is a way but Views is a temperamental beast and CCK is hard to follow too, I've chased around through the code and can't see how at the moment. Of course it needs to be supported in the end.
Comment #15
rooby commentedIt seems to work for me. I've only had a quick glance but if you use a relationship it should work.
Only thing missing is some sort of option to use a cck location field as the origin to measure the distance from.
I'll have a proper test a bit later.
Comment #16
yesct commentedah, hope!
Comment #17
rooby commentedIt looks good to me for CCK fields.
Like with most other dealings with node views and CCK location fields it requires the 'Content: Location' relationship for the CCK location field you want to use.
I have tested most of the 'Origin' options with CCK and they work, including the PHP code option. I have not yet tested the postal code based options.
The only option that doesn't relate to CCK location fields is the "Node's Latitude / Longitude from views nid argument" option, which specifically uses the node location of the given nid.
For this I could add the option to use a CCK location field for the given node id instead of the node lcoation. A select field of any CCK location fields in the system could be provided to choose from. If the field doesn't exist on the given nid you would just get no results, like any other time there are no coordinates.
Sound like an OK option?
Also, as a note for myself to fix, the origin option:
"User's Latitude / Longitude from views nid argument"
should read:
"User's Latitude / Longitude from views uid argument"
Comment #18
rooby commentedMarked #767280: Postal code proximity filter "appears" to not work in views as a duplicate of this as this patch will fix the problem reported there.
Comment #19
rooby commentedI have tested CCK locations to work with the post code options now too.
If you are having any problems with the post code proximity stuff not working make sure you have uploaded the zipcodes database file for the country you are trying to use. Also note that the au & be files are wrong so they don't work properly for this use. See #830352: postcode database files for au & be have lat/lon reversed..
Comment #20
hutch commented@rooby, This sounds like a good option. If you can post a patch I'll test ASAP.
I notice that there is the option 'Use a relationship' in several other places apart from the 'Content: Location' relationship, should they be ignored?
Comment #21
rooby commentedI'll add that extra option tomorrow and post back a new patch.
In the relationships part of views you add a new relationship 'Content: Location' for the CCK location field you want to use.
Then, wherever you want to use a location field that is part of the CCK field you need to select 'Location' (or whatever you called the relationship if you didn't use the default label) for the use a relationship option.
This goes for arguments, fields, sort fields, filters.
Basically the relationship links the node in the view to the location object of the CCK field.
Then when you say use the relationship you are using the location object instead of the node object.
You can also have other relationships with things like users to get full access to user objects in a node view etc.
Relationships are a pretty cool and powerful part of views and can be super useful.
I should probably add a README.txt with this information because I think a lot of peoples issues with CCK location and views might be related to this need for a relationship.
Comment #22
hutch commentedI have been attempting a debug of the 'node_arg' method in
location_views_handler_filter_proximity.inc in an attempt to figure out how to get it to work with CCK_location.
I stuffed
$tempnodeinto print_r() and sent it to watchdog so I could have a good look at it.This led me to replace lines 338 and 339
with
where 'field_location' is the name of the CCK_location object
Now it works with CCK_location
The Views setup:
Relationships is Content: Location
Arguments is (Location) Node: Nid
Fields is (Location) Node: Title
Filters is (Location) Location: Distance / Proximity with nid as arg method.
Of course this is no solution but it might help in finding one ;-)
Comment #23
rooby commentedYeah, that will sort that part out. The other part of it is making an option to select which field to use, which will be pretty straight forward too.
I'll knock it over when I get home tonight.
A few things that might make your life easier:
For your debugging of $tempnode, if you have the devel module enabled try replacing your watchdog call with:
It's an invaluable function for debugging.
Another devel one that can be very useful sometimes is:
Which instead of outputting to the screen outputs to a drupal_debug.txt file in whatever directory your site uses for its temp file directory (/tmp by default).
And for the views relationships, you only need to use the relationship when you want to pull data from a related object.
So in this case, node is the base object and location is the related object, because we want the cck location instead of the node location.
So for your views setup you would want:
Relationships is Content: Location
Arguments is (Do not use a relationship) Node: Nid
Fields is (Do not use a relationship) Node: Title
Filters is (Location) Location: Distance / Proximity with nid as arg method.
Also, if you haven't tried out the Global: Null argument you should have a look. I would say it is more useful with the distance filter than the Node: Nid argument is because you can pass your nid into it and the filter can use it but doesn't affect the output.
Although I suppose the Node: Nid argument with the 'Exclude the argument' option would do almost the same thing.
Comment #24
hutch commentedAh yes I had forgotten about dpm and dd is new to me, very handy
I've stuck with Node: Nid argument with the 'Exclude the argument' option, Global null did not exclude the node used in argument
I also got sort to work using Use Distance / Proximity filter.
Sort Criteria (Location) Location: Distance / Proximity asc
And thanks for the explanation re objects, much clearer now.
This is motoring along very nicely, thanks rooby
Comment #25
rooby commentedYeah, I didn't even consider the 'Exclude the argument' until I was writing that last comment. That would probably be most useful.
Here is an updated patch.
* It fixes the text in "User's Latitude / Longitude from views uid argument" as mentioned in #17.
* For the "Node's Latitude / Longitude from views nid argument" there is now an option to select whether to use node locations or a CCK location field. FOr multiple location fields the first location is used.
* I fixed a couple of other bugs too. The field & sort handlers has code copied from the filter handler which wasn't valid (it was using $this->value instead of $this->options for a few things). So before the distance field and sort didn't work for:
"Node's Latitude / Longitude from views nid argument"
"User's Latitude / Longitude from views uid argument"
"Postal Code / Country"
"Postal Code (assume default country)"
Seems to be working much better now.
Using some of those options with a couple of different CCK location fields and couple of views relationships is pretty darn confusing.
I think I definitely should put some info about it in a readme.txt
Comment #26
yesct commentedhurray, this is really exciting. When things get all set, I can make a few screen casts of "how to" also for documentation. Many of the issues in the queue right now, have been: how do i ...
:)
Comment #27
hutch commentedPatch in #25 works for node arg with CCK_location in Live Preview, both default and block display.
However I am unable to get the block to display when visiting the node's page. I put dd in and found that $nid is not being loaded by $nodehandler->get_value() circa line 358 in location_views_handler_filter_proximity.inc
So much for my CCK_location testrig
Loaded the patch into a fresh copy of location in a testrig using 'classic' location, when I tried to edit the proximity filter got a nasty:
From php.log
[18-Jun-2010 18:36:24] PHP Fatal error: Call to undefined function content_fields() in /path/to/my/sites/example.com/modules/location/handlers/location_views_handler_filter_proximity.inc on line 181
This Drupal instance does *not* have cck installed.
So I added
if (module_exists('cck'))and wrapped it around line 181 and the foreach thereafter and all is well ;-)Something similar will be required for sort and the others as well I guess.
The block *does* work with 'classic' location BTW ;-)
Perhaps the time has come to build a handlers_common.inc for these shared bits to go into.
Comment #28
rooby commentedYeah, I forgot about testing blocks. Oops.
Oops to assuming cck exists too.
Yeah, I was thinking about the shared code thing last night too. It's definitely needed.
Will break out the common code in the next update.
Comment #29
rooby commentedUpdate.
Changes are:
* Fixed the error when cck is not enabled.
* Fixed a couple of minor bugs with the default options for the filter handler.
* Moved a few common pieces of code into location.views.inc functions that are called from all the proximity handlers.
I haven't had a chance to test blocks properly so i'll do that next.
Comment #30
rooby commentedI have a view using proximity/distance field, sort and filter based on an nid argument with the "Action to take if argument is not present: " argument option set to default value using "Node ID from URL".
Using this setup with CCK location fields I can get it all working with a block on a node page.
If yours is still not working can you post a txt file of your views export?
Comment #31
hutch commentedHmmm struggling here, tried the patch in #29 got WSOD, php.log says
[24-Jun-2010 14:30:03] PHP Fatal error: Call to undefined method location_views_handler_filter_proximity::calculate_coords() in /my/path/to/sites/example.com/modules/location/location.views.inc on line 482
So I've rolled back to #25
Tried
"Action to take if argument is not present: " argument option set to default value using "Node ID from URL".
It works with CCK
Hurray!
Comment #32
rooby commentedI've had a quick look and this patch should fix the problem you were seeing in #31.
I'm pretty ready for bed so I'll have a proper test of it tomorrow.
Comment #33
johnthomas00 commentedThanks for your efforst guys. This is exciting.
I could not get #32 to work. Same error as #31.
In case it is helpful,
http://drupal.org/node/357295 #30 has a solution
http://drupal.org/files/issues/location.357295.patch that has been working great for me.
Comment #34
rooby commentedI have tested this again with no issues and have tested the hook_update_N again with no issues.
Committed to 6. If we don't have issues with it in the next couple of days we should be good for a new release.
Thanks for all the testing.
@johnthomas00
I already committed before you posted.
What error are you seeing with #32?
Was it the one hutch mentioned in #31? - "[24-Jun-2010 14:30:03] PHP Fatal error: Call to undefined method location_views_handler_filter_proximity::calculate_coords() in /my/path/to/sites/example.com/modules/location/location.views.inc on line 482"
I have tested #32 and that error is gone (I also know it's gone as I removed the offending line).
Are you sure you tested #32?
If you can check out the latest version from cvs can you test that and see if you are getting your error. If not can you test the latest dev when it is updated (sometime in the next 12 hours)?
Comment #35
rooby commentedAlso, #357295: Proximity Search based on lat/lon, using views arguments was marked as a duplicate of this issue so that issue is closed now and this one takes its place. This issue provides the functionality of that issue + more. If there is something in that issue that this patch doesn't do let me know.
Comment #36
rooby commentedCommitted to 7 as well.
http://drupal.org/cvs?commit=387932
http://drupal.org/cvs?commit=387930
Comment #37
johnthomas00 commentedJust tried CVS, getting:
[Sun Jul 04 07:39:02 2010] [error] [client 10.8.0.22] PHP Fatal error: Call to undefined method location_handler_field_location_distance::_get_reference_location() in /var/www/drupal/all/modules/location/handlers/location_handler_field_location_distance.inc on line 131, referer: http://example.com/myview
Comment #38
rooby commentedThanks for that.
For anyone who wants to know it affected table view click sorting on the distance/proximity field.
Committed the fix to 6 & 7.
I didn't make a patch but here is the diff for the 6 commit.
http://drupal.org/cvs?commit=387936
http://drupal.org/cvs?commit=387934
Comment #39
johnthomas00 commentedThanks, that fixed it.
Could you help me get this to work. I will show you what I am trying, perhaps you can suggest where I am blowing it:
I am am attaching a view to a node to show nearby nodes.
I add an argument to my view, of the Node Nid default from the URL.
I add the location distance proximity field to my view.
My view only has one node, the node I am viewing (because that is an argument). I was hoping to have all nodes with the distance, and then filter sort to the nearby ones.
Comment #40
rooby commentedIf you use the Node: Nid argument as is you will only get the one node.
There are two other options:
1. If you want your view to display all nodes EXCEPT the node that is the nid argument use the Node: Nid argument and check the "Exclude the argument" option (the last option) for that argument.
2. If you want your view to display all nodes INCLUDING the node that is the nid argument use the Global: Null argument. That argument will not affect the view's output but can be used by your distance field & sort.
Does that solve your problem?
Comment #41
johnthomas00 commentedYes, (thanks for the Global:Null trick, I will remember that.)
I had to do a few things to convert my views to this new method. Everything works AWESOME!! Thanks!
Comment #42
rooby commentedNo worries, glad to help.
Comment #44
dpatte commentedsub
Comment #45
rooby commented@dpatte:
No need to subscribe to issues that are already fixed.
See http://drupal.org/node/156119 for more information.
This functionality is already in the module.
Comment #46
dpatte commentedI subscribed as a way of bookmarking this page for later reference