Commit 382e4d2c authored by Shashi Gowda's avatar Shashi Gowda

people tag actions

parent f446db8e
<?php
/**
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008-2010, StatusNet, Inc.
*
* Action to add a people tag to a user.
*
* 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/>.
*
* PHP version 5
*
* @category Action
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
require_once INSTALLDIR . '/lib/togglepeopletag.php';
/**
*
* Action to tag a profile with a single tag.
*
* Takes parameters:
*
* - tagged: the ID of the profile being tagged
* - token: session token to prevent CSRF attacks
* - ajax: boolean; whether to return Ajax or full-browser results
* - peopletag_id: the ID of the tag being used
*
* Only works if the current user is logged in.
*
* @category Action
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/
*/
class AddpeopletagAction extends Action
{
var $user;
var $tagged;
var $peopletag;
/**
* Check pre-requisites and instantiate attributes
*
* @param Array $args array of arguments (URL, GET, POST)
*
* @return boolean success flag
*/
function prepare($args)
{
parent::prepare($args);
// CSRF protection
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token.'.
' Try again, please.'));
return false;
}
// Only for logged-in users
$this->user = common_current_user();
if (empty($this->user)) {
$this->clientError(_('Not logged in.'));
return false;
}
// Profile to subscribe to
$tagged_id = $this->arg('tagged');
$this->tagged = Profile::staticGet('id', $tagged_id);
if (empty($this->tagged)) {
$this->clientError(_('No such profile.'));
return false;
}
$id = $this->arg('peopletag_id');
$this->peopletag = Profile_list::staticGet('id', $id);
if (empty($this->peopletag)) {
$this->clientError(_('No such peopletag.'));
return false;
}
// OMB 0.1 doesn't have a mechanism for local-server-
// originated tag.
$omb01 = Remote_profile::staticGet('id', $tagged_id);
if (!empty($omb01)) {
$this->clientError(_('You cannot tag an OMB 0.1'.
' remote profile with this action.'));
return false;
}
return true;
}
/**
* Handle request
*
* Does the tagging and returns results.
*
* @param Array $args unused.
*
* @return void
*/
function handle($args)
{
// Throws exception on error
$ptag = Profile_tag::setTag($this->user->id, $this->tagged->id,
$this->peopletag->tag);
if (!$ptag) {
$user = User::staticGet('id', $id);
if ($user) {
$this->clientError(
sprintf(_('There was an unexpected error while tagging %s'),
$user->nickname));
} else {
$this->clientError(sprintf(_('There was a problem tagging %s.' .
'The remote server is probably not responding correctly, ' .
'please try retrying later.'), $this->profile->profileurl));
}
return false;
}
if ($this->boolean('ajax')) {
$this->startHTML('text/xml;charset=utf-8');
$this->elementStart('head');
$this->element('title', null, _('Subscribed'));
$this->elementEnd('head');
$this->elementStart('body');
$unsubscribe = new UntagButton($this, $this->tagged, $this->peopletag);
$unsubscribe->show();
$this->elementEnd('body');
$this->elementEnd('html');
} else {
$url = common_local_url('subscriptions',
array('nickname' => $this->user->nickname));
common_redirect($url, 303);
}
}
}
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Edit an existing group
*
* PHP version 5
*
* LICENCE: 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 Group
* @package StatusNet
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
/**
* Add a new group
*
* This is the form for adding a new group
*
* @category Group
* @package StatusNet
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class EditpeopletagAction extends OwnerDesignAction
{
var $msg, $confirm, $confirm_args=array();
function title()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $this->boolean('delete')) {
return sprintf(_('Delete %s people tag'), $this->peopletag->tag);
}
return sprintf(_('Edit people tag %s'), $this->peopletag->tag);
}
/**
* Prepare to run
*/
function prepare($args)
{
parent::prepare($args);
if (!common_logged_in()) {
$this->clientError(_('Not logged in.'));
return false;
}
$id = $this->arg('id');
$tagger_arg = $this->arg('tagger');
$tag_arg = $this->arg('tag');
$tagger = common_canonical_nickname($tagger_arg);
$tag = common_canonical_tag($tag_arg);
$current = common_current_user();
// Permanent redirect on non-canonical tag
if ($tagger_arg != $tagger || $tag_arg != $tag) {
$args = array('tagger' => $tagger, 'tag' => $tag);
common_redirect(common_local_url('editpeopletag', $args), 301);
return false;
}
$user = null;
if ($id) {
$this->peopletag = Profile_list::staticGet('id', $id);
if (!empty($this->peopletag)) {
$user = User::staticGet('id', $this->peopletag->tagger);
}
} else {
if (!$tagger) {
$this->clientError(_('No tagger or ID.'), 404);
return false;
}
$user = User::staticGet('nickname', $tagger);
$this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag));
}
if (!$this->peopletag) {
$this->clientError(_('No such peopletag.'), 404);
return false;
}
if (!$user) {
// This should not be happening
$this->clientError(_('Not a local user.'), 404);
return false;
}
if ($current->id != $user->id) {
$this->clientError(_('You must be the creator of the tag to edit it.'), 404);
return false;
}
$this->tagger = $user->getProfile();
return true;
}
/**
* Handle the request
*
* On GET, show the form. On POST, try to save the group.
*
* @param array $args unused
*
* @return void
*/
function handle($args)
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->trySave();
} else {
$this->showForm();
}
}
function showConfirm($msg=null, $fwd=null)
{
$this->confirm = $msg;
$this->confirm_args = $fwd;
$this->showPage();
}
function showConfirmForm()
{
$this->elementStart('form', array('id' => 'form_peopletag_edit_confirm',
'class' => 'form_settings',
'method' => 'post',
'action' => common_local_url('editpeopletag',
array('tagger' => $this->tagger->nickname,
'tag' => $this->peopletag->tag))));
$this->elementStart('fieldset');
$this->hidden('token', common_session_token());
$this->hidden('id', $this->arg('id'));
foreach ($this->confirm_args as $key => $val) {
$this->hidden($key, $val);
}
$this->submit('form_action-no',
_m('BUTTON','No'),
'submit form_action-primary',
'cancel');
$this->submit('form_action-yes',
_m('BUTTON','Yes'),
'submit form_action-secondary',
'confirm');
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
function showForm($msg=null)
{
$this->msg = $msg;
$this->showPage();
}
function showLocalNav()
{
$nav = new PeopletagGroupNav($this, $this->peopletag);
$nav->show();
}
function showContent()
{
if ($this->confirm) {
$this->showConfirmForm();
return;
}
$form = new PeopletagEditForm($this, $this->peopletag);
$form->show();
$form->showProfileList();
}
function showPageNotice()
{
if ($this->msg) {
$this->element('p', 'error', $this->msg);
} else if ($this->confirm) {
$this->element('p', 'instructions', $this->confirm);
} else {
$this->element('p', 'instructions',
_('Use this form to edit the people tag.'));
}
}
function showScripts()
{
parent::showScripts();
$this->autofocus('tag');
}
function trySave()
{
$tag = common_canonical_tag($this->trimmed('tag'));
$description = $this->trimmed('description');
$private = $this->boolean('private');
$delete = $this->arg('delete');
$confirm = $this->arg('confirm');
$cancel = $this->arg('cancel');
if ($delete && $cancel) {
$this->showForm(_('Delete aborted.'));
return;
}
$set_private = $private && $this->peopletag->private != $private;
if ($delete && !$confirm) {
$this->showConfirm(_('Deleting this tag will permanantly remove ' .
'all its subscription and membership records. ' .
'Do you still want to continue?'), array('delete' => 1));
return;
} else if (common_valid_tag($tag)) {
$this->showForm(_('Invalid tag.'));
return;
} else if ($tag != $this->peopletag->tag && $this->tagExists($tag)) {
$this->showForm(sprintf(_('You already have a tag named %s.'), $tag));
return;
} else if (Profile_list::descriptionTooLong($description)) {
$this->showForm(sprintf(_('description is too long (max %d chars).'), Profile_list::maxDescription()));
return;
} else if ($set_private && !$confirm && !$cancel) {
$fwd = array('tag' => $tag,
'description' => $description,
'private' => (int) $private);
$this->showConfirm(_('Setting a public tag as private will ' .
'permanently remove all the existing ' .
'subscriptions to it. Do you still want to continue?'), $fwd);
return;
}
$this->peopletag->query('BEGIN');
$orig = clone($this->peopletag);
$this->peopletag->tag = $tag;
$this->peopletag->description = $description;
if (!$set_private || $confirm) {
$this->peopletag->private = $private;
}
$result = $this->peopletag->update($orig);
if (!$result) {
common_log_db_error($this->group, 'UPDATE', __FILE__);
$this->serverError(_('Could not update peopletag.'));
}
$this->peopletag->query('COMMIT');
if ($set_private && $confirm) {
Profile_tag_subscription::cleanup($this->peopletag);
}
if ($delete) {
// This might take quite a bit of time.
$this->peopletag->delete();
// send home.
common_redirect(common_local_url('all',
array('nickname' => $this->tagger->nickname)),
303);
}
if ($tag != $orig->tag) {
common_redirect(common_local_url('editpeopletag',
array('tagger' => $this->tagger->nickname,
'tag' => $tag)),
303);
} else {
$this->showForm(_('Options saved.'));
}
}
function tagExists($tag)
{
$args = array('tagger' => $this->tagger->id, 'tag' => $tag);
$ptag = Profile_list::pkeyGet($args);
return !empty($ptag);
}
}
......@@ -2,7 +2,7 @@
/**
* StatusNet, the distributed open-source microblogging tool
*
* Action for showing profiles self-tagged with a given tag
* People tags by a user
*
* PHP version 5
*
......@@ -16,13 +16,16 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* PHP version 5
*
* 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 Action
* @category Personal
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @author Shashi Gowda <connect2shashi@gmail.com>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
......@@ -32,149 +35,125 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
/**
* This class outputs a paginated list of profiles self-tagged with a given tag
*
* @category Output
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*
* @see Action
*/
require_once INSTALLDIR.'/lib/peopletaglist.php';
// cache 3 pages
define('PEOPLETAG_CACHE_WINDOW', PEOPLETAGS_PER_PAGE*3 + 1);
class PeopletagAction extends Action
{
var $tag = null;
var $page = null;
var $tag = null;
/**
* For initializing members of the class.
*
* @param array $argarray misc. arguments
*
* @return boolean true
*/
function prepare($argarray)
function isReadOnly($args)
{
parent::prepare($argarray);
$this->tag = $this->trimmed('tag');
if (!common_valid_profile_tag($this->tag)) {
$this->clientError(sprintf(_('Not a valid people tag: %s.'),
$this->tag));
return;
}
$this->page = ($this->arg('page')) ? $this->arg('page') : 1;
common_set_returnto($this->selfUrl());
return true;
}
/**
* Handler method
*
* @param array $argarray is ignored since it's now passed in in prepare()
*
* @return boolean is read only action?
*/
function handle($argarray)
function title()
{
parent::handle($argarray);
$this->showPage();
if ($this->page == 1) {
return sprintf(_("Public people tag %s"), $this->tag);
} else {
return sprintf(_("Public people tag %s, page %d"), $this->tag, $this->page);
}
}
/**
* Whips up a query to get a list of profiles based on the provided
* people tag and page, initalizes a ProfileList widget, and displays
* it to the user.
*
* @return nothing
*/
function showContent()
function prepare($args)
{
parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
$profile = new Profile();
$tag_arg = $this->arg('tag');
$tag = common_canonical_tag($tag_arg);
$offset = ($this->page - 1) * PROFILES_PER_PAGE;
$limit = PROFILES_PER_PAGE + 1;
// Permanent redirect on non-canonical nickname
if (common_config('db', 'type') == 'pgsql') {
$lim = ' LIMIT ' . $limit . ' OFFSET ' . $offset;
} else {
$lim = ' LIMIT ' . $offset . ', ' . $limit;
if ($tag_arg != $tag) {
$args = array('tag' => $nickname);
if ($this->page && $this->page != 1) {
$args['page'] = $this->page;
}
common_redirect(common_local_url('peopletag', $args), 301);
return false;
}
$this->tag = $tag;
// XXX: memcached this
$qry = 'SELECT profile.* ' .
'FROM profile JOIN profile_tag ' .
'ON profile.id = profile_tag.tagger ' .
'WHERE profile_tag.tagger = profile_tag.tagged ' .
"AND tag = '%s' " .
'ORDER BY profile_tag.modified DESC%s';
$profile->query(sprintf($qry, $this->tag, $lim));
$ptl = new PeopleTagList($profile, $this); // pass the ammunition
$cnt = $ptl->show();
$this->pagination($this->page > 1,
$cnt > PROFILES_PER_PAGE,
$this->page,
'peopletag',
array('tag' => $this->tag));
return true;
}
/**
* Returns the page title
*
* @return string page title
*/
function title()
function handle($args)
{
return sprintf(_('Users self-tagged with %1$s - page %2$d'),
$this->tag, $this->page);
parent::handle($args);
$this->showPage();
}
}
function showLocalNav()
{
$nav = new PublicGroupNav($this);
$nav->show();
}
class PeopleTagList extends ProfileList
{
function newListItem($profile)
function showAnonymousMessage()
{
return new PeopleTagListItem($profile, $this->action);
$notice =
_('People tags are how you sort similar ' .
'people on %%site.name%%, a [micro-blogging]' .
'(http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [StatusNet](http://status.net/) tool. ' .
'You can then easily keep track of what they ' .
'are doing by subscribing to the tag\'s timeline.' );
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($notice));
$this->elementEnd('div');
}
}
class PeopleTagListItem extends ProfileListItem
{
function linkAttributes()
function showContent()
{
$aAttrs = parent::linkAttributes();
$offset = ($this->page-1) * PEOPLETAGS_PER_PAGE;
$limit = PEOPLETAGS_PER_PAGE + 1;
$ptags = new Profile_list();
$ptags->tag = $this->tag;
$user = common_current_user();
if (empty($user)) {
$ckey = sprintf('profile_list:tag:%s', $this->tag);
$ptags->private = false;
$ptags->orderBy('profile_list.modified DESC');
$c = Cache::instance();
if ($offset+$limit <= PEOPLETAG_CACHE_WINDOW && !empty($c)) {
$cached_ptags = Profile_list::getCached($ckey, $offset, $limit);
if ($cached_ptags === false) {
$ptags->limit(0, PEOPLETAG_CACHE_WINDOW);
$ptags->find();
Profile_list::setCache($ckey, $ptags, $offset, $limit);
} else {
$ptags = clone($cached_ptags);
}
} else {
$ptags->limit($offset, $limit);
$ptags->find();
}
} else {
$ptags->whereAdd('(profile_list.private = false OR (' .
' profile_list.tagger =' . $user->id .
' AND profile_list.private = true) )');
if (common_config('nofollow', 'peopletag')) {
$aAttrs['rel'] .= ' nofollow';
$ptags->orderBy('profile_list.modified DESC');
$ptags->find();
}
return $aAttrs;
$pl = new PeopletagList($ptags, $this);
$cnt = $pl->show();
$this->pagination($this->page > 1, $cnt > PEOPLETAGS_PER_PAGE,
$this->page, 'peopletag', array('tag' => $this->tag));
}
function homepageAttributes()
function showSections()
{