08
Feb
2011
admin

Mit dem Zend Framework eine Facebook Anwendung erstellen - Teil 2

Im ersten Teil dieses Tutorials haben wir das Zend Framework und unsere Facebook Anwendung soweit vorbereitet, dass wir die Startseite unseres Projektes auf der Facebook Leinwand-Seite sehen können (z.B. http://apps.facebook.com/atw-zend/). Als nächstes werden wir uns damit beschäftigen, wie wir mit dem Zend Framework auf die Facebook API zugreifen können.

Dazu müssen wir uns als erstes natürlich wieder die Facebook PHP SDK herunterladen und in unserem Projekt einbinden. Ich habe dafür ein weiteres Unterverzeichnis im Ordner library angelegt, welches ich Abouttheweb genannt habe. In diesem Verzeichnis liegt die Datei facebook.php aus dem PHP SDK Downloadarchiv, welche dort im Verzeichnis src zu finden ist. Damit ergibt sich nun folgende Ordnerstruktur:

facebook-anwendungen-mit-dem-zend-framework-lib.jpg

Damit hätten wir unser Projekt soweit vorbereitet, dass wir nun loslegen können. Als erstes binden wir die Facebook Library ein, damit wir in unserem Projekt darauf zugreifen können. Der Übersicht halber habe ich das in der Bootstrap Klasse gemacht:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

  protected function _initFacebook()
  {
    require_once 'Abouttheweb/facebook.php';
  }

}

Um nun den Zugriff auf Facebook zu organisieren, werden wir uns ein Model erstellen. Dieses Model erhält den Namen Facebook und wird wieder mit dem Zend Tool erstellt:

zf create model Facebook

Damit wir in unserem Model auf das Facebook Objekt und dessen Methoden zugreifen können, werden wir unser Model von der Facebook Klasse erben lassen.

class Application_Model_Facebook extends Facebook
{

  /**
   * Facebook application ID.
   */
  const APP_ID      = '152782611441849';

  /**
   * Facebook application secret.
   */
  const APP_SECRET  = '7a5aeb8b1a014eb8b2f39720432b5cf5';

  /**
   * Facebook cookie support.
   */
  const COOKIE  = true;

  /**
   * Initialize a Facebook Application.
   *
   * The configuration:
   * - appId: the application ID
   * - secret: the application secret
   * - cookie: (optional) boolean true to enable cookie support
   * - domain: (optional) domain for the cookie
   * - fileUpload: (optional) boolean indicating if file uploads are enabled
   *
   * @param Array $config the application configuration
   */
  public function  __construct($config) {
    // If no appId is specified in the $config array, use self::APP_ID
    if (!isset($config['appId'])) {
      $config['appId'] = self::APP_ID;
    }
    // If no secret is specified in the $config array, use self::APP_SECRET
    if (!isset($config['secret'])) {
      $config['secret'] = self::APP_SECRET;
    }
    // If the cookie parameter is not set, use self::COOKIE
    if (!isset($config['cookie'])) {
      $config['cookie'] = self::COOKIE;
    }
    parent::__construct($config);
  }
}

Erklärung
Im Konstruktor des Models schauen wir als erstes nach, ob als Parameter die Anwendungs ID und das Anwendungs Geheimnis übergeben, sowie der Cookie Support spezifieziert wurden. Wenn nicht, nutzen wir dafür unsere vordefinierten Konstanten. Das hat den Grund, dass ich beim Initialisieren eines Objektes nicht jedes Mal diese Daten angeben möchte, mir aber trotzdem nicht die Möglichkeit nehmen lassen will, die Daten an bestimmten Stellen zu überschreiben.

Um den bisher erstellten Code ein mal zu testen, werden wir nun den indexController bearbeiten und dort eine Instanz unseres Models erzeugen und ausgeben lassen.

class IndexController extends Zend_Controller_Action
{

    public function init() {
      /* Initialize action controller here */
    }

    public function indexAction() {
      $fb = new Application_Model_Facebook();
      Zend_Debug::dump($fb);
      exit;
    }

}

Die Ausgabe sieht wie folgt aus:

facebook-anwendungen-mit-dem-zend-framework-dump-fb-object.jpg

Sehen wir uns die Ausgabe genau an, sehen wir, dass die Eigenschaften session und signedRequest beide null sind. Daran lässt sich z.B. sehen, dass die Anwendung keine Berechtigung hat, auf unsere Daten zuzugreifen und API Abfragen zu starten, um etwas über uns zu erfahren. Ein paar grundlegende Informationen können wir allerdings schon jetzt erfahren. Dazu ändern wir nun als erstes unseren indexController leicht ab.

class IndexController extends Zend_Controller_Action
{

    public function init() {
      /* Initialize action controller here */
    }

    public function indexAction() {
      Zend_Debug::dump($this->_getAllParams());

      $fb = new Application_Model_Facebook();
      Zend_Debug::dump($fb);
      exit;
    }

}

Wir erhalten ein weiteres Array, welches den codierten signedRequest enthält.

facebook-anwendungen-mit-dem-zend-framework-dump-signed-request.jpg

Der signedRequest befindet sich im $_REQUEST Array, wird aber nicht standardmäßig von unserem Objekt abgefragt. Um die Daten daraus im Klartext zu erhalten, können wir die Methode getSignedRequest() benutzen, die in der Facebook PHP SDK enthalten ist. Eine andere Möglichkeit den signedRequest zu erhalten, ist der Aufruf der Methode getSession(), welche wiederum getSignedRequest() aufruft.

class IndexController extends Zend_Controller_Action
{

    public function init() {
      /* Initialize action controller here */
    }

    public function indexAction() {
      $fb = new Application_Model_Facebook();
      $fb->getSession();
      Zend_Debug::dump($fb);
      exit;
    }

}

Die Ausgabe enthält nun den dekodierten signedRequest.

facebook-anwendungen-mit-dem-zend-framework-dump-signed-request-decrypted.jpg

Wie man sieht, bleibt die Eigenschaft session weiterhin null, da wir die Anwendung ja noch nicht autorisiert haben, Daten von uns abzufragen. Wie in den vorangegangenen Tutorials auch, können wir getSession() nun nutzen, um den Benutzer zum Autorisierungs-Dialog weiterzuleiten, sollte er unsere Anwendung noch nicht autorisiert haben. Im entgegengesetzten Fall, werden wir die Daten des Benutzers ausgeben. Dafür werden wir im Model eine Methode hinzufügen, die uns die Daten des Benutzers liefert. Außerdem fügen wir eine weitere Konstante hinzu, die die Basis URL zum OAuth Dialog enthält.

class Application_Model_Facebook extends Facebook
{

  /**
   * Facebook application ID.
   */
  const APP_ID      = '152782611441849';

  /**
   * Facebook application secret.
   */
  const APP_SECRET  = '7a5aeb8b1a014eb8b2f39720432b5cf5';

  /**
   * Facebook cookie support.
   */
  const COOKIE      = true;

  /**
   * Base URL of the OAuth dialog.
   */
  const OAUTH_URL   = 'https://www.facebook.com/dialog/oauth';

  /**
   * Initialize a Facebook Application.
   *
   * The configuration:
   * - appId: the application ID
   * - secret: the application secret
   * - cookie: (optional) boolean true to enable cookie support
   * - domain: (optional) domain for the cookie
   * - fileUpload: (optional) boolean indicating if file uploads are enabled
   *
   * @param Array $config the application configuration
   */
  public function  __construct($config = null) {
    // If no appId is specified in the $config array, use self::APP_ID
    if (!isset($config['appId'])) {
      $config['appId'] = self::APP_ID;
    }
    // If no secret is specified in the $config array, use self::APP_SECRET
    if (!isset($config['secret'])) {
      $config['secret'] = self::APP_SECRET;
    }
    // If the cookie parameter is not set, use self::COOKIE
    if (!isset($config['cookie'])) {
      $config['cookie'] = self::COOKIE;
    }
    parent::__construct($config);
  }

  public function getUserInfo() {
    return $this->api('/me');
  }
}

Im indexController werden wir nun mit der Methode getSession() abfragen, ob der Benutzer unsere Anwendung autorisiert hat. Wenn ja, bekommt er seine Daten ausgegeben, wenn nicht, wird er auf den Autentifizierungs Dialog weitergeleitet. Dafür bauen wir im indexController den Link zum Autentifizierungs Dialog zusammen und rendern das View Script redirect.phtml, welches die Umleitung, bzw. den Redirect, ausführt.

class IndexController extends Zend_Controller_Action
{

    public function init() {
      /* Initialize action controller here */
    }

    public function indexAction() {
      $fb = new Application_Model_Facebook();

      if (!$fb->getSession()) {

        $this->view->redirect_url =
               Application_Model_Facebook::OAUTH_URL
               . '?client_id='.Application_Model_Facebook::APP_ID
               . '&scope=user_birthday'
               . '&redirect_uri='.$_SERVER['HTTP_REFERER']
               . '&response_type=token';
        $this->_helper->viewRenderer->setScriptAction('redirect');

      } else {

        Zend_Debug::dump($fb->getUserInfo());
        
      }
    }

}

Das benötigte View Script redirect.phtml legen wir wieder mit dem Zend Tool an.

zf create view index redirect

Das View Script redirect.phtml enthält nun die Weiterleitung, die wir, wie immer, mit Javascript vornehmen, da wir uns hier in einem IFrame befinden und deshalb nicht einfach einen Redirect Header mit PHP senden können. Das View Script enthält also folgendes:

<script type="text/javascript">
  top.location = "<?php print $this->redirect_url; ?>";
</script>

Bestätigen wir nun den Autentifizierungs Dialog, erhalten wir unsere Daten als Array.

facebook-anwendungen-mit-dem-zend-framework-me-dump.jpg

Hinweis
Du kannst alle Codebeispiele von AboutTheWeb über ein SVN Repository auschecken. Dieses Beispiel findest du unter folgender Adresse:
http://svn.abouttheweb.de/atwtutorials/trunk/zendfb/

Alternativ kannst Du alle Codebeispiele über das AboutTheWeb github Repository auschecken.

ACHTUNG:
Das Zend Framework ist im Repository nicht enthalten!

Trackback-URL für diesen Beitrag

http://abouttheweb.de/trackback/632

Mit dem Zend Framework eine Facebook Anwendung erstellen - Teil

Mit dem Zend Framework eine Facebook Anwendung erstellen - Teil

Ähnliche Artikel

Bild des Benutzers stefan
stefan
Mo, 02/21/2011 - 13:05

Hi!

Vielen Dank für diese Tutorial.

Ich bekomme jedoch beim Aufruf:
$fb = new Application_Model_Facebook();
im indexController folgenden Fehler:

Warning: Missing argument 1 for Application_Model_Facebook::__construct(), called in /application/controllers/IndexController.php on line 14 and defined in /application/models/Facebook.php on line 11

Die Funktion _construct($config) scheint ohne Übergabe von $config nicht laufen zu wollen.

Wie hast du das gelöst?

Danke und Gruss

Bild des Benutzers admin
admin
Mo, 02/21/2011 - 13:13

Hallo Stefan,

das ist eine Warnung, weil der Konstruktor einen Parameter erwartet.
ändere den Konstruktor der Facebook Klasse mal etwas ab:

public function  __construct($config = null)

Ich habe es im Tutorial ebenfalls abgeändert.
Das sollte deinen Fehler beheben.

Bild des Benutzers stefan
stefan
Mo, 02/21/2011 - 13:41

Danke hat geholfen!

Bild des Benutzers stefan
stefan
Mo, 02/21/2011 - 17:28

Sorry, muss dich noch mal nerven

Ich krieg die Session einfach nicht zum laufen. Ich vermute mal, dass da was mit dem Schlüssel falsch läuft. Gibt es eine Möglichkeit Facebook beim Aufruf von getSession() Fehlermeldungen zu entlocken?

Danke!

Bild des Benutzers stefan
stefan
Mo, 02/21/2011 - 18:38

Wie gesagt, bei mir hat der Aufbau der Session nicht funktioniert

Habe dann dies

$_session = $fb->getSession();
    	if (!$_session) {
    		$url = $fb->getLoginUrl(array(
    			'canvas' => 1,
    			'fbconnect' => 0
    		));
    		$this->view->redirect_url = $url;
    		$this->_helper->viewRenderer->setScriptAction('redirect');
    	}

eingefügt und damit zum Laufen gebracht.

Gruesse

Bild des Benutzers admin
admin
Mo, 02/21/2011 - 20:36

Hallo Stefan,

die von dir genutzte Methode ist die "alte" Variante. In diesem Beispiel nutze ich die neueren Dialoge zur Authentifizierung. Irgendwas war offensichtlich an deiner redirect_url nicht in Ordnung. Was das war, lässt sich natürlich schlecht sagen.

Hast du das Beispiel aus dem SVN-, bzw. github-Repository ausgecheckt? Ansonsten könnten sich beim Abtippen, bzw. copy&paste Fehler eingeschlichen haben.

Bild des Benutzers Peter
Peter
Do, 03/31/2011 - 02:02

Hi,

ich bekomme diesen Fehler nachdem letzten Schritt?

Message: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Jemand eine Idee?

Bild des Benutzers admin
admin
Do, 03/31/2011 - 09:34

@Peter
Das sollte behoben sein, wenn du in der Facebook PHP SKD folgende CURL Optionen hinzufügst:

CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 2
X
Laden