| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * StatusNet - the distributed open-source microblogging tool | 
					
						
							|  |  |  |  * Copyright (C) 2010, StatusNet, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * A plugin to allow anonymous users to favorite notices | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-10-01 11:12:53 -07:00
										 |  |  |  * If you want to keep certain users from having anonymous faving for their | 
					
						
							|  |  |  |  * notices initialize the plugin with the restricted array, e.g.: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * addPlugin( | 
					
						
							|  |  |  |  *     'AnonymousFave', | 
					
						
							|  |  |  |  *     array('restricted' => array('spock', 'kirk', 'bones')) | 
					
						
							|  |  |  |  * ); | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |  * PHP version 5 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @category  Plugin | 
					
						
							|  |  |  |  * @package   StatusNet | 
					
						
							|  |  |  |  * @author    Zach Copley <zach@status.net> | 
					
						
							|  |  |  |  * @copyright 2010 StatusNet, Inc. | 
					
						
							|  |  |  |  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 | 
					
						
							|  |  |  |  * @link      http://status.net/ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (!defined('STATUSNET')) { | 
					
						
							|  |  |  |     // This check helps protect against security problems;
 | 
					
						
							|  |  |  |     // your code file can't be executed directly from the web.
 | 
					
						
							|  |  |  |     exit(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | define('ANONYMOUS_FAVE_PLUGIN_VERSION', '0.1'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Anonymous Fave plugin to allow anonymous (not logged in) users | 
					
						
							|  |  |  |  * to favorite notices | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @category  Plugin | 
					
						
							|  |  |  |  * @package   StatusNet | 
					
						
							|  |  |  |  * @author    Zach Copley <zach@status.net> | 
					
						
							|  |  |  |  * @copyright 2010 StatusNet, Inc. | 
					
						
							|  |  |  |  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 | 
					
						
							|  |  |  |  * @link      http://status.net/ | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-10-01 11:12:53 -07:00
										 |  |  | class AnonymousFavePlugin extends Plugin | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Array of users who should not have anon faving. The default is
 | 
					
						
							|  |  |  |     // that anonymous faving is allowed for all users.
 | 
					
						
							|  |  |  |     public $restricted = array(); | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function onArgsInitialize() { | 
					
						
							|  |  |  |         // We always want a session because we're tracking anon users
 | 
					
						
							|  |  |  |         common_ensure_session(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 19:07:45 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Hook for ensuring our tables are created | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Ensures the fave_tally table is there and has the right columns | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return boolean hook return | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onCheckSchema() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $schema = Schema::get(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // For storing total number of times a notice has been faved
 | 
					
						
							| 
									
										
										
										
											2013-08-19 17:08:18 +02:00
										 |  |  |         $schema->ensureTable('fave_tally', Fave_tally::schemaDef()); | 
					
						
							| 
									
										
										
										
											2010-09-28 19:07:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |     function onEndShowHTML($action) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!common_logged_in()) { | 
					
						
							|  |  |  |             // Set a place to return to when submitting forms
 | 
					
						
							|  |  |  |             common_set_returnto($action->selfUrl()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onEndShowScripts($action) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Setup ajax calls for favoriting. Usually this is only done when
 | 
					
						
							|  |  |  |         // a user is logged in.
 | 
					
						
							|  |  |  |         $action->inlineScript('SN.U.NoticeFavor();'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 11:12:53 -07:00
										 |  |  |     function onStartInitializeRouter($m) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |         $m->connect('main/anonfavor', array('action' => 'AnonFavor')); | 
					
						
							|  |  |  |         $m->connect('main/anondisfavor', array('action' => 'AnonDisFavor')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 11:12:53 -07:00
										 |  |  |     function onStartShowNoticeOptions($item) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |         if (!common_logged_in()) { | 
					
						
							|  |  |  |             $item->out->elementStart('div', 'notice-options'); | 
					
						
							|  |  |  |             $item->showFaveForm(); | 
					
						
							|  |  |  |             $item->out->elementEnd('div'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 11:12:53 -07:00
										 |  |  |     function onStartShowFaveForm($item) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!common_logged_in() && $this->hasAnonFaving($item)) { | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  |             $profile = AnonymousFavePlugin::getAnonProfile(); | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |             if (!empty($profile)) { | 
					
						
							|  |  |  |                 if ($profile->hasFave($item->notice)) { | 
					
						
							|  |  |  |                     $disfavor = new AnonDisFavorForm($item->out, $item->notice); | 
					
						
							|  |  |  |                     $disfavor->show(); | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     $favor = new AnonFavorForm($item->out, $item->notice); | 
					
						
							|  |  |  |                     $favor->show(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 14:08:31 -07:00
										 |  |  |     function onEndFavorNoticeForm($form, $notice) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->showTally($form->out, $notice); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onEndDisFavorNoticeForm($form, $notice) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->showTally($form->out, $notice); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function showTally($out, $notice) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $tally = Fave_tally::ensureTally($notice->id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($tally)) { | 
					
						
							|  |  |  |             $out->elementStart( | 
					
						
							|  |  |  |                 'div', | 
					
						
							|  |  |  |                 array( | 
					
						
							|  |  |  |                     'id' => 'notice-' . $notice->id . '-tally', | 
					
						
							|  |  |  |                     'class' => 'notice-tally' | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2010-10-01 11:31:44 -07:00
										 |  |  |             $out->elementStart('span', array('class' => 'fave-tally-title')); | 
					
						
							| 
									
										
										
										
											2010-10-04 11:42:16 -07:00
										 |  |  |             // TRANS: Label for tally for number of times a notice was favored.
 | 
					
						
							| 
									
										
										
										
											2010-10-01 11:31:44 -07:00
										 |  |  |             $out->raw(sprintf(_m("Favored"))); | 
					
						
							|  |  |  |             $out->elementEnd('span'); | 
					
						
							|  |  |  |             $out->elementStart('span', array('class' => 'fave-tally')); | 
					
						
							|  |  |  |             $out->raw($tally->count); | 
					
						
							|  |  |  |             $out->elementEnd('span'); | 
					
						
							| 
									
										
										
										
											2010-09-29 14:08:31 -07:00
										 |  |  |             $out->elementEnd('div'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 12:49:53 -07:00
										 |  |  |     function onEndFavorNotice($profile, $notice) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $tally = Fave_tally::increment($notice->id); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onEndDisfavorNotice($profile, $notice) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $tally = Fave_tally::decrement($notice->id); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 11:12:53 -07:00
										 |  |  |     static function createAnonProfile() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |         // Get the anon user's IP, and turn it into a nickname
 | 
					
						
							|  |  |  |         list($proxy, $ip) = common_client_ip(); | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // IP + time + random number should help to avoid collisions
 | 
					
						
							|  |  |  |         $baseNickname = $ip . '-' . time() . '-' . common_good_rand(5); | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $profile = new Profile(); | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  |         $profile->nickname = $baseNickname; | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |         $id = $profile->insert(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  |         if (!$id) { | 
					
						
							| 
									
										
										
										
											2010-10-01 21:45:19 +02:00
										 |  |  |             // TRANS: Server exception.
 | 
					
						
							| 
									
										
										
										
											2011-04-06 15:08:39 +02:00
										 |  |  |             throw new ServerException(_m("Could not create anonymous user session.")); | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Stick the Profile ID into the nickname
 | 
					
						
							|  |  |  |         $orig = clone($profile); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $profile->nickname = 'anon-' . $id . '-' . $baseNickname; | 
					
						
							|  |  |  |         $result = $profile->update($orig); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!$result) { | 
					
						
							| 
									
										
										
										
											2010-10-01 21:45:19 +02:00
										 |  |  |             // TRANS: Server exception.
 | 
					
						
							| 
									
										
										
										
											2011-04-06 15:08:39 +02:00
										 |  |  |             throw new ServerException(_m("Could not create anonymous user session.")); | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  |         common_log( | 
					
						
							|  |  |  |             LOG_INFO, | 
					
						
							|  |  |  |             "AnonymousFavePlugin - created profile for anonymous user from IP: " | 
					
						
							|  |  |  |             . $ip | 
					
						
							|  |  |  |             . ', nickname = ' | 
					
						
							|  |  |  |             . $profile->nickname | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |         return $profile; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 11:12:53 -07:00
										 |  |  |     static function getAnonProfile() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  |         $token = $_SESSION['anon_token']; | 
					
						
							|  |  |  |         $anon = base64_decode($token); | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $profile = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  |         if (!empty($anon) && substr($anon, 0, 5) == 'anon-') { | 
					
						
							|  |  |  |             $parts = explode('-', $anon); | 
					
						
							|  |  |  |             $id = $parts[1]; | 
					
						
							|  |  |  |             // Do Profile lookup by ID instead of nickname for safety/performance
 | 
					
						
							| 
									
										
										
										
											2013-08-18 13:04:58 +02:00
										 |  |  |             $profile = Profile::getKV('id', $id); | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2010-09-29 16:11:32 -07:00
										 |  |  |             $profile = AnonymousFavePlugin::createAnonProfile(); | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  |             // Obfuscate so it's hard to figure out the Profile ID
 | 
					
						
							|  |  |  |             $_SESSION['anon_token'] = base64_encode($profile->nickname); | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 15:52:18 -07:00
										 |  |  |         return $profile; | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 11:12:53 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Determine whether a given NoticeListItem should have the | 
					
						
							|  |  |  |      * anonymous fave/disfave form | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param NoticeListItem $item | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return boolean false if the profile associated with the notice is | 
					
						
							|  |  |  |      *                       in the list of restricted profiles, otherwise | 
					
						
							|  |  |  |      *                       return true | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function hasAnonFaving($item) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2013-08-18 13:04:58 +02:00
										 |  |  |         $profile = Profile::getKV('id', $item->notice->profile_id); | 
					
						
							| 
									
										
										
										
											2010-10-01 11:12:53 -07:00
										 |  |  |         if (in_array($profile->nickname, $this->restricted)) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Provide plugin version information. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * This data is used when showing the version page. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array &$versions array of version data arrays; see EVENTS.txt | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return boolean hook value | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function onPluginVersion(&$versions) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $url = 'http://status.net/wiki/Plugin:AnonymousFave'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $versions[] = array('name' => 'AnonymousFave', | 
					
						
							|  |  |  |             'version' => ANONYMOUS_FAVE_PLUGIN_VERSION, | 
					
						
							|  |  |  |             'author' => 'Zach Copley', | 
					
						
							|  |  |  |             'homepage' => $url, | 
					
						
							|  |  |  |             'rawdescription' => | 
					
						
							| 
									
										
										
										
											2010-10-01 21:45:19 +02:00
										 |  |  |             // TRANS: Plugin description.
 | 
					
						
							| 
									
										
										
										
											2010-09-28 17:17:09 -07:00
										 |  |  |             _m('Allow anonymous users to favorite notices.')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |