PageRenderTime 58ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/web/proxy/Tweetr.php

http://tweetr.googlecode.com/
PHP | 326 lines | 207 code | 42 blank | 77 comment | 37 complexity | fe792e0b2e5898be06141365c92e9d00 MD5 | raw file
  1. <?php
  2. /**
  3. * Tweetr Proxy Class
  4. * @author Sandro Ducceschi [swfjunkie.com, Switzerland]
  5. */
  6. class Tweetr
  7. {
  8. //--------------------------------------------------------------------------
  9. //
  10. // Class variables
  11. //
  12. //--------------------------------------------------------------------------
  13. const USER_AGENT = 'TweetrProxy/0.95';
  14. const USER_AGENT_LINK = 'http://tweetr.googlecode.com/';
  15. const BASEURL = '/proxy';
  16. const DEBUGMODE = false;
  17. const GHOST_DEFAULT = 'ghost';
  18. const CACHE_ENABLED = false;
  19. const CACHE_TIME = 120; // 2 minutes
  20. const CACHE_DIRECTORY = 'cache';
  21. const UPLOAD_DIRECTORY = 'tmp';
  22. //--------------------------------------------------------------------------
  23. //
  24. // Initialization
  25. //
  26. //--------------------------------------------------------------------------
  27. /**
  28. * Creates a Tweetr Proxy Instance
  29. * @param (array) $options Associative Array containing optional values see http://code.google.com/p/tweetr/wiki/PHPProxyUsage
  30. */
  31. public function Tweetr($options = null)
  32. {
  33. // set the options
  34. $this->baseURL = (isset($options['baseURL'])) ? $options['baseURL'] : self::BASEURL;
  35. $this->userAgent = (isset($options['userAgent'])) ? $options['userAgent'] : self::USER_AGENT;
  36. $this->userAgentLink = (isset($options['userAgentLink'])) ? $options['userAgentLink'] : self::USER_AGENT_LINK;
  37. $this->indexContent = (isset($options['indexContent'])) ? $options['indexContent'] : '<html><head><title>'.$this->userAgent.'</title></head><body><a href="'.$this->userAgentLink.'" title="Go to Website">'.$this->userAgent.'</a></body></html>';
  38. $this->debug = (isset($options['debugMode'])) ? $options['debugMode'] : self::DEBUGMODE;
  39. $this->ghostName = (isset($options['ghostName'])) ? $options['ghostName'] : self::GHOST_DEFAULT;
  40. $this->ghostPass = (isset($options['ghostPass'])) ? $options['ghostPass'] : self::GHOST_DEFAULT;
  41. $this->userName = (isset($options['userName'])) ? $options['userName'] : null;
  42. $this->userPass = (isset($options['userPass'])) ? $options['userPass'] : null;
  43. $this->cacheEnabled = (isset($options['cache_enabled'])) ? $options['cache_enabled'] : self::CACHE_ENABLED;
  44. $this->cacheTime = (isset($options['cache_time'])) ? $options['cache_time'] : self::CACHE_TIME;
  45. $this->cacheDirectory = "./".((isset($options['cache_directory'])) ? $options['cache_directory'] : self::CACHE_DIRECTORY)."/";
  46. $this->uploadDirectory = "./".((isset($options['upload_directory'])) ? $options['upload_directory'] : self::UPLOAD_DIRECTORY)."/";
  47. // set the current url and parse it
  48. $this->url = parse_url($_SERVER['REQUEST_URI']);
  49. $this->parseRequest();
  50. }
  51. //--------------------------------------------------------------------------
  52. //
  53. // Variables
  54. //
  55. //--------------------------------------------------------------------------
  56. private $url;
  57. private $debug;
  58. private $baseURL;
  59. private $userAgent;
  60. private $userAgentLink;
  61. private $indexContent;
  62. private $userName;
  63. private $userPass;
  64. private $ghostName;
  65. private $ghostPass;
  66. private $cacheEnabled;
  67. private $cacheTime;
  68. private $cacheDirectory;
  69. private $uploadDirectory;
  70. //--------------------------------------------------------------------------
  71. //
  72. // Methods
  73. //
  74. //--------------------------------------------------------------------------
  75. /**
  76. * Pre-Parses the received request to see if we need authentication or not
  77. */
  78. private function parseRequest()
  79. {
  80. if($_SERVER['REQUEST_METHOD'] == 'POST')
  81. {
  82. $this->checkCredentials();
  83. }
  84. else
  85. {
  86. if($this->url['path'] == $this->baseURL.'/')
  87. die(urldecode($this->indexContent));
  88. else
  89. $this->checkCredentials();
  90. }
  91. }
  92. /**
  93. * Makes a request to twitter with the data provided and returns the result to the screen
  94. */
  95. private function twitterRequest($authentication = false)
  96. {
  97. /* caching - begin */
  98. if($_SERVER['REQUEST_METHOD'] != 'POST' && $this->cacheEnabled && $this->cacheExists())
  99. {
  100. header('Content-type: text/xml; charset=utf-8');
  101. echo $this->cacheRead();
  102. return;
  103. }
  104. /* caching - end */
  105. $twitterURL = 'http://api.twitter.com/1'.str_replace($this->baseURL,'',$this->url['path']);
  106. if($_SERVER['REQUEST_METHOD'] == 'GET')
  107. $twitterURL .= '?'.$this->url['query'];
  108. $opt[CURLOPT_URL] = $twitterURL;
  109. $opt[CURLOPT_USERAGENT] = $this->userAgent;
  110. $opt[CURLOPT_RETURNTRANSFER] = true;
  111. $opt[CURLOPT_TIMEOUT] = 60;
  112. if($authentication)
  113. {
  114. $opt[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC;
  115. $creds = (isset($_GET['hash'])) ? $_GET['hash'] : $_POST['hash'];
  116. $credsArr = explode(':', base64_decode($creds));
  117. $credUser = $credsArr[0];
  118. $credPass = $credsArr[1];
  119. if( isset($this->ghostName) && isset($this->ghostPass) &&
  120. isset($this->userName) && isset($this->userPass) &&
  121. $this->ghostName == $credUser && $this->ghostPass == $credPass)
  122. {
  123. $opt[CURLOPT_USERPWD] = $this->userName .':'. $this->userPass;
  124. }
  125. else
  126. {
  127. $opt[CURLOPT_USERPWD] = $credUser .':'. $credPass;
  128. }
  129. }
  130. if($_SERVER['REQUEST_METHOD'] == 'POST')
  131. {
  132. $postFields = array();
  133. if (isset($_FILES['image']))
  134. {
  135. $imagePath = $this->uploadDirectory.$_FILES['image']['name'];
  136. if (move_uploaded_file($_FILES['image']['tmp_name'], $imagePath))
  137. $postFields['image'] = '@'.realpath($imagePath);
  138. else
  139. die('Upload failed, check upload directory permissions/path...');
  140. }
  141. foreach($_POST as $key => $val)
  142. $postFields[$key] = stripslashes($val);
  143. $opt[CURLOPT_POST] = true;
  144. $opt[CURLOPT_HTTPHEADER] = array('Expect:');
  145. $opt[CURLOPT_POSTFIELDS] = $postFields;
  146. }
  147. //do the request
  148. $curl = curl_init();
  149. curl_setopt_array($curl, $opt);
  150. ob_start();
  151. $response = curl_exec($curl);
  152. if(strlen(''.$response) < 2 )
  153. $response = ob_get_contents();
  154. ob_end_clean();
  155. if (isset($imagePath))
  156. unlink($imagePath);
  157. if($this->debug)
  158. {
  159. $headers = curl_getinfo($curl);
  160. $errorNumber = curl_errno($curl);
  161. $errorMessage = curl_error($curl);
  162. }
  163. curl_close($curl);
  164. if($this->debug)
  165. {
  166. $this->log($headers);
  167. $this->log($errorNumber);
  168. $this->log($errorMessage);
  169. }
  170. header('Content-type: text/xml; charset=utf-8');
  171. /* caching - begin */
  172. if ($this->cacheEnabled)
  173. $this->cacheInit();
  174. echo $response;
  175. if ($this->cacheEnabled)
  176. $this->cacheEnd();
  177. }
  178. /**
  179. * Requests Basic Authentication
  180. */
  181. private function checkCredentials()
  182. {
  183. if (!isset($_GET['hash']) && !isset($_POST['hash']))
  184. $this->twitterRequest();
  185. else
  186. $this->twitterRequest(true);
  187. }
  188. /**
  189. * Log Method that you can overwrite with your own logging stuff.
  190. * FirePHP is my personal recommendation though ;)
  191. * @param $obj Whatever you are trying to log
  192. */
  193. private function log($obj)
  194. {
  195. //require_once('fire/fb.php');
  196. //FB::log($obj);
  197. }
  198. //-------------------------------
  199. // Caching
  200. //-------------------------------
  201. /**
  202. * Start Caching Process
  203. */
  204. private function cacheInit()
  205. {
  206. if($this->cacheExists())
  207. {
  208. echo $this->cacheRead();
  209. exit();
  210. }
  211. else
  212. {
  213. ob_start();
  214. }
  215. }
  216. /**
  217. * End Caching Process
  218. */
  219. private function cacheEnd()
  220. {
  221. $data = ob_get_clean();
  222. $this->cacheSave($data);
  223. echo $data;
  224. }
  225. /**
  226. * Create cache key
  227. */
  228. private function cacheKey()
  229. {
  230. foreach($_POST as $key => $value) $keys[] = $key . '=' . urlencode($value) ;
  231. foreach($_GET as $key => $value) $keys[] = $key . '=' . urlencode($value) ;
  232. $keys[] = 'app=tweetr';
  233. $keys[] = 'requrl='.urlencode($this->url['path']);
  234. sort($keys);
  235. return md5(implode('&', $keys));
  236. }
  237. /**
  238. * Returns filename
  239. */
  240. private function cacheFilename()
  241. {
  242. return $this->cacheDirectory. $this->cacheKey() . '.cache';
  243. }
  244. /**
  245. * Checks if a specific cached file exists
  246. */
  247. private function cacheExists()
  248. {
  249. if(@file_exists($this->cacheFilename()) && (time() - $this->cacheTime) < @filemtime($this->cacheFilename()))
  250. return true;
  251. else
  252. return false;
  253. }
  254. /**
  255. * Reads the Cache
  256. */
  257. private function cacheRead()
  258. {
  259. return file_get_contents($this->cacheFilename());
  260. }
  261. /**
  262. * Destroy uneccessary cache files
  263. */
  264. private function cachePurge()
  265. {
  266. $dir_handle = @opendir($this->cacheDirectory) or die('Unable to open '.$this->cacheDirectory);
  267. while ($file = readdir($dir_handle))
  268. {
  269. if ($file!='.' && $file!='..' && (time() - $this->cacheTime) > @filemtime($this->cacheDirectory.$file))
  270. unlink($this->cacheDirectory.$file) or die('Error. Could not erase file : '.$file);
  271. }
  272. }
  273. /**
  274. * Save a cache file
  275. */
  276. private function cacheSave($value)
  277. {
  278. $this->cachePurge();
  279. $fp = @fopen($this->cacheFilename(), 'w') or die('Error opening file: '.$this->cacheFilename());
  280. @fwrite($fp, $value) or die('Error writing file.');
  281. @fclose($fp);
  282. }
  283. }
  284. ?>