So excuse the title, but for lack of a better way to describe everything together, I'll explain a little more in depth.
So for a project I'm currently working on, the customer has requested a Facebook login for its users, things get complicated because they also want a user profile page and a folder or storage area to upload images which can be tagged and displayed throughout the site based on some prerequisites...
I suppose the question here is how to best implement this idea, yes yes, that's pretty broad I know... I've already taken a look at the cs.auth.facebook package, but I find it lacks any flexibility in controlling the API requests without modifying the actual code. The default userschema is too minimalist for my needs, I tried creating a custom userschema.xml so as to define some custom fields and parameters, but it's still not quite what I need. I suppose it's more tailored to a default site user rather than a custom one..?
This leaves me with Products.membrane which if I'm honest, I've yet to test fully, but looks like what I may need.
So following on from this, what would be your approach to creating a custom user with a Facebook login and storing some files that user may upload. The following requirements should be met.
Facebook login
Custom fields to store user defined profile data
A user profile page with overview
A user gallery
Just some hints or pointers would be useful! Thanks peeps!
You can use event subscribers to get the user information that you need when the user logs into your site. There are two interfaces that describe events for which you can subscribe and get the information you need from Facebook:
Thanks for the fast reply, that will definitely be useful... But I'm still trying to figure out the best way to create a profile page then, or what the best way of doing so would be. Take for example this forum, when you navigate to /users/erral for example, I can see your profile. Assuming you're logged in, you can also add some content or change some field data. So how would you go about this with the Facebook login..?
I guess you need to create some folder users and in there return a dynamic view-name from the username? Could you/someone please elaborate a little on this..?
In Plone you can create Member folders, by default in /Members/erral, but the path can be configured, and even the content-type of that folder can be configured.
So I did as you said and everything is running smoothly, managed to setup a user folder environment with a custom Content-Type to handle any extra profile fields I'd like to store. So thanks for that!
My next question comes back around to the cs.auth.facebook plug-in...
However, reading through the API docs shows that there's a slew of other fields I can use. Do you know if there's some way of requesting extra data with the plug-in, without having to modify the code..? Just wondering, in case you've had some experience using it..?
When we developed the plugin, we decided to get the minimal information possible from Facebook to be able to identify the user and let event subscribers or other views to get extra information. Moreover at that time some extra permissions were required to get some other information from API, so we let it as it is.
At this moment we get that information you say and also the profile photo using login event subscribers.
OK, I think I'll use a combination of both plug-ins, maybe I can integrate a sync button or something... @erral - I was wondering why the other FB Graph fields weren't being returned, so I guess you need to request them separately... So for this maybe I'll use the pas.plugins.authomatic plug-in.
I have just 1 final question to wrap this up, really great help you guys! The profile_image saved by cs.auth.facebook, when calling the MemberData object for the user, using the getProperty('portrait') method, returns some image binary... Is there a way of displaying this in the template or do I need to convert and save the binary as a NamedBlobImage object..?
Edit:
I also tried using getPersonalPortrait with api.portal.get_tool('portal_membership') accompanied by the current user ID, but this just returns the defaultPortrait.png image...
If you are saving it in the member folder as a field it will be already available as a field, so you can render it using the standard @@images view and plone.app.imaging.
session = self.object.REQUEST.SESSION
portal = api.portal.get()
current_user = api.user.get_current()
...
# Checks if user is of type FacebookUser
...
available_fields = dict()
fields = [
'location',
'address',
'locale',
'first_name',
'last_name',
'about',
'email',
]
values = get_auth(context=portal, user=current_user.id, fields=fields)
for field in fields:
if field in values:
available_fields[field] = values[field]
session.set('fb_data', available_fields)
From there I redirect to the member folder and assign the fields with any available session data.
There's probably a better way to do this, but it seems to work so... For now, mission accomplished.