diff options
-rw-r--r-- | actions/repeat.php | 122 | ||||
-rw-r--r-- | classes/Notice.php | 14 | ||||
-rw-r--r-- | classes/Profile.php | 11 | ||||
-rw-r--r-- | classes/statusnet.ini | 2 | ||||
-rw-r--r-- | db/08to09.sql | 4 | ||||
-rw-r--r-- | db/08to09_pg.sql | 1 | ||||
-rw-r--r-- | db/statusnet.sql | 2 | ||||
-rw-r--r-- | db/statusnet_pg.sql | 4 | ||||
-rw-r--r-- | js/util.js | 5 | ||||
-rw-r--r-- | lib/noticelist.php | 21 | ||||
-rw-r--r-- | lib/repeatform.php | 145 | ||||
-rw-r--r-- | theme/base/css/display.css | 4 |
12 files changed, 327 insertions, 8 deletions
diff --git a/actions/repeat.php b/actions/repeat.php new file mode 100644 index 000000000..194833fe0 --- /dev/null +++ b/actions/repeat.php @@ -0,0 +1,122 @@ +<?php + +/** + * Forward action. + * + * PHP version 5 + * + * @category Action + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://status.net/ + * + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2008, 2009, StatusNet, 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('STATUSNET')) { + exit(1); +} + +/** + * Forward action + * + * @category Action + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://status.net/ + */ + +class ForwardAction extends Action +{ + var $user = null; + var $notice = null; + + function prepare($args) + { + parent::prepare($args); + + $this->user = common_current_user(); + + if (empty($this->user)) { + $this->clientError(_("Only logged-in users can forward notices.")); + return false; + } + + $id = $this->trimmed('notice'); + + if (empty($id)) { + $this->clientError(_("No notice specified.")); + return false; + } + + $this->notice = Notice::staticGet('id', $id); + + if (empty($this->notice)) { + $this->clientError(_("No notice specified.")); + return false; + } + + if ($this->user->id == $this->notice->profile_id) { + $this->clientError(_("You can't forward your own notice.")); + return false; + } + + $token = $this->trimmed('token-'.$id); + + if (empty($token) || $token != common_session_token()) { + $this->clientError(_("There was a problem with your session token. Try again, please.")); + return false; + } + + $profile = $this->user->getProfile(); + + if ($profile->hasForwarded($id)) { + $this->clientError(_("You already forwarded that notice.")); + return false; + } + + return true; + } + + /** + * Class handler. + * + * @param array $args query arguments + * + * @return void + */ + + function handle($args) + { + $forward = Forward::saveNew($this->user->id, $this->notice->id); + + if ($this->boolean('ajax')) { + $this->startHTML('text/xml;charset=utf-8'); + $this->elementStart('head'); + $this->element('title', null, _('Forwarded')); + $this->elementEnd('head'); + $this->elementStart('body'); + $this->element('p', array('id' => 'forward_response'), _('Forwarded!')); + $this->elementEnd('body'); + $this->elementEnd('html'); + } else { + // FIXME! + } + } +} diff --git a/classes/Notice.php b/classes/Notice.php index 4422866fa..228201188 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -55,13 +55,13 @@ class Notice extends Memcached_DataObject public $__table = 'notice'; // table name public $id; // int(4) primary_key not_null - public $profile_id; // int(4) not_null + public $profile_id; // int(4) multiple_key not_null public $uri; // varchar(255) unique_key - public $content; // text() - public $rendered; // text() + public $content; // text + public $rendered; // text public $url; // varchar(255) - public $created; // datetime() not_null - public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP + public $created; // datetime multiple_key not_null default_0000-00-00%2000%3A00%3A00 + public $modified; // timestamp not_null default_CURRENT_TIMESTAMP public $reply_to; // int(4) public $is_local; // tinyint(1) public $source; // varchar(32) @@ -70,9 +70,11 @@ class Notice extends Memcached_DataObject public $lon; // decimal(10,7) public $location_id; // int(4) public $location_ns; // int(4) + public $repeat_of; // int(4) /* Static get */ - function staticGet($k,$v=NULL) { + function staticGet($k,$v=NULL) + { return Memcached_DataObject::staticGet('Notice',$k,$v); } diff --git a/classes/Profile.php b/classes/Profile.php index 4b2e09006..03196447b 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -716,4 +716,15 @@ class Profile extends Memcached_DataObject } return $result; } + + function hasRepeated($notice_id) + { + // XXX: not really a pkey, but should work + + $notice = Memcached_DataObject::pkeyGet('Notice', + array('profile_id' => $this->id, + 'repeat_of' => $notice_id)); + + return !empty($notice); + } } diff --git a/classes/statusnet.ini b/classes/statusnet.ini index 835faeb0b..ff4ef2c14 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -1,3 +1,4 @@ + [avatar] profile_id = 129 original = 17 @@ -306,6 +307,7 @@ lat = 1 lon = 1 location_id = 1 location_ns = 1 +repeat_of = 1 [notice__keys] id = N diff --git a/db/08to09.sql b/db/08to09.sql index 64640f4ce..28ec3ec16 100644 --- a/db/08to09.sql +++ b/db/08to09.sql @@ -4,8 +4,10 @@ alter table notice add column lon decimal(10,7) comment 'longitude', add column location_id integer comment 'location id if possible', add column location_ns integer comment 'namespace for location', + add column repeat_of integer comment 'notice this is a repeat of' references notice (id), drop index notice_profile_id_idx, - add index notice_profile_id_idx (profile_id,created,id); + add index notice_profile_id_idx (profile_id,created,id), + add index notice_repeatof_idx (repeat_of); alter table message modify column content text comment 'message content'; diff --git a/db/08to09_pg.sql b/db/08to09_pg.sql index 1df8c249b..0398952f6 100644 --- a/db/08to09_pg.sql +++ b/db/08to09_pg.sql @@ -74,6 +74,7 @@ ALTER TABLE notice ADD COLUMN lat decimal(10, 7) /* comment 'latitude'*/; ALTER TABLE notice ADD COLUMN lon decimal(10,7) /* comment 'longitude'*/; ALTER TABLE notice ADD COLUMN location_id integer /* comment 'location id if possible'*/ ; ALTER TABLE notice ADD COLUMN location_ns integer /* comment 'namespace for location'*/; +ALTER TABLE notice ADD COLUMN repeat_of integer / * comment 'notice this is a repeat of' */ references notice (id); ALTER TABLE profile ADD COLUMN lat decimal(10,7) /*comment 'latitude'*/ ; ALTER TABLE profile ADD COLUMN lon decimal(10,7) /*comment 'longitude'*/; diff --git a/db/statusnet.sql b/db/statusnet.sql index 18abcdfdb..6b3c2ca06 100644 --- a/db/statusnet.sql +++ b/db/statusnet.sql @@ -129,11 +129,13 @@ create table notice ( lon decimal(10,7) comment 'longitude', location_id integer comment 'location id if possible', location_ns integer comment 'namespace for location', + repeat_of integer comment 'notice this is a repeat of' references notice (id), index notice_profile_id_idx (profile_id,created,id), index notice_conversation_idx (conversation), index notice_created_idx (created), index notice_replyto_idx (reply_to), + index notice_repeatof_idx (repeat_of), FULLTEXT(content) ) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci; diff --git a/db/statusnet_pg.sql b/db/statusnet_pg.sql index c37fa81de..020bfd967 100644 --- a/db/statusnet_pg.sql +++ b/db/statusnet_pg.sql @@ -135,7 +135,9 @@ create table notice ( lat decimal(10,7) /* comment 'latitude'*/ , lon decimal(10,7) /* comment 'longitude'*/ , location_id integer /* comment 'location id if possible'*/ , - location_ns integer /* comment 'namespace for location'*/ + location_ns integer /* comment 'namespace for location'*/ , + repeat_of integer /* comment 'notice this is a repeat of' */ references notice (id) , + /* FULLTEXT(content) */ ); diff --git a/js/util.js b/js/util.js index 336cd8cfe..f60b5d313 100644 --- a/js/util.js +++ b/js/util.js @@ -315,6 +315,10 @@ var SN = { // StatusNet $('.form_disfavor').each(function() { SN.U.FormXHR($(this)); }); }, + NoticeRepeat: function() { + $('.form_repeat').each(function() { SN.U.FormXHR($(this)); }); + }, + NoticeAttachments: function() { $('.notice a.attachment').each(function() { SN.U.NoticeWithAttachment($(this).closest('.notice')); @@ -448,6 +452,7 @@ var SN = { // StatusNet Notices: function() { if ($('body.user_in').length > 0) { SN.U.NoticeFavor(); + SN.U.NoticeRepeat(); SN.U.NoticeReply(); } diff --git a/lib/noticelist.php b/lib/noticelist.php index 21cec528f..924056ece 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -212,6 +212,7 @@ class NoticeListItem extends Widget $this->out->elementStart('div', 'notice-options'); $this->showFaveForm(); $this->showReplyLink(); + $this->showRepeatForm(); $this->showDeleteLink(); $this->out->elementEnd('div'); } @@ -552,6 +553,26 @@ class NoticeListItem extends Widget } /** + * show the form to repeat a notice + * + * @return void + */ + + function showRepeatForm() + { + $user = common_current_user(); + if ($user && $user->id != $this->notice->profile_id) { + $profile = $user->getProfile(); + if ($profile->hasRepeated($this->notice->id)) { + $this->out->text(_('Repeated')); + } else { + $rf = new RepeatForm($this->out, $this->notice); + $rf->show(); + } + } + } + + /** * finish the notice * * Close the last elements in the notice list item diff --git a/lib/repeatform.php b/lib/repeatform.php new file mode 100644 index 000000000..50e5d6dbe --- /dev/null +++ b/lib/repeatform.php @@ -0,0 +1,145 @@ +<?php +/** + * StatusNet, the distributed open-source microblogging tool + * + * Form for repeating a notice + * + * 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 Form + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @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/ + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Form for repeating a notice + * + * @category Form + * @package StatusNet + * @author Evan Prodromou <evan@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/ + */ + +class RepeatForm extends Form +{ + /** + * Notice to repeat + */ + + var $notice = null; + + /** + * Constructor + * + * @param HTMLOutputter $out output channel + * @param Notice $notice notice to repeat + */ + + function __construct($out=null, $notice=null) + { + parent::__construct($out); + + $this->notice = $notice; + } + + /** + * ID of the form + * + * @return int ID of the form + */ + + function id() + { + return 'repeat-' . $this->notice->id; + } + + /** + * Action of the form + * + * @return string URL of the action + */ + + function action() + { + return common_local_url('repeat'); + } + + /** + * Include a session token for CSRF protection + * + * @return void + */ + + function sessionToken() + { + $this->out->hidden('token-' . $this->notice->id, + common_session_token()); + } + + /** + * Legend of the Form + * + * @return void + */ + function formLegend() + { + $this->out->element('legend', null, _('Repeat this notice')); + } + + /** + * Data elements + * + * @return void + */ + + function formData() + { + $this->out->hidden('notice-n'.$this->notice->id, + $this->notice->id, + 'notice'); + } + + /** + * Action elements + * + * @return void + */ + + function formActions() + { + $this->out->submit('repeat-submit-' . $this->notice->id, + _('Repeat'), 'submit', null, _('Repeat this notice')); + } + + /** + * Class of the form. + * + * @return string the form's class + */ + + function formClass() + { + return 'form_repeat'; + } +} diff --git a/theme/base/css/display.css b/theme/base/css/display.css index e88e1f222..7446a42cd 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -994,11 +994,13 @@ float:left; } .notice-options .notice_delete, .notice-options .notice_reply, +.notice-options .form_repeat, .notice-options .form_favor, .notice-options .form_disfavor { float:left; margin-left:20%; } +.notice-options .form_repeat, .notice-options .form_favor, .notice-options .form_disfavor { margin-left:0; @@ -1024,10 +1026,12 @@ border-radius:0; -moz-border-radius:0; -webkit-border-radius:0; } +.notice-options .form_repeat legend, .notice-options .form_favor legend, .notice-options .form_disfavor legend { display:none; } +.notice-options .form_repeat fieldset, .notice-options .form_favor fieldset, .notice-options .form_disfavor fieldset { border:0; |