CakePHPでFacebookにConnect、wallに投稿する機能つくってみました。

facebookが日本でもだいぶ認知されてきました。ユーザ数も増えてきて、facebookユーザを自分のアプリに取り込んでみたいと思っている人もいると思います。そこで、今回は、CakePHPfacebookにconnectして、wallに投稿する機能を実装してみました。

実装する上でやったこと。
1.facebookデベロッパー登録。
2.facebookアプリ登録。
3.facebookphpsdkをダウンロードして配置する。場所はapp/vendors/facebookfacebookディレクトリは自分で作成しておく。
4.facebook-php-sdkのbase_facebook.phpをすこしいじる。
5.コードを書く。

今回は3〜5の手順を説明します。1と2に関しては既に文献がたくさんありますから。

今回は、以下のサイトを参考にさせていただきました。
facebook アプリの作り方・PHP 編(2010 年 10 月版) - 19790401173.4
PHP で Facebook アプリをつくろう
Facebookプロモーション | アドコード
Into my web: CakePHPでFacebookにConnectしてみた

3.facebookphpsdkをダウンロードして配置する。
facebook/php-sdk · GitHub
からsdkをダウンロードします。
次に、facebook-php-sdkというフォルダ名をfacebookとします。(名前は正直どうでもいいです。)
app/vendorsに配置します。なので、app/vendors/facebookという感じになると思います。

4.app/vendors/facebook/src/base_facebook.phpをいじる。
461行目にあるgetLoginUrl()という関数を修正します。

public function getLoginUrl($params=array()) {
    $this->establishCSRFTokenState();
    $currentUrl = $this->getCurrentUrl();
    return $this->getUrl(
      'www',
      'dialog/oauth',
      array_merge(array(
                    'client_id' => $this->getAppId(),
                    'redirect_uri' => $currentUrl, // possibly overwritten
                    'state' => $this->state),
                  $params));
  }

上が修正前のものです。

public function getLoginUrl($params=array()) {
    $this->establishCSRFTokenState();
    $currentUrl = $this->getCurrentUrl();
    return $this->getUrl(
      'www',
      'dialog/oauth',
      array_merge(array(
                    'client_id' => $this->getAppId(),
                    'redirect_uri' => 'コールバックに指定するURLを記述する。ここでは(http://hogehoge.com/cake/examples/callback/)とする。', // possibly overwritten
                    'state' => $this->state),
                  $params));
  }

5.ソースを公開します。公開用にコードを修正、削除した部分がありますので、もしかしたらそのままでは動かない場合もあると思います。

テーブル構造

CREATE TABLE IF NOT EXISTS `examples` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `facebook_id` bigint(64) NOT NULL,
  `facebook_access_token` varchar(200) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `created` datetime NOT NULL,
  `updated` datetime NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=60 ;

コントローラ

<?php
App::import('Vendor','facebook',array('file' => 'facebook'.DS.'src'.DS.'facebook.php'));
class ExamplesController extends AppController {
    public $uses = array('Example');
    public $facebook;
    
    public function beforefilter(){
    	
    	$this->Auth->allow('index','facebook','callback');
    	
    	$this->Auth->loginRedirect = array('controller' => 'examples','action' => 'test');
    	$this->Auth->logoutRedirect = array('controller' => 'examples','action' => 'logout');
    	$this->Auth->loginAction = '/examples/login';
    	
    	//facebookでのログインフィールド設定
    	$this->Auth->fields = array('username' => 'facebook_id',
    				     'password' => 'facebook_access_token');
    
    	
    	parent::beforeFilter();	
    }    
	
	public function index(){//認証なしでも入れる一般ページ
		
	}
	
	public function login(){
	
		if ($this->Auth->login($this->data)) {
			$this->redirect($this->Auth->redirect());
		}
	}
	
	public function facebook(){//facebookの認証処理部分		
		$this->autoRender = false;  
                $this->facebook = $this->createFacebook();
    	        $url = $this->facebook->getLoginUrl(array('redirect_url' => '','scope' => 'email,publish_stream','canvas' => 1,'fbconnect' => 0));
       	$this->redirect($url);
	}
	
	public function callback(){//facebookの認証処理部分
	$this->facebook = $this->createFacebook();
    	$me = null;
		$user = $this->facebook->getUser();
          
    	if ($user) {
    		$me = $this->facebook->api('/me');
    	} else {
    		
    	}
            
        
    	$access_token = $this->facebook->getAccessToken();//access_token入手
    	$test = $this->Example->find('first',array('conditions' => array('facebook_id' => $me['id'])));
    	
    	$this->Example->facebook(
				Array(
        		              'facebook_id' => $me['id'],
            	                      'username' => $me['first_name'].'.'.$me['last_name'],
            	                      'facebook_access_token' =>  $access_token,
            	                      )
            );//facebookのデータからユーザ登録を行う
    	
    	
		$this->data['Example']['facebook_id'] = $me['id'];
		$this->data['Example']['facebook_access_token'] = $access_token;
		
		
		
		if ($this->Auth->login($this->data)){//Authの処理
			$this->redirect($this->Auth->redirect());//ログイン成功したら、リダイレクト
		} else {
			//$this->redirect('/examples/index/');//失敗したら、元のページへもどる
		}
		
    							
	}
	
	public function logout(){
		$this->Auth->logout();
		$this->flash('トップページにとぶ','index');
	}
	
	public function test() {//ログイン後のトップページ
		$data =$this->Auth->user();
		print_r($data);
		
	}
	
	public function post() {//facebookのwallにpostする処理
		if (!empty($this->data)) {
		
		$data =$this->Auth->user();
		$user = $this->Example->findById($data['Example']['id']);
                $this->facebook = $this->createFacebook();
		$attachment =  array(
    	'access_token' => $user['Example']['facebook_access_token'],
    	'message' => $this->data['Example']['facebook_wall'],
    	'name' => "name test",
    	'link' => "",
    	'description' => "here description",
    	'picture'=> "http://example.jp/image.jpg"
		);
		$this->facebook->api('/me/feed', 'POST', $attachment);
		
		$this->flash('マイページに戻ります','/examples/test/');
		
		}
	}

       private function createFacebook() {
    
         return new Facebook(array(  
        'appId'  => 'アプリID',
        'secret' => 'アプリの秘訣',  
    ));
    }

}

モデル

<?php
class Example extends AppModel
{
	public $name = 'Example';
	
	/*
	 * うまい具合にメンバーの登録・更新ができる関数
	 */
	
	public function facebook($example_data)//facebookと上手く連携して、ユーザ登録ができる関数
	{
		$example = $this->find('first', array('conditions' => array('facebook_id' => $example_data['facebook_id'])));
		if ($example) {
			$example_data['id'] = $example['Example']['id'];
		}
		$this->create();
		$this->save(Array("Example" => $example_data));
	}
	
}

ビュー
views/examples/post.ctp

<?php echo $form->create('Example',array('action' => 'post','type' => 'post')); ?>
<?php echo $form->input('Example.facebook_wall'); ?>
<?php echo $form->end('submit'); ?>

views/examples/index.ctp

<?php echo $html->link('facebookでログイン','/examples/facebook/'); ?>