-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit of barebones facebook-connect integration with SilverS…
…tripe
- Loading branch information
0 parents
commit 3db3505
Showing
12 changed files
with
1,340 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
Copyright (c) 2010, Will Rossiter | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
* Redistributions of source code must retain the above copyright | ||
notice, this list of conditions and the following disclaimer. | ||
* Redistributions in binary form must reproduce the above copyright | ||
notice, this list of conditions and the following disclaimer in the | ||
documentation and/or other materials provided with the distribution. | ||
* Neither the name of the organization nor the | ||
names of its contributors may be used to endorse or promote products | ||
derived from this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY WILL ROSSITER ''AS IS'' AND ANY | ||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL Will Rossiter BE LIABLE FOR ANY | ||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# Facebook Connect Integration Module | ||
|
||
## Maintainer Contact | ||
* Will Rossiter | ||
<will (at) silverstripe (dot) com> | ||
|
||
## Requirements | ||
* SilverStripe 2.4 or newer. | ||
|
||
## Overview | ||
The module provides a **basic** interface for implementing facebook connect on a website. Specifically its to integrate | ||
user sign-on and sign up on a SilverStripe website - for example allowing login functionality by facebook rather than | ||
the existing security. You can extend it using your own code but for now this is a super basic edition | ||
|
||
### What it provides | ||
|
||
* Loads and setups Facebook Connect interactivity | ||
* Authenticates users visiting the site - if they are logged into facebook then you can access there information via | ||
the following controls. You can also optionally set whether to save visitors information as members on your site | ||
(for example if you need to cache their information) | ||
|
||
If you haven't disabled the FacebookConnect::$create_member variable you can access the facebooks member information | ||
by using.. | ||
|
||
<% control CurrentMember %> | ||
$FirstName $LastName $Picture(small) | ||
<% end_control %> | ||
|
||
If you have disabled the creation of members you can use the facebook specific member control. This still returns a | ||
member object the only difference is that it won't save the information to the database | ||
|
||
<% control FacebookCurrentMember %> | ||
$FirstName $LastName $Picture(small) | ||
<% end_control %> | ||
|
||
### What it does not provide (yet) | ||
|
||
* This current iteration only provides the backbone. In future updates I am aiming to integrate things like publishing | ||
stories to a users wall, interacting with events, groups and other things like friends. | ||
|
||
* More controls over the logged in members information (eg status updates, events, groups) | ||
|
||
### How to use | ||
|
||
* To setup facebook connect your first need to download this and put it in your SilverStripe sites root folder. | ||
* You need to register your website / application at http://developers.facebook.com/setup | ||
* Once you have registered your app then set the following in your mysite/_config.php file. Replace the values with the ones | ||
you should get after registering your app | ||
|
||
FacebookConnect::set_api_key('api-key'); | ||
FacebookConnect::set_api_secret('api-secret'); | ||
FacebookConnect::set_app_id('api-id'); | ||
|
||
* You need to add the fb: namespace to your Page.ss file. For example your <html> tag at the top should look like | ||
|
||
<html lang="en" xmlns:fb="http://www.facebook.com/2008/fbml"> | ||
|
||
* Once you have done that you should be able to use the includes provided in this module. Note you must include the ConnectRoot.ss | ||
include. So include the following code in your template | ||
|
||
<% include ConnectRoot %> | ||
<% if FacebookConnectMember %> | ||
<p>Hi $FacebookConnectMember.FirstName | ||
<% include ConnectLogout %> | ||
<% else %> | ||
<% include ConnectLogin %> | ||
<% end_if %> | ||
|
||
* You can also access the facebook member information in your PHP code. The Facebook API connection and current member are | ||
cached on the controller object. So for example if this is in your Page_Controller class | ||
|
||
$this->CurrentFacebookMember(); // returns the current facebook member (wrapped in a SS Member Object) | ||
$this->getFacebook(); // returns the API connection which you can use to write your own query | ||
|
||
### Configuration | ||
|
||
By default users who login to your site via facebook (and give your website permission) are created member objects and saved to | ||
your database. If you wish to turn off saving member data to your database you can set it in your mysite/_config.php file | ||
|
||
FacebookConnect::set_create_member(false) | ||
|
||
However if you want this functionality enabled (which it is by default) but the members saved in a special group you can define | ||
the groups to add them to (mailing lists, user permissions etc) by defining the following in your mysite/_config.php file | ||
|
||
FacebookConnect::set_member_groups('facebook-members'); | ||
|
||
Or as an array | ||
|
||
FacebookConnect::set_member_groups(array('group-1', 'group-2')); | ||
|
||
### License | ||
|
||
Released under the BSD License. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
// configuration for facebook connect. You should not edit any of these | ||
// values and instead override from the mysite/_config file | ||
|
||
// adds an extension hook to member | ||
DataObject::add_extension('Member', 'FacebookMember'); | ||
|
||
DataObject::add_extension('Controller', 'FacebookConnect'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
<?php | ||
|
||
/** | ||
* Main controller class to handle facebook connect implementations. Extends the built in | ||
* SilverStripe controller to add addition template functionality. | ||
* | ||
* | ||
* @package facebookconnect | ||
*/ | ||
|
||
class FacebookConnect extends Extension { | ||
|
||
/** | ||
* When a user iteracts with the website should we create a | ||
* {@link Member} on the site with their details and login that {@link Member} | ||
* object via {@link Member->login()} | ||
* | ||
* This is enabled by default since most apps (like forum) need valid | ||
* {@link Member} objects. To disable this set {@link FacebookConnect::set_create_member(false)} | ||
* | ||
* By setting this to true we also require the 'email' permission from the | ||
* open graph as members still need to be tided to emails as the identifier. | ||
*/ | ||
private static $create_member = true; | ||
|
||
/** | ||
* If creating members is enabled then its a smart idea to set a group | ||
* to save all the members too. For instance you might want to save all fbconnect | ||
* members automatically to your mailing list. | ||
* | ||
* You must have {@link FacebookConnect::$create_member} set to true (as it is by default) | ||
* for this to make any effect. | ||
* | ||
* @var Array array('groupcode', 'groupcode1') | ||
*/ | ||
private static $member_groups = array(); | ||
|
||
/** | ||
* The permissions which you require for your application. The facebook api has a | ||
* list of all the permissions. If you leave the $create_member option to true | ||
* by default it adds the email permission no matter what you set here | ||
* | ||
* @see http://developers.facebook.com/docs/authentication/permissions | ||
* @var Array | ||
*/ | ||
private static $permissions = array(); | ||
|
||
/** | ||
* @var Facebook - facebook client | ||
*/ | ||
private $facebook; | ||
|
||
/** | ||
* @var Member The facebook member logged in | ||
*/ | ||
private $facebookmember; | ||
|
||
private static $api_key = ""; | ||
|
||
private static $api_secret = ""; | ||
|
||
private static $app_id = ""; | ||
|
||
/** | ||
* Sets whether a {@link Member} object should be created when a facebook member on the | ||
* site authenicates. If this is set to false to access the member and its data you will | ||
* have to use <% control CurrentFacebookMember %> rather than <% control CurrentMember %> | ||
* | ||
* @param bool | ||
*/ | ||
public static function set_create_member($bool) { | ||
self::$create_member = $bool; | ||
} | ||
|
||
public static function create_member() { | ||
return self::$create_member; | ||
} | ||
|
||
public static function set_member_groups($group) { | ||
if(is_array($group)) { | ||
self::$member_groups = $group; | ||
} | ||
else { | ||
self::$member_groups[] = $group; | ||
} | ||
} | ||
|
||
public static function get_member_groups() { | ||
return (count(self::$member_groups) > 0) ? self::$member_groups : false; | ||
} | ||
|
||
public static function set_permissions($permissions = array()) { | ||
self::$permissions = $permissions; | ||
} | ||
|
||
public static function get_permissions() { | ||
return self::$permissions; | ||
} | ||
|
||
public static function set_api_key($key) { | ||
self::$api_key = $key; | ||
} | ||
|
||
public static function set_api_secret($secret) { | ||
self::$api_secret = $secret; | ||
} | ||
|
||
public static function set_app_id($id) { | ||
self::$app_id = $id; | ||
} | ||
|
||
public static function get_app_id() { | ||
return self::$app_id; | ||
} | ||
|
||
public static function get_api_secret() { | ||
return self::$api_secret; | ||
} | ||
|
||
public static function getFacebook() { | ||
return $this->facebook; | ||
} | ||
|
||
/** | ||
* Extends the built in {@link Controller::init()} function to load the | ||
* required files for facebook connect. | ||
*/ | ||
public function onBeforeInit() { | ||
$this->facebook = new Facebook(array( | ||
'appId' => self::get_app_id(), | ||
'secret' => self::get_api_secret(), | ||
'cookie' => true, | ||
)); | ||
|
||
$session = $this->facebook->getSession(); | ||
|
||
if($session) { | ||
try { | ||
$result = $this->facebook->api('/me'); | ||
|
||
if($result) { | ||
|
||
// check to see if a member already with that email | ||
$email = (isset($result['email'])) ? $result['email'] : false; | ||
if($email) { | ||
$member = DataObject::get_one('Member', "Email = '". Convert::raw2sql($email) ."'"); | ||
|
||
if(!$member) $member = new Member(); | ||
} | ||
else { | ||
// create a new member object can cache it on this controller. | ||
// if we have create member object enabled then we can also write | ||
// it to the database and log that member in! | ||
$member = new Member(); | ||
} | ||
|
||
$member->Email = (isset($result['email'])) ? $result['email'] : ""; | ||
$member->FirstName = (isset($result['first_name'])) ? $result['first_name'] : ""; | ||
$member->Surname = (isset($result['last_name'])) ? $result['last_name'] : ""; | ||
$member->FacebookLink = (isset($result['link'])) ? $result['link'] : ""; | ||
$member->FacebookUID = (isset($result['id'])) ? $result['id'] : ""; | ||
$member->FacebookTimezone = (isset($result['timezone'])) ? $result['timezone'] : ""; | ||
$this->facebookmember = $member; | ||
|
||
if(self::create_member()) { | ||
$member->write(); | ||
$member->logIn(); | ||
|
||
if($groups = self::get_member_groups()) { | ||
foreach($groups as $group) { | ||
Group::add_to_group_by_code($member, $group); | ||
} | ||
} | ||
} | ||
} | ||
} catch (FacebookApiException $e) { | ||
user_error($e, E_USER_WARNING); | ||
} | ||
} | ||
|
||
// add the javascript requirements | ||
Requirements::customScript(<<<JS | ||
(function() { | ||
var e = document.createElement('script'); | ||
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js'; | ||
e.async = true; | ||
document.getElementById('fb-root').appendChild(e); | ||
}()); | ||
JS | ||
); | ||
|
||
$appID = self::get_app_id(); | ||
$sessionJSON = json_encode($session); | ||
|
||
Requirements::customScript(<<<JS | ||
window.fbAsyncInit = function() { | ||
FB.init({ | ||
appId : '$appID', | ||
session : $sessionJSON, | ||
status : true, | ||
cookie : true, | ||
xfbml : true | ||
}); | ||
FB.Event.subscribe('auth.login', function() { | ||
window.location.reload(); | ||
}); | ||
}; | ||
JS | ||
); | ||
} | ||
|
||
/** | ||
* If {@link FacebookConnect::set_create_member()} is set to false then the build in | ||
* CurrentMember functionality will not be functional. If the user has specifically | ||
* overridden the create member then they can update to use this function. | ||
* | ||
* It wraps the raw data fields from facebook. | ||
* | ||
* @return ArrayData | ||
*/ | ||
public function CurrentFacebookMember() { | ||
return ($this->facebookmember) ? $this->facebookmember : false; | ||
} | ||
|
||
/** | ||
* Logout link | ||
* | ||
* @return String | ||
*/ | ||
public function FacebookLogoutLink() { | ||
return $this->facebook->getLogoutUrl(); | ||
} | ||
|
||
/** | ||
* Permissions to require on the login button | ||
* | ||
* @return String | ||
*/ | ||
public function FacebookPermissions() { | ||
|
||
$permissions = self::get_permissions(); | ||
|
||
if(self::create_member()) { | ||
$permissions = $permissions + array('email'); | ||
} | ||
|
||
return implode(',', $permissions); | ||
} | ||
} |
Oops, something went wrong.