| 
									
										
										
										
											2008-05-07 13:15:42 -04:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2009-10-04 11:14:26 +13:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2009-08-25 18:14:12 -04:00
										 |  |  |  * StatusNet - the distributed open-source microblogging tool | 
					
						
							| 
									
										
										
										
											2011-07-15 12:13:57 -07:00
										 |  |  |  * Copyright (C) 2008-2011 StatusNet, Inc. | 
					
						
							| 
									
										
										
										
											2008-05-20 15:14:12 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2008-05-14 15:26:48 -04:00
										 |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2008-05-20 15:14:12 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2008-05-14 15:26:48 -04:00
										 |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the | 
					
						
							| 
									
										
										
										
											2008-05-14 15:26:48 -04:00
										 |  |  |  * GNU Affero General Public License for more details. | 
					
						
							| 
									
										
										
										
											2008-05-20 15:14:12 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2008-05-14 15:26:48 -04:00
										 |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |  * along with this program.     If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-10-04 11:14:26 +13:00
										 |  |  |  * @category Notices | 
					
						
							|  |  |  |  * @package  StatusNet | 
					
						
							|  |  |  |  * @author   Brenda Wallace <shiny@cpan.org> | 
					
						
							|  |  |  |  * @author   Christopher Vollick <psycotica0@gmail.com> | 
					
						
							|  |  |  |  * @author   CiaranG <ciaran@ciarang.com> | 
					
						
							|  |  |  |  * @author   Craig Andrews <candrews@integralblue.com> | 
					
						
							|  |  |  |  * @author   Evan Prodromou <evan@controlezvous.ca> | 
					
						
							|  |  |  |  * @author   Gina Haeussge <osd@foosel.net> | 
					
						
							|  |  |  |  * @author   Jeffery To <jeffery.to@gmail.com> | 
					
						
							|  |  |  |  * @author   Mike Cochrane <mikec@mikenz.geek.nz> | 
					
						
							|  |  |  |  * @author   Robin Millette <millette@controlyourself.ca> | 
					
						
							|  |  |  |  * @author   Sarven Capadisli <csarven@controlyourself.ca> | 
					
						
							|  |  |  |  * @author   Tom Adams <tom@holizz.com> | 
					
						
							| 
									
										
										
										
											2010-05-27 18:26:47 -04:00
										 |  |  |  * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org | 
					
						
							| 
									
										
										
										
											2009-10-04 11:14:26 +13:00
										 |  |  |  * @license  GNU Affero General Public License http://www.gnu.org/licenses/ | 
					
						
							| 
									
										
										
										
											2008-05-14 15:26:48 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-05-14 15:00:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | if (!defined('STATUSNET') && !defined('LACONICA')) { | 
					
						
							|  |  |  |     exit(1); | 
					
						
							| 
									
										
										
										
											2009-10-04 11:14:26 +13:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-05-14 15:00:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-07 13:15:42 -04:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |  * Table Definition for notice | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-09-26 12:18:24 -04:00
										 |  |  | require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; | 
					
						
							| 
									
										
										
										
											2008-05-07 13:15:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-21 12:29:47 -07:00
										 |  |  | /* We keep 200 notices, the max number of notices available per API request, | 
					
						
							| 
									
										
										
											
												single function for important streams, with memcached support
I moved the 4 streams for a user (with friends, faves, replies,
personal) into functions on the User object. Added a helper function
in Notice for making notice streams. Also, will fetch notice streams
out of the memcached server, if possible. Made the API, RSS, and HTML
output all use the same streams (hopefully cached).
Added some code to Notice to blow the cache when a notice is posted.
Also, added code to favor and disfavor actions to blow the faves
cache, too.
darcs-hash:20080928120119-5ed1f-ead542348bcd3cf315be6f42934353154402eb16.gz
											
										 
											2008-09-28 08:01:19 -04:00
										 |  |  |  * in the memcached cache. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-24 18:04:19 -04:00
										 |  |  | define('NOTICE_CACHE_WINDOW', CachingNoticeStream::CACHE_WINDOW); | 
					
						
							| 
									
										
										
											
												single function for important streams, with memcached support
I moved the 4 streams for a user (with friends, faves, replies,
personal) into functions on the User object. Added a helper function
in Notice for making notice streams. Also, will fetch notice streams
out of the memcached server, if possible. Made the API, RSS, and HTML
output all use the same streams (hopefully cached).
Added some code to Notice to blow the cache when a notice is posted.
Also, added code to favor and disfavor actions to blow the faves
cache, too.
darcs-hash:20080928120119-5ed1f-ead542348bcd3cf315be6f42934353154402eb16.gz
											
										 
											2008-09-28 08:01:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-26 00:47:27 -07:00
										 |  |  | define('MAX_BOXCARS', 128); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 17:52:02 -04:00
										 |  |  | class Notice extends Managed_DataObject | 
					
						
							| 
									
										
										
										
											2008-05-07 13:15:42 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |     ###START_AUTOCODE
 | 
					
						
							|  |  |  |     /* the code below is auto generated do not remove the above tag */ | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-16 18:26:15 -05:00
										 |  |  |     public $__table = 'notice';                          // table name
 | 
					
						
							|  |  |  |     public $id;                              // int(4)  primary_key not_null
 | 
					
						
							| 
									
										
										
										
											2009-12-11 10:22:56 -05:00
										 |  |  |     public $profile_id;                      // int(4)  multiple_key not_null
 | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |     public $uri;                             // varchar(255)  unique_key
 | 
					
						
							| 
									
										
										
										
											2009-12-11 10:22:56 -05:00
										 |  |  |     public $content;                         // text
 | 
					
						
							|  |  |  |     public $rendered;                        // text
 | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |     public $url;                             // varchar(255)
 | 
					
						
							| 
									
										
										
										
											2009-12-11 10:22:56 -05:00
										 |  |  |     public $created;                         // datetime  multiple_key not_null default_0000-00-00%2000%3A00%3A00
 | 
					
						
							|  |  |  |     public $modified;                        // timestamp   not_null default_CURRENT_TIMESTAMP
 | 
					
						
							| 
									
										
										
										
											2009-02-16 18:26:15 -05:00
										 |  |  |     public $reply_to;                        // int(4)
 | 
					
						
							| 
									
										
										
										
											2010-01-07 20:59:31 +00:00
										 |  |  |     public $is_local;                        // int(4)
 | 
					
						
							| 
									
										
										
										
											2009-02-16 18:26:15 -05:00
										 |  |  |     public $source;                          // varchar(32)
 | 
					
						
							| 
									
										
										
										
											2009-02-26 13:37:00 -08:00
										 |  |  |     public $conversation;                    // int(4)
 | 
					
						
							| 
									
										
										
										
											2009-09-15 18:28:44 -04:00
										 |  |  |     public $lat;                             // decimal(10,7)
 | 
					
						
							|  |  |  |     public $lon;                             // decimal(10,7)
 | 
					
						
							|  |  |  |     public $location_id;                     // int(4)
 | 
					
						
							|  |  |  |     public $location_ns;                     // int(4)
 | 
					
						
							| 
									
										
										
										
											2009-12-11 10:22:56 -05:00
										 |  |  |     public $repeat_of;                       // int(4)
 | 
					
						
							| 
									
										
										
										
											2011-08-22 16:02:14 -04:00
										 |  |  |     public $verb;                            // varchar(255)
 | 
					
						
							| 
									
										
										
										
											2011-03-07 14:20:55 -05:00
										 |  |  |     public $object_type;                     // varchar(255)
 | 
					
						
							| 
									
										
										
										
											2011-03-16 22:30:31 -04:00
										 |  |  |     public $scope;                           // int(4)
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |     /* Static get */ | 
					
						
							| 
									
										
										
										
											2009-12-11 10:22:56 -05:00
										 |  |  |     function staticGet($k,$v=NULL) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-09-15 18:28:44 -04:00
										 |  |  |         return Memcached_DataObject::staticGet('Notice',$k,$v); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |     /* the code above is auto generated do not remove the tag below */ | 
					
						
							|  |  |  |     ###END_AUTOCODE
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 17:52:02 -04:00
										 |  |  |     public static function schemaDef() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-09-18 18:28:44 -04:00
										 |  |  |         $def = array( | 
					
						
							| 
									
										
										
										
											2011-08-22 17:52:02 -04:00
										 |  |  |             'fields' => array( | 
					
						
							|  |  |  |                 'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'), | 
					
						
							|  |  |  |                 'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'who made the update'), | 
					
						
							|  |  |  |                 'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier, usually a tag URI'), | 
					
						
							| 
									
										
										
										
											2011-08-27 16:33:15 -04:00
										 |  |  |                 'content' => array('type' => 'text', 'description' => 'update content', 'collate' => 'utf8_general_ci'), | 
					
						
							| 
									
										
										
										
											2011-08-22 17:52:02 -04:00
										 |  |  |                 'rendered' => array('type' => 'text', 'description' => 'HTML version of the content'), | 
					
						
							|  |  |  |                 'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL of any attachment (image, video, bookmark, whatever)'), | 
					
						
							|  |  |  |                 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), | 
					
						
							|  |  |  |                 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'), | 
					
						
							|  |  |  |                 'reply_to' => array('type' => 'int', 'description' => 'notice replied to (usually a guess)'), | 
					
						
							|  |  |  |                 'is_local' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'notice was generated by a user'), | 
					
						
							|  |  |  |                 'source' => array('type' => 'varchar', 'length' => 32, 'description' => 'source of comment, like "web", "im", or "clientname"'), | 
					
						
							|  |  |  |                 'conversation' => array('type' => 'int', 'description' => 'id of root notice in this conversation'), | 
					
						
							|  |  |  |                 'lat' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'), | 
					
						
							|  |  |  |                 'lon' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'), | 
					
						
							|  |  |  |                 'location_id' => array('type' => 'int', 'description' => 'location id if possible'), | 
					
						
							|  |  |  |                 'location_ns' => array('type' => 'int', 'description' => 'namespace for location'), | 
					
						
							|  |  |  |                 'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'), | 
					
						
							|  |  |  |                 'object_type' => array('type' => 'varchar', 'length' => 255, 'description' => 'URI representing activity streams object type', 'default' => 'http://activitystrea.ms/schema/1.0/note'), | 
					
						
							| 
									
										
										
										
											2011-08-23 11:42:18 -04:00
										 |  |  |                 'verb' => array('type' => 'varchar', 'length' => 255, 'description' => 'URI representing activity streams verb', 'default' => 'http://activitystrea.ms/schema/1.0/post'), | 
					
						
							| 
									
										
										
										
											2011-08-22 17:52:02 -04:00
										 |  |  |                 'scope' => array('type' => 'int', | 
					
						
							| 
									
										
										
										
											2011-09-08 12:38:11 -04:00
										 |  |  |                                  'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = followers; null = default'), | 
					
						
							| 
									
										
										
										
											2011-08-22 17:52:02 -04:00
										 |  |  |             ), | 
					
						
							|  |  |  |             'primary key' => array('id'), | 
					
						
							|  |  |  |             'unique keys' => array( | 
					
						
							|  |  |  |                 'notice_uri_key' => array('uri'), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             'foreign keys' => array( | 
					
						
							|  |  |  |                 'notice_profile_id_fkey' => array('profile', array('profile_id' => 'id')), | 
					
						
							|  |  |  |                 'notice_reply_to_fkey' => array('notice', array('reply_to' => 'id')), | 
					
						
							|  |  |  |                 'notice_conversation_fkey' => array('conversation', array('conversation' => 'id')), # note... used to refer to notice.id
 | 
					
						
							|  |  |  |                 'notice_repeat_of_fkey' => array('notice', array('repeat_of' => 'id')), # @fixme: what about repeats of deleted notices?
 | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             'indexes' => array( | 
					
						
							| 
									
										
										
										
											2011-10-20 12:50:39 -04:00
										 |  |  |                 'notice_created_id_is_local_idx' => array('created', 'id', 'is_local'), | 
					
						
							| 
									
										
										
										
											2011-08-22 17:52:02 -04:00
										 |  |  |                 'notice_profile_id_idx' => array('profile_id', 'created', 'id'), | 
					
						
							| 
									
										
										
										
											2011-10-20 12:50:39 -04:00
										 |  |  |                 'notice_repeat_of_created_id_idx' => array('repeat_of', 'created', 'id'), | 
					
						
							|  |  |  |                 'notice_conversation_created_id_idx' => array('conversation', 'created', 'id'), | 
					
						
							|  |  |  |                 'notice_replyto_idx' => array('reply_to') | 
					
						
							| 
									
										
										
										
											2011-08-22 17:52:02 -04:00
										 |  |  |             ) | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2011-09-18 18:28:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (common_config('search', 'type') == 'fulltext') { | 
					
						
							|  |  |  |             $def['fulltext indexes'] = array('content' => array('content')); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $def; | 
					
						
							| 
									
										
										
										
											2011-08-22 17:52:02 -04:00
										 |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2011-07-14 14:41:30 -04:00
										 |  |  | 	function multiGet($kc, $kvs, $skipNulls=true) | 
					
						
							| 
									
										
										
										
											2011-07-14 12:02:58 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-07-14 14:41:30 -04:00
										 |  |  | 		return Memcached_DataObject::multiGet('Notice', $kc, $kvs, $skipNulls); | 
					
						
							| 
									
										
										
										
											2011-07-14 12:02:58 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-08-27 20:09:07 -07:00
										 |  |  |     /* Notice types */ | 
					
						
							| 
									
										
										
										
											2009-08-19 08:34:17 +02:00
										 |  |  |     const LOCAL_PUBLIC    =  1; | 
					
						
							| 
									
										
										
										
											2011-07-15 12:13:57 -07:00
										 |  |  |     const REMOTE          =  0; | 
					
						
							| 
									
										
										
										
											2009-08-19 08:34:17 +02:00
										 |  |  |     const LOCAL_NONPUBLIC = -1; | 
					
						
							|  |  |  |     const GATEWAY         = -2; | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-29 11:53:26 -04:00
										 |  |  |     const PUBLIC_SCOPE    = 0; // Useful fake constant
 | 
					
						
							| 
									
										
										
										
											2011-03-16 22:54:57 -04:00
										 |  |  |     const SITE_SCOPE      = 1; | 
					
						
							|  |  |  |     const ADDRESSEE_SCOPE = 2; | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |     const GROUP_SCOPE     = 4; | 
					
						
							|  |  |  |     const FOLLOWER_SCOPE  = 8; | 
					
						
							| 
									
										
										
										
											2011-03-16 22:54:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-07 16:55:32 -04:00
										 |  |  |     protected $_profile = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 14:33:23 -05:00
										 |  |  |     function getProfile() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-09 22:16:52 +05:30
										 |  |  |         if (is_int($this->_profile) && $this->_profile == -1) { | 
					
						
							| 
									
										
										
										
											2011-08-01 14:51:59 -04:00
										 |  |  |             $this->_setProfile(Profile::staticGet('id', $this->profile_id)); | 
					
						
							| 
									
										
										
										
											2010-07-13 10:51:25 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-07 16:55:32 -04:00
										 |  |  |             if (empty($this->_profile)) { | 
					
						
							|  |  |  |                 // TRANS: Server exception thrown when a user profile for a notice cannot be found.
 | 
					
						
							|  |  |  |                 // TRANS: %1$d is a profile ID (number), %2$d is a notice ID (number).
 | 
					
						
							|  |  |  |                 throw new ServerException(sprintf(_('No such profile (%1$d) for notice (%2$d).'), $this->profile_id, $this->id)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-07-13 10:51:25 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-07 16:55:32 -04:00
										 |  |  |         return $this->_profile; | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-01 14:51:59 -04:00
										 |  |  |      | 
					
						
							|  |  |  |     function _setProfile($profile) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->_profile = $profile; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 14:33:23 -05:00
										 |  |  |     function delete() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-07-16 00:52:23 -04:00
										 |  |  |         // For auditing purposes, save a record that the notice
 | 
					
						
							|  |  |  |         // was deleted.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-24 07:47:15 -07:00
										 |  |  |         // @fixme we have some cases where things get re-run and so the
 | 
					
						
							|  |  |  |         // insert fails.
 | 
					
						
							|  |  |  |         $deleted = Deleted_notice::staticGet('id', $this->id); | 
					
						
							| 
									
										
										
										
											2010-12-27 22:58:13 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!$deleted) { | 
					
						
							|  |  |  |             $deleted = Deleted_notice::staticGet('uri', $this->uri); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-24 07:47:15 -07:00
										 |  |  |         if (!$deleted) { | 
					
						
							|  |  |  |             $deleted = new Deleted_notice(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-24 07:47:15 -07:00
										 |  |  |             $deleted->id         = $this->id; | 
					
						
							|  |  |  |             $deleted->profile_id = $this->profile_id; | 
					
						
							|  |  |  |             $deleted->uri        = $this->uri; | 
					
						
							|  |  |  |             $deleted->created    = $this->created; | 
					
						
							|  |  |  |             $deleted->deleted    = common_sql_now(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-24 07:47:15 -07:00
										 |  |  |             $deleted->insert(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-14 11:54:20 -07:00
										 |  |  |         if (Event::handle('NoticeDeleteRelated', array($this))) { | 
					
						
							| 
									
										
										
										
											2009-12-12 16:02:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-14 11:54:20 -07:00
										 |  |  |             // Clear related records
 | 
					
						
							| 
									
										
										
										
											2009-12-12 16:02:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-14 11:54:20 -07:00
										 |  |  |             $this->clearReplies(); | 
					
						
							|  |  |  |             $this->clearRepeats(); | 
					
						
							|  |  |  |             $this->clearFaves(); | 
					
						
							|  |  |  |             $this->clearTags(); | 
					
						
							|  |  |  |             $this->clearGroupInboxes(); | 
					
						
							| 
									
										
										
										
											2010-12-28 13:44:18 -08:00
										 |  |  |             $this->clearFiles(); | 
					
						
							| 
									
										
										
										
											2010-08-14 11:54:20 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // NOTE: we don't clear inboxes
 | 
					
						
							|  |  |  |             // NOTE: we don't clear queue items
 | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-13 17:38:27 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 19:38:40 +01:00
										 |  |  |         $result = parent::delete(); | 
					
						
							| 
									
										
										
										
											2010-03-15 14:19:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $this->blowOnDelete(); | 
					
						
							|  |  |  |         return $result; | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-25 11:26:33 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Extract #hashtags from this notice's content and save them to the database.
 | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2008-12-23 14:33:23 -05:00
										 |  |  |     function saveTags() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |         /* extract all #hastags */ | 
					
						
							| 
									
										
										
										
											2011-02-23 16:37:55 -08:00
										 |  |  |         $count = preg_match_all('/(?:^|\s)#([\pL\pN_\-\.]{1,64})/u', strtolower($this->content), $match); | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |         if (!$count) { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-25 11:26:33 -08:00
										 |  |  |         /* Add them to the database */ | 
					
						
							|  |  |  |         return $this->saveKnownTags($match[1]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Record the given set of hash tags in the db for this notice. | 
					
						
							|  |  |  |      * Given tag strings will be normalized and checked for dupes. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function saveKnownTags($hashtags) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-07-20 14:18:48 +12:00
										 |  |  |         //turn each into their canonical tag
 | 
					
						
							|  |  |  |         //this is needed to remove dupes before saving e.g. #hash.tag = #hashtag
 | 
					
						
							| 
									
										
										
										
											2010-02-25 11:26:33 -08:00
										 |  |  |         for($i=0; $i<count($hashtags); $i++) { | 
					
						
							| 
									
										
										
										
											2010-04-14 11:09:54 +02:00
										 |  |  |             /* elide characters we don't want in the tag */ | 
					
						
							| 
									
										
										
										
											2010-02-25 11:26:33 -08:00
										 |  |  |             $hashtags[$i] = common_canonical_tag($hashtags[$i]); | 
					
						
							| 
									
										
										
										
											2009-07-20 14:18:48 +12:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-20 14:18:48 +12:00
										 |  |  |         foreach(array_unique($hashtags) as $hashtag) { | 
					
						
							| 
									
										
										
										
											2009-02-16 18:02:31 -05:00
										 |  |  |             $this->saveTag($hashtag); | 
					
						
							| 
									
										
										
										
											2010-01-30 14:37:39 -05:00
										 |  |  |             self::blow('profile:notice_ids_tagged:%d:%s', $this->profile_id, $hashtag); | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-25 11:26:33 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Record a single hash tag as associated with this notice. | 
					
						
							|  |  |  |      * Tag format and uniqueness must be validated by caller. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-02-16 18:02:31 -05:00
										 |  |  |     function saveTag($hashtag) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $tag = new Notice_tag(); | 
					
						
							|  |  |  |         $tag->notice_id = $this->id; | 
					
						
							|  |  |  |         $tag->tag = $hashtag; | 
					
						
							|  |  |  |         $tag->created = $this->created; | 
					
						
							|  |  |  |         $id = $tag->insert(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-16 18:02:31 -05:00
										 |  |  |         if (!$id) { | 
					
						
							| 
									
										
										
										
											2010-04-11 01:08:51 +02:00
										 |  |  |             // TRANS: Server exception. %s are the error details.
 | 
					
						
							| 
									
										
										
										
											2011-04-10 19:59:55 +02:00
										 |  |  |             throw new ServerException(sprintf(_('Database error inserting hashtag: %s.'), | 
					
						
							| 
									
										
										
										
											2009-02-16 18:02:31 -05:00
										 |  |  |                                               $last_error->message)); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // if it's saved, blow its cache
 | 
					
						
							|  |  |  |         $tag->blowCache(false); | 
					
						
							| 
									
										
										
										
											2009-02-16 18:02:31 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 18:27:03 -05:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Save a new notice and push it out to subscribers' inboxes. | 
					
						
							|  |  |  |      * Poster's permissions are checked before sending. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param int $profile_id Profile ID of the poster | 
					
						
							|  |  |  |      * @param string $content source message text; links may be shortened | 
					
						
							|  |  |  |      *                        per current user's preference | 
					
						
							|  |  |  |      * @param string $source source key ('web', 'api', etc) | 
					
						
							|  |  |  |      * @param array $options Associative array of optional properties: | 
					
						
							|  |  |  |      *              string 'created' timestamp of notice; defaults to now | 
					
						
							|  |  |  |      *              int 'is_local' source/gateway ID, one of: | 
					
						
							|  |  |  |      *                  Notice::LOCAL_PUBLIC    - Local, ok to appear in public timeline | 
					
						
							| 
									
										
										
										
											2011-07-15 12:13:57 -07:00
										 |  |  |      *                  Notice::REMOTE          - Sent from a remote service; | 
					
						
							| 
									
										
										
										
											2009-12-15 18:27:03 -05:00
										 |  |  |      *                                            hide from public timeline but show in | 
					
						
							|  |  |  |      *                                            local "and friends" timelines | 
					
						
							|  |  |  |      *                  Notice::LOCAL_NONPUBLIC - Local, but hide from public timeline | 
					
						
							| 
									
										
										
										
											2011-07-15 12:13:57 -07:00
										 |  |  |      *                  Notice::GATEWAY         - From another non-OStatus service; | 
					
						
							| 
									
										
										
										
											2009-12-15 18:27:03 -05:00
										 |  |  |      *                                            will not appear in public views | 
					
						
							|  |  |  |      *              float 'lat' decimal latitude for geolocation | 
					
						
							|  |  |  |      *              float 'lon' decimal longitude for geolocation | 
					
						
							|  |  |  |      *              int 'location_id' geoname identifier | 
					
						
							|  |  |  |      *              int 'location_ns' geoname namespace to interpret location_id | 
					
						
							|  |  |  |      *              int 'reply_to'; notice ID this is a reply to | 
					
						
							|  |  |  |      *              int 'repeat_of'; notice ID this is a repeat of | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |      *              string 'uri' unique ID for notice; defaults to local notice URL | 
					
						
							|  |  |  |      *              string 'url' permalink to notice; defaults to local notice URL | 
					
						
							|  |  |  |      *              string 'rendered' rendered HTML version of content | 
					
						
							|  |  |  |      *              array 'replies' list of profile URIs for reply delivery in | 
					
						
							|  |  |  |      *                              place of extracting @-replies from content. | 
					
						
							|  |  |  |      *              array 'groups' list of group IDs to deliver to, in place of | 
					
						
							|  |  |  |      *                              extracting ! tags from content | 
					
						
							| 
									
										
										
										
											2010-02-25 11:26:33 -08:00
										 |  |  |      *              array 'tags' list of hashtag strings to save with the notice | 
					
						
							|  |  |  |      *                           in place of extracting # tags from content
 | 
					
						
							| 
									
										
										
										
											2010-03-02 16:30:09 -08:00
										 |  |  |      *              array 'urls' list of attached/referred URLs to save with the | 
					
						
							|  |  |  |      *                           notice in place of extracting links from content | 
					
						
							| 
									
										
										
										
											2010-12-16 16:17:38 -05:00
										 |  |  |      *              boolean 'distribute' whether to distribute the notice, default true | 
					
						
							| 
									
										
										
										
											2011-03-07 14:20:55 -05:00
										 |  |  |      *              string 'object_type' URL of the associated object type (default ActivityObject::NOTE) | 
					
						
							| 
									
										
										
										
											2011-08-22 16:02:14 -04:00
										 |  |  |      *              string 'verb' URL of the associated verb (default ActivityVerb::POST) | 
					
						
							| 
									
										
										
										
											2011-03-26 15:49:46 -04:00
										 |  |  |      *              int 'scope' Scope bitmask; default to SITE_SCOPE on private sites, 0 otherwise | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |      * @fixme tag override | 
					
						
							| 
									
										
										
										
											2009-12-15 18:27:03 -05:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return Notice | 
					
						
							|  |  |  |      * @throws ClientException | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-12-11 11:29:51 -05:00
										 |  |  |     static function saveNew($profile_id, $content, $source, $options=null) { | 
					
						
							| 
									
										
										
										
											2009-12-15 13:05:05 -08:00
										 |  |  |         $defaults = array('uri' => null, | 
					
						
							| 
									
										
										
										
											2010-02-21 09:17:00 -05:00
										 |  |  |                           'url' => null, | 
					
						
							| 
									
										
										
										
											2009-12-15 13:05:05 -08:00
										 |  |  |                           'reply_to' => null, | 
					
						
							| 
									
										
										
										
											2010-12-16 16:17:38 -05:00
										 |  |  |                           'repeat_of' => null, | 
					
						
							| 
									
										
										
										
											2011-03-26 15:49:46 -04:00
										 |  |  |                           'scope' => null, | 
					
						
							| 
									
										
										
										
											2011-08-22 16:02:14 -04:00
										 |  |  |                           'distribute' => true, | 
					
						
							|  |  |  |                           'object_type' => null, | 
					
						
							|  |  |  |                           'verb' => null); | 
					
						
							| 
									
										
										
										
											2009-12-11 11:29:51 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-20 11:53:47 -04:00
										 |  |  |         if (!empty($options) && is_array($options)) { | 
					
						
							|  |  |  |             $options = array_merge($defaults, $options); | 
					
						
							| 
									
										
										
										
											2009-12-11 11:29:51 -05:00
										 |  |  |             extract($options); | 
					
						
							| 
									
										
										
										
											2010-08-12 15:18:50 -07:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             extract($defaults); | 
					
						
							| 
									
										
										
										
											2009-12-11 11:29:51 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 08:36:47 -10:00
										 |  |  |         if (!isset($is_local)) { | 
					
						
							| 
									
										
										
										
											2009-12-11 11:29:51 -05:00
										 |  |  |             $is_local = Notice::LOCAL_PUBLIC; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-02 10:56:44 -08:00
										 |  |  |         $profile = Profile::staticGet('id', $profile_id); | 
					
						
							|  |  |  |         $user = User::staticGet('id', $profile_id); | 
					
						
							|  |  |  |         if ($user) { | 
					
						
							|  |  |  |             // Use the local user's shortening preferences, if applicable.
 | 
					
						
							|  |  |  |             $final = $user->shortenLinks($content); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $final = common_shorten_links($content); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (Notice::contentTooLong($final)) { | 
					
						
							| 
									
										
										
										
											2010-07-29 11:34:58 +02:00
										 |  |  |             // TRANS: Client exception thrown if a notice contains too many characters.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |             throw new ClientException(_('Problem saving notice. Too long.')); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-28 14:21:42 -04:00
										 |  |  |         if (empty($profile)) { | 
					
						
							| 
									
										
										
										
											2010-07-29 11:34:58 +02:00
										 |  |  |             // TRANS: Client exception thrown when trying to save a notice for an unknown user.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |             throw new ClientException(_('Problem saving notice. Unknown user.')); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (common_config('throttle', 'enabled') && !Notice::checkEditThrottle($profile_id)) { | 
					
						
							|  |  |  |             common_log(LOG_WARNING, 'Excessive posting by profile #' . $profile_id . '; throttled.'); | 
					
						
							| 
									
										
										
										
											2010-07-29 11:34:58 +02:00
										 |  |  |             // TRANS: Client exception thrown when a user tries to post too many notices in a given time frame.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |             throw new ClientException(_('Too many notices too fast; take a breather '. | 
					
						
							| 
									
										
										
										
											2009-09-29 17:16:07 -04:00
										 |  |  |                                         'and post again in a few minutes.')); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (common_config('site', 'dupelimit') > 0 && !Notice::checkDupes($profile_id, $final)) { | 
					
						
							|  |  |  |             common_log(LOG_WARNING, 'Dupe posting by profile #' . $profile_id . '; throttled.'); | 
					
						
							| 
									
										
										
										
											2010-07-29 11:34:58 +02:00
										 |  |  |             // TRANS: Client exception thrown when a user tries to post too many duplicate notices in a given time frame.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |             throw new ClientException(_('Too many duplicate messages too quickly;'. | 
					
						
							| 
									
										
										
										
											2009-09-29 17:16:07 -04:00
										 |  |  |                                         ' take a breather and post again in a few minutes.')); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-16 19:03:59 +01:00
										 |  |  |         if (!$profile->hasRight(Right::NEWNOTICE)) { | 
					
						
							|  |  |  |             common_log(LOG_WARNING, "Attempted post from user disallowed to post: " . $profile->nickname); | 
					
						
							| 
									
										
										
										
											2010-07-29 20:44:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-29 11:34:58 +02:00
										 |  |  |             // TRANS: Client exception thrown when a user tries to post while being banned.
 | 
					
						
							| 
									
										
										
										
											2010-07-29 18:47:28 +00:00
										 |  |  |             throw new ClientException(_('You are banned from posting notices on this site.'), 403); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $notice = new Notice(); | 
					
						
							|  |  |  |         $notice->profile_id = $profile_id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $autosource = common_config('public', 'autosource'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 11:54:23 -04:00
										 |  |  |         // Sandboxed are non-false, but not 1, either
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 08:48:16 -08:00
										 |  |  |         if (!$profile->hasRight(Right::PUBLICNOTICE) || | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |             ($source && $autosource && in_array($source, $autosource))) { | 
					
						
							|  |  |  |             $notice->is_local = Notice::LOCAL_NONPUBLIC; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $notice->is_local = $is_local; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($created)) { | 
					
						
							|  |  |  |             $notice->created = $created; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $notice->created = common_sql_now(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $notice->content = $final; | 
					
						
							| 
									
										
										
										
											2010-02-21 09:17:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |         $notice->source = $source; | 
					
						
							|  |  |  |         $notice->uri = $uri; | 
					
						
							| 
									
										
										
										
											2010-02-21 09:17:00 -05:00
										 |  |  |         $notice->url = $url; | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-04 22:34:47 -04:00
										 |  |  |         // Get the groups here so we can figure out replies and such
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!isset($groups)) { | 
					
						
							|  |  |  |             $groups = self::groupsFromText($notice->content, $profile); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-04 18:13:28 -04:00
										 |  |  |         $reply = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-11 11:51:09 -05:00
										 |  |  |         // Handle repeat case
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (isset($repeat_of)) { | 
					
						
							| 
									
										
										
										
											2011-03-29 11:53:26 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // Check for a private one
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $repeat = Notice::staticGet('id', $repeat_of); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-29 16:20:12 -07:00
										 |  |  |             if (empty($repeat)) { | 
					
						
							| 
									
										
										
										
											2011-03-31 22:48:03 +02:00
										 |  |  |                 // TRANS: Client exception thrown in notice when trying to repeat a missing or deleted notice.
 | 
					
						
							| 
									
										
										
										
											2011-03-29 16:20:12 -07:00
										 |  |  |                 throw new ClientException(_('Cannot repeat; original notice is missing or deleted.')); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ($profile->id == $repeat->profile_id) { | 
					
						
							|  |  |  |                 // TRANS: Client error displayed when trying to repeat an own notice.
 | 
					
						
							|  |  |  |                 throw new ClientException(_('You cannot repeat your own notice.')); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ($repeat->scope != Notice::SITE_SCOPE && | 
					
						
							| 
									
										
										
										
											2011-03-29 11:53:26 -04:00
										 |  |  |                 $repeat->scope != Notice::PUBLIC_SCOPE) { | 
					
						
							| 
									
										
										
										
											2011-03-29 16:20:12 -07:00
										 |  |  |                 // TRANS: Client error displayed when trying to repeat a non-public notice.
 | 
					
						
							| 
									
										
										
										
											2011-03-29 11:53:26 -04:00
										 |  |  |                 throw new ClientException(_('Cannot repeat a private notice.'), 403); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-29 16:20:12 -07:00
										 |  |  |             if (!$repeat->inScope($profile)) { | 
					
						
							|  |  |  |                 // The generic checks above should cover this, but let's be sure!
 | 
					
						
							|  |  |  |                 // TRANS: Client error displayed when trying to repeat a notice you cannot access.
 | 
					
						
							|  |  |  |                 throw new ClientException(_('Cannot repeat a notice you cannot read.'), 403); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ($profile->hasRepeated($repeat->id)) { | 
					
						
							|  |  |  |                 // TRANS: Client error displayed when trying to repeat an already repeated notice.
 | 
					
						
							|  |  |  |                 throw new ClientException(_('You already repeated that notice.')); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-03-29 11:53:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-11 11:51:09 -05:00
										 |  |  |             $notice->repeat_of = $repeat_of; | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2011-04-04 18:13:28 -04:00
										 |  |  |             $reply = self::getReplyTo($reply_to, $profile_id, $source, $final); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!empty($reply)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (!$reply->inScope($profile)) { | 
					
						
							|  |  |  |                     // TRANS: Client error displayed when trying to reply to a notice a the target has no access to.
 | 
					
						
							|  |  |  |                     // TRANS: %1$s is a user nickname, %2$d is a notice ID (number).
 | 
					
						
							|  |  |  |                     throw new ClientException(sprintf(_('%1$s has no access to notice %2$d.'), | 
					
						
							|  |  |  |                                                       $profile->nickname, $reply->id), 403); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-04 18:13:28 -04:00
										 |  |  |                 $notice->reply_to     = $reply->id; | 
					
						
							|  |  |  |                 $notice->conversation = $reply->conversation; | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-04 22:34:47 -04:00
										 |  |  |                 // If the original is private to a group, and notice has no group specified,
 | 
					
						
							|  |  |  |                 // make it to the same group(s)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (empty($groups) && ($reply->scope | Notice::GROUP_SCOPE)) { | 
					
						
							|  |  |  |                     $groups = array(); | 
					
						
							|  |  |  |                     $replyGroups = $reply->getGroups(); | 
					
						
							|  |  |  |                     foreach ($replyGroups as $group) { | 
					
						
							|  |  |  |                         if ($profile->isMember($group)) { | 
					
						
							|  |  |  |                             $groups[] = $group->id; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-04 18:13:28 -04:00
										 |  |  |                 // Scope set below
 | 
					
						
							| 
									
										
										
										
											2011-03-28 12:01:08 -04:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 11:47:00 -04:00
										 |  |  |         if (!empty($lat) && !empty($lon)) { | 
					
						
							|  |  |  |             $notice->lat = $lat; | 
					
						
							|  |  |  |             $notice->lon = $lon; | 
					
						
							| 
									
										
										
										
											2009-12-28 15:13:15 -08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($location_ns) && !empty($location_id)) { | 
					
						
							| 
									
										
										
										
											2009-10-23 11:47:00 -04:00
										 |  |  |             $notice->location_id = $location_id; | 
					
						
							|  |  |  |             $notice->location_ns = $location_ns; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Use notice for context when deciding who @nickname refers to
In a federated system, "@nickname" is insufficient to uniquely
identify a user. However, it's a very convenient idiom. We need to
guess from context who 'nickname' refers to.
Previously, we were using the sender's profile (or what we knew about
them) as the only context. So, we assumed that they'd be mentioning to
someone they followed, or someone who followed them, or someone on
their own server.
Now, we include the notice information for context. We check to see if
the notice is a reply to another notice, and if the author of the
original notice has the nickname 'nickname', then the mention is
probably for them. Alternately, if the original notice mentions someone
with nickname 'nickname', then this notice is probably referring to
_them_.
Doing this kind of context sleuthing means we have to render the
content very late in the notice-saving process.
											
										 
											2010-02-27 16:06:46 -05:00
										 |  |  |         if (!empty($rendered)) { | 
					
						
							|  |  |  |             $notice->rendered = $rendered; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $notice->rendered = common_render_content($final, $notice); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 16:02:14 -04:00
										 |  |  |         if (empty($verb)) { | 
					
						
							|  |  |  |             if (!empty($notice->repeat_of)) { | 
					
						
							|  |  |  |                 $notice->verb        = ActivityVerb::SHARE; | 
					
						
							| 
									
										
										
										
											2011-09-19 16:11:43 -04:00
										 |  |  |                 $notice->object_type = ActivityObject::ACTIVITY; | 
					
						
							| 
									
										
										
										
											2011-08-22 16:02:14 -04:00
										 |  |  |             } else { | 
					
						
							|  |  |  |                 $notice->verb        = ActivityVerb::POST; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $notice->verb = $verb; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 14:20:55 -05:00
										 |  |  |         if (empty($object_type)) { | 
					
						
							| 
									
										
										
										
											2011-03-07 14:27:23 -05:00
										 |  |  |             $notice->object_type = (empty($notice->reply_to)) ? ActivityObject::NOTE : ActivityObject::COMMENT; | 
					
						
							| 
									
										
										
										
											2011-03-07 14:20:55 -05:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             $notice->object_type = $object_type; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-26 15:49:46 -04:00
										 |  |  |         if (is_null($scope)) { // 0 is a valid value
 | 
					
						
							| 
									
										
										
										
											2011-04-04 18:13:28 -04:00
										 |  |  |             if (!empty($reply)) { | 
					
						
							|  |  |  |                 $notice->scope = $reply->scope; | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2011-07-01 21:50:04 -04:00
										 |  |  |                 $notice->scope = self::defaultScope(); | 
					
						
							| 
									
										
										
										
											2011-04-04 18:13:28 -04:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-03-26 15:49:46 -04:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             $notice->scope = $scope; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-31 12:56:53 -04:00
										 |  |  |         // For private streams
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $user = $profile->getUser(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($user)) { | 
					
						
							|  |  |  |             if ($user->private_stream && | 
					
						
							|  |  |  |                 ($notice->scope == Notice::PUBLIC_SCOPE || | 
					
						
							|  |  |  |                  $notice->scope == Notice::SITE_SCOPE)) { | 
					
						
							|  |  |  |                 $notice->scope |= Notice::FOLLOWER_SCOPE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-04 17:33:42 -04:00
										 |  |  |         // Force the scope for private groups
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach ($groups as $groupId) { | 
					
						
							|  |  |  |             $group = User_group::staticGet('id', $groupId); | 
					
						
							|  |  |  |             if (!empty($group)) { | 
					
						
							|  |  |  |                 if ($group->force_scope) { | 
					
						
							|  |  |  |                     $notice->scope |= Notice::GROUP_SCOPE; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |         if (Event::handle('StartNoticeSave', array(&$notice))) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |             // XXX: some of these functions write to the DB
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |             $id = $notice->insert(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!$id) { | 
					
						
							|  |  |  |                 common_log_db_error($notice, 'INSERT', __FILE__); | 
					
						
							| 
									
										
										
										
											2010-07-29 11:34:58 +02:00
										 |  |  |                 // TRANS: Server exception thrown when a notice cannot be saved.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |                 throw new ServerException(_('Problem saving notice.')); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |             // Update ID-dependent columns: URI, conversation
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |             $orig = clone($notice); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $changed = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (empty($uri)) { | 
					
						
							|  |  |  |                 $notice->uri = common_notice_uri($notice); | 
					
						
							|  |  |  |                 $changed = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |             // If it's not part of a conversation, it's
 | 
					
						
							|  |  |  |             // the beginning of a new conversation.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (empty($notice->conversation)) { | 
					
						
							| 
									
										
										
										
											2010-02-17 01:12:13 -08:00
										 |  |  |                 $conv = Conversation::create(); | 
					
						
							|  |  |  |                 $notice->conversation = $conv->id; | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |                 $changed = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ($changed) { | 
					
						
							|  |  |  |                 if (!$notice->update($orig)) { | 
					
						
							|  |  |  |                     common_log_db_error($notice, 'UPDATE', __FILE__); | 
					
						
							| 
									
										
										
										
											2010-07-29 11:34:58 +02:00
										 |  |  |                     // TRANS: Server exception thrown when a notice cannot be updated.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |                     throw new ServerException(_('Problem saving notice.')); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 11:54:23 -04:00
										 |  |  |         // Clear the cache for subscribed users, so they'll update at next request
 | 
					
						
							|  |  |  |         // XXX: someone clever could prepend instead of clearing the cache
 | 
					
						
							| 
									
										
										
										
											2010-02-21 23:56:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |         $notice->blowOnInsert(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-25 11:26:33 -08:00
										 |  |  |         // Save per-notice metadata...
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-21 23:56:48 -05:00
										 |  |  |         if (isset($replies)) { | 
					
						
							|  |  |  |             $notice->saveKnownReplies($replies); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $notice->saveReplies(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-25 11:26:33 -08:00
										 |  |  |         if (isset($tags)) { | 
					
						
							|  |  |  |             $notice->saveKnownTags($tags); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $notice->saveTags(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-14 11:11:02 +02:00
										 |  |  |         // Note: groups may save tags, so must be run after tags are saved
 | 
					
						
							|  |  |  |         // to avoid errors on duplicates.
 | 
					
						
							| 
									
										
										
										
											2011-04-04 17:33:42 -04:00
										 |  |  |         // Note: groups should always be set.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $notice->saveKnownGroups($groups); | 
					
						
							| 
									
										
										
										
											2010-04-14 11:11:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-02 16:30:09 -08:00
										 |  |  |         if (isset($urls)) { | 
					
						
							|  |  |  |             $notice->saveKnownUrls($urls); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $notice->saveUrls(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-02-25 11:26:33 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-16 16:17:38 -05:00
										 |  |  |         if ($distribute) { | 
					
						
							|  |  |  |             // Prepare inbox delivery, may be queued to background.
 | 
					
						
							|  |  |  |             $notice->distribute(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |         return $notice; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-17 01:12:13 -08:00
										 |  |  |     function blowOnInsert($conversation = false) | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-03-31 16:15:05 -04:00
										 |  |  |         $this->blowStream('profile:notice_ids:%d', $this->profile_id); | 
					
						
							| 
									
										
										
										
											2011-02-03 13:58:56 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if ($this->isPublic()) { | 
					
						
							| 
									
										
										
										
											2011-03-31 16:15:05 -04:00
										 |  |  |             $this->blowStream('public'); | 
					
						
							| 
									
										
										
										
											2011-02-03 13:58:56 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 12:25:04 -04:00
										 |  |  |         self::blow('notice:list-ids:conversation:%s', $this->conversation); | 
					
						
							| 
									
										
										
										
											2012-03-21 16:40:42 -04:00
										 |  |  |         self::blow('conversation:notice_count:%d', $this->conversation); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |         if (!empty($this->repeat_of)) { | 
					
						
							| 
									
										
										
										
											2011-08-22 12:39:37 -04:00
										 |  |  |             // XXX: we should probably only use one of these
 | 
					
						
							| 
									
										
										
										
											2011-03-31 16:15:05 -04:00
										 |  |  |             $this->blowStream('notice:repeats:%d', $this->repeat_of); | 
					
						
							| 
									
										
										
										
											2011-08-22 12:39:37 -04:00
										 |  |  |             self::blow('notice:list-ids:repeat_of:%d', $this->repeat_of); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |         $original = Notice::staticGet('id', $this->repeat_of); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |         if (!empty($original)) { | 
					
						
							|  |  |  |             $originalUser = User::staticGet('id', $original->profile_id); | 
					
						
							|  |  |  |             if (!empty($originalUser)) { | 
					
						
							| 
									
										
										
										
											2011-03-31 16:15:05 -04:00
										 |  |  |                 $this->blowStream('user:repeats_of_me:%d', $originalUser->id); | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |         $profile = Profile::staticGet($this->profile_id); | 
					
						
							| 
									
										
										
										
											2011-03-31 16:15:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-23 17:24:01 -07:00
										 |  |  |         if (!empty($profile)) { | 
					
						
							|  |  |  |             $profile->blowNoticeCount(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-04-13 01:26:56 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |         $ptags = $this->getProfileTags(); | 
					
						
							|  |  |  |         foreach ($ptags as $ptag) { | 
					
						
							|  |  |  |             $ptag->blowNoticeStreamCache(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-15 14:19:22 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Clear cache entries related to this notice at delete time. | 
					
						
							|  |  |  |      * Necessary to avoid breaking paging on public, profile timelines. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function blowOnDelete() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->blowOnInsert(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self::blow('profile:notice_ids:%d;last', $this->profile_id); | 
					
						
							| 
									
										
										
										
											2011-02-03 13:58:56 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if ($this->isPublic()) { | 
					
						
							|  |  |  |             self::blow('public;last'); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-17 17:06:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self::blow('fave:by_notice', $this->id); | 
					
						
							| 
									
										
										
										
											2011-03-17 17:36:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if ($this->conversation) { | 
					
						
							|  |  |  |             // In case we're the first, will need to calc a new root.
 | 
					
						
							|  |  |  |             self::blow('notice:conversation_root:%d', $this->conversation); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-04-13 01:26:56 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |         $ptags = $this->getProfileTags(); | 
					
						
							|  |  |  |         foreach ($ptags as $ptag) { | 
					
						
							|  |  |  |             $ptag->blowNoticeStreamCache(true); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-03-15 14:19:22 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-31 16:15:05 -04:00
										 |  |  |     function blowStream() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $c = self::memcache(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (empty($c)) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $args = func_get_args(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $format = array_shift($args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $keyPart = vsprintf($format, $args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $cacheKey = Cache::key($keyPart); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         $c->delete($cacheKey); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // delete the "last" stream, too, if this notice is
 | 
					
						
							|  |  |  |         // older than the top of that stream
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $lastKey = $cacheKey.';last'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $lastStr = $c->get($lastKey); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($lastStr !== false) { | 
					
						
							|  |  |  |             $window     = explode(',', $lastStr); | 
					
						
							|  |  |  |             $lastID     = $window[0]; | 
					
						
							|  |  |  |             $lastNotice = Notice::staticGet('id', $lastID); | 
					
						
							|  |  |  |             if (empty($lastNotice) // just weird
 | 
					
						
							|  |  |  |                 || strtotime($lastNotice->created) >= strtotime($this->created)) { | 
					
						
							|  |  |  |                 $c->delete($lastKey); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-16 23:10:17 -04:00
										 |  |  |     /** save all urls in the notice to the db | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |      * | 
					
						
							|  |  |  |      * follow redirects and save all available file information | 
					
						
							|  |  |  |      * (mimetype, date, size, oembed, etc.) | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return void | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function saveUrls() { | 
					
						
							| 
									
										
										
										
											2010-11-17 13:03:59 -08:00
										 |  |  |         if (common_config('attachments', 'process_links')) { | 
					
						
							|  |  |  |             common_replace_urls_callback($this->content, array($this, 'saveUrl'), $this->id); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-02 16:30:09 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Save the given URLs as related links/attachments to the db | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * follow redirects and save all available file information | 
					
						
							|  |  |  |      * (mimetype, date, size, oembed, etc.) | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return void | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function saveKnownUrls($urls) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-11-17 13:03:59 -08:00
										 |  |  |         if (common_config('attachments', 'process_links')) { | 
					
						
							|  |  |  |             // @fixme validation?
 | 
					
						
							|  |  |  |             foreach (array_unique($urls) as $url) { | 
					
						
							|  |  |  |                 File::processNew($url, $this->id); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-03-02 16:30:09 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @private callback | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-12-02 10:56:44 -08:00
										 |  |  |     function saveUrl($url, $notice_id) { | 
					
						
							| 
									
										
										
										
											2009-06-16 23:10:17 -04:00
										 |  |  |         File::processNew($url, $notice_id); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-07 09:43:50 -08:00
										 |  |  |     static function checkDupes($profile_id, $content) { | 
					
						
							|  |  |  |         $profile = Profile::staticGet($profile_id); | 
					
						
							| 
									
										
										
										
											2009-10-28 14:21:42 -04:00
										 |  |  |         if (empty($profile)) { | 
					
						
							| 
									
										
										
										
											2009-03-07 09:43:50 -08:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-24 18:04:19 -04:00
										 |  |  |         $notice = $profile->getNotices(0, CachingNoticeStream::CACHE_WINDOW); | 
					
						
							| 
									
										
										
										
											2009-10-28 14:21:42 -04:00
										 |  |  |         if (!empty($notice)) { | 
					
						
							| 
									
										
										
										
											2009-03-07 09:43:50 -08:00
										 |  |  |             $last = 0; | 
					
						
							|  |  |  |             while ($notice->fetch()) { | 
					
						
							|  |  |  |                 if (time() - strtotime($notice->created) >= common_config('site', 'dupelimit')) { | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } else if ($notice->content == $content) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-22 11:54:23 -04:00
										 |  |  |         // If we get here, oldest item in cache window is not
 | 
					
						
							|  |  |  |         // old enough for dupe limit; do direct check against DB
 | 
					
						
							| 
									
										
										
										
											2009-03-07 09:43:50 -08:00
										 |  |  |         $notice = new Notice(); | 
					
						
							|  |  |  |         $notice->profile_id = $profile_id; | 
					
						
							|  |  |  |         $notice->content = $content; | 
					
						
							| 
									
										
										
										
											2010-11-03 17:25:29 -07:00
										 |  |  |         $threshold = common_sql_date(time() - common_config('site', 'dupelimit')); | 
					
						
							|  |  |  |         $notice->whereAdd(sprintf("created > '%s'", $notice->escape($threshold))); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-07 09:43:50 -08:00
										 |  |  |         $cnt = $notice->count(); | 
					
						
							| 
									
										
										
										
											2009-03-07 23:04:30 +01:00
										 |  |  |         return ($cnt == 0); | 
					
						
							| 
									
										
										
										
											2009-03-07 09:43:50 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-10 12:47:22 -05:00
										 |  |  |     static function checkEditThrottle($profile_id) { | 
					
						
							|  |  |  |         $profile = Profile::staticGet($profile_id); | 
					
						
							| 
									
										
										
										
											2009-10-28 14:21:42 -04:00
										 |  |  |         if (empty($profile)) { | 
					
						
							| 
									
										
										
										
											2008-12-10 12:47:22 -05:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-22 11:54:23 -04:00
										 |  |  |         // Get the Nth notice
 | 
					
						
							| 
									
										
										
										
											2008-12-10 12:47:22 -05:00
										 |  |  |         $notice = $profile->getNotices(common_config('throttle', 'count') - 1, 1); | 
					
						
							|  |  |  |         if ($notice && $notice->fetch()) { | 
					
						
							| 
									
										
										
										
											2011-03-22 11:54:23 -04:00
										 |  |  |             // If the Nth notice was posted less than timespan seconds ago
 | 
					
						
							| 
									
										
										
										
											2008-12-10 12:47:22 -05:00
										 |  |  |             if (time() - strtotime($notice->created) <= common_config('throttle', 'timespan')) { | 
					
						
							| 
									
										
										
										
											2011-03-22 11:54:23 -04:00
										 |  |  |                 // Then we throttle
 | 
					
						
							| 
									
										
										
										
											2008-12-10 12:47:22 -05:00
										 |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-22 11:54:23 -04:00
										 |  |  |         // Either not N notices in the stream, OR the Nth was not posted within timespan seconds
 | 
					
						
							| 
									
										
										
										
											2008-12-10 12:47:22 -05:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-02 23:12:21 -04:00
										 |  |  | 	protected $_attachments = -1; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-06-25 11:08:32 -07:00
										 |  |  |     function attachments() { | 
					
						
							| 
									
										
										
										
											2011-04-06 23:33:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-02 23:12:21 -04:00
										 |  |  | 		if ($this->_attachments != -1)  { | 
					
						
							|  |  |  |             return $this->_attachments; | 
					
						
							| 
									
										
										
										
											2009-06-25 11:08:32 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-08-02 23:12:21 -04:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		$f2ps = Memcached_DataObject::listGet('File_to_post', 'post_id', array($this->id)); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		$ids = array(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		foreach ($f2ps[$this->id] as $f2p) { | 
					
						
							|  |  |  |             $ids[] = $f2p->file_id;     | 
					
						
							| 
									
										
										
										
											2011-04-06 23:33:35 -04:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-08-02 23:12:21 -04:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		$files = Memcached_DataObject::multiGet('File', 'id', $ids); | 
					
						
							| 
									
										
										
										
											2011-04-06 23:33:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-02 23:12:21 -04:00
										 |  |  | 		$this->_attachments = $files->fetchAll(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  |         return $this->_attachments; | 
					
						
							| 
									
										
										
										
											2009-06-25 11:08:32 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-02 23:12:21 -04:00
										 |  |  | 	function _setAttachments($attachments) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	    $this->_attachments = $attachments; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-02 11:54:02 -08:00
										 |  |  |     function publicStream($offset=0, $limit=20, $since_id=0, $max_id=0) | 
					
						
							| 
									
										
										
										
											2008-12-23 14:33:23 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-03-24 18:04:19 -04:00
										 |  |  |         $stream = new PublicNoticeStream(); | 
					
						
							| 
									
										
										
										
											2011-03-23 11:29:55 -04:00
										 |  |  |         return $stream->getNotices($offset, $limit, $since_id, $max_id); | 
					
						
							| 
									
										
										
										
											2009-04-29 12:05:31 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-02 11:54:02 -08:00
										 |  |  |     function conversationStream($id, $offset=0, $limit=20, $since_id=0, $max_id=0) | 
					
						
							| 
									
										
										
										
											2009-06-25 09:43:30 -07:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-03-24 18:04:19 -04:00
										 |  |  |         $stream = new ConversationNoticeStream($id); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 11:29:55 -04:00
										 |  |  |         return $stream->getNotices($offset, $limit, $since_id, $max_id); | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 11:36:51 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Is this notice part of an active conversation? | 
					
						
							| 
									
										
										
										
											2010-05-06 00:20:10 -07:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2010-04-09 11:36:51 -07:00
										 |  |  |      * @return boolean true if other messages exist in the same | 
					
						
							|  |  |  |      *                 conversation, false if this is the only one | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function hasConversation() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!empty($this->conversation)) { | 
					
						
							|  |  |  |             $conversation = Notice::conversationStream( | 
					
						
							|  |  |  |                 $this->conversation, | 
					
						
							|  |  |  |                 1, | 
					
						
							|  |  |  |                 1 | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2010-09-28 23:21:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 11:36:51 -07:00
										 |  |  |             if ($conversation->N > 0) { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-17 17:36:53 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Grab the earliest notice from this conversation. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Notice or null | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2011-04-11 11:19:11 -04:00
										 |  |  |     function conversationRoot($profile=-1) | 
					
						
							| 
									
										
										
										
											2011-03-17 17:36:53 -07:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-11 11:19:11 -04:00
										 |  |  |         // XXX: can this happen?
 | 
					
						
							| 
									
										
										
										
											2011-03-17 17:36:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-11 11:19:11 -04:00
										 |  |  |         if (empty($this->conversation)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-17 17:36:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-11 11:19:11 -04:00
										 |  |  |         // Get the current profile if not specified
 | 
					
						
							| 
									
										
										
										
											2011-03-17 17:36:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-11 11:19:11 -04:00
										 |  |  |         if (is_int($profile) && $profile == -1) { | 
					
						
							|  |  |  |             $profile = Profile::current(); | 
					
						
							| 
									
										
										
										
											2011-03-17 17:36:53 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-04-11 11:19:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // If this notice is out of scope, no root for you!
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!$this->inScope($profile)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // If this isn't a reply to anything, then it's its own
 | 
					
						
							|  |  |  |         // root.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (empty($this->reply_to)) { | 
					
						
							|  |  |  |             return $this; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         if (is_null($profile)) { | 
					
						
							|  |  |  |             $keypart = sprintf('notice:conversation_root:%d:null', $this->id); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $keypart = sprintf('notice:conversation_root:%d:%d', | 
					
						
							|  |  |  |                                $this->id, | 
					
						
							|  |  |  |                                $profile->id); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |         $root = self::cacheGet($keypart); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($root !== false && $root->inScope($profile)) { | 
					
						
							|  |  |  |             return $root; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $last = $this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             do { | 
					
						
							|  |  |  |                 $parent = $last->getOriginal(); | 
					
						
							|  |  |  |                 if (!empty($parent) && $parent->inScope($profile)) { | 
					
						
							|  |  |  |                     $last = $parent; | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     $root = $last; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } while (!empty($parent)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self::cacheSet($keypart, $root); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $root; | 
					
						
							| 
									
										
										
										
											2011-03-17 17:36:53 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-04-11 11:19:11 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-15 13:06:21 -08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2010-09-20 15:57:46 -07:00
										 |  |  |      * Pull up a full list of local recipients who will be getting | 
					
						
							|  |  |  |      * this notice in their inbox. Results will be cached, so don't | 
					
						
							|  |  |  |      * change the input data wily-nilly! | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $groups optional list of Group objects; | 
					
						
							|  |  |  |      *              if left empty, will be loaded from group_inbox records | 
					
						
							|  |  |  |      * @param array $recipient optional list of reply profile ids | 
					
						
							|  |  |  |      *              if left empty, will be loaded from reply records | 
					
						
							|  |  |  |      * @return array associating recipient user IDs with an inbox source constant | 
					
						
							| 
									
										
										
										
											2010-01-15 13:06:21 -08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  |     function whoGets($groups=null, $recipients=null) | 
					
						
							| 
									
										
										
										
											2008-12-23 14:33:23 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-01-13 00:16:54 -08:00
										 |  |  |         $c = self::memcache(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($c)) { | 
					
						
							| 
									
										
										
										
											2010-09-06 10:07:43 -04:00
										 |  |  |             $ni = $c->get(Cache::key('notice:who_gets:'.$this->id)); | 
					
						
							| 
									
										
										
										
											2010-01-13 00:16:54 -08:00
										 |  |  |             if ($ni !== false) { | 
					
						
							|  |  |  |                 return $ni; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  |         if (is_null($groups)) { | 
					
						
							|  |  |  |             $groups = $this->getGroups(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (is_null($recipients)) { | 
					
						
							|  |  |  |             $recipients = $this->getReplies(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-13 17:38:27 -04:00
										 |  |  |         $users = $this->getSubscribedUsers(); | 
					
						
							| 
									
										
										
										
											2011-03-06 23:28:03 +05:30
										 |  |  |         $ptags = $this->getProfileTags(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-13 17:38:27 -04:00
										 |  |  |         // FIXME: kind of ignoring 'transitional'...
 | 
					
						
							|  |  |  |         // we'll probably stop supporting inboxless mode
 | 
					
						
							|  |  |  |         // in 0.9.x
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-13 17:38:27 -04:00
										 |  |  |         $ni = array(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 12:49:17 -07:00
										 |  |  |         // Give plugins a chance to add folks in at start...
 | 
					
						
							|  |  |  |         if (Event::handle('StartNoticeWhoGets', array($this, &$ni))) { | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |             foreach ($users as $id) { | 
					
						
							| 
									
										
										
										
											2011-03-15 12:49:17 -07:00
										 |  |  |                 $ni[$id] = NOTICE_INBOX_SOURCE_SUB; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             foreach ($groups as $group) { | 
					
						
							|  |  |  |                 $users = $group->getUserMembers(); | 
					
						
							|  |  |  |                 foreach ($users as $id) { | 
					
						
							|  |  |  |                     if (!array_key_exists($id, $ni)) { | 
					
						
							|  |  |  |                         $ni[$id] = NOTICE_INBOX_SOURCE_GROUP; | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2009-06-26 00:47:27 -07:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 08:30:16 +05:30
										 |  |  |             foreach ($ptags as $ptag) { | 
					
						
							|  |  |  |                 $users = $ptag->getUserSubscribers(); | 
					
						
							|  |  |  |                 foreach ($users as $id) { | 
					
						
							|  |  |  |                     if (!array_key_exists($id, $ni)) { | 
					
						
							| 
									
										
										
										
											2012-03-23 12:55:39 -04:00
										 |  |  |                         $ni[$id] = NOTICE_INBOX_SOURCE_PROFILE_TAG; | 
					
						
							| 
									
										
										
										
											2011-03-06 23:28:03 +05:30
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 08:30:16 +05:30
										 |  |  |             foreach ($recipients as $recipient) { | 
					
						
							|  |  |  |                 if (!array_key_exists($recipient, $ni)) { | 
					
						
							|  |  |  |                     $ni[$recipient] = NOTICE_INBOX_SOURCE_REPLY; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2012-03-23 12:55:39 -04:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-09-20 15:57:46 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-23 12:55:39 -04:00
										 |  |  |             // Exclude any deleted, non-local, or blocking recipients.
 | 
					
						
							|  |  |  |             $profile = $this->getProfile(); | 
					
						
							|  |  |  |             $originalProfile = null; | 
					
						
							|  |  |  |             if ($this->repeat_of) { | 
					
						
							|  |  |  |                 // Check blocks against the original notice's poster as well.
 | 
					
						
							|  |  |  |                 $original = Notice::staticGet('id', $this->repeat_of); | 
					
						
							|  |  |  |                 if ($original) { | 
					
						
							|  |  |  |                     $originalProfile = $original->getProfile(); | 
					
						
							| 
									
										
										
										
											2011-03-15 12:49:17 -07:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2012-03-23 12:55:39 -04:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             foreach ($ni as $id => $source) { | 
					
						
							|  |  |  |                 $user = User::staticGet('id', $id); | 
					
						
							|  |  |  |                 if (empty($user) || $user->hasBlocked($profile) || | 
					
						
							|  |  |  |                     ($originalProfile && $user->hasBlocked($originalProfile))) { | 
					
						
							|  |  |  |                     unset($ni[$id]); | 
					
						
							| 
									
										
										
										
											2011-03-15 12:49:17 -07:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2009-10-28 15:33:10 -04:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-03-15 12:49:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // Give plugins a chance to filter out...
 | 
					
						
							|  |  |  |             Event::handle('EndNoticeWhoGets', array($this, &$ni)); | 
					
						
							| 
									
										
										
										
											2009-10-28 15:33:10 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 00:16:54 -08:00
										 |  |  |         if (!empty($c)) { | 
					
						
							|  |  |  |             // XXX: pack this data better
 | 
					
						
							| 
									
										
										
										
											2010-09-06 10:07:43 -04:00
										 |  |  |             $c->set(Cache::key('notice:who_gets:'.$this->id), $ni); | 
					
						
							| 
									
										
										
										
											2010-01-13 00:16:54 -08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-09 13:55:54 -08:00
										 |  |  |         return $ni; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Adds this notice to the inboxes of each local user who should receive | 
					
						
							|  |  |  |      * it, based on author subscriptions, group memberships, and @-replies. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Warning: running a second time currently will make items appear | 
					
						
							|  |  |  |      * multiple times in users' inboxes. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @fixme make more robust against errors | 
					
						
							|  |  |  |      * @fixme break up massive deliveries to smaller background tasks | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $groups optional list of Group objects; | 
					
						
							|  |  |  |      *              if left empty, will be loaded from group_inbox records | 
					
						
							|  |  |  |      * @param array $recipient optional list of reply profile ids | 
					
						
							|  |  |  |      *              if left empty, will be loaded from reply records | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function addToInboxes($groups=null, $recipients=null) | 
					
						
							| 
									
										
										
										
											2010-01-09 13:55:54 -08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  |         $ni = $this->whoGets($groups, $recipients); | 
					
						
							| 
									
										
										
										
											2010-01-09 13:55:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-18 07:11:20 -05:00
										 |  |  |         $ids = array_keys($ni); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // We remove the author (if they're a local user),
 | 
					
						
							|  |  |  |         // since we'll have already done this in distribute()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $i = array_search($this->profile_id, $ids); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($i !== false) { | 
					
						
							|  |  |  |             unset($ids[$i]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Bulk insert
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Inbox::bulkInsert($this->id, $ids); | 
					
						
							| 
									
										
										
										
											2009-10-13 17:38:27 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 14:19:07 -05:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |     function getSubscribedUsers() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $user = new User(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         if(common_config('db','quote_identifiers')) | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |           $user_table = '"user"'; | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         else $user_table = 'user'; | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |         $qry = | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |           'SELECT id ' . | 
					
						
							|  |  |  |           'FROM '. $user_table .' JOIN subscription '. | 
					
						
							|  |  |  |           'ON '. $user_table .'.id = subscription.subscriber ' . | 
					
						
							|  |  |  |           'WHERE subscription.subscribed = %d '; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |         $user->query(sprintf($qry, $this->profile_id)); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |         $ids = array(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |         while ($user->fetch()) { | 
					
						
							|  |  |  |             $ids[] = $user->id; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |         $user->free(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |         return $ids; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-06 23:28:03 +05:30
										 |  |  |     function getProfileTags() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-13 01:26:56 +05:30
										 |  |  |         $profile = $this->getProfile(); | 
					
						
							|  |  |  |         $list    = $profile->getOtherTags($profile); | 
					
						
							|  |  |  |         $ptags   = array(); | 
					
						
							| 
									
										
										
										
											2011-03-06 23:28:03 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-13 01:26:56 +05:30
										 |  |  |         while($list->fetch()) { | 
					
						
							|  |  |  |             $ptags[] = clone($list); | 
					
						
							| 
									
										
										
										
											2011-03-06 23:28:03 +05:30
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $ptags; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-15 13:06:21 -08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |      * Record this notice to the given group inboxes for delivery. | 
					
						
							|  |  |  |      * Overrides the regular parsing of !group markup. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $group_ids | 
					
						
							|  |  |  |      * @fixme might prefer URIs as identifiers, as for replies? | 
					
						
							|  |  |  |      *        best with generalizations on user_group to support | 
					
						
							|  |  |  |      *        remote groups better. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function saveKnownGroups($group_ids) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!is_array($group_ids)) { | 
					
						
							| 
									
										
										
										
											2010-07-29 11:34:58 +02:00
										 |  |  |             // TRANS: Server exception thrown when no array is provided to the method saveKnownGroups().
 | 
					
						
							| 
									
										
										
										
											2010-11-04 18:33:39 +01:00
										 |  |  |             throw new ServerException(_('Bad type provided to saveKnownGroups.')); | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $groups = array(); | 
					
						
							| 
									
										
										
										
											2010-08-10 13:36:38 -07:00
										 |  |  |         foreach (array_unique($group_ids) as $id) { | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |             $group = User_group::staticGet('id', $id); | 
					
						
							|  |  |  |             if ($group) { | 
					
						
							|  |  |  |                 common_log(LOG_ERR, "Local delivery to group id $id, $group->nickname"); | 
					
						
							|  |  |  |                 $result = $this->addToGroupInbox($group); | 
					
						
							|  |  |  |                 if (!$result) { | 
					
						
							|  |  |  |                     common_log_db_error($gi, 'INSERT', __FILE__); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-20 16:19:07 -04:00
										 |  |  |                 if (common_config('group', 'addtag')) { | 
					
						
							|  |  |  |                     // we automatically add a tag for every group name, too
 | 
					
						
							| 
									
										
										
										
											2011-04-04 17:33:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-20 16:19:07 -04:00
										 |  |  |                     $tag = Notice_tag::pkeyGet(array('tag' => common_canonical_tag($group->nickname), | 
					
						
							|  |  |  |                                                      'notice_id' => $this->id)); | 
					
						
							| 
									
										
										
										
											2011-04-04 17:33:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-20 16:19:07 -04:00
										 |  |  |                     if (is_null($tag)) { | 
					
						
							|  |  |  |                         $this->saveTag($group->nickname); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2011-04-04 17:33:42 -04:00
										 |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |                 $groups[] = clone($group); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 common_log(LOG_ERR, "Local delivery to group id $id skipped, doesn't exist"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $groups; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Parse !group delivery and record targets into group_inbox. | 
					
						
							| 
									
										
										
										
											2010-01-15 13:06:21 -08:00
										 |  |  |      * @return array of Group objects | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-01-21 21:53:02 -05:00
										 |  |  |     function saveGroups() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-01-13 00:47:12 -08:00
										 |  |  |         // Don't save groups for repeats
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($this->repeat_of)) { | 
					
						
							|  |  |  |             return array(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-21 21:53:02 -05:00
										 |  |  |         $profile = $this->getProfile(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-04 17:33:42 -04:00
										 |  |  |         $groups = self::groupsFromText($this->content, $profile); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-21 21:53:02 -05:00
										 |  |  |         /* Add them to the database */ | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-04 17:33:42 -04:00
										 |  |  |         foreach ($groups as $group) { | 
					
						
							| 
									
										
										
										
											2009-01-21 21:53:02 -05:00
										 |  |  |             /* XXX: remote groups. */ | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-14 23:43:47 -07:00
										 |  |  |             if (empty($group)) { | 
					
						
							| 
									
										
										
										
											2009-01-21 22:40:42 -05:00
										 |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-21 21:53:02 -05:00
										 |  |  |             if ($profile->isMember($group)) { | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |                 $result = $this->addToGroupInbox($group); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-21 21:53:02 -05:00
										 |  |  |                 if (!$result) { | 
					
						
							|  |  |  |                     common_log_db_error($gi, 'INSERT', __FILE__); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-26 00:47:27 -07:00
										 |  |  |                 $groups[] = clone($group); | 
					
						
							| 
									
										
										
										
											2009-01-21 21:53:02 -05:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-26 00:47:27 -07:00
										 |  |  |         return $groups; | 
					
						
							| 
									
										
										
										
											2009-01-21 21:53:02 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |     function addToGroupInbox($group) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $gi = Group_inbox::pkeyGet(array('group_id' => $group->id, | 
					
						
							|  |  |  |                                          'notice_id' => $this->id)); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |         if (empty($gi)) { | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |             $gi = new Group_inbox(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |             $gi->group_id  = $group->id; | 
					
						
							|  |  |  |             $gi->notice_id = $this->id; | 
					
						
							|  |  |  |             $gi->created   = $this->created; | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |             $result = $gi->insert(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-09 18:32:52 -08:00
										 |  |  |             if (!$result) { | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |                 common_log_db_error($gi, 'INSERT', __FILE__); | 
					
						
							| 
									
										
										
										
											2010-07-29 11:34:58 +02:00
										 |  |  |                 // TRANS: Server exception thrown when an update for a group inbox fails.
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |                 throw new ServerException(_('Problem saving group inbox.')); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self::blow('user_group:notice_ids:%d', $gi->group_id); | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 23:00:46 -07:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Save reply records indicating that this notice needs to be | 
					
						
							|  |  |  |      * delivered to the local users with the given URIs. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Since this is expected to be used when saving foreign-sourced | 
					
						
							|  |  |  |      * messages, we won't deliver to any remote targets as that's the | 
					
						
							|  |  |  |      * source service's responsibility. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2010-04-20 12:06:54 +02:00
										 |  |  |      * Mail notifications etc will be handled later. | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @param array of unique identifier URIs for recipients | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-21 23:56:48 -05:00
										 |  |  |     function saveKnownReplies($uris) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-04-09 10:46:18 -07:00
										 |  |  |         if (empty($uris)) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-09-01 16:15:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 10:46:18 -07:00
										 |  |  |         $sender = Profile::staticGet($this->profile_id); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 13:36:38 -07:00
										 |  |  |         foreach (array_unique($uris) as $uri) { | 
					
						
							| 
									
										
										
										
											2010-02-21 23:56:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 16:15:51 -04:00
										 |  |  |             $profile = Profile::fromURI($uri); | 
					
						
							| 
									
										
										
										
											2010-02-21 23:56:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 16:15:51 -04:00
										 |  |  |             if (empty($profile)) { | 
					
						
							|  |  |  |                 common_log(LOG_WARNING, "Unable to determine profile for URI '$uri'"); | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-02-21 23:56:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 16:15:51 -04:00
										 |  |  |             if ($profile->hasBlocked($sender)) { | 
					
						
							|  |  |  |                 common_log(LOG_INFO, "Not saving reply to profile {$profile->id} ($uri) from sender {$sender->id} because of a block."); | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-02-21 23:56:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-20 12:05:24 -04:00
										 |  |  |             $this->saveReply($profile->id); | 
					
						
							|  |  |  |             self::blow('reply:stream:%d', $profile->id); | 
					
						
							| 
									
										
										
										
											2010-02-21 23:56:48 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-11 13:53:09 -08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |      * Pull @-replies from this message's content in StatusNet markup format | 
					
						
							|  |  |  |      * and save reply records indicating that this message needs to be | 
					
						
							|  |  |  |      * delivered to those users. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2010-04-20 12:06:54 +02:00
										 |  |  |      * Mail notifications to local profiles will be sent later. | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2009-12-11 13:53:09 -08:00
										 |  |  |      * @return array of integer profile IDs | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-02-21 16:20:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-22 01:53:27 -05:00
										 |  |  |     function saveReplies() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-01-13 01:13:06 -08:00
										 |  |  |         // Don't save reply data for repeats
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($this->repeat_of)) { | 
					
						
							|  |  |  |             return array(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-22 01:53:27 -05:00
										 |  |  |         $sender = Profile::staticGet($this->profile_id); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-20 12:05:24 -04:00
										 |  |  |         $replied = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // If it's a reply, save for the replied-to author
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($this->reply_to)) { | 
					
						
							|  |  |  |             $original = $this->getOriginal(); | 
					
						
							|  |  |  |             if (!empty($original)) { // that'd be weird
 | 
					
						
							|  |  |  |                 $author = $original->getProfile(); | 
					
						
							|  |  |  |                 if (!empty($author)) { | 
					
						
							|  |  |  |                     $this->saveReply($author->id); | 
					
						
							|  |  |  |                     $replied[$author->id] = 1; | 
					
						
							|  |  |  |                     self::blow('reply:stream:%d', $author->id); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-27 16:30:38 -05:00
										 |  |  |         // @todo ideally this parser information would only
 | 
					
						
							|  |  |  |         // be calculated once.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $mentions = common_find_mentions($this->content, $this); | 
					
						
							| 
									
										
										
										
											2010-02-21 16:20:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-22 01:53:27 -05:00
										 |  |  |         // store replied only for first @ (what user/notice what the reply directed,
 | 
					
						
							|  |  |  |         // we assume first @ is it)
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-21 16:20:30 -05:00
										 |  |  |         foreach ($mentions as $mention) { | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-21 16:20:30 -05:00
										 |  |  |             foreach ($mention['mentioned'] as $mentioned) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // skip if they're already covered
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (!empty($replied[$mentioned->id])) { | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // Don't save replies from blocked profile to local user
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 $mentioned_user = User::staticGet('id', $mentioned->id); | 
					
						
							|  |  |  |                 if (!empty($mentioned_user) && $mentioned_user->hasBlocked($sender)) { | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-20 12:05:24 -04:00
										 |  |  |                 $this->saveReply($mentioned->id); | 
					
						
							|  |  |  |                 $replied[$mentioned->id] = 1; | 
					
						
							|  |  |  |                 self::blow('reply:stream:%d', $mentioned->id); | 
					
						
							| 
									
										
										
										
											2009-01-22 01:53:27 -05:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-28 15:33:10 -04:00
										 |  |  |         $recipientIds = array_keys($replied); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $recipientIds; | 
					
						
							| 
									
										
										
										
											2009-01-22 01:53:27 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-20 12:05:24 -04:00
										 |  |  |     function saveReply($profileId) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $reply = new Reply(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $reply->notice_id  = $this->id; | 
					
						
							|  |  |  |         $reply->profile_id = $profileId; | 
					
						
							|  |  |  |         $reply->modified   = $this->created; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $reply->insert(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $reply; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-03 00:59:09 -04:00
										 |  |  |     protected $_replies = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-20 12:06:54 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Pull the complete list of @-reply targets for this notice. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array of integer profile ids | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  |     function getReplies() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-08-03 00:59:09 -04:00
										 |  |  |         if ($this->_replies != -1) { | 
					
						
							|  |  |  |             return $this->_replies; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-03 00:59:09 -04:00
										 |  |  |         $replyMap = Memcached_DataObject::listGet('Reply', 'notice_id', array($this->id)); | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-03 00:59:09 -04:00
										 |  |  |         $ids = array(); | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-03 00:59:09 -04:00
										 |  |  |         foreach ($replyMap[$this->id] as $reply) { | 
					
						
							|  |  |  |             $ids[] = $reply->profile_id; | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-03 00:59:09 -04:00
										 |  |  |         $this->_replies = $ids; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  |         return $ids; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-03 00:59:09 -04:00
										 |  |  |     function _setReplies($replies) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->_replies = $replies; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 15:17:03 -04:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Pull the complete list of @-reply targets for this notice. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array of Profiles | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function getReplyProfiles() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-08-02 11:09:30 -04:00
										 |  |  |         $ids = $this->getReplies(); | 
					
						
							| 
									
										
										
										
											2011-04-16 15:17:03 -04:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2011-08-02 11:09:30 -04:00
										 |  |  |         $profiles = Profile::multiGet('id', $ids); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         return $profiles->fetchAll(); | 
					
						
							| 
									
										
										
										
											2011-04-16 15:17:03 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-20 12:06:54 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Send e-mail notifications to local @-reply targets. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Replies must already have been saved; this is expected to be run | 
					
						
							|  |  |  |      * from the distrib queue handler. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function sendReplyNotifications() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Don't send reply notifications for repeats
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($this->repeat_of)) { | 
					
						
							|  |  |  |             return array(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $recipientIds = $this->getReplies(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach ($recipientIds as $recipientId) { | 
					
						
							|  |  |  |             $user = User::staticGet('id', $recipientId); | 
					
						
							|  |  |  |             if (!empty($user)) { | 
					
						
							|  |  |  |                 mail_notify_attn($user, $this); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-15 13:06:21 -08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2010-02-23 00:44:45 +00:00
										 |  |  |      * Pull list of groups this notice needs to be delivered to, | 
					
						
							|  |  |  |      * as previously recorded by saveGroups() or saveKnownGroups(). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array of Group objects | 
					
						
							| 
									
										
										
										
											2010-01-15 13:06:21 -08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2011-08-02 18:13:56 -04:00
										 |  |  |      | 
					
						
							|  |  |  |     protected $_groups = -1; | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  |     function getGroups() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-01-15 13:06:21 -08:00
										 |  |  |         // Don't save groups for repeats
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($this->repeat_of)) { | 
					
						
							|  |  |  |             return array(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-08-02 18:13:56 -04:00
										 |  |  |          | 
					
						
							|  |  |  |         if ($this->_groups != -1) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             return $this->_groups; | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-08-02 18:13:56 -04:00
										 |  |  |          | 
					
						
							|  |  |  |         $gis = Memcached_DataObject::listGet('Group_inbox', 'notice_id', array($this->id)); | 
					
						
							| 
									
										
										
										
											2011-08-03 00:04:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $ids = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-02 18:13:56 -04:00
										 |  |  | 		foreach ($gis[$this->id] as $gi) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		    $ids[] = $gi->group_id; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2011-08-01 16:59:43 -04:00
										 |  |  | 		$groups = User_group::multiGet('id', $ids); | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2011-08-02 18:13:56 -04:00
										 |  |  | 		$this->_groups = $groups->fetchAll(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		return $this->_groups; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     function _setGroups($groups) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->_groups = $groups; | 
					
						
							| 
									
										
										
										
											2010-01-13 12:37:01 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Convert a notice into an activity for export. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param User $cur Current user | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |      * @return Activity activity object representing this Notice. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-17 19:02:57 -08:00
										 |  |  |     function asActivity($cur) | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-12-06 17:28:22 -05:00
										 |  |  |         $act = self::cacheGet(Cache::codeKey('notice:as-activity:'.$this->id)); | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 16:38:02 -05:00
										 |  |  |         if (!empty($act)) { | 
					
						
							|  |  |  |             return $act; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  |         $act = new Activity(); | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |         if (Event::handle('StartNoticeAsActivity', array($this, &$act))) { | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-18 17:06:03 -04:00
										 |  |  |             $act->id      = $this->uri; | 
					
						
							|  |  |  |             $act->time    = strtotime($this->created); | 
					
						
							|  |  |  |             $act->link    = $this->bestUrl(); | 
					
						
							|  |  |  |             $act->content = common_xml_safe_str($this->rendered); | 
					
						
							|  |  |  |             $act->title   = common_xml_safe_str($this->content); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $profile = $this->getProfile(); | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-17 19:02:57 -08:00
										 |  |  |             $act->actor            = ActivityObject::fromProfile($profile); | 
					
						
							|  |  |  |             $act->actor->extra[]   = $profile->profileInfo($cur); | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 16:02:14 -04:00
										 |  |  |             $act->verb = $this->verb; | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 16:02:14 -04:00
										 |  |  |             if ($this->repeat_of) { | 
					
						
							| 
									
										
										
										
											2011-07-18 17:06:03 -04:00
										 |  |  |                 $repeated = Notice::staticGet('id', $this->repeat_of); | 
					
						
							| 
									
										
										
										
											2012-04-23 19:15:12 -04:00
										 |  |  |                 if (!empty($repeated)) { | 
					
						
							|  |  |  |                     $act->objects[] = $repeated->asActivity($cur); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2011-07-18 17:06:03 -04:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2011-08-22 16:02:14 -04:00
										 |  |  |                 $act->objects[] = ActivityObject::fromNotice($this); | 
					
						
							| 
									
										
										
										
											2011-07-18 17:06:03 -04:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // XXX: should this be handled by default processing for object entry?
 | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             // Categories
 | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $tags = $this->getTags(); | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             foreach ($tags as $tag) { | 
					
						
							|  |  |  |                 $cat       = new AtomCategory(); | 
					
						
							|  |  |  |                 $cat->term = $tag; | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |                 $act->categories[] = $cat; | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             // Enclosures
 | 
					
						
							|  |  |  |             // XXX: use Atom Media and/or File activity objects instead
 | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $attachments = $this->attachments(); | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             foreach ($attachments as $attachment) { | 
					
						
							|  |  |  |                 $enclosure = $attachment->getEnclosure(); | 
					
						
							|  |  |  |                 if ($enclosure) { | 
					
						
							|  |  |  |                     $act->enclosures[] = $enclosure; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $ctx = new ActivityContext(); | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             if (!empty($this->reply_to)) { | 
					
						
							|  |  |  |                 $reply = Notice::staticGet('id', $this->reply_to); | 
					
						
							|  |  |  |                 if (!empty($reply)) { | 
					
						
							|  |  |  |                     $ctx->replyToID  = $reply->uri; | 
					
						
							|  |  |  |                     $ctx->replyToUrl = $reply->bestUrl(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $ctx->location = $this->getLocation(); | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $conv = null; | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             if (!empty($this->conversation)) { | 
					
						
							|  |  |  |                 $conv = Conversation::staticGet('id', $this->conversation); | 
					
						
							|  |  |  |                 if (!empty($conv)) { | 
					
						
							|  |  |  |                     $ctx->conversation = $conv->uri; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $reply_ids = $this->getReplies(); | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             foreach ($reply_ids as $id) { | 
					
						
							| 
									
										
										
										
											2011-04-07 10:52:28 -04:00
										 |  |  |                 $rprofile = Profile::staticGet('id', $id); | 
					
						
							|  |  |  |                 if (!empty($rprofile)) { | 
					
						
							|  |  |  |                     $ctx->attention[] = $rprofile->getUri(); | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $groups = $this->getGroups(); | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             foreach ($groups as $group) { | 
					
						
							| 
									
										
										
										
											2011-02-17 10:51:00 -05:00
										 |  |  |                 $ctx->attention[] = $group->getUri(); | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             // XXX: deprecated; use ActivityVerb::SHARE instead
 | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $repeat = null; | 
					
						
							| 
									
										
										
										
											2010-08-10 17:03:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             if (!empty($this->repeat_of)) { | 
					
						
							|  |  |  |                 $repeat = Notice::staticGet('id', $this->repeat_of); | 
					
						
							| 
									
										
										
										
											2011-08-27 10:01:35 -04:00
										 |  |  |                 if (!empty($repeat)) { | 
					
						
							|  |  |  |                     $ctx->forwardID  = $repeat->uri; | 
					
						
							|  |  |  |                     $ctx->forwardUrl = $repeat->bestUrl(); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             $act->context = $ctx; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |             // Source
 | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |             $atom_feed = $profile->getAtomFeed(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |             if (!empty($atom_feed)) { | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 $act->source = new ActivitySource(); | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 // XXX: we should store the actual feed ID
 | 
					
						
							| 
									
										
										
										
											2010-08-03 15:50:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 $act->source->id = $atom_feed; | 
					
						
							| 
									
										
										
										
											2010-08-03 15:50:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 // XXX: we should store the actual feed title
 | 
					
						
							| 
									
										
										
										
											2010-08-03 15:50:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 $act->source->title = $profile->getBestName(); | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 $act->source->links['alternate'] = $profile->profileurl; | 
					
						
							|  |  |  |                 $act->source->links['self']      = $atom_feed; | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 $act->source->icon = $profile->avatarUrl(AVATAR_PROFILE_SIZE); | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 $notice = $profile->getCurrentNotice(); | 
					
						
							| 
									
										
										
										
											2010-08-03 15:50:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 if (!empty($notice)) { | 
					
						
							|  |  |  |                     $act->source->updated = self::utcDate($notice->created); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-08-03 15:50:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 $user = User::staticGet('id', $profile->id); | 
					
						
							| 
									
										
										
										
											2010-08-03 15:50:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                 if (!empty($user)) { | 
					
						
							|  |  |  |                     $act->source->links['license'] = common_config('license', 'url'); | 
					
						
							| 
									
										
										
										
											2010-08-03 15:50:21 -07:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2009-03-22 16:58:38 -04:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             if ($this->isLocal()) { | 
					
						
							|  |  |  |                 $act->selfLink = common_local_url('ApiStatusesShow', array('id' => $this->id, | 
					
						
							|  |  |  |                                                                            'format' => 'atom')); | 
					
						
							|  |  |  |                 $act->editLink = $act->selfLink; | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |             Event::handle('EndNoticeAsActivity', array($this, &$act)); | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:28:22 -05:00
										 |  |  |         self::cacheSet(Cache::codeKey('notice:as-activity:'.$this->id), $act); | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |         return $act; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-10 16:15:05 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |     // This has gotten way too long. Needs to be sliced up into functional bits
 | 
					
						
							|  |  |  |     // or ideally exported to a utility class.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |     function asAtomEntry($namespace=false, | 
					
						
							|  |  |  |                          $source=false, | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  |                          $author=true, | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |                          $cur=null) | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-02-17 19:02:57 -08:00
										 |  |  |         $act = $this->asActivity($cur); | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |         $act->extra[] = $this->noticeInfo($cur); | 
					
						
							|  |  |  |         return $act->asString($namespace, $author, $source); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Extra notice info for atom entries | 
					
						
							| 
									
										
										
										
											2011-01-29 00:33:13 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2010-12-08 07:25:55 -05:00
										 |  |  |      * Clients use some extra notice info in the atom stream. | 
					
						
							|  |  |  |      * This gives it to them. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param User $cur Current user | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array representation of <statusnet:notice_info> element | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function noticeInfo($cur) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // local notice ID (useful to clients for ordering)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $noticeInfoAttr = array('local_id' => $this->id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // notice source
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $ns = $this->getSource(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($ns)) { | 
					
						
							|  |  |  |             $noticeInfoAttr['source'] =  $ns->code; | 
					
						
							|  |  |  |             if (!empty($ns->url)) { | 
					
						
							|  |  |  |                 $noticeInfoAttr['source_link'] = $ns->url; | 
					
						
							|  |  |  |                 if (!empty($ns->name)) { | 
					
						
							|  |  |  |                     $noticeInfoAttr['source'] =  '<a href="' | 
					
						
							|  |  |  |                         . htmlspecialchars($ns->url) | 
					
						
							|  |  |  |                         . '" rel="nofollow">' | 
					
						
							|  |  |  |                         . htmlspecialchars($ns->name) | 
					
						
							|  |  |  |                         . '</a>'; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // favorite and repeated
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($cur)) { | 
					
						
							|  |  |  |             $noticeInfoAttr['favorite'] = ($cur->hasFave($this)) ? "true" : "false"; | 
					
						
							|  |  |  |             $cp = $cur->getProfile(); | 
					
						
							|  |  |  |             $noticeInfoAttr['repeated'] = ($cp->hasRepeated($this->id)) ? "true" : "false"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($this->repeat_of)) { | 
					
						
							|  |  |  |             $noticeInfoAttr['repeat_of'] = $this->repeat_of; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return array('statusnet:notice_info', $noticeInfoAttr, null); | 
					
						
							| 
									
										
										
										
											2009-03-22 16:58:38 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-20 15:56:36 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Returns an XML string fragment with a reference to a notice as an | 
					
						
							|  |  |  |      * Activity Streams noun object with the given element type. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Assumes that 'activity' namespace has been previously defined. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $element one of 'subject', 'object', 'target' | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-12-05 16:15:05 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-20 15:56:36 -08:00
										 |  |  |     function asActivityNoun($element) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-02-22 17:10:50 -08:00
										 |  |  |         $noun = ActivityObject::fromNotice($this); | 
					
						
							|  |  |  |         return $noun->asString('activity:' . $element); | 
					
						
							| 
									
										
										
										
											2010-02-20 15:56:36 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-22 16:58:38 -04:00
										 |  |  |     function bestUrl() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!empty($this->url)) { | 
					
						
							|  |  |  |             return $this->url; | 
					
						
							|  |  |  |         } else if (!empty($this->uri) && preg_match('/^https?:/', $this->uri)) { | 
					
						
							|  |  |  |             return $this->uri; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             return common_local_url('shownotice', | 
					
						
							|  |  |  |                                     array('notice' => $this->id)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |      * Determine which notice, if any, a new notice is in reply to. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * For conversation tracking, we try to see where this notice fits | 
					
						
							|  |  |  |      * in the tree. Rough algorithm is: | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * if (reply_to is set and valid) { | 
					
						
							|  |  |  |      *     return reply_to; | 
					
						
							|  |  |  |      * } else if ((source not API or Web) and (content starts with "T NAME" or "@name ")) { | 
					
						
							|  |  |  |      *     return ID of last notice by initial @name in content; | 
					
						
							|  |  |  |      * } | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Note that all @nickname instances will still be used to save "reply" records, | 
					
						
							|  |  |  |      * so the notice shows up in the mentioned users' "replies" tab. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param integer $reply_to   ID passed in by Web or API | 
					
						
							|  |  |  |      * @param integer $profile_id ID of author | 
					
						
							|  |  |  |      * @param string  $source     Source tag, like 'web' or 'gwibber' | 
					
						
							|  |  |  |      * @param string  $content    Final notice content | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return integer ID of replied-to notice, or null for not a reply. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static function getReplyTo($reply_to, $profile_id, $source, $content) | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         static $lb = array('xmpp', 'mail', 'sms', 'omb'); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         // If $reply_to is specified, we check that it exists, and then
 | 
					
						
							|  |  |  |         // return it if it does
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         if (!empty($reply_to)) { | 
					
						
							|  |  |  |             $reply_notice = Notice::staticGet('id', $reply_to); | 
					
						
							|  |  |  |             if (!empty($reply_notice)) { | 
					
						
							| 
									
										
										
										
											2011-04-04 18:13:28 -04:00
										 |  |  |                 return $reply_notice; | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 23:28:51 +01:00
										 |  |  |         // If it's not a "low bandwidth" source (one where you can't set
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         // a reply_to argument), we return. This is mostly web and API
 | 
					
						
							|  |  |  |         // clients.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         if (!in_array($source, $lb)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         // Is there an initial @ or T?
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         if (preg_match('/^T ([A-Z0-9]{1,64}) /', $content, $match) || | 
					
						
							|  |  |  |             preg_match('/^@([a-z0-9]{1,64})\s+/', $content, $match)) { | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  |             $nickname = common_canonical_nickname($match[1]); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         // Figure out who that is.
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         $sender = Profile::staticGet('id', $profile_id); | 
					
						
							| 
									
										
										
										
											2010-02-08 14:06:36 -08:00
										 |  |  |         if (empty($sender)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         $recipient = common_relative_profile($sender, $nickname, common_sql_now()); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         if (empty($recipient)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         // Get their last notice
 | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         $last = $recipient->getCurrentNotice(); | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         if (!empty($last)) { | 
					
						
							| 
									
										
										
										
											2011-04-04 18:13:28 -04:00
										 |  |  |             return $last; | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-04-04 18:13:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return null; | 
					
						
							| 
									
										
										
										
											2009-07-29 11:45:32 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 08:05:13 -04:00
										 |  |  |     static function maxContent() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $contentlimit = common_config('notice', 'contentlimit'); | 
					
						
							|  |  |  |         // null => use global limit (distinct from 0!)
 | 
					
						
							|  |  |  |         if (is_null($contentlimit)) { | 
					
						
							|  |  |  |             $contentlimit = common_config('site', 'textlimit'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return $contentlimit; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-03 20:34:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 08:05:13 -04:00
										 |  |  |     static function contentTooLong($content) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $contentlimit = self::maxContent(); | 
					
						
							|  |  |  |         return ($contentlimit > 0 && !empty($content) && (mb_strlen($content) > $contentlimit)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-29 14:43:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function getLocation() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $location = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($this->location_id) && !empty($this->location_ns)) { | 
					
						
							|  |  |  |             $location = Location::fromId($this->location_id, $this->location_ns); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (is_null($location)) { // no ID, or Location::fromId() failed
 | 
					
						
							|  |  |  |             if (!empty($this->lat) && !empty($this->lon)) { | 
					
						
							|  |  |  |                 $location = Location::fromLatLon($this->lat, $this->lon); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $location; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-12-11 11:51:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-29 16:20:12 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Convenience function for posting a repeat of an existing message. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param int $repeater_id: profile ID of user doing the repeat | 
					
						
							|  |  |  |      * @param string $source: posting source key, eg 'web', 'api', etc | 
					
						
							|  |  |  |      * @return Notice | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @throws Exception on failure or permission problems | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-12-11 11:51:09 -05:00
										 |  |  |     function repeat($repeater_id, $source) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $author = Profile::staticGet('id', $this->profile_id); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 01:08:51 +02:00
										 |  |  |         // TRANS: Message used to repeat a notice. RT is the abbreviation of 'retweet'.
 | 
					
						
							|  |  |  |         // TRANS: %1$s is the repeated user's name, %2$s is the repeated notice.
 | 
					
						
							| 
									
										
										
										
											2009-12-11 11:51:09 -05:00
										 |  |  |         $content = sprintf(_('RT @%1$s %2$s'), | 
					
						
							|  |  |  |                            $author->nickname, | 
					
						
							|  |  |  |                            $this->content); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-05 15:04:08 -08:00
										 |  |  |         $maxlen = common_config('site', 'textlimit'); | 
					
						
							| 
									
										
										
										
											2010-01-05 16:15:12 -08:00
										 |  |  |         if ($maxlen > 0 && mb_strlen($content) > $maxlen) { | 
					
						
							| 
									
										
										
										
											2010-01-05 15:04:08 -08:00
										 |  |  |             // Web interface and current Twitter API clients will
 | 
					
						
							|  |  |  |             // pull the original notice's text, but some older
 | 
					
						
							|  |  |  |             // clients and RSS/Atom feeds will see this trimmed text.
 | 
					
						
							|  |  |  |             //
 | 
					
						
							|  |  |  |             // Unfortunately this is likely to lose tags or URLs
 | 
					
						
							|  |  |  |             // at the end of long notices.
 | 
					
						
							|  |  |  |             $content = mb_substr($content, 0, $maxlen - 4) . ' ...'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-29 12:12:08 -04:00
										 |  |  |         // Scope is same as this one's
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return self::saveNew($repeater_id, | 
					
						
							|  |  |  |                              $content, | 
					
						
							|  |  |  |                              $source, | 
					
						
							|  |  |  |                              array('repeat_of' => $this->id, | 
					
						
							|  |  |  |                                    'scope' => $this->scope)); | 
					
						
							| 
									
										
										
										
											2009-12-11 11:51:09 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-12-12 14:46:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // These are supposed to be in chron order!
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function repeatStream($limit=100) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-09-06 09:56:45 -04:00
										 |  |  |         $cache = Cache::instance(); | 
					
						
							| 
									
										
										
										
											2009-12-12 14:46:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (empty($cache)) { | 
					
						
							|  |  |  |             $ids = $this->_repeatStreamDirect($limit); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2010-09-06 10:07:43 -04:00
										 |  |  |             $idstr = $cache->get(Cache::key('notice:repeats:'.$this->id)); | 
					
						
							| 
									
										
										
										
											2010-01-04 10:03:57 -10:00
										 |  |  |             if ($idstr !== false) { | 
					
						
							| 
									
										
										
										
											2011-07-14 12:53:18 -04:00
										 |  |  |             	if (empty($idstr)) { | 
					
						
							|  |  |  |             		$ids = array(); | 
					
						
							|  |  |  |             	} else { | 
					
						
							|  |  |  |                 	$ids = explode(',', $idstr); | 
					
						
							|  |  |  |             	} | 
					
						
							| 
									
										
										
										
											2009-12-12 14:46:24 -05:00
										 |  |  |             } else { | 
					
						
							|  |  |  |                 $ids = $this->_repeatStreamDirect(100); | 
					
						
							| 
									
										
										
										
											2010-09-06 10:07:43 -04:00
										 |  |  |                 $cache->set(Cache::key('notice:repeats:'.$this->id), implode(',', $ids)); | 
					
						
							| 
									
										
										
										
											2009-12-12 14:46:24 -05:00
										 |  |  |             } | 
					
						
							|  |  |  |             if ($limit < 100) { | 
					
						
							|  |  |  |                 // We do a max of 100, so slice down to limit
 | 
					
						
							|  |  |  |                 $ids = array_slice($ids, 0, $limit); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 11:59:01 -04:00
										 |  |  |         return NoticeStream::getStreamByIds($ids); | 
					
						
							| 
									
										
										
										
											2009-12-12 14:46:24 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function _repeatStreamDirect($limit) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $notice = new Notice(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $notice->selectAdd(); // clears it
 | 
					
						
							|  |  |  |         $notice->selectAdd('id'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $notice->repeat_of = $this->id; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-17 15:13:09 -08:00
										 |  |  |         $notice->orderBy('created, id'); // NB: asc!
 | 
					
						
							| 
									
										
										
										
											2009-12-12 14:46:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-17 15:04:10 -08:00
										 |  |  |         if (!is_null($limit)) { | 
					
						
							|  |  |  |             $notice->limit(0, $limit); | 
					
						
							| 
									
										
										
										
											2009-12-12 14:46:24 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-14 12:53:18 -04:00
										 |  |  |         return $notice->fetchAll('id'); | 
					
						
							| 
									
										
										
										
											2009-12-12 14:46:24 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-12-28 15:13:15 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function locationOptions($lat, $lon, $location_id, $location_ns, $profile = null) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $options = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($location_id) && !empty($location_ns)) { | 
					
						
							|  |  |  |             $options['location_id'] = $location_id; | 
					
						
							|  |  |  |             $options['location_ns'] = $location_ns; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $location = Location::fromId($location_id, $location_ns); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!empty($location)) { | 
					
						
							|  |  |  |                 $options['lat'] = $location->lat; | 
					
						
							|  |  |  |                 $options['lon'] = $location->lon; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } else if (!empty($lat) && !empty($lon)) { | 
					
						
							|  |  |  |             $options['lat'] = $lat; | 
					
						
							|  |  |  |             $options['lon'] = $lon; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $location = Location::fromLatLon($lat, $lon); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!empty($location)) { | 
					
						
							|  |  |  |                 $options['location_id'] = $location->location_id; | 
					
						
							|  |  |  |                 $options['location_ns'] = $location->location_ns; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else if (!empty($profile)) { | 
					
						
							|  |  |  |             if (isset($profile->lat) && isset($profile->lon)) { | 
					
						
							|  |  |  |                 $options['lat'] = $profile->lat; | 
					
						
							|  |  |  |                 $options['lon'] = $profile->lon; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (isset($profile->location_id) && isset($profile->location_ns)) { | 
					
						
							|  |  |  |                 $options['location_id'] = $profile->location_id; | 
					
						
							|  |  |  |                 $options['location_ns'] = $profile->location_ns; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $options; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function clearReplies() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $replyNotice = new Notice(); | 
					
						
							|  |  |  |         $replyNotice->reply_to = $this->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         //Null any notices that are replies to this notice
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($replyNotice->find()) { | 
					
						
							|  |  |  |             while ($replyNotice->fetch()) { | 
					
						
							|  |  |  |                 $orig = clone($replyNotice); | 
					
						
							|  |  |  |                 $replyNotice->reply_to = null; | 
					
						
							|  |  |  |                 $replyNotice->update($orig); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Reply records
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $reply = new Reply(); | 
					
						
							|  |  |  |         $reply->notice_id = $this->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($reply->find()) { | 
					
						
							|  |  |  |             while($reply->fetch()) { | 
					
						
							|  |  |  |                 self::blow('reply:stream:%d', $reply->profile_id); | 
					
						
							|  |  |  |                 $reply->delete(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $reply->free(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-28 13:44:18 -08:00
										 |  |  |     function clearFiles() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $f2p = new File_to_post(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $f2p->post_id = $this->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($f2p->find()) { | 
					
						
							|  |  |  |             while ($f2p->fetch()) { | 
					
						
							|  |  |  |                 $f2p->delete(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // FIXME: decide whether to delete File objects
 | 
					
						
							|  |  |  |         // ...and related (actual) files
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |     function clearRepeats() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $repeatNotice = new Notice(); | 
					
						
							|  |  |  |         $repeatNotice->repeat_of = $this->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         //Null any notices that are repeats of this notice
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($repeatNotice->find()) { | 
					
						
							|  |  |  |             while ($repeatNotice->fetch()) { | 
					
						
							|  |  |  |                 $orig = clone($repeatNotice); | 
					
						
							|  |  |  |                 $repeatNotice->repeat_of = null; | 
					
						
							|  |  |  |                 $repeatNotice->update($orig); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function clearFaves() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $fave = new Fave(); | 
					
						
							|  |  |  |         $fave->notice_id = $this->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($fave->find()) { | 
					
						
							|  |  |  |             while ($fave->fetch()) { | 
					
						
							|  |  |  |                 self::blow('fave:ids_by_user_own:%d', $fave->user_id); | 
					
						
							|  |  |  |                 self::blow('fave:ids_by_user_own:%d;last', $fave->user_id); | 
					
						
							|  |  |  |                 self::blow('fave:ids_by_user:%d', $fave->user_id); | 
					
						
							|  |  |  |                 self::blow('fave:ids_by_user:%d;last', $fave->user_id); | 
					
						
							|  |  |  |                 $fave->delete(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $fave->free(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function clearTags() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $tag = new Notice_tag(); | 
					
						
							|  |  |  |         $tag->notice_id = $this->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($tag->find()) { | 
					
						
							|  |  |  |             while ($tag->fetch()) { | 
					
						
							| 
									
										
										
										
											2010-09-06 10:03:51 -04:00
										 |  |  |                 self::blow('profile:notice_ids_tagged:%d:%s', $this->profile_id, Cache::keyize($tag->tag)); | 
					
						
							|  |  |  |                 self::blow('profile:notice_ids_tagged:%d:%s;last', $this->profile_id, Cache::keyize($tag->tag)); | 
					
						
							|  |  |  |                 self::blow('notice_tag:notice_ids:%s', Cache::keyize($tag->tag)); | 
					
						
							|  |  |  |                 self::blow('notice_tag:notice_ids:%s;last', Cache::keyize($tag->tag)); | 
					
						
							| 
									
										
										
										
											2010-01-25 18:08:21 -05:00
										 |  |  |                 $tag->delete(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $tag->free(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function clearGroupInboxes() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $gi = new Group_inbox(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $gi->notice_id = $this->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($gi->find()) { | 
					
						
							|  |  |  |             while ($gi->fetch()) { | 
					
						
							|  |  |  |                 self::blow('user_group:notice_ids:%d', $gi->group_id); | 
					
						
							|  |  |  |                 $gi->delete(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $gi->free(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-28 18:40:38 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function distribute() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-02-18 07:11:20 -05:00
										 |  |  |         // We always insert for the author so they don't
 | 
					
						
							|  |  |  |         // have to wait
 | 
					
						
							| 
									
										
										
										
											2010-09-30 16:25:15 -07:00
										 |  |  |         Event::handle('StartNoticeDistribute', array($this)); | 
					
						
							| 
									
										
										
										
											2010-02-18 07:11:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $user = User::staticGet('id', $this->profile_id); | 
					
						
							|  |  |  |         if (!empty($user)) { | 
					
						
							|  |  |  |             Inbox::insertNotice($user->id, $this->id); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 18:40:38 -05:00
										 |  |  |         if (common_config('queue', 'inboxes')) { | 
					
						
							|  |  |  |             // If there's a failure, we want to _force_
 | 
					
						
							|  |  |  |             // distribution at this point.
 | 
					
						
							|  |  |  |             try { | 
					
						
							|  |  |  |                 $qm = QueueManager::get(); | 
					
						
							|  |  |  |                 $qm->enqueue($this, 'distrib'); | 
					
						
							|  |  |  |             } catch (Exception $e) { | 
					
						
							|  |  |  |                 // If the exception isn't transient, this
 | 
					
						
							|  |  |  |                 // may throw more exceptions as DQH does
 | 
					
						
							|  |  |  |                 // its own enqueueing. So, we ignore them!
 | 
					
						
							|  |  |  |                 try { | 
					
						
							|  |  |  |                     $handler = new DistribQueueHandler(); | 
					
						
							|  |  |  |                     $handler->handle($this); | 
					
						
							|  |  |  |                 } catch (Exception $e) { | 
					
						
							|  |  |  |                     common_log(LOG_ERR, "emergency redistribution resulted in " . $e->getMessage()); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 // Re-throw so somebody smarter can handle it.
 | 
					
						
							|  |  |  |                 throw $e; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $handler = new DistribQueueHandler(); | 
					
						
							|  |  |  |             $handler->handle($this); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-02-03 12:31:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function insert() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $result = parent::insert(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($result) { | 
					
						
							|  |  |  |             // Profile::hasRepeated() abuses pkeyGet(), so we
 | 
					
						
							|  |  |  |             // have to clear manually
 | 
					
						
							|  |  |  |             if (!empty($this->repeat_of)) { | 
					
						
							|  |  |  |                 $c = self::memcache(); | 
					
						
							|  |  |  |                 if (!empty($c)) { | 
					
						
							|  |  |  |                     $ck = self::multicacheKey('Notice', | 
					
						
							|  |  |  |                                               array('profile_id' => $this->profile_id, | 
					
						
							|  |  |  |                                                     'repeat_of' => $this->repeat_of)); | 
					
						
							|  |  |  |                     $c->delete($ck); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $result; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-05-06 00:20:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the source of the notice | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Notice_source $ns A notice source object. 'code' is the only attribute | 
					
						
							|  |  |  |      *                           guaranteed to be populated. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function getSource() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $ns = new Notice_source(); | 
					
						
							|  |  |  |         if (!empty($this->source)) { | 
					
						
							|  |  |  |             switch ($this->source) { | 
					
						
							|  |  |  |             case 'web': | 
					
						
							|  |  |  |             case 'xmpp': | 
					
						
							|  |  |  |             case 'mail': | 
					
						
							|  |  |  |             case 'omb': | 
					
						
							|  |  |  |             case 'system': | 
					
						
							|  |  |  |             case 'api': | 
					
						
							|  |  |  |                 $ns->code = $this->source; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 $ns = Notice_source::staticGet($this->source); | 
					
						
							|  |  |  |                 if (!$ns) { | 
					
						
							|  |  |  |                     $ns = new Notice_source(); | 
					
						
							|  |  |  |                     $ns->code = $this->source; | 
					
						
							|  |  |  |                     $app = Oauth_application::staticGet('name', $this->source); | 
					
						
							|  |  |  |                     if ($app) { | 
					
						
							|  |  |  |                         $ns->name = $app->name; | 
					
						
							|  |  |  |                         $ns->url  = $app->source_url; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return $ns; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-03 16:58:45 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Determine whether the notice was locally created | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return boolean locality | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function isLocal() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return ($this->is_local == Notice::LOCAL_PUBLIC || | 
					
						
							|  |  |  |                 $this->is_local == Notice::LOCAL_NONPUBLIC); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 12:51:29 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the list of hash tags saved with this notice. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array of strings | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  |     public function getTags() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $tags = array(); | 
					
						
							| 
									
										
										
										
											2011-04-06 23:25:24 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $keypart = sprintf('notice:tags:%d', $this->id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $tagstr = self::cacheGet($keypart); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($tagstr !== false) { | 
					
						
							|  |  |  |             $tags = explode(',', $tagstr); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $tag = new Notice_tag(); | 
					
						
							|  |  |  |             $tag->notice_id = $this->id; | 
					
						
							|  |  |  |             if ($tag->find()) { | 
					
						
							|  |  |  |                 while ($tag->fetch()) { | 
					
						
							|  |  |  |                     $tags[] = $tag->tag; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-04-06 23:25:24 -04:00
										 |  |  |             self::cacheSet($keypart, implode(',', $tags)); | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-04-06 23:25:24 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-02 17:16:04 -07:00
										 |  |  |         return $tags; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-08-03 15:55:40 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     static private function utcDate($dt) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $dateStr = date('d F Y H:i:s', strtotime($dt)); | 
					
						
							|  |  |  |         $d = new DateTime($dateStr, new DateTimeZone('UTC')); | 
					
						
							|  |  |  |         return $d->format(DATE_W3C); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-12-17 12:09:02 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Look up the creation timestamp for a given notice ID, even | 
					
						
							|  |  |  |      * if it's been deleted. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param int $id | 
					
						
							|  |  |  |      * @return mixed string recorded creation timestamp, or false if can't be found | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getAsTimestamp($id) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-12-17 12:38:38 -08:00
										 |  |  |         if (!$id) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-17 12:09:02 -08:00
										 |  |  |         $notice = Notice::staticGet('id', $id); | 
					
						
							|  |  |  |         if ($notice) { | 
					
						
							|  |  |  |             return $notice->created; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-12-17 12:38:38 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $deleted = Deleted_notice::staticGet('id', $id); | 
					
						
							|  |  |  |         if ($deleted) { | 
					
						
							|  |  |  |             return $deleted->created; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2010-12-17 12:09:02 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-12-17 13:03:18 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Build an SQL 'where' fragment for timestamp-based sorting from a since_id | 
					
						
							|  |  |  |      * parameter, matching notices posted after the given one (exclusive). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * If the referenced notice can't be found, will return false. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param int $id | 
					
						
							|  |  |  |      * @param string $idField | 
					
						
							|  |  |  |      * @param string $createdField | 
					
						
							|  |  |  |      * @return mixed string or false if no match | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function whereSinceId($id, $idField='id', $createdField='created') | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $since = Notice::getAsTimestamp($id); | 
					
						
							|  |  |  |         if ($since) { | 
					
						
							|  |  |  |             return sprintf("($createdField = '%s' and $idField > %d) or ($createdField > '%s')", $since, $id, $since); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-17 13:20:38 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Build an SQL 'where' fragment for timestamp-based sorting from a since_id | 
					
						
							|  |  |  |      * parameter, matching notices posted after the given one (exclusive), and | 
					
						
							|  |  |  |      * if necessary add it to the data object's query. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param DB_DataObject $obj | 
					
						
							|  |  |  |      * @param int $id | 
					
						
							|  |  |  |      * @param string $idField | 
					
						
							|  |  |  |      * @param string $createdField | 
					
						
							|  |  |  |      * @return mixed string or false if no match | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function addWhereSinceId(DB_DataObject $obj, $id, $idField='id', $createdField='created') | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-12-27 22:35:57 -08:00
										 |  |  |         $since = self::whereSinceId($id, $idField, $createdField); | 
					
						
							| 
									
										
										
										
											2010-12-17 13:20:38 -08:00
										 |  |  |         if ($since) { | 
					
						
							|  |  |  |             $obj->whereAdd($since); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-17 13:03:18 -08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Build an SQL 'where' fragment for timestamp-based sorting from a max_id | 
					
						
							|  |  |  |      * parameter, matching notices posted before the given one (inclusive). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * If the referenced notice can't be found, will return false. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param int $id | 
					
						
							|  |  |  |      * @param string $idField | 
					
						
							|  |  |  |      * @param string $createdField | 
					
						
							|  |  |  |      * @return mixed string or false if no match | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function whereMaxId($id, $idField='id', $createdField='created') | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $max = Notice::getAsTimestamp($id); | 
					
						
							|  |  |  |         if ($max) { | 
					
						
							|  |  |  |             return sprintf("($createdField < '%s') or ($createdField = '%s' and $idField <= %d)", $max, $max, $id); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-12-17 13:20:38 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Build an SQL 'where' fragment for timestamp-based sorting from a max_id | 
					
						
							|  |  |  |      * parameter, matching notices posted before the given one (inclusive), and | 
					
						
							|  |  |  |      * if necessary add it to the data object's query. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param DB_DataObject $obj | 
					
						
							|  |  |  |      * @param int $id | 
					
						
							|  |  |  |      * @param string $idField | 
					
						
							|  |  |  |      * @param string $createdField | 
					
						
							|  |  |  |      * @return mixed string or false if no match | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function addWhereMaxId(DB_DataObject $obj, $id, $idField='id', $createdField='created') | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-12-27 22:35:57 -08:00
										 |  |  |         $max = self::whereMaxId($id, $idField, $createdField); | 
					
						
							| 
									
										
										
										
											2010-12-17 13:20:38 -08:00
										 |  |  |         if ($max) { | 
					
						
							|  |  |  |             $obj->whereAdd($max); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-02-03 13:58:56 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function isPublic() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (common_config('public', 'localonly')) { | 
					
						
							|  |  |  |             return ($this->is_local == Notice::LOCAL_PUBLIC); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             return (($this->is_local != Notice::LOCAL_NONPUBLIC) && | 
					
						
							|  |  |  |                     ($this->is_local != Notice::GATEWAY)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Check that the given profile is allowed to read, respond to, or otherwise | 
					
						
							|  |  |  |      * act on this notice. | 
					
						
							| 
									
										
										
										
											2011-04-10 19:59:55 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |      * The $scope member is a bitmask of scopes, representing a logical AND of the | 
					
						
							|  |  |  |      * scope requirement. So, 0x03 (Notice::ADDRESSEE_SCOPE | Notice::SITE_SCOPE) means | 
					
						
							|  |  |  |      * "only visible to people who are mentioned in the notice AND are users on this site." | 
					
						
							|  |  |  |      * Users on the site who are not mentioned in the notice will not be able to see the | 
					
						
							|  |  |  |      * notice. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2011-03-29 17:01:53 -07:00
										 |  |  |      * @param Profile $profile The profile to check; pass null to check for public/unauthenticated users. | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return boolean whether the profile is in the notice's scope | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function inScope($profile) | 
					
						
							| 
									
										
										
										
											2011-04-07 16:24:56 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-10 19:19:10 -04:00
										 |  |  |         if (is_null($profile)) { | 
					
						
							|  |  |  |             $keypart = sprintf('notice:in-scope-for:%d:null', $this->id); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $keypart = sprintf('notice:in-scope-for:%d:%d', $this->id, $profile->id); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-04-07 16:24:56 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $result = self::cacheGet($keypart); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($result === false) { | 
					
						
							| 
									
										
										
										
											2012-03-20 16:38:56 -04:00
										 |  |  |             $bResult = false; | 
					
						
							| 
									
										
										
										
											2012-03-20 21:13:12 -04:00
										 |  |  |             if (Event::handle('StartNoticeInScope', array($this, $profile, &$bResult))) { | 
					
						
							| 
									
										
										
										
											2012-03-20 16:38:56 -04:00
										 |  |  |                 $bResult = $this->_inScope($profile); | 
					
						
							| 
									
										
										
										
											2012-03-20 21:13:12 -04:00
										 |  |  |                 Event::handle('EndNoticeInScope', array($this, $profile, &$bResult)); | 
					
						
							| 
									
										
										
										
											2012-03-20 16:38:56 -04:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-04-07 16:24:56 -04:00
										 |  |  |             $result = ($bResult) ? 1 : 0; | 
					
						
							|  |  |  |             self::cacheSet($keypart, $result, 0, 300); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return ($result == 1) ? true : false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function _inScope($profile) | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-09-08 13:05:17 -04:00
										 |  |  |         if (!is_null($this->scope)) { | 
					
						
							| 
									
										
										
										
											2011-09-08 12:38:11 -04:00
										 |  |  |             $scope = $this->scope; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $scope = self::defaultScope(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-26 16:23:20 -04:00
										 |  |  |         // If there's no scope, anyone (even anon) is in scope.
 | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |         if ($scope == 0) { // Not private
 | 
					
						
							| 
									
										
										
										
											2011-03-26 16:23:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 13:02:33 -04:00
										 |  |  |             return !$this->isHiddenSpam($profile); | 
					
						
							| 
									
										
										
										
											2011-03-26 16:23:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |         } else { // Private, somehow
 | 
					
						
							| 
									
										
										
										
											2011-03-26 16:23:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |             // If there's scope, anon cannot be in scope
 | 
					
						
							| 
									
										
										
										
											2011-03-26 16:23:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |             if (empty($profile)) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |             // Author is always in scope
 | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |             if ($this->profile_id == $profile->id) { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Only for users on this site
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ($scope & Notice::SITE_SCOPE) { | 
					
						
							|  |  |  |                 $user = $profile->getUser(); | 
					
						
							|  |  |  |                 if (empty($user)) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |             // Only for users mentioned in the notice
 | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |             if ($scope & Notice::ADDRESSEE_SCOPE) { | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |                 $repl = Reply::pkeyGet(array('notice_id' => $this->id, | 
					
						
							|  |  |  |                                              'profile_id' => $profile->id)); | 
					
						
							| 
									
										
										
										
											2011-08-02 11:09:30 -04:00
										 |  |  | 										  | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |                 if (empty($repl)) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |             // Only for members of the given group
 | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |             if ($scope & Notice::GROUP_SCOPE) { | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |                 // XXX: just query for the single membership
 | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |                 $groups = $this->getGroups(); | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |                 $foundOne = false; | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |                 foreach ($groups as $group) { | 
					
						
							|  |  |  |                     if ($profile->isMember($group)) { | 
					
						
							|  |  |  |                         $foundOne = true; | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (!$foundOne) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |             // Only for followers of the author
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $author = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ($scope & Notice::FOLLOWER_SCOPE) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 23:37:12 -04:00
										 |  |  |                 try { | 
					
						
							|  |  |  |                     $author = $this->getProfile(); | 
					
						
							|  |  |  |                 } catch (Exception $e) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |          | 
					
						
							|  |  |  |                 if (!Subscription::exists($profile, $author)) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 13:02:33 -04:00
										 |  |  |             return !$this->isHiddenSpam($profile); | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 13:02:33 -04:00
										 |  |  |     function isHiddenSpam($profile) { | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |          | 
					
						
							|  |  |  |         // Hide posts by silenced users from everyone but moderators.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (common_config('notice', 'hidespam')) { | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 23:37:12 -04:00
										 |  |  |             try { | 
					
						
							|  |  |  |                 $author = $this->getProfile(); | 
					
						
							|  |  |  |             } catch(Exception $e) { | 
					
						
							|  |  |  |                 // If we can't get an author, keep it hidden.
 | 
					
						
							|  |  |  |                 // XXX: technically not spam, but, whatever.
 | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if ($author->hasRole(Profile_role::SILENCED)) { | 
					
						
							| 
									
										
										
										
											2012-04-23 21:25:53 -04:00
										 |  |  |                 if (empty($profile) || (($profile->id !== $author->id) && (!$profile->hasRight(Right::REVIEWSPAM)))) { | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 10:17:11 -04:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2011-03-22 11:36:48 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-04-04 17:33:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     static function groupsFromText($text, $profile) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $groups = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* extract all !group */ | 
					
						
							|  |  |  |         $count = preg_match_all('/(?:^|\s)!(' . Nickname::DISPLAY_FMT . ')/', | 
					
						
							|  |  |  |                                 strtolower($text), | 
					
						
							|  |  |  |                                 $match); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!$count) { | 
					
						
							|  |  |  |             return $groups; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach (array_unique($match[1]) as $nickname) { | 
					
						
							|  |  |  |             $group = User_group::getForNickname($nickname, $profile); | 
					
						
							|  |  |  |             if (!empty($group) && $profile->isMember($group)) { | 
					
						
							|  |  |  |                 $groups[] = $group->id; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $groups; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-04-11 11:19:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     protected $_original = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function getOriginal() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (is_int($this->_original) && $this->_original == -1) { | 
					
						
							|  |  |  |             if (empty($this->reply_to)) { | 
					
						
							|  |  |  |                 $this->_original = null; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 $this->_original = Notice::staticGet('id', $this->reply_to); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return $this->_original; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-04-18 18:23:06 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Magic function called at serialize() time. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * We use this to drop a couple process-specific references | 
					
						
							|  |  |  |      * from DB_DataObject which can cause trouble in future | 
					
						
							|  |  |  |      * processes. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array of variable names to include in serialization. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function __sleep() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $vars = parent::__sleep(); | 
					
						
							| 
									
										
										
										
											2011-08-22 12:39:37 -04:00
										 |  |  |         $skip = array('_original', '_profile', '_groups', '_attachments', '_faves', '_replies', '_repeats'); | 
					
						
							| 
									
										
										
										
											2011-04-18 18:23:06 -04:00
										 |  |  |         return array_diff($vars, $skip); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-07-01 21:50:04 -04:00
										 |  |  |      | 
					
						
							|  |  |  |     static function defaultScope() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     	$scope = common_config('notice', 'defaultscope'); | 
					
						
							|  |  |  |     	if (is_null($scope)) { | 
					
						
							|  |  |  |     		if (common_config('site', 'private')) { | 
					
						
							|  |  |  |     			$scope = 1; | 
					
						
							|  |  |  |     		} else { | 
					
						
							|  |  |  |     			$scope = 0; | 
					
						
							|  |  |  |     		} | 
					
						
							|  |  |  |     	} | 
					
						
							|  |  |  |     	return $scope; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-04-18 18:23:06 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-01 14:51:59 -04:00
										 |  |  | 	static function fillProfiles($notices) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-08-02 11:54:27 -04:00
										 |  |  | 		$map = self::getProfiles($notices); | 
					
						
							| 
									
										
										
										
											2011-08-01 14:51:59 -04:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		foreach ($notices as $notice) { | 
					
						
							| 
									
										
										
										
											2011-08-02 11:54:27 -04:00
										 |  |  | 			if (array_key_exists($notice->profile_id, $map)) { | 
					
						
							|  |  |  | 				$notice->_setProfile($map[$notice->profile_id]);     | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2011-08-01 14:51:59 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2011-08-02 11:54:27 -04:00
										 |  |  | 		return array_values($map); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	static function getProfiles(&$notices) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		$ids = array(); | 
					
						
							|  |  |  | 		foreach ($notices as $notice) { | 
					
						
							|  |  |  | 			$ids[] = $notice->profile_id; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-08-01 14:51:59 -04:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2011-08-02 11:54:27 -04:00
										 |  |  | 		$ids = array_unique($ids); | 
					
						
							| 
									
										
										
										
											2011-08-01 14:51:59 -04:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2011-08-02 11:54:27 -04:00
										 |  |  | 		return Memcached_DataObject::pivotGet('Profile', 'id', $ids);  | 
					
						
							| 
									
										
										
										
											2011-08-01 14:51:59 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-08-02 18:13:56 -04:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	static function fillGroups(&$notices) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-08-02 23:12:21 -04:00
										 |  |  |         $ids = self::_idsOf($notices); | 
					
						
							| 
									
										
										
										
											2011-08-02 18:13:56 -04:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		$gis = Memcached_DataObject::listGet('Group_inbox', 'notice_id', $ids); | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2011-08-03 00:04:18 -04:00
										 |  |  |         $gids = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-02 18:13:56 -04:00
										 |  |  | 		foreach ($gis as $id => $gi) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		    foreach ($gi as $g) | 
					
						
							|  |  |  | 		    { | 
					
						
							|  |  |  | 		        $gids[] = $g->group_id; | 
					
						
							|  |  |  | 		    } | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		$gids = array_unique($gids); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		$group = Memcached_DataObject::pivotGet('User_group', 'id', $gids); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		foreach ($notices as $notice) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			$grps = array(); | 
					
						
							|  |  |  | 			$gi = $gis[$notice->id]; | 
					
						
							|  |  |  | 			foreach ($gi as $g) { | 
					
						
							|  |  |  | 			    $grps[] = $group[$g->group_id]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		    $notice->_setGroups($grps); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-08-02 23:12:21 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     static function _idsOf(&$notices) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 		$ids = array(); | 
					
						
							|  |  |  | 		foreach ($notices as $notice) { | 
					
						
							|  |  |  | 			$ids[] = $notice->id; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		$ids = array_unique($ids); | 
					
						
							|  |  |  |         return $ids; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static function fillAttachments(&$notices) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $ids = self::_idsOf($notices); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$f2pMap = Memcached_DataObject::listGet('File_to_post', 'post_id', $ids); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		$fileIds = array(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		foreach ($f2pMap as $noticeId => $f2ps) { | 
					
						
							|  |  |  |             foreach ($f2ps as $f2p) { | 
					
						
							|  |  |  |                 $fileIds[] = $f2p->file_id;     | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $fileIds = array_unique($fileIds); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$fileMap = Memcached_DataObject::pivotGet('File', 'id', $fileIds); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		foreach ($notices as $notice) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			$files = array(); | 
					
						
							|  |  |  | 			$f2ps = $f2pMap[$notice->id]; | 
					
						
							|  |  |  | 			foreach ($f2ps as $f2p) { | 
					
						
							|  |  |  | 			    $files[] = $fileMap[$f2p->file_id]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		    $notice->_setAttachments($files); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-03 00:04:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-08 12:01:39 -04:00
										 |  |  |     protected $_faves; | 
					
						
							| 
									
										
										
										
											2011-08-03 00:04:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * All faves of this notice | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array Array of Fave objects | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function getFaves() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-08-08 12:01:39 -04:00
										 |  |  |         if (isset($this->_faves) && is_array($this->_faves)) { | 
					
						
							| 
									
										
										
										
											2011-08-03 00:04:18 -04:00
										 |  |  |             return $this->_faves; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-08-08 12:01:39 -04:00
										 |  |  |         $faveMap = Memcached_DataObject::listGet('Fave', 'notice_id', array($this->id)); | 
					
						
							|  |  |  |         $this->_faves = $faveMap[$this->id]; | 
					
						
							| 
									
										
										
										
											2011-08-03 00:04:18 -04:00
										 |  |  |         return $this->_faves; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-23 09:39:05 -07:00
										 |  |  |     function _setFaves($faves) | 
					
						
							| 
									
										
										
										
											2011-08-03 00:04:18 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         $this->_faves = $faves; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static function fillFaves(&$notices) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $ids = self::_idsOf($notices); | 
					
						
							|  |  |  |         $faveMap = Memcached_DataObject::listGet('Fave', 'notice_id', $ids); | 
					
						
							| 
									
										
										
										
											2011-08-08 12:01:39 -04:00
										 |  |  |         $cnt = 0; | 
					
						
							|  |  |  |         $faved = array(); | 
					
						
							|  |  |  |         foreach ($faveMap as $id => $faves) { | 
					
						
							|  |  |  |             $cnt += count($faves); | 
					
						
							|  |  |  |             if (count($faves) > 0) { | 
					
						
							|  |  |  |                 $faved[] = $id; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-08-03 00:04:18 -04:00
										 |  |  |         foreach ($notices as $notice) { | 
					
						
							| 
									
										
										
										
											2011-08-23 00:40:54 -04:00
										 |  |  |         	$faves = $faveMap[$notice->id]; | 
					
						
							| 
									
										
										
										
											2011-08-23 09:52:48 -07:00
										 |  |  |             $notice->_setFaves($faves); | 
					
						
							| 
									
										
										
										
											2011-08-03 00:04:18 -04:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-03 00:59:09 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     static function fillReplies(&$notices) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $ids = self::_idsOf($notices); | 
					
						
							|  |  |  |         $replyMap = Memcached_DataObject::listGet('Reply', 'notice_id', $ids); | 
					
						
							|  |  |  |         foreach ($notices as $notice) { | 
					
						
							|  |  |  |             $replies = $replyMap[$notice->id]; | 
					
						
							|  |  |  |             $ids = array(); | 
					
						
							|  |  |  |             foreach ($replies as $reply) { | 
					
						
							|  |  |  |                 $ids[] = $reply->profile_id; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $notice->_setReplies($ids); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-22 12:39:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     protected $_repeats; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function getRepeats() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (isset($this->_repeats) && is_array($this->_repeats)) { | 
					
						
							|  |  |  |             return $this->_repeats; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $repeatMap = Memcached_DataObject::listGet('Notice', 'repeat_of', array($this->id)); | 
					
						
							|  |  |  |         $this->_repeats = $repeatMap[$this->id]; | 
					
						
							|  |  |  |         return $this->_repeats; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-23 09:39:05 -07:00
										 |  |  |     function _setRepeats($repeats) | 
					
						
							| 
									
										
										
										
											2011-08-22 12:39:37 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         $this->_repeats = $repeats; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static function fillRepeats(&$notices) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $ids = self::_idsOf($notices); | 
					
						
							|  |  |  |         $repeatMap = Memcached_DataObject::listGet('Notice', 'repeat_of', $ids); | 
					
						
							|  |  |  |         foreach ($notices as $notice) { | 
					
						
							| 
									
										
										
										
											2011-08-23 00:40:54 -04:00
										 |  |  |         	$repeats = $repeatMap[$notice->id]; | 
					
						
							| 
									
										
										
										
											2011-08-23 09:52:48 -07:00
										 |  |  |             $notice->_setRepeats($repeats); | 
					
						
							| 
									
										
										
										
											2011-08-22 12:39:37 -04:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-05-07 13:15:42 -04:00
										 |  |  | } |