More rewriting of Facebook lib.
authorMichael J. Rubinsky <mrubinsk@horde.org>
Tue, 24 Feb 2009 15:47:48 +0000 (10:47 -0500)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Wed, 25 Feb 2009 19:13:11 +0000 (14:13 -0500)
Move FQL queries and Events methods to separate classes.
Don't *always* assume we want to pass the session_key.
Break out some common code into a Base class

framework/Service_Facebook/lib/Horde/Service/Facebook.php
framework/Service_Facebook/lib/Horde/Service/Facebook/Auth.php
framework/Service_Facebook/lib/Horde/Service/Facebook/Base.php [new file with mode: 0644]
framework/Service_Facebook/lib/Horde/Service/Facebook/Events.php [new file with mode: 0644]
framework/Service_Facebook/lib/Horde/Service/Facebook/Fql.php [new file with mode: 0644]
framework/Service_Facebook/lib/Horde/Service/Facebook/Request.php
framework/Service_Facebook/package.xml

index 57ac429..89e83af 100644 (file)
@@ -269,130 +269,6 @@ class Horde_Service_Facebook
         $this->_batchRequest = null;
     }
 
-
-    /**
-     * Returns events according to the filters specified.
-     *
-     * @param int $uid            (Optional) User associated with events. A null
-     *                            parameter will default to the session user.
-     * @param string $eids        (Optional) Filter by these comma-separated event
-     *                            ids. A null parameter will get all events for
-     *                            the user.
-     * @param int $start_time     (Optional) Filter with this unix time as lower
-     *                            bound.  A null or zero parameter indicates no
-     *                            lower bound.
-     * @param int $end_time       (Optional) Filter with this UTC as upper bound.
-     *                            A null or zero parameter indicates no upper
-     *                            bound.
-     * @param string $rsvp_status (Optional) Only show events where the given uid
-     *                            has this rsvp status.  This only works if you
-     *                            have specified a value for $uid.  Values are as
-     *                            in events.getMembers.  Null indicates to ignore
-     *                            rsvp status when filtering.
-     *
-     * @return array  The events matching the query.
-     */
-    public function &events_get($uid=null, $eids=null, $start_time=null,
-                                $end_time=null, $rsvp_status=null)
-    {
-        // Note we return a reference to support batched calls
-        //  (see self::call_method)
-        return $this->call_method('facebook.events.get',
-            array('uid' => $uid,
-                  'eids' => $eids,
-                  'start_time' => $start_time,
-                  'end_time' => $end_time,
-                  'rsvp_status' => $rsvp_status));
-    }
-
-    /**
-     * Returns membership list data associated with an event.
-     *
-     * @param int $eid  event id
-     *
-     * @return array  An assoc array of four membership lists, with keys
-     *                'attending', 'unsure', 'declined', and 'not_replied'
-     */
-    public function &events_getMembers($eid)
-    {
-        return $this->call_method('facebook.events.getMembers', array('eid' => $eid));
-    }
-
-    /**
-     * RSVPs the current user to this event.
-     *
-     * @param int $eid             event id
-     * @param string $rsvp_status  'attending', 'unsure', or 'declined'
-     *
-     * @return bool  true if successful
-     */
-    public function &events_rsvp($eid, $rsvp_status)
-    {
-        return $this->call_method('facebook.events.rsvp',
-            array('eid' => $eid,
-                  'rsvp_status' => $rsvp_status));
-    }
-
-
-    /**
-     * Cancels an event. Only works for events where application is the admin.
-     *
-     * @param int $eid                event id
-     * @param string $cancel_message  (Optional) message to send to members of
-     *                                the event about why it is cancelled
-     *
-     * @return bool  true if successful
-     */
-    public function &events_cancel($eid, $cancel_message='')
-    {
-        return $this->call_method('facebook.events.cancel',
-            array('eid' => $eid,
-                  'cancel_message' => $cancel_message));
-    }
-
-    /**
-     * Creates an event on behalf of the user is there is a session, otherwise on
-     * behalf of app.  Successful creation guarantees app will be admin.
-     *
-     * @param assoc array $event_info  json encoded event information
-     *
-     * @return int  event id
-     */
-    public function &events_create($event_info)
-    {
-        return $this->call_method('facebook.events.create', array('event_info' => $event_info));
-    }
-
-    /**
-     * Edits an existing event. Only works for events where application is admin.
-     *
-     * @param int $eid                 event id
-     * @param assoc array $event_info  json encoded event information
-     *
-     * @return bool  true if successful
-     */
-    public function &events_edit($eid, $event_info)
-    {
-        return $this->call_method('facebook.events.edit',
-            array('eid' => $eid,
-                  'event_info' => $event_info));
-    }
-
-    /**
-     * Makes an FQL query.  This is a generalized way of accessing all the data
-     * in the API, as an alternative to most of the other method calls.  More
-     * info at http://developers.facebook.com/documentation.php?v=1.0&doc=fql
-     *
-     * @param string $query  the query to evaluate
-     *
-     * @return array  generalized array representing the results
-     */
-    public function &fql_query($query)
-    {
-        return $this->call_method('facebook.fql.query', array('query' => $query));
-    }
-
-
     /**
      * Returns whether or not pairs of users are friends.
      * Note that the Facebook friend relationship is symmetric.
@@ -476,42 +352,6 @@ class Horde_Service_Facebook
     }
 
     /**
-     * Returns cookies according to the filters specified.
-     *
-     * @param int $uid     User for which the cookies are needed.
-     * @param string $name (Optional) A null parameter will get all cookies
-     *                     for the user.
-     *
-     * @return array  Cookies!  Nom nom nom nom nom.
-     */
-    public function data_getCookies($uid, $name)
-    {
-        return $this->call_method('facebook.data.getCookies',
-            array('uid' => $uid, 'name' => $name));
-    }
-
-    /**
-     * Sets cookies according to the params specified.
-     *
-     * @param int $uid       User for which the cookies are needed.
-     * @param string $name   Name of the cookie
-     * @param string $value  (Optional) if expires specified and is in the past
-     * @param int $expires   (Optional) Expiry time
-     * @param string $path   (Optional) Url path to associate with (default is /)
-     *
-     * @return bool  true on success
-     */
-    public function data_setCookie($uid, $name, $value, $expires, $path)
-    {
-        return $this->call_method('facebook.data.setCookie',
-            array('uid' => $uid,
-                  'name' => $name,
-                  'value' => $value,
-                  'expires' => $expires,
-                  'path' => $path));
-    }
-
-    /**
      * Retrieves links posted by the given user.
      *
      * @param int    $uid      The user whose links you wish to retrieve
@@ -900,12 +740,15 @@ class Horde_Service_Facebook
      *
      * @return boolean  true if the user has authorized the app
      */
-    public function &users_isAppUser($uid=null)
+    public function &users_isAppUser($uid = null, $sid = null)
     {
-        if ($uid === null && isset($this->is_user)) {
-            return $this->is_user;
+        if (empty($uid) && !empty($sid)) {
+            $params = array('session_key' => $sid);
+        } elseif (!empty($uid)) {
+            $params = array('uid' => $uid);
+        } else {
+            throw new InvalidArgumentException('isAppUser requires either a uid or a session_key');
         }
-
         return $this->call_method('facebook.users.isAppUser', array('uid' => $uid));
     }
 
@@ -918,7 +761,7 @@ class Horde_Service_Facebook
     */
     public function &users_isVerified()
     {
-    return $this->call_method('facebook.users.isVerified');
+        return $this->call_method('facebook.users.isVerified');
     }
 
   /**
index 9017275..fd14e36 100644 (file)
@@ -6,6 +6,9 @@
  * For now, only provide methods for authenticating that make sense from
  * within a Horde context.
  *
+ * Note, we don't extend Base since we are a special case in that not all
+ * the info is set until *after* we are authenticated.
+ *
  * Copyright 2009 The Horde Project (http://www.horde.org)
  *
  * @author Michael J. Rubinsky <mrubinsk@horde.org>
@@ -163,7 +166,13 @@ class Horde_Service_Facebook_Auth
      */
     private function _expireSession()
     {
-        return $this->_facebook->call_method('facebook.auth.expireSession');
+        // Requires a session
+        if (empty($this->_sessionKey)) {
+            throw new Horde_Service_Facebook_Exception(
+            'No Session', Horde_Service_Facebook_ErrorCodes::API_EC_SESSION_REQUIRED);
+        }
+
+        return $this->_facebook->call_method('facebook.auth.expireSession', array('session_key' => $this->_sessionKey));
     }
 
     /**
@@ -191,27 +200,23 @@ class Horde_Service_Facebook_Auth
     }
 
     /**
-     * Validates that the parameters passed in were sent from Facebook. It does so
-     * by validating that the signature matches one that could only be generated
-     * by using your application's secret key.
-     *
-     * Valid parameters will cause an active session to be set. Note that this
-     * will only return true if the session is NOT set manually via setUser()
-     * in client code.
-     *
-     * Facebook-provided parameters will come from $_POST, $_GET, or $_COOKIE,
+     * Attempt to create or obtain Facebook session parameters from data sent
+     * to us by Facebook. This will come from $_POST, $_GET, or $_COOKIE,
      * in that order. $_POST and $_GET are always more up-to-date than cookies,
-     * so we prefer those if they are available.
+     * so we prefer those if they are available. Data obtained from Facebook
+     * is always validated by checking the signature.
      *
      * For nitty-gritty details of when each of these is used, check out
      * http://wiki.developers.facebook.com/index.php/Verifying_The_Signature
      *
-     * @param boolean  Resolve_auth_token  convert an auth token into a session
-     * @param boolean  Should we ignore any session data present in cookies?
-     *                 (Needed when we need to make sure we are using a new
-     *                  infinite session when returned)
+     * @param boolean $ignore_cookies      Ignore any seemingly valid session
+     *                                     session data obtained from a cookie.
+     *                                     (Needed to allow us to overwrite a
+     *                                      stale value when we get a new token)
+     * @param boolean $resolve_auth_token  Call auth.getSession if we have an
+     *                                     auth_token and no other parameters?
      *
-     * @return boolean  Whether or not we were able to obtain the params.
+     * @return boolean
      */
     public function validateSession($ignore_cookies = false, $resolve_auth_token = true)
     {
@@ -406,9 +411,9 @@ class Horde_Service_Facebook_Auth
      *
      * @return void
      */
-    public function setUser($user, $sessionKey, $expires = null)
+    public function setUser($user, $sessionKey, $expires = null, $no_coookie = false)
     {
-        if (!$this->_request->getCookie($this->_facebook->api_key . '_user') ||
+        if ($no_cookie || !$this->_request->getCookie($this->_facebook->api_key . '_user') ||
             $this->_request->getCookie($this->_facebook->api_key . '_user') != $user) {
 
             $this->setCookies($user, $sessionKey, $expires);
diff --git a/framework/Service_Facebook/lib/Horde/Service/Facebook/Base.php b/framework/Service_Facebook/lib/Horde/Service/Facebook/Base.php
new file mode 100644 (file)
index 0000000..c507574
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Base class for all Horde_Service_Framework_* classes
+ */
+abstract class Horde_Service_Facebook_Base
+{
+    private $_facebook;
+    private $_request;
+    private $_sessionKey;
+
+    /**
+     *
+     * @param $facebook
+     * @param $request
+     * @param $params
+     * @return unknown_type
+     */
+    public function __construct($facebook, $request, $params = array())
+    {
+        $this->_facebook = $facebook;
+        $this->_request = $request;
+        $this->_sessionKey = $facebook->auth->getSessionKey();
+    }
+
+
+}
\ No newline at end of file
diff --git a/framework/Service_Facebook/lib/Horde/Service/Facebook/Events.php b/framework/Service_Facebook/lib/Horde/Service/Facebook/Events.php
new file mode 100644 (file)
index 0000000..e242ee6
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Events methods for Horde_Service_Facebook
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org)
+ *
+ * @author Michael J. Rubinsky <mrubinsk@horde.org>
+ * @category Horde
+ * @package Horde_Service_Facebook
+ */
+ class Horde_Service_Facebook_Events extends Horde_Service_Facebook_Base
+ {
+    /**
+     * Returns events according to the filters specified.
+     *
+     * @param int $uid            (Optional) User associated with events. A null
+     *                            parameter will default to the session user.
+     * @param string $eids        (Optional) Filter by these comma-separated event
+     *                            ids. A null parameter will get all events for
+     *                            the user.
+     * @param int $start_time     (Optional) Filter with this unix time as lower
+     *                            bound.  A null or zero parameter indicates no
+     *                            lower bound.
+     * @param int $end_time       (Optional) Filter with this UTC as upper bound.
+     *                            A null or zero parameter indicates no upper
+     *                            bound.
+     * @param string $rsvp_status (Optional) Only show events where the given uid
+     *                            has this rsvp status.  This only works if you
+     *                            have specified a value for $uid.  Values are as
+     *                            in events.getMembers.  Null indicates to ignore
+     *                            rsvp status when filtering.
+     *
+     * @return array  The events matching the query.
+     */
+    public function &events_get($uid = null, $eids = null, $start_time = null,
+                                $end_time = null, $rsvp_status = null)
+    {
+        // Note we return a reference to support batched calls
+        //  (see Horde_Service_Facebook::call_method)
+        return $this->_facebook->call_method('facebook.events.get',
+            array('uid' => $uid,
+                  'eids' => $eids,
+                  'start_time' => $start_time,
+                  'end_time' => $end_time,
+                  'rsvp_status' => $rsvp_status,
+                  'session_key' => $this->_sessionKey));
+    }
+
+    /**
+     * Returns membership list data associated with an event.
+     *
+     * @param int $eid  event id
+     *
+     * @return array  An assoc array of four membership lists, with keys
+     *                'attending', 'unsure', 'declined', and 'not_replied'
+     */
+    public function &events_getMembers($eid)
+    {
+        return $this->_facebook->call_method('facebook.events.getMembers',
+                                             array('eid' => $eid,
+                                                   'session_key' => $this->_sessionKey));
+    }
+
+    /**
+     * RSVPs the current user to this event.
+     *
+     * @param int $eid             event id
+     * @param string $rsvp_status  'attending', 'unsure', or 'declined'
+     *
+     * @return bool  true if successful
+     */
+    public function &events_rsvp($eid, $rsvp_status)
+    {
+        return $this->_facebook->call_method('facebook.events.rsvp',
+            array('eid' => $eid,
+                  'rsvp_status' => $rsvp_status,
+                   'session_key' => $this->_sessionKey));
+    }
+
+
+    /**
+     * Cancels an event. Only works for events where application is the admin.
+     *
+     * @param int $eid                event id
+     * @param string $cancel_message  (Optional) message to send to members of
+     *                                the event about why it is cancelled
+     *
+     * @return bool  true if successful
+     */
+    public function &events_cancel($eid, $cancel_message = '')
+    {
+        return $this->_facebook->call_method('facebook.events.cancel',
+            array('eid' => $eid,
+                  'cancel_message' => $cancel_message,
+                  'session_key' => $this->_sessionKey));
+    }
+
+    /**
+     * Creates an event on behalf of the user is there is a session, otherwise on
+     * behalf of app.  Successful creation guarantees app will be admin.
+     *
+     * @param assoc array $event_info  json encoded event information
+     *
+     * @return int  event id
+     */
+    public function &events_create($event_info)
+    {
+        return $this->_facebook->call_method('facebook.events.create',
+            array('event_info' => $event_info,
+                  'session_key' => $this->_sessionKey));
+    }
+
+    /**
+     * Edits an existing event. Only works for events where application is admin.
+     *
+     * @param int $eid                 event id
+     * @param assoc array $event_info  json encoded event information
+     *
+     * @return bool  true if successful
+     */
+    public function &events_edit($eid, $event_info)
+    {
+        return $this->_facebook->call_method('facebook.events.edit',
+            array('eid' => $eid,
+                  'event_info' => $event_info,
+                  'session_key' => $this->_sessionKey));
+    }
+
+ }
\ No newline at end of file
diff --git a/framework/Service_Facebook/lib/Horde/Service/Facebook/Fql.php b/framework/Service_Facebook/lib/Horde/Service/Facebook/Fql.php
new file mode 100644 (file)
index 0000000..497b357
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Execute FQL  queries
+ */
+class Horde_Service_Facebook_Fql extends Horde_Service_Facebook_Base
+{
+
+    /**
+     * Run a FQL query, optionally including the current session_key.
+     *
+     * http://developers.facebook.com/documentation.php?v=1.0&doc=fql
+     *
+     * @param string $query             The FQL to run.
+     * @param boolean $include_session  Include the session_key
+     *
+     * @return array of hashes containing results.
+     */
+    public function run($query, $include_session = true)
+    {
+        $params = array('query' => $query);
+        if ($include_session) {
+            $params['session_key'] = $this->_sessionKey;
+        }
+
+        return $this->_facebook->call_method('facebook.fql.query', $params);
+    }
+
+}
\ No newline at end of file
index 2e8174c..1249253 100644 (file)
@@ -66,9 +66,6 @@ class Horde_Service_Facebook_Request
         // We only support JSON
         $params['format'] = 'json';
         $params['method'] = $method;
-        if (empty($params['session_key'])) {
-            $params['session_key'] = $this->_facebook->auth->getSessionKey();
-        }
         $params['api_key'] = $this->_facebook->api_key;
         $params['call_id'] = microtime(true);
         if ($params['call_id'] <= $this->_last_call_id) {
index af5c098..0484780 100644 (file)
@@ -33,6 +33,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
     <dir name="Horde">
      <dir name="Service">
       <dir name="Facebook">
+       <file name="Base.php" role="php" />
+       <file name="Fql.php" role="php" />
        <file name="Exception.php" role="php" />
        <file name="ErrorCodes.php" role="php" />
        <file name="Request.php" role="php" />
@@ -61,6 +63,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
  </dependencies>
  <phprelease>
   <filelist>
+   <install name="lib/Horde/Service/Facebook/Base.php" as="Horde/Service/Facebook/Base.php" />
+   <install name="lib/Horde/Service/Facebook/Fql.php" as="Horde/Service/Facebook/Fql.php" />
    <install name="lib/Horde/Service/Facebook/Exception.php" as="Horde/Service/Facebook/Exception.php" />
    <install name="lib/Horde/Service/Facebook/ErrorCodes.php" as="Horde/Service/Facebook/ErrorCodes.php" />
    <install name="lib/Horde/Service/Facebook/Request.php" as="Horde/Service/Facebook/Request.php" />