--- /dev/null
+<?php
+/**
+ * Callback page for Twitter integration.
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ */
+
+require_once dirname(__FILE__) . '/../lib/base.php';
+
+if (!Horde_Auth::getAuth()) {
+ Horde::authenticationFailureRedirect();
+}
+
+/* Keys - these are obtained when registering for the service */
+$consumer_key = '********';
+$consumer_secret = '*********';
+
+/* Used to obtain an unprivileged request token */
+$token_url = 'http://twitter.com/oauth/request_token';
+
+/* Used for allowing the user to allow/deny access to the application */
+// (User is redirected to this URL if needed).
+$auth_url = 'http://twitter.com/oauth/authorize';
+
+// Used to obtain an access token after user authorizes the application
+$accessToken_url = 'http://twitter.com/oauth/access_token';
+
+/* Parameters required for the Horde_Oauth_Consumer */
+$params = array('key' => $consumer_key,
+ 'secret' => $consumer_secret,
+ 'requestTokenUrl' => $token_url,
+ 'authorizeTokenUrl' => $auth_url,
+ 'accessTokenUrl' => $accessToken_url,
+ 'signatureMethod' => new Horde_Oauth_SignatureMethod_HmacSha1());
+
+/* Create the Consumer */
+$oauth = new Horde_Oauth_Consumer($params);
+
+/* Create the Twitter client */
+$twitter = new Horde_Service_Twitter(array('oauth' => $oauth,
+ 'request' => new Horde_Controller_Request_Http()));
+/* At this point we would check for an existing, valid authorization token */
+// $auth_token should be a Horde_Oauth_Token object
+// $auth_token = getTokenFromStorage();
+
+// Do we have a good auth token? Keep in mind this is example code, and in a true
+// callback page we probably wouldn't be doing anything if we already have a token,
+// but for testing purposes....
+if (!empty($auth_token)) {
+ /* Have a token, tell the Twitter client about it */
+ $twitter->auth->setToken($auth_token);
+
+ // Do something cool....
+ // $twitter->statuses->update('Testing Horde/Twitter integration');
+
+} elseif (!empty($_SESSION['twitter_request_secret'])) {
+ /* No existing auth token, maybe we are in the process of getting it? */
+ $a_token = $twitter->auth->getAccessToken(new Horde_Controller_Request_Http(),
+ $_SESSION['twitter_request_secret']);
+
+ // Clear the request secret from the session now that we're done with it,
+ // again, using _SESSION for simplicity for this example
+ $_SESSION['twitter_request_secret'] = '';
+
+ if ($a_token === false || empty($a_token)) {
+ // We had a request secret, but something went wrong. maybe navigated
+ // back here between requests?
+ echo 'error';
+ die;
+ } else {
+ // We have a good token, save it to DB etc....
+ var_dump($a_token);
+ die;
+ }
+}
+
+// No auth token, not in the process of getting one...ask user to verify
+$results = $twitter->auth->getRequestToken();
+$_SESSION['twitter_request_secret'] = $results->secret;
+
+// Redirect to auth url
+header('Location:' . Horde::externalUrl($twitter->auth->getUserAuthorizationUrl($results), false));
--- /dev/null
+<?php
+/**
+ * Horde_Service_Twitter class abstracts communication with Twitter's
+ * rest interface.
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org)
+ *
+ * @author Michael J. Rubinsky <mrubinsk@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ * @category Horde
+ * @package Horde_Service_Twitter
+ */
+class Horde_Service_Twitter
+{
+
+ /**
+ * Cache for the various objects we lazy load in __get()
+ *
+ * @var hash of Horde_Service_Twitter_* objects
+ */
+ protected $_objCache = array();
+
+ protected $_config;
+
+ /**
+ * Const'r
+ *
+ * @param array $config Configuration parameters:
+ * <pre>
+ * 'oauth' - Horde_Oauth object
+ */
+ public function __construct($config)
+ {
+ // TODO: Check for req'd config
+ $this->_config = $config;
+
+ }
+
+ /**
+ * Lazy load the twitter classes.
+ *
+ * @param string $value The lowercase representation of the subclass.
+ *
+ * @throws Horde_Service_Twitter_Exception
+ * @return Horde_Service_Twitter_* object.
+ */
+ public function __get($value)
+ {
+ // First, see if it's an allowed protected value.
+ switch ($value) {
+ case 'oauth':
+ return $this->_config['oauth'];
+
+ }
+
+ // If not, assume it's a method/action class...
+ $class = 'Horde_Service_Twitter_' . ucfirst($value);
+ if (!empty($this->_objCache[$class])) {
+ return $this->_objCache[$class];
+ }
+
+ if (!class_exists($class)) {
+ throw new Horde_Service_Twitter_Exception(sprintf("%s class not found", $class));
+ }
+
+
+ $this->_objCache[$class] = new $class($this, $this->oauth);
+ return $this->_objCache[$class];
+ }
+
+ /**
+ * Send a request to the Twitter api
+ *
+ * @param $url
+ * @param $params
+ * @return unknown_type
+ */
+ public function getRequest($url, $params = array())
+ {
+ $request = new Horde_Oauth_Request($url, $params);
+ $request->sign($this->oauth->signatureMethod, $this->oauth, $this->auth->getAccessToken());
+
+ $client = new Horde_Http_Client();
+ $response = $client->get($url, array('Authorization' => $request->buildAuthorizationHeader()));
+
+ return $response->getBody();
+ }
+
+ public function postRequest($url, $params = array())
+ {
+ $request = new Horde_Oauth_Request($url, $params);
+ $request->sign($this->oauth->signatureMethod, $this->oauth, $this->auth->getAccessToken());
+
+ $client = new Horde_Http_Client();
+ $response = $client->post($url, $params, array('Authorization' => $request->buildAuthorizationHeader()));
+
+ return $response->getBody();
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde_Service_Twitter_Auth class to abstract all auth related tasks
+ *
+ * Basically implements Horde_Oauth_Client and passes the calls along to the
+ * protected oauth object.
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org)
+ *
+ * @author Michael J. Rubinsky <mrubinsk@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ * @category Horde
+ * @package Horde_Service_Twitter
+ */
+class Horde_Service_Twitter_Auth {
+
+ /**
+ *
+ * @var Horde_Service_Twitter
+ */
+ protected $_twitter;
+
+ /**
+ *
+ */
+ protected $_token;
+
+ /**
+ * Const'r
+ *
+ * @return Horde_Service_Twitter_Auth
+ */
+ public function __construct($twitter, $oauth)
+ {
+ $this->_twitter = $twitter;
+ }
+
+ /**
+ * Obtain the URL used to get an authorization token.
+ *
+ * @param Horde_Oauth_Token $requestToken The request token
+ *
+ * @return string The Url
+ */
+ public function getUserAuthorizationUrl($requestToken)
+ {
+ return $this->_twitter->oauth->getUserAuthorizationUrl($requestToken);
+ }
+
+ /**
+ * Set the access token
+ *
+ * @param $token
+ * @return unknown_type
+ */
+ public function setToken($token)
+ {
+ // @TODO: sanity check this
+ $this->_token = $token;
+ }
+
+ /**
+ * Obtain the access token. This is the token that should be persisted to
+ * storage.
+ *
+ * @param Horde_Controller_Request_Http Http request object
+ * @param Horde_Oauth_Token $requestSecret The token secret returned by
+ * Twitter after the user authorizes
+ * the application.
+ * @return Horde_Oauth_Token
+ */
+ public function getAccessToken($request = null, $requestSecret = null)
+ {
+ if (!empty($this->_token)) {
+ return $this->_token;
+ }
+
+ //@TODO: Verify the existence of requestSecret...
+
+ $params = $request->getGetParams();
+ if (empty($params['oauth_token'])) {
+ return false;
+ }
+ $token = new Horde_Oauth_Token($params['oauth_token'], $requestSecret);
+
+ return $this->_twitter->oauth->getAccessToken($token);
+ }
+
+ public function getRequestToken($params = array())
+ {
+ return $this->_twitter->oauth->getRequestToken($params);
+ }
+
+}
--- /dev/null
+<?php
+class Horde_Service_Twitter_Exception extends Exception {
+}
+?>
--- /dev/null
+<?php
+/**
+ * Horde_Service_Twitter_Statuses class for updating user statuses.
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org)
+ *
+ * @author Michael J. Rubinsky <mrubinsk@horde.org>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ * @category Horde
+ * @package Horde_Service_Twitter
+ */
+class Horde_Service_Twitter_Statuses
+{
+
+ public function __construct($twitter, $oauth)
+ {
+ $this->_twitter = $twitter;
+ }
+
+ /**
+ * Obtain the requested status
+ *
+ * @return unknown_type
+ */
+ public function show($id)
+ {
+
+ }
+
+ public function update($status)
+ {
+ $url = 'http://twitter.com/statuses/update.json';
+ return $this->_twitter->postRequest($url, array('status' => $status));
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Service_Twitter</name>
+ <channel>pear.horde.org</channel>
+ <summary>Horde Twitter client</summary>
+ <description>This package provides client libraries for the Twitter REST API
+ </description>
+ <lead>
+ <name>Michael J. Rubinsky</name>
+ <user>mrubinsk</user>
+ <email>mrubinsk@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <date>2009-07-18</date>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <license uri="http://opensource.org/licenses/bsd-license.php">BSD</license>
+ <notes>
+* Initial release
+ </notes>
+ <contents>
+ <dir name="/">
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Service">
+ <dir name="Twitter">
+ <file name="Auth.php" role="php" />
+ <file name="Exception.php" role="php" />
+ <file name="Statuses.php" role="php" />
+ </dir> <!-- /lib/Horde/Service/Twitter-->
+ <file name="Twitter.php" role="php" />
+ </dir> <!-- /lib/Horde/Service -->
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.0</min>
+ </php>
+ <pearinstaller>
+ <min>1.5.0</min>
+ </pearinstaller>
+ <package>
+ <name>Http_Client</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ </required>
+ </dependencies>
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/Service/Twitter/Auth.php" as="Horde/Service/Twitter/Auth.php" />
+ <install name="lib/Horde/Service/Twitter/Exception.php" as="Horde/Service/Twitter/Exception.php" />
+ <install name="lib/Horde/Service/Twitter/Statuses.php" as="Horde/Service/Twitter/Statuses.php" />
+ <install name="lib/Horde/Service/Twitter.php" as="Horde/Service/Twitter.php" />
+ </filelist>
+ </phprelease>
+</package>