PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/webapp/_lib/model/class.Post.php

http://github.com/ginatrapani/ThinkUp
PHP | 318 lines | 122 code | 7 blank | 189 comment | 7 complexity | 2ce9395eaa79ca02c68aff018b494ed2 MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0, GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. *
  4. * ThinkUp/webapp/_lib/model/class.Post.php
  5. *
  6. * Copyright (c) 2009-2016 Gina Trapani
  7. *
  8. * LICENSE:
  9. *
  10. * This file is part of ThinkUp (http://thinkup.com).
  11. *
  12. * ThinkUp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
  13. * License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any
  14. * later version.
  15. *
  16. * ThinkUp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
  17. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  18. * details.
  19. *
  20. * You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
  21. * <http://www.gnu.org/licenses/>.
  22. *
  23. *
  24. * Post
  25. * A post, tweet, or status update on a ThinkUp source network or service (like Twitter or Facebook)
  26. * @license http://www.gnu.org/licenses/gpl.html
  27. * @copyright 2009-2016 Gina Trapani
  28. * @author Gina Trapani <ginatrapani[at]gmail[dot]com>
  29. */
  30. class Post {
  31. /**
  32. * @const int
  33. * Twitter currently maxes out on returning a RT count at 100.
  34. */
  35. const TWITTER_RT_THRESHOLD = 100;
  36. /**
  37. * @var int Internal unique ID..
  38. */
  39. var $id;
  40. /**
  41. * @var int The ID of the post inside the respective service.
  42. */
  43. var $post_id;
  44. /**
  45. * @var int The user ID inside the respective service, e.g. Twitter or Facebook user IDs.
  46. */
  47. var $author_user_id;
  48. /**
  49. * @var str The user's username inside the respective service, e.g. Twitter or Facebook user name.
  50. */
  51. var $author_username;
  52. /**
  53. * @var str The user's real, full name on a given service, e.g. Gina Trapani.
  54. */
  55. var $author_fullname;
  56. /**
  57. * @var str The URL to the user's avatar for a given service.
  58. */
  59. var $author_avatar;
  60. /**
  61. * @var int Post author's follower count. [Twitter-specific]
  62. */
  63. var $author_follower_count;
  64. /**
  65. * @var str The textual content of a user's post on a given service.
  66. */
  67. var $post_text;
  68. /**
  69. * @var bool Whether or not this post is protected, e.g. not publicly visible.
  70. */
  71. var $is_protected;
  72. /**
  73. * @var str The client used to publish this post, e.g. if you post from the Twitter web interface, this will be
  74. * "web".
  75. */
  76. var $source;
  77. /**
  78. * @var str Author-level location, e.g., the author's location as set in his or her profile. Use author-level
  79. location if post-level location is not set.
  80. */
  81. var $location;
  82. /**
  83. * @var str Post-level name of a place from which a post was published, ie, Woodland Hills, Los Angeles.
  84. */
  85. var $place;
  86. /**
  87. * @var str Post-level place ID on a given network.
  88. */
  89. var $place_id;
  90. /**
  91. * @var str The post's latitude and longitude coordinates.
  92. */
  93. var $geo;
  94. /**
  95. * @var str The UTC date/time when this post was published.
  96. */
  97. var $pub_date;
  98. /**
  99. * @var int The ID of the user that this post is in reply to.
  100. */
  101. var $in_reply_to_user_id;
  102. /**
  103. * @var int The ID of the post that this post is in reply to.
  104. */
  105. var $in_reply_to_post_id;
  106. /**
  107. * @var int The total number of replies this post received in the data store.
  108. */
  109. var $reply_count_cache;
  110. /**
  111. * @var tinyint Whether or not this reply was authored by a friend of the original post's author.
  112. */
  113. var $is_reply_by_friend;
  114. /**
  115. * @var int The ID of the post that this post is a retweet of. [Twitter-specific]
  116. */
  117. var $in_retweet_of_post_id;
  118. /**
  119. * @var int Manual count of old-style retweets as determined by ThinkUp. [Twitter-specific]
  120. */
  121. var $old_retweet_count_cache;
  122. /**
  123. * @var tinyint Whether or not this retweet was posted by a friend of the original post's author. [Twitter-specific]
  124. */
  125. var $is_retweet_by_friend;
  126. /**
  127. * @var int The distance (in km) away from the post that this post is in reply or retweet of [Twitter-specific-ish]
  128. */
  129. var $reply_retweet_distance;
  130. /**
  131. * @var str The network that this post belongs to in lower-case, e.g. twitter or facebook
  132. */
  133. var $network;
  134. /**
  135. * @var int Whether or not this post has been geo-encoded.
  136. * @TODO Give these constants meaningful names
  137. * 0 if Not Geoencoded, 1 if Successful, 2 if ZERO_RESULTS,
  138. * 3 if OVER_QUERY_LIMIT, 4 if REQUEST_DENIED, 5 if INVALID_REQUEST, 6 if INSUFFICIENT_DATA
  139. */
  140. var $is_geo_encoded = false;
  141. /**
  142. * @var int The ID of the user that this post is retweeting. [Twitter-specific]
  143. */
  144. var $in_rt_of_user_id;
  145. /**
  146. * @var int Manual count of native retweets as determined by ThinkUp. [Twitter-specific]
  147. */
  148. var $retweet_count_cache;
  149. /**
  150. * @var int The total number of native retweets as reported by Twitter API. [Twitter-specific]
  151. */
  152. var $retweet_count_api;
  153. /**
  154. * @var int The total number of favorites or likes this post received.
  155. */
  156. var $favlike_count_cache;
  157. /**
  158. *
  159. * @var User $author Optionally set
  160. */
  161. var $author;
  162. /**
  163. *
  164. * @var Array of Links $links Optionally set
  165. */
  166. var $links = array();
  167. /**
  168. * @var str Non-persistent, 'true' or 'false'
  169. */
  170. var $favorited;
  171. /**
  172. * @var str Non-persistent, When was this post favorited (only set in the context of fetching favorite posts)
  173. */
  174. var $favorited_timestamp;
  175. /**
  176. * @var int Non-persistent, used for UI
  177. */
  178. var $all_retweets;
  179. /**
  180. * @var int Non-persistent, used for UI, indicates whether Twitter RT count threshold was reached.
  181. */
  182. var $rt_threshold;
  183. /**
  184. * @var Str Link to this post on the respective service.
  185. */
  186. var $permalink;
  187. /**
  188. * Constructor
  189. * @param array $val Array of key/value pairs
  190. * @return Post
  191. */
  192. public function __construct($val) {
  193. // a fix for getPost() where the join of the links table column links.id overides the posts.id
  194. if (isset($val["post_key"])) {
  195. $this->id = $val["post_key"];
  196. } else {
  197. $this->id = $val["id"];
  198. }
  199. $this->post_id = $val["post_id"];
  200. $this->author_user_id = $val["author_user_id"];
  201. $this->author_username = $val["author_username"];
  202. $this->author_fullname = $val["author_fullname"];
  203. $this->author_avatar = $val["author_avatar"];
  204. $this->post_text = $val["post_text"];
  205. $this->is_protected = PDODAO::convertDBToBool($val["is_protected"]);
  206. $this->source = $val["source"];
  207. $this->location = $val["location"];
  208. $this->place = $val["place"];
  209. $this->place_id = $val["place_id"];
  210. $this->geo = $val["geo"];
  211. $this->pub_date = $val["pub_date"];
  212. $this->adj_pub_date = $val["adj_pub_date"];
  213. $this->in_reply_to_user_id = $val["in_reply_to_user_id"];
  214. $this->in_reply_to_post_id = $val["in_reply_to_post_id"];
  215. $this->reply_count_cache = $val["reply_count_cache"];
  216. $this->in_retweet_of_post_id = $val["in_retweet_of_post_id"];
  217. $this->in_rt_of_user_id = $val["in_rt_of_user_id"];
  218. $this->retweet_count_cache = $val["retweet_count_cache"];
  219. $this->retweet_count_api = $val["retweet_count_api"];
  220. $this->old_retweet_count_cache = $val["old_retweet_count_cache"];
  221. $this->reply_retweet_distance = $val["reply_retweet_distance"];
  222. $this->is_geo_encoded = $val["is_geo_encoded"];
  223. $this->network = $val["network"];
  224. $this->is_reply_by_friend = PDODAO::convertDBToBool($val["is_reply_by_friend"]);
  225. $this->is_retweet_by_friend = PDODAO::convertDBToBool($val["is_retweet_by_friend"]);
  226. $this->favlike_count_cache = $val["favlike_count_cache"];
  227. // favorited is non-persistent. Will be set from xml, but not from database retrieval.
  228. if (isset($val["favorited"])) {
  229. $this->favorited = $val["favorited"];
  230. }
  231. // favorited_timestamp is non-persistent. Will be set when joined to favorites table
  232. if (isset($val["favorited_timestamp"])) {
  233. $this->favorited_timestamp = $val["favorited_timestamp"];
  234. }
  235. // For the retweet count display, we will use the larger of retweet_count_cache and retweet_count_api,
  236. // and add it to old_retweet_count_cache.
  237. $largest_native_RT_count = $val['retweet_count_cache'];
  238. $this->rt_threshold = 0;
  239. // if twitter's reported count is larger, use that
  240. if ($val['retweet_count_api'] > $val['retweet_count_cache']) {
  241. $largest_native_RT_count = $val['retweet_count_api'];
  242. if ($largest_native_RT_count >= self::TWITTER_RT_THRESHOLD ) {
  243. // if the new RT count, obtained from twitter, has maxed out, set a non-persistent flag field
  244. // to indicate this. The templates will make use of this info to add a '+' after the sum if the
  245. // flag is set.
  246. $this->rt_threshold = 1;
  247. }
  248. }
  249. // non-persistent, used for UI information display
  250. $this->all_retweets = $val['old_retweet_count_cache'] + $largest_native_RT_count;
  251. $this->permalink = $val['permalink'];
  252. }
  253. /**
  254. * Add link to links array.
  255. * @param Link $link
  256. */
  257. public function addLink(Link $link) {
  258. $this->links[] = $link;
  259. }
  260. /**
  261. * Extract URLs from post text.
  262. * Find syntactically correct URLs such as http://foobar.com/data.php and some plausible URL fragments, e.g.
  263. * bit.ly/asb12 www.google.com, and fix URL fragments to be valid URLs.
  264. * Only return valid URLs
  265. * Regex pattern based on http://daringfireball.net/2010/07/improved_regex_for_matching_urls
  266. * with a modification in the third group to ensure that https?:/// (third slash) doesn't match.
  267. * @param string $post_text
  268. * @return array $matches
  269. */
  270. public static function extractURLs($post_text) {
  271. $url_pattern = '(?i)\b'.
  272. '((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)'.
  273. '(?:[^\s()<>/][^\s()<>]*|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+'.
  274. '(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’,]))';
  275. preg_match_all('#'.$url_pattern.'#', $post_text, $matches);
  276. $corrected_urls = array_map( 'Link::addMissingHttp', $matches[0]);
  277. return array_filter($corrected_urls,'Utils::validateURL');
  278. }
  279. /**
  280. * Extracts mentions from a Tweet.
  281. *
  282. * @param str $post_text The post text to search.
  283. * @return array $matches All mentions in this tweet.
  284. */
  285. public static function extractMentions($post_text) {
  286. if (!class_exists('Twitter_Extractor')) {
  287. Loader::addSpecialClass('Twitter_Extractor',
  288. 'plugins/twitter/extlib/twitter-text-php/lib/Twitter/Extractor.php');
  289. }
  290. $tweet = new Twitter_Extractor($post_text);
  291. $mentions = $tweet->extractMentionedUsernames();
  292. foreach ($mentions as $k => $v) {
  293. $mentions[$k] = '@' . $v;
  294. }
  295. return $mentions;
  296. }
  297. /**
  298. * Extracts hashtags from a Tweet.
  299. *
  300. * @param str $post_text The post text to search.
  301. * @return array $matches All hashtags in this tweet.
  302. */
  303. public static function extractHashtags($post_text) {
  304. preg_match_all('/(^|[^a-z0-9_])#([a-z0-9_]+)/i', $post_text, $matches);
  305. // sometimes there's leading or trailing whitespace on the match, trim it
  306. foreach ($matches[0] as $key=>$match) {
  307. $matches[0][$key] = trim($match, ' ');
  308. }
  309. return $matches[0];
  310. }
  311. }