Views integration

lonehorseend - December 15, 2008 - 17:56
Project:Ubercart Addresses
Version:6.x-1.x-dev
Component:Code
Category:feature request
Priority:normal
Assigned:freixas
Status:closed
Description

I have my site set up so that a person is required to enter their name and address information when the register from uc_address. I'd to take some of that information and use it in a view. How would I go about doing this?

#1

freixas - December 15, 2008 - 23:19

In Drupal 5, the Views module only handles nodes, so you are out of luck.

In Drupal 6, Views can handle all sorts of data, but doesn't know anything about the data in uc_addresses. I would need to add some code to hook the uc_addresses data into the Views system. You can request an enhancement if you'd like. It's more likely to get done if you submit a patch with your enhancement request, though :-)

#2

lonehorseend - December 16, 2008 - 09:26
Component:User interface» Code
Category:support request» feature request

It's something I definitely need, so let me see what I can do. It'll definitely need some work though as I'm comfortable with PHP and some module tweaking, but I'm still learning a lot about Drupal 6 and Views 2.

#3

lonehorseend - December 16, 2008 - 18:07
Status:active» needs work

Okay, so here's a start based on what I've been reading.

This needs to be placed in the module itself:

<?php
function uc_address_views_api() {
  return array(
'api' => 2.0);
}
?>

And then we need a new file named uc_address.views.inc, which I've attached because it was so long.

Notes:

1) The join in uc_address.views inc is used to determine default address and I'm not sure how to join both values of uc_address_defaults, so I joined the aid.
2) I used this http://groups.drupal.org/node/17236 as an example for my attempt, wasn't sure what else I needed to do after it. In other words, I'm wondering if we've given Views enough information.
3) Not sure how to translate country, zone, created, and modified back into something that the user would be able to understand on their view since they are stored as integers. Need more research into this.

AttachmentSize
uc_adddress.views_.inc_.txt 6.98 KB

#4

freixas - December 19, 2008 - 01:37

Thanks for your work. I am not going to try out your code at this time since it sounds like you still have work to do. I encourage anyone else who has an interest in using Views with uc_addresses to help out, if you can.

If I get some free time, I may give it a try.

I suspect that the database tables uc_countries and uc_zones can help with the country and zone numbers.

For the join, maybe you need to look at the join for the point of view of the uc_addresses_defaults table. You join the addresses and the users to the defaults table, you don't join the defaults to the addresses table.

Off the top of my head, for uc_addresses_defaults:

SELECT * FROM {uc_addresses_defaults}
LEFT JOIN {uc_addresses} ON {uc_addresses_defaults}.aid = {uc_addresses}.aid
LEFT JOIN {users} ON {uc_addresses_defaults}.uid = {users.uid}
LEFT JOIN {uc_countries} ON {uc_addresses}.country = {uc_countries}.country_id
LEFT JOIN {uc_zones} ON {uc_addresses}.zone = {uc_zones}.zone_id

For uc_addresses, the interesting joins are:

SELECT * FROM {uc_addresses}
LEFT JOIN {users} ON {uc_addresses}.uid = {users.uid}
LEFT JOIN {uc_countries} ON {uc_addresses}.country = {uc_countries}.country_id
LEFT JOIN {uc_zones} ON {uc_addresses}.zone = {uc_zones}.zone_id

I'm sure my syntax is off a bit and I don't know how Views 2 would express these relationships, but it may give you some ideas.

#5

caminoz74 - August 26, 2009 - 13:02

Hi,
I am wondering whether you may any further progress with this patch?? also, its a basic question but when you say "this need to be place in the module itself", where exactly in the module.. i'm not a coder just fumbling my way through!

thanks
Cam

#6

lonehorseend - August 26, 2009 - 17:58

Hey Cam:

It's been a while since I worked on this. A long while as I moved onto other stuff. I'd have to go back and revisit what I did. But usually if I don't give a specific line number it means that it can be placed anywhere in the module, just so its there.

#7

caminoz74 - August 26, 2009 - 22:09

Thanks for getting back to me... I put it in the views.module file at the bottom and then added the file to the views/modules folder as mentioned with no joy?? the fields did not appear when I created a user view?

I am assuming this was tested so i'll try again but at this stage I can't see how to get it working... i'm no good on coding so i'll see how I go!

cheers
cam

#8

caminoz74 - August 26, 2009 - 23:47

I have now, just incase, tried to put the code into the uc_addresses.module file and the attachment into the addresses root folder... still no joy??

really appreciate a couple of basic tips!!!

thanks

#9

madsph - August 27, 2009 - 13:07

@lonehorseend

caminoz74 ask for help with this in the uc_views project, so I took the time to look into your patch to see if I could get it to work.
I had to make a few adjustments, but other than that it works fine.

I was wondering if you would allow me to add this as a sub module of uc_views?

#10

freixas - August 27, 2009 - 13:44

@madsph

Wouldn't it make more sense to patch uc_addresses than to add this to uc_views? If you add this to uc_views, database changes would require patching two modules owned by two different people and on two different release schedules.

#11

caminoz74 - August 27, 2009 - 14:27

Hi Freixas,

Not knowing much about the coding side of things, this is an interesting thought. In my case, I want to use the uc_addresses module so users can access their My Account page to maintain contact details AND I need to be able to have these fields available to the Views module.

???

#12

lonehorseend - August 27, 2009 - 20:36

@madsph
Sure. Whenever I post stuff, I put it where I'm answering a question. If it works somewhere else, great! I don't mind it being moved there. But freixas is right, it makes more sense to keep the patch for uc_address so there is only one set of files that needs to be updated and maintained.

@ Cam:
Sorry for the confusion. Guess I should have added that the code was meant for uc_address and not views. Usually the function line will show what module something goes to. The patch definitely was not ready for primetime. Thanks to madsph for fixing it!

#13

yanku - August 28, 2009 - 06:06

subscribing

#14

madsph - August 28, 2009 - 08:28

@freixas + @lonehorseend

You are absolutely right - uc_addresses is the right place to put it.
The reason I suggested to put it into uc_views is that I use some of the view_handlers from uc_views to display and filter content nicely, so there is a dependency there. The dependency to uc_addresses is much harder though.

Also from a maintainance point of view (if the uc_addresses tables altered or expanded) it would be more safe to have the views in that module.

I'll add the module here so freixas can fit it into the uc_addresses.

By the way - there is some minor code clean up that could still be performed (eg. using table schema to provide help texts rather than hard coding) - I can do that for you if you are interested.

AttachmentSize
uc_views_addresses.zip 2.49 KB

#15

freixas - August 28, 2009 - 14:18

Any and all code clean-up would be appreciated. Thanks for the offer!

Regarding the dependency on uc_views: I haven't looked at the patch yet, but I would like it to be an optional dependency—if you don't have uc_views installed, then you don't get the integration with Views., but everything else still works.

#16

freixas - August 28, 2009 - 15:58

OK, I looked at the patch. It looks like I can add it as a sub-module within uc_addresses. People can decide whether to enable it or not. If they enable it, they have to install uc_views; if not, they don't.

I'll go ahead and add this.

#17

freixas - August 28, 2009 - 17:01

I'm not a Views expert or a uc_views expert, but something in the module doesn't feel right.

There are two tables used by uc_addresses: uc_addresses and uc_addresses_defaults. The useful joins are: uc_adresses + user and uc_addresses_defaults + uc_addresses + user. Not useful would be to join uc_addresses + uc_addresses_defaults, which is what it looks like this module does. Of course, I may be misunderstanding.

A left join of uc_adresses with uc_addresses_defaults would return a table containing only the addresses that are default addresses. This table would also have a duplicate field name: uid (this assumes the join field is not included, otherwise the 'aid' field would also be duplicated). Of course, maybe the code does some automatic renaming? In any case, this code looks suspicious:

<?php
$data
['uc_addresses']['table']['base'] = array(
   
'field' => 'aid',
   
'title' => t('Address'),
   
'help' => t("Ubercart Address fields."),
   
'weight' => -9,
  );

$data['uc_addresses']['aid'] = array(
   
'title' => t('Default address'),
   
'help' => t('The default address for the user'),
   
'relationship' => array(
     
'label' => t('Address'),
     
'base' => 'uc_addresses_defaults',
     
'base field' => 'aid',
    ),
  );
?>

I'm trying to figure out what this means and failing. The default address for a user is obtained by joining the users table with the uc_addresses_defaults table and then with the uc_addresses table. Again, I'm flailing around here, but would it make more sense to have two Views groups, one for uc_addresses and one for uc_addresses_defaults?

The only thing that makes sense relative to uc_addresses and the default address would be a computed field that says whether the address is a default address. To do this right, I believe you need a right join or else you only get addresses that are default addresses.

madsph, can you clarify any of this?

#18

madsph - September 1, 2009 - 16:42

I am not an expert in uc_addresses but I think you are right I will take a look into it and get back to you.

#19

madsph - September 2, 2009 - 10:48

I have given this another shot - just yesterday I finished the first version of a drupal code generation tool that so far has the ability to generate views definitions for db-tables (http://drupal.org/project/code_gen if you a interested).

So I thought why not try it with this :-).

So i did that and added the more specific handlers for some of the fields - added a relationship to users for uc_addresses table, and created a filter handler for the aid field of uc_addresses that lets you filter on default address or not.

I hope this solves the issues you raised.

I also defined uc_addresses_defaults for views although I can't think of a good use for it right now - so you may want to leave that out for now.

AttachmentSize
uc_views_addresses.zip 9.39 KB

#20

freixas - September 2, 2009 - 12:40

Thanks for all your hard work! I'll give it a shot as soon as I have a moment.

As for uc_addresses_defaults: this might actually be useful. I'm guessing that you would be able to generate a list of all users and their default address (which, one hopes, is their primary contact information). This might valuable for the store owner.

Actually, I am guessing that you will get a list of all users with a default address unless you do a right join from the uc_addresses_defaults table to the users table (or a left join of the users table with the uc_addresses_table). On some systems, not all users will have an address. However, on systems where uc_addresses is installed from the start and where addresses are required during registration, the uc_addresses_defaults table will include all users.

I'll know more once I take a look at the code and try it out.

#21

madsph - September 3, 2009 - 08:02

Yes a view with a users default addresses is definitely valuable - so I included a filter for the aid field of uc_addresses that can do that - what it actually does is that it adds the following where clause to the select:

WHERE uc_addresses.aid = (SELECT uad.aid FROM uc_addresses_defaults as uad
                                                 WHERE uad.uid = (SELECT ua.uid from uc_addresses as ua where ua.aid = uc_addresses.aid))

I know this seems silly instead of just making the correct joins through uc_addresses_defaults - but it was the only way I could think of that lets us use uc_addresses independently of uc_addresses_defaults which we might also want to do at times.

This could be optimized if I could get the uid of uc_addresses without making the last select (hmmm .... while thinking of it right now I should be able to replace that with simply uc_addresses.uid - I'll try that and get back to you)

#22

madsph - September 3, 2009 - 08:09

Yes there was of course a simpler way to do it.

Here is a new filter that adds the following where clause in stead:

WHERE uc_addresses.aid = (SELECT uad.aid FROM uc_addresses_defaults as uad WHERE uad.uid = uc_addresses.uid)

Please note that the .txt extension is only to please the upload file filter.

AttachmentSize
uc_views_addresses_handler_filter_default_address.inc_.txt 545 bytes

#23

freixas - September 6, 2009 - 21:24
Assigned to:Anonymous» freixas

Just a (non) progress report:

I made a few changes to the last patches from madsph:

  • Changed the name from uc_views_addresses... to uc_addresses_view...
  • The titles for the most fields is obtained through uc_get_field_name() so that they match what the user sees.
  • Tweaked some names ("aid" to "Address ID").

I suspect I screwed up something because nothing new shows up when I try to create a new view. The thing to do is to go back to the last patch and verify that it works without any changes, but I'm out of time right now. I'll get back to it soon.

#24

madsph - September 7, 2009 - 06:22

If you upload your version I will have a look at it to see if I can figure out what is wrong.

#25

freixas - September 9, 2009 - 21:28

@madsph

Thanks for the offer of assistance. I felt that before sending you my code, I should try your code without any changes.

First, I disabled my version and removed the code. Then I installed your last uc_views_addresses module and then added the new uc_views_addresses_handler_filter_default_address.inc.

I enabled the module and went to create a new view. I am running as user 1, so I should have permissions for everything. I looked through the Relationships, Arguments, Fields, Sort criteria and Filters options trying to find a group called "uc_addresses". No luck.

I found a reference to "uc_views..." where "..." wasn't "_addresses":

<?php
 
//int
 
$data['uc_addresses']['zone'] = array(
   
'title' => 'zone',
   
'help' => $uc_addresses['fields']['zone']['description'],
   
'field' => array(
       
'handler' => 'uc_views_handler_field_zone',
       
'click sortable' => TRUE,
    ),
?>

Thinking that there might still be dependence with uc_views (although one wasn't listed), I installed uc_views, which then required me to install views_slideshow. With everything installed and enabled, I still found no uc_addresses groups.

I'm not a Views expert—am I looking in the wrong place? Do I have to enable something? Could you provide a sequence of steps to verify that the group is being created?

As I said, this uses your code without any changes. Every module was installed directly in my sites/all/modules directory (not within uc_addresses). Versions are:

Ubercart Views 6.x-2.0
Views 6.x-2.6
Views Slideshow 6.x-1.0-beta2
Ubercart 6.x-2.0-rc6

Thanks for any help.

#26

madsph - September 10, 2009 - 06:13

Strange ...

I will try and make a clean install and let you know the steps. I am of to a meeting in an hour, that will take the rest of my day, so I hope I will be able to complete this by then - otherwise I will have to get back to you tomorrow.

#27

madsph - September 10, 2009 - 06:48

Okay, I have made a clean install now doing the following:
1. Install drupal 6.13
2. Install modules:
- All of the "Ubercart - core" modules
- The "Views" modules - views, exporter and ui
- The "Ubercart extra" modules - Addresses and uc_views_addresses (this will also install uc_views - I added that as a dependency)
3. Create adresses for the admin user
- One home address (default)
- One work address (not default)
4. Create the view (I will make one that you can import)

I have attached the modules uc_views, uc_views_addresses and uc_addresses that I use so we are sure to test on the same environment.

AttachmentSize
uc_address_test.zip 75.18 KB
deafult_address_view_for_import.txt 11.38 KB

#28

freixas - September 28, 2009 - 16:36

Hi, madsph,

Sorry for the delay. I've been on vacation the last week and was pretty busy before I left. I have two questions for you:

  1. Are you saying that the configuration you just created works correctly with your Views addition?
  2. If I duplicate your build, what steps would I take to verify that the Views code you added for uc_addresses is working as expected?

Thanks!

#29

madsph - September 29, 2009 - 11:32

Welcome back :-)

Basically, if you follow the steps using the modules included in the zip file. Then you should be able to import the view in the txt file, which should verify that the code works.

Hope that explains it.

#30

caminoz74 - September 30, 2009 - 01:20

just to add support... I have installed the modules as madsph has provided and they work great!!

I know I am just peripheral to all the actual coding so just saying thanks heaps for all the work... this is going to bring a full uc/views/directory listing together for me (and others)... gmap intergration with is next!! (I hope)

all the best

#31

freixas - October 6, 2009 - 16:59

I finally had a chance to try this out again.

As I said, I am not a Views expert. The problem I had came from the fact that I selected "Node" in the first step for creating a view. If I select "User", your code appears to work.

Putting the address into the "User" category isn't quite right, although it works. Let's say I wanted to display all addresses in the USA. I can define this view and get it to work, but here is the SQL code:

SELECT users.uid AS uid,
   uc_addresses.city AS uc_addresses_city
FROM users users
LEFT JOIN uc_addresses uc_addresses ON users.uid = uc_addresses.uid
WHERE uc_addresses.country in ('840')

This SELECT has an unnecessary JOIN. The correct code would be:

SELECT uc_addresses.city AS uc_addresses_city
FROM uc_addresses
WHERE uc_addresses.country in ('840')

I don't know how hard it would be to add a "Ubercart Addresses" type to the set of View types, but that would be the right way to add this.

The other thing I am having trouble with is the dependency on uc_views. Originally, I argued that this enhancement should be added to uc_addresses rather than uc_views; otherwise, "changes would require patching two modules owned by two different people and on two different release schedules." With the dependency on uc_views, this problem occurs regardless of where the code is added.

Given this and the fact that I am no Views expert, that I didn't produce the code and that uc_addresses maintenance tends to be at the bottom of my queue, I am reversing my position. madsph, if it is acceptable to you, please go ahead and add this module to your set of Ubercart Views enhancements.

I would make the following recommendations, but they are your choice:

  • If you could create a Views type of Ubercart Addresses, that would be great!
  • The titles for the most fields should be obtained through uc_get_field_name() so that they match what the user sees (refer to the code in uc_addresses_address_pane.inc).
  • It would be nice to make the names more readable and consistent with the style used by Views. For the View type or group, "uc addresses" should be "Ubercart Addresses". Then change the field titles as described above (using uc_get_field_name()). There are still two fields left. I would rename these as: aid => Address ID, uid => User ID.

Let me know if this sounds OK to you. Thanks for all your work!

#32

madsph - October 7, 2009 - 07:22

You are right about the sql - and also the solution. We need to make uc_addressess a base table for views - which is no trouble at all.

I can also maintain the code in the uc_views project, if you think that is best. Under any circumstances I will make this a separate module, so people do not need to install Ubercart Addresses to get the rest of the view stuff I am doing. That means we can easily move the code back to your project if you change your mind later.

Using uc_get_field_name is also a good idea - I wasn't aware that a helper function for address field names existed - but it is clearly the right way to do it in this case.

I will post back when I have a module ready for download with uc_views.

#33

madsph - October 7, 2009 - 11:46

The module has been added to the 6.x-3.x-dev of uc_views with freixas suggestions.

#34

freixas - October 7, 2009 - 14:54
Status:needs work» closed

madsph: Thanks again for all your work, not just for adding Views support for uc_addresses, but also for other parts of ubercart. I think I will add a note on the front page of the uc_addresses module, so people will know about your module.

I am closing this feature request.

 
 

Drupal is a registered trademark of Dries Buytaert.