Avoid ordering just by a timestamp
Try to also employ an id when possible. Involves reworking some of the indices.
This commit is contained in:
parent
ae4f3176b1
commit
a0f72fe5c6
|
@ -122,20 +122,19 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||||
{
|
{
|
||||||
$group = new User_group();
|
$group = new User_group();
|
||||||
|
|
||||||
$offset = intval($this->page - 1) * intval($this->count);
|
$group->selectAdd();
|
||||||
$limit = intval($this->count);
|
$group->selectAdd('user_group.*');
|
||||||
|
$group->joinAdd(['id', 'local_group:group_id']);
|
||||||
|
$group->orderBy('user_group.created DESC, user_group.id DESC');
|
||||||
|
|
||||||
$group->query(
|
$offset = ((int) $this->page - 1) * (int) $this->count;
|
||||||
'SELECT user_group.* '.
|
$group->limit($offset, $this->count);
|
||||||
'FROM user_group INNER JOIN local_group ' .
|
|
||||||
'ON user_group.id = local_group.group_id '.
|
|
||||||
'ORDER BY created DESC ' .
|
|
||||||
'LIMIT ' . $limit . ' OFFSET ' . $offset
|
|
||||||
);
|
|
||||||
|
|
||||||
$groups = array();
|
$groups = [];
|
||||||
|
if ($group->find()) {
|
||||||
while ($group->fetch()) {
|
while ($group->fetch()) {
|
||||||
$groups[] = clone($group);
|
$groups[] = clone $group;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $groups;
|
return $groups;
|
||||||
|
|
|
@ -1,36 +1,31 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
|
||||||
*
|
|
||||||
* Latest groups information
|
* Latest groups information
|
||||||
*
|
*
|
||||||
* 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 Personal
|
* @category Personal
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @author Sarven Capadisli <csarven@status.net>
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
* @copyright 2008-2009 StatusNet, Inc.
|
* @copyright 2008-2009 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
defined('GNUSOCIAL') || die();
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR . '/lib/groups/grouplist.php';
|
require_once INSTALLDIR . '/lib/groups/grouplist.php';
|
||||||
|
|
||||||
|
@ -40,47 +35,47 @@ require_once INSTALLDIR . '/lib/groups/grouplist.php';
|
||||||
* Show the latest groups on the site
|
* Show the latest groups on the site
|
||||||
*
|
*
|
||||||
* @category Personal
|
* @category Personal
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @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
|
* @copyright 2008-2009 StatusNet, Inc.
|
||||||
* @link http://status.net/
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
class GroupsAction extends Action
|
class GroupsAction extends Action
|
||||||
{
|
{
|
||||||
var $page = null;
|
public $page = null;
|
||||||
var $profile = null;
|
public $profile = null;
|
||||||
|
|
||||||
function isReadOnly($args)
|
public function isReadOnly($args)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function title()
|
public function title()
|
||||||
{
|
{
|
||||||
if ($this->page == 1) {
|
if ($this->page == 1) {
|
||||||
// TRANS: Title for first page of the groups list.
|
// TRANS: Title for first page of the groups list.
|
||||||
return _m('TITLE',"Groups");
|
return _m('TITLE', 'Groups');
|
||||||
} else {
|
} else {
|
||||||
// TRANS: Title for all but the first page of the groups list.
|
// TRANS: Title for all but the first page of the groups list.
|
||||||
// TRANS: %d is the page number.
|
// TRANS: %d is the page number.
|
||||||
return sprintf(_m('TITLE',"Groups, page %d"), $this->page);
|
return sprintf(_m('TITLE', 'Groups, page %d'), $this->page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepare(array $args = array())
|
public function prepare(array $args = [])
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
parent::handle();
|
parent::handle();
|
||||||
$this->showPage();
|
$this->showPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPageNotice()
|
public function showPageNotice()
|
||||||
{
|
{
|
||||||
$notice =
|
$notice =
|
||||||
// TRANS: Page notice of group list. %%%%site.name%%%% is the StatusNet site name,
|
// TRANS: Page notice of group list. %%%%site.name%%%% is the StatusNet site name,
|
||||||
|
@ -97,39 +92,45 @@ class GroupsAction extends Action
|
||||||
$this->elementEnd('div');
|
$this->elementEnd('div');
|
||||||
}
|
}
|
||||||
|
|
||||||
function showContent()
|
public function showContent()
|
||||||
{
|
{
|
||||||
if (common_logged_in()) {
|
if (common_logged_in()) {
|
||||||
$this->elementStart('p', array('id' => 'new_group'));
|
$this->elementStart('p', ['id' => 'new_group']);
|
||||||
$this->element('a', array('href' => common_local_url('newgroup'),
|
$this->element(
|
||||||
'class' => 'more'),
|
'a',
|
||||||
|
[
|
||||||
|
'href' => common_local_url('newgroup'),
|
||||||
|
'class' => 'more',
|
||||||
|
],
|
||||||
// TRANS: Link to create a new group on the group list page.
|
// TRANS: Link to create a new group on the group list page.
|
||||||
_('Create a new group'));
|
_('Create a new group')
|
||||||
|
);
|
||||||
$this->elementEnd('p');
|
$this->elementEnd('p');
|
||||||
}
|
}
|
||||||
|
|
||||||
$offset = ($this->page-1) * GROUPS_PER_PAGE;
|
$offset = ($this->page-1) * GROUPS_PER_PAGE;
|
||||||
$limit = GROUPS_PER_PAGE + 1;
|
$limit = GROUPS_PER_PAGE + 1;
|
||||||
|
|
||||||
$qry = 'SELECT user_group.* '.
|
|
||||||
'from user_group join local_group on user_group.id = local_group.group_id '.
|
|
||||||
'order by user_group.created desc '.
|
|
||||||
'limit ' . $limit . ' offset ' . $offset;
|
|
||||||
|
|
||||||
$groups = new User_group();
|
$groups = new User_group();
|
||||||
|
$groups->selectAdd();
|
||||||
$cnt = 0;
|
$groups->selectAdd('user_group.*');
|
||||||
|
$groups->joinAdd(['id', 'local_group:group_id']);
|
||||||
$groups->query($qry);
|
$groups->orderBy('user_group.created DESC, user_group.id DESC');
|
||||||
|
$groups->limit($offset, $limit);
|
||||||
|
$groups->find();
|
||||||
|
|
||||||
$gl = new GroupList($groups, null, $this);
|
$gl = new GroupList($groups, null, $this);
|
||||||
$cnt = $gl->show();
|
$cnt = $gl->show();
|
||||||
|
|
||||||
$this->pagination($this->page > 1, $cnt > GROUPS_PER_PAGE,
|
$this->pagination(
|
||||||
$this->page, 'groups');
|
$this->page > 1,
|
||||||
|
$cnt > GROUPS_PER_PAGE,
|
||||||
|
$this->page,
|
||||||
|
'groups'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSections()
|
public function showSections()
|
||||||
{
|
{
|
||||||
$gbp = new GroupsByPostsSection($this);
|
$gbp = new GroupsByPostsSection($this);
|
||||||
$gbp->show();
|
$gbp->show();
|
||||||
|
|
|
@ -32,6 +32,7 @@ defined('GNUSOCIAL') || die();
|
||||||
* @category Settings
|
* @category Settings
|
||||||
* @package GNUsocial
|
* @package GNUsocial
|
||||||
* @author Zach Copley <zach@status.net>
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2008-2009 StatusNet, Inc.
|
||||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*
|
*
|
||||||
* @see SettingsAction
|
* @see SettingsAction
|
||||||
|
@ -79,7 +80,7 @@ class OauthappssettingsAction extends SettingsAction
|
||||||
$application->owner = $this->scoped->getID();
|
$application->owner = $this->scoped->getID();
|
||||||
$application->whereAdd("name <> 'anonymous'");
|
$application->whereAdd("name <> 'anonymous'");
|
||||||
$application->limit($offset, $limit);
|
$application->limit($offset, $limit);
|
||||||
$application->orderBy('created DESC');
|
$application->orderBy('created DESC, id DESC');
|
||||||
$application->find();
|
$application->find();
|
||||||
|
|
||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
|
|
|
@ -112,13 +112,13 @@ class PeopletagAction extends Action
|
||||||
|
|
||||||
$ptags = new Profile_list();
|
$ptags = new Profile_list();
|
||||||
$ptags->tag = $this->tag;
|
$ptags->tag = $this->tag;
|
||||||
|
$ptags->orderBy('profile_list.modified DESC, profile_list.tagged DESC');
|
||||||
|
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
|
||||||
if (empty($user)) {
|
if (empty($user)) {
|
||||||
$ckey = sprintf('profile_list:tag:%s', $this->tag);
|
$ckey = sprintf('profile_list:tag:%s', $this->tag);
|
||||||
$ptags->private = false;
|
$ptags->private = false;
|
||||||
$ptags->orderBy('profile_list.modified DESC');
|
|
||||||
|
|
||||||
$c = Cache::instance();
|
$c = Cache::instance();
|
||||||
if ($offset+$limit <= PEOPLETAG_CACHE_WINDOW && !empty($c)) {
|
if ($offset+$limit <= PEOPLETAG_CACHE_WINDOW && !empty($c)) {
|
||||||
|
@ -146,7 +146,6 @@ class PeopletagAction extends Action
|
||||||
$user->getID()
|
$user->getID()
|
||||||
));
|
));
|
||||||
|
|
||||||
$ptags->orderBy('profile_list.modified DESC');
|
|
||||||
$ptags->find();
|
$ptags->find();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,8 @@ class SelftagAction extends Action
|
||||||
{
|
{
|
||||||
$profile = new Profile();
|
$profile = new Profile();
|
||||||
|
|
||||||
$profile->_join .= "\n" . <<<'END'
|
$profile->joinAdd(['id', 'profile_list:tagger']);
|
||||||
INNER JOIN profile_list ON profile.id = profile_list.tagger
|
$profile->joinAdd(['id', 'profile_role:profile_id'], 'LEFT');
|
||||||
LEFT JOIN profile_role ON profile.id = profile_role.profile_id
|
|
||||||
END;
|
|
||||||
|
|
||||||
$profile->whereAdd(sprintf(
|
$profile->whereAdd(sprintf(
|
||||||
"profile_list.tag = '%s'",
|
"profile_list.tag = '%s'",
|
||||||
|
@ -113,7 +111,7 @@ class SelftagAction extends Action
|
||||||
$profile->whereAdd('profile_list.private IS NOT TRUE');
|
$profile->whereAdd('profile_list.private IS NOT TRUE');
|
||||||
}
|
}
|
||||||
|
|
||||||
$profile->orderBy('profile_list.modified DESC');
|
$profile->orderBy('profile_list.modified DESC, profile_list.id DESC');
|
||||||
|
|
||||||
$offset = ($this->page - 1) * PROFILES_PER_PAGE;
|
$offset = ($this->page - 1) * PROFILES_PER_PAGE;
|
||||||
$limit = PROFILES_PER_PAGE + 1;
|
$limit = PROFILES_PER_PAGE + 1;
|
||||||
|
|
|
@ -56,9 +56,8 @@ class Group_member extends Managed_DataObject
|
||||||
'group_member_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
|
'group_member_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'group_member_created_idx' => array('created'),
|
'group_member_profile_id_created_group_id_idx' => array('profile_id', 'created', 'group_id'),
|
||||||
'group_member_profile_id_created_idx' => array('profile_id', 'created'),
|
'group_member_group_id_created_profile_id_idx' => array('profile_id', 'created', 'group_id'),
|
||||||
'group_member_group_id_created_idx' => array('group_id', 'created'),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -160,7 +159,7 @@ class Group_member extends Managed_DataObject
|
||||||
|
|
||||||
$membership->profile_id = $memberId;
|
$membership->profile_id = $memberId;
|
||||||
|
|
||||||
$membership->orderBy('created DESC');
|
$membership->orderBy('created DESC, group_id DESC');
|
||||||
|
|
||||||
$membership->limit($offset, $limit);
|
$membership->limit($offset, $limit);
|
||||||
|
|
||||||
|
|
|
@ -1414,7 +1414,8 @@ class Notice extends Managed_DataObject
|
||||||
if (empty($this->reply_to)) {
|
if (empty($this->reply_to)) {
|
||||||
$root = new Notice;
|
$root = new Notice;
|
||||||
$root->conversation = $this->conversation;
|
$root->conversation = $this->conversation;
|
||||||
$root->orderBy('notice.created ASC');
|
$root->orderBy('created, id');
|
||||||
|
$root->limit(0, 1);
|
||||||
$root->find(true); // true means "fetch first result"
|
$root->find(true); // true means "fetch first result"
|
||||||
$root->free();
|
$root->free();
|
||||||
return $root;
|
return $root;
|
||||||
|
|
|
@ -61,7 +61,7 @@ class Profile extends Managed_DataObject
|
||||||
),
|
),
|
||||||
'primary key' => array('id'),
|
'primary key' => array('id'),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'profile_nickname_idx' => array('nickname'),
|
'profile_nickname_created_id_idx' => array('nickname', 'created', 'id'),
|
||||||
),
|
),
|
||||||
'fulltext indexes' => array(
|
'fulltext indexes' => array(
|
||||||
'profile_fulltext_idx' => array('nickname', 'fullname', 'location', 'bio', 'homepage'),
|
'profile_fulltext_idx' => array('nickname', 'fullname', 'location', 'bio', 'homepage'),
|
||||||
|
@ -333,7 +333,7 @@ class Profile extends Managed_DataObject
|
||||||
$gm = new Group_member();
|
$gm = new Group_member();
|
||||||
|
|
||||||
$gm->profile_id = $this->id;
|
$gm->profile_id = $this->id;
|
||||||
$gm->orderBy('created DESC');
|
$gm->orderBy('created DESC, group_id DESC');
|
||||||
|
|
||||||
if ($gm->find()) {
|
if ($gm->find()) {
|
||||||
while ($gm->fetch()) {
|
while ($gm->fetch()) {
|
||||||
|
@ -518,7 +518,7 @@ class Profile extends Managed_DataObject
|
||||||
$qry .= 'AND cursor < ' . $upto . ' ';
|
$qry .= 'AND cursor < ' . $upto . ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
$qry .= 'ORDER BY profile_tag.modified DESC ';
|
$qry .= 'ORDER BY profile_tag.modified DESC, profile_tag.tagged DESC ';
|
||||||
|
|
||||||
if ($offset >= 0 && !is_null($limit)) {
|
if ($offset >= 0 && !is_null($limit)) {
|
||||||
$qry .= sprintf('LIMIT %d OFFSET %d ', $limit, $offset);
|
$qry .= sprintf('LIMIT %d OFFSET %d ', $limit, $offset);
|
||||||
|
@ -569,7 +569,6 @@ class Profile extends Managed_DataObject
|
||||||
public function getTagSubscriptions(int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
|
public function getTagSubscriptions(int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
|
||||||
{
|
{
|
||||||
$lists = new Profile_list();
|
$lists = new Profile_list();
|
||||||
$subs = new Profile_tag_subscription();
|
|
||||||
|
|
||||||
$lists->joinAdd(['id', 'profile_tag_subscription:profile_tag_id']);
|
$lists->joinAdd(['id', 'profile_tag_subscription:profile_tag_id']);
|
||||||
|
|
||||||
|
@ -597,7 +596,7 @@ class Profile extends Managed_DataObject
|
||||||
$lists->limit($offset, $limit);
|
$lists->limit($offset, $limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
$lists->orderBy('profile_tag_subscription.created DESC');
|
$lists->orderBy('profile_tag_subscription.created DESC, profile_list.id DESC');
|
||||||
$lists->find();
|
$lists->find();
|
||||||
|
|
||||||
return $lists;
|
return $lists;
|
||||||
|
@ -676,46 +675,52 @@ class Profile extends Managed_DataObject
|
||||||
|
|
||||||
public function getTaggedSubscribers($tag, $offset = 0, $limit = null)
|
public function getTaggedSubscribers($tag, $offset = 0, $limit = null)
|
||||||
{
|
{
|
||||||
$qry =
|
$profile = new Profile();
|
||||||
'SELECT profile.* ' .
|
|
||||||
'FROM profile JOIN subscription ' .
|
$qry = <<<END
|
||||||
'ON profile.id = subscription.subscriber ' .
|
SELECT profile.*
|
||||||
'JOIN profile_tag ON (profile_tag.tagged = subscription.subscriber ' .
|
FROM profile
|
||||||
'AND profile_tag.tagger = subscription.subscribed) ' .
|
INNER JOIN subscription ON profile.id = subscription.subscriber
|
||||||
'WHERE subscription.subscribed = %d ' .
|
INNER JOIN profile_tag
|
||||||
"AND profile_tag.tag = '%s' " .
|
ON profile_tag.tagged = subscription.subscriber
|
||||||
'AND subscription.subscribed <> subscription.subscriber ' .
|
AND profile_tag.tagger = subscription.subscribed
|
||||||
'ORDER BY subscription.created DESC ';
|
WHERE subscription.subscribed = {$this->getID()}
|
||||||
|
AND profile_tag.tag = '{$profile->escape($tag)}'
|
||||||
|
AND subscription.subscribed <> subscription.subscriber
|
||||||
|
ORDER BY subscription.created DESC, subscription.subscriber DESC
|
||||||
|
END;
|
||||||
|
|
||||||
if ($offset) {
|
if ($offset) {
|
||||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
$profile = new Profile();
|
$cnt = $profile->query($qry);
|
||||||
|
|
||||||
$cnt = $profile->query(sprintf($qry, $this->id, $profile->escape($tag)));
|
|
||||||
|
|
||||||
return $profile;
|
return $profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTaggedSubscriptions($tag, $offset = 0, $limit = null)
|
public function getTaggedSubscriptions($tag, $offset = 0, $limit = null)
|
||||||
{
|
{
|
||||||
$qry =
|
|
||||||
'SELECT profile.* ' .
|
|
||||||
'FROM profile JOIN subscription ' .
|
|
||||||
'ON profile.id = subscription.subscribed ' .
|
|
||||||
'JOIN profile_tag on (profile_tag.tagged = subscription.subscribed ' .
|
|
||||||
'AND profile_tag.tagger = subscription.subscriber) ' .
|
|
||||||
'WHERE subscription.subscriber = %d ' .
|
|
||||||
"AND profile_tag.tag = '%s' " .
|
|
||||||
'AND subscription.subscribed <> subscription.subscriber ' .
|
|
||||||
'ORDER BY subscription.created DESC ';
|
|
||||||
|
|
||||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
|
||||||
|
|
||||||
$profile = new Profile();
|
$profile = new Profile();
|
||||||
|
|
||||||
$profile->query(sprintf($qry, $this->id, $profile->escape($tag)));
|
$qry = <<<END
|
||||||
|
SELECT profile.*
|
||||||
|
FROM profile
|
||||||
|
INNER JOIN subscription ON profile.id = subscription.subscribed
|
||||||
|
INNER JOIN profile_tag
|
||||||
|
ON profile_tag.tagged = subscription.subscribed
|
||||||
|
AND profile_tag.tagger = subscription.subscriber
|
||||||
|
WHERE subscription.subscriber = {$this->getID()}
|
||||||
|
AND profile_tag.tag = '{$profile->escape($tag)}'
|
||||||
|
AND subscription.subscribed <> subscription.subscriber
|
||||||
|
ORDER BY subscription.created DESC, subscription.subscribed DESC
|
||||||
|
END;
|
||||||
|
|
||||||
|
if ($offset) {
|
||||||
|
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile->query($qry);
|
||||||
|
|
||||||
return $profile;
|
return $profile;
|
||||||
}
|
}
|
||||||
|
@ -734,7 +739,9 @@ class Profile extends Managed_DataObject
|
||||||
$subqueue->joinAdd(array('id', 'subscription_queue:subscriber'));
|
$subqueue->joinAdd(array('id', 'subscription_queue:subscriber'));
|
||||||
$subqueue->whereAdd(sprintf('subscription_queue.subscribed = %d', $this->getID()));
|
$subqueue->whereAdd(sprintf('subscription_queue.subscribed = %d', $this->getID()));
|
||||||
$subqueue->limit($offset, $limit);
|
$subqueue->limit($offset, $limit);
|
||||||
$subqueue->orderBy('subscription_queue.created', 'DESC');
|
$subqueue->orderBy(
|
||||||
|
'subscription_queue.created DESC, subscription_queue.subscriber DESC'
|
||||||
|
);
|
||||||
if (!$subqueue->find()) {
|
if (!$subqueue->find()) {
|
||||||
throw new NoResultException($subqueue);
|
throw new NoResultException($subqueue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ class Profile_list extends Managed_DataObject
|
||||||
'profile_list_tagger_fkey' => array('profile', array('tagger' => 'id')),
|
'profile_list_tagger_fkey' => array('profile', array('tagger' => 'id')),
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'profile_list_modified_idx' => array('modified'),
|
'profile_list_modified_id_idx' => array('modified', 'id'),
|
||||||
'profile_list_tag_idx' => array('tag'),
|
'profile_list_tag_idx' => array('tag'),
|
||||||
'profile_list_tagged_count_idx' => array('tagged_count'),
|
'profile_list_tagged_count_idx' => array('tagged_count'),
|
||||||
'profile_list_subscriber_count_idx' => array('subscriber_count'),
|
'profile_list_subscriber_count_idx' => array('subscriber_count'),
|
||||||
|
@ -225,11 +225,11 @@ class Profile_list extends Managed_DataObject
|
||||||
$subs->whereAdd('cursor <= ' . $upto);
|
$subs->whereAdd('cursor <= ' . $upto);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($limit != null) {
|
if (!is_null($limit)) {
|
||||||
$subs->limit($offset, $limit);
|
$subs->limit($offset, $limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
$subs->orderBy('profile_tag_subscription.created DESC');
|
$subs->orderBy('profile_tag_subscription.created DESC, profile.id DESC');
|
||||||
$subs->find();
|
$subs->find();
|
||||||
|
|
||||||
return $subs;
|
return $subs;
|
||||||
|
@ -327,11 +327,11 @@ class Profile_list extends Managed_DataObject
|
||||||
$tagged->whereAdd('cursor <= ' . $upto);
|
$tagged->whereAdd('cursor <= ' . $upto);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($limit != null) {
|
if (!is_null($limit)) {
|
||||||
$tagged->limit($offset, $limit);
|
$tagged->limit($offset, $limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
$tagged->orderBy('profile_tag.modified DESC');
|
$tagged->orderBy('profile_tag.modified DESC, profile_tag.tagged DESC');
|
||||||
$tagged->find();
|
$tagged->find();
|
||||||
|
|
||||||
return $tagged;
|
return $tagged;
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Profile_tag extends Managed_DataObject
|
||||||
'profile_tag_tagged_fkey' => array('profile', array('tagged' => 'id')),
|
'profile_tag_tagged_fkey' => array('profile', array('tagged' => 'id')),
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'profile_tag_modified_idx' => array('modified'),
|
'profile_tag_modified_tagged_idx' => array('modified', 'tagged'),
|
||||||
'profile_tag_tagger_tag_idx' => array('tagger', 'tag'),
|
'profile_tag_tagger_tag_idx' => array('tagger', 'tag'),
|
||||||
'profile_tag_tagged_idx' => array('tagged'),
|
'profile_tag_tagged_idx' => array('tagged'),
|
||||||
),
|
),
|
||||||
|
|
|
@ -50,9 +50,7 @@ class Profile_tag_subscription extends Managed_DataObject
|
||||||
'profile_tag_subscription_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
|
'profile_tag_subscription_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
// @fixme probably we want a (profile_id, created) index here?
|
'profile_tag_subscription_profile_id_created_profile_tag_id_idx' => array('profile_id', 'created', 'profile_tag_id'),
|
||||||
'profile_tag_subscription_profile_id_idx' => array('profile_id'),
|
|
||||||
'profile_tag_subscription_created_idx' => array('created'),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Queue_item extends Managed_DataObject
|
||||||
),
|
),
|
||||||
'primary key' => array('id'),
|
'primary key' => array('id'),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'queue_item_created_idx' => array('created'),
|
'queue_item_created_id_idx' => array('created', 'id'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ class Queue_item extends Managed_DataObject
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$qi->whereAdd('claimed IS NULL');
|
$qi->whereAdd('claimed IS NULL');
|
||||||
$qi->orderBy('created');
|
$qi->orderBy('created, id');
|
||||||
|
|
||||||
$qi->limit(1);
|
$qi->limit(1);
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,8 @@ class Subscription extends Managed_DataObject
|
||||||
'subscription_uri_key' => array('uri'),
|
'subscription_uri_key' => array('uri'),
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'subscription_subscriber_created_idx' => array('subscriber', 'created'),
|
'subscription_subscriber_created_subscribed_idx' => array('subscriber', 'created', 'subscribed'),
|
||||||
'subscription_subscribed_created_idx' => array('subscribed', 'created'),
|
'subscription_subscribed_created_subscriber_idx' => array('subscribed', 'created', 'subscriber'),
|
||||||
'subscription_token_idx' => array('token'),
|
'subscription_token_idx' => array('token'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -407,7 +407,7 @@ class Subscription extends Managed_DataObject
|
||||||
$sub->$by_type = $profile_id;
|
$sub->$by_type = $profile_id;
|
||||||
$sub->selectAdd($get_type);
|
$sub->selectAdd($get_type);
|
||||||
$sub->whereAdd($get_type . ' <> ' . $profile_id);
|
$sub->whereAdd($get_type . ' <> ' . $profile_id);
|
||||||
$sub->orderBy('created DESC');
|
$sub->orderBy("created DESC, {$get_type} DESC");
|
||||||
$sub->limit($queryoffset, $querylimit);
|
$sub->limit($queryoffset, $querylimit);
|
||||||
|
|
||||||
if (!$sub->find()) {
|
if (!$sub->find()) {
|
||||||
|
|
|
@ -103,7 +103,7 @@ class User extends Managed_DataObject
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'user_carrier_idx' => array('carrier'),
|
'user_carrier_idx' => array('carrier'),
|
||||||
'user_created_idx' => array('created'),
|
'user_created_id_idx' => array('created', 'id'),
|
||||||
'user_smsemail_idx' => array('smsemail'),
|
'user_smsemail_idx' => array('smsemail'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -734,7 +734,7 @@ class User extends Managed_DataObject
|
||||||
|
|
||||||
$pr = new Profile_role();
|
$pr = new Profile_role();
|
||||||
$pr->role = Profile_role::OWNER;
|
$pr->role = Profile_role::OWNER;
|
||||||
$pr->orderBy('created');
|
$pr->orderBy('created, profile_id');
|
||||||
$pr->limit(1);
|
$pr->limit(1);
|
||||||
|
|
||||||
if (!$pr->find(true)) {
|
if (!$pr->find(true)) {
|
||||||
|
@ -839,21 +839,23 @@ class User extends Managed_DataObject
|
||||||
*/
|
*/
|
||||||
public function getConnectedApps($offset = 0, $limit = null)
|
public function getConnectedApps($offset = 0, $limit = null)
|
||||||
{
|
{
|
||||||
$qry =
|
|
||||||
'SELECT u.* ' .
|
|
||||||
'FROM oauth_application_user AS u, oauth_application AS a ' .
|
|
||||||
'WHERE u.profile_id = %d ' .
|
|
||||||
'AND a.id = u.application_id ' .
|
|
||||||
'AND u.access_type > 0 ' .
|
|
||||||
'ORDER BY u.created DESC ';
|
|
||||||
|
|
||||||
if ($offset > 0) {
|
|
||||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
$apps = new Oauth_application_user();
|
$apps = new Oauth_application_user();
|
||||||
|
|
||||||
$cnt = $apps->query(sprintf($qry, $this->id));
|
$apps->selectAdd();
|
||||||
|
$apps->selectAdd('oauth_application_user.*');
|
||||||
|
|
||||||
|
$apps->joinAdd(['application_id', 'oauth_application:id']);
|
||||||
|
|
||||||
|
$apps->profile_id = $this->getID();
|
||||||
|
$apps->whereAdd('oauth_application_user.access_type > 0');
|
||||||
|
|
||||||
|
$apps->orderBy('oauth_application_user.created DESC, oauth_application.id DESC');
|
||||||
|
|
||||||
|
if ($offset > 0) {
|
||||||
|
$apps->limit($offset, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
$apps->find();
|
||||||
|
|
||||||
return $apps;
|
return $apps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,7 @@ class User_group extends Managed_DataObject
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'user_group_nickname_idx' => array('nickname'),
|
'user_group_nickname_idx' => array('nickname'),
|
||||||
|
'user_group_created_id_idx' => array('created', 'id'),
|
||||||
'user_group_profile_id_idx' => array('profile_id'), //make this unique in future
|
'user_group_profile_id_idx' => array('profile_id'), //make this unique in future
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -202,7 +203,7 @@ class User_group extends Managed_DataObject
|
||||||
|
|
||||||
$gm->group_id = $this->id;
|
$gm->group_id = $this->id;
|
||||||
|
|
||||||
$gm->orderBy('created DESC');
|
$gm->orderBy('created DESC, profile_id DESC');
|
||||||
|
|
||||||
if (!is_null($limit)) {
|
if (!is_null($limit)) {
|
||||||
$gm->limit($offset, $limit);
|
$gm->limit($offset, $limit);
|
||||||
|
@ -304,7 +305,7 @@ class User_group extends Managed_DataObject
|
||||||
'group_member.group_id = %d AND group_member.is_admin IS TRUE',
|
'group_member.group_id = %d AND group_member.is_admin IS TRUE',
|
||||||
$this->getID()
|
$this->getID()
|
||||||
));
|
));
|
||||||
$admins->orderBy('group_member.modified ASC');
|
$admins->orderBy('group_member.modified, group_member.profile_id');
|
||||||
$admins->limit($offset, $limit);
|
$admins->limit($offset, $limit);
|
||||||
$admins->find();
|
$admins->find();
|
||||||
|
|
||||||
|
@ -317,7 +318,7 @@ class User_group extends Managed_DataObject
|
||||||
$blocked = new Profile();
|
$blocked = new Profile();
|
||||||
$blocked->joinAdd(array('id', 'group_block:blocked'));
|
$blocked->joinAdd(array('id', 'group_block:blocked'));
|
||||||
$blocked->whereAdd(sprintf('group_block.group_id = %u', $this->id));
|
$blocked->whereAdd(sprintf('group_block.group_id = %u', $this->id));
|
||||||
$blocked->orderBy('group_block.modified DESC');
|
$blocked->orderBy('group_block.modified DESC, group_block.blocked DESC');
|
||||||
$blocked->limit($offset, $limit);
|
$blocked->limit($offset, $limit);
|
||||||
$blocked->find();
|
$blocked->find();
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,29 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
* Class for activity streams
|
||||||
* Copyright (C) 2010 StatusNet, Inc.
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* @package GNUsocial
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* (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/>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
defined('GNUSOCIAL') || die();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for activity streams
|
* Class for activity streams
|
||||||
*
|
*
|
||||||
|
@ -24,6 +31,9 @@
|
||||||
*
|
*
|
||||||
* We extend atomusernoticefeed since it does some nice setup for us.
|
* We extend atomusernoticefeed since it does some nice setup for us.
|
||||||
*
|
*
|
||||||
|
* @package GNUsocial
|
||||||
|
* @copyright 2010 StatusNet, Inc.
|
||||||
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
class UserActivityStream extends AtomUserNoticeFeed
|
class UserActivityStream extends AtomUserNoticeFeed
|
||||||
{
|
{
|
||||||
|
@ -37,14 +47,18 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* @param boolean $indent
|
* @param bool $indent
|
||||||
* @param boolean $outputMode: UserActivityStream::OUTPUT_STRING to return a string,
|
* @param bool $outputMode: UserActivityStream::OUTPUT_STRING to return a string,
|
||||||
* or UserActivityStream::OUTPUT_RAW to go to raw output.
|
* or UserActivityStream::OUTPUT_RAW to go to raw output.
|
||||||
* Raw output mode will attempt to stream, keeping less
|
* Raw output mode will attempt to stream, keeping less
|
||||||
* data in memory but will leave $this->activities incomplete.
|
* data in memory but will leave $this->activities incomplete.
|
||||||
*/
|
*/
|
||||||
function __construct($user, $indent = true, $outputMode = UserActivityStream::OUTPUT_STRING, $after = null)
|
public function __construct(
|
||||||
{
|
$user,
|
||||||
|
$indent = true,
|
||||||
|
$outputMode = UserActivityStream::OUTPUT_STRING,
|
||||||
|
$after = null
|
||||||
|
) {
|
||||||
parent::__construct($user, null, $indent);
|
parent::__construct($user, null, $indent);
|
||||||
|
|
||||||
$this->outputMode = $outputMode;
|
$this->outputMode = $outputMode;
|
||||||
|
@ -102,7 +116,7 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
* Interleave the pre-sorted objects with the user's
|
* Interleave the pre-sorted objects with the user's
|
||||||
* notices, all in reverse chron order.
|
* notices, all in reverse chron order.
|
||||||
*/
|
*/
|
||||||
function renderEntries($format=Feed::ATOM, $handle=null)
|
public function renderEntries($format = Feed::ATOM, $handle = null)
|
||||||
{
|
{
|
||||||
$haveOne = false;
|
$haveOne = false;
|
||||||
|
|
||||||
|
@ -223,7 +237,7 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function compareObject($a, $b)
|
public function compareObject($a, $b)
|
||||||
{
|
{
|
||||||
$ac = strtotime((empty($a->created)) ? $a->modified : $a->created);
|
$ac = strtotime((empty($a->created)) ? $a->modified : $a->created);
|
||||||
$bc = strtotime((empty($b->created)) ? $b->modified : $b->created);
|
$bc = strtotime((empty($b->created)) ? $b->modified : $b->created);
|
||||||
|
@ -231,7 +245,7 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
return (($ac == $bc) ? 0 : (($ac < $bc) ? 1 : -1));
|
return (($ac == $bc) ? 0 : (($ac < $bc) ? 1 : -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSubscriptions()
|
public function getSubscriptions()
|
||||||
{
|
{
|
||||||
$subs = array();
|
$subs = array();
|
||||||
|
|
||||||
|
@ -254,7 +268,7 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
return $subs;
|
return $subs;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSubscribers()
|
public function getSubscribers()
|
||||||
{
|
{
|
||||||
$subs = array();
|
$subs = array();
|
||||||
|
|
||||||
|
@ -283,9 +297,9 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
* @param int $end unix timestamp for latest
|
* @param int $end unix timestamp for latest
|
||||||
* @return array of Notice objects
|
* @return array of Notice objects
|
||||||
*/
|
*/
|
||||||
function getNoticesBetween($start=0, $end=0)
|
public function getNoticesBetween($start = 0, $end = 0)
|
||||||
{
|
{
|
||||||
$notices = array();
|
$notices = [];
|
||||||
|
|
||||||
$notice = new Notice();
|
$notice = new Notice();
|
||||||
|
|
||||||
|
@ -311,7 +325,7 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
$notice->whereAdd("created < '$tsend'");
|
$notice->whereAdd("created < '$tsend'");
|
||||||
}
|
}
|
||||||
|
|
||||||
$notice->orderBy('created DESC');
|
$notice->orderBy('created DESC, id DESC');
|
||||||
|
|
||||||
if ($notice->find()) {
|
if ($notice->find()) {
|
||||||
while ($notice->fetch()) {
|
while ($notice->fetch()) {
|
||||||
|
@ -322,7 +336,7 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
return $notices;
|
return $notices;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNotices()
|
public function getNotices()
|
||||||
{
|
{
|
||||||
if (!empty($this->after)) {
|
if (!empty($this->after)) {
|
||||||
return $this->getNoticesBetween($this->after);
|
return $this->getNoticesBetween($this->after);
|
||||||
|
@ -331,7 +345,7 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGroups()
|
public function getGroups()
|
||||||
{
|
{
|
||||||
$groups = array();
|
$groups = array();
|
||||||
|
|
||||||
|
@ -352,12 +366,13 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||||
return $groups;
|
return $groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createdAfter($item) {
|
public function createdAfter($item)
|
||||||
|
{
|
||||||
$created = strtotime((empty($item->created)) ? $item->modified : $item->created);
|
$created = strtotime((empty($item->created)) ? $item->modified : $item->created);
|
||||||
return ($created >= $this->after);
|
return ($created >= $this->after);
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeJSON($handle)
|
public function writeJSON($handle)
|
||||||
{
|
{
|
||||||
require_once INSTALLDIR . '/lib/activitystreams/activitystreamjsondocument.php';
|
require_once INSTALLDIR . '/lib/activitystreams/activitystreamjsondocument.php';
|
||||||
fwrite($handle, '{"items": [');
|
fwrite($handle, '{"items": [');
|
||||||
|
|
|
@ -1,35 +1,30 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
|
||||||
*
|
|
||||||
* FIXME
|
* FIXME
|
||||||
*
|
*
|
||||||
* 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 Widget
|
* @category Widget
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2009 StatusNet, Inc.
|
* @copyright 2009 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
defined('GNUSOCIAL') || die();
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME
|
* FIXME
|
||||||
|
@ -37,38 +32,39 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
* These are the widgets that show interesting data about a person * group, or site.
|
* These are the widgets that show interesting data about a person * group, or site.
|
||||||
*
|
*
|
||||||
* @category Widget
|
* @category Widget
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @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
|
* @copyright 2009 StatusNet, Inc.
|
||||||
* @link http://status.net/
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
class AttachmentNoticeSection extends NoticeSection
|
class AttachmentNoticeSection extends NoticeSection
|
||||||
{
|
{
|
||||||
function showContent() {
|
public function showContent()
|
||||||
|
{
|
||||||
parent::showContent();
|
parent::showContent();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNotices()
|
public function getNotices()
|
||||||
{
|
{
|
||||||
$notice = new Notice;
|
$notice = new Notice;
|
||||||
|
|
||||||
$notice->joinAdd(array('id', 'file_to_post:post_id'));
|
$notice->joinAdd(array('id', 'file_to_post:post_id'));
|
||||||
$notice->whereAdd(sprintf('file_to_post.file_id = %d', $this->out->attachment->id));
|
$notice->whereAdd(sprintf('file_to_post.file_id = %d', $this->out->attachment->id));
|
||||||
|
|
||||||
$notice->orderBy('created desc');
|
$notice->selectAdd('notice.id');
|
||||||
$notice->selectAdd('post_id as id');
|
$notice->orderBy('notice.created DESC, notice.id DESC');
|
||||||
$notice->find();
|
$notice->find();
|
||||||
return $notice;
|
return $notice;
|
||||||
}
|
}
|
||||||
|
|
||||||
function title()
|
public function title()
|
||||||
{
|
{
|
||||||
// TRANS: Title.
|
// TRANS: Title.
|
||||||
return _('Notices where this attachment appears');
|
return _('Notices where this attachment appears');
|
||||||
}
|
}
|
||||||
|
|
||||||
function divId()
|
public function divId()
|
||||||
{
|
{
|
||||||
return 'attachment_section';
|
return 'attachment_section';
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,7 @@ class RawConversationNoticeStream extends NoticeStream
|
||||||
self::filterVerbs($notice, $this->selectVerbs);
|
self::filterVerbs($notice, $this->selectVerbs);
|
||||||
|
|
||||||
// ORDER BY
|
// ORDER BY
|
||||||
// currently imitates the previously used "_reverseChron" sorting
|
$notice->orderBy('notice.created DESC, notice.id DESC');
|
||||||
$notice->orderBy('notice.created DESC');
|
|
||||||
$notice->find();
|
$notice->find();
|
||||||
return $notice->fetchAll('id');
|
return $notice->fetchAll('id');
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,6 @@ class SearchEngine
|
||||||
public function set_sort_mode($mode)
|
public function set_sort_mode($mode)
|
||||||
{
|
{
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case 'chron':
|
|
||||||
return $this->target->orderBy('created DESC');
|
|
||||||
break;
|
|
||||||
case 'reverse_chron':
|
|
||||||
return $this->target->orderBy('created ASC');
|
|
||||||
break;
|
|
||||||
case 'nickname_desc':
|
case 'nickname_desc':
|
||||||
if ($this->table != 'profile') {
|
if ($this->table != 'profile') {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
@ -63,8 +57,12 @@ class SearchEngine
|
||||||
return $this->target->orderBy(sprintf('%1$s.nickname ASC', $this->table));
|
return $this->target->orderBy(sprintf('%1$s.nickname ASC', $this->table));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'reverse_chron':
|
||||||
|
return $this->target->orderBy('created, id');
|
||||||
|
break;
|
||||||
|
case 'chron':
|
||||||
default:
|
default:
|
||||||
return $this->target->orderBy('created DESC');
|
return $this->target->orderBy('created DESC, id DESC');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,19 +51,27 @@ class FeaturedUsersSection extends ProfileSection
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$quoted = array();
|
$quoted_nicks = implode(
|
||||||
|
',',
|
||||||
|
array_map(
|
||||||
|
function (string $nick): string {
|
||||||
|
return "'{$nick}'";
|
||||||
|
},
|
||||||
|
$featured_nicks
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
foreach ($featured_nicks as $nick) {
|
$user_table = common_database_tablename('user');
|
||||||
$quoted[] = "'$nick'";
|
|
||||||
}
|
|
||||||
|
|
||||||
$table = common_database_tablename('user');
|
|
||||||
$limit = PROFILES_PER_SECTION + 1;
|
$limit = PROFILES_PER_SECTION + 1;
|
||||||
|
|
||||||
$qry = 'SELECT profile.* ' .
|
$qry = <<<END
|
||||||
'FROM profile INNER JOIN ' . $table . ' ON profile.id = ' . $table . '.id ' .
|
SELECT profile.*
|
||||||
'WHERE ' . $table . '.nickname IN (' . implode(',', $quoted) . ') ' .
|
FROM profile
|
||||||
'ORDER BY profile.created DESC LIMIT ' . $limit;
|
INNER JOIN {$user_table} ON profile.id = {$user_table}.id
|
||||||
|
WHERE profile.nickname IN ({$quoted_nicks})
|
||||||
|
ORDER BY profile.created DESC, profile.id DESC
|
||||||
|
LIMIT {$limit};
|
||||||
|
END;
|
||||||
|
|
||||||
$profile = Memcached_DataObject::cachedQuery('Profile', $qry, 6 * 3600);
|
$profile = Memcached_DataObject::cachedQuery('Profile', $qry, 6 * 3600);
|
||||||
return $profile;
|
return $profile;
|
||||||
|
|
|
@ -411,6 +411,7 @@ class FavoriteModule extends ActivityVerbHandlerModule
|
||||||
if (!empty($uas->after)) {
|
if (!empty($uas->after)) {
|
||||||
$fave->whereAdd("modified > '" . common_sql_date($uas->after) . "'");
|
$fave->whereAdd("modified > '" . common_sql_date($uas->after) . "'");
|
||||||
}
|
}
|
||||||
|
$fave->orderBy('modified DESC, notice_id DESC');
|
||||||
|
|
||||||
if ($fave->find()) {
|
if ($fave->find()) {
|
||||||
while ($fave->fetch()) {
|
while ($fave->fetch()) {
|
||||||
|
|
|
@ -1,43 +1,44 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
|
||||||
*
|
|
||||||
* Show up to 100 favs of a notice
|
* Show up to 100 favs of 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 API
|
* @category API
|
||||||
* @package GNUsocial
|
* @package GNUsocial
|
||||||
* @author Hannes Mannerheim <h@nnesmannerhe.im>
|
* @author Hannes Mannerheim <h@nnesmannerhe.im>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @link http://www.gnu.org/software/social/
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
defined('GNUSOCIAL') || die();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show up to 100 favs of a notice
|
* Show up to 100 favs of a notice
|
||||||
*
|
*
|
||||||
|
* @package GNUsocial
|
||||||
|
* @author Hannes Mannerheim <h@nnesmannerhe.im>
|
||||||
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
class ApiStatusesFavsAction extends ApiAuthAction
|
class ApiStatusesFavsAction extends ApiAuthAction
|
||||||
{
|
{
|
||||||
const MAXCOUNT = 100;
|
const MAXCOUNT = 100;
|
||||||
|
|
||||||
var $original = null; // Notice object for which to retrieve favs
|
// Notice object for which to retrieve favs
|
||||||
var $cnt = self::MAXCOUNT;
|
public $original = null;
|
||||||
|
public $cnt = self::MAXCOUNT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take arguments for running
|
* Take arguments for running
|
||||||
|
@ -46,7 +47,7 @@ class ApiStatusesFavsAction extends ApiAuthAction
|
||||||
*
|
*
|
||||||
* @return boolean success flag
|
* @return boolean success flag
|
||||||
*/
|
*/
|
||||||
protected function prepare(array $args=array())
|
protected function prepare(array $args = [])
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
|
@ -91,17 +92,16 @@ class ApiStatusesFavsAction extends ApiAuthAction
|
||||||
$fave->selectAdd();
|
$fave->selectAdd();
|
||||||
$fave->selectAdd('user_id');
|
$fave->selectAdd('user_id');
|
||||||
$fave->notice_id = $this->original->id;
|
$fave->notice_id = $this->original->id;
|
||||||
$fave->orderBy('modified');
|
$fave->orderBy('modified, user_id');
|
||||||
if (!is_null($this->cnt)) {
|
if (!is_null($this->cnt)) {
|
||||||
$fave->limit(0, $this->cnt);
|
$fave->limit(0, $this->cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
$ids = $fave->fetchAll('user_id');
|
$ids = $fave->fetchAll('user_id');
|
||||||
|
|
||||||
// get nickname and profile image
|
// Get nickname and profile image.
|
||||||
$ids_with_profile_data = array();
|
$ids_with_profile_data = [];
|
||||||
$i=0;
|
foreach (array_values($ids) as $i => $id) {
|
||||||
foreach($ids as $id) {
|
|
||||||
$profile = Profile::getKV('id', $id);
|
$profile = Profile::getKV('id', $id);
|
||||||
$ids_with_profile_data[$i]['user_id'] = $id;
|
$ids_with_profile_data[$i]['user_id'] = $id;
|
||||||
$ids_with_profile_data[$i]['nickname'] = $profile->nickname;
|
$ids_with_profile_data[$i]['nickname'] = $profile->nickname;
|
||||||
|
@ -111,7 +111,6 @@ class ApiStatusesFavsAction extends ApiAuthAction
|
||||||
$profile->id = $id;
|
$profile->id = $id;
|
||||||
$avatarurl = $profile->avatarUrl(24);
|
$avatarurl = $profile->avatarUrl(24);
|
||||||
$ids_with_profile_data[$i]['avatarurl'] = $avatarurl;
|
$ids_with_profile_data[$i]['avatarurl'] = $avatarurl;
|
||||||
$i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->initDocument('json');
|
$this->initDocument('json');
|
||||||
|
@ -129,7 +128,7 @@ class ApiStatusesFavsAction extends ApiAuthAction
|
||||||
* @return boolean is read only action?
|
* @return boolean is read only action?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function isReadOnly($args)
|
public function isReadOnly($args)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,8 @@ class Fave extends Managed_DataObject
|
||||||
'fave_user_id_fkey' => array('profile', array('user_id' => 'id')), // note: formerly referenced notice.id, but we can now record remote users' favorites
|
'fave_user_id_fkey' => array('profile', array('user_id' => 'id')), // note: formerly referenced notice.id, but we can now record remote users' favorites
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'fave_user_id_modified_idx' => array('user_id', 'modified'),
|
'fave_user_id_modified_notice_id_idx' => array('user_id', 'modified', 'notice_id'),
|
||||||
'fave_modified_idx' => array('modified'),
|
'fave_notice_id_modified_user_id_idx' => array('notice_id', 'modified', 'user_id'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ class Fave extends Managed_DataObject
|
||||||
|
|
||||||
$fav->user_id = $profileId;
|
$fav->user_id = $profileId;
|
||||||
|
|
||||||
$fav->orderBy('modified DESC');
|
$fav->orderBy('modified DESC, notice_id DESC');
|
||||||
|
|
||||||
$fav->limit($offset, $limit);
|
$fav->limit($offset, $limit);
|
||||||
|
|
||||||
|
|
|
@ -88,46 +88,36 @@ class RawFaveNoticeStream extends NoticeStream
|
||||||
*/
|
*/
|
||||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||||
{
|
{
|
||||||
$fav = new Fave();
|
$fave = new Fave();
|
||||||
$qry = null;
|
|
||||||
|
|
||||||
if ($this->own) {
|
$fave->selectAdd();
|
||||||
$qry = 'SELECT fave.* FROM fave ';
|
$fave->selectAdd('fave.*');
|
||||||
$qry .= 'WHERE fave.user_id = ' . $this->user_id . ' ';
|
$fave->user_id = $this->user_id;
|
||||||
} else {
|
|
||||||
$qry = 'SELECT fave.* FROM fave ';
|
if (!$this->own) {
|
||||||
$qry .= 'INNER JOIN notice ON fave.notice_id = notice.id ';
|
$fave->joinAdd(['notice_id', 'notice:id']);
|
||||||
$qry .= 'WHERE fave.user_id = ' . $this->user_id . ' ';
|
$fave->whereAdd('notice.is_local <> ' . Notice::GATEWAY);
|
||||||
$qry .= 'AND notice.is_local <> ' . Notice::GATEWAY . ' ';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($since_id != 0) {
|
Notice::addWhereSinceId($fave, $since_id, 'notice_id', 'fave.modified');
|
||||||
$qry .= 'AND notice_id > ' . $since_id . ' ';
|
Notice::addWhereMaxId($fave, $max_id, 'notice_id', 'fave.modified');
|
||||||
}
|
|
||||||
|
|
||||||
if ($max_id != 0) {
|
|
||||||
$qry .= 'AND notice_id <= ' . $max_id . ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: we sort by fave time, not by notice time!
|
// NOTE: we sort by fave time, not by notice time!
|
||||||
|
$fave->orderBy('fave.modified DESC, notice_id DESC');
|
||||||
$qry .= 'ORDER BY modified DESC ';
|
|
||||||
|
|
||||||
if (!is_null($offset)) {
|
if (!is_null($offset)) {
|
||||||
$qry .= "LIMIT $limit OFFSET $offset";
|
$fave->limit($offset, $limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
$fav->query($qry);
|
$ids = [];
|
||||||
|
if ($fave->find()) {
|
||||||
$ids = array();
|
while ($fave->fetch()) {
|
||||||
|
$ids[] = $fave->notice_id;
|
||||||
while ($fav->fetch()) {
|
}
|
||||||
$ids[] = $fav->notice_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$fav->free();
|
$fave->free();
|
||||||
unset($fav);
|
unset($fave);
|
||||||
|
|
||||||
return $ids;
|
return $ids;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,19 +55,22 @@ class RawPopularNoticeStream extends NoticeStream
|
||||||
{
|
{
|
||||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||||
{
|
{
|
||||||
$weightexpr = common_sql_weight('modified', common_config('popular', 'dropoff'));
|
$weightexpr = common_sql_weight(
|
||||||
|
'modified',
|
||||||
|
common_config('popular', 'dropoff')
|
||||||
|
);
|
||||||
$cutoff = sprintf(
|
$cutoff = sprintf(
|
||||||
"modified > TIMESTAMP '%s'",
|
"modified > CURRENT_TIMESTAMP - INTERVAL '%d' SECOND",
|
||||||
common_sql_date(time() - common_config('popular', 'cutoff'))
|
common_config('popular', 'cutoff')
|
||||||
);
|
);
|
||||||
|
|
||||||
$fave = new Fave();
|
$fave = new Fave();
|
||||||
$fave->selectAdd();
|
$fave->selectAdd();
|
||||||
$fave->selectAdd('notice_id');
|
$fave->selectAdd('notice_id');
|
||||||
$fave->selectAdd("$weightexpr as weight");
|
$fave->selectAdd("{$weightexpr} AS weight");
|
||||||
$fave->whereAdd($cutoff);
|
$fave->whereAdd($cutoff);
|
||||||
$fave->orderBy('weight DESC');
|
|
||||||
$fave->groupBy('notice_id');
|
$fave->groupBy('notice_id');
|
||||||
|
$fave->orderBy('weight DESC');
|
||||||
|
|
||||||
if (!is_null($offset)) {
|
if (!is_null($offset)) {
|
||||||
$fave->limit($offset, $limit);
|
$fave->limit($offset, $limit);
|
||||||
|
|
|
@ -134,7 +134,7 @@ class apActorLikedAction extends ManagedAction
|
||||||
|
|
||||||
$fav->user_id = $user_id;
|
$fav->user_id = $user_id;
|
||||||
|
|
||||||
$fav->orderBy('modified DESC');
|
$fav->orderBy('modified DESC, notice_id DESC');
|
||||||
|
|
||||||
if ($since_id != null) {
|
if ($since_id != null) {
|
||||||
$fav->whereAdd("notice_id > {$since_id}");
|
$fav->whereAdd("notice_id > {$since_id}");
|
||||||
|
|
|
@ -45,7 +45,7 @@ function testAllUsers($filter, $minimum, $percent)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$user = new User();
|
$user = new User();
|
||||||
$user->orderBy('created');
|
$user->orderBy('created, id');
|
||||||
$user->limit($offset, $limit);
|
$user->limit($offset, $limit);
|
||||||
|
|
||||||
$found = $user->find();
|
$found = $user->find();
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of this file.
|
|
||||||
*
|
|
||||||
* @package GNUsocial
|
* @package GNUsocial
|
||||||
* @copyright 2012 StatusNet, Inc.
|
* @copyright 2012 StatusNet, Inc.
|
||||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
|
@ -48,7 +46,7 @@ function testAllUsers($filter)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$user = new User();
|
$user = new User();
|
||||||
$user->orderBy('created');
|
$user->orderBy('created, id');
|
||||||
$user->limit($offset, $limit);
|
$user->limit($offset, $limit);
|
||||||
|
|
||||||
$found = $user->find();
|
$found = $user->find();
|
||||||
|
|
|
@ -73,9 +73,9 @@ class Bookmark extends Managed_DataObject
|
||||||
'bookmark_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
|
'bookmark_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
|
||||||
'bookmark_uri_fkey' => array('notice', array('uri' => 'uri')),
|
'bookmark_uri_fkey' => array('notice', array('uri' => 'uri')),
|
||||||
),
|
),
|
||||||
'indexes' => array('bookmark_created_idx' => array('created'),
|
'indexes' => array(
|
||||||
'bookmark_url_idx' => array('url'),
|
'bookmark_url_idx' => array('url'),
|
||||||
'bookmark_profile_id_idx' => array('profile_id'),
|
'bookmark_profile_id_created_idx' => array('profile_id', 'created'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,32 +30,30 @@ class RawBookmarksNoticeStream extends NoticeStream
|
||||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||||
{
|
{
|
||||||
$notice = new Notice();
|
$notice = new Notice();
|
||||||
$qry = null;
|
|
||||||
|
|
||||||
$qry = 'SELECT notice.* FROM notice ';
|
$notice->selectAdd();
|
||||||
$qry .= 'INNER JOIN bookmark ON bookmark.uri = notice.uri ';
|
$notice->selectAdd('notice.*');
|
||||||
$qry .= 'WHERE bookmark.profile_id = ' . $this->user_id . ' ';
|
|
||||||
$qry .= 'AND notice.is_local <> ' . Notice::GATEWAY . ' ';
|
|
||||||
|
|
||||||
if ($since_id != 0) {
|
$notice->joinAdd(['uri', 'bookmark:uri']);
|
||||||
$qry .= 'AND notice.id > ' . $since_id . ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($max_id != 0) {
|
$notice->whereAdd(sprintf('bookmark.profile_id = %d', $this->user_id));
|
||||||
$qry .= 'AND notice.id <= ' . $max_id . ' ';
|
$notice->whereAdd('notice.is_local <> ' . Notice::GATEWAY);
|
||||||
}
|
|
||||||
|
Notice::addWhereSinceId($notice, $since_id, 'notice.id', 'bookmark.created');
|
||||||
|
Notice::addWhereMaxId($notice, $max_id, 'notice.id', 'bookmark.created');
|
||||||
|
|
||||||
// NOTE: we sort by bookmark time, not by notice time!
|
// NOTE: we sort by bookmark time, not by notice time!
|
||||||
$qry .= 'ORDER BY created DESC ';
|
$notice->orderBy('bookmark.created DESC');
|
||||||
if (!is_null($offset)) {
|
if (!is_null($offset)) {
|
||||||
$qry .= "LIMIT $limit OFFSET $offset";
|
$notice->limit($offset, $limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
$notice->query($qry);
|
$ids = [];
|
||||||
$ids = array();
|
if ($notice->find()) {
|
||||||
while ($notice->fetch()) {
|
while ($notice->fetch()) {
|
||||||
$ids[] = $notice->id;
|
$ids[] = $notice->id;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$notice->free();
|
$notice->free();
|
||||||
unset($notice);
|
unset($notice);
|
||||||
|
|
|
@ -208,7 +208,7 @@ class DirectMessagePlugin extends Plugin
|
||||||
|
|
||||||
$message->selectAdd(); // clears it
|
$message->selectAdd(); // clears it
|
||||||
$message->selectAdd('id');
|
$message->selectAdd('id');
|
||||||
$message->orderBy('created ASC');
|
$message->orderBy('created, id');
|
||||||
|
|
||||||
if ($message->find()) {
|
if ($message->find()) {
|
||||||
while ($message->fetch()) {
|
while ($message->fetch()) {
|
||||||
|
|
|
@ -82,11 +82,8 @@ class Message extends Managed_DataObject
|
||||||
'message_to_profile_fkey' => array('profile', array('to_profile' => 'id')),
|
'message_to_profile_fkey' => array('profile', array('to_profile' => 'id')),
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
// @fixme these are really terrible indexes, since you can only sort on one of them at a time.
|
'message_from_profile_created_id_idx' => array('from_profile', 'created', 'id'),
|
||||||
// looks like we really need a (to_profile, created) for inbox and a (from_profile, created) for outbox
|
'message_to_profile_created_id_idx' => array('to_profile', 'created', 'id'),
|
||||||
'message_from_profile_idx' => array('from_profile'),
|
|
||||||
'message_to_profile_idx' => array('to_profile'),
|
|
||||||
'message_created_idx' => array('created'),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,31 +21,29 @@ class RawEventsNoticeStream extends NoticeStream
|
||||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||||
{
|
{
|
||||||
$notice = new Notice();
|
$notice = new Notice();
|
||||||
$qry = null;
|
|
||||||
|
|
||||||
$qry = 'SELECT notice.* FROM notice ';
|
$notice->selectAdd();
|
||||||
$qry .= 'INNER JOIN happening ON happening.uri = notice.uri ';
|
$notice->selectAdd('notice.*');
|
||||||
$qry .= 'AND notice.is_local <> ' . Notice::GATEWAY . ' ';
|
|
||||||
|
|
||||||
if ($since_id != 0) {
|
$notice->joinAdd(['uri', 'happening:uri']);
|
||||||
$qry .= 'AND notice.id > ' . $since_id . ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($max_id != 0) {
|
$notice->whereAdd('notice.is_local <> ' . Notice::GATEWAY);
|
||||||
$qry .= 'AND notice.id <= ' . $max_id . ' ';
|
|
||||||
}
|
Notice::addWhereSinceId($notice, $since_id, 'notice.id', 'happening.created');
|
||||||
|
Notice::addWhereMaxId($notice, $max_id, 'notice.id', 'happening.created');
|
||||||
|
|
||||||
// NOTE: we sort by event time, not by notice time!
|
// NOTE: we sort by event time, not by notice time!
|
||||||
$qry .= 'ORDER BY happening.created DESC ';
|
$notice->orderBy('happening.created DESC');
|
||||||
if (!is_null($offset)) {
|
if (!is_null($offset)) {
|
||||||
$qry .= "LIMIT $limit OFFSET $offset";
|
$notice->limit($offset, $limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
$notice->query($qry);
|
$ids = [];
|
||||||
$ids = array();
|
if ($notice->find()) {
|
||||||
while ($notice->fetch()) {
|
while ($notice->fetch()) {
|
||||||
$ids[] = $notice->id;
|
$ids[] = $notice->id;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$notice->free();
|
$notice->free();
|
||||||
unset($notice);
|
unset($notice);
|
||||||
|
|
|
@ -1,35 +1,30 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data class for group direct messages
|
* Data class for group direct messages
|
||||||
*
|
*
|
||||||
* PHP version 5
|
|
||||||
*
|
|
||||||
* @category Data
|
* @category Data
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @copyright 2009 StatusNet, Inc.
|
||||||
* @link http://status.net/
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*
|
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
|
||||||
* Copyright (C) 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')) {
|
defined('GNUSOCIAL') || die();
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||||
|
|
||||||
|
@ -37,12 +32,10 @@ require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||||
* Data class for group direct messages
|
* Data class for group direct messages
|
||||||
*
|
*
|
||||||
* @category GroupPrivateMessage
|
* @category GroupPrivateMessage
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @copyright 2009 StatusNet, Inc.
|
||||||
* @link http://status.net/
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*
|
|
||||||
* @see DB_DataObject
|
|
||||||
*/
|
*/
|
||||||
class Group_message extends Managed_DataObject
|
class Group_message extends Managed_DataObject
|
||||||
{
|
{
|
||||||
|
@ -81,20 +74,22 @@ class Group_message extends Managed_DataObject
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'group_message_from_profile_idx' => array('from_profile'),
|
'group_message_from_profile_idx' => array('from_profile'),
|
||||||
'group_message_to_group_idx' => array('to_group'),
|
'group_message_to_group_created_idx' => array('to_group', 'created'),
|
||||||
'group_message_url_idx' => array('url'),
|
'group_message_url_idx' => array('url'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function send($user, $group, $text)
|
public static function send($user, $group, $text)
|
||||||
{
|
{
|
||||||
if (!$user->hasRight(Right::NEWMESSAGE)) {
|
if (!$user->hasRight(Right::NEWMESSAGE)) {
|
||||||
// XXX: maybe break this out into a separate right
|
// XXX: maybe break this out into a separate right
|
||||||
// TRANS: Exception thrown when trying to send group private message without having the right to do that.
|
// TRANS: Exception thrown when trying to send group private message without having the right to do that.
|
||||||
// TRANS: %s is a user nickname.
|
// TRANS: %s is a user nickname.
|
||||||
throw new Exception(sprintf(_m('User %s is not allowed to send private messages.'),
|
throw new Exception(sprintf(
|
||||||
$user->nickname));
|
_m('User %s is not allowed to send private messages.'),
|
||||||
|
$user->nickname
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Group_privacy_settings::ensurePost($user, $group);
|
Group_privacy_settings::ensurePost($user, $group);
|
||||||
|
@ -106,10 +101,14 @@ class Group_message extends Managed_DataObject
|
||||||
if (Message::contentTooLong($text)) {
|
if (Message::contentTooLong($text)) {
|
||||||
// TRANS: Exception thrown when trying to send group private message that is too long.
|
// TRANS: Exception thrown when trying to send group private message that is too long.
|
||||||
// TRANS: %d is the maximum meggage length.
|
// TRANS: %d is the maximum meggage length.
|
||||||
throw new Exception(sprintf(_m('That\'s too long. Maximum message size is %d character.',
|
throw new Exception(sprintf(
|
||||||
|
_m(
|
||||||
|
'That\'s too long. Maximum message size is %d character.',
|
||||||
'That\'s too long. Maximum message size is %d characters.',
|
'That\'s too long. Maximum message size is %d characters.',
|
||||||
Message::maxContent()),
|
Message::maxContent()
|
||||||
Message::maxContent()));
|
),
|
||||||
|
Message::maxContent()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid! Let's do this thing!
|
// Valid! Let's do this thing!
|
||||||
|
@ -134,7 +133,7 @@ class Group_message extends Managed_DataObject
|
||||||
return $gm;
|
return $gm;
|
||||||
}
|
}
|
||||||
|
|
||||||
function distribute()
|
public function distribute()
|
||||||
{
|
{
|
||||||
$group = User_group::getKV('id', $this->to_group);
|
$group = User_group::getKV('id', $this->to_group);
|
||||||
|
|
||||||
|
@ -145,7 +144,7 @@ class Group_message extends Managed_DataObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGroup()
|
public function getGroup()
|
||||||
{
|
{
|
||||||
$group = User_group::getKV('id', $this->to_group);
|
$group = User_group::getKV('id', $this->to_group);
|
||||||
if (empty($group)) {
|
if (empty($group)) {
|
||||||
|
@ -155,7 +154,7 @@ class Group_message extends Managed_DataObject
|
||||||
return $group;
|
return $group;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSender()
|
public function getSender()
|
||||||
{
|
{
|
||||||
$sender = Profile::getKV('id', $this->from_profile);
|
$sender = Profile::getKV('id', $this->from_profile);
|
||||||
if (empty($sender)) {
|
if (empty($sender)) {
|
||||||
|
@ -165,7 +164,7 @@ class Group_message extends Managed_DataObject
|
||||||
return $sender;
|
return $sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function forGroup($group, $offset, $limit)
|
public static function forGroup($group, $offset, $limit)
|
||||||
{
|
{
|
||||||
// XXX: cache
|
// XXX: cache
|
||||||
$gm = new Group_message();
|
$gm = new Group_message();
|
||||||
|
|
|
@ -1,34 +1,30 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
|
||||||
* Copyright (C) 2010, StatusNet, Inc.
|
|
||||||
*
|
|
||||||
* Throttle registration by IP address
|
* Throttle registration by IP address
|
||||||
*
|
*
|
||||||
* PHP version 5
|
|
||||||
*
|
|
||||||
* 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 Spam
|
* @category Spam
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2010 StatusNet, Inc.
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
defined('GNUSOCIAL') || die();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throttle registration by IP address
|
* Throttle registration by IP address
|
||||||
|
@ -36,11 +32,10 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
* We a) record IP address of registrants and b) throttle registrations.
|
* We a) record IP address of registrants and b) throttle registrations.
|
||||||
*
|
*
|
||||||
* @category Spam
|
* @category Spam
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2010 StatusNet, Inc.
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class RegisterThrottlePlugin extends Plugin
|
class RegisterThrottlePlugin extends Plugin
|
||||||
|
@ -73,7 +68,7 @@ class RegisterThrottlePlugin extends Plugin
|
||||||
/**
|
/**
|
||||||
* Whether we're enabled; prevents recursion.
|
* Whether we're enabled; prevents recursion.
|
||||||
*/
|
*/
|
||||||
static private $enabled = true;
|
private static $enabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database schema setup
|
* Database schema setup
|
||||||
|
@ -93,9 +88,11 @@ class RegisterThrottlePlugin extends Plugin
|
||||||
|
|
||||||
public function onRouterInitialized(URLMapper $m)
|
public function onRouterInitialized(URLMapper $m)
|
||||||
{
|
{
|
||||||
$m->connect('main/ipregistrations/:ipaddress',
|
$m->connect(
|
||||||
|
'main/ipregistrations/:ipaddress',
|
||||||
['action' => 'ipregistrations'],
|
['action' => 'ipregistrations'],
|
||||||
['ipaddress' => '[0-9a-f\.\:]+']);
|
['ipaddress' => '[0-9a-f\.\:]+']
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,7 +115,6 @@ class RegisterThrottlePlugin extends Plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->regLimits as $seconds => $limit) {
|
foreach ($this->regLimits as $seconds => $limit) {
|
||||||
|
|
||||||
$this->debug("Checking $seconds ($limit)");
|
$this->debug("Checking $seconds ($limit)");
|
||||||
|
|
||||||
$reg = $this->_getNthReg($ipaddress, $limit);
|
$reg = $this->_getNthReg($ipaddress, $limit);
|
||||||
|
@ -151,7 +147,7 @@ class RegisterThrottlePlugin extends Plugin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEndShowSections(Action $action)
|
public function onEndShowSections(Action $action)
|
||||||
{
|
{
|
||||||
if (!$action instanceof ShowstreamAction) {
|
if (!$action instanceof ShowstreamAction) {
|
||||||
// early return for actions we're not interested in
|
// early return for actions we're not interested in
|
||||||
|
@ -188,11 +184,17 @@ class RegisterThrottlePlugin extends Plugin
|
||||||
$attrs = ['class'=>'ipaddress'];
|
$attrs = ['class'=>'ipaddress'];
|
||||||
if (!is_null($ipaddress)) {
|
if (!is_null($ipaddress)) {
|
||||||
$el = 'a';
|
$el = 'a';
|
||||||
$attrs['href'] = common_local_url('ipregistrations', array('ipaddress'=>$ipaddress));
|
$attrs['href'] = common_local_url(
|
||||||
|
'ipregistrations',
|
||||||
|
['ipaddress' => $ipaddress]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
$action->element($el, $attrs,
|
$action->element(
|
||||||
|
$el,
|
||||||
|
$attrs,
|
||||||
// TRANS: Unknown IP address.
|
// TRANS: Unknown IP address.
|
||||||
$ipaddress ?: _('unknown'));
|
$ipaddress ?? _('unknown')
|
||||||
|
);
|
||||||
|
|
||||||
$action->elementEnd('div');
|
$action->elementEnd('div');
|
||||||
}
|
}
|
||||||
|
@ -285,7 +287,7 @@ class RegisterThrottlePlugin extends Plugin
|
||||||
|
|
||||||
$reg->ipaddress = $ipaddress;
|
$reg->ipaddress = $ipaddress;
|
||||||
|
|
||||||
$reg->orderBy('created DESC');
|
$reg->orderBy('created DESC, user_id DESC');
|
||||||
$reg->limit($n - 1, 1);
|
$reg->limit($n - 1, 1);
|
||||||
|
|
||||||
if ($reg->find(true)) {
|
if ($reg->find(true)) {
|
||||||
|
|
|
@ -1,42 +1,39 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data class for storing IP addresses of new registrants.
|
* Data class for storing IP addresses of new registrants.
|
||||||
*
|
*
|
||||||
* PHP version 5
|
|
||||||
*
|
|
||||||
* @category Data
|
* @category Data
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @link http://status.net/
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*
|
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
|
||||||
* Copyright (C) 2010, 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('GNUSOCIAL')) { exit(1); }
|
defined('GNUSOCIAL') || die();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data class for storing IP addresses of new registrants.
|
* Data class for storing IP addresses of new registrants.
|
||||||
*
|
*
|
||||||
* @category Spam
|
* @category Spam
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @link http://status.net/
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
class Registration_ip extends Managed_DataObject
|
class Registration_ip extends Managed_DataObject
|
||||||
{
|
{
|
||||||
|
@ -60,8 +57,7 @@ class Registration_ip extends Managed_DataObject
|
||||||
'registration_ip_user_id_fkey' => array('user', array('user_id' => 'id')),
|
'registration_ip_user_id_fkey' => array('user', array('user_id' => 'id')),
|
||||||
),
|
),
|
||||||
'indexes' => array(
|
'indexes' => array(
|
||||||
'registration_ip_ipaddress_idx' => array('ipaddress'),
|
'registration_ip_ipaddress_created_idx' => array('ipaddress', 'created'),
|
||||||
'registration_ip_created_idx' => array('created'),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +69,7 @@ class Registration_ip extends Managed_DataObject
|
||||||
*
|
*
|
||||||
* @return Array IDs of users who registered with this address.
|
* @return Array IDs of users who registered with this address.
|
||||||
*/
|
*/
|
||||||
static function usersByIP($ipaddress)
|
public static function usersByIP($ipaddress)
|
||||||
{
|
{
|
||||||
$ids = array();
|
$ids = array();
|
||||||
|
|
||||||
|
|
|
@ -1,51 +1,46 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
|
||||||
*
|
|
||||||
* Show list of user pages
|
* Show list of user pages
|
||||||
*
|
*
|
||||||
* 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 Sitemap
|
* @category Sitemap
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2010 StatusNet, Inc.
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET')) {
|
defined('GNUSOCIAL') || die();
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sitemap for users
|
* sitemap for users
|
||||||
*
|
*
|
||||||
* @category Sitemap
|
* @category Sitemap
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @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
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @link http://status.net/
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
class NoticesitemapAction extends SitemapAction
|
class NoticesitemapAction extends SitemapAction
|
||||||
{
|
{
|
||||||
var $notices = null;
|
public $notices = null;
|
||||||
var $j = 0;
|
public $j = 0;
|
||||||
|
|
||||||
function prepare(array $args = array())
|
public function prepare(array $args = [])
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
|
@ -67,7 +62,7 @@ class NoticesitemapAction extends SitemapAction
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextUrl()
|
public function nextUrl()
|
||||||
{
|
{
|
||||||
if ($this->j < count($this->notices)) {
|
if ($this->j < count($this->notices)) {
|
||||||
$n = $this->notices[$this->j];
|
$n = $this->notices[$this->j];
|
||||||
|
@ -81,12 +76,11 @@ class NoticesitemapAction extends SitemapAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNotices($y, $m, $d, $i)
|
public function getNotices($y, $m, $d, $i)
|
||||||
{
|
{
|
||||||
$n = Notice::cacheGet("sitemap:notice:$y:$m:$d:$i");
|
$n = Notice::cacheGet("sitemap:notice:{$y}:{$m}:{$d}:{$i}");
|
||||||
|
|
||||||
if ($n === false) {
|
if ($n === false) {
|
||||||
|
|
||||||
$notice = new Notice();
|
$notice = new Notice();
|
||||||
|
|
||||||
$begindt = sprintf('%04d-%02d-%02d 00:00:00', $y, $m, $d);
|
$begindt = sprintf('%04d-%02d-%02d 00:00:00', $y, $m, $d);
|
||||||
|
@ -106,7 +100,7 @@ class NoticesitemapAction extends SitemapAction
|
||||||
|
|
||||||
$notice->whereAdd('is_local = ' . Notice::LOCAL_PUBLIC);
|
$notice->whereAdd('is_local = ' . Notice::LOCAL_PUBLIC);
|
||||||
|
|
||||||
$notice->orderBy('created');
|
$notice->orderBy('created, id');
|
||||||
|
|
||||||
$offset = ($i-1) * SitemapPlugin::NOTICES_PER_MAP;
|
$offset = ($i-1) * SitemapPlugin::NOTICES_PER_MAP;
|
||||||
$limit = SitemapPlugin::NOTICES_PER_MAP;
|
$limit = SitemapPlugin::NOTICES_PER_MAP;
|
||||||
|
@ -124,10 +118,12 @@ class NoticesitemapAction extends SitemapAction
|
||||||
$c = Cache::instance();
|
$c = Cache::instance();
|
||||||
|
|
||||||
if (!empty($c)) {
|
if (!empty($c)) {
|
||||||
$c->set(Cache::key("sitemap:notice:$y:$m:$d:$i"),
|
$c->set(
|
||||||
|
Cache::key("sitemap:notice:$y:$m:$d:$i"),
|
||||||
$n,
|
$n,
|
||||||
Cache::COMPRESSED,
|
Cache::COMPRESSED,
|
||||||
((time() > $theend) ? (time() + 90 * 24 * 60 * 60) : (time() + 5 * 60)));
|
((time() > $theend) ? (time() + 90 * 24 * 60 * 60) : (time() + 5 * 60))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,51 +1,46 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
|
||||||
*
|
|
||||||
* Show list of user pages
|
* Show list of user pages
|
||||||
*
|
*
|
||||||
* 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 Sitemap
|
* @category Sitemap
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2010 StatusNet, Inc.
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET')) {
|
defined('GNUSOCIAL') || die();
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sitemap for users
|
* sitemap for users
|
||||||
*
|
*
|
||||||
* @category Sitemap
|
* @category Sitemap
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @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
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @link http://status.net/
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
class UsersitemapAction extends SitemapAction
|
class UsersitemapAction extends SitemapAction
|
||||||
{
|
{
|
||||||
var $users = null;
|
public $users = null;
|
||||||
var $j = 0;
|
public $j = 0;
|
||||||
|
|
||||||
function prepare(array $args = array())
|
public function prepare(array $args = [])
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
|
@ -66,7 +61,7 @@ class UsersitemapAction extends SitemapAction
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextUrl()
|
public function nextUrl()
|
||||||
{
|
{
|
||||||
if ($this->j < count($this->users)) {
|
if ($this->j < count($this->users)) {
|
||||||
$nickname = $this->users[$this->j];
|
$nickname = $this->users[$this->j];
|
||||||
|
@ -77,12 +72,11 @@ class UsersitemapAction extends SitemapAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsers($y, $m, $d, $i)
|
public function getUsers($y, $m, $d, $i)
|
||||||
{
|
{
|
||||||
$u = User::cacheGet("sitemap:user:$y:$m:$d:$i");
|
$u = User::cacheGet("sitemap:user:$y:$m:$d:$i");
|
||||||
|
|
||||||
if ($u === false) {
|
if ($u === false) {
|
||||||
|
|
||||||
$user = new User();
|
$user = new User();
|
||||||
|
|
||||||
$begindt = sprintf('%04d-%02d-%02d 00:00:00', $y, $m, $d);
|
$begindt = sprintf('%04d-%02d-%02d 00:00:00', $y, $m, $d);
|
||||||
|
@ -99,7 +93,7 @@ class UsersitemapAction extends SitemapAction
|
||||||
$user->whereAdd("created >= '$begindt'");
|
$user->whereAdd("created >= '$begindt'");
|
||||||
$user->whereAdd("created < '$enddt'");
|
$user->whereAdd("created < '$enddt'");
|
||||||
|
|
||||||
$user->orderBy('created');
|
$user->orderBy('created, id');
|
||||||
|
|
||||||
$offset = ($i-1) * SitemapPlugin::USERS_PER_MAP;
|
$offset = ($i-1) * SitemapPlugin::USERS_PER_MAP;
|
||||||
$limit = SitemapPlugin::USERS_PER_MAP;
|
$limit = SitemapPlugin::USERS_PER_MAP;
|
||||||
|
@ -115,10 +109,12 @@ class UsersitemapAction extends SitemapAction
|
||||||
$c = Cache::instance();
|
$c = Cache::instance();
|
||||||
|
|
||||||
if (!empty($c)) {
|
if (!empty($c)) {
|
||||||
$c->set(Cache::key("sitemap:user:$y:$m:$d:$i"),
|
$c->set(
|
||||||
|
Cache::key("sitemap:user:{$y}:{$m}:{$d}:{$i}"),
|
||||||
$u,
|
$u,
|
||||||
Cache::COMPRESSED,
|
Cache::COMPRESSED,
|
||||||
((time() > $theend) ? (time() + 90 * 24 * 60 * 60) : (time() + 5 * 60)));
|
((time() > $theend) ? (time() + 90 * 24 * 60 * 60) : (time() + 5 * 60))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,58 +1,46 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
|
||||||
* Copyright (C) 2010, StatusNet, Inc.
|
|
||||||
*
|
|
||||||
* Plugin to throttle subscriptions by a user
|
* Plugin to throttle subscriptions by a user
|
||||||
*
|
*
|
||||||
* PHP version 5
|
|
||||||
*
|
|
||||||
* 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 Throttle
|
* @category Throttle
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2010 StatusNet, Inc.
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET')) {
|
defined('GNUSOCIAL') || die();
|
||||||
// This check helps protect against security problems;
|
|
||||||
// your code file can't be executed directly from the web.
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscription throttle
|
* Subscription throttle
|
||||||
*
|
*
|
||||||
* @category Throttle
|
* @category Throttle
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2010 StatusNet, Inc.
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
*/
|
||||||
class SubscriptionThrottlePlugin extends Plugin
|
class SubscriptionThrottlePlugin extends Plugin
|
||||||
{
|
{
|
||||||
const PLUGIN_VERSION = '2.0.0';
|
const PLUGIN_VERSION = '2.0.0';
|
||||||
|
|
||||||
public $subLimits = array(86400 => 100,
|
public $subLimits = [86400 => 100, 3600 => 50];
|
||||||
3600 => 50);
|
public $groupLimits = [86400 => 50, 3600 => 25];
|
||||||
|
|
||||||
public $groupLimits = array(86400 => 50,
|
|
||||||
3600 => 25);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter subscriptions to see if they're coming too fast.
|
* Filter subscriptions to see if they're coming too fast.
|
||||||
|
@ -62,7 +50,7 @@ class SubscriptionThrottlePlugin extends Plugin
|
||||||
*
|
*
|
||||||
* @return boolean hook value
|
* @return boolean hook value
|
||||||
*/
|
*/
|
||||||
function onStartSubscribe(Profile $profile, $other)
|
public function onStartSubscribe(Profile $profile, $other)
|
||||||
{
|
{
|
||||||
foreach ($this->subLimits as $seconds => $limit) {
|
foreach ($this->subLimits as $seconds => $limit) {
|
||||||
$sub = $this->_getNthSub($profile, $limit);
|
$sub = $this->_getNthSub($profile, $limit);
|
||||||
|
@ -88,12 +76,11 @@ class SubscriptionThrottlePlugin extends Plugin
|
||||||
*
|
*
|
||||||
* @return boolean hook value
|
* @return boolean hook value
|
||||||
*/
|
*/
|
||||||
function onStartJoinGroup($group, $profile)
|
public function onStartJoinGroup($group, $profile)
|
||||||
{
|
{
|
||||||
foreach ($this->groupLimits as $seconds => $limit) {
|
foreach ($this->groupLimits as $seconds => $limit) {
|
||||||
$mem = $this->_getNthMem($profile, $limit);
|
$mem = $this->_getNthMem($profile, $limit);
|
||||||
if (!empty($mem)) {
|
if (!empty($mem)) {
|
||||||
|
|
||||||
$jointime = strtotime($mem->created);
|
$jointime = strtotime($mem->created);
|
||||||
$now = time();
|
$now = time();
|
||||||
if ($now - $jointime < $seconds) {
|
if ($now - $jointime < $seconds) {
|
||||||
|
@ -142,7 +129,7 @@ class SubscriptionThrottlePlugin extends Plugin
|
||||||
$mem = new Group_member();
|
$mem = new Group_member();
|
||||||
|
|
||||||
$mem->profile_id = $profile->id;
|
$mem->profile_id = $profile->id;
|
||||||
$mem->orderBy('created DESC');
|
$mem->orderBy('created DESC, group_id DESC');
|
||||||
$mem->limit($n - 1, 1);
|
$mem->limit($n - 1, 1);
|
||||||
|
|
||||||
if ($mem->find(true)) {
|
if ($mem->find(true)) {
|
||||||
|
|
|
@ -1,47 +1,39 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social 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.
|
||||||
|
//
|
||||||
|
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show latest and greatest profile flags
|
* Show latest and greatest profile flags
|
||||||
*
|
*
|
||||||
* PHP version 5
|
|
||||||
*
|
|
||||||
* @category Action
|
* @category Action
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
*
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
*
|
|
||||||
* @see http://status.net/
|
|
||||||
*
|
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
|
||||||
* Copyright (C) 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);
|
defined('GNUSOCIAL') || die();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the latest and greatest profile flags
|
* Show the latest and greatest profile flags
|
||||||
*
|
*
|
||||||
* @category Action
|
* @category Action
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
*
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @copyright 2009 StatusNet, Inc.
|
||||||
*
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @see http://status.net/
|
|
||||||
*/
|
*/
|
||||||
class AdminprofileflagAction extends Action
|
class AdminprofileflagAction extends Action
|
||||||
{
|
{
|
||||||
|
@ -139,8 +131,12 @@ class AdminprofileflagAction extends Action
|
||||||
|
|
||||||
$cnt = $pl->show();
|
$cnt = $pl->show();
|
||||||
|
|
||||||
$this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
|
$this->pagination(
|
||||||
$this->page, 'adminprofileflag');
|
$this->page > 1,
|
||||||
|
$cnt > PROFILES_PER_PAGE,
|
||||||
|
$this->page,
|
||||||
|
'adminprofileflag'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,12 +185,10 @@ class AdminprofileflagAction extends Action
|
||||||
* Most of the hard part is done in FlaggedProfileListItem.
|
* Most of the hard part is done in FlaggedProfileListItem.
|
||||||
*
|
*
|
||||||
* @category Widget
|
* @category Widget
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
*
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @copyright 2009 StatusNet, Inc.
|
||||||
*
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @see http://status.net/
|
|
||||||
*/
|
*/
|
||||||
class FlaggedProfileList extends ProfileList
|
class FlaggedProfileList extends ProfileList
|
||||||
{
|
{
|
||||||
|
@ -215,12 +209,10 @@ class FlaggedProfileList extends ProfileList
|
||||||
* Specialization of ProfileListItem to show flagging information
|
* Specialization of ProfileListItem to show flagging information
|
||||||
*
|
*
|
||||||
* @category Widget
|
* @category Widget
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
*
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @copyright 2009 StatusNet, Inc.
|
||||||
*
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
* @see http://status.net/
|
|
||||||
*/
|
*/
|
||||||
class FlaggedProfileListItem extends ProfileListItem
|
class FlaggedProfileListItem extends ProfileListItem
|
||||||
{
|
{
|
||||||
|
@ -354,7 +346,7 @@ class FlaggedProfileListItem extends ProfileListItem
|
||||||
$ufp->selectAdd();
|
$ufp->selectAdd();
|
||||||
$ufp->selectAdd('user_id');
|
$ufp->selectAdd('user_id');
|
||||||
$ufp->profile_id = $this->profile->id;
|
$ufp->profile_id = $this->profile->id;
|
||||||
$ufp->orderBy('created');
|
$ufp->orderBy('created, user_id');
|
||||||
|
|
||||||
if ($ufp->find()) { // XXX: this should always happen
|
if ($ufp->find()) { // XXX: this should always happen
|
||||||
while ($ufp->fetch()) {
|
while ($ufp->fetch()) {
|
||||||
|
@ -376,12 +368,16 @@ class FlaggedProfileListItem extends ProfileListItem
|
||||||
$lnks = [];
|
$lnks = [];
|
||||||
|
|
||||||
foreach ($flaggers as $flagger) {
|
foreach ($flaggers as $flagger) {
|
||||||
$url = common_local_url('showstream',
|
$url = common_local_url(
|
||||||
['nickname' => $flagger->nickname]);
|
'showstream',
|
||||||
|
['nickname' => $flagger->nickname]
|
||||||
|
);
|
||||||
|
|
||||||
$lnks[] = XMLStringer::estring('a', ['href' => $url,
|
$lnks[] = XMLStringer::estring(
|
||||||
'class' => 'flagger', ],
|
'a',
|
||||||
$flagger->nickname);
|
['href' => $url, 'class' => 'flagger'],
|
||||||
|
$flagger->nickname
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cnt > 0) {
|
if ($cnt > 0) {
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
*
|
*
|
||||||
* @category Data
|
* @category Data
|
||||||
* @package GNUsocial
|
* @package GNUsocial
|
||||||
*
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2009 StatusNet, Inc.
|
* @copyright 2009 StatusNet, Inc.
|
||||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('GNUSOCIAL') || die();
|
defined('GNUSOCIAL') || die();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,7 +33,6 @@ defined('GNUSOCIAL') || die();
|
||||||
*
|
*
|
||||||
* @category Action
|
* @category Action
|
||||||
* @package GNUsocial
|
* @package GNUsocial
|
||||||
*
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @copyright 2009 StatusNet, Inc.
|
* @copyright 2009 StatusNet, Inc.
|
||||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
|
@ -65,8 +64,8 @@ class User_flag_profile extends Managed_DataObject
|
||||||
],
|
],
|
||||||
'primary key' => ['profile_id', 'user_id'],
|
'primary key' => ['profile_id', 'user_id'],
|
||||||
'indexes' => [
|
'indexes' => [
|
||||||
'user_flag_profile_cleared_idx' => ['cleared'],
|
'user_flag_profile_cleared_profile_id_idx' => ['cleared', 'profile_id'],
|
||||||
'user_flag_profile_created_idx' => ['created'],
|
'user_flag_profile_profile_id_created_user_id_idx' => ['profile_id', 'created', 'user_id'],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user