summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--classes/Notice.php47
-rw-r--r--config.php.sample6
-rw-r--r--lib/common.php3
4 files changed, 50 insertions, 8 deletions
diff --git a/README b/README
index 388d67ed2..ec2e2ec4f 100644
--- a/README
+++ b/README
@@ -879,6 +879,8 @@ notice: A plain string that will appear on every page. A good place
to put introductory information about your service, or info about
upgrades and outages, or other community info. Any HTML will
be escaped.
+dupelimit: Time in which it's not OK for the same person to post the
+ same notice; default = 60 seconds.
db
--
diff --git a/classes/Notice.php b/classes/Notice.php
index 907239b08..eac90ce95 100644
--- a/classes/Notice.php
+++ b/classes/Notice.php
@@ -121,6 +121,8 @@ class Notice extends Memcached_DataObject
$profile = Profile::staticGet($profile_id);
+ $final = common_shorten_links($content);
+
if (!$profile) {
common_log(LOG_ERR, 'Problem saving notice. Unknown user.');
return _('Problem saving notice. Unknown user.');
@@ -131,7 +133,12 @@ class Notice extends Memcached_DataObject
return _('Too many notices too fast; take a breather and post again in a few minutes.');
}
- $banned = common_config('profile', 'banned');
+ if (common_config('site', 'dupelimit') > 0 && !Notice::checkDupes($profile_id, $final)) {
+ common_log(LOG_WARNING, 'Dupe posting by profile #' . $profile_id . '; throttled.');
+ return _('Too many duplicate messages too quickly; take a breather and post again in a few minutes.');
+ }
+
+ $banned = common_config('profile', 'banned');
if ( in_array($profile_id, $banned) || in_array($profile->nickname, $banned)) {
common_log(LOG_WARNING, "Attempted post from banned user: $profile->nickname (user id = $profile_id).");
@@ -155,12 +162,12 @@ class Notice extends Memcached_DataObject
$notice->query('BEGIN');
- $notice->reply_to = $reply_to;
- $notice->created = common_sql_now();
- $notice->content = common_shorten_links($content);
- $notice->rendered = common_render_content($notice->content, $notice);
- $notice->source = $source;
- $notice->uri = $uri;
+ $notice->reply_to = $reply_to;
+ $notice->created = common_sql_now();
+ $notice->content = $final;
+ $notice->rendered = common_render_content($final, $notice);
+ $notice->source = $source;
+ $notice->uri = $uri;
if (Event::handle('StartNoticeSave', array(&$notice))) {
@@ -204,6 +211,32 @@ class Notice extends Memcached_DataObject
return $notice;
}
+ static function checkDupes($profile_id, $content) {
+ $profile = Profile::staticGet($profile_id);
+ if (!$profile) {
+ return false;
+ }
+ $notice = $profile->getNotices(0, NOTICE_CACHE_WINDOW);
+ if ($notice) {
+ $last = 0;
+ while ($notice->fetch()) {
+ if (time() - strtotime($notice->created) >= common_config('site', 'dupelimit')) {
+ return true;
+ } else if ($notice->content == $content) {
+ return false;
+ }
+ }
+ }
+ # If we get here, oldest item in cache window is not
+ # old enough for dupe limit; do direct check against DB
+ $notice = new Notice();
+ $notice->profile_id = $profile_id;
+ $notice->content = $content;
+ $notice->whereAdd('now() - created < ' . common_config('notice', 'dupelimit'));
+ $cnt = $notice->count();
+ return ($cnt > 0);
+ }
+
static function checkEditThrottle($profile_id) {
$profile = Profile::staticGet($profile_id);
if (!$profile) {
diff --git a/config.php.sample b/config.php.sample
index a6cada77a..c2b27408c 100644
--- a/config.php.sample
+++ b/config.php.sample
@@ -159,3 +159,9 @@ $config['sphinx']['port'] = 3312;
# Add Google Analytics
# require_once('plugins/GoogleAnalyticsPlugin.php');
# $ga = new GoogleAnalyticsPlugin('your secret code');
+
+#Don't allow saying the same thing more than once per hour
+#$config['site']['dupelimit'] = 3600;
+#Don't enforce the dupe limit
+#$config['site']['dupelimit'] = -1;
+
diff --git a/lib/common.php b/lib/common.php
index 0355d01e3..917fdeafa 100644
--- a/lib/common.php
+++ b/lib/common.php
@@ -85,7 +85,8 @@ $config =
'broughtbyurl' => null,
'closed' => false,
'inviteonly' => false,
- 'private' => false),
+ 'private' => false,
+ 'dupelimit' => 60), # default for same person saying the same thing
'syslog' =>
array('appname' => 'laconica', # for syslog
'priority' => 'debug'), # XXX: currently ignored