]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - classes/Notice.php
Return redirect code correctly as HTTP status, not a header. Fixes ticket #1371
[quix0rs-gnu-social.git] / classes / Notice.php
index 907239b084bf43027c1d95d8f8016d66c886ffc3..44a6aeb986914b4ab6c6c8ccc8987d2a67443329 100644 (file)
@@ -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,36 @@ 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;
+        if (common_config('db','type') == 'pgsql')
+            $notice->whereAdd('extract(epoch from now() - created) < ' . common_config('site', 'dupelimit'));
+        else
+            $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit'));
+
+        $cnt = $notice->count();
+        return ($cnt == 0);
+    }
+
     static function checkEditThrottle($profile_id) {
         $profile = Profile::staticGet($profile_id);
         if (!$profile) {
@@ -762,4 +799,98 @@ class Notice extends Memcached_DataObject
             }
         }
     }
+
+    function asAtomEntry($namespace=false, $source=false)
+    {
+        $profile = $this->getProfile();
+
+        $xs = new XMLStringer(true);
+
+        if ($namespace) {
+            $attrs = array('xmlns' => 'http://www.w3.org/2005/Atom',
+                           'xmlns:thr' => 'http://purl.org/syndication/thread/1.0');
+        } else {
+            $attrs = array();
+        }
+
+        $xs->elementStart('entry', $attrs);
+
+        if ($source) {
+            $xs->elementStart('source');
+            $xs->element('title', null, $profile->nickname . " - " . common_config('site', 'name'));
+            $xs->element('link', array('href' => $profile->profileurl));
+            $user = User::staticGet('id', $profile->id);
+            if (!empty($user)) {
+                $atom_feed = common_local_url('api',
+                                              array('apiaction' => 'statuses',
+                                                    'method' => 'user_timeline',
+                                                    'argument' => $profile->nickname.'.atom'));
+                $xs->element('link', array('rel' => 'self',
+                                           'type' => 'application/atom+xml',
+                                           'href' => $profile->profileurl));
+                $xs->element('link', array('rel' => 'license',
+                                           'href' => common_config('license', 'url')));
+            }
+
+            $xs->element('icon', null, $profile->avatarUrl(AVATAR_PROFILE_SIZE));
+        }
+
+        $xs->elementStart('author');
+        $xs->element('name', null, $profile->nickname);
+        $xs->element('uri', null, $profile->profileurl);
+        $xs->elementEnd('author');
+
+        if ($source) {
+            $xs->elementEnd('source');
+        }
+
+        $xs->element('title', null, $this->content);
+        $xs->element('summary', null, $this->content);
+
+        $xs->element('link', array('rel' => 'alternate',
+                                   'href' => $this->bestUrl()));
+
+        $xs->element('id', null, $this->uri);
+
+        $xs->element('published', null, common_date_w3dtf($this->created));
+        $xs->element('updated', null, common_date_w3dtf($this->modified));
+
+        if ($this->reply_to) {
+            $reply_notice = Notice::staticGet('id', $this->reply_to);
+            if (!empty($reply_notice)) {
+                $xs->element('link', array('rel' => 'related',
+                                           'href' => $reply_notice->bestUrl()));
+                $xs->element('thr:in-reply-to',
+                             array('ref' => $reply_notice->uri,
+                                   'href' => $reply_notice->bestUrl()));
+            }
+        }
+
+        $xs->element('content', array('type' => 'html'), $this->rendered);
+
+        $tag = new Notice_tag();
+        $tag->notice_id = $this->id;
+        if ($tag->find()) {
+            while ($tag->fetch()) {
+                $xs->element('category', array('term' => $tag->tag));
+            }
+        }
+        $tag->free();
+
+        $xs->elementEnd('entry');
+
+        return $xs->getString();
+    }
+
+    function bestUrl()
+    {
+        if (!empty($this->url)) {
+            return $this->url;
+        } else if (!empty($this->uri) && preg_match('/^https?:/', $this->uri)) {
+            return $this->uri;
+        } else {
+            return common_local_url('shownotice',
+                                    array('notice' => $this->id));
+        }
+    }
 }