FriendsOfSymfony / FOSFacebookBundle

NOT MAINTAINED - see https://github.com/hwi/HWIOAuthBundle
321 stars 140 forks source link

Abstracting Facebook API functions #78

Open TomiS opened 12 years ago

reisba commented 12 years ago

This abstracts the process of performing same basic tasks through Facebook API, such as retrieving user information and publishing posts as the user to user's own stream or as a Facebook page to a user controlled page. If there is interest to add this functionality to FOSFacebookBundle, pleaser feel free.

Justification would be that it is often a basic functionality that you use Facebook connectivity on a site for and it can be occasionally annoying and time consuming to follow the api changes of Facebook or learn how to do this functionality on your own. I'd find it easier to have it centralized in one place and if anything changes, you'll need to change your code only in one place (this bundle) and the developer would not necessarily need to know the specifics how the Fb api actually works.

How sending a message works is you create a container object for the message, call a service to handle the sending and order it to post the message. Example:

$streamPost = new fosStreamPost();
$streamPost->setMessage("Hello world");
// optional image
$streamPost->setAttachment("my image name", "caption text", "http://image_url...");
$facebookPush = $this->get("fos_facebook.facebook_push");
// send to user stream
$facebookPush->publishStream($streamPost);
// or facebook page
$facebookPush->publishPage($streamPost, "pageid");
reisba commented 12 years ago

@stof I committed fixes that should fix up the majority of the pull request's issues reported above. Any other stuff that needs fixing that is preventing this from being accepted?

schmittjoh commented 12 years ago

I'm not sure we should add such code to this bundle. You can easily add that to your application if you need another abstraction layer on top of the Facebook SDK.

lsmith77 commented 12 years ago

well we all know that the Facebook SDK's are horribly managed. so in that regards anything that makes it easier to deal with their madness is good. but it sounds a bit beyond the scope of this Bundle. aka maybe this should be a separate lib, which we might in the end want to use instead of directly using the official Facebook SDK, but that would then need to be reviewed.

reisba commented 12 years ago

That's pretty much my motivation too: anything to make it easier to manage the interaction towards FB. Every time I've implemented stuff on our sites that deal with Facebook, part of it has always been the authentication and part of it has been pushing data to their api: it's always been very intertwined. So I thought having this functionality that you need the most in thew same Bundle that you can just add to your project and be done with it (without worrying about anything additional configurations) felt like a good idea.

But yea, of course, if you feel this bloats FOSFacebook beyond what you feel is reasonable, I do understand.

TomiS commented 12 years ago

Hi @schmittjoh and others who are against this addition

Just to add weight to the earlier comment from my colleague @reisba. The rationale for adding the new abstraction layer is based on a couple of years of experience in suffering with the shitty backwards compatibility policy of Facebook API. Adding another layer might not be the 'thinnest' or even most elegant possible solution but it definitely has proven useful in daily work. And, as far as I understand, shouldn't making daily work easier be the whole point of wrapping stuff in bundles afterall? Furthermore, you could compare this case to databases or filesystems. They also have abstraction layers just to make it easier for all developers to use the 'feature' without needing to actually completely understand how it works. In our (small) company we have figured that it is certainly enough that one person suffers the mental punishment caused by the frequent changes in Facebook API so that the rest of us doesn't have to.

A separate lib might also be an option as proposed by @lsmith77 but, on the other hand, I don't see the need for it when there's a nice FacebookBundle already available that could easily be used for abstracting the whole Facebook, and thus, letting us developers out of the misery of using the API directly.

Anyway, here's my thoughts. I'm always interested in hearing if I just haven't understand the whole point of this bundle or something else that is relevant to discussion :)

lsmith77 commented 12 years ago

A separate lib has the big advantage that non Symfony2 users might also contribute and use it. IMHO Bundles should be the thinnest possible glue between some library and Symfony2.

Notice that for example I am in the process of moving out some features of FOSRestBundle into a separate lib.

schmittjoh commented 12 years ago

@TomiS, I generally don't mind adding such code, but currently I'm not seeing the bigger picture here. What is your vision with this library? What kind of abstraction have you planned? How much of the Facebook API do you want to abstract? How do you want to abstract it? Do you plan a data mapper implementation? Does it support synchornization with Facebook? etc.

$facebookManager = new FacebookManager();
$post = new StreamPost();
$post->setTitle('foo');
$facebookManager->persist($post);
$facebookManager->flush();

$post = $facebookManager->find('StreamPost', '1234665452423424');
$post->addComment(new Comment('foo'));
$facebookManager->persist($post);
$facebookManager->flush();

Would something like this be possible?

schmittjoh commented 12 years ago

btw, a data mapper implementation would be awesome because you could re-use the same objects with Doctrine ORM, et.al. and cache their content on your local server without any additional effort.

TomiS commented 12 years ago

@schmittjoh, to be honest, we don't have a bigger picture figured out yet. In our previous framework, we have just abstracted the most frequently used Facebook API functions and added features when we needed some. Mostly they are just authentication using facebook connect and posting stuff to one's Facebook stream. But of course there could be something else too, we just haven't needed that stuff yet.

About your mapper implementation idea. I think I see the point there. It would be nice that the usage pattern (from programmer point of view) would be the same as with any Doctrine Object. However, I'm wondering if the method persist is suitable here because we (at least) have never stored anything we push to Facebook. It's been fire and forget similar to email spamming in our applications. So I'm just asking just out of curiosity, what would be the use case for caching Facebook shares locally?

stof commented 12 years ago

@TomiS the point with this interface is to send the changes only in flush, doing them for the final changeset. Not sure it fits with Facebook though

stof commented 12 years ago

@lsmith77 @schmittjoh what do you think about it finally ? should it be merged ?

lsmith77 commented 12 years ago

i still think it should be a separate lib. there are tons of people out there that have nothing to do that could also benefit from something that isn't as crappy as the Facebook php sdk and putting the "burden" of maintenance on this bundle alone for an alternative is too big and not practical.

stof commented 12 years ago

so creating a standalone library being a wrapper around the Facebook sdk ?

lsmith77 commented 12 years ago

yes .. if this is done right .. it could get a lot of attention.

reisba commented 12 years ago

After searching the github a bit to see if anything similar has been done already, I do see some benefits for implementing this as library. There's a pile of plugins for different frameworks, but nothing really generic caught my eye. If this would be written as a lib, it would definitely remain as more generic piece that you could use anywhere, not just in symfony2 and maybe encourage more contributions to develop it.

This could be thought of more as a lib for abstracting sharing to social media sites (or at least provide support for this) if it's done more in the style like the Gaufrette-lib and the KnpGaufretteBundle have been done for filesystems. We could define an interface that specifies some generic functionality that "all" social media sites support (send messages, get info, ....) and then an adapter class (such as Facebook) that simply maps how this specific social media site API does sending messages etc. The actual adapter can still provide more functionality than defined in the interface and like suggested above, could receive the actual connector class (in the case of Facebook, the FB php-library connector class) as a parameter in its constructor. All it would take for Symfony to use it, would be to map it as a service.