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

/protected/application/plugins/twitter/models/TwitterModel.php

https://github.com/rjdjohnston/core
PHP | 356 lines | 256 code | 69 blank | 31 comment | 52 complexity | 1ae575b9d5fbf8d51d12b8342f9a73b9 MD5 | raw file
  1. <?php
  2. /*
  3. * Copyright 2008-2009 Laurent Eschenauer and Alard Weisscher
  4. * Copyright 2010 John Hobbs
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. */
  19. class TwitterModel extends SourceModel {
  20. protected $_name = 'twitter_data';
  21. protected $_prefix = 'twitter';
  22. protected $_search = 'text';
  23. protected $_update_tweet = "Updated %d times my Twitter status %s";
  24. public function getServiceName() {
  25. return "Twitter";
  26. }
  27. public function getServiceURL() {
  28. if ($username = $this->getProperty('username')) {
  29. return "http://www.twitter.com/$username";
  30. }
  31. else {
  32. return "http://www.twitter.com/";
  33. }
  34. }
  35. public function getServiceDescription() {
  36. return "Twitter is a micro-blogging platform.";
  37. }
  38. public function isStoryElement() {
  39. return true;
  40. }
  41. public function importData() {
  42. $username = $this->getProperty('username');
  43. if (!$username) {
  44. throw new Stuffpress_Exception("Update failed, connector not properly configured");
  45. }
  46. // Proceed with the update
  47. $items = $this->updateData(true);
  48. $this->setImported(true);
  49. return $items;
  50. }
  51. public function updateData($import = false) {
  52. // Get service propertie
  53. $config = Zend_Registry::get("configuration");
  54. $user = $config->twitter->username;
  55. $pwd = $config->twitter->password;
  56. $pages = $import ? 32 : 1;
  57. $count = $import ? 100 : 50;
  58. // Get user properties
  59. $username = $this->getProperty('username');
  60. $uid = $this->getProperty('uid', 0);
  61. if (!$username) {
  62. throw new Stuffpress_Exception("Update failed, connector not properly configured");
  63. }
  64. // Update the user uid if required
  65. if (!$uid || $uid==0) {
  66. $uid = $this->getTwitterUid($username);
  67. if ($uid > 0) {
  68. $this->setProperty('uid', $uid);
  69. }
  70. }
  71. // Fetch the data from twitter
  72. $result = array();
  73. $curl = curl_init();
  74. curl_setopt($curl, CURLOPT_HEADER, false);
  75. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  76. //curl_setopt($curl, CURLOPT_USERPWD, "$user:$pwd");
  77. curl_setopt($curl, CURLOPT_USERAGENT,'Storytlr/1.0');
  78. for($page=1; $page<= $pages; $page ++) {
  79. $url = "http://twitter.com/statuses/user_timeline/$username.xml?count=$count&page=$page";
  80. curl_setopt($curl, CURLOPT_URL, $url);
  81. $response = curl_exec($curl);
  82. $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  83. if ($http_code != 200) {
  84. throw new Stuffpress_Exception("Twitter API returned http status $http_code for url: $url", $http_code);
  85. }
  86. if (!($data = simplexml_load_string($response))) {
  87. throw new Stuffpress_Exception("Twitter did not return any result for url: $url", 0);
  88. }
  89. if (count($data) == 0) {
  90. break;
  91. }
  92. $items = $this->processItems($data);
  93. $result = array_merge($result,$items);
  94. if (count($data) < $count) {
  95. break;
  96. }
  97. }
  98. curl_close ($curl);
  99. unset($curl);
  100. // Mark as updated (could have been with errors)
  101. $this->markUpdated();
  102. return $result;
  103. }
  104. public function getConfigForm($populate=false) {
  105. $form = new Stuffpress_Form();
  106. // Add the blog url element
  107. $label = $this->getServiceName(). " username";
  108. $element = $form->createElement('text', 'username', array('label' => $label , 'decorators' => $form->elementDecorators));
  109. $element->setRequired(true);
  110. $form->addElement($element);
  111. // Options
  112. $options = array();
  113. if ($this->getPropertyDefault('hide_replies')) $options[] = 'hide_replies';
  114. $e = new Zend_Form_Element_MultiCheckbox('options', array(
  115. 'decorators' => $form->elementDecorators,
  116. 'multiOptions' => array(
  117. 'hide_replies' => 'Hide @replies tweets'
  118. )
  119. ));
  120. $e->setLabel('Options');
  121. $e->setValue($options);
  122. $form->addElement($e);
  123. if($populate) {
  124. $options = array();
  125. $values = $this->getProperties();
  126. if ($this->getProperty('hide_replies')) $options[]='hide_replies';
  127. $values['options'] = $options;
  128. $form->populate($values);
  129. }
  130. return $form;
  131. }
  132. public function processConfigForm($form) {
  133. $values = $form->getValues();
  134. $username = $values['username'];
  135. $options = $values['options'];
  136. $update = false;
  137. // Save twitter username
  138. if($username != $this->getProperty('username')) {
  139. $this->_properties->setProperty('username', $username);
  140. $update = true;
  141. }
  142. // Save hide_replies property
  143. $hide_replies = @in_array('hide_replies',$options) ? 1 : 0;
  144. $this->_properties->setProperty('hide_replies', $hide_replies);
  145. return $update;
  146. }
  147. public function processGnipItem($activity) {
  148. if (!$item = @new SimpleXMLElement($activity->payload->decodedRaw())) {
  149. return;
  150. }
  151. if ($activity->action != 'notice') {
  152. return;
  153. }
  154. $text = $item->title;
  155. $text = mb_substr($text, strpos($text, ':') + 2);
  156. $tags = $this->getTags($text);
  157. $data = array();
  158. if ($photo = $this->getPhoto($text)) {
  159. $data['photo_key'] = $photo['key'];
  160. $data['photo_service'] = $photo['service'];
  161. }
  162. $data['created_at'] = $item->published;
  163. $data['twitter_id'] = $item->status_id;
  164. $data['text'] = $text;
  165. $data['source'] = $item->from_source->asXML();
  166. $data['truncated'] = 0;
  167. $data['in_reply_to_status'] = $item->in_reply_to_status_id;
  168. $data['in_reply_to_user_id'] = $item->in_reply_to_user_id;
  169. $hide_replies = $this->getProperty('hide_replies');
  170. $is_reply = (mb_substr($text, 0, 1) == '@') ? true : false;
  171. $is_repost = @in_array(strip_tags($data['source']), array('storytlr'));
  172. $is_hidden = ($is_repost || ($is_reply && $hide_replies)) ? 1 : 0;
  173. $type = $photo ? SourceItem::IMAGE_TYPE : SourceItem::STATUS_TYPE;
  174. if ($is_repost) return;
  175. $this->addItem($data, strtotime($item->published), $type, $tags, false, $is_hidden, $data['text']);
  176. }
  177. private function processItems($items) {
  178. $result = array();
  179. if ($items && count($items)>0) foreach ($items as $item) {
  180. $data = array();
  181. $tags = $this->getTags((string) $item->text);
  182. if ($photo = $this->getPhoto((string) $item->text)) {
  183. $data['photo_key'] = $photo['key'];
  184. $data['photo_service'] = $photo['service'];
  185. }
  186. $data['created_at'] = (string) $item->created_at;
  187. $data['twitter_id'] = (string) $item->id;
  188. $data['text'] = (string) $item->text;
  189. $data['source'] = (string) $item->source;
  190. $data['truncated'] = ((string)$item->truncated == "false") ? 0:1;
  191. $data['in_reply_to_status'] = (string) $item->in_reply_to_status_id;
  192. $data['in_reply_to_user_id'] = (string) $item->in_reply_to_user_id;
  193. $hide_replies = $this->getProperty('hide_replies');
  194. $is_reply = (mb_substr($data['text'], 0, 1) == '@') ? true : false;
  195. $is_repost = @in_array(strip_tags($data['source']), array('storytlr'));
  196. $is_hidden = ($is_repost || ($is_reply && $hide_replies)) ? 1 : 0;
  197. $type = $photo ? SourceItem::IMAGE_TYPE : SourceItem::STATUS_TYPE;
  198. if ($is_repost) continue;
  199. $id = $this->addItem($data, strtotime($data['created_at']), $type, $tags, false, $is_hidden, $data['text']);
  200. if ($id) $result[] = $id;
  201. unset($data);
  202. }
  203. return $result;
  204. }
  205. public function processItem($item) {
  206. $result = array();
  207. $tags = $this->getTags((string) $item->text);
  208. if ($photo = $this->getPhoto((string) $item->text)) {
  209. $data['photo_key'] = $photo['key'];
  210. $data['photo_service'] = $photo['service'];
  211. }
  212. $data['created_at'] = (string) $item->created_at;
  213. $data['twitter_id'] = (string) $item->id;
  214. $data['text'] = (string) $item->text;
  215. $data['source'] = (string) $item->source;
  216. $data['truncated'] = ((string)$item->truncated == "false") ? 0:1;
  217. $data['in_reply_to_status'] = (string) $item->in_reply_to_status_id;
  218. $data['in_reply_to_user_id'] = (string) $item->in_reply_to_screen_name;
  219. $hide_replies = $this->getProperty('hide_replies');
  220. $is_reply = (mb_substr($data['text'], 0, 1) == '@') ? true : false;
  221. $is_repost = @in_array(strip_tags($data['source']), array('storytlr'));
  222. $is_hidden = ($is_repost || ($is_reply && $hide_replies)) ? 1 : 0;
  223. $type = $photo ? SourceItem::IMAGE_TYPE : SourceItem::STATUS_TYPE;
  224. if ($is_repost) continue;
  225. $id = $this->addItem($data, strtotime($data['created_at']), $type, $tags, false, $is_hidden, $data['text']);
  226. if ($id) $result[] = $id;
  227. return $result;
  228. }
  229. private function getPhoto($status) {
  230. $matches = array();
  231. // Do we have a twitpic ?
  232. if (preg_match("/twitpic.com\/(\w+)/i",$status,$matches)) {
  233. $photo['key'] = $matches[1];
  234. $photo['service'] = 'twitpic';
  235. return $photo;
  236. }
  237. // Do we have an android ?
  238. elseif (preg_match("/phodroid.com\/(\w+)/i",$status,$matches)) {
  239. $photo['key'] = $matches[1];
  240. $photo['service'] = 'phodroid';
  241. return $photo;
  242. }
  243. // Do we have brizzly?s
  244. elseif (preg_match("/brizzly.com\/pic\/(\w+)/i",$status,$matches)) {
  245. $photo['key'] = $matches[1];
  246. $photo['service'] = 'brizzly';
  247. return $photo;
  248. } else {
  249. return false;
  250. }
  251. }
  252. private function getTags($status) {
  253. $matches = array();
  254. preg_match_all("/#(\w+)/",$status,$matches);
  255. return $matches[1];
  256. }
  257. private function getLastID() {
  258. $sql = "SELECT twitter_id FROM `$this->_name` WHERE source_id = :source_id ORDER BY id DESC";
  259. $data = array(":source_id" => $this->_source->id);
  260. $id = $this->_db->fetchOne($sql, $data);
  261. echo "Fetched the ID $id for Twitter.\r\n";
  262. return $id;
  263. }
  264. private function getTwitterUid($username) {
  265. $config = Zend_Registry::get("configuration");
  266. $user = $config->twitter->username;
  267. $pwd = $config->twitter->password;
  268. $curl = curl_init();
  269. curl_setopt($curl, CURLOPT_HEADER, false);
  270. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  271. curl_setopt($curl, CURLOPT_USERPWD, "$user:$pwd");
  272. curl_setopt($curl, CURLOPT_USERAGENT,'Storytlr/1.0');
  273. $url = "http://twitter.com/users/show.json?screen_name=$username";
  274. curl_setopt($curl, CURLOPT_URL, $url);
  275. $response = curl_exec($curl);
  276. $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  277. if ($http_code != 200) {
  278. return 0;
  279. }
  280. if ($response && strlen($response) > 0) {
  281. $twitter_user = json_decode($response);
  282. $uid = $twitter_user->id;
  283. return $uid;
  284. }
  285. return 0;
  286. }
  287. }