initial non-Ajax version of favorites

darcs-hash:20080908181624-84dde-8200e1d91eb5f560ef0f296c9e1c56f93ef1b0c5.gz
This commit is contained in:
Evan Prodromou 2008-09-08 14:16:24 -04:00
parent 75f285ddf6
commit a8a3667774
10 changed files with 362 additions and 4 deletions

74
actions/disfavor.php Normal file
View File

@ -0,0 +1,74 @@
<?php
/*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
* 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/>.
*/
if (!defined('LACONICA')) { exit(1); }
require_once($INSTALLDIR.'/lib/mail.php');
class DisfavorAction extends Action {
function handle($args) {
parent::handle($args);
if (!common_logged_in()) {
common_user_error(_('Not logged in.'));
return;
}
$user = common_current_user();
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
common_redirect(common_local_url('favorites', array('nickname' => $user->nickname)));
return;
}
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
$this->client_error(_('There was a problem with your session token. Try again, please.'));
return;
}
$id = $this->trimmed('notice');
$notice = Notice::staticGet($id);
$fave = new Fave();
$fave->user_id = $this->id;
$fave->notice_id = $notice->id;
if (!$fave->find(true)) {
$this->client_error(_('This notice is not a favorite!'));
return;
}
$result = $fave->delete();
if (!$result) {
common_log_db_error($fave, 'DELETE', __FILE__);
$this->server_error(_('Could not delete favorite.'));
return;
}
# XXX: ajax response
common_redirect(common_local_url('favorites',
array('nickname' => $user->nickname)));
}
}

100
actions/favor.php Normal file
View File

@ -0,0 +1,100 @@
<?php
/*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
* 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/>.
*/
if (!defined('LACONICA')) { exit(1); }
require_once($INSTALLDIR.'/lib/mail.php');
class FavorAction extends Action {
function handle($args) {
parent::handle($args);
if (!common_logged_in()) {
common_user_error(_('Not logged in.'));
return;
}
$user = common_current_user();
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
common_redirect(common_local_url('showfavorites', array('nickname' => $user->nickname)));
return;
}
# CSRF protection
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
$this->client_error(_('There was a problem with your session token. Try again, please.'));
return;
}
$id = $this->trimmed('notice');
$notice = Notice::staticGet($id);
if ($user->hasFave($notice)) {
$this->client_error(_('This notice is already a favorite!'));
return;
}
$fave = Fave::addNew($user, $notice);
if (!$fave) {
$this->server_error(_('Could not create favorite.'));
return;
}
$this->notify($fave, $notice, $user);
common_redirect(common_local_url('showfavorites',
array('nickname' => $user->nickname)));
}
function notify($fave, $notice, $user) {
$other = User::staticGet('id', $notice->profile_id);
if ($other) {
if ($other->email && $other->emailnotifyfav) {
$this->notify_mail($other, $user, $notice);
}
# XXX: notify by IM
# XXX: notify by SMS
}
}
function notify_mail($other, $user, $notice) {
$profile = $user->getProfile();
$bestname = $profile->getBestName();
$subject = sprintf(_('%s added your notice as a favorite'), $bestname);
$body = sprintf(_('%1$s just added your notice from %2$s as one of their favorites.\n\n' .
'In case you forgot, you can see the text of your notice here:\n\n' .
'%3$s\n\n' .
'You can see the list of %1$s\'s favorites here:\n\n' .
'%4$s\n\n' .
'Faithfully yours,\n' .
'%5$s\n'),
$bestname,
common_exact_date($notice->created),
common_local_url('shownotice', array('notice' => $notice->id)),
common_local_url('showfavorites', array('nickname' => $user->nickname)),
common_config('site', 'name'));
mail_to_user($other, $subject, $body);
}
}

106
actions/showfavorites.php Normal file
View File

@ -0,0 +1,106 @@
<?php
/*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
* 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/>.
*/
if (!defined('LACONICA')) { exit(1); }
require_once(INSTALLDIR.'/actions/showstream.php');
class ShowfavoritesAction extends StreamAction {
function handle($args) {
parent::handle($args);
$nickname = common_canonical_nickname($this->arg('nickname'));
$user = User::staticGet('nickname', $nickname);
if (!$user) {
$this->client_error(_('No such user.'));
return;
}
$profile = $user->getProfile();
if (!$profile) {
common_server_error(_('User has no profile.'));
return;
}
# Looks like we're good; show the header
common_show_header(sprintf(_("%s favorite notices"), $profile->nickname),
array($this, 'show_header'), $user,
array($this, 'show_top'));
$this->show_notices($user);
common_show_footer();
}
function show_header($user) {
common_element('link', array('rel' => 'alternate',
'href' => common_local_url('favoritesrss', array('nickname' =>
$user->nickname)),
'type' => 'application/rss+xml',
'title' => sprintf(_('Feed for favorites of %s'), $user->nickname)));
}
function show_top($user) {
$cur = common_current_user();
if ($cur && $cur->id == $user->id) {
common_notice_form('all');
}
$this->views_menu();
}
function show_notices($user) {
$page = $this->trimmed('page');
if (!$page) {
$page = 1;
}
$notice = $user->favoriteNotices(($page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
if (!$notice) {
$this->server_error(_('Could not retrieve favorite notices.'));
return;
}
common_element_start('ul', array('id' => 'notices'));
$cnt = 0;
while ($notice->fetch() && $cnt <= NOTICES_PER_PAGE) {
$cnt++;
if ($cnt > NOTICES_PER_PAGE) {
break;
}
$this->show_notice($notice);
}
common_element_end('ul');
common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
$page, 'showfavorites', array('nickname' => $user->nickname));
}
}

View File

@ -19,4 +19,15 @@ class Fave extends DB_DataObject
/* the code above is auto generated do not remove the tag below */ /* the code above is auto generated do not remove the tag below */
###END_AUTOCODE ###END_AUTOCODE
static function addNew($user, $notice) {
$fave = new Fave();
$fave->user_id = $user->id;
$fave->notice_id = $notice->id;
if (!$fave->insert()) {
common_log_db_error($fave, 'INSERT', __FILE__);
return false;
}
return $fave;
}
} }

View File

@ -43,6 +43,7 @@ class User extends DB_DataObject
public $email; // varchar(255) unique_key public $email; // varchar(255) unique_key
public $incomingemail; // varchar(255) unique_key public $incomingemail; // varchar(255) unique_key
public $emailnotifysub; // tinyint(1) default_1 public $emailnotifysub; // tinyint(1) default_1
public $emailnotifyfav; // tinyint(1) default_1
public $emailmicroid; // tinyint(1) default_1 public $emailmicroid; // tinyint(1) default_1
public $language; // varchar(50) public $language; // varchar(50)
public $timezone; // varchar(50) public $timezone; // varchar(50)
@ -275,4 +276,18 @@ class User extends DB_DataObject
} }
} }
} }
function hasFave($notice) {
$fave = new Fave();
$fave->user_id = $this->id;
$fave->notice_id = $notice->id;
if ($fave->find()) {
$result = true;
} else {
$result = false;
}
$fave->free();
unset($fave);
return $result;
}
} }

View File

@ -252,6 +252,7 @@ password = 2
email = 2 email = 2
incomingemail = 2 incomingemail = 2
emailnotifysub = 17 emailnotifysub = 17
emailnotifyfav = 17
emailmicroid = 17 emailmicroid = 17
language = 2 language = 2
timezone = 2 timezone = 2

View File

@ -47,6 +47,7 @@ create table user (
email varchar(255) unique key comment 'email address for password recovery etc.', email varchar(255) unique key comment 'email address for password recovery etc.',
incomingemail varchar(255) unique key comment 'email address for post-by-email', incomingemail varchar(255) unique key comment 'email address for post-by-email',
emailnotifysub tinyint default 1 comment 'Notify by email of subscriptions', emailnotifysub tinyint default 1 comment 'Notify by email of subscriptions',
emailnotifyfav tinyint default 1 comment 'Notify by email of favorites',
emailmicroid tinyint default 1 comment 'whether to publish email microid', emailmicroid tinyint default 1 comment 'whether to publish email microid',
language varchar(50) comment 'preferred language', language varchar(50) comment 'preferred language',
timezone varchar(50) comment 'timezone', timezone varchar(50) comment 'timezone',
@ -281,10 +282,10 @@ create table foreign_link (
credentials varchar(255) comment 'authc credentials, typically a password', credentials varchar(255) comment 'authc credentials, typically a password',
noticesync tinyint not null default 1 comment 'notice synchronization, bit 1 = sync outgoing, bit 2 = sync incoming', noticesync tinyint not null default 1 comment 'notice synchronization, bit 1 = sync outgoing, bit 2 = sync incoming',
friendsync tinyint not null default 2 comment 'friend synchronization, bit 1 = sync outgoing, bit 2 = sync incoming', friendsync tinyint not null default 2 comment 'friend synchronization, bit 1 = sync outgoing, bit 2 = sync incoming',
profilesync tinyint not null default 1 comment 'profile synchronization, bit 1 = sync outgoing, bit 2 = sync incoming', profilesync tinyint not null default 1 comment 'profile synchronization, bit 1 = sync outgoing, bit 2 = sync incoming',
created datetime not null comment 'date this record was created', created datetime not null comment 'date this record was created',
modified timestamp comment 'date this record was modified', modified timestamp comment 'date this record was modified',
constraint primary key (user_id, foreign_id, service), constraint primary key (user_id, foreign_id, service),
index foreign_user_user_id_idx (user_id) index foreign_user_user_id_idx (user_id)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;

View File

@ -35,6 +35,9 @@ RewriteRule ^main/recoverpassword$ index.php?action=recoverpassword [L,QSA]
RewriteRule ^main/recoverpassword/(.*)$ index.php?action=recoverpassword&code=$1 [L,QSA] RewriteRule ^main/recoverpassword/(.*)$ index.php?action=recoverpassword&code=$1 [L,QSA]
RewriteRule ^main/invite$ index.php?action=invite [L,QSA] RewriteRule ^main/invite$ index.php?action=invite [L,QSA]
RewriteRule ^main/favor$ index.php?action=favor [L,QSA]
RewriteRule ^main/disfavor$ index.php?action=disfavor [L,QSA]
RewriteRule ^settings/avatar$ index.php?action=avatar [L,QSA] RewriteRule ^settings/avatar$ index.php?action=avatar [L,QSA]
RewriteRule ^settings/password$ index.php?action=password [L,QSA] RewriteRule ^settings/password$ index.php?action=password [L,QSA]
RewriteRule ^settings/profile$ index.php?action=profilesettings [L,QSA] RewriteRule ^settings/profile$ index.php?action=profilesettings [L,QSA]
@ -67,6 +70,7 @@ RewriteRule ^(\w+)/foaf$ index.php?action=foaf&nickname=$1 [L,QSA]
RewriteRule ^(\w+)/replies$ index.php?action=replies&nickname=$1 [L,QSA] RewriteRule ^(\w+)/replies$ index.php?action=replies&nickname=$1 [L,QSA]
RewriteRule ^(\w+)/replies/rss$ index.php?action=repliesrss&nickname=$1 [L,QSA] RewriteRule ^(\w+)/replies/rss$ index.php?action=repliesrss&nickname=$1 [L,QSA]
RewriteRule ^(\w+)/avatar/(original|96|48|24)$ index.php?action=avatarbynickname&nickname=$1&size=$2 [L,QSA] RewriteRule ^(\w+)/avatar/(original|96|48|24)$ index.php?action=avatarbynickname&nickname=$1&size=$2 [L,QSA]
RewriteRule ^(\w+)/favorites$ index.php?action=showfavorites&nickname=$1 [L,QSA]
RewriteRule ^(\w+)$ index.php?action=showstream&nickname=$1 [L,QSA] RewriteRule ^(\w+)$ index.php?action=showstream&nickname=$1 [L,QSA]

View File

@ -60,6 +60,11 @@ class StreamAction extends Action {
_('Profile'), _('Profile'),
($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname, ($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname,
$action == 'showstream'); $action == 'showstream');
common_menu_item(common_local_url('showfavorites', array('nickname' =>
$nickname)),
_('Favorites'),
sprintf(_('%s\'s favorite notices'), ($user_profile) ? $user_profile->getBestName() : _('User')),
$action == 'showfavorites');
common_element_end('ul'); common_element_end('ul');
} }
@ -133,10 +138,17 @@ class StreamAction extends Action {
common_raw('&times;'); common_raw('&times;');
common_element_end('a'); common_element_end('a');
} }
if ($user) {
if ($user->hasFave($notice)) {
common_disfavor_form($notice);
} else {
common_favor_form($notice);
}
}
common_element_end('p'); common_element_end('p');
common_element_end('li'); common_element_end('li');
} }
function source_link($source) { function source_link($source) {
$source_name = _($source); $source_name = _($source);
switch ($source) { switch ($source) {

View File

@ -174,7 +174,7 @@ function common_show_header($pagetitle, $callable=NULL, $data=NULL, $headercall=
# FIXME: correct language for interface # FIXME: correct language for interface
$language = common_language(); $language = common_language();
common_element_start('html', array('xmlns' => 'http://www.w3.org/1999/xhtml', common_element_start('html', array('xmlns' => 'http://www.w3.org/1999/xhtml',
'xml:lang' => $language, 'xml:lang' => $language,
'lang' => $language)); 'lang' => $language));
@ -913,6 +913,16 @@ function common_fancy_url($action, $args=NULL) {
return common_path($path . (($args) ? ('?' . http_build_query($args)) : '')); return common_path($path . (($args) ? ('?' . http_build_query($args)) : ''));
case 'tags': case 'tags':
return common_path('tags' . (($args) ? ('?' . http_build_query($args)) : '')); return common_path('tags' . (($args) ? ('?' . http_build_query($args)) : ''));
case 'favor':
return common_path('main/favor');
case 'disfavor':
return common_path('main/disfavor');
case 'showfavorites':
if ($args && isset($args['page'])) {
return common_path($args['nickname'].'/favorites?page=' . $args['page']);
} else {
return common_path($args['nickname'].'/favorites');
}
default: default:
return common_simple_url($action, $args); return common_simple_url($action, $args);
} }
@ -1537,6 +1547,30 @@ function common_session_token() {
return $_SESSION['token']; return $_SESSION['token'];
} }
function common_disfavor_form($notice) {
common_element_start('form', array('id' => 'disfavor-' . $notice->id,
'method' => 'post',
'action' => common_local_url('disfavor')));
common_hidden('token', common_session_token());
common_hidden('notice', $notice->id);
common_element('input', array('type' => 'button',
'class' => 'disfavor'),
'♥');
common_element_end('form');
}
function common_favor_form($notice) {
common_element_start('form', array('id' => 'favor-' . $notice->id,
'method' => 'post',
'action' => common_local_url('disfavor')));
common_hidden('token', common_session_token());
common_hidden('notice', $notice->id);
common_element('input', array('type' => 'button',
'class' => 'disfavor'),
'♡');
common_element_end('form');
}
function common_cache_key($extra) { function common_cache_key($extra) {
return 'laconica:' . common_keyize(common_config('site', 'name')) . ':' . $extra; return 'laconica:' . common_keyize(common_config('site', 'name')) . ':' . $extra;
} }