1: <?php
2: /**
3: * Horde_Service_Twitter class abstracts communication with Twitter's
4: * rest interface.
5: *
6: * Copyright 2009-2012 Horde LLC (http://www.horde.org/)
7: *
8: * @property-read Horde_Service_Twitter_Account $account
9: * The twitter account object for calling account methods.
10: * @property-read Horde_Service_Twitter_Statuses $statuses
11: * The twitter status object for updating and retrieving user
12: * statuses.
13: * @property-read Horde_Service_Twitter_Auth $auth
14: * The twitter authentication object.
15: * @property-read Horde_Service_Twitter_Request $request
16: * The twitter request object that wraps sending requests to
17: * Twitter's REST API.
18: * @property-read Horde_Cache $responseCache
19: * The cache object.
20: * @property-read integer $cacheLifetime
21: * The default cache lifetime.
22: *
23: * @author Michael J. Rubinsky <mrubinsk@horde.org>
24: * @license http://www.horde.org/licenses/bsd BSD
25: * @category Horde
26: * @package Service_Twitter
27: */
28: class Horde_Service_Twitter
29: {
30: /* Constants */
31: const REQUEST_TOKEN_URL = 'https://api.twitter.com/oauth/request_token';
32: const USER_AUTHORIZE_URL = 'https://api.twitter.com/oauth/authorize';
33: const ACCESS_TOKEN_URL = 'https://api.twitter.com/oauth/access_token';
34:
35: /**
36: * Cache for the various objects we lazy load in __get()
37: *
38: * @var hash of Horde_Service_Twitter_* objects
39: */
40: protected $_objCache = array();
41:
42: /**
43: * (Optional) Cache object.
44: *
45: * @var Horde_Cache
46: */
47: protected $_responseCache;
48:
49: /**
50: * Default cache lifetime.
51: *
52: * @var integer
53: */
54: protected $_cacheLifetime = 300;
55:
56: /**
57: * Optional logger.
58: *
59: * @var Horde_Log_Logger
60: */
61: protected $_logger;
62:
63: /**
64: * Can't lazy load the auth or request class since we need to know early if
65: * we are OAuth or Basic
66: *
67: * @var Horde_Service_Twitter_Auth
68: */
69: protected $_auth;
70:
71: /**
72: * The twitter request object.
73: *
74: * @var Horde_Service_Twitter_Request
75: */
76: protected $_request;
77:
78: /**
79: * The http client.
80: *
81: * @var Horde_Http_Client
82: */
83: protected $_httpClient;
84:
85: /**
86: * Constructor.
87: *
88: * @param Horde_Service_Twitter_Auth $auth An authentication object
89: * @param Horde_Service_Twitter_Request $request A request object.
90: */
91: public function __construct(Horde_Service_Twitter_Auth $auth,
92: Horde_Service_Twitter_Request $request)
93: {
94: $this->_auth = $auth;
95: $this->_auth->setTwitter($this);
96: $this->_request = $request;
97: $this->_request->setTwitter($this);
98: }
99:
100: /**
101: * Factory method to easily build a working Twitter client object.
102: *
103: * @param array $params Configuration parameters, with the following keys:
104: * - 'oauth' (required):
105: * - 'consumer_key' (required): The application's
106: * consumer key
107: * - 'consumer_secret' (required): The application's
108: * consumer secret
109: * - 'access_token' (optional): The user's access
110: * token
111: * - 'access_token_secret' (optional): The user's
112: * access token secret.
113: * - 'http' (optional): any configuration parameters
114: * for Horde_Http_Client, e.g. proxy settings.
115: *
116: * @return Horde_Service_Twitter A twitter object that can be used
117: * immediately to update and receive
118: * statuses etc.
119: */
120: static public function create($params)
121: {
122: if (!isset($params['oauth'])) {
123: throw new Horde_Service_Twitter_Exception('Only OAuth authentication is supported.');
124: }
125:
126: /* Parameters required for the Horde_Oauth_Consumer */
127: $consumer_params = array(
128: 'key' => $params['oauth']['consumer_key'],
129: 'secret' => $params['oauth']['consumer_secret'],
130: 'requestTokenUrl' => self::REQUEST_TOKEN_URL,
131: 'authorizeTokenUrl' => self::USER_AUTHORIZE_URL,
132: 'accessTokenUrl' => self::ACCESS_TOKEN_URL,
133: 'signatureMethod' => new Horde_Oauth_SignatureMethod_HmacSha1());
134:
135: /* Create the Consumer */
136: $oauth = new Horde_Oauth_Consumer($consumer_params);
137:
138: /* Create the Twitter client */
139: $twitter = new Horde_Service_Twitter(
140: new Horde_Service_Twitter_Auth_Oauth($oauth),
141: new Horde_Service_Twitter_Request_Oauth(
142: new Horde_Controller_Request_Http()));
143:
144: /* Create HTTP client. */
145: $http_params = isset($params['http']) ? $params['http'] : array();
146: $twitter->setHttpClient(new Horde_Http_Client($http_params));
147:
148: /* Check for an existing token */
149: if (!empty($params['oauth']['access_token']) &&
150: !empty($params['oauth']['access_token_secret'])) {
151: $auth_token = new Horde_Oauth_Token(
152: $params['oauth']['access_token'],
153: $params['oauth']['access_token_secret']);
154: $twitter->auth->setToken($auth_token);
155: }
156:
157: return $twitter;
158: }
159:
160: public function setCache(Horde_Cache $cache)
161: {
162: $this->_responseCache = $cache;
163: }
164:
165: public function setLogger(Horde_Log_Logger $logger)
166: {
167: $this->_logger = $logger;
168: }
169:
170: /**
171: * Set the http client.
172: *
173: * @param Horde_Http_Client $client The http client
174: */
175: public function setHttpClient(Horde_Http_Client $client)
176: {
177: $this->_httpClient = $client;
178: }
179:
180: /**
181: * Get the http client.
182: *
183: * @return Horde_Http_Client
184: */
185: public function getHttpClient()
186: {
187: return $this->_httpClient;
188: }
189:
190: /**
191: * Lazy load the twitter classes.
192: *
193: * @param string $value The lowercase representation of the subclass.
194: *
195: * @throws Horde_Service_Twitter_Exception
196: * @return Horde_Service_Twitter_* object.
197: */
198: public function __get($value)
199: {
200: // First, see if it's an allowed protected value.
201: switch ($value) {
202: case 'auth':
203: return $this->_auth;
204: case 'request':
205: return $this->_request;
206: case 'responseCache':
207: return $this->_responseCache;
208: case 'cacheLifetime':
209: return $this->_cacheLifetime;
210: }
211:
212: // If not, assume it's a method/action class...
213: $class = 'Horde_Service_Twitter_' . ucfirst($value);
214: if (!empty($this->_objCache[$class])) {
215: return $this->_objCache[$class];
216: }
217:
218: if (!class_exists($class)) {
219: throw new Horde_Service_Twitter_Exception(sprintf("%s class not found", $class));
220: }
221:
222:
223: $this->_objCache[$class] = new $class($this);
224: return $this->_objCache[$class];
225: }
226:
227: }
228: