Thursday, October 22, 2009

FB Connect and cakePHP

When building a website using cakePHP and FB Connect it is important to take note of the cakePHP routing.  If you have done some customizing in your cakephp routes.php file, it may cause some problems when you try to use the FB Connect login-button.

To be safe, turn off all routing for cakePHP when it accesses the xd_receiver.htm file.

/** 
* turn off cakephp routing for facebook connect xd_receiver
*/
Router::connect('/xd_receiver.htm', null);

Wednesday, September 09, 2009

Fixing default cakePHP pagination in FBML

CakePHP pagination generates relative URLs that look like

/posts/view/page:5

when you use

$paginator->prev()
$paginator->numbers()
$paginator->next()

This doesn't work in FBML, so you need to sort of hack the PaginatorHelper to display it as

http://apps.facebook.com/someapp/posts/view/page:5

So you change function link() to

function link($title, $url = array(), $options = array()) {
        $options = array_merge(array('model' => null, 'escape' => true), $options);
        $model = $options['model'];
        unset($options['model']);

        if (!empty($this->options)) {
            $options = array_merge($this->options, $options);
        }
        if (isset($options['url'])) {
            $url = array_merge((array)$options['url'], (array)$url);
            unset($options['url']);
        }
        if(!isset($_SERVER['HTTP_X_FB_USER_REMOTE_ADDR']) ) {
            $url = $this->url($url, true, $model);
            $obj = isset($options['update']) ? 'Ajax' : 'Html';
            $url = array_merge(array('page' => $this->current($model)), $url);
            $url = array_merge(Set::filter($url, true), array_intersect_key($url, array('plugin'=>true)));
        } else {
            //if its part of the facebook app, preprend http://apps.facebook.com/dev_zenmanga to the $url
            $obj = isset($options['update']) ? 'Ajax' : 'Html';
            $url = 'http://apps.facebook.com/someapp' . substr(parent::url($url), true);
        }
        return $this->{$obj}->link($title, $url, $options);
    }

$_SERVER['HTTP_X_FB_USER_REMOTE_ADDR']
will print out the server IP that your facebook app is hosted on, so if that is set, then we know we are running on the facebook server.

A better way will be to write in your config/bootstrap.php

if(isset($_SERVER['HTTP_X_FB_USER_REMOTE_ADDR'])){
        Configure::write('App.base', 'http://apps.facebook.com/someapp/');
    }