Merge branch 'pgsql_support' into nightly
This commit is contained in:
commit
8f309bc768
@ -164,10 +164,9 @@ The ones that you may want to set are listed below for clarity.
|
||||
|
||||
* `database` (string, required, default null): a DSN (Data Source Name) for your
|
||||
GNU social database. This is in the format
|
||||
'protocol://username:password@hostname/databasename', where 'protocol' is '
|
||||
mysql' or 'mysqli' (or possibly 'postgresql', if you really know what
|
||||
you're doing), 'username' is the username, 'password' is the password,
|
||||
and etc.
|
||||
'protocol://username:password@hostname/databasename', where 'protocol' is
|
||||
'mysqli' or 'pgsql' or 'mysql', 'username' is the username, 'password' is
|
||||
the password, and etc.
|
||||
|
||||
* `ini_yourdbname` (string, default null): if your database is not named 'statusnet',
|
||||
you'll need to set this to point to the location of the statusnet.ini file.
|
||||
@ -178,12 +177,9 @@ The ones that you may want to set are listed below for clarity.
|
||||
'MDB2' to use the other driver type for DB_DataObject, but note that it
|
||||
breaks the OpenID libraries, which only support PEAR::DB.
|
||||
|
||||
* `quote_identifiers`(boolean, default false): Set this to true if you're using
|
||||
postgresql.
|
||||
|
||||
* `type` (enum["mysql", "postgresql"], default 'mysql'): Used for certain
|
||||
database-specific optimization code. Assumes mysql if not set. MySQL also
|
||||
covers MySQLi and MariaDB.
|
||||
* `type` (enum["mysql", "pgsql"], default 'mysql'): Used for certain
|
||||
database-specific optimization code. Assumes mysql if not set. "mysql"
|
||||
covers MariaDB, Oracle MySQL, mysqli or otherwise.
|
||||
|
||||
* `mirror` (array, default null): you can set this to an array of DSNs, in the
|
||||
format of the above 'database' value. If it's set, certain read-only
|
||||
|
@ -1,55 +1,45 @@
|
||||
<?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 the newest groups
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Returns of the lastest 20 groups for the site
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
{
|
||||
var $groups = null;
|
||||
public $groups = null;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
@ -58,7 +48,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare(array $args = array())
|
||||
public function prepare(array $args = [])
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -77,7 +67,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle()
|
||||
public function handle()
|
||||
{
|
||||
parent::handle();
|
||||
|
||||
@ -90,7 +80,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
// TRANS: Message is used as a subtitle when listing the latest 20 groups. %s is a site name.
|
||||
$subtitle = sprintf(_("groups on %s"), $sitename);
|
||||
|
||||
switch($this->format) {
|
||||
switch ($this->format) {
|
||||
case 'xml':
|
||||
$this->showXmlGroups($this->groups);
|
||||
break;
|
||||
@ -128,21 +118,20 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return array groups
|
||||
*/
|
||||
function getGroups()
|
||||
public function getGroups()
|
||||
{
|
||||
$qry = 'SELECT user_group.* '.
|
||||
'from user_group join local_group on user_group.id = local_group.group_id '.
|
||||
'order by created desc ';
|
||||
$offset = intval($this->page - 1) * intval($this->count);
|
||||
$limit = intval($this->count);
|
||||
if (common_config('db', 'type') == 'pgsql') {
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
$group = new User_group();
|
||||
|
||||
$group->query($qry);
|
||||
$offset = intval($this->page - 1) * intval($this->count);
|
||||
$limit = intval($this->count);
|
||||
|
||||
$group->query(
|
||||
'SELECT user_group.* '.
|
||||
'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();
|
||||
while ($group->fetch()) {
|
||||
@ -159,7 +148,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
public function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -169,7 +158,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string datestamp of the site's latest group
|
||||
*/
|
||||
function lastModified()
|
||||
public function lastModified()
|
||||
{
|
||||
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||
return strtotime($this->groups[0]->created);
|
||||
@ -186,10 +175,9 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
function etag()
|
||||
public function etag()
|
||||
{
|
||||
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||
|
||||
$last = count($this->groups) - 1;
|
||||
|
||||
return '"' . implode(
|
||||
|
@ -1,48 +1,40 @@
|
||||
<?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
|
||||
*
|
||||
* Settings for email
|
||||
*
|
||||
* 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 Settings
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Settings for email
|
||||
*
|
||||
* @category Settings
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see Widget
|
||||
*/
|
||||
|
||||
class EmailsettingsAction extends SettingsAction
|
||||
{
|
||||
/**
|
||||
@ -50,7 +42,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return string Title of the page
|
||||
*/
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Title for e-mail settings.
|
||||
return _('Email settings');
|
||||
@ -61,7 +53,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return instructions for use
|
||||
*/
|
||||
function getInstructions()
|
||||
public function getInstructions()
|
||||
{
|
||||
// XXX: For consistency of parameters in messages, this should be a
|
||||
// regular parameters, replaced with sprintf().
|
||||
@ -70,7 +62,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
return _('Manage how you get email from %%site.name%%.');
|
||||
}
|
||||
|
||||
function showScripts()
|
||||
public function showScripts()
|
||||
{
|
||||
parent::showScripts();
|
||||
$this->script('emailsettings.js');
|
||||
@ -85,7 +77,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showContent()
|
||||
public function showContent()
|
||||
{
|
||||
$user = $this->scoped->getUser();
|
||||
|
||||
@ -106,50 +98,58 @@ class EmailsettingsAction extends SettingsAction
|
||||
$this->element('p', array('class' => 'form_note'), _('Current confirmed email address.'));
|
||||
$this->hidden('email', $user->email);
|
||||
// TRANS: Button label to remove a confirmed e-mail address.
|
||||
$this->submit('remove', _m('BUTTON','Remove'));
|
||||
$this->submit('remove', _m('BUTTON', 'Remove'));
|
||||
} else {
|
||||
try {
|
||||
$confirm = $this->getConfirmation();
|
||||
$this->element('p', array('id' => 'form_unconfirmed'), $confirm->address);
|
||||
$this->element('p', array('class' => 'form_note'),
|
||||
// TRANS: Form note in e-mail settings form.
|
||||
_('Awaiting confirmation on this address. '.
|
||||
'Check your inbox (and spam box!) for a message '.
|
||||
'with further instructions.'));
|
||||
$this->element(
|
||||
'p',
|
||||
['class' => 'form_note'],
|
||||
// TRANS: Form note in e-mail settings form.
|
||||
_('Awaiting confirmation on this address. '.
|
||||
'Check your inbox (and spam box!) for a message '.
|
||||
'with further instructions.')
|
||||
);
|
||||
$this->hidden('email', $confirm->address);
|
||||
// TRANS: Button label to cancel an e-mail address confirmation procedure.
|
||||
$this->submit('cancel', _m('BUTTON','Cancel'));
|
||||
$this->submit('cancel', _m('BUTTON', 'Cancel'));
|
||||
} catch (NoResultException $e) {
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for e-mail address input in e-mail settings form.
|
||||
$this->input('email', _('Email address'),
|
||||
$this->trimmed('email') ?: null,
|
||||
// TRANS: Instructions for e-mail address input form. Do not translate
|
||||
// TRANS: "example.org". It is one of the domain names reserved for
|
||||
// TRANS: use in examples by http://www.rfc-editor.org/rfc/rfc2606.txt.
|
||||
// TRANS: Any other domain may be owned by a legitimate person or
|
||||
// TRANS: organization.
|
||||
_('Email address, like "UserName@example.org"'));
|
||||
$this->input(
|
||||
'email',
|
||||
_('Email address'),
|
||||
$this->trimmed('email') ?: null,
|
||||
// TRANS: Instructions for e-mail address input form. Do not translate
|
||||
// TRANS: "example.org". It is one of the domain names reserved for
|
||||
// TRANS: use in examples by http://www.rfc-editor.org/rfc/rfc2606.txt.
|
||||
// TRANS: Any other domain may be owned by a legitimate person or
|
||||
// TRANS: organization.
|
||||
_('Email address, like "UserName@example.org"')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
// TRANS: Button label for adding an e-mail address in e-mail settings form.
|
||||
$this->submit('add', _m('BUTTON','Add'));
|
||||
$this->submit('add', _m('BUTTON', 'Add'));
|
||||
}
|
||||
}
|
||||
$this->elementEnd('fieldset');
|
||||
|
||||
if (common_config('emailpost', 'enabled') && $user->email) {
|
||||
if (common_config('emailpost', 'enabled') && $user->email) {
|
||||
$this->elementStart('fieldset', array('id' => 'settings_email_incoming'));
|
||||
// TRANS: Form legend for incoming e-mail settings form.
|
||||
$this->element('legend', null, _('Incoming email'));
|
||||
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailpost',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('I want to post notices by email.'),
|
||||
$user->emailpost);
|
||||
$this->checkbox(
|
||||
'emailpost',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('I want to post notices by email.'),
|
||||
$user->emailpost
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
|
||||
@ -168,12 +168,15 @@ class EmailsettingsAction extends SettingsAction
|
||||
$this->element('span', 'address', $user->incomingemail);
|
||||
// @todo XXX: Looks a little awkward in the UI.
|
||||
// Something like "xxxx@identi.ca Send email ..". Needs improvement.
|
||||
$this->element('span', 'input_instructions',
|
||||
// TRANS: Form instructions for incoming e-mail form in e-mail settings.
|
||||
_('Send email to this address to post new notices.'));
|
||||
$this->element(
|
||||
'span',
|
||||
'input_instructions',
|
||||
// TRANS: Form instructions for incoming e-mail form in e-mail settings.
|
||||
_('Send email to this address to post new notices.')
|
||||
);
|
||||
$this->elementEnd('p');
|
||||
// TRANS: Button label for removing a set sender e-mail address to post notices from.
|
||||
$this->submit('removeincoming', _m('BUTTON','Remove'));
|
||||
$this->submit('removeincoming', _m('BUTTON', 'Remove'));
|
||||
}
|
||||
|
||||
$this->elementStart('p');
|
||||
@ -189,7 +192,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
$this->elementEnd('p');
|
||||
|
||||
// TRANS: Button label for adding an e-mail address to send notices from.
|
||||
$this->submit('newincoming', _m('BUTTON','New'));
|
||||
$this->submit('newincoming', _m('BUTTON', 'New'));
|
||||
|
||||
$this->elementEnd('div'); // div#emailincoming
|
||||
|
||||
@ -204,34 +207,42 @@ class EmailsettingsAction extends SettingsAction
|
||||
|
||||
if (Event::handle('StartEmailFormData', array($this, $this->scoped))) {
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifysub',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me notices of new subscriptions through email.'),
|
||||
$user->emailnotifysub);
|
||||
$this->checkbox(
|
||||
'emailnotifysub',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me notices of new subscriptions through email.'),
|
||||
$user->emailnotifysub
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifymsg',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone sends me a private message.'),
|
||||
$user->emailnotifymsg);
|
||||
$this->checkbox(
|
||||
'emailnotifymsg',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone sends me a private message.'),
|
||||
$user->emailnotifymsg
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifyattn',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone sends me an "@-reply".'),
|
||||
$user->emailnotifyattn);
|
||||
$this->checkbox(
|
||||
'emailnotifyattn',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone sends me an "@-reply".'),
|
||||
$user->emailnotifyattn
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifynudge',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Allow friends to nudge me and send me an email.'),
|
||||
$user->emailnotifynudge);
|
||||
$this->checkbox(
|
||||
'emailnotifynudge',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Allow friends to nudge me and send me an email.'),
|
||||
$user->emailnotifynudge
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
Event::handle('EndEmailFormData', array($this, $this->scoped));
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
// TRANS: Button label to save e-mail preferences.
|
||||
$this->submit('save', _m('BUTTON','Save'));
|
||||
$this->submit('save', _m('BUTTON', 'Save'));
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
@ -242,7 +253,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return Confirm_address Email address confirmation for user, or null
|
||||
*/
|
||||
function getConfirmation()
|
||||
public function getConfirmation()
|
||||
{
|
||||
$confirm = new Confirm_address();
|
||||
|
||||
@ -260,15 +271,15 @@ class EmailsettingsAction extends SettingsAction
|
||||
{
|
||||
if ($this->arg('save')) {
|
||||
return $this->savePreferences();
|
||||
} else if ($this->arg('add')) {
|
||||
} elseif ($this->arg('add')) {
|
||||
return $this->addAddress();
|
||||
} else if ($this->arg('cancel')) {
|
||||
} elseif ($this->arg('cancel')) {
|
||||
return $this->cancelConfirmation();
|
||||
} else if ($this->arg('remove')) {
|
||||
} elseif ($this->arg('remove')) {
|
||||
return $this->removeAddress();
|
||||
} else if ($this->arg('removeincoming')) {
|
||||
} elseif ($this->arg('removeincoming')) {
|
||||
return $this->removeIncoming();
|
||||
} else if ($this->arg('newincoming')) {
|
||||
} elseif ($this->arg('newincoming')) {
|
||||
return $this->newIncoming();
|
||||
}
|
||||
|
||||
@ -281,14 +292,14 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function savePreferences()
|
||||
public function savePreferences()
|
||||
{
|
||||
if (Event::handle('StartEmailSaveForm', array($this, $this->scoped))) {
|
||||
$emailnotifysub = $this->booleanintstring('emailnotifysub');
|
||||
$emailnotifymsg = $this->booleanintstring('emailnotifymsg');
|
||||
$emailnotifynudge = $this->booleanintstring('emailnotifynudge');
|
||||
$emailnotifyattn = $this->booleanintstring('emailnotifyattn');
|
||||
$emailpost = $this->booleanintstring('emailpost');
|
||||
$emailnotifysub = $this->boolean('emailnotifysub');
|
||||
$emailnotifymsg = $this->boolean('emailnotifymsg');
|
||||
$emailnotifynudge = $this->boolean('emailnotifynudge');
|
||||
$emailnotifyattn = $this->boolean('emailnotifyattn');
|
||||
$emailpost = $this->boolean('emailpost');
|
||||
|
||||
$user = $this->scoped->getUser();
|
||||
$user->query('BEGIN');
|
||||
@ -322,7 +333,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function addAddress()
|
||||
public function addAddress()
|
||||
{
|
||||
$user = $this->scoped->getUser();
|
||||
|
||||
@ -344,16 +355,15 @@ class EmailsettingsAction extends SettingsAction
|
||||
if (!Validate::email($email, common_config('email', 'check_domain'))) {
|
||||
// TRANS: Message given saving e-mail address that not valid.
|
||||
throw new ClientException(_('Not a valid email address.'));
|
||||
} else if ($user->email == $email) {
|
||||
} elseif ($user->email === $email) {
|
||||
// TRANS: Message given saving e-mail address that is already set.
|
||||
throw new ClientException(_('That is already your email address.'));
|
||||
} else if ($this->emailExists($email)) {
|
||||
} elseif ($this->emailExists($email)) {
|
||||
// TRANS: Message given saving e-mail address that is already set for another user.
|
||||
throw new ClientException(_('That email address already belongs to another user.'));
|
||||
}
|
||||
|
||||
if (Event::handle('StartAddEmailAddress', array($user, $email))) {
|
||||
|
||||
$confirm = new Confirm_address();
|
||||
|
||||
$confirm->address = $email;
|
||||
@ -385,7 +395,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function cancelConfirmation()
|
||||
public function cancelConfirmation()
|
||||
{
|
||||
$email = $this->trimmed('email');
|
||||
|
||||
@ -411,7 +421,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function removeAddress()
|
||||
public function removeAddress()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
@ -425,7 +435,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
}
|
||||
|
||||
$original = clone($user);
|
||||
$user->email = null;
|
||||
$user->email = DB_DataObject_Cast::sql('NULL');
|
||||
// Throws exception on failure. Also performs it within a transaction.
|
||||
$user->updateWithKeys($original);
|
||||
|
||||
@ -438,7 +448,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function removeIncoming()
|
||||
public function removeIncoming()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
@ -448,8 +458,8 @@ class EmailsettingsAction extends SettingsAction
|
||||
}
|
||||
|
||||
$orig = clone($user);
|
||||
$user->incomingemail = null;
|
||||
$user->emailpost = 0;
|
||||
$user->incomingemail = DB_DataObject_Cast::sql('NULL');
|
||||
$user->emailpost = false;
|
||||
// Throws exception on failure. Also performs it within a transaction.
|
||||
$user->updateWithKeys($orig);
|
||||
|
||||
@ -462,12 +472,12 @@ class EmailsettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function newIncoming()
|
||||
public function newIncoming()
|
||||
{
|
||||
$user = common_current_user();
|
||||
$orig = clone($user);
|
||||
$user->incomingemail = mail_new_incoming_address();
|
||||
$user->emailpost = 1;
|
||||
$user->emailpost = true;
|
||||
// Throws exception on failure. Also performs it within a transaction.
|
||||
$user->updateWithKeys($orig);
|
||||
|
||||
@ -485,7 +495,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
* @return boolean Whether the email already exists.
|
||||
*/
|
||||
|
||||
function emailExists($email)
|
||||
public function emailExists($email)
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
|
@ -1,36 +1,31 @@
|
||||
<?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
|
||||
*
|
||||
* List of featured users
|
||||
*
|
||||
* 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 Public
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR . '/lib/profile/profilelist.php';
|
||||
require_once INSTALLDIR . '/lib/groups/publicgroupnav.php';
|
||||
@ -38,23 +33,19 @@ require_once INSTALLDIR . '/lib/groups/publicgroupnav.php';
|
||||
/**
|
||||
* List of featured users
|
||||
*
|
||||
* @category Public
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@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
|
||||
* @link http://status.net/
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class FeaturedAction extends Action
|
||||
{
|
||||
var $page = null;
|
||||
public $page = null;
|
||||
|
||||
function isReadOnly($args)
|
||||
public function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare(array $args = array())
|
||||
public function prepare(array $args = [])
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
@ -62,7 +53,7 @@ class FeaturedAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
if ($this->page == 1) {
|
||||
// TRANS: Page title for first page of featured users.
|
||||
@ -74,14 +65,14 @@ class FeaturedAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function handle()
|
||||
public function handle()
|
||||
{
|
||||
parent::handle();
|
||||
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
function showPageNotice()
|
||||
public function showPageNotice()
|
||||
{
|
||||
$instr = $this->getInstructions();
|
||||
$output = common_markup_to_html($instr);
|
||||
@ -90,14 +81,16 @@ class FeaturedAction extends Action
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function getInstructions()
|
||||
public function getInstructions()
|
||||
{
|
||||
// TRANS: Description on page displaying featured users.
|
||||
return sprintf(_('A selection of some great users on %s.'),
|
||||
common_config('site', 'name'));
|
||||
return sprintf(
|
||||
_('A selection of some great users on %s.'),
|
||||
common_config('site', 'name')
|
||||
);
|
||||
}
|
||||
|
||||
function showContent()
|
||||
public function showContent()
|
||||
{
|
||||
// XXX: Note I'm doing it this two-stage way because a raw query
|
||||
// with a JOIN was *not* working. --Zach
|
||||
@ -105,7 +98,6 @@ class FeaturedAction extends Action
|
||||
$featured_nicks = common_config('nickname', 'featured');
|
||||
|
||||
if (count($featured_nicks) > 0) {
|
||||
|
||||
$quoted = array();
|
||||
|
||||
foreach ($featured_nicks as $nick) {
|
||||
@ -115,7 +107,7 @@ class FeaturedAction extends Action
|
||||
$user = new User;
|
||||
$user->whereAdd(sprintf('nickname IN (%s)', implode(',', $quoted)));
|
||||
$user->limit(($this->page - 1) * PROFILES_PER_PAGE, PROFILES_PER_PAGE + 1);
|
||||
$user->orderBy(common_database_tablename('user') .'.nickname ASC');
|
||||
$user->orderBy($user->escapedTableName() . '.nickname ASC');
|
||||
|
||||
$user->find();
|
||||
|
||||
@ -138,8 +130,12 @@ class FeaturedAction extends Action
|
||||
|
||||
$profile->free();
|
||||
|
||||
$this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
|
||||
$this->page, 'featured');
|
||||
$this->pagination(
|
||||
$this->page > 1,
|
||||
$cnt > PROFILES_PER_PAGE,
|
||||
$this->page,
|
||||
'featured'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Make another user an admin of a group
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Make another user an admin of a group
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @category Action
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2008, 2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Make another user an admin of a group
|
||||
*
|
||||
* @copyright 2008, 2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class MakeadminAction extends RedirectingAction
|
||||
{
|
||||
var $profile = null;
|
||||
var $group = null;
|
||||
public $profile = null;
|
||||
public $group = null;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
@ -54,7 +45,7 @@ class MakeadminAction extends RedirectingAction
|
||||
* @return boolean success flag
|
||||
*/
|
||||
|
||||
function prepare(array $args = array())
|
||||
public function prepare(array $args = [])
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
@ -95,10 +86,14 @@ class MakeadminAction extends RedirectingAction
|
||||
if ($this->profile->isAdmin($this->group)) {
|
||||
// TRANS: Client error displayed when trying to make another user admin on the Make Admin page who already is admin.
|
||||
// TRANS: %1$s is the user that is already admin, %2$s is the group user is already admin for.
|
||||
$this->clientError(sprintf(_('%1$s is already an admin for group "%2$s".'),
|
||||
$this->profile->getBestName(),
|
||||
$this->group->getBestName()),
|
||||
401);
|
||||
$this->clientError(
|
||||
sprintf(
|
||||
_('%1$s is already an admin for group "%2$s".'),
|
||||
$this->profile->getBestName(),
|
||||
$this->group->getBestName()
|
||||
),
|
||||
401
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -111,7 +106,7 @@ class MakeadminAction extends RedirectingAction
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle()
|
||||
public function handle()
|
||||
{
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
@ -125,7 +120,7 @@ class MakeadminAction extends RedirectingAction
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function makeAdmin()
|
||||
public function makeAdmin()
|
||||
{
|
||||
$member = Group_member::pkeyGet(array('group_id' => $this->group->id,
|
||||
'profile_id' => $this->profile->id));
|
||||
@ -134,14 +129,16 @@ class MakeadminAction extends RedirectingAction
|
||||
// TRANS: Server error displayed when trying to make another user admin on the Make Admin page fails
|
||||
// TRANS: because the group membership record could not be gotten.
|
||||
// TRANS: %1$s is the to be admin user, %2$s is the group user should be admin for.
|
||||
$this->serverError(_('Can\'t get membership record for %1$s in group %2$s.'),
|
||||
$this->profile->getBestName(),
|
||||
$this->group->getBestName());
|
||||
$this->serverError(
|
||||
_('Can\'t get membership record for %1$s in group %2$s.'),
|
||||
$this->profile->getBestName(),
|
||||
$this->group->getBestName()
|
||||
);
|
||||
}
|
||||
|
||||
$orig = clone($member);
|
||||
|
||||
$member->is_admin = 1;
|
||||
$member->is_admin = true;
|
||||
|
||||
$result = $member->update($orig);
|
||||
|
||||
@ -150,9 +147,11 @@ class MakeadminAction extends RedirectingAction
|
||||
// TRANS: Server error displayed when trying to make another user admin on the Make Admin page fails
|
||||
// TRANS: because the group adminship record coud not be saved properly.
|
||||
// TRANS: %1$s is the to be admin user, %2$s is the group user is already admin for.
|
||||
$this->serverError(_('Can\'t make %1$s an admin for group %2$s.'),
|
||||
$this->profile->getBestName(),
|
||||
$this->group->getBestName());
|
||||
$this->serverError(
|
||||
_('Can\'t make %1$s an admin for group %2$s.'),
|
||||
$this->profile->getBestName(),
|
||||
$this->group->getBestName()
|
||||
);
|
||||
}
|
||||
|
||||
$this->returnToPrevious();
|
||||
@ -161,13 +160,14 @@ class MakeadminAction extends RedirectingAction
|
||||
/**
|
||||
* If we reached this form without returnto arguments, default to
|
||||
* the top of the group's member list.
|
||||
*
|
||||
*
|
||||
* @return string URL
|
||||
*/
|
||||
function defaultReturnTo()
|
||||
public function defaultReturnTo()
|
||||
{
|
||||
return common_local_url('groupmembers',
|
||||
array('nickname' => $this->group->nickname));
|
||||
return common_local_url(
|
||||
'groupmembers',
|
||||
['nickname' => $this->group->nickname]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,46 +1,38 @@
|
||||
<?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
|
||||
*
|
||||
* Change profile settings
|
||||
*
|
||||
* 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 Settings
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Change profile settings
|
||||
*
|
||||
* @category Settings
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class ProfilesettingsAction extends SettingsAction
|
||||
{
|
||||
@ -49,7 +41,7 @@ class ProfilesettingsAction extends SettingsAction
|
||||
*
|
||||
* @return string Title of the page
|
||||
*/
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Page title for profile settings.
|
||||
return _('Profile settings');
|
||||
@ -60,14 +52,14 @@ class ProfilesettingsAction extends SettingsAction
|
||||
*
|
||||
* @return instructions for use
|
||||
*/
|
||||
function getInstructions()
|
||||
public function getInstructions()
|
||||
{
|
||||
// TRANS: Usage instructions for profile settings.
|
||||
return _('You can update your personal profile info here '.
|
||||
'so people know more about you.');
|
||||
}
|
||||
|
||||
function showScripts()
|
||||
public function showScripts()
|
||||
{
|
||||
parent::showScripts();
|
||||
$this->autofocus('fullname');
|
||||
@ -80,7 +72,7 @@ class ProfilesettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showContent()
|
||||
public function showContent()
|
||||
{
|
||||
$user = $this->scoped->getUser();
|
||||
|
||||
@ -98,29 +90,40 @@ class ProfilesettingsAction extends SettingsAction
|
||||
if (Event::handle('StartProfileFormData', array($this))) {
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label in form for profile settings.
|
||||
$this->input('nickname', _('Nickname'),
|
||||
$this->trimmed('nickname') ?: $this->scoped->getNickname(),
|
||||
// TRANS: Tooltip for field label in form for profile settings.
|
||||
_('1-64 lowercase letters or numbers, no punctuation or spaces.'),
|
||||
null, false, // "name" (will be set to id), then "required"
|
||||
!common_config('profile', 'changenick')
|
||||
? array('disabled' => 'disabled', 'placeholder' => null)
|
||||
: array('placeholder' => null));
|
||||
$this->input(
|
||||
'nickname',
|
||||
_('Nickname'),
|
||||
$this->trimmed('nickname') ?: $this->scoped->getNickname(),
|
||||
// TRANS: Tooltip for field label in form for profile settings.
|
||||
_('1-64 lowercase letters or numbers, no punctuation or spaces.'),
|
||||
null,
|
||||
false, // "name" (will be set to id), then "required"
|
||||
(common_config('profile', 'changenick')
|
||||
? ['placeholder' => null]
|
||||
: ['disabled' => 'disabled', 'placeholder' => null])
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label in form for profile settings.
|
||||
$this->input('fullname', _('Full name'),
|
||||
$this->trimmed('fullname') ?: $this->scoped->getFullname(),
|
||||
// TRANS: Instructions for full name text field on profile settings
|
||||
_('A full name is required, if empty it will be set to your nickname.'),
|
||||
null, true);
|
||||
$this->input(
|
||||
'fullname',
|
||||
_('Full name'),
|
||||
$this->trimmed('fullname') ?: $this->scoped->getFullname(),
|
||||
// TRANS: Instructions for full name text field on profile settings
|
||||
_('A full name is required, if empty it will be set to your nickname.'),
|
||||
null,
|
||||
true
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label in form for profile settings.
|
||||
$this->input('homepage', _('Homepage'),
|
||||
$this->trimmed('homepage') ?: $this->scoped->getHomepage(),
|
||||
// TRANS: Tooltip for field label in form for profile settings.
|
||||
_('URL of your homepage, blog, or profile on another site.'));
|
||||
$this->input(
|
||||
'homepage',
|
||||
_('Homepage'),
|
||||
$this->trimmed('homepage') ?: $this->scoped->getHomepage(),
|
||||
// TRANS: Tooltip for field label in form for profile settings.
|
||||
_('URL of your homepage, blog, or profile on another site.')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$maxBio = Profile::maxBio();
|
||||
@ -128,97 +131,129 @@ class ProfilesettingsAction extends SettingsAction
|
||||
// TRANS: Tooltip for field label in form for profile settings. Plural
|
||||
// TRANS: is decided by the number of characters available for the
|
||||
// TRANS: biography (%d).
|
||||
$bioInstr = sprintf(_m('Describe yourself and your interests in %d character.',
|
||||
'Describe yourself and your interests in %d characters.',
|
||||
$maxBio),
|
||||
$maxBio);
|
||||
$bioInstr = sprintf(
|
||||
_m('Describe yourself and your interests in %d character.',
|
||||
'Describe yourself and your interests in %d characters.',
|
||||
$maxBio),
|
||||
$maxBio
|
||||
);
|
||||
} else {
|
||||
// TRANS: Tooltip for field label in form for profile settings.
|
||||
$bioInstr = _('Describe yourself and your interests.');
|
||||
}
|
||||
// TRANS: Text area label in form for profile settings where users can provide
|
||||
// TRANS: their biography.
|
||||
$this->textarea('bio', _('Bio'),
|
||||
$this->trimmed('bio') ?: $this->scoped->getDescription(),
|
||||
$bioInstr);
|
||||
$this->textarea(
|
||||
'bio',
|
||||
_('Bio'),
|
||||
($this->trimmed('bio') ?: $this->scoped->getDescription()),
|
||||
$bioInstr
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label in form for profile settings.
|
||||
$this->input('location', _('Location'),
|
||||
$this->trimmed('location') ?: $this->scoped->location,
|
||||
// TRANS: Tooltip for field label in form for profile settings.
|
||||
_('Where you are, like "City, State (or Region), Country".'));
|
||||
$this->input(
|
||||
'location',
|
||||
_('Location'),
|
||||
($this->trimmed('location') ?: $this->scoped->location),
|
||||
// TRANS: Tooltip for field label in form for profile settings.
|
||||
_('Where you are, like "City, State (or Region), Country".')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
if (common_config('location', 'share') == 'user') {
|
||||
$this->elementStart('li');
|
||||
// TRANS: Checkbox label in form for profile settings.
|
||||
$this->checkbox('sharelocation', _('Share my current location when posting notices'),
|
||||
($this->arg('sharelocation')) ?
|
||||
$this->boolean('sharelocation') : $this->scoped->shareLocation());
|
||||
$this->checkbox(
|
||||
'sharelocation',
|
||||
_('Share my current location when posting notices'),
|
||||
($this->arg('sharelocation') ?
|
||||
$this->boolean('sharelocation') : $this->scoped->shareLocation())
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
Event::handle('EndProfileFormData', array($this));
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label in form for profile settings.
|
||||
$this->input('tags', _('Tags'),
|
||||
$this->trimmed('tags') ?: implode(' ', Profile_tag::getSelfTagsArray($this->scoped)),
|
||||
// TRANS: Tooltip for field label in form for profile settings.
|
||||
_('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated.'));
|
||||
$this->input(
|
||||
'tags',
|
||||
_('Tags'),
|
||||
($this->trimmed('tags') ?: implode(' ', Profile_tag::getSelfTagsArray($this->scoped))),
|
||||
// TRANS: Tooltip for field label in form for profile settings.
|
||||
_('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated.')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$language = common_language();
|
||||
// TRANS: Dropdownlist label in form for profile settings.
|
||||
$this->dropdown('language', _('Language'),
|
||||
// TRANS: Tooltip for dropdown list label in form for profile settings.
|
||||
get_nice_language_list(), _('Preferred language.'),
|
||||
false, $language);
|
||||
$this->dropdown(
|
||||
'language',
|
||||
_('Language'),
|
||||
// TRANS: Tooltip for dropdown list label in form for profile settings.
|
||||
get_nice_language_list(),
|
||||
_('Preferred language.'),
|
||||
false,
|
||||
$language
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$timezone = common_timezone();
|
||||
$timezones = array();
|
||||
foreach(DateTimeZone::listIdentifiers() as $k => $v) {
|
||||
foreach (DateTimeZone::listIdentifiers() as $k => $v) {
|
||||
$timezones[$v] = $v;
|
||||
}
|
||||
$this->elementStart('li');
|
||||
// TRANS: Dropdownlist label in form for profile settings.
|
||||
$this->dropdown('timezone', _('Timezone'),
|
||||
// TRANS: Tooltip for dropdown list label in form for profile settings.
|
||||
$timezones, _('What timezone are you normally in?'),
|
||||
true, $timezone);
|
||||
$this->dropdown(
|
||||
'timezone',
|
||||
_('Timezone'),
|
||||
// TRANS: Tooltip for dropdown list label in form for profile settings.
|
||||
$timezones,
|
||||
_('What timezone are you normally in?'),
|
||||
true,
|
||||
$timezone
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('autosubscribe',
|
||||
// TRANS: Checkbox label in form for profile settings.
|
||||
_('Automatically subscribe to whoever '.
|
||||
'subscribes to me (best for non-humans)'),
|
||||
($this->arg('autosubscribe')) ?
|
||||
$this->boolean('autosubscribe') : $user->autosubscribe);
|
||||
$this->checkbox(
|
||||
'autosubscribe',
|
||||
// TRANS: Checkbox label in form for profile settings.
|
||||
_('Automatically subscribe to whoever '.
|
||||
'subscribes to me (best for non-humans)'),
|
||||
($this->arg('autosubscribe') ?
|
||||
$this->boolean('autosubscribe') : $user->autosubscribe)
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->dropdown('subscribe_policy',
|
||||
// TRANS: Dropdown field label on profile settings, for what policies to apply when someone else tries to subscribe to your updates.
|
||||
_('Subscription policy'),
|
||||
// TRANS: Dropdown field option for following policy.
|
||||
array(User::SUBSCRIBE_POLICY_OPEN => _('Let anyone follow me'),
|
||||
// TRANS: Dropdown field option for following policy.
|
||||
User::SUBSCRIBE_POLICY_MODERATE => _('Ask me first')),
|
||||
// TRANS: Dropdown field title on group edit form.
|
||||
_('Whether other users need your permission to follow your updates.'),
|
||||
false,
|
||||
(empty($user->subscribe_policy)) ? User::SUBSCRIBE_POLICY_OPEN : $user->subscribe_policy);
|
||||
$this->dropdown(
|
||||
'subscribe_policy',
|
||||
// TRANS: Dropdown field label on profile settings, for what policies to apply when someone else tries to subscribe to your updates.
|
||||
_('Subscription policy'),
|
||||
[
|
||||
// TRANS: Dropdown field option for following policy.
|
||||
User::SUBSCRIBE_POLICY_OPEN => _('Let anyone follow me'),
|
||||
// TRANS: Dropdown field option for following policy.
|
||||
User::SUBSCRIBE_POLICY_MODERATE => _('Ask me first'),
|
||||
],
|
||||
// TRANS: Dropdown field title on group edit form.
|
||||
_('Whether other users need your permission to follow your updates.'),
|
||||
false,
|
||||
(empty($user->subscribe_policy) ? User::SUBSCRIBE_POLICY_OPEN : $user->subscribe_policy)
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
if (common_config('profile', 'allowprivate') || $user->private_stream) {
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('private_stream',
|
||||
// TRANS: Checkbox label in profile settings.
|
||||
_('Make updates visible only to my followers'),
|
||||
($this->arg('private_stream')) ?
|
||||
$this->boolean('private_stream') : $user->private_stream);
|
||||
$this->checkbox(
|
||||
'private_stream',
|
||||
// TRANS: Checkbox label in profile settings.
|
||||
_('Make updates visible only to my followers'),
|
||||
($this->arg('private_stream') ?
|
||||
$this->boolean('private_stream') : $user->private_stream)
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
// TRANS: Button to save input in profile settings.
|
||||
$this->submit('save', _m('BUTTON','Save'));
|
||||
$this->submit('save', _m('BUTTON', 'Save'));
|
||||
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
@ -255,7 +290,7 @@ class ProfilesettingsAction extends SettingsAction
|
||||
$homepage = $this->trimmed('homepage');
|
||||
$bio = $this->trimmed('bio');
|
||||
$location = $this->trimmed('location');
|
||||
$autosubscribe = $this->booleanintstring('autosubscribe');
|
||||
$autosubscribe = $this->boolean('autosubscribe');
|
||||
$subscribe_policy = $this->trimmed('subscribe_policy');
|
||||
$language = $this->trimmed('language');
|
||||
$timezone = $this->trimmed('timezone');
|
||||
@ -266,24 +301,26 @@ class ProfilesettingsAction extends SettingsAction
|
||||
!common_valid_http_url($homepage)) {
|
||||
// TRANS: Validation error in form for profile settings.
|
||||
throw new ClientException(_('Homepage is not a valid URL.'));
|
||||
} else if (!is_null($fullname) && mb_strlen($fullname) > 191) {
|
||||
} elseif (!is_null($fullname) && mb_strlen($fullname) > 191) {
|
||||
// TRANS: Validation error in form for profile settings.
|
||||
throw new ClientException(_('Full name is too long (maximum 191 characters).'));
|
||||
} else if (Profile::bioTooLong($bio)) {
|
||||
} elseif (Profile::bioTooLong($bio)) {
|
||||
// TRANS: Validation error in form for profile settings.
|
||||
// TRANS: Plural form is used based on the maximum number of allowed
|
||||
// TRANS: characters for the biography (%d).
|
||||
throw new ClientException(sprintf(_m('Bio is too long (maximum %d character).',
|
||||
'Bio is too long (maximum %d characters).',
|
||||
Profile::maxBio()),
|
||||
Profile::maxBio()));
|
||||
} else if (!is_null($location) && mb_strlen($location) > 191) {
|
||||
throw new ClientException(sprintf(
|
||||
_m('Bio is too long (maximum %d character).',
|
||||
'Bio is too long (maximum %d characters).',
|
||||
Profile::maxBio()),
|
||||
Profile::maxBio()
|
||||
));
|
||||
} elseif (!is_null($location) && mb_strlen($location) > 191) {
|
||||
// TRANS: Validation error in form for profile settings.
|
||||
throw new ClientException(_('Location is too long (maximum 191 characters).'));
|
||||
} else if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) {
|
||||
} elseif (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) {
|
||||
// TRANS: Validation error in form for profile settings.
|
||||
throw new ClientException(_('Timezone not selected.'));
|
||||
} else if (!is_null($language) && strlen($language) > 50) {
|
||||
} elseif (!is_null($language) && strlen($language) > 50) {
|
||||
// TRANS: Validation error in form for profile settings.
|
||||
throw new ClientException(_('Language is too long (maximum 50 characters).'));
|
||||
}
|
||||
@ -291,7 +328,6 @@ class ProfilesettingsAction extends SettingsAction
|
||||
$tags = array();
|
||||
$tag_priv = array();
|
||||
if (is_string($tagstring) && strlen($tagstring) > 0) {
|
||||
|
||||
$tags = preg_split('/[\s,]+/', $tagstring);
|
||||
|
||||
foreach ($tags as &$tag) {
|
||||
@ -314,21 +350,19 @@ class ProfilesettingsAction extends SettingsAction
|
||||
// Only allow setting private_stream if site policy allows it
|
||||
// (or user already _has_ a private stream, then you can unset it)
|
||||
if (common_config('profile', 'allowprivate') || $user->private_stream) {
|
||||
$private_stream = $this->booleanintstring('private_stream');
|
||||
$private_stream = $this->boolean('private_stream');
|
||||
} else {
|
||||
// if not allowed, we set to the existing value
|
||||
$private_stream = $user->private_stream;
|
||||
$private_stream = (bool) $user->private_stream;
|
||||
}
|
||||
|
||||
// $user->nickname is updated through Profile->update();
|
||||
|
||||
// XXX: XOR
|
||||
if (($user->autosubscribe ^ $autosubscribe)
|
||||
|| ($user->private_stream ^ $private_stream)
|
||||
if ((bool) $user->autosubscribe != $autosubscribe
|
||||
|| (bool) $user->private_stream != $private_stream
|
||||
|| $user->timezone != $timezone
|
||||
|| $user->language != $language
|
||||
|| $user->subscribe_policy != $subscribe_policy) {
|
||||
|
||||
$original = clone($user);
|
||||
|
||||
$user->autosubscribe = $autosubscribe;
|
||||
@ -378,7 +412,6 @@ class ProfilesettingsAction extends SettingsAction
|
||||
}
|
||||
|
||||
if (common_config('location', 'share') == 'user') {
|
||||
|
||||
$exists = false;
|
||||
|
||||
$prefs = User_location_prefs::getKV('user_id', $this->scoped->getID());
|
||||
@ -393,7 +426,7 @@ class ProfilesettingsAction extends SettingsAction
|
||||
$orig = clone($prefs);
|
||||
}
|
||||
|
||||
$prefs->share_location = $this->booleanintstring('sharelocation');
|
||||
$prefs->share_location = $this->boolean('sharelocation');
|
||||
|
||||
if ($exists) {
|
||||
$result = $prefs->update($orig);
|
||||
@ -429,11 +462,11 @@ class ProfilesettingsAction extends SettingsAction
|
||||
|
||||
// TRANS: Confirmation shown when user profile settings are saved.
|
||||
return _('Settings saved.');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function showAside() {
|
||||
public function showAside()
|
||||
{
|
||||
$this->elementStart('div', array('id' => 'aside_primary',
|
||||
'class' => 'aside'));
|
||||
|
||||
@ -443,26 +476,32 @@ class ProfilesettingsAction extends SettingsAction
|
||||
if (Event::handle('StartProfileSettingsActions', array($this))) {
|
||||
if ($this->scoped->hasRight(Right::BACKUPACCOUNT)) {
|
||||
$this->elementStart('li');
|
||||
$this->element('a',
|
||||
array('href' => common_local_url('backupaccount')),
|
||||
// TRANS: Option in profile settings to create a backup of the account of the currently logged in user.
|
||||
_('Backup account'));
|
||||
$this->element(
|
||||
'a',
|
||||
['href' => common_local_url('backupaccount')],
|
||||
// TRANS: Option in profile settings to create a backup of the account of the currently logged in user.
|
||||
_('Backup account')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
if ($this->scoped->hasRight(Right::DELETEACCOUNT)) {
|
||||
$this->elementStart('li');
|
||||
$this->element('a',
|
||||
array('href' => common_local_url('deleteaccount')),
|
||||
// TRANS: Option in profile settings to delete the account of the currently logged in user.
|
||||
_('Delete account'));
|
||||
$this->element(
|
||||
'a',
|
||||
['href' => common_local_url('deleteaccount')],
|
||||
// TRANS: Option in profile settings to delete the account of the currently logged in user.
|
||||
_('Delete account')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
if ($this->scoped->hasRight(Right::RESTOREACCOUNT)) {
|
||||
$this->elementStart('li');
|
||||
$this->element('a',
|
||||
array('href' => common_local_url('restoreaccount')),
|
||||
// TRANS: Option in profile settings to restore the account of the currently logged in user from a backup.
|
||||
_('Restore account'));
|
||||
$this->element(
|
||||
'a',
|
||||
['href' => common_local_url('restoreaccount')],
|
||||
// TRANS: Option in profile settings to restore the account of the currently logged in user from a backup.
|
||||
_('Restore account')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
Event::handle('EndProfileSettingsActions', array($this));
|
||||
|
@ -1,53 +1,45 @@
|
||||
<?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
|
||||
*
|
||||
* Action for showing profiles self-tagged with a given tag
|
||||
*
|
||||
* 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 Action
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* This class outputs a paginated list of profiles self-tagged with a given tag
|
||||
*
|
||||
* @category Output
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @category Output
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see Action
|
||||
* @see Action
|
||||
*/
|
||||
class SelftagAction extends Action
|
||||
{
|
||||
var $tag = null;
|
||||
var $page = null;
|
||||
public $tag = null;
|
||||
public $page = null;
|
||||
|
||||
/**
|
||||
* For initializing members of the class.
|
||||
@ -57,7 +49,7 @@ class SelftagAction extends Action
|
||||
* @return boolean true
|
||||
* @throws ClientException
|
||||
*/
|
||||
function prepare(array $args = [])
|
||||
public function prepare(array $args = [])
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -66,8 +58,10 @@ class SelftagAction extends Action
|
||||
if (!common_valid_profile_tag($this->tag)) {
|
||||
// TRANS: Client error displayed when trying to list a profile with an invalid list.
|
||||
// TRANS: %s is the invalid list name.
|
||||
$this->clientError(sprintf(_('Not a valid list: %s.'),
|
||||
$this->tag));
|
||||
$this->clientError(sprintf(
|
||||
_('Not a valid list: %s.'),
|
||||
$this->tag
|
||||
));
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -83,7 +77,7 @@ class SelftagAction extends Action
|
||||
*
|
||||
* @return void is read only action?
|
||||
*/
|
||||
function handle()
|
||||
public function handle()
|
||||
{
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
@ -94,19 +88,13 @@ class SelftagAction extends Action
|
||||
* people tag and page, initalizes a ProfileList widget, and displays
|
||||
* it to the user.
|
||||
*/
|
||||
function showContent()
|
||||
public function showContent()
|
||||
{
|
||||
$profile = new Profile();
|
||||
|
||||
$offset = ($this->page - 1) * PROFILES_PER_PAGE;
|
||||
$limit = PROFILES_PER_PAGE + 1;
|
||||
|
||||
if (common_config('db', 'type') == 'pgsql') {
|
||||
$lim = ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$lim = ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
|
||||
// XXX: memcached this
|
||||
|
||||
$qry = 'SELECT profile.* ' .
|
||||
@ -125,18 +113,21 @@ class SelftagAction extends Action
|
||||
' OR profile_list.private = false) ';
|
||||
}
|
||||
|
||||
$qry .= 'ORDER BY profile_tag.modified DESC%s';
|
||||
$qry .= 'ORDER BY profile_tag.modified DESC ' .
|
||||
'LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
|
||||
$profile->query(sprintf($qry, $this->tag, $lim));
|
||||
$profile->query(sprintf($qry, $this->tag));
|
||||
|
||||
$ptl = new SelfTagProfileList($profile, $this); // pass the ammunition
|
||||
$cnt = $ptl->show();
|
||||
|
||||
$this->pagination($this->page > 1,
|
||||
$cnt > PROFILES_PER_PAGE,
|
||||
$this->page,
|
||||
'selftag',
|
||||
array('tag' => $this->tag));
|
||||
$this->pagination(
|
||||
$this->page > 1,
|
||||
$cnt > PROFILES_PER_PAGE,
|
||||
$this->page,
|
||||
'selftag',
|
||||
['tag' => $this->tag]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,18 +135,21 @@ class SelftagAction extends Action
|
||||
*
|
||||
* @return string page title
|
||||
*/
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Page title for page showing self tags.
|
||||
// TRANS: %1$s is a tag, %2$d is a page number.
|
||||
return sprintf(_('Users self-tagged with %1$s, page %2$d'),
|
||||
$this->tag, $this->page);
|
||||
return sprintf(
|
||||
_('Users self-tagged with %1$s, page %2$d'),
|
||||
$this->tag,
|
||||
$this->page
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SelfTagProfileList extends ProfileList
|
||||
{
|
||||
function newListItem(Profile $target)
|
||||
public function newListItem(Profile $target)
|
||||
{
|
||||
return new SelfTagProfileListItem($target, $this->action);
|
||||
}
|
||||
@ -163,7 +157,7 @@ class SelfTagProfileList extends ProfileList
|
||||
|
||||
class SelfTagProfileListItem extends ProfileListItem
|
||||
{
|
||||
function linkAttributes()
|
||||
public function linkAttributes()
|
||||
{
|
||||
$aAttrs = parent::linkAttributes();
|
||||
|
||||
@ -174,7 +168,7 @@ class SelfTagProfileListItem extends ProfileListItem
|
||||
return $aAttrs;
|
||||
}
|
||||
|
||||
function homepageAttributes()
|
||||
public function homepageAttributes()
|
||||
{
|
||||
$aAttrs = parent::linkAttributes();
|
||||
|
||||
@ -185,7 +179,7 @@ class SelfTagProfileListItem extends ProfileListItem
|
||||
return $aAttrs;
|
||||
}
|
||||
|
||||
function showTags()
|
||||
public function showTags()
|
||||
{
|
||||
$selftags = new SelfTagsWidget($this->out, $this->profile, $this->profile);
|
||||
$selftags->show();
|
||||
|
@ -1,46 +1,39 @@
|
||||
<?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
|
||||
* Settings for SMS.
|
||||
*
|
||||
* Settings for SMS
|
||||
*
|
||||
* 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 Settings
|
||||
* @package StatusNet
|
||||
* @category Setting
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Settings for SMS
|
||||
*
|
||||
* @category Settings
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see SettingsAction
|
||||
*/
|
||||
|
||||
class SmssettingsAction extends SettingsAction
|
||||
{
|
||||
protected function doPreparation()
|
||||
@ -56,7 +49,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return string Title of the page
|
||||
*/
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Title for SMS settings.
|
||||
return _('SMS settings');
|
||||
@ -67,7 +60,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return instructions for use
|
||||
*/
|
||||
function getInstructions()
|
||||
public function getInstructions()
|
||||
{
|
||||
// XXX: For consistency of parameters in messages, this should be a
|
||||
// regular parameters, replaced with sprintf().
|
||||
@ -76,7 +69,7 @@ class SmssettingsAction extends SettingsAction
|
||||
return _('You can receive SMS messages through email from %%site.name%%.');
|
||||
}
|
||||
|
||||
function showScripts()
|
||||
public function showScripts()
|
||||
{
|
||||
parent::showScripts();
|
||||
$this->autofocus('sms');
|
||||
@ -90,7 +83,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showContent()
|
||||
public function showContent()
|
||||
{
|
||||
$user = $this->scoped->getUser();
|
||||
|
||||
@ -107,80 +100,105 @@ class SmssettingsAction extends SettingsAction
|
||||
|
||||
if ($user->sms) {
|
||||
$carrier = $user->getCarrier();
|
||||
$this->element('p', 'form_confirmed',
|
||||
$user->sms . ' (' . $carrier->name . ')');
|
||||
$this->element('p', 'form_guide',
|
||||
// TRANS: Form guide in SMS settings form.
|
||||
_('Current confirmed SMS-enabled phone number.'));
|
||||
$this->element(
|
||||
'p',
|
||||
'form_confirmed',
|
||||
$user->sms . ' (' . $carrier->name . ')'
|
||||
);
|
||||
$this->element(
|
||||
'p',
|
||||
'form_guide',
|
||||
// TRANS: Form guide in SMS settings form.
|
||||
_('Current confirmed SMS-enabled phone number.')
|
||||
);
|
||||
$this->hidden('sms', $user->sms);
|
||||
$this->hidden('carrier', $user->carrier);
|
||||
// TRANS: Button label to remove a confirmed SMS address.
|
||||
$this->submit('remove', _m('BUTTON','Remove'));
|
||||
$this->submit('remove', _m('BUTTON', 'Remove'));
|
||||
} else {
|
||||
try {
|
||||
$confirm = $this->getConfirmation();
|
||||
$carrier = Sms_carrier::getKV($confirm->address_extra);
|
||||
$this->element('p', 'form_unconfirmed',
|
||||
$confirm->address . ' (' . $carrier->name . ')');
|
||||
$this->element('p', 'form_guide',
|
||||
// TRANS: Form guide in IM settings form.
|
||||
_('Awaiting confirmation on this phone number.'));
|
||||
$this->element(
|
||||
'p',
|
||||
'form_unconfirmed',
|
||||
$confirm->address . ' (' . $carrier->name . ')'
|
||||
);
|
||||
$this->element(
|
||||
'p',
|
||||
'form_guide',
|
||||
// TRANS: Form guide in IM settings form.
|
||||
_('Awaiting confirmation on this phone number.')
|
||||
);
|
||||
$this->hidden('sms', $confirm->address);
|
||||
$this->hidden('carrier', $confirm->address_extra);
|
||||
// TRANS: Button label to cancel a SMS address confirmation procedure.
|
||||
$this->submit('cancel', _m('BUTTON','Cancel'));
|
||||
$this->submit('cancel', _m('BUTTON', 'Cancel'));
|
||||
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for SMS address input in SMS settings form.
|
||||
$this->input('code', _('Confirmation code'), null,
|
||||
// TRANS: Form field instructions in SMS settings form.
|
||||
_('Enter the code you received on your phone.'));
|
||||
$this->input(
|
||||
'code',
|
||||
_('Confirmation code'),
|
||||
null,
|
||||
// TRANS: Form field instructions in SMS settings form.
|
||||
_('Enter the code you received on your phone.')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
// TRANS: Button label to confirm SMS confirmation code in SMS settings.
|
||||
$this->submit('confirm', _m('BUTTON','Confirm'));
|
||||
$this->submit('confirm', _m('BUTTON', 'Confirm'));
|
||||
} catch (NoResultException $e) {
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for SMS phone number input in SMS settings form.
|
||||
$this->input('sms', _('SMS phone number'),
|
||||
($this->arg('sms')) ? $this->arg('sms') : null,
|
||||
// TRANS: SMS phone number input field instructions in SMS settings form.
|
||||
_('Phone number, no punctuation or spaces, '.
|
||||
'with area code.'));
|
||||
$this->input(
|
||||
'sms',
|
||||
_('SMS phone number'),
|
||||
($this->arg('sms') ?: null),
|
||||
// TRANS: SMS phone number input field instructions in SMS settings form.
|
||||
_('Phone number, no punctuation or spaces, ' .
|
||||
'with area code.')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
$this->carrierSelect();
|
||||
// TRANS: Button label for adding a SMS phone number in SMS settings form.
|
||||
$this->submit('add', _m('BUTTON','Add'));
|
||||
$this->submit('add', _m('BUTTON', 'Add'));
|
||||
}
|
||||
}
|
||||
$this->elementEnd('fieldset');
|
||||
|
||||
if ($user->sms) {
|
||||
$this->elementStart('fieldset', array('id' => 'settings_sms_incoming_email'));
|
||||
$this->elementStart('fieldset', ['id' => 'settings_sms_incoming_email']);
|
||||
// XXX: Confused! This is about SMS. Should this message be updated?
|
||||
// TRANS: Form legend for incoming SMS settings form.
|
||||
$this->element('legend', null, _('Incoming email'));
|
||||
|
||||
if ($user->incomingemail) {
|
||||
$this->element('p', 'form_unconfirmed', $user->incomingemail);
|
||||
$this->element('p', 'form_note',
|
||||
// XXX: Confused! This is about SMS. Should this message be updated?
|
||||
// TRANS: Form instructions for incoming SMS e-mail address form in SMS settings.
|
||||
_('Send email to this address to post new notices.'));
|
||||
$this->element(
|
||||
'p',
|
||||
'form_note',
|
||||
// XXX: Confused! This is about SMS. Should this message be updated?
|
||||
// TRANS: Form instructions for incoming SMS e-mail address form in SMS settings.
|
||||
_('Send email to this address to post new notices.')
|
||||
);
|
||||
// TRANS: Button label for removing a set sender SMS e-mail address to post notices from.
|
||||
$this->submit('removeincoming', _m('BUTTON','Remove'));
|
||||
$this->submit('removeincoming', _m('BUTTON', 'Remove'));
|
||||
}
|
||||
|
||||
$this->element('p', 'form_guide',
|
||||
// XXX: Confused! This is about SMS. Should this message be updated?
|
||||
// TRANS: Instructions for incoming SMS e-mail address input form.
|
||||
_('Make a new email address for posting to; '.
|
||||
'cancels the old one.'));
|
||||
$this->element(
|
||||
'p',
|
||||
'form_guide',
|
||||
// XXX: Confused! This is about SMS. Should this message be updated?
|
||||
// TRANS: Instructions for incoming SMS e-mail address input form.
|
||||
_('Make a new email address for posting to; ' .
|
||||
'cancels the old one.')
|
||||
);
|
||||
// TRANS: Button label for adding an SMS e-mail address to send notices from.
|
||||
$this->submit('newincoming', _m('BUTTON','New'));
|
||||
$this->submit('newincoming', _m('BUTTON', 'New'));
|
||||
$this->elementEnd('fieldset');
|
||||
}
|
||||
|
||||
@ -190,17 +208,19 @@ class SmssettingsAction extends SettingsAction
|
||||
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('smsnotify',
|
||||
// TRANS: Checkbox label in SMS preferences form.
|
||||
_('Send me notices through SMS; '.
|
||||
'I understand I may incur '.
|
||||
'exorbitant charges from my carrier.'),
|
||||
$user->smsnotify);
|
||||
$this->checkbox(
|
||||
'smsnotify',
|
||||
// TRANS: Checkbox label in SMS preferences form.
|
||||
_('Send me notices through SMS; ' .
|
||||
'I understand I may incur ' .
|
||||
'exorbitant charges from my carrier.'),
|
||||
$user->smsnotify
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
|
||||
// TRANS: Button label to save SMS preferences.
|
||||
$this->submit('save', _m('BUTTON','Save'));
|
||||
$this->submit('save', _m('BUTTON', 'Save'));
|
||||
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
@ -213,7 +233,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @todo very similar to EmailsettingsAction::getConfirmation(); refactor?
|
||||
*/
|
||||
function getConfirmation()
|
||||
public function getConfirmation()
|
||||
{
|
||||
$confirm = new Confirm_address();
|
||||
|
||||
@ -229,20 +249,19 @@ class SmssettingsAction extends SettingsAction
|
||||
|
||||
protected function doPost()
|
||||
{
|
||||
|
||||
if ($this->arg('save')) {
|
||||
return $this->savePreferences();
|
||||
} else if ($this->arg('add')) {
|
||||
} elseif ($this->arg('add')) {
|
||||
return $this->addAddress();
|
||||
} else if ($this->arg('cancel')) {
|
||||
} elseif ($this->arg('cancel')) {
|
||||
return $this->cancelConfirmation();
|
||||
} else if ($this->arg('remove')) {
|
||||
} elseif ($this->arg('remove')) {
|
||||
return $this->removeAddress();
|
||||
} else if ($this->arg('removeincoming')) {
|
||||
} elseif ($this->arg('removeincoming')) {
|
||||
return $this->removeIncoming();
|
||||
} else if ($this->arg('newincoming')) {
|
||||
} elseif ($this->arg('newincoming')) {
|
||||
return $this->newIncoming();
|
||||
} else if ($this->arg('confirm')) {
|
||||
} elseif ($this->arg('confirm')) {
|
||||
return $this->confirmCode();
|
||||
}
|
||||
// TRANS: Message given submitting a form with an unknown action in SMS settings.
|
||||
@ -256,7 +275,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function savePreferences()
|
||||
public function savePreferences()
|
||||
{
|
||||
$user = $this->scoped->getUser();
|
||||
|
||||
@ -288,7 +307,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function addAddress()
|
||||
public function addAddress()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
@ -312,7 +331,7 @@ class SmssettingsAction extends SettingsAction
|
||||
if ($user->sms === $sms) {
|
||||
// TRANS: Message given saving SMS phone number that is already set.
|
||||
throw new AlreadyFulfilledException(_('That is already your phone number.'));
|
||||
} else if ($this->smsExists($sms)) {
|
||||
} elseif ($this->smsExists($sms)) {
|
||||
// TRANS: Message given saving SMS phone number that is already set for another user.
|
||||
throw new ClientException(_('That phone number already belongs to another user.'));
|
||||
}
|
||||
@ -335,9 +354,11 @@ class SmssettingsAction extends SettingsAction
|
||||
|
||||
$carrier = Sms_carrier::getKV($carrier_id);
|
||||
|
||||
mail_confirm_sms($confirm->code,
|
||||
$user->nickname,
|
||||
$carrier->toEmailAddress($sms));
|
||||
mail_confirm_sms(
|
||||
$confirm->code,
|
||||
$user->nickname,
|
||||
$carrier->toEmailAddress($sms)
|
||||
);
|
||||
|
||||
// TRANS: Message given saving valid SMS phone number that is to be confirmed.
|
||||
return _('A confirmation code was sent to the phone number you added. '.
|
||||
@ -352,7 +373,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function cancelConfirmation()
|
||||
public function cancelConfirmation()
|
||||
{
|
||||
$sms = $this->trimmed('sms');
|
||||
$carrier = $this->trimmed('carrier');
|
||||
@ -379,7 +400,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function removeAddress()
|
||||
public function removeAddress()
|
||||
{
|
||||
$user = $this->scoped->getUser();
|
||||
|
||||
@ -396,9 +417,9 @@ class SmssettingsAction extends SettingsAction
|
||||
|
||||
$original = clone($user);
|
||||
|
||||
$user->sms = null;
|
||||
$user->carrier = null;
|
||||
$user->smsemail = null;
|
||||
$user->sms = DB_DataObject_Cast::sql('NULL');
|
||||
$user->carrier = DB_DataObject_Cast::sql('NULL');
|
||||
$user->smsemail = DB_DataObject_Cast::sql('NULL');
|
||||
|
||||
// Throws exception on failure. Also performs it within a transaction.
|
||||
$user->updateWithKeys($original);
|
||||
@ -416,7 +437,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return boolean does the number exist
|
||||
*/
|
||||
function smsExists($sms)
|
||||
public function smsExists($sms)
|
||||
{
|
||||
$other = User::getKV('sms', $sms);
|
||||
|
||||
@ -432,7 +453,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function carrierSelect()
|
||||
public function carrierSelect()
|
||||
{
|
||||
$carrier = new Sms_carrier();
|
||||
|
||||
@ -444,22 +465,33 @@ class SmssettingsAction extends SettingsAction
|
||||
$this->element('label', array('for' => 'carrier'), _('Mobile carrier'));
|
||||
$this->elementStart('select', array('name' => 'carrier',
|
||||
'id' => 'carrier'));
|
||||
$this->element('option', array('value' => 0),
|
||||
// TRANS: Default option for mobile carrier dropdown menu in SMS settings.
|
||||
_('Select a carrier'));
|
||||
$this->element(
|
||||
'option',
|
||||
['value' => 0],
|
||||
// TRANS: Default option for mobile carrier dropdown menu in SMS settings.
|
||||
_('Select a carrier')
|
||||
);
|
||||
while ($carrier->fetch()) {
|
||||
$this->element('option', array('value' => $carrier->id),
|
||||
$carrier->name);
|
||||
$this->element(
|
||||
'option',
|
||||
['value' => $carrier->id],
|
||||
$carrier->name
|
||||
);
|
||||
}
|
||||
$this->elementEnd('select');
|
||||
$this->element('p', 'form_guide',
|
||||
// TRANS: Form instructions for mobile carrier dropdown menu in SMS settings.
|
||||
// TRANS: %s is an administrative contact's e-mail address.
|
||||
sprintf(_('Mobile carrier for your phone. '.
|
||||
'If you know a carrier that accepts ' .
|
||||
'SMS over email but isn\'t listed here, ' .
|
||||
'send email to let us know at %s.'),
|
||||
common_config('site', 'email')));
|
||||
$this->element(
|
||||
'p',
|
||||
'form_guide',
|
||||
// TRANS: Form instructions for mobile carrier dropdown menu in SMS settings.
|
||||
// TRANS: %s is an administrative contact's e-mail address.
|
||||
sprintf(
|
||||
_('Mobile carrier for your phone. ' .
|
||||
'If you know a carrier that accepts ' .
|
||||
'SMS over email but isn\'t listed here, ' .
|
||||
'send email to let us know at %s.'),
|
||||
common_config('site', 'email')
|
||||
)
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
}
|
||||
@ -471,7 +503,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function confirmCode()
|
||||
public function confirmCode()
|
||||
{
|
||||
$code = $this->trimmed('code');
|
||||
|
||||
@ -488,7 +520,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function removeIncoming()
|
||||
public function removeIncoming()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
@ -499,7 +531,7 @@ class SmssettingsAction extends SettingsAction
|
||||
|
||||
$orig = clone($user);
|
||||
|
||||
$user->incomingemail = null;
|
||||
$user->incomingemail = DB_DataObject_Cast::sql('NULL');
|
||||
|
||||
// Throws exception on failure. Also performs it within a transaction.
|
||||
$user->updateWithKeys($orig);
|
||||
@ -515,7 +547,7 @@ class SmssettingsAction extends SettingsAction
|
||||
*
|
||||
* @see Emailsettings::newIncoming
|
||||
*/
|
||||
function newIncoming()
|
||||
public function newIncoming()
|
||||
{
|
||||
$user = $this->scoped->getUser();
|
||||
|
||||
|
@ -1,28 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
// @todo FIXME: documentation needed.
|
||||
class SupAction extends Action
|
||||
{
|
||||
function handle()
|
||||
public function handle()
|
||||
{
|
||||
parent::handle();
|
||||
|
||||
@ -43,21 +40,23 @@ class SupAction extends Action
|
||||
'updates' => $updates));
|
||||
}
|
||||
|
||||
function availablePeriods()
|
||||
public function availablePeriods()
|
||||
{
|
||||
static $periods = array(86400, 43200, 21600, 7200,
|
||||
3600, 1800, 600, 300, 120,
|
||||
60, 30, 15);
|
||||
$available = array();
|
||||
foreach ($periods as $period) {
|
||||
$available[$period] = common_local_url('sup',
|
||||
array('seconds' => $period));
|
||||
$available[$period] = common_local_url(
|
||||
'sup',
|
||||
['seconds' => $period]
|
||||
);
|
||||
}
|
||||
|
||||
return $available;
|
||||
}
|
||||
|
||||
function getUpdates($seconds)
|
||||
public function getUpdates($seconds)
|
||||
{
|
||||
$notice = new Notice();
|
||||
|
||||
@ -69,9 +68,7 @@ class SupAction extends Action
|
||||
$notice->query('SELECT profile_id, max(id) AS max_id ' .
|
||||
'FROM ( ' .
|
||||
'SELECT profile_id, id FROM notice ' .
|
||||
((common_config('db','type') == 'pgsql') ?
|
||||
'WHERE extract(epoch from created) > (extract(epoch from now()) - ' . $seconds . ') ' :
|
||||
'WHERE created > "'.$divider.'" ' ) .
|
||||
"WHERE created > TIMESTAMP '" . $divider . "' " .
|
||||
') AS latest ' .
|
||||
'GROUP BY profile_id');
|
||||
|
||||
@ -84,7 +81,7 @@ class SupAction extends Action
|
||||
return $updates;
|
||||
}
|
||||
|
||||
function isReadOnly($args)
|
||||
public function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1,6 +1,20 @@
|
||||
<?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/>.
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for avatar
|
||||
@ -10,20 +24,20 @@ class Avatar extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'avatar'; // table name
|
||||
public $profile_id; // int(4) primary_key not_null
|
||||
public $original; // tinyint(1)
|
||||
public $original; // bool default_false
|
||||
public $width; // int(4) primary_key not_null
|
||||
public $height; // int(4) primary_key not_null
|
||||
public $mediatype; // varchar(32) not_null
|
||||
public $filename; // varchar(191) not 255 because utf8mb4 takes more space
|
||||
public $created; // datetime() not_null default_0000-00-00%2000%3A00%3A00
|
||||
public $modified; // datetime() not_null default_CURRENT_TIMESTAMP
|
||||
|
||||
|
||||
public static function schemaDef()
|
||||
{
|
||||
return array(
|
||||
'fields' => array(
|
||||
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
|
||||
'original' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'uploaded by user or generated?'),
|
||||
'original' => array('type' => 'bool', 'default' => false, 'description' => 'uploaded by user or generated?'),
|
||||
'width' => array('type' => 'int', 'not null' => true, 'description' => 'image width'),
|
||||
'height' => array('type' => 'int', 'not null' => true, 'description' => 'image height'),
|
||||
'mediatype' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'file type'),
|
||||
@ -45,7 +59,7 @@ class Avatar extends Managed_DataObject
|
||||
}
|
||||
|
||||
// We clean up the file, too
|
||||
function delete($useWhere=false)
|
||||
public function delete($useWhere = false)
|
||||
{
|
||||
$filename = $this->filename;
|
||||
if (file_exists(Avatar::path($filename))) {
|
||||
@ -57,11 +71,12 @@ class Avatar extends Managed_DataObject
|
||||
|
||||
/*
|
||||
* Deletes all avatars (but may spare the original) from a profile.
|
||||
*
|
||||
*
|
||||
* @param Profile $target The profile we're deleting avatars of.
|
||||
* @param boolean $original Whether original should be removed or not.
|
||||
*/
|
||||
public static function deleteFromProfile(Profile $target, $original=true) {
|
||||
public static function deleteFromProfile(Profile $target, $original = true)
|
||||
{
|
||||
try {
|
||||
$avatars = self::getProfileAvatars($target);
|
||||
foreach ($avatars as $avatar) {
|
||||
@ -77,7 +92,7 @@ class Avatar extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
|
||||
static protected $_avatars = array();
|
||||
protected static $_avatars = [];
|
||||
|
||||
/*
|
||||
* Get an avatar by profile. Currently can't call newSize with $height
|
||||
@ -93,7 +108,7 @@ class Avatar extends Managed_DataObject
|
||||
$size = "{$width}x{$height}";
|
||||
if (!isset(self::$_avatars[$target->id])) {
|
||||
self::$_avatars[$target->id] = array();
|
||||
} elseif (isset(self::$_avatars[$target->id][$size])){
|
||||
} elseif (isset(self::$_avatars[$target->id][$size])) {
|
||||
return self::$_avatars[$target->id][$size];
|
||||
}
|
||||
|
||||
@ -137,7 +152,8 @@ class Avatar extends Managed_DataObject
|
||||
return $avatar;
|
||||
}
|
||||
|
||||
public static function getProfileAvatars(Profile $target) {
|
||||
public static function getProfileAvatars(Profile $target)
|
||||
{
|
||||
$avatar = new Avatar();
|
||||
$avatar->profile_id = $target->id;
|
||||
if (!$avatar->find()) {
|
||||
@ -149,7 +165,7 @@ class Avatar extends Managed_DataObject
|
||||
/**
|
||||
* Where should the avatar go for this user?
|
||||
*/
|
||||
static function filename($id, $extension, $size=null, $extra=null)
|
||||
public static function filename($id, $extension, $size = null, $extra = null)
|
||||
{
|
||||
if ($size) {
|
||||
return $id . '-' . $size . (($extra) ? ('-' . $extra) : '') . $extension;
|
||||
@ -158,7 +174,7 @@ class Avatar extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
static function path($filename)
|
||||
public static function path($filename)
|
||||
{
|
||||
$dir = common_config('avatar', 'dir');
|
||||
|
||||
@ -169,7 +185,7 @@ class Avatar extends Managed_DataObject
|
||||
return $dir . $filename;
|
||||
}
|
||||
|
||||
static function url($filename)
|
||||
public static function url($filename)
|
||||
{
|
||||
$path = common_config('avatar', 'path');
|
||||
|
||||
@ -194,20 +210,21 @@ class Avatar extends Managed_DataObject
|
||||
return $protocol.'://'.$server.$path.$filename;
|
||||
}
|
||||
|
||||
function displayUrl()
|
||||
public function displayUrl()
|
||||
{
|
||||
return Avatar::url($this->filename);
|
||||
}
|
||||
|
||||
static function urlByProfile(Profile $target, $width=null, $height=null) {
|
||||
public static function urlByProfile(Profile $target, $width = null, $height = null)
|
||||
{
|
||||
try {
|
||||
return self::byProfile($target, $width, $height)->displayUrl();
|
||||
return self::byProfile($target, $width, $height)->displayUrl();
|
||||
} catch (Exception $e) {
|
||||
return self::defaultImage($width);
|
||||
}
|
||||
}
|
||||
|
||||
static function defaultImage($size=null)
|
||||
public static function defaultImage($size = null)
|
||||
{
|
||||
if (is_null($size)) {
|
||||
$size = AVATAR_PROFILE_SIZE;
|
||||
@ -218,7 +235,8 @@ class Avatar extends Managed_DataObject
|
||||
return Theme::path('default-avatar-'.$sizenames[$size].'.png');
|
||||
}
|
||||
|
||||
static function newSize(Profile $target, $width) {
|
||||
public static function newSize(Profile $target, $width)
|
||||
{
|
||||
$width = intval($width);
|
||||
if ($width < 1 || $width > common_config('avatar', 'maxsize')) {
|
||||
// TRANS: An error message when avatar size is unreasonable
|
||||
@ -231,8 +249,12 @@ class Avatar extends Managed_DataObject
|
||||
$original = Avatar::getUploaded($target);
|
||||
|
||||
$imagefile = new ImageFile(null, Avatar::path($original->filename));
|
||||
$filename = Avatar::filename($target->getID(), image_type_to_extension($imagefile->preferredType()),
|
||||
$width, common_timestamp());
|
||||
$filename = Avatar::filename(
|
||||
$target->getID(),
|
||||
image_type_to_extension($imagefile->preferredType()),
|
||||
$width,
|
||||
common_timestamp()
|
||||
);
|
||||
$imagefile->resizeTo(Avatar::path($filename), array('width'=>$width, 'height'=>$height));
|
||||
|
||||
$scaled = clone($original);
|
||||
|
@ -1,35 +1,32 @@
|
||||
<?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
|
||||
*
|
||||
* Data class for Conversations
|
||||
*
|
||||
* 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 Data
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2010 StatusNet Inc.
|
||||
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class Conversation extends Managed_DataObject
|
||||
{
|
||||
@ -57,14 +54,14 @@ class Conversation extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
static public function beforeSchemaUpdate()
|
||||
public static function beforeSchemaUpdate()
|
||||
{
|
||||
$table = strtolower(get_called_class());
|
||||
$schema = Schema::get();
|
||||
$schemadef = $schema->getTableDef($table);
|
||||
|
||||
// 2016-01-06 We have to make sure there is no conversation with id==0 since it will screw up auto increment resequencing
|
||||
if ($schemadef['fields']['id']['auto_increment']) {
|
||||
if ($schemadef['fields']['id']['auto_increment'] ?? false) {
|
||||
// since we already have auto incrementing ('serial') we can continue
|
||||
return;
|
||||
}
|
||||
@ -91,7 +88,7 @@ class Conversation extends Managed_DataObject
|
||||
*
|
||||
* @return Conversation the new conversation DO
|
||||
*/
|
||||
static function create(ActivityContext $ctx=null, $created=null)
|
||||
public static function create(ActivityContext $ctx = null, $created = null)
|
||||
{
|
||||
// Be aware that the Notice does not have an id yet since it's not inserted!
|
||||
$conv = new Conversation();
|
||||
@ -100,11 +97,16 @@ class Conversation extends Managed_DataObject
|
||||
$conv->uri = $ctx->conversation;
|
||||
$conv->url = $ctx->conversation_url;
|
||||
} else {
|
||||
$conv->uri = sprintf('%s%s=%s:%s=%s',
|
||||
TagURI::mint(),
|
||||
'objectType', 'thread',
|
||||
'nonce', common_random_hexstr(8));
|
||||
$conv->url = null; // locally generated Conversation objects don't get static URLs stored
|
||||
$conv->uri = sprintf(
|
||||
'%s%s=%s:%s=%s',
|
||||
TagURI::mint(),
|
||||
'objectType',
|
||||
'thread',
|
||||
'nonce',
|
||||
common_random_hexstr(8)
|
||||
);
|
||||
// locally generated Conversation objects don't get static URLs stored
|
||||
$conv->url = DB_DataObject_Cast::sql('NULL');
|
||||
}
|
||||
// This insert throws exceptions on failure
|
||||
$conv->insert();
|
||||
@ -112,7 +114,7 @@ class Conversation extends Managed_DataObject
|
||||
return $conv;
|
||||
}
|
||||
|
||||
static function noticeCount($id)
|
||||
public static function noticeCount($id)
|
||||
{
|
||||
$keypart = sprintf('conversation:notice_count:%d', $id);
|
||||
|
||||
@ -132,7 +134,7 @@ class Conversation extends Managed_DataObject
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
static public function getUrlFromNotice(Notice $notice, $anchor=true)
|
||||
public static function getUrlFromNotice(Notice $notice, $anchor = true)
|
||||
{
|
||||
$conv = Conversation::getByID($notice->conversation);
|
||||
return $conv->getUrl($anchor ? $notice->getID() : null);
|
||||
|
@ -1,29 +1,26 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* GNU social - a federating social network
|
||||
*
|
||||
* Abstraction for files
|
||||
*
|
||||
* 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 Files
|
||||
* @package GNUsocial
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @author Miguel Dantas <biodantas@gmail.com>
|
||||
* @copyright 2008-2009, 2019 Free Software Foundation http://fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link https://www.gnu.org/software/social/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
@ -248,14 +245,14 @@ class File extends Managed_DataObject
|
||||
// TRANS: gettext support multiple plurals in the same message, unfortunately...
|
||||
throw new ClientException(
|
||||
sprintf(
|
||||
_m(
|
||||
_m(
|
||||
'No file may be larger than %1$d byte and the file you sent was %2$s. Try to upload a smaller version.',
|
||||
'No file may be larger than %1$d bytes and the file you sent was %2$s. Try to upload a smaller version.',
|
||||
$fileQuota
|
||||
),
|
||||
$fileQuota,
|
||||
$fileSizeText
|
||||
)
|
||||
$fileQuota,
|
||||
$fileSizeText
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -277,13 +274,13 @@ class File extends Managed_DataObject
|
||||
// TRANS: %d (number) is the user quota in bytes and is used for plural.
|
||||
throw new ClientException(
|
||||
sprintf(
|
||||
_m(
|
||||
_m(
|
||||
'A file this large would exceed your user quota of %d byte.',
|
||||
'A file this large would exceed your user quota of %d bytes.',
|
||||
common_config('attachments', 'user_quota')
|
||||
),
|
||||
common_config('attachments', 'user_quota')
|
||||
)
|
||||
common_config('attachments', 'user_quota')
|
||||
)
|
||||
);
|
||||
}
|
||||
$query .= ' AND EXTRACT(month FROM file.modified) = EXTRACT(month FROM now()) AND EXTRACT(year FROM file.modified) = EXTRACT(year FROM now())';
|
||||
@ -295,13 +292,13 @@ class File extends Managed_DataObject
|
||||
// TRANS: $d (number) is the monthly user quota in bytes and is used for plural.
|
||||
throw new ClientException(
|
||||
sprintf(
|
||||
_m(
|
||||
_m(
|
||||
'A file this large would exceed your monthly quota of %d byte.',
|
||||
'A file this large would exceed your monthly quota of %d bytes.',
|
||||
common_config('attachments', 'monthly_quota')
|
||||
),
|
||||
common_config('attachments', 'monthly_quota')
|
||||
)
|
||||
common_config('attachments', 'monthly_quota')
|
||||
)
|
||||
);
|
||||
}
|
||||
return true;
|
||||
@ -346,7 +343,8 @@ class File extends Managed_DataObject
|
||||
* @param string $filename
|
||||
* @return string|bool Value from the 'extblacklist' array, in the config
|
||||
*/
|
||||
public static function getSafeExtension(string $filename) {
|
||||
public static function getSafeExtension(string $filename)
|
||||
{
|
||||
if (preg_match('/^.+?\.([A-Za-z0-9]+)$/', $filename, $matches) === 1) {
|
||||
// we matched on a file extension, so let's see if it means something.
|
||||
$ext = mb_strtolower($matches[1]);
|
||||
@ -888,7 +886,11 @@ class File extends Managed_DataObject
|
||||
echo "\nFound old $table table, upgrading it to contain 'urlhash' field...";
|
||||
|
||||
$file = new File();
|
||||
$file->query(sprintf('SELECT id, LEFT(url, 191) AS shortenedurl, COUNT(*) AS c FROM %1$s WHERE LENGTH(url)>191 GROUP BY shortenedurl HAVING c > 1', $schema->quoteIdentifier($table)));
|
||||
$file->query(sprintf(
|
||||
'SELECT id, LEFT(url, 191) AS shortenedurl, COUNT(*) FROM %1$s ' .
|
||||
'WHERE LENGTH(url) > 191 GROUP BY id, shortenedurl HAVING COUNT(*) > 1',
|
||||
common_database_tablename($table)
|
||||
));
|
||||
print "\nFound {$file->N} URLs with too long entries in file table\n";
|
||||
while ($file->fetch()) {
|
||||
// We've got a URL that is too long for our future file table
|
||||
@ -941,13 +943,20 @@ class File extends Managed_DataObject
|
||||
$tablefix = new $classname;
|
||||
// urlhash is hash('sha256', $url) in the File table
|
||||
echo "Updating urlhash fields in $table table...";
|
||||
// Maybe very MySQL specific :(
|
||||
switch (common_config('db', 'type')) {
|
||||
case 'pgsql':
|
||||
$url_sha256 = 'encode(sha256(CAST("url" AS bytea)), \'hex\')';
|
||||
break;
|
||||
case 'mysql':
|
||||
$url_sha256 = 'sha2(`url`, 256)';
|
||||
break;
|
||||
default:
|
||||
throw new ServerException('Unknown DB type selected.');
|
||||
}
|
||||
$tablefix->query(sprintf(
|
||||
'UPDATE %1$s SET %2$s=%3$s;',
|
||||
$schema->quoteIdentifier($table),
|
||||
'urlhash',
|
||||
// The line below is "result of sha256 on column `url`"
|
||||
'SHA2(url, 256)'
|
||||
'UPDATE %1$s SET urlhash = %2$s;',
|
||||
$tablefix->escapedTableName(),
|
||||
$url_sha256
|
||||
));
|
||||
echo "DONE.\n";
|
||||
echo "Resuming core schema upgrade...";
|
||||
|
@ -1,28 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for file_redirection
|
||||
*/
|
||||
|
||||
class File_redirection extends Managed_DataObject
|
||||
{
|
||||
###START_AUTOCODE
|
||||
@ -54,17 +50,18 @@ class File_redirection extends Managed_DataObject
|
||||
),
|
||||
'primary key' => array('urlhash'),
|
||||
'foreign keys' => array(
|
||||
'file_redirection_file_id_fkey' => array('file' => array('file_id' => 'id')),
|
||||
'file_redirection_file_id_fkey' => array('file', array('file_id' => 'id')),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static public function getByUrl($url)
|
||||
public static function getByUrl($url)
|
||||
{
|
||||
return self::getByPK(array('urlhash' => File::hashurl($url)));
|
||||
}
|
||||
|
||||
static function _commonHttp($url, $redirs) {
|
||||
public static function _commonHttp($url, $redirs)
|
||||
{
|
||||
$request = new HTTPClient($url);
|
||||
$request->setConfig(array(
|
||||
'connect_timeout' => 10, // # seconds to wait
|
||||
@ -96,10 +93,13 @@ class File_redirection extends Managed_DataObject
|
||||
* size (optional): byte size from Content-Length header
|
||||
* time (optional): timestamp from Last-Modified header
|
||||
*/
|
||||
static function lookupWhere($short_url, $redirs = 10, $protected = false) {
|
||||
if ($redirs < 0) return false;
|
||||
public static function lookupWhere($short_url, $redirs = 10, $protected = false)
|
||||
{
|
||||
if ($redirs < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(strpos($short_url,'://') === false){
|
||||
if (strpos($short_url, '://') === false) {
|
||||
return $short_url;
|
||||
}
|
||||
try {
|
||||
@ -128,13 +128,13 @@ class File_redirection extends Managed_DataObject
|
||||
common_log(LOG_ERR, "Error while following redirects for $short_url: " . $e->getMessage());
|
||||
return $short_url;
|
||||
}
|
||||
|
||||
// if last url after all redirections is protected,
|
||||
// use the url before it in the redirection chain
|
||||
|
||||
// if last url after all redirections is protected,
|
||||
// use the url before it in the redirection chain
|
||||
if ($response->getRedirectCount() && File::isProtected($response->getEffectiveUrl())) {
|
||||
$return_url = $response->redirUrls[$response->getRedirectCount()-1];
|
||||
$return_url = $response->redirUrls[$response->getRedirectCount() - 1];
|
||||
} else {
|
||||
$return_url = $response->getEffectiveUrl();
|
||||
$return_url = $response->getEffectiveUrl();
|
||||
}
|
||||
|
||||
$ret = array('code' => $response->getStatus()
|
||||
@ -142,12 +142,20 @@ class File_redirection extends Managed_DataObject
|
||||
, 'url' => $return_url);
|
||||
|
||||
$type = $response->getHeader('Content-Type');
|
||||
if ($type) $ret['type'] = $type;
|
||||
if ($protected) $ret['protected'] = true;
|
||||
if ($type) {
|
||||
$ret['type'] = $type;
|
||||
}
|
||||
if ($protected) {
|
||||
$ret['protected'] = true;
|
||||
}
|
||||
$size = $response->getHeader('Content-Length'); // @fixme bytes?
|
||||
if ($size) $ret['size'] = $size;
|
||||
if ($size) {
|
||||
$ret['size'] = $size;
|
||||
}
|
||||
$time = $response->getHeader('Last-Modified');
|
||||
if ($time) $ret['time'] = strtotime($time);
|
||||
if ($time) {
|
||||
$ret['time'] = strtotime($time);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@ -164,7 +172,8 @@ class File_redirection extends Managed_DataObject
|
||||
* @param boolean $discover true to attempt dereferencing the redirect if we don't know it already
|
||||
* @return File_redirection
|
||||
*/
|
||||
static function where($in_url, $discover=true) {
|
||||
public static function where($in_url, $discover = true)
|
||||
{
|
||||
$redir = new File_redirection();
|
||||
$redir->url = $in_url;
|
||||
$redir->urlhash = File::hashurl($redir->url);
|
||||
@ -179,14 +188,16 @@ class File_redirection extends Managed_DataObject
|
||||
$r->redir_url = $f->url;
|
||||
} catch (NoResultException $e) {
|
||||
// Invalid entry, delete and run again
|
||||
common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File redirection entry and and trying again...");
|
||||
common_log(
|
||||
LOG_ERR,
|
||||
'Could not find File with id=' . $r->file_id . ' referenced in File_redirection, deleting File redirection entry and and trying again...'
|
||||
);
|
||||
$r->delete();
|
||||
return self::where($in_url);
|
||||
return self::where($in_url);
|
||||
}
|
||||
|
||||
// File_redirecion and File record found, return both
|
||||
return $r;
|
||||
|
||||
} catch (NoResultException $e) {
|
||||
// File_redirecion record not found, but this might be a direct link to a file
|
||||
try {
|
||||
@ -194,15 +205,15 @@ class File_redirection extends Managed_DataObject
|
||||
$redir->file_id = $f->id;
|
||||
$redir->file = $f;
|
||||
return $redir;
|
||||
} catch (NoResultException $e) {
|
||||
} catch (NoResultException $e) {
|
||||
// nope, this was not a direct link to a file either, let's keep going
|
||||
}
|
||||
}
|
||||
|
||||
if ($discover) {
|
||||
// try to follow redirects and get the final url
|
||||
if ($discover) {
|
||||
// try to follow redirects and get the final url
|
||||
$redir_info = File_redirection::lookupWhere($in_url);
|
||||
if(is_string($redir_info)) {
|
||||
if (is_string($redir_info)) {
|
||||
$redir_info = array('url' => $redir_info);
|
||||
}
|
||||
|
||||
@ -212,29 +223,32 @@ class File_redirection extends Managed_DataObject
|
||||
try {
|
||||
$r = File_redirection::getByUrl($redir_info['url']);
|
||||
|
||||
$f = File::getKV('id',$r->file_id);
|
||||
$f = File::getKV('id', $r->file_id);
|
||||
|
||||
if($f instanceof File) {
|
||||
if ($f instanceof File) {
|
||||
$redir->file = $f;
|
||||
$redir->redir_url = $f->url;
|
||||
$redir->redir_url = $f->url;
|
||||
} else {
|
||||
// Invalid entry in File_redirection, delete and run again
|
||||
common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File_redirection entry and trying again...");
|
||||
common_log(
|
||||
LOG_ERR,
|
||||
'Could not find File with id=' . $r->file_id . ' referenced in File_redirection, deleting File_redirection entry and trying again...'
|
||||
);
|
||||
$r->delete();
|
||||
return self::where($in_url);
|
||||
return self::where($in_url);
|
||||
}
|
||||
} catch (NoResultException $e) {
|
||||
// save the file now when we know that we don't have it in File_redirection
|
||||
try {
|
||||
$redir->file = File::saveNew($redir_info,$redir_info['url']);
|
||||
$redir->file = File::saveNew($redir_info, $redir_info['url']);
|
||||
} catch (ServerException $e) {
|
||||
common_log(LOG_ERR, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a redirection and we have a file to redirect to, save it
|
||||
// (if it doesn't exist in File_redirection already)
|
||||
if($redir->file instanceof File && $redir_info['url'] != $in_url) {
|
||||
// (if it doesn't exist in File_redirection already)
|
||||
if ($redir->file instanceof File && $redir_info['url'] != $in_url) {
|
||||
try {
|
||||
$file_redir = File_redirection::getByUrl($in_url);
|
||||
} catch (NoResultException $e) {
|
||||
@ -243,12 +257,12 @@ class File_redirection extends Managed_DataObject
|
||||
$file_redir->url = $in_url;
|
||||
$file_redir->file_id = $redir->file->getID();
|
||||
$file_redir->insert();
|
||||
$file_redir->redir_url = $redir->file->url;
|
||||
}
|
||||
$file_redir->redir_url = $redir->file->url;
|
||||
}
|
||||
|
||||
$file_redir->file = $redir->file;
|
||||
return $file_redir;
|
||||
}
|
||||
$file_redir->file = $redir->file;
|
||||
return $file_redir;
|
||||
}
|
||||
}
|
||||
|
||||
return $redir;
|
||||
@ -268,7 +282,7 @@ class File_redirection extends Managed_DataObject
|
||||
* @param User $user whose shortening options to use; defaults to the current web session user
|
||||
* @return string
|
||||
*/
|
||||
static function makeShort($long_url, $user=null)
|
||||
public static function makeShort($long_url, $user = null)
|
||||
{
|
||||
$canon = File_redirection::_canonUrl($long_url);
|
||||
|
||||
@ -293,7 +307,7 @@ class File_redirection extends Managed_DataObject
|
||||
* @return string
|
||||
*/
|
||||
|
||||
static function forceShort($long_url, $user)
|
||||
public static function forceShort($long_url, $user)
|
||||
{
|
||||
$canon = File_redirection::_canonUrl($long_url);
|
||||
|
||||
@ -303,7 +317,8 @@ class File_redirection extends Managed_DataObject
|
||||
return !empty($short_url) ? $short_url : $long_url;
|
||||
}
|
||||
|
||||
static function _userMakeShort($long_url, User $user=null, $force = false) {
|
||||
public static function _userMakeShort($long_url, User $user = null, $force = false)
|
||||
{
|
||||
$short_url = common_shorten_url($long_url, $user, $force);
|
||||
if (!empty($short_url) && $short_url != $long_url) {
|
||||
$short_url = (string)$short_url;
|
||||
@ -343,8 +358,11 @@ class File_redirection extends Managed_DataObject
|
||||
* @param string $default_scheme if given a bare link; defaults to 'http://'
|
||||
* @return string
|
||||
*/
|
||||
static function _canonUrl($in_url, $default_scheme = 'http://') {
|
||||
if (empty($in_url)) return false;
|
||||
public static function _canonUrl($in_url, $default_scheme = 'http://')
|
||||
{
|
||||
if (empty($in_url)) {
|
||||
return false;
|
||||
}
|
||||
$out_url = $in_url;
|
||||
$p = parse_url($out_url);
|
||||
if (empty($p['host']) || empty($p['scheme'])) {
|
||||
@ -377,13 +395,17 @@ class File_redirection extends Managed_DataObject
|
||||
default:
|
||||
$out_url = $default_scheme . ltrim($out_url, '/');
|
||||
$p = parse_url($out_url);
|
||||
if (empty($p['scheme'])) return false;
|
||||
if (empty($p['scheme'])) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (('ftp' == $p['scheme']) || ('ftps' == $p['scheme']) || ('http' == $p['scheme']) || ('https' == $p['scheme'])) {
|
||||
if (empty($p['host'])) return false;
|
||||
if (empty($p['host'])) {
|
||||
return false;
|
||||
}
|
||||
if (empty($p['path'])) {
|
||||
$out_url .= '/';
|
||||
}
|
||||
@ -392,7 +414,8 @@ class File_redirection extends Managed_DataObject
|
||||
return $out_url;
|
||||
}
|
||||
|
||||
static function saveNew($data, $file_id, $url) {
|
||||
public static function saveNew($data, $file_id, $url)
|
||||
{
|
||||
$file_redir = new File_redirection;
|
||||
$file_redir->urlhash = File::hashurl($url);
|
||||
$file_redir->url = $url;
|
||||
@ -402,7 +425,7 @@ class File_redirection extends Managed_DataObject
|
||||
$file_redir->insert();
|
||||
}
|
||||
|
||||
static public function beforeSchemaUpdate()
|
||||
public static function beforeSchemaUpdate()
|
||||
{
|
||||
$table = strtolower(get_called_class());
|
||||
$schema = Schema::get();
|
||||
@ -416,16 +439,16 @@ class File_redirection extends Managed_DataObject
|
||||
echo "\nFound old $table table, upgrading it to contain 'urlhash' field...";
|
||||
// We have to create a urlhash that is _not_ the primary key,
|
||||
// transfer data and THEN run checkSchema
|
||||
$schemadef['fields']['urlhash'] = array (
|
||||
'type' => 'varchar',
|
||||
'length' => 64,
|
||||
'not null' => true,
|
||||
'description' => 'sha256 hash of the URL',
|
||||
);
|
||||
$schemadef['fields']['url'] = array (
|
||||
'type' => 'text',
|
||||
'description' => 'short URL (or any other kind of redirect) for file (id)',
|
||||
);
|
||||
$schemadef['fields']['urlhash'] = [
|
||||
'type' => 'varchar',
|
||||
'length' => 64,
|
||||
'not null' => true,
|
||||
'description' => 'sha256 hash of the URL',
|
||||
];
|
||||
$schemadef['fields']['url'] = [
|
||||
'type' => 'text',
|
||||
'description' => 'short URL (or any other kind of redirect) for file (id)',
|
||||
];
|
||||
unset($schemadef['primary key']);
|
||||
$schema->ensureTable($table, $schemadef);
|
||||
echo "DONE.\n";
|
||||
@ -434,17 +457,27 @@ class File_redirection extends Managed_DataObject
|
||||
$tablefix = new $classname;
|
||||
// urlhash is hash('sha256', $url) in the File table
|
||||
echo "Updating urlhash fields in $table table...";
|
||||
// Maybe very MySQL specific :(
|
||||
$tablefix->query(sprintf('UPDATE %1$s SET %2$s=%3$s;',
|
||||
$schema->quoteIdentifier($table),
|
||||
'urlhash',
|
||||
// The line below is "result of sha256 on column `url`"
|
||||
'SHA2(url, 256)'));
|
||||
switch (common_config('db', 'type')) {
|
||||
case 'pgsql':
|
||||
$url_sha256 = 'encode(sha256(CAST("url" AS bytea)), \'hex\')';
|
||||
break;
|
||||
case 'mysql':
|
||||
$url_sha256 = 'sha2(`url`, 256)';
|
||||
break;
|
||||
default:
|
||||
throw new ServerException('Unknown DB type selected.');
|
||||
}
|
||||
$tablefix->query(sprintf(
|
||||
'UPDATE %1$s SET urlhash = %2$s;',
|
||||
$tablefix->escapedTableName(),
|
||||
$url_sha256
|
||||
));
|
||||
echo "DONE.\n";
|
||||
echo "Resuming core schema upgrade...";
|
||||
}
|
||||
|
||||
public function getFile() {
|
||||
public function getFile()
|
||||
{
|
||||
if (!$this->file instanceof File) {
|
||||
$this->file = File::getByID($this->file_id);
|
||||
}
|
||||
|
@ -1,28 +1,29 @@
|
||||
<?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) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for file_thumbnail
|
||||
*/
|
||||
|
||||
class File_thumbnail extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'file_thumbnail'; // table name
|
||||
@ -44,8 +45,8 @@ class File_thumbnail extends Managed_DataObject
|
||||
'urlhash' => array('type' => 'varchar', 'length' => 64, 'description' => 'sha256 of url field if non-empty'),
|
||||
'url' => array('type' => 'text', 'description' => 'URL of thumbnail'),
|
||||
'filename' => array('type' => 'text', 'description' => 'if stored locally, filename is put here'),
|
||||
'width' => array('type' => 'int', 'description' => 'width of thumbnail'),
|
||||
'height' => array('type' => 'int', 'description' => 'height of thumbnail'),
|
||||
'width' => array('type' => 'int', 'not null' => true, 'description' => 'width of thumbnail'),
|
||||
'height' => array('type' => 'int', 'not null' => true, 'description' => 'height of thumbnail'),
|
||||
'modified' => array('type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'),
|
||||
),
|
||||
'primary key' => array('file_id', 'width', 'height'),
|
||||
@ -65,21 +66,26 @@ class File_thumbnail extends Managed_DataObject
|
||||
* @param object $data
|
||||
* @param int $file_id
|
||||
*/
|
||||
public static function saveNew($data, $file_id) {
|
||||
public static function saveNew($data, $file_id)
|
||||
{
|
||||
if (!empty($data->thumbnail_url)) {
|
||||
// Non-photo types such as video will usually
|
||||
// show us a thumbnail, though it's not required.
|
||||
self::saveThumbnail($file_id,
|
||||
$data->thumbnail_url,
|
||||
$data->thumbnail_width,
|
||||
$data->thumbnail_height);
|
||||
} else if ($data->type == 'photo') {
|
||||
self::saveThumbnail(
|
||||
$file_id,
|
||||
$data->thumbnail_url,
|
||||
$data->thumbnail_width,
|
||||
$data->thumbnail_height
|
||||
);
|
||||
} elseif ($data->type == 'photo') {
|
||||
// The inline photo URL given should also fit within
|
||||
// our requested thumbnail size, per oEmbed spec.
|
||||
self::saveThumbnail($file_id,
|
||||
$data->url,
|
||||
$data->width,
|
||||
$data->height);
|
||||
self::saveThumbnail(
|
||||
$file_id,
|
||||
$data->url,
|
||||
$data->width,
|
||||
$data->height
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +98,8 @@ class File_thumbnail extends Managed_DataObject
|
||||
* @return File_thumbnail
|
||||
* @throws NoResultException if no File_thumbnail matched the criteria
|
||||
*/
|
||||
static function byFile(File $file, $notNullUrl=true) {
|
||||
public static function byFile(File $file, $notNullUrl = true)
|
||||
{
|
||||
$thumb = new File_thumbnail();
|
||||
$thumb->file_id = $file->getID();
|
||||
if ($notNullUrl) {
|
||||
@ -116,7 +123,7 @@ class File_thumbnail extends Managed_DataObject
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
*/
|
||||
static function saveThumbnail($file_id, $url, $width, $height, $filename=null)
|
||||
public static function saveThumbnail($file_id, $url, $width, $height, $filename = null)
|
||||
{
|
||||
$tn = new File_thumbnail;
|
||||
$tn->file_id = $file_id;
|
||||
@ -128,7 +135,7 @@ class File_thumbnail extends Managed_DataObject
|
||||
return $tn;
|
||||
}
|
||||
|
||||
static function path($filename)
|
||||
public static function path($filename)
|
||||
{
|
||||
File::tryFilename($filename);
|
||||
|
||||
@ -142,7 +149,7 @@ class File_thumbnail extends Managed_DataObject
|
||||
return $dir . $filename;
|
||||
}
|
||||
|
||||
static function url($filename)
|
||||
public static function url($filename)
|
||||
{
|
||||
File::tryFilename($filename);
|
||||
|
||||
@ -276,7 +283,7 @@ class File_thumbnail extends Managed_DataObject
|
||||
return $this->file_id;
|
||||
}
|
||||
|
||||
static public function hashurl($url)
|
||||
public static function hashurl($url)
|
||||
{
|
||||
if (!mb_strlen($url)) {
|
||||
throw new Exception('No URL provided to hash algorithm.');
|
||||
|
@ -1,4 +1,21 @@
|
||||
<?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/>.
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for request_queue
|
||||
*/
|
||||
@ -23,7 +40,7 @@ class Group_join_queue extends Managed_DataObject
|
||||
'description' => 'Holder for group join requests awaiting moderation.',
|
||||
'fields' => array(
|
||||
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'remote or local profile making the request'),
|
||||
'group_id' => array('type' => 'int', 'description' => 'remote or local group to join, if any'),
|
||||
'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'remote or local group to join, if any'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'),
|
||||
),
|
||||
'primary key' => array('profile_id', 'group_id'),
|
||||
@ -48,27 +65,27 @@ class Group_join_queue extends Managed_DataObject
|
||||
return $rq;
|
||||
}
|
||||
|
||||
function getMember()
|
||||
public function getMember()
|
||||
{
|
||||
$member = Profile::getKV('id', $this->profile_id);
|
||||
|
||||
if (empty($member)) {
|
||||
// TRANS: Exception thrown providing an invalid profile ID.
|
||||
// TRANS: %s is the invalid profile ID.
|
||||
throw new Exception(sprintf(_('Profile ID %s is invalid.'),$this->profile_id));
|
||||
throw new Exception(sprintf(_('Profile ID %s is invalid.'), $this->profile_id));
|
||||
}
|
||||
|
||||
return $member;
|
||||
}
|
||||
|
||||
function getGroup()
|
||||
public function getGroup()
|
||||
{
|
||||
$group = User_group::getKV('id', $this->group_id);
|
||||
|
||||
if (empty($group)) {
|
||||
// TRANS: Exception thrown providing an invalid group ID.
|
||||
// TRANS: %s is the invalid group ID.
|
||||
throw new Exception(sprintf(_('Group ID %s is invalid.'),$this->group_id));
|
||||
throw new Exception(sprintf(_('Group ID %s is invalid.'), $this->group_id));
|
||||
}
|
||||
|
||||
return $group;
|
||||
@ -77,7 +94,7 @@ class Group_join_queue extends Managed_DataObject
|
||||
/**
|
||||
* Abort the pending group join...
|
||||
*/
|
||||
function abort()
|
||||
public function abort()
|
||||
{
|
||||
$profile = $this->getMember();
|
||||
$group = $this->getGroup();
|
||||
@ -93,7 +110,7 @@ class Group_join_queue extends Managed_DataObject
|
||||
*
|
||||
* @return Group_member object on success
|
||||
*/
|
||||
function complete()
|
||||
public function complete()
|
||||
{
|
||||
$join = null;
|
||||
$profile = $this->getMember();
|
||||
|
@ -1,4 +1,21 @@
|
||||
<?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/>.
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for group_member
|
||||
*/
|
||||
@ -11,7 +28,7 @@ class Group_member extends Managed_DataObject
|
||||
public $__table = 'group_member'; // table name
|
||||
public $group_id; // int(4) primary_key not_null
|
||||
public $profile_id; // int(4) primary_key not_null
|
||||
public $is_admin; // tinyint(1)
|
||||
public $is_admin; // bool default_false
|
||||
public $uri; // varchar(191) not 255 because utf8mb4 takes more space
|
||||
public $created; // datetime() not_null default_0000-00-00%2000%3A00%3A00
|
||||
public $modified; // datetime() not_null default_CURRENT_TIMESTAMP
|
||||
@ -25,7 +42,7 @@ class Group_member extends Managed_DataObject
|
||||
'fields' => array(
|
||||
'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'),
|
||||
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
|
||||
'is_admin' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'is this user an admin?'),
|
||||
'is_admin' => array('type' => 'bool', 'default' => false, 'description' => 'is this user an admin?'),
|
||||
'uri' => array('type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'),
|
||||
@ -54,20 +71,22 @@ class Group_member extends Managed_DataObject
|
||||
*
|
||||
* @param integer $group_id Group to add to
|
||||
* @param integer $profile_id Profile being added
|
||||
*
|
||||
*
|
||||
* @return Group_member new membership object
|
||||
*/
|
||||
|
||||
static function join($group_id, $profile_id)
|
||||
public static function join($group_id, $profile_id)
|
||||
{
|
||||
$member = new Group_member();
|
||||
|
||||
$member->group_id = $group_id;
|
||||
$member->profile_id = $profile_id;
|
||||
$member->created = common_sql_now();
|
||||
$member->uri = self::newUri(Profile::getByID($profile_id),
|
||||
User_group::getByID($group_id),
|
||||
$member->created);
|
||||
$member->uri = self::newUri(
|
||||
Profile::getByID($profile_id),
|
||||
User_group::getByID($group_id),
|
||||
$member->created
|
||||
);
|
||||
|
||||
$result = $member->insert();
|
||||
|
||||
@ -80,7 +99,7 @@ class Group_member extends Managed_DataObject
|
||||
return $member;
|
||||
}
|
||||
|
||||
static function leave($group_id, $profile_id)
|
||||
public static function leave($group_id, $profile_id)
|
||||
{
|
||||
$member = Group_member::pkeyGet(array('group_id' => $group_id,
|
||||
'profile_id' => $profile_id));
|
||||
@ -101,27 +120,27 @@ class Group_member extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
|
||||
function getMember()
|
||||
public function getMember()
|
||||
{
|
||||
$member = Profile::getKV('id', $this->profile_id);
|
||||
|
||||
if (empty($member)) {
|
||||
// TRANS: Exception thrown providing an invalid profile ID.
|
||||
// TRANS: %s is the invalid profile ID.
|
||||
throw new Exception(sprintf(_("Profile ID %s is invalid."),$this->profile_id));
|
||||
throw new Exception(sprintf(_("Profile ID %s is invalid."), $this->profile_id));
|
||||
}
|
||||
|
||||
return $member;
|
||||
}
|
||||
|
||||
function getGroup()
|
||||
public function getGroup()
|
||||
{
|
||||
$group = User_group::getKV('id', $this->group_id);
|
||||
|
||||
if (empty($group)) {
|
||||
// TRANS: Exception thrown providing an invalid group ID.
|
||||
// TRANS: %s is the invalid group ID.
|
||||
throw new Exception(sprintf(_("Group ID %s is invalid."),$this->group_id));
|
||||
throw new Exception(sprintf(_('Group ID %s is invalid.'), $this->group_id));
|
||||
}
|
||||
|
||||
return $group;
|
||||
@ -137,7 +156,7 @@ class Group_member extends Managed_DataObject
|
||||
* @return Group_member stream of memberships, use fetch() to iterate
|
||||
*/
|
||||
|
||||
static function byMember($memberId, $offset=0, $limit=GROUPS_PER_PAGE)
|
||||
public static function byMember($memberId, $offset = 0, $limit = GROUPS_PER_PAGE)
|
||||
{
|
||||
$membership = new Group_member();
|
||||
|
||||
@ -152,7 +171,7 @@ class Group_member extends Managed_DataObject
|
||||
return $membership;
|
||||
}
|
||||
|
||||
function asActivity()
|
||||
public function asActivity()
|
||||
{
|
||||
$member = $this->getMember();
|
||||
|
||||
@ -180,13 +199,19 @@ class Group_member extends Managed_DataObject
|
||||
|
||||
// TRANS: Success message for subscribe to group attempt through OStatus.
|
||||
// TRANS: %1$s is the member name, %2$s is the subscribed group's name.
|
||||
$act->content = sprintf(_('%1$s has joined group %2$s.'),
|
||||
$member->getBestName(),
|
||||
$group->getBestName());
|
||||
$act->content = sprintf(
|
||||
_('%1$s has joined group %2$s.'),
|
||||
$member->getBestName(),
|
||||
$group->getBestName()
|
||||
);
|
||||
|
||||
$url = common_local_url('AtomPubShowMembership',
|
||||
array('profile' => $member->id,
|
||||
'group' => $group->id));
|
||||
$url = common_local_url(
|
||||
'AtomPubShowMembership',
|
||||
[
|
||||
'profile' => $member->id,
|
||||
'group' => $group->id,
|
||||
]
|
||||
);
|
||||
|
||||
$act->selfLink = $url;
|
||||
$act->editLink = $url;
|
||||
@ -203,7 +228,7 @@ class Group_member extends Managed_DataObject
|
||||
mail_notify_group_join($this->getGroup(), $this->getMember());
|
||||
}
|
||||
|
||||
function getUri()
|
||||
public function getUri()
|
||||
{
|
||||
return $this->uri ?: self::newUri($this->getMember(), $this->getGroup()->getProfile(), $this->created);
|
||||
}
|
||||
|
@ -1,28 +1,31 @@
|
||||
<?php
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Wrapper for Memcached_DataObject which knows its own schema definition.
|
||||
* Builds its own damn settings from a schema definition.
|
||||
*
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @package GNUsocial
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @copyright 2010 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
abstract class Managed_DataObject extends Memcached_DataObject
|
||||
{
|
||||
/**
|
||||
@ -42,7 +45,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* @return get_called_class() object if found, or null for no hits
|
||||
*
|
||||
*/
|
||||
static function getKV($k,$v=NULL)
|
||||
public static function getKV($k, $v = null)
|
||||
{
|
||||
return parent::getClassKV(get_called_class(), $k, $v);
|
||||
}
|
||||
@ -59,12 +62,12 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* @return get_called_class() object if found, or null for no hits
|
||||
*
|
||||
*/
|
||||
static function pkeyGet(array $kv)
|
||||
public static function pkeyGet(array $kv)
|
||||
{
|
||||
return parent::pkeyGetClass(get_called_class(), $kv);
|
||||
}
|
||||
|
||||
static function pkeyCols()
|
||||
public static function pkeyCols()
|
||||
{
|
||||
return parent::pkeyColsClass(get_called_class());
|
||||
}
|
||||
@ -78,10 +81,10 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
*
|
||||
* @return array Array of objects, in order
|
||||
*/
|
||||
static function multiGet($keyCol, array $keyVals, $skipNulls=true)
|
||||
{
|
||||
return parent::multiGetClass(get_called_class(), $keyCol, $keyVals, $skipNulls);
|
||||
}
|
||||
public static function multiGet($keyCol, array $keyVals, $skipNulls = true)
|
||||
{
|
||||
return parent::multiGetClass(get_called_class(), $keyCol, $keyVals, $skipNulls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple items from the database by key
|
||||
@ -92,10 +95,10 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
*
|
||||
* @return array Array mapping $keyVals to objects, or null if not found
|
||||
*/
|
||||
static function pivotGet($keyCol, array $keyVals, array $otherCols=array())
|
||||
{
|
||||
return parent::pivotGetClass(get_called_class(), $keyCol, $keyVals, $otherCols);
|
||||
}
|
||||
public static function pivotGet($keyCol, array $keyVals, array $otherCols = [])
|
||||
{
|
||||
return parent::pivotGetClass(get_called_class(), $keyCol, $keyVals, $otherCols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a multi-instance object
|
||||
@ -110,7 +113,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* Exception is thrown when no entries are found.
|
||||
*
|
||||
*/
|
||||
static function listFind($keyCol, array $keyVals)
|
||||
public static function listFind($keyCol, array $keyVals)
|
||||
{
|
||||
return parent::listFindClass(get_called_class(), $keyCol, $keyVals);
|
||||
}
|
||||
@ -128,7 +131,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* @return array with an get_called_class() object for each $keyVals entry
|
||||
*
|
||||
*/
|
||||
static function listGet($keyCol, array $keyVals)
|
||||
public static function listGet($keyCol, array $keyVals)
|
||||
{
|
||||
return parent::listGetClass(get_called_class(), $keyCol, $keyVals);
|
||||
}
|
||||
@ -149,11 +152,11 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* get/set an array of table primary keys
|
||||
*
|
||||
* Key info is pulled from the table definition array.
|
||||
*
|
||||
*
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
function keys()
|
||||
public function keys()
|
||||
{
|
||||
return array_keys($this->keyTypes());
|
||||
}
|
||||
@ -167,7 +170,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* @return array (column,use_native,sequence_name)
|
||||
*/
|
||||
|
||||
function sequenceKey()
|
||||
public function sequenceKey()
|
||||
{
|
||||
$table = static::schemaDef();
|
||||
foreach ($table['fields'] as $name => $column) {
|
||||
@ -191,7 +194,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* @return array key definitions
|
||||
*/
|
||||
|
||||
function keyTypes()
|
||||
public function keyTypes()
|
||||
{
|
||||
$table = static::schemaDef();
|
||||
$keys = array();
|
||||
@ -218,16 +221,17 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* @param array $column
|
||||
* @return int
|
||||
*/
|
||||
function columnBitmap($column)
|
||||
public function columnBitmap($column)
|
||||
{
|
||||
$type = $column['type'];
|
||||
|
||||
// For quoting style...
|
||||
$intTypes = array('int',
|
||||
'integer',
|
||||
'float',
|
||||
'serial',
|
||||
'numeric');
|
||||
$intTypes = [
|
||||
'int',
|
||||
'float',
|
||||
'serial',
|
||||
'numeric'
|
||||
];
|
||||
if (in_array($type, $intTypes)) {
|
||||
$style = DB_DATAOBJECT_INT;
|
||||
} else {
|
||||
@ -235,12 +239,15 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
}
|
||||
|
||||
// Data type formatting style...
|
||||
$formatStyles = array('blob' => DB_DATAOBJECT_BLOB,
|
||||
'text' => DB_DATAOBJECT_TXT,
|
||||
'date' => DB_DATAOBJECT_DATE,
|
||||
'time' => DB_DATAOBJECT_TIME,
|
||||
'datetime' => DB_DATAOBJECT_DATE | DB_DATAOBJECT_TIME,
|
||||
'timestamp' => DB_DATAOBJECT_MYSQLTIMESTAMP);
|
||||
$formatStyles = [
|
||||
'blob' => DB_DATAOBJECT_BLOB,
|
||||
'text' => DB_DATAOBJECT_TXT,
|
||||
'bool' => DB_DATAOBJECT_BOOL,
|
||||
'date' => DB_DATAOBJECT_DATE,
|
||||
'time' => DB_DATAOBJECT_TIME,
|
||||
'datetime' => DB_DATAOBJECT_DATE | DB_DATAOBJECT_TIME,
|
||||
'timestamp' => DB_DATAOBJECT_MYSQLTIMESTAMP,
|
||||
];
|
||||
|
||||
if (isset($formatStyles[$type])) {
|
||||
$style |= $formatStyles[$type];
|
||||
@ -254,7 +261,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
return $style;
|
||||
}
|
||||
|
||||
function links()
|
||||
public function links()
|
||||
{
|
||||
$links = array();
|
||||
|
||||
@ -277,7 +284,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
*
|
||||
* @return array of strings
|
||||
*/
|
||||
function _allCacheKeys()
|
||||
public function _allCacheKeys()
|
||||
{
|
||||
$table = static::schemaDef();
|
||||
$ckeys = array();
|
||||
@ -322,7 +329,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* @return Managed_DataObject of the get_called_class() type
|
||||
* @throws NoResultException if no object with that primary key
|
||||
*/
|
||||
static function getByPK(array $vals)
|
||||
public static function getByPK(array $vals)
|
||||
{
|
||||
$classname = get_called_class();
|
||||
|
||||
@ -356,7 +363,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
* @return Managed_DataObject of the get_called_class() type
|
||||
* @throws NoResultException if no object with that primary key
|
||||
*/
|
||||
static function getByKeys(array $vals)
|
||||
public static function getByKeys(array $vals)
|
||||
{
|
||||
$classname = get_called_class();
|
||||
|
||||
@ -381,7 +388,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
return $object;
|
||||
}
|
||||
|
||||
static function getByID($id)
|
||||
public static function getByID($id)
|
||||
{
|
||||
if (!property_exists(get_called_class(), 'id')) {
|
||||
throw new ServerException('Trying to get undefined property of dataobject class.');
|
||||
@ -394,7 +401,7 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
return static::getByPK(array('id' => $id));
|
||||
}
|
||||
|
||||
static function getByUri($uri)
|
||||
public static function getByUri($uri)
|
||||
{
|
||||
if (!property_exists(get_called_class(), 'uri')) {
|
||||
throw new ServerException('Trying to get undefined property of dataobject class.');
|
||||
@ -537,18 +544,20 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
$pid = $schema['primary key'];
|
||||
unset($schema);
|
||||
}
|
||||
$pidWhere = array();
|
||||
foreach((array)$pid as $pidCol) {
|
||||
$pidWhere = [];
|
||||
foreach ((array) $pid as $pidCol) {
|
||||
$pidWhere[] = sprintf('%1$s = %2$s', $pidCol, $this->_quote($orig->$pidCol));
|
||||
}
|
||||
if (empty($pidWhere)) {
|
||||
throw new ServerException('No primary ID column(s) set for updateWithKeys');
|
||||
}
|
||||
|
||||
$qry = sprintf('UPDATE %1$s SET %2$s WHERE %3$s',
|
||||
common_database_tablename($this->tableName()),
|
||||
implode(', ', $parts),
|
||||
implode(' AND ', $pidWhere));
|
||||
$qry = sprintf(
|
||||
'UPDATE %1$s SET %2$s WHERE %3$s',
|
||||
$this->escapedTableName(),
|
||||
implode(', ', $parts),
|
||||
implode(' AND ', $pidWhere)
|
||||
);
|
||||
|
||||
$result = $this->query($qry);
|
||||
if ($result === false) {
|
||||
@ -576,21 +585,23 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
return $result;
|
||||
}
|
||||
|
||||
static public function beforeSchemaUpdate()
|
||||
public static function beforeSchemaUpdate()
|
||||
{
|
||||
// NOOP
|
||||
}
|
||||
|
||||
static function newUri(Profile $actor, Managed_DataObject $object, $created=null)
|
||||
public static function newUri(Profile $actor, Managed_DataObject $object, $created = null)
|
||||
{
|
||||
if (is_null($created)) {
|
||||
$created = common_sql_now();
|
||||
}
|
||||
return TagURI::mint(strtolower(get_called_class()).':%d:%s:%d:%s',
|
||||
$actor->getID(),
|
||||
ActivityUtils::resolveUri($object->getObjectType(), true),
|
||||
$object->getID(),
|
||||
common_date_iso8601($created));
|
||||
return TagURI::mint(
|
||||
strtolower(get_called_class()) . ':%d:%s:%d:%s',
|
||||
$actor->getID(),
|
||||
ActivityUtils::resolveUri($object->getObjectType(), true),
|
||||
$object->getID(),
|
||||
common_date_iso8601($created)
|
||||
);
|
||||
}
|
||||
|
||||
protected function onInsert()
|
||||
|
@ -1,23 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @copyright 2008, 2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class Memcached_DataObject extends Safe_DataObject
|
||||
{
|
||||
@ -30,7 +32,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
* @param mixed $v key field value, or leave out for primary key lookup
|
||||
* @return mixed Memcached_DataObject subtype or false
|
||||
*/
|
||||
static function getClassKV($cls, $k, $v=null)
|
||||
public static function getClassKV($cls, $k, $v = null)
|
||||
{
|
||||
if (is_null($v)) {
|
||||
$v = $k;
|
||||
@ -71,7 +73,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
*
|
||||
* @return array Array of objects, in order
|
||||
*/
|
||||
static function multiGetClass($cls, $keyCol, array $keyVals, $skipNulls=true)
|
||||
public static function multiGetClass($cls, $keyCol, array $keyVals, $skipNulls = true)
|
||||
{
|
||||
$obj = new $cls;
|
||||
|
||||
@ -100,8 +102,27 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
$keyVals[$key] = $obj->escape($val);
|
||||
}
|
||||
|
||||
// FIND_IN_SET will make sure we keep the desired order
|
||||
$obj->orderBy(sprintf("FIND_IN_SET(%s, '%s')", $keyCol, implode(',', $keyVals)));
|
||||
switch (common_config('db', 'type')) {
|
||||
case 'pgsql':
|
||||
// "position" will make sure we keep the desired order
|
||||
$obj->orderBy(sprintf(
|
||||
"position(',' || CAST(%s AS text) || ',' IN ',%s,')",
|
||||
$keyCol,
|
||||
implode(',', $keyVals)
|
||||
));
|
||||
break;
|
||||
case 'mysql':
|
||||
// "find_in_set" will make sure we keep the desired order
|
||||
$obj->orderBy(sprintf(
|
||||
"find_in_set(%s, '%s')",
|
||||
$keyCol,
|
||||
implode(',', $keyVals)
|
||||
));
|
||||
break;
|
||||
default:
|
||||
throw new ServerException('Unknown DB type selected.');
|
||||
}
|
||||
|
||||
$obj->find();
|
||||
|
||||
return $obj;
|
||||
@ -117,7 +138,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
*
|
||||
* @return array Array mapping $keyVals to objects, or null if not found
|
||||
*/
|
||||
static function pivotGetClass($cls, $keyCol, array $keyVals, array $otherCols = array())
|
||||
public static function pivotGetClass($cls, $keyCol, array $keyVals, array $otherCols = [])
|
||||
{
|
||||
if (is_array($keyCol)) {
|
||||
foreach ($keyVals as $keyVal) {
|
||||
@ -130,7 +151,6 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
$toFetch = array();
|
||||
|
||||
foreach ($keyVals as $keyVal) {
|
||||
|
||||
if (is_array($keyCol)) {
|
||||
$kv = array_combine($keyCol, $keyVal);
|
||||
} else {
|
||||
@ -147,7 +167,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
} else {
|
||||
$result[$keyVal] = $i;
|
||||
}
|
||||
} else if (!empty($keyVal)) {
|
||||
} elseif (!empty($keyVal)) {
|
||||
$toFetch[] = $keyVal;
|
||||
}
|
||||
}
|
||||
@ -207,7 +227,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $result;
|
||||
}
|
||||
|
||||
static function _inMultiKey($i, $cols, $values)
|
||||
public static function _inMultiKey($i, $cols, $values)
|
||||
{
|
||||
$types = array();
|
||||
|
||||
@ -255,7 +275,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $query;
|
||||
}
|
||||
|
||||
static function pkeyColsClass($cls)
|
||||
public static function pkeyColsClass($cls)
|
||||
{
|
||||
$i = new $cls;
|
||||
$types = $i->keyTypes();
|
||||
@ -272,7 +292,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $pkey;
|
||||
}
|
||||
|
||||
static function listFindClass($cls, $keyCol, array $keyVals)
|
||||
public static function listFindClass($cls, $keyCol, array $keyVals)
|
||||
{
|
||||
$i = new $cls;
|
||||
$i->whereAddIn($keyCol, $keyVals, $i->columnType($keyCol));
|
||||
@ -283,7 +303,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $i;
|
||||
}
|
||||
|
||||
static function listGetClass($cls, $keyCol, array $keyVals)
|
||||
public static function listGetClass($cls, $keyCol, array $keyVals)
|
||||
{
|
||||
$pkeyMap = array_fill_keys($keyVals, array());
|
||||
$result = array_fill_keys($keyVals, array());
|
||||
@ -296,7 +316,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
// We only cache keys -- not objects!
|
||||
|
||||
foreach ($keyVals as $keyVal) {
|
||||
$l = self::cacheGet(sprintf("%s:list-ids:%s:%s", strtolower($cls), $keyCol, $keyVal));
|
||||
$l = self::cacheGet(sprintf('%s:list-ids:%s:%s', strtolower($cls), $keyCol, $keyVal));
|
||||
if ($l !== false) {
|
||||
$pkeyMap[$keyVal] = $l;
|
||||
foreach ($l as $pkey) {
|
||||
@ -312,7 +332,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
|
||||
foreach ($pkeyMap as $keyVal => $pkeyList) {
|
||||
foreach ($pkeyList as $pkeyVal) {
|
||||
$i = $keyResults[implode(',',$pkeyVal)];
|
||||
$i = $keyResults[implode(',', $pkeyVal)];
|
||||
if (!empty($i)) {
|
||||
$result[$keyVal][] = $i;
|
||||
}
|
||||
@ -338,15 +358,17 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
// no results found for our keyVals, so we leave them as empty arrays
|
||||
}
|
||||
foreach ($toFetch as $keyVal) {
|
||||
self::cacheSet(sprintf("%s:list-ids:%s:%s", strtolower($cls), $keyCol, $keyVal),
|
||||
$pkeyMap[$keyVal]);
|
||||
self::cacheSet(
|
||||
sprintf("%s:list-ids:%s:%s", strtolower($cls), $keyCol, $keyVal),
|
||||
$pkeyMap[$keyVal]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function columnType($columnName)
|
||||
public function columnType($columnName)
|
||||
{
|
||||
$keys = $this->table();
|
||||
if (!array_key_exists($columnName, $keys)) {
|
||||
@ -365,7 +387,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
/**
|
||||
* @todo FIXME: Should this return false on lookup fail to match getKV?
|
||||
*/
|
||||
static function pkeyGetClass($cls, array $kv)
|
||||
public static function pkeyGetClass($cls, array $kv)
|
||||
{
|
||||
$i = self::multicache($cls, $kv);
|
||||
if ($i !== false) { // false == cache miss
|
||||
@ -395,7 +417,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function insert()
|
||||
public function insert()
|
||||
{
|
||||
$result = parent::insert();
|
||||
if ($result) {
|
||||
@ -405,7 +427,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $result;
|
||||
}
|
||||
|
||||
function update($dataObject=false)
|
||||
public function update($dataObject = false)
|
||||
{
|
||||
if (is_object($dataObject) && $dataObject instanceof Memcached_DataObject) {
|
||||
$dataObject->decache(); # might be different keys
|
||||
@ -418,17 +440,19 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $result;
|
||||
}
|
||||
|
||||
function delete($useWhere=false)
|
||||
public function delete($useWhere = false)
|
||||
{
|
||||
$this->decache(); # while we still have the values!
|
||||
return parent::delete($useWhere);
|
||||
}
|
||||
|
||||
static function memcache() {
|
||||
public static function memcache()
|
||||
{
|
||||
return Cache::instance();
|
||||
}
|
||||
|
||||
static function cacheKey($cls, $k, $v) {
|
||||
public static function cacheKey($cls, $k, $v)
|
||||
{
|
||||
if (is_object($cls) || is_object($k) || (is_object($v) && !($v instanceof DB_DataObject_Cast))) {
|
||||
$e = new Exception();
|
||||
common_log(LOG_ERR, __METHOD__ . ' object in param: ' .
|
||||
@ -438,7 +462,8 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return Cache::key(strtolower($cls).':'.$k.':'.$vstr);
|
||||
}
|
||||
|
||||
static function getcached($cls, $k, $v) {
|
||||
public static function getcached($cls, $k, $v)
|
||||
{
|
||||
$c = self::memcache();
|
||||
if (!$c) {
|
||||
return false;
|
||||
@ -456,7 +481,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function keyTypes()
|
||||
public function keyTypes()
|
||||
{
|
||||
// ini-based classes return number-indexed arrays. handbuilt
|
||||
// classes return column => keytype. Make this uniform.
|
||||
@ -472,18 +497,17 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
global $_DB_DATAOBJECT;
|
||||
if (!isset($_DB_DATAOBJECT['INI'][$this->_database][$this->tableName()."__keys"])) {
|
||||
$this->databaseStructure();
|
||||
|
||||
}
|
||||
return $_DB_DATAOBJECT['INI'][$this->_database][$this->tableName()."__keys"];
|
||||
}
|
||||
|
||||
function encache()
|
||||
public function encache()
|
||||
{
|
||||
$c = self::memcache();
|
||||
|
||||
if (!$c) {
|
||||
return false;
|
||||
} else if ($this->tableName() == 'user' && is_object($this->id)) {
|
||||
} elseif ($this->tableName() === 'user' && is_object($this->id)) {
|
||||
// Special case for User bug
|
||||
$e = new Exception();
|
||||
common_log(LOG_ERR, __METHOD__ . ' caching user with User object as ID ' .
|
||||
@ -498,7 +522,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function decache()
|
||||
public function decache()
|
||||
{
|
||||
$c = self::memcache();
|
||||
|
||||
@ -513,7 +537,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function _allCacheKeys()
|
||||
public function _allCacheKeys()
|
||||
{
|
||||
$ckeys = array();
|
||||
|
||||
@ -524,7 +548,6 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
$pval = array();
|
||||
|
||||
foreach ($types as $key => $type) {
|
||||
|
||||
assert(!empty($key));
|
||||
|
||||
if ($type == 'U') {
|
||||
@ -532,7 +555,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
continue;
|
||||
}
|
||||
$ckeys[] = self::cacheKey($this->tableName(), $key, self::valueString($this->$key));
|
||||
} else if ($type == 'K' || $type == 'N') {
|
||||
} elseif (in_array($type, ['K', 'N'])) {
|
||||
$pkey[] = $key;
|
||||
$pval[] = self::valueString($this->$key);
|
||||
} else {
|
||||
@ -552,7 +575,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $ckeys;
|
||||
}
|
||||
|
||||
static function multicache($cls, $kv)
|
||||
public static function multicache($cls, $kv)
|
||||
{
|
||||
ksort($kv);
|
||||
$c = self::memcache();
|
||||
@ -563,7 +586,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
static function multicacheKey($cls, $kv)
|
||||
public static function multicacheKey($cls, $kv)
|
||||
{
|
||||
ksort($kv);
|
||||
$pkeys = implode(',', array_keys($kv));
|
||||
@ -571,30 +594,35 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return self::cacheKey($cls, $pkeys, $pvals);
|
||||
}
|
||||
|
||||
function getSearchEngine($table)
|
||||
public function getSearchEngine($table)
|
||||
{
|
||||
require_once INSTALLDIR . '/lib/search/search_engines.php';
|
||||
|
||||
if (Event::handle('GetSearchEngine', array($this, $table, &$search_engine))) {
|
||||
if ('mysql' === common_config('db', 'type')) {
|
||||
$type = common_config('search', 'type');
|
||||
if ($type == 'like') {
|
||||
$search_engine = new MySQLLikeSearch($this, $table);
|
||||
} else if ($type == 'fulltext') {
|
||||
$search_engine = new MySQLSearch($this, $table);
|
||||
} else {
|
||||
// Low level exception. No need for i18n as discussed with Brion.
|
||||
throw new ServerException('Unknown search type: ' . $type);
|
||||
if (Event::handle('GetSearchEngine', [$this, $table, &$search_engine])) {
|
||||
$type = common_config('search', 'type');
|
||||
if ($type === 'like') {
|
||||
$search_engine = new SQLLikeSearch($this, $table);
|
||||
} elseif ($type === 'fulltext') {
|
||||
switch (common_config('db', 'type')) {
|
||||
case 'pgsql':
|
||||
$search_engine = new PostgreSQLSearch($this, $table);
|
||||
break;
|
||||
case 'mysql':
|
||||
$search_engine = new MySQLSearch($this, $table);
|
||||
break;
|
||||
default:
|
||||
throw new ServerException('Unknown DB type selected.');
|
||||
}
|
||||
} else {
|
||||
$search_engine = new PGSearch($this, $table);
|
||||
// Low level exception. No need for i18n as discussed with Brion.
|
||||
throw new ServerException('Unknown search type: ' . $type);
|
||||
}
|
||||
}
|
||||
|
||||
return $search_engine;
|
||||
}
|
||||
|
||||
static function cachedQuery($cls, $qry, $expiry=3600)
|
||||
public static function cachedQuery($cls, $qry, $expiry = 3600)
|
||||
{
|
||||
$c = self::memcache();
|
||||
if (!$c) {
|
||||
@ -631,7 +659,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
* @access private
|
||||
* @return mixed none or PEAR_Error
|
||||
*/
|
||||
function _query($string)
|
||||
public function _query($string)
|
||||
{
|
||||
if (common_config('db', 'annotate_queries')) {
|
||||
$string = $this->annotateQuery($string);
|
||||
@ -680,7 +708,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
* @param string $string SQL query string
|
||||
* @return string SQL query string, with a comment in it
|
||||
*/
|
||||
function annotateQuery($string)
|
||||
public function annotateQuery($string)
|
||||
{
|
||||
$ignore = array('annotateQuery',
|
||||
'_query',
|
||||
@ -707,7 +735,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
$here = $frame['class'] . '::' . $func;
|
||||
break;
|
||||
} else if (isset($frame['type']) && $frame['type'] == '->') {
|
||||
} elseif (isset($frame['type']) && $frame['type'] === '->') {
|
||||
if ($frame['object'] === $this && in_array($func, $ignore)) {
|
||||
continue;
|
||||
}
|
||||
@ -736,7 +764,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
|
||||
// Sanitize a query for logging
|
||||
// @fixme don't trim spaces in string literals
|
||||
function sanitizeQuery($string)
|
||||
public function sanitizeQuery($string)
|
||||
{
|
||||
$string = preg_replace('/\s+/', ' ', $string);
|
||||
$string = trim($string);
|
||||
@ -746,7 +774,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
// We overload so that 'SET NAMES "utf8mb4"' is called for
|
||||
// each connection
|
||||
|
||||
function _connect()
|
||||
public function _connect()
|
||||
{
|
||||
global $_DB_DATAOBJECT, $_PEAR;
|
||||
|
||||
@ -757,7 +785,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
$exists = true;
|
||||
} else {
|
||||
$exists = false;
|
||||
}
|
||||
}
|
||||
|
||||
// @fixme horrible evil hack!
|
||||
//
|
||||
@ -794,7 +822,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
if (!empty($conn)) {
|
||||
if ($DB instanceof DB_mysqli || $DB instanceof MDB2_Driver_mysqli) {
|
||||
mysqli_set_charset($conn, 'utf8mb4');
|
||||
} else if ($DB instanceof DB_mysql || $DB instanceof MDB2_Driver_mysql) {
|
||||
} elseif ($DB instanceof DB_mysql || $DB instanceof MDB2_Driver_mysql) {
|
||||
mysql_set_charset('utf8mb4', $conn);
|
||||
}
|
||||
}
|
||||
@ -810,7 +838,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
|
||||
// XXX: largely cadged from DB_DataObject
|
||||
|
||||
function _getDbDsnMD5()
|
||||
public function _getDbDsnMD5()
|
||||
{
|
||||
if ($this->_database_dsn_md5) {
|
||||
return $this->_database_dsn_md5;
|
||||
@ -828,7 +856,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $sum;
|
||||
}
|
||||
|
||||
function _getDbDsn()
|
||||
public function _getDbDsn()
|
||||
{
|
||||
global $_DB_DATAOBJECT;
|
||||
|
||||
@ -843,14 +871,13 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
$dsn = isset($this->_database_dsn) ? $this->_database_dsn : null;
|
||||
|
||||
if (!$dsn) {
|
||||
|
||||
if (!$this->_database) {
|
||||
$this->_database = isset($options["table_{$this->tableName()}"]) ? $options["table_{$this->tableName()}"] : null;
|
||||
}
|
||||
|
||||
if ($this->_database && !empty($options["database_{$this->_database}"])) {
|
||||
if ($this->_database && !empty($options["database_{$this->_database}"])) {
|
||||
$dsn = $options["database_{$this->_database}"];
|
||||
} else if (!empty($options['database'])) {
|
||||
} elseif (!empty($options['database'])) {
|
||||
$dsn = $options['database'];
|
||||
}
|
||||
}
|
||||
@ -863,7 +890,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
static function blow()
|
||||
public static function blow()
|
||||
{
|
||||
$c = self::memcache();
|
||||
|
||||
@ -882,7 +909,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $c->delete($cacheKey);
|
||||
}
|
||||
|
||||
function fixupTimestamps()
|
||||
public function fixupTimestamps()
|
||||
{
|
||||
// Fake up timestamp columns
|
||||
$columns = $this->table();
|
||||
@ -893,12 +920,12 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function debugDump()
|
||||
public function debugDump()
|
||||
{
|
||||
common_debug("debugDump: " . common_log_objstring($this));
|
||||
}
|
||||
|
||||
function raiseError($message, $type = null, $behaviour = null)
|
||||
public function raiseError($message, $type = null, $behavior = null)
|
||||
{
|
||||
$id = get_class($this);
|
||||
if (!empty($this->id)) {
|
||||
@ -911,7 +938,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
throw new ServerException("[$id] DB_DataObject error [$type]: $message");
|
||||
}
|
||||
|
||||
static function cacheGet($keyPart)
|
||||
public static function cacheGet($keyPart)
|
||||
{
|
||||
$c = self::memcache();
|
||||
|
||||
@ -924,7 +951,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $c->get($cacheKey);
|
||||
}
|
||||
|
||||
static function cacheSet($keyPart, $value, $flag=null, $expiry=null)
|
||||
public static function cacheSet($keyPart, $value, $flag = null, $expiry = null)
|
||||
{
|
||||
$c = self::memcache();
|
||||
|
||||
@ -937,7 +964,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $c->set($cacheKey, $value, $flag, $expiry);
|
||||
}
|
||||
|
||||
static function valueString($v)
|
||||
public static function valueString($v)
|
||||
{
|
||||
$vstr = null;
|
||||
if (is_object($v) && $v instanceof DB_DataObject_Cast) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,32 +1,32 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* GNU social
|
||||
*
|
||||
* Data class for Notice preferences
|
||||
*
|
||||
* 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 Data
|
||||
* @package GNUsocial
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2013 Free Software Foundation, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://www.gnu.org/software/social/
|
||||
* @author Diogo Cordeiro <diogo@fc.up.pt>
|
||||
* @copyright 2013 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class Notice_prefs extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'notice_prefs'; // table name
|
||||
@ -58,7 +58,7 @@ class Notice_prefs extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
static function getNamespacePrefs(Notice $notice, $namespace, array $topic=array())
|
||||
public static function getNamespacePrefs(Notice $notice, $namespace, array $topic = [])
|
||||
{
|
||||
if (empty($topic)) {
|
||||
$prefs = new Notice_prefs();
|
||||
@ -76,13 +76,13 @@ class Notice_prefs extends Managed_DataObject
|
||||
return $prefs;
|
||||
}
|
||||
|
||||
static function getNamespace(Notice $notice, $namespace, array $topic=array())
|
||||
public static function getNamespace(Notice $notice, $namespace, array $topic = [])
|
||||
{
|
||||
$prefs = self::getNamespacePrefs($notice, $namespace, $topic);
|
||||
return $prefs->fetchAll();
|
||||
}
|
||||
|
||||
static function getAll(Notice $notice)
|
||||
public static function getAll(Notice $notice)
|
||||
{
|
||||
try {
|
||||
$prefs = self::listFind('notice_id', array($notice->getID()));
|
||||
@ -100,13 +100,17 @@ class Notice_prefs extends Managed_DataObject
|
||||
return $list;
|
||||
}
|
||||
|
||||
static function getTopic(Notice $notice, $namespace, $topic) {
|
||||
return self::getByPK(array('notice_id' => $notice->getID(),
|
||||
'namespace' => $namespace,
|
||||
'topic' => $topic));
|
||||
public static function getTopic(Notice $notice, $namespace, $topic)
|
||||
{
|
||||
return self::getByPK([
|
||||
'notice_id' => $notice->getID(),
|
||||
'namespace' => $namespace,
|
||||
'topic' => $topic,
|
||||
]);
|
||||
}
|
||||
|
||||
static function getData(Notice $notice, $namespace, $topic, $def=null) {
|
||||
public static function getData(Notice $notice, $namespace, $topic, $def = null)
|
||||
{
|
||||
try {
|
||||
$pref = self::getTopic($notice, $namespace, $topic);
|
||||
} catch (NoResultException $e) {
|
||||
@ -120,7 +124,8 @@ class Notice_prefs extends Managed_DataObject
|
||||
return $pref->data;
|
||||
}
|
||||
|
||||
static function getConfigData(Notice $notice, $namespace, $topic) {
|
||||
public static function getConfigData(Notice $notice, $namespace, $topic)
|
||||
{
|
||||
try {
|
||||
$data = self::getData($notice, $namespace, $topic);
|
||||
} catch (NoResultException $e) {
|
||||
@ -140,14 +145,15 @@ class Notice_prefs extends Managed_DataObject
|
||||
* @return true if changes are made, false if no action taken
|
||||
* @throws ServerException if preference could not be saved
|
||||
*/
|
||||
static function setData(Notice $notice, $namespace, $topic, $data=null) {
|
||||
public static function setData(Notice $notice, $namespace, $topic, $data = null)
|
||||
{
|
||||
try {
|
||||
$pref = self::getTopic($notice, $namespace, $topic);
|
||||
if (is_null($data)) {
|
||||
$pref->delete();
|
||||
} else {
|
||||
$orig = clone($pref);
|
||||
$pref->data = $data;
|
||||
$pref->data = DB_DataObject_Cast::blob($data);
|
||||
$pref->update($orig);
|
||||
}
|
||||
return true;
|
||||
@ -161,7 +167,7 @@ class Notice_prefs extends Managed_DataObject
|
||||
$pref->notice_id = $notice->getID();
|
||||
$pref->namespace = $namespace;
|
||||
$pref->topic = $topic;
|
||||
$pref->data = $data;
|
||||
$pref->data = DB_DataObject_Cast::blob($data);
|
||||
$pref->created = common_sql_now();
|
||||
|
||||
if ($pref->insert() === false) {
|
||||
|
@ -1,9 +1,26 @@
|
||||
<?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/>.
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||
|
||||
/**
|
||||
* Table Definition for notice_source
|
||||
*/
|
||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||
|
||||
class Notice_source extends Managed_DataObject
|
||||
{
|
||||
###START_AUTOCODE
|
||||
@ -26,7 +43,7 @@ class Notice_source extends Managed_DataObject
|
||||
'code' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'source code'),
|
||||
'name' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'name of the source'),
|
||||
'url' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'url to link to'),
|
||||
'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'date this record was created'),
|
||||
'notice_id' => array('type' => 'int', 'not null' => true, 'default' => 0, 'description' => 'date this record was created'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'),
|
||||
),
|
||||
|
@ -1,9 +1,26 @@
|
||||
<?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/>.
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||
|
||||
/**
|
||||
* Table Definition for oauth_application_user
|
||||
*/
|
||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||
|
||||
class Oauth_application_user extends Managed_DataObject
|
||||
{
|
||||
###START_AUTOCODE
|
||||
@ -39,7 +56,7 @@ class Oauth_application_user extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
static function getByUserAndToken($user, $token)
|
||||
public static function getByUserAndToken($user, $token)
|
||||
{
|
||||
if (empty($user) || empty($token)) {
|
||||
return null;
|
||||
@ -56,7 +73,7 @@ class Oauth_application_user extends Managed_DataObject
|
||||
return empty($result) ? null : $oau;
|
||||
}
|
||||
|
||||
function updateKeys(&$orig)
|
||||
public function updateKeys(&$orig)
|
||||
{
|
||||
$this->_connect();
|
||||
$parts = array();
|
||||
@ -72,13 +89,11 @@ class Oauth_application_user extends Managed_DataObject
|
||||
$toupdate = implode(', ', $parts);
|
||||
|
||||
$table = $this->tableName();
|
||||
if(common_config('db','quote_identifiers')) {
|
||||
$table = '"' . $table . '"';
|
||||
}
|
||||
$qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
|
||||
' WHERE profile_id = ' . $orig->profile_id
|
||||
. ' AND application_id = ' . $orig->application_id
|
||||
. " AND token = '$orig->token'";
|
||||
$tableName = $this->escapedTableName();
|
||||
$qry = 'UPDATE ' . $tableName . ' SET ' . $toupdate .
|
||||
' WHERE profile_id = ' . $orig->profile_id .
|
||||
' AND application_id = ' . $orig->application_id .
|
||||
" AND token = '" . $orig->token . "'";
|
||||
$orig->decache();
|
||||
$result = $this->query($qry);
|
||||
if ($result) {
|
||||
|
@ -1,9 +1,26 @@
|
||||
<?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/>.
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||
|
||||
/**
|
||||
* Table Definition for oauth_association
|
||||
*/
|
||||
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||
|
||||
class Oauth_token_association extends Managed_DataObject
|
||||
{
|
||||
###START_AUTOCODE
|
||||
@ -19,7 +36,7 @@ class Oauth_token_association extends Managed_DataObject
|
||||
/* the code above is auto generated do not remove the tag below */
|
||||
###END_AUTOCODE
|
||||
|
||||
static function getByUserAndToken($user, $token)
|
||||
public static function getByUserAndToken($user, $token)
|
||||
{
|
||||
if (empty($user) || empty($token)) {
|
||||
return null;
|
||||
@ -49,8 +66,8 @@ class Oauth_token_association extends Managed_DataObject
|
||||
),
|
||||
'primary key' => array('profile_id', 'application_id', 'token'),
|
||||
'foreign keys' => array(
|
||||
'oauth_token_association_profile_fkey' => array('profile_id', array('profile' => 'id')),
|
||||
'oauth_token_association_application_fkey' => array('application_id', array('application' => 'id')),
|
||||
'oauth_token_association_profile_fkey' => array('profile', array('profile_id' => 'id')),
|
||||
'oauth_token_association_application_fkey' => array('oauth_application', array('application_id' => 'id')),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -1,48 +1,36 @@
|
||||
<?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) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Older-style UI preferences
|
||||
*
|
||||
* 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 UI
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
// This check helps protect against security problems;
|
||||
// your code file can't be executed directly from the web.
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Separate table for storing UI preferences
|
||||
*
|
||||
* @category UI
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class Old_school_prefs extends Managed_DataObject
|
||||
@ -60,17 +48,14 @@ class Old_school_prefs extends Managed_DataObject
|
||||
return array(
|
||||
'fields' => array(
|
||||
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user who has the preference'),
|
||||
'stream_mode_only' => array('type' => 'int',
|
||||
'size' => 'tiny',
|
||||
'default' => 1,
|
||||
'stream_mode_only' => array('type' => 'bool',
|
||||
'default' => true,
|
||||
'description' => 'No conversation streams'),
|
||||
'conversation_tree' => array('type' => 'int',
|
||||
'size' => 'tiny',
|
||||
'default' => 1,
|
||||
'conversation_tree' => array('type' => 'bool',
|
||||
'default' => true,
|
||||
'description' => 'Hierarchical tree view for conversations'),
|
||||
'stream_nicknames' => array('type' => 'int',
|
||||
'size' => 'tiny',
|
||||
'default' => 1,
|
||||
'stream_nicknames' => array('type' => 'bool',
|
||||
'default' => true,
|
||||
'description' => 'Show nicknames for authors and addressees in streams'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'),
|
||||
|
@ -1,23 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008-2011, 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/>.
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @copyright 2008-2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for profile
|
||||
@ -81,7 +83,7 @@ class Profile extends Managed_DataObject
|
||||
throw new NoSuchUserException(array('email'=>$email));
|
||||
}
|
||||
return $user->getProfile();
|
||||
}
|
||||
}
|
||||
|
||||
protected $_user = array();
|
||||
|
||||
@ -202,16 +204,16 @@ class Profile extends Managed_DataObject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getBestName()
|
||||
public function getBestName()
|
||||
{
|
||||
return ($this->fullname) ? $this->fullname : $this->nickname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the currently scoped profile into account to give a name
|
||||
* Takes the currently scoped profile into account to give a name
|
||||
* to list in notice streams. Preferences may differ between profiles.
|
||||
*/
|
||||
function getStreamName()
|
||||
public function getStreamName()
|
||||
{
|
||||
$user = common_current_user();
|
||||
if ($user instanceof User && $user->streamNicknames()) {
|
||||
@ -228,7 +230,7 @@ class Profile extends Managed_DataObject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getFancyName()
|
||||
public function getFancyName()
|
||||
{
|
||||
$uri = null;
|
||||
try {
|
||||
@ -243,7 +245,7 @@ class Profile extends Managed_DataObject
|
||||
|
||||
if (mb_strlen($this->getFullname()) > 0) {
|
||||
// TRANS: The "fancy name": Full name of a profile or group (%1$s) followed by some URI (%2$s) in parentheses.
|
||||
return sprintf(_m('FANCYNAME','%1$s (%2$s)'), $this->getFullname(), $uri);
|
||||
return sprintf(_m('FANCYNAME', '%1$s (%2$s)'), $this->getFullname(), $uri);
|
||||
} else {
|
||||
return $uri;
|
||||
}
|
||||
@ -254,7 +256,7 @@ class Profile extends Managed_DataObject
|
||||
*
|
||||
* @return mixed Notice or null
|
||||
*/
|
||||
function getCurrentNotice(Profile $scoped=null)
|
||||
public function getCurrentNotice(Profile $scoped = null)
|
||||
{
|
||||
try {
|
||||
$notice = $this->getNotices(0, 1, 0, 0, $scoped);
|
||||
@ -271,16 +273,16 @@ class Profile extends Managed_DataObject
|
||||
// Maybe we should let this through if it's handled well upstream
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0)
|
||||
public function getReplies($offset = 0, $limit = NOTICES_PER_PAGE, $since_id = 0, $before_id = 0)
|
||||
{
|
||||
return Reply::stream($this->getID(), $offset, $limit, $since_id, $before_id);
|
||||
}
|
||||
|
||||
function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
|
||||
public function getTaggedNotices($tag, $offset = 0, $limit = NOTICES_PER_PAGE, $since_id = 0, $max_id = 0)
|
||||
{
|
||||
//FIXME: Get Profile::current() some other way to avoid possible
|
||||
// confusion between current session profile and background processing.
|
||||
@ -289,39 +291,39 @@ class Profile extends Managed_DataObject
|
||||
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
||||
}
|
||||
|
||||
function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, Profile $scoped=null)
|
||||
public function getNotices($offset = 0, $limit = NOTICES_PER_PAGE, $since_id = 0, $max_id = 0, Profile $scoped = null)
|
||||
{
|
||||
$stream = new ProfileNoticeStream($this, $scoped);
|
||||
|
||||
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
||||
}
|
||||
|
||||
function isMember(User_group $group)
|
||||
public function isMember(User_group $group)
|
||||
{
|
||||
$groups = $this->getGroups(0, null);
|
||||
$groups = $this->getGroups(0, null);
|
||||
while ($groups instanceof User_group && $groups->fetch()) {
|
||||
if ($groups->id == $group->id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if ($groups->id == $group->id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAdmin(User_group $group)
|
||||
public function isAdmin(User_group $group)
|
||||
{
|
||||
$gm = Group_member::pkeyGet(array('profile_id' => $this->id,
|
||||
'group_id' => $group->id));
|
||||
return (!empty($gm) && $gm->is_admin);
|
||||
}
|
||||
|
||||
function isPendingMember($group)
|
||||
public function isPendingMember($group)
|
||||
{
|
||||
$request = Group_join_queue::pkeyGet(array('profile_id' => $this->id,
|
||||
'group_id' => $group->id));
|
||||
return !empty($request);
|
||||
}
|
||||
|
||||
function getGroups($offset=0, $limit=PROFILES_PER_PAGE)
|
||||
public function getGroups($offset = 0, $limit = PROFILES_PER_PAGE)
|
||||
{
|
||||
$ids = array();
|
||||
|
||||
@ -356,14 +358,15 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function getGroupCount() {
|
||||
public function getGroupCount()
|
||||
{
|
||||
$groups = $this->getGroups(0, null);
|
||||
return $groups instanceof User_group
|
||||
? $groups->N
|
||||
: 0;
|
||||
}
|
||||
|
||||
function isTagged($peopletag)
|
||||
public function isTagged($peopletag)
|
||||
{
|
||||
$tag = Profile_tag::pkeyGet(array('tagger' => $peopletag->tagger,
|
||||
'tagged' => $this->id,
|
||||
@ -371,7 +374,7 @@ class Profile extends Managed_DataObject
|
||||
return !empty($tag);
|
||||
}
|
||||
|
||||
function canTag($tagged)
|
||||
public function canTag($tagged)
|
||||
{
|
||||
if (empty($tagged)) {
|
||||
return false;
|
||||
@ -395,16 +398,16 @@ class Profile extends Managed_DataObject
|
||||
if ($local) {
|
||||
return true;
|
||||
}
|
||||
} else if ($subs) {
|
||||
} elseif ($subs) {
|
||||
return (Subscription::exists($this, $tagged) ||
|
||||
Subscription::exists($tagged, $this));
|
||||
} else if ($remote) {
|
||||
} elseif ($remote) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getLists(Profile $scoped=null, $offset=0, $limit=null, $since_id=0, $max_id=0)
|
||||
public function getLists(Profile $scoped = null, $offset = 0, $limit = null, $since_id = 0, $max_id = 0)
|
||||
{
|
||||
$ids = array();
|
||||
|
||||
@ -421,15 +424,15 @@ class Profile extends Managed_DataObject
|
||||
$list->tagger = $this->id;
|
||||
$list->selectAdd('id as "cursor"');
|
||||
|
||||
if ($since_id>0) {
|
||||
$list->whereAdd('id > '.$since_id);
|
||||
if ($since_id > 0) {
|
||||
$list->whereAdd('id > ' . $since_id);
|
||||
}
|
||||
|
||||
if ($max_id>0) {
|
||||
$list->whereAdd('id <= '.$max_id);
|
||||
if ($max_id > 0) {
|
||||
$list->whereAdd('id <= ' . $max_id);
|
||||
}
|
||||
|
||||
if($offset>=0 && !is_null($limit)) {
|
||||
if ($offset >= 0 && !is_null($limit)) {
|
||||
$list->limit($offset, $limit);
|
||||
}
|
||||
|
||||
@ -452,7 +455,6 @@ class Profile extends Managed_DataObject
|
||||
$list = Profile_list::getKV('id', $id);
|
||||
if (!empty($list) &&
|
||||
($showPrivate || !$list->private)) {
|
||||
|
||||
if (!isset($list->cursor)) {
|
||||
$list->cursor = $list->id;
|
||||
}
|
||||
@ -476,33 +478,47 @@ class Profile extends Managed_DataObject
|
||||
* @return Profile_list resulting lists
|
||||
*/
|
||||
|
||||
function getOtherTags(Profile $scoped=null, $offset=0, $limit=null, $since_id=0, $max_id=0)
|
||||
public function getOtherTags(Profile $scoped = null, int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
|
||||
{
|
||||
$list = new Profile_list();
|
||||
|
||||
$qry = sprintf('select profile_list.*, unix_timestamp(profile_tag.modified) as "cursor" ' .
|
||||
'from profile_tag join profile_list '.
|
||||
'on (profile_tag.tagger = profile_list.tagger ' .
|
||||
' and profile_tag.tag = profile_list.tag) ' .
|
||||
'where profile_tag.tagged = %d ',
|
||||
$this->id);
|
||||
if (common_config('db', 'type') !== 'mysql') {
|
||||
$cursor = sprintf(
|
||||
'((EXTRACT(DAY %1$s) * 24 + EXTRACT(HOUR %1$s)) * 60 + ' .
|
||||
'EXTRACT(MINUTE %1$s)) * 60 + FLOOR(EXTRACT(SECOND %1$s)) AS "cursor"',
|
||||
"FROM (profile_tag.modified - TIMESTAMP '1970-01-01 00:00:00')"
|
||||
);
|
||||
} else {
|
||||
// The SQL/Foundation conforming implementation above doesn't work on MariaDB/MySQL
|
||||
$cursor = "timestampdiff(SECOND, '1970-01-01', profile_tag.modified) AS `cursor`";
|
||||
}
|
||||
|
||||
$qry = sprintf(
|
||||
'SELECT profile_list.*, ' . $cursor . ' ' .
|
||||
'FROM profile_tag INNER JOIN profile_list ' .
|
||||
'ON (profile_tag.tagger = profile_list.tagger ' .
|
||||
' AND profile_tag.tag = profile_list.tag) ' .
|
||||
'WHERE profile_tag.tagged = %d ',
|
||||
$this->id
|
||||
);
|
||||
|
||||
if (!is_null($scoped)) {
|
||||
$qry .= sprintf('AND ( ( profile_list.private = false ) ' .
|
||||
'OR ( profile_list.tagger = %d AND ' .
|
||||
'profile_list.private = true ) )',
|
||||
$scoped->getID());
|
||||
$qry .= sprintf(
|
||||
'AND ( profile_list.private = false ' .
|
||||
'OR ( profile_list.tagger = %d AND ' .
|
||||
'profile_list.private = TRUE ) )',
|
||||
$scoped->getID()
|
||||
);
|
||||
} else {
|
||||
$qry .= 'AND profile_list.private = 0 ';
|
||||
$qry .= 'AND profile_list.private = FALSE ';
|
||||
}
|
||||
|
||||
if ($since_id > 0) {
|
||||
$qry .= sprintf('AND (cursor > %d) ', $since_id);
|
||||
if ($since > 0) {
|
||||
$qry .= 'AND cursor > ' . $since . ' ';
|
||||
}
|
||||
|
||||
if ($max_id > 0) {
|
||||
$qry .= sprintf('AND (cursor < %d) ', $max_id);
|
||||
if ($upto > 0) {
|
||||
$qry .= 'AND cursor < ' . $upto . ' ';
|
||||
}
|
||||
|
||||
$qry .= 'ORDER BY profile_tag.modified DESC ';
|
||||
@ -515,21 +531,21 @@ class Profile extends Managed_DataObject
|
||||
return $list;
|
||||
}
|
||||
|
||||
function getPrivateTags($offset=0, $limit=null, $since_id=0, $max_id=0)
|
||||
public function getPrivateTags($offset = 0, $limit = null, $since_id = 0, $max_id = 0)
|
||||
{
|
||||
$tags = new Profile_list();
|
||||
$tags->private = true;
|
||||
$tags->tagger = $this->id;
|
||||
|
||||
if ($since_id>0) {
|
||||
$tags->whereAdd('id > '.$since_id);
|
||||
if ($since_id > 0) {
|
||||
$tags->whereAdd('id > ' . $since_id);
|
||||
}
|
||||
|
||||
if ($max_id>0) {
|
||||
$tags->whereAdd('id <= '.$max_id);
|
||||
if ($max_id > 0) {
|
||||
$tags->whereAdd('id <= ' . $max_id);
|
||||
}
|
||||
|
||||
if($offset>=0 && !is_null($limit)) {
|
||||
if ($offset >= 0 && !is_null($limit)) {
|
||||
$tags->limit($offset, $limit);
|
||||
}
|
||||
|
||||
@ -539,13 +555,13 @@ class Profile extends Managed_DataObject
|
||||
return $tags;
|
||||
}
|
||||
|
||||
function hasLocalTags()
|
||||
public function hasLocalTags()
|
||||
{
|
||||
$tags = new Profile_tag();
|
||||
|
||||
$tags->joinAdd(array('tagger', 'user:id'));
|
||||
$tags->whereAdd('tagged = '.$this->id);
|
||||
$tags->whereAdd('tagger != '.$this->id);
|
||||
$tags->whereAdd('tagged = ' . $this->id);
|
||||
$tags->whereAdd('tagger <> ' . $this->id);
|
||||
|
||||
$tags->limit(0, 1);
|
||||
$tags->fetch();
|
||||
@ -553,31 +569,38 @@ class Profile extends Managed_DataObject
|
||||
return ($tags->N == 0) ? false : true;
|
||||
}
|
||||
|
||||
function getTagSubscriptions($offset=0, $limit=null, $since_id=0, $max_id=0)
|
||||
public function getTagSubscriptions(int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
|
||||
{
|
||||
$lists = new Profile_list();
|
||||
$subs = new Profile_tag_subscription();
|
||||
|
||||
$lists->joinAdd(array('id', 'profile_tag_subscription:profile_tag_id'));
|
||||
$lists->joinAdd(['id', 'profile_tag_subscription:profile_tag_id']);
|
||||
|
||||
#@fixme: postgres (round(date_part('epoch', my_date)))
|
||||
$lists->selectAdd('unix_timestamp(profile_tag_subscription.created) as "cursor"');
|
||||
if (common_config('db', 'type') !== 'mysql') {
|
||||
$lists->selectAdd(sprintf(
|
||||
'((EXTRACT(DAY %1$s) * 24 + EXTRACT(HOUR %1$s)) * 60 + ' .
|
||||
'EXTRACT(MINUTE %1$s)) * 60 + FLOOR(EXTRACT(SECOND %1$s)) AS "cursor"',
|
||||
"FROM (profile_tag_subscription.created - TIMESTAMP '1970-01-01 00:00:00')"
|
||||
));
|
||||
} else {
|
||||
$lists->selectAdd("timestampdiff(SECOND, '1970-01-01', profile_tag_subscription.created) AS `cursor`");
|
||||
}
|
||||
|
||||
$lists->whereAdd('profile_tag_subscription.profile_id = '.$this->id);
|
||||
|
||||
if ($since_id>0) {
|
||||
$lists->whereAdd('cursor > '.$since_id);
|
||||
if ($since > 0) {
|
||||
$lists->whereAdd('cursor > ' . $since);
|
||||
}
|
||||
|
||||
if ($max_id>0) {
|
||||
$lists->whereAdd('cursor <= '.$max_id);
|
||||
if ($upto > 0) {
|
||||
$lists->whereAdd('cursor <= ' . $upto);
|
||||
}
|
||||
|
||||
if($offset>=0 && !is_null($limit)) {
|
||||
if ($offset >= 0 && !is_null($limit)) {
|
||||
$lists->limit($offset, $limit);
|
||||
}
|
||||
|
||||
$lists->orderBy('"cursor" DESC');
|
||||
$lists->orderBy('profile_tag_subscription.created DESC');
|
||||
$lists->find();
|
||||
|
||||
return $lists;
|
||||
@ -590,7 +613,7 @@ class Profile extends Managed_DataObject
|
||||
* @param User_group $group
|
||||
* @return mixed: Group_member on success, Group_join_queue if pending approval, null on some cancels?
|
||||
*/
|
||||
function joinGroup(User_group $group)
|
||||
public function joinGroup(User_group $group)
|
||||
{
|
||||
$join = null;
|
||||
if ($group->join_policy == User_group::JOIN_POLICY_MODERATE) {
|
||||
@ -616,7 +639,7 @@ class Profile extends Managed_DataObject
|
||||
*
|
||||
* @param User_group $group
|
||||
*/
|
||||
function leaveGroup(User_group $group)
|
||||
public function leaveGroup(User_group $group)
|
||||
{
|
||||
if (Event::handle('StartLeaveGroup', array($group, $this))) {
|
||||
Group_member::leave($group->id, $this->id);
|
||||
@ -627,12 +650,12 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function avatarUrl($size=AVATAR_PROFILE_SIZE)
|
||||
public function avatarUrl($size = AVATAR_PROFILE_SIZE)
|
||||
{
|
||||
return Avatar::urlByProfile($this, $size);
|
||||
}
|
||||
|
||||
function getSubscribed($offset=0, $limit=null)
|
||||
public function getSubscribed($offset = 0, $limit = null)
|
||||
{
|
||||
$subs = Subscription::getSubscribedIDs($this->id, $offset, $limit);
|
||||
try {
|
||||
@ -643,7 +666,7 @@ class Profile extends Managed_DataObject
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
function getSubscribers($offset=0, $limit=null)
|
||||
public function getSubscribers($offset = 0, $limit = null)
|
||||
{
|
||||
$subs = Subscription::getSubscriberIDs($this->id, $offset, $limit);
|
||||
try {
|
||||
@ -654,7 +677,7 @@ class Profile extends Managed_DataObject
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
function getTaggedSubscribers($tag, $offset=0, $limit=null)
|
||||
public function getTaggedSubscribers($tag, $offset = 0, $limit = null)
|
||||
{
|
||||
$qry =
|
||||
'SELECT profile.* ' .
|
||||
@ -664,7 +687,7 @@ class Profile extends Managed_DataObject
|
||||
'AND profile_tag.tagger = subscription.subscribed) ' .
|
||||
'WHERE subscription.subscribed = %d ' .
|
||||
"AND profile_tag.tag = '%s' " .
|
||||
'AND subscription.subscribed != subscription.subscriber ' .
|
||||
'AND subscription.subscribed <> subscription.subscriber ' .
|
||||
'ORDER BY subscription.created DESC ';
|
||||
|
||||
if ($offset) {
|
||||
@ -678,7 +701,7 @@ class Profile extends Managed_DataObject
|
||||
return $profile;
|
||||
}
|
||||
|
||||
function getTaggedSubscriptions($tag, $offset=0, $limit=null)
|
||||
public function getTaggedSubscriptions($tag, $offset = 0, $limit = null)
|
||||
{
|
||||
$qry =
|
||||
'SELECT profile.* ' .
|
||||
@ -688,7 +711,7 @@ class Profile extends Managed_DataObject
|
||||
'AND profile_tag.tagger = subscription.subscriber) ' .
|
||||
'WHERE subscription.subscriber = %d ' .
|
||||
"AND profile_tag.tag = '%s' " .
|
||||
'AND subscription.subscribed != subscription.subscriber ' .
|
||||
'AND subscription.subscribed <> subscription.subscriber ' .
|
||||
'ORDER BY subscription.created DESC ';
|
||||
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
@ -707,7 +730,7 @@ class Profile extends Managed_DataObject
|
||||
* @param int $limit
|
||||
* @return Profile
|
||||
*/
|
||||
function getRequests($offset=0, $limit=null)
|
||||
public function getRequests($offset = 0, $limit = null)
|
||||
{
|
||||
// FIXME: mysql only
|
||||
$subqueue = new Profile();
|
||||
@ -721,7 +744,7 @@ class Profile extends Managed_DataObject
|
||||
return $subqueue;
|
||||
}
|
||||
|
||||
function subscriptionCount()
|
||||
public function subscriptionCount()
|
||||
{
|
||||
$c = Cache::instance();
|
||||
|
||||
@ -749,7 +772,7 @@ class Profile extends Managed_DataObject
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
function subscriberCount()
|
||||
public function subscriberCount()
|
||||
{
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
@ -761,8 +784,8 @@ class Profile extends Managed_DataObject
|
||||
|
||||
$sub = new Subscription();
|
||||
$sub->subscribed = $this->id;
|
||||
$sub->whereAdd('subscriber != subscribed');
|
||||
$cnt = (int) $sub->count('distinct subscriber');
|
||||
$sub->whereAdd('subscriber <> subscribed');
|
||||
$cnt = (int) $sub->count('DISTINCT subscriber');
|
||||
|
||||
if (!empty($c)) {
|
||||
$c->set(Cache::key('profile:subscriber_count:'.$this->id), $cnt);
|
||||
@ -777,12 +800,12 @@ class Profile extends Managed_DataObject
|
||||
* @param Profile $other
|
||||
* @return boolean
|
||||
*/
|
||||
function isSubscribed(Profile $other)
|
||||
public function isSubscribed(Profile $other)
|
||||
{
|
||||
return Subscription::exists($this, $other);
|
||||
}
|
||||
|
||||
function readableBy(Profile $other=null)
|
||||
public function readableBy(Profile $other = null)
|
||||
{
|
||||
// If it's not a private stream, it's readable by anyone
|
||||
if (!$this->isPrivateStream()) {
|
||||
@ -793,7 +816,7 @@ class Profile extends Managed_DataObject
|
||||
return is_null($other) ? false : $other->isSubscribed($this);
|
||||
}
|
||||
|
||||
function requiresSubscriptionApproval(Profile $other=null): bool
|
||||
public function requiresSubscriptionApproval(Profile $other = null): bool
|
||||
{
|
||||
if (!$this->isLocal()) {
|
||||
// We don't know for remote users, and we'll always be able to send
|
||||
@ -818,7 +841,7 @@ class Profile extends Managed_DataObject
|
||||
* @param Profile $other
|
||||
* @return boolean
|
||||
*/
|
||||
function hasPendingSubscription(Profile $other)
|
||||
public function hasPendingSubscription(Profile $other)
|
||||
{
|
||||
return Subscription_queue::exists($this, $other);
|
||||
}
|
||||
@ -829,13 +852,13 @@ class Profile extends Managed_DataObject
|
||||
* @param Profile $other
|
||||
* @return boolean
|
||||
*/
|
||||
function mutuallySubscribed(Profile $other)
|
||||
public function mutuallySubscribed(Profile $other)
|
||||
{
|
||||
return $this->isSubscribed($other) &&
|
||||
$other->isSubscribed($this);
|
||||
}
|
||||
|
||||
function noticeCount()
|
||||
public function noticeCount()
|
||||
{
|
||||
$c = Cache::instance();
|
||||
|
||||
@ -858,7 +881,7 @@ class Profile extends Managed_DataObject
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
function blowSubscriberCount()
|
||||
public function blowSubscriberCount()
|
||||
{
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
@ -866,7 +889,7 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function blowSubscriptionCount()
|
||||
public function blowSubscriptionCount()
|
||||
{
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
@ -874,7 +897,7 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function blowNoticeCount()
|
||||
public function blowNoticeCount()
|
||||
{
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
@ -882,7 +905,7 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
static function maxBio()
|
||||
public static function maxBio()
|
||||
{
|
||||
$biolimit = common_config('profile', 'biolimit');
|
||||
// null => use global limit (distinct from 0!)
|
||||
@ -892,13 +915,13 @@ class Profile extends Managed_DataObject
|
||||
return $biolimit;
|
||||
}
|
||||
|
||||
static function bioTooLong($bio)
|
||||
public static function bioTooLong($bio)
|
||||
{
|
||||
$biolimit = self::maxBio();
|
||||
return ($biolimit > 0 && !empty($bio) && (mb_strlen($bio) > $biolimit));
|
||||
}
|
||||
|
||||
function update($dataObject=false)
|
||||
public function update($dataObject = false)
|
||||
{
|
||||
if (is_object($dataObject) && $this->nickname != $dataObject->nickname) {
|
||||
try {
|
||||
@ -946,7 +969,7 @@ class Profile extends Managed_DataObject
|
||||
return $relMes;
|
||||
}
|
||||
|
||||
function delete($useWhere=false)
|
||||
public function delete($useWhere = false)
|
||||
{
|
||||
$this->_deleteNotices();
|
||||
$this->_deleteSubscriptions();
|
||||
@ -957,10 +980,11 @@ class Profile extends Managed_DataObject
|
||||
|
||||
// Warning: delete() will run on the batch objects,
|
||||
// not on individual objects.
|
||||
$related = array('Reply',
|
||||
'Group_member',
|
||||
'Profile_role'
|
||||
);
|
||||
$related = [
|
||||
'Reply',
|
||||
'Group_member',
|
||||
'Profile_role',
|
||||
];
|
||||
Event::handle('ProfileDeleteRelated', array($this, &$related));
|
||||
|
||||
foreach ($related as $cls) {
|
||||
@ -968,7 +992,7 @@ class Profile extends Managed_DataObject
|
||||
$inst->profile_id = $this->id;
|
||||
$inst->delete();
|
||||
}
|
||||
|
||||
|
||||
$this->grantRole(Profile_role::DELETED);
|
||||
|
||||
$localuser = User::getKV('id', $this->id);
|
||||
@ -979,7 +1003,7 @@ class Profile extends Managed_DataObject
|
||||
return parent::delete($useWhere);
|
||||
}
|
||||
|
||||
function _deleteNotices()
|
||||
public function _deleteNotices()
|
||||
{
|
||||
$notice = new Notice();
|
||||
$notice->profile_id = $this->id;
|
||||
@ -992,7 +1016,7 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function _deleteSubscriptions()
|
||||
public function _deleteSubscriptions()
|
||||
{
|
||||
$sub = new Subscription();
|
||||
$sub->subscriber = $this->getID();
|
||||
@ -1040,14 +1064,14 @@ class Profile extends Managed_DataObject
|
||||
$self->delete();
|
||||
}
|
||||
|
||||
function _deleteTags()
|
||||
public function _deleteTags()
|
||||
{
|
||||
$tag = new Profile_tag();
|
||||
$tag->tagged = $this->id;
|
||||
$tag->delete();
|
||||
}
|
||||
|
||||
function _deleteBlocks()
|
||||
public function _deleteBlocks()
|
||||
{
|
||||
$block = new Profile_block();
|
||||
$block->blocked = $this->id;
|
||||
@ -1058,7 +1082,7 @@ class Profile extends Managed_DataObject
|
||||
$block->delete();
|
||||
}
|
||||
|
||||
function _deleteAttentions()
|
||||
public function _deleteAttentions()
|
||||
{
|
||||
$att = new Attention();
|
||||
$att->profile_id = $this->getID();
|
||||
@ -1103,7 +1127,7 @@ class Profile extends Managed_DataObject
|
||||
|
||||
if ($cfg == 'always') {
|
||||
return true;
|
||||
} else if ($cfg == 'never') {
|
||||
} elseif ($cfg == 'never') {
|
||||
return false;
|
||||
} else { // user
|
||||
$share = common_config('location', 'sharedefault');
|
||||
@ -1120,7 +1144,7 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function hasRole($name)
|
||||
public function hasRole($name)
|
||||
{
|
||||
$has_role = false;
|
||||
if (Event::handle('StartHasRole', array($this, $name, &$has_role))) {
|
||||
@ -1132,10 +1156,9 @@ class Profile extends Managed_DataObject
|
||||
return $has_role;
|
||||
}
|
||||
|
||||
function grantRole($name)
|
||||
public function grantRole($name)
|
||||
{
|
||||
if (Event::handle('StartGrantRole', array($this, $name))) {
|
||||
|
||||
$role = new Profile_role();
|
||||
|
||||
$role->profile_id = $this->id;
|
||||
@ -1158,17 +1181,20 @@ class Profile extends Managed_DataObject
|
||||
return $result;
|
||||
}
|
||||
|
||||
function revokeRole($name)
|
||||
public function revokeRole($name)
|
||||
{
|
||||
if (Event::handle('StartRevokeRole', array($this, $name))) {
|
||||
|
||||
$role = Profile_role::pkeyGet(array('profile_id' => $this->id,
|
||||
'role' => $name));
|
||||
|
||||
if (empty($role)) {
|
||||
// TRANS: Exception thrown when trying to revoke an existing role for a user that does not exist.
|
||||
// TRANS: %1$s is the role name, %2$s is the user ID (number).
|
||||
throw new Exception(sprintf(_('Cannot revoke role "%1$s" for user #%2$d; does not exist.'),$name, $this->id));
|
||||
throw new Exception(sprintf(
|
||||
_('Cannot revoke role "%1$s" for user #%2$d; does not exist.'),
|
||||
$name,
|
||||
$this->id
|
||||
));
|
||||
}
|
||||
|
||||
$result = $role->delete();
|
||||
@ -1177,7 +1203,11 @@ class Profile extends Managed_DataObject
|
||||
common_log_db_error($role, 'DELETE', __FILE__);
|
||||
// TRANS: Exception thrown when trying to revoke a role for a user with a failing database query.
|
||||
// TRANS: %1$s is the role name, %2$s is the user ID (number).
|
||||
throw new Exception(sprintf(_('Cannot revoke role "%1$s" for user #%2$d; database error.'),$name, $this->id));
|
||||
throw new Exception(sprintf(
|
||||
_('Cannot revoke role "%1$s" for user #%2$d; database error.'),
|
||||
$name,
|
||||
$this->id
|
||||
));
|
||||
}
|
||||
|
||||
if ($name == 'owner') {
|
||||
@ -1190,27 +1220,27 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function isSandboxed()
|
||||
public function isSandboxed()
|
||||
{
|
||||
return $this->hasRole(Profile_role::SANDBOXED);
|
||||
}
|
||||
|
||||
function isSilenced()
|
||||
public function isSilenced()
|
||||
{
|
||||
return $this->hasRole(Profile_role::SILENCED);
|
||||
}
|
||||
|
||||
function sandbox()
|
||||
public function sandbox()
|
||||
{
|
||||
$this->grantRole(Profile_role::SANDBOXED);
|
||||
}
|
||||
|
||||
function unsandbox()
|
||||
public function unsandbox()
|
||||
{
|
||||
$this->revokeRole(Profile_role::SANDBOXED);
|
||||
}
|
||||
|
||||
function silence()
|
||||
public function silence()
|
||||
{
|
||||
$this->grantRole(Profile_role::SILENCED);
|
||||
if (common_config('notice', 'hidespam')) {
|
||||
@ -1218,7 +1248,7 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function silenceAs(Profile $actor)
|
||||
public function silenceAs(Profile $actor)
|
||||
{
|
||||
if (!$actor->hasRight(Right::SILENCEUSER)) {
|
||||
throw new AuthorizationException(_('You cannot silence users on this site.'));
|
||||
@ -1234,7 +1264,7 @@ class Profile extends Managed_DataObject
|
||||
return $this->silence();
|
||||
}
|
||||
|
||||
function unsilence()
|
||||
public function unsilence()
|
||||
{
|
||||
$this->revokeRole(Profile_role::SILENCED);
|
||||
if (common_config('notice', 'hidespam')) {
|
||||
@ -1242,7 +1272,7 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function unsilenceAs(Profile $actor)
|
||||
public function unsilenceAs(Profile $actor)
|
||||
{
|
||||
if (!$actor->hasRight(Right::SILENCEUSER)) {
|
||||
// TRANS: Client error displayed trying to unsilence a user when the user does not have the right.
|
||||
@ -1255,7 +1285,7 @@ class Profile extends Managed_DataObject
|
||||
return $this->unsilence();
|
||||
}
|
||||
|
||||
function flushVisibility()
|
||||
public function flushVisibility()
|
||||
{
|
||||
// Get all notices
|
||||
$stream = new ProfileNoticeStream($this, $this);
|
||||
@ -1301,8 +1331,7 @@ class Profile extends Managed_DataObject
|
||||
}
|
||||
|
||||
if (Event::handle('UserRightsCheck', array($this, $right, &$result))) {
|
||||
switch ($right)
|
||||
{
|
||||
switch ($right) {
|
||||
case Right::DELETEOTHERSNOTICE:
|
||||
case Right::MAKEGROUPADMIN:
|
||||
case Right::SANDBOXUSER:
|
||||
@ -1380,7 +1409,7 @@ class Profile extends Managed_DataObject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function asAtomAuthor($cur = null)
|
||||
public function asAtomAuthor($cur = null)
|
||||
{
|
||||
$xs = new XMLStringer(true);
|
||||
|
||||
@ -1388,7 +1417,7 @@ class Profile extends Managed_DataObject
|
||||
$xs->element('name', null, $this->nickname);
|
||||
$xs->element('uri', null, $this->getUri());
|
||||
if ($cur != null) {
|
||||
$attrs = Array();
|
||||
$attrs = [];
|
||||
$attrs['following'] = $cur->isSubscribed($this) ? 'true' : 'false';
|
||||
$attrs['blocking'] = $cur->hasBlocked($this) ? 'true' : 'false';
|
||||
$xs->element('statusnet:profile_info', $attrs, null);
|
||||
@ -1409,7 +1438,7 @@ class Profile extends Managed_DataObject
|
||||
* @return array representation of <statusnet:profile_info> element or null
|
||||
*/
|
||||
|
||||
function profileInfo(Profile $scoped=null)
|
||||
public function profileInfo(Profile $scoped = null)
|
||||
{
|
||||
$profileInfoAttr = array('local_id' => $this->id);
|
||||
|
||||
@ -1431,7 +1460,7 @@ class Profile extends Managed_DataObject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function asActivityActor()
|
||||
public function asActivityActor()
|
||||
{
|
||||
return $this->asActivityNoun('actor');
|
||||
}
|
||||
@ -1447,7 +1476,7 @@ class Profile extends Managed_DataObject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function asActivityNoun($element)
|
||||
public function asActivityNoun($element)
|
||||
{
|
||||
$noun = $this->asActivityObject();
|
||||
return $noun->asString('activity:' . $element);
|
||||
@ -1619,7 +1648,7 @@ class Profile extends Managed_DataObject
|
||||
return $scheme ? $acct : mb_substr($acct, 5);
|
||||
}
|
||||
|
||||
function hasBlocked(Profile $other)
|
||||
public function hasBlocked(Profile $other)
|
||||
{
|
||||
$block = Profile_block::exists($this, $other);
|
||||
return !empty($block);
|
||||
@ -1652,7 +1681,7 @@ class Profile extends Managed_DataObject
|
||||
*
|
||||
* @param string $uri A unique identifier for a resource (profile/group/whatever)
|
||||
*/
|
||||
static function fromUri($uri)
|
||||
public static function fromUri($uri)
|
||||
{
|
||||
$profile = null;
|
||||
|
||||
@ -1677,7 +1706,7 @@ class Profile extends Managed_DataObject
|
||||
return $profile;
|
||||
}
|
||||
|
||||
function canRead(Notice $notice)
|
||||
public function canRead(Notice $notice)
|
||||
{
|
||||
if ($notice->scope & Notice::SITE_SCOPE) {
|
||||
$user = $this->getUser();
|
||||
@ -1717,7 +1746,7 @@ class Profile extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
|
||||
static function current()
|
||||
public static function current()
|
||||
{
|
||||
$user = common_current_user();
|
||||
if (empty($user)) {
|
||||
@ -1728,7 +1757,7 @@ class Profile extends Managed_DataObject
|
||||
return $profile;
|
||||
}
|
||||
|
||||
static function ensureCurrent()
|
||||
public static function ensureCurrent()
|
||||
{
|
||||
$profile = self::current();
|
||||
if (!$profile instanceof Profile) {
|
||||
@ -1747,7 +1776,7 @@ class Profile extends Managed_DataObject
|
||||
* @return array of variable names to include in serialization.
|
||||
*/
|
||||
|
||||
function __sleep()
|
||||
public function __sleep()
|
||||
{
|
||||
$vars = parent::__sleep();
|
||||
$skip = array('_user', '_group');
|
||||
@ -1802,11 +1831,13 @@ class Profile extends Managed_DataObject
|
||||
return !is_null($private_stream) && $private_stream;
|
||||
}
|
||||
|
||||
public function delPref($namespace, $topic) {
|
||||
public function delPref($namespace, $topic)
|
||||
{
|
||||
return Profile_prefs::setData($this, $namespace, $topic, null);
|
||||
}
|
||||
|
||||
public function getPref($namespace, $topic, $default=null) {
|
||||
public function getPref($namespace, $topic, $default = null)
|
||||
{
|
||||
// If you want an exception to be thrown, call Profile_prefs::getData directly
|
||||
try {
|
||||
return Profile_prefs::getData($this, $namespace, $topic, $default);
|
||||
@ -1821,7 +1852,8 @@ class Profile extends Managed_DataObject
|
||||
return Profile_prefs::getConfigData($this, $namespace, $topic);
|
||||
}
|
||||
|
||||
public function setPref($namespace, $topic, $data) {
|
||||
public function setPref($namespace, $topic, $data)
|
||||
{
|
||||
return Profile_prefs::setData($this, $namespace, $topic, $data);
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,28 @@
|
||||
<?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
|
||||
*
|
||||
* 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 Notices
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||
* @category Notices
|
||||
* @package GNUsocial
|
||||
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class Profile_list extends Managed_DataObject
|
||||
{
|
||||
@ -30,7 +31,7 @@ class Profile_list extends Managed_DataObject
|
||||
public $tagger; // int(4)
|
||||
public $tag; // varchar(64)
|
||||
public $description; // text
|
||||
public $private; // tinyint(1)
|
||||
public $private; // bool default_false
|
||||
public $created; // datetime() not_null default_0000-00-00%2000%3A00%3A00
|
||||
public $modified; // datetime() not_null default_CURRENT_TIMESTAMP
|
||||
public $uri; // varchar(191) unique_key not 255 because utf8mb4 takes more space
|
||||
@ -46,7 +47,7 @@ class Profile_list extends Managed_DataObject
|
||||
'tagger' => array('type' => 'int', 'not null' => true, 'description' => 'user making the tag'),
|
||||
'tag' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'people tag'),
|
||||
'description' => array('type' => 'text', 'description' => 'description of the people tag'),
|
||||
'private' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'is this tag private'),
|
||||
'private' => array('type' => 'bool', 'default' => false, 'description' => 'is this tag private'),
|
||||
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date the tag was added'),
|
||||
'modified' => array('type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date the tag was modified'),
|
||||
@ -58,7 +59,8 @@ class Profile_list extends Managed_DataObject
|
||||
),
|
||||
'primary key' => array('tagger', 'tag'),
|
||||
'unique keys' => array(
|
||||
'profile_list_id_key' => array('id')
|
||||
'profile_list_id_key' => array('id'),
|
||||
'profile_list_tag_key' => array('tag'),
|
||||
),
|
||||
'foreign keys' => array(
|
||||
'profile_list_tagger_fkey' => array('profile', array('tagger' => 'id')),
|
||||
@ -79,7 +81,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return Profile the tagger
|
||||
*/
|
||||
|
||||
function getTagger()
|
||||
public function getTagger()
|
||||
{
|
||||
return Profile::getByID($this->tagger);
|
||||
}
|
||||
@ -91,7 +93,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return String
|
||||
*/
|
||||
|
||||
function getBestName()
|
||||
public function getBestName()
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
@ -102,15 +104,17 @@ class Profile_list extends Managed_DataObject
|
||||
* @return String uri
|
||||
*/
|
||||
|
||||
function getUri()
|
||||
public function getUri()
|
||||
{
|
||||
$uri = null;
|
||||
if (Event::handle('StartProfiletagGetUri', array($this, &$uri))) {
|
||||
if (!empty($this->uri)) {
|
||||
$uri = $this->uri;
|
||||
} else {
|
||||
$uri = common_local_url('profiletagbyid',
|
||||
array('id' => $this->id, 'tagger_id' => $this->tagger));
|
||||
$uri = common_local_url(
|
||||
'profiletagbyid',
|
||||
['id' => $this->id, 'tagger_id' => $this->tagger]
|
||||
);
|
||||
}
|
||||
}
|
||||
Event::handle('EndProfiletagGetUri', array($this, &$uri));
|
||||
@ -123,7 +127,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return String home url
|
||||
*/
|
||||
|
||||
function homeUrl()
|
||||
public function homeUrl()
|
||||
{
|
||||
$url = null;
|
||||
if (Event::handle('StartUserPeopletagHomeUrl', array($this, &$url))) {
|
||||
@ -131,9 +135,13 @@ class Profile_list extends Managed_DataObject
|
||||
if (!empty($this->mainpage)) {
|
||||
$url = $this->mainpage;
|
||||
} else {
|
||||
$url = common_local_url('showprofiletag',
|
||||
array('nickname' => $this->getTagger()->nickname,
|
||||
'tag' => $this->tag));
|
||||
$url = common_local_url(
|
||||
'showprofiletag',
|
||||
[
|
||||
'nickname' => $this->getTagger()->nickname,
|
||||
'tag' => $this->tag,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
Event::handle('EndUserPeopletagHomeUrl', array($this, &$url));
|
||||
@ -146,12 +154,14 @@ class Profile_list extends Managed_DataObject
|
||||
* @return String permalink
|
||||
*/
|
||||
|
||||
function permalink()
|
||||
public function permalink()
|
||||
{
|
||||
$url = null;
|
||||
if (Event::handle('StartProfiletagPermalink', array($this, &$url))) {
|
||||
$url = common_local_url('profiletagbyid',
|
||||
array('id' => $this->id));
|
||||
$url = common_local_url(
|
||||
'profiletagbyid',
|
||||
['id' => $this->id]
|
||||
);
|
||||
}
|
||||
Event::handle('EndProfiletagPermalink', array($this, &$url));
|
||||
return $url;
|
||||
@ -169,7 +179,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return Notice the query
|
||||
*/
|
||||
|
||||
function getNotices($offset, $limit, $since_id=null, $max_id=null)
|
||||
public function getNotices($offset, $limit, $since_id = null, $max_id = null)
|
||||
{
|
||||
// FIXME: Use something else than Profile::current() to avoid
|
||||
// possible confusion between session user and queue processing.
|
||||
@ -190,7 +200,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return Profile results
|
||||
*/
|
||||
|
||||
function getSubscribers($offset=0, $limit=null, $since=0, $upto=0)
|
||||
public function getSubscribers(int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
|
||||
{
|
||||
$subs = new Profile();
|
||||
|
||||
@ -199,8 +209,15 @@ class Profile_list extends Managed_DataObject
|
||||
);
|
||||
$subs->whereAdd('profile_tag_subscription.profile_tag_id = ' . $this->id);
|
||||
|
||||
$subs->selectAdd('unix_timestamp(profile_tag_subscription.' .
|
||||
'created) as "cursor"');
|
||||
if (common_config('db', 'type') !== 'mysql') {
|
||||
$subs->selectAdd(sprintf(
|
||||
'((EXTRACT(DAY %1$s) * 24 + EXTRACT(HOUR %1$s)) * 60 + ' .
|
||||
'EXTRACT(MINUTE %1$s)) * 60 + FLOOR(EXTRACT(SECOND %1$s)) AS "cursor"',
|
||||
"FROM (profile_tag_subscription.created - TIMESTAMP '1970-01-01 00:00:00')"
|
||||
));
|
||||
} else {
|
||||
$subs->selectAdd("timestampdiff(SECOND, '1970-01-01', profile_tag_subscription.created) AS `cursor`");
|
||||
}
|
||||
|
||||
if ($since != 0) {
|
||||
$subs->whereAdd('cursor > ' . $since);
|
||||
@ -227,24 +244,22 @@ class Profile_list extends Managed_DataObject
|
||||
* @return array ids of users
|
||||
*/
|
||||
|
||||
function getUserSubscribers()
|
||||
public function getUserSubscribers()
|
||||
{
|
||||
// XXX: cache this
|
||||
|
||||
$user = new User();
|
||||
if(common_config('db','quote_identifiers'))
|
||||
$user_table = '"user"';
|
||||
else $user_table = 'user';
|
||||
|
||||
$qry =
|
||||
'SELECT id ' .
|
||||
'FROM '. $user_table .' JOIN profile_tag_subscription '.
|
||||
'ON '. $user_table .'.id = profile_tag_subscription.profile_id ' .
|
||||
'WHERE profile_tag_subscription.profile_tag_id = %d ';
|
||||
$user->query(sprintf(
|
||||
'SELECT id ' .
|
||||
'FROM %1$s INNER JOIN profile_tag_subscription ' .
|
||||
'ON %1$s.id = profile_tag_subscription.profile_id ' .
|
||||
'WHERE profile_tag_subscription.profile_tag_id = %2$d ',
|
||||
$user->escapedTableName(),
|
||||
$this->id
|
||||
));
|
||||
|
||||
$user->query(sprintf($qry, $this->id));
|
||||
|
||||
$ids = array();
|
||||
$ids = [];
|
||||
|
||||
while ($user->fetch()) {
|
||||
$ids[] = $user->id;
|
||||
@ -264,7 +279,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return boolean subscription status
|
||||
*/
|
||||
|
||||
function hasSubscriber($id)
|
||||
public function hasSubscriber($id)
|
||||
{
|
||||
if (!is_numeric($id)) {
|
||||
$id = $id->id;
|
||||
@ -288,13 +303,21 @@ class Profile_list extends Managed_DataObject
|
||||
* @return Profile results
|
||||
*/
|
||||
|
||||
function getTagged($offset=0, $limit=null, $since=0, $upto=0)
|
||||
public function getTagged(int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
|
||||
{
|
||||
$tagged = new Profile();
|
||||
$tagged->joinAdd(array('id', 'profile_tag:tagged'));
|
||||
$tagged->joinAdd(['id', 'profile_tag:tagged']);
|
||||
|
||||
if (common_config('db', 'type') !== 'mysql') {
|
||||
$tagged->selectAdd(sprintf(
|
||||
'((EXTRACT(DAY %1$s) * 24 + EXTRACT(HOUR %1$s)) * 60 + ' .
|
||||
'EXTRACT(MINUTE %1$s)) * 60 + FLOOR(EXTRACT(SECOND %1$s)) AS "cursor"',
|
||||
"FROM (profile_tag.modified - TIMESTAMP '1970-01-01 00:00:00')"
|
||||
));
|
||||
} else {
|
||||
$tagged->selectAdd("timestampdiff(SECOND, '1970-01-01', profile_tag.modified) AS `cursor`");
|
||||
}
|
||||
|
||||
#@fixme: postgres
|
||||
$tagged->selectAdd('unix_timestamp(profile_tag.modified) as "cursor"');
|
||||
$tagged->whereAdd('profile_tag.tagger = '.$this->tagger);
|
||||
$tagged->whereAdd("profile_tag.tag = '{$this->tag}'");
|
||||
|
||||
@ -323,7 +346,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return boolean success
|
||||
*/
|
||||
|
||||
function delete($useWhere=false)
|
||||
public function delete($useWhere = false)
|
||||
{
|
||||
// force delete one item at a time.
|
||||
if (empty($this->id)) {
|
||||
@ -350,7 +373,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return boolean success
|
||||
*/
|
||||
|
||||
function update($dataObject=false)
|
||||
public function update($dataObject = false)
|
||||
{
|
||||
if (!is_object($dataObject) && !$dataObject instanceof Profile_list) {
|
||||
return parent::update($dataObject);
|
||||
@ -361,9 +384,9 @@ class Profile_list extends Managed_DataObject
|
||||
// if original tag was different
|
||||
// check to see if the new tag already exists
|
||||
// if not, rename the tag correctly
|
||||
if($dataObject->tag != $this->tag || $dataObject->tagger != $this->tagger) {
|
||||
if ($dataObject->tag != $this->tag || $dataObject->tagger != $this->tagger) {
|
||||
$existing = Profile_list::getByTaggerAndTag($this->tagger, $this->tag);
|
||||
if(!empty($existing)) {
|
||||
if (!empty($existing)) {
|
||||
// TRANS: Server exception.
|
||||
throw new ServerException(_('The tag you are trying to rename ' .
|
||||
'to already exists.'));
|
||||
@ -382,7 +405,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return string atom author element
|
||||
*/
|
||||
|
||||
function asAtomAuthor()
|
||||
public function asAtomAuthor()
|
||||
{
|
||||
$xs = new XMLStringer(true);
|
||||
|
||||
@ -404,7 +427,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return string activitystreams noun
|
||||
*/
|
||||
|
||||
function asActivityNoun($element)
|
||||
public function asActivityNoun($element)
|
||||
{
|
||||
$noun = ActivityObject::fromPeopletag($this);
|
||||
return $noun->asString('activity:' . $element);
|
||||
@ -419,11 +442,13 @@ class Profile_list extends Managed_DataObject
|
||||
* @return integer count
|
||||
*/
|
||||
|
||||
function taggedCount($recount=false)
|
||||
public function taggedCount($recount = false)
|
||||
{
|
||||
$keypart = sprintf('profile_list:tagged_count:%d:%s',
|
||||
$this->tagger,
|
||||
$this->tag);
|
||||
$keypart = sprintf(
|
||||
'profile_list:tagged_count:%d:%s',
|
||||
$this->tagger,
|
||||
$this->tag
|
||||
);
|
||||
|
||||
$count = self::cacheGet($keypart);
|
||||
|
||||
@ -450,15 +475,16 @@ class Profile_list extends Managed_DataObject
|
||||
* @return integer count
|
||||
*/
|
||||
|
||||
function subscriberCount($recount=false)
|
||||
public function subscriberCount($recount = false)
|
||||
{
|
||||
$keypart = sprintf('profile_list:subscriber_count:%d',
|
||||
$this->id);
|
||||
$keypart = sprintf(
|
||||
'profile_list:subscriber_count:%d',
|
||||
$this->id
|
||||
);
|
||||
|
||||
$count = self::cacheGet($keypart);
|
||||
|
||||
if ($count === false) {
|
||||
|
||||
$sub = new Profile_tag_subscription();
|
||||
$sub->profile_tag_id = $this->id;
|
||||
$count = (int) $sub->count('distinct profile_id');
|
||||
@ -478,7 +504,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return integer count
|
||||
*/
|
||||
|
||||
function blowNoticeStreamCache($all=false)
|
||||
public function blowNoticeStreamCache($all = false)
|
||||
{
|
||||
self::blow('profile_list:notice_ids:%d', $this->id);
|
||||
if ($all) {
|
||||
@ -496,7 +522,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return integer count
|
||||
*/
|
||||
|
||||
static function getByTaggerAndTag($tagger, $tag)
|
||||
public static function getByTaggerAndTag($tagger, $tag)
|
||||
{
|
||||
$ptag = Profile_list::pkeyGet(array('tagger' => $tagger, 'tag' => $tag));
|
||||
return $ptag;
|
||||
@ -514,11 +540,11 @@ class Profile_list extends Managed_DataObject
|
||||
* @return Profile_list the people tag object
|
||||
*/
|
||||
|
||||
static function ensureTag($tagger, $tag, $description=null, $private=false)
|
||||
public static function ensureTag($tagger, $tag, $description = null, $private = false)
|
||||
{
|
||||
$ptag = Profile_list::getByTaggerAndTag($tagger, $tag);
|
||||
|
||||
if(empty($ptag->id)) {
|
||||
if (empty($ptag->id)) {
|
||||
$args = array(
|
||||
'tag' => $tag,
|
||||
'tagger' => $tagger,
|
||||
@ -544,7 +570,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return integer maximum number of characters
|
||||
*/
|
||||
|
||||
static function maxDescription()
|
||||
public static function maxDescription()
|
||||
{
|
||||
$desclimit = common_config('peopletag', 'desclimit');
|
||||
// null => use global limit (distinct from 0!)
|
||||
@ -563,7 +589,7 @@ class Profile_list extends Managed_DataObject
|
||||
* @return boolean is the descripition too long?
|
||||
*/
|
||||
|
||||
static function descriptionTooLong($desc)
|
||||
public static function descriptionTooLong($desc)
|
||||
{
|
||||
$desclimit = self::maxDescription();
|
||||
return ($desclimit > 0 && !empty($desc) && (mb_strlen($desc) > $desclimit));
|
||||
@ -578,7 +604,8 @@ class Profile_list extends Managed_DataObject
|
||||
*
|
||||
* @return mixed Profile_list on success, false on fail
|
||||
*/
|
||||
static function saveNew(array $fields) {
|
||||
public static function saveNew(array $fields)
|
||||
{
|
||||
extract($fields);
|
||||
|
||||
$ptag = new Profile_list();
|
||||
@ -639,7 +666,7 @@ class Profile_list extends Managed_DataObject
|
||||
$result = $ptag->update($orig);
|
||||
if (!$result) {
|
||||
common_log_db_error($ptag, 'UPDATE', __FILE__);
|
||||
// TRANS: Server exception saving new tag.
|
||||
// TRANS: Server exception saving new tag.
|
||||
throw new ServerException(_('Could not set profile tag URI.'));
|
||||
}
|
||||
}
|
||||
@ -647,7 +674,7 @@ class Profile_list extends Managed_DataObject
|
||||
if (!isset($mainpage) || empty($mainpage)) {
|
||||
$orig = clone($ptag);
|
||||
$user = User::getKV('id', $ptag->tagger);
|
||||
if(!empty($user)) {
|
||||
if (!empty($user)) {
|
||||
$ptag->mainpage = common_local_url('showprofiletag', array('tag' => $ptag->tag, 'nickname' => $user->getNickname()));
|
||||
} else {
|
||||
$ptag->mainpage = $uri; // assume this is a remote peopletag and the uri works
|
||||
@ -687,9 +714,9 @@ class Profile_list extends Managed_DataObject
|
||||
* @returns array (array (mixed items), int next_cursor, int previous_cursor)
|
||||
*/
|
||||
|
||||
// XXX: This should be in Memcached_DataObject... eventually.
|
||||
// XXX: This should be in Memcached_DataObject... eventually
|
||||
|
||||
static function getAtCursor($fn, array $args, $cursor, $count=20)
|
||||
public static function getAtCursor($fn, array $args, $cursor, $count = 20)
|
||||
{
|
||||
$items = array();
|
||||
|
||||
@ -698,12 +725,12 @@ class Profile_list extends Managed_DataObject
|
||||
$next_cursor = 0;
|
||||
$prev_cursor = 0;
|
||||
|
||||
if($cursor > 0) {
|
||||
if ($cursor > 0) {
|
||||
// if cursor is +ve fetch $count+2 items before cursor starting at cursor
|
||||
$max_id = $cursor;
|
||||
$fn_args = array_merge($args, array(0, $count+2, 0, $max_id));
|
||||
$list = call_user_func_array($fn, $fn_args);
|
||||
while($list->fetch()) {
|
||||
while ($list->fetch()) {
|
||||
$items[] = clone($list);
|
||||
}
|
||||
|
||||
@ -734,15 +761,14 @@ class Profile_list extends Managed_DataObject
|
||||
$next_cursor = isset($next->cursor) ?
|
||||
$items[$count-1]->cursor : $items[$count-1]->id;
|
||||
}
|
||||
|
||||
} else if($cursor < -1) {
|
||||
} elseif ($cursor < -1) {
|
||||
// if cursor is -ve fetch $count+2 items created after -$cursor-1
|
||||
$cursor = abs($cursor);
|
||||
$since_id = $cursor-1;
|
||||
|
||||
$fn_args = array_merge($args, array(0, $count+2, $since_id));
|
||||
$list = call_user_func_array($fn, $fn_args);
|
||||
while($list->fetch()) {
|
||||
while ($list->fetch()) {
|
||||
$items[] = clone($list);
|
||||
}
|
||||
|
||||
@ -755,7 +781,10 @@ class Profile_list extends Managed_DataObject
|
||||
} else {
|
||||
$next_cursor = isset($items[$end]->cursor) ?
|
||||
$items[$end]->cursor : $items[$end]->id;
|
||||
if ($end > $count) array_pop($items); // excess item.
|
||||
if ($end > $count) {
|
||||
// excess item
|
||||
array_pop($items);
|
||||
}
|
||||
|
||||
// check if there are more items for next page
|
||||
$fn_args = array_merge($args, array(0, 1, 0, $cursor));
|
||||
@ -771,23 +800,22 @@ class Profile_list extends Managed_DataObject
|
||||
$prev_cursor = isset($prev->cursor) ?
|
||||
-$items[0]->cursor : -$items[0]->id;
|
||||
}
|
||||
} else if($cursor == -1) {
|
||||
} elseif ($cursor == -1) {
|
||||
$fn_args = array_merge($args, array(0, $count+1));
|
||||
$list = call_user_func_array($fn, $fn_args);
|
||||
|
||||
while($list->fetch()) {
|
||||
while ($list->fetch()) {
|
||||
$items[] = clone($list);
|
||||
}
|
||||
|
||||
if (count($items)==$count+1) {
|
||||
$next = array_pop($items);
|
||||
if(isset($next->cursor)) {
|
||||
if (isset($next->cursor)) {
|
||||
$next_cursor = $items[$count-1]->cursor;
|
||||
} else {
|
||||
$next_cursor = $items[$count-1]->id;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return array($items, $next_cursor, $prev_cursor);
|
||||
}
|
||||
@ -803,7 +831,8 @@ class Profile_list extends Managed_DataObject
|
||||
* @return boolean success
|
||||
*/
|
||||
|
||||
static function setCache($ckey, &$tag, $offset=0, $limit=null) {
|
||||
public static function setCache($ckey, &$tag, $offset = 0, $limit = null)
|
||||
{
|
||||
$cache = Cache::instance();
|
||||
if (empty($cache)) {
|
||||
return false;
|
||||
@ -834,8 +863,8 @@ class Profile_list extends Managed_DataObject
|
||||
* @return Profile_list results
|
||||
*/
|
||||
|
||||
static function getCached($ckey, $offset=0, $limit=null) {
|
||||
|
||||
public static function getCached($ckey, $offset = 0, $limit = null)
|
||||
{
|
||||
$keys_str = self::cacheGet($ckey);
|
||||
if ($keys_str === false) {
|
||||
return false;
|
||||
@ -862,7 +891,8 @@ class Profile_list extends Managed_DataObject
|
||||
* @return Profile_list results
|
||||
*/
|
||||
|
||||
static function getByKeys(array $keys) {
|
||||
public static function getByKeys(array $keys)
|
||||
{
|
||||
$cache = Cache::instance();
|
||||
|
||||
if (!empty($cache)) {
|
||||
@ -910,7 +940,7 @@ class Profile_list extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function insert()
|
||||
public function insert()
|
||||
{
|
||||
$result = parent::insert();
|
||||
if ($result) {
|
||||
|
@ -1,32 +1,31 @@
|
||||
<?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
|
||||
*
|
||||
* Data class for Profile preferences
|
||||
*
|
||||
* 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 Data
|
||||
* @package GNUsocial
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2013 Free Software Foundation, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://www.gnu.org/software/social/
|
||||
* @copyright 2013 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class Profile_prefs extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'profile_prefs'; // table name
|
||||
@ -58,7 +57,7 @@ class Profile_prefs extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
static function getNamespacePrefs(Profile $profile, $namespace, array $topic=array())
|
||||
public static function getNamespacePrefs(Profile $profile, $namespace, array $topic = [])
|
||||
{
|
||||
if (empty($topic)) {
|
||||
$prefs = new Profile_prefs();
|
||||
@ -76,13 +75,13 @@ class Profile_prefs extends Managed_DataObject
|
||||
return $prefs;
|
||||
}
|
||||
|
||||
static function getNamespace(Profile $profile, $namespace, array $topic=array())
|
||||
public static function getNamespace(Profile $profile, $namespace, array $topic = [])
|
||||
{
|
||||
$prefs = self::getNamespacePrefs($profile, $namespace, $topic);
|
||||
return $prefs->fetchAll();
|
||||
}
|
||||
|
||||
static function getAll(Profile $profile)
|
||||
public static function getAll(Profile $profile)
|
||||
{
|
||||
try {
|
||||
$prefs = self::listFind('profile_id', array($profile->getID()));
|
||||
@ -100,13 +99,15 @@ class Profile_prefs extends Managed_DataObject
|
||||
return $list;
|
||||
}
|
||||
|
||||
static function getTopic(Profile $profile, $namespace, $topic) {
|
||||
public static function getTopic(Profile $profile, $namespace, $topic)
|
||||
{
|
||||
return Profile_prefs::getByPK(array('profile_id' => $profile->getID(),
|
||||
'namespace' => $namespace,
|
||||
'topic' => $topic));
|
||||
}
|
||||
|
||||
static function getData(Profile $profile, $namespace, $topic, $def=null) {
|
||||
public static function getData(Profile $profile, $namespace, $topic, $def = null)
|
||||
{
|
||||
try {
|
||||
$pref = self::getTopic($profile, $namespace, $topic);
|
||||
} catch (NoResultException $e) {
|
||||
@ -120,7 +121,8 @@ class Profile_prefs extends Managed_DataObject
|
||||
return $pref->data;
|
||||
}
|
||||
|
||||
static function getConfigData(Profile $profile, $namespace, $topic) {
|
||||
public static function getConfigData(Profile $profile, $namespace, $topic)
|
||||
{
|
||||
try {
|
||||
$data = self::getData($profile, $namespace, $topic);
|
||||
} catch (NoResultException $e) {
|
||||
@ -140,14 +142,15 @@ class Profile_prefs extends Managed_DataObject
|
||||
* @return true if changes are made, false if no action taken
|
||||
* @throws ServerException if preference could not be saved
|
||||
*/
|
||||
static function setData(Profile $profile, $namespace, $topic, $data=null) {
|
||||
public static function setData(Profile $profile, $namespace, $topic, $data = null)
|
||||
{
|
||||
try {
|
||||
$pref = self::getTopic($profile, $namespace, $topic);
|
||||
if (is_null($data)) {
|
||||
$pref->delete();
|
||||
} else {
|
||||
$orig = clone($pref);
|
||||
$pref->data = $data;
|
||||
$pref->data = DB_DataObject_Cast::blob($data);
|
||||
$pref->update($orig);
|
||||
}
|
||||
return true;
|
||||
@ -161,7 +164,7 @@ class Profile_prefs extends Managed_DataObject
|
||||
$pref->profile_id = $profile->getID();
|
||||
$pref->namespace = $namespace;
|
||||
$pref->topic = $topic;
|
||||
$pref->data = $data;
|
||||
$pref->data = DB_DataObject_Cast::blob($data);
|
||||
$pref->created = common_sql_now();
|
||||
|
||||
if ($pref->insert() === false) {
|
||||
|
@ -1,8 +1,24 @@
|
||||
<?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/>.
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for profile_tag
|
||||
*/
|
||||
|
||||
class Profile_tag extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'profile_tag'; // table name
|
||||
@ -35,35 +51,34 @@ class Profile_tag extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
function links()
|
||||
public function links()
|
||||
{
|
||||
return array('tagger,tag' => 'profile_list:tagger,tag');
|
||||
}
|
||||
|
||||
function getMeta()
|
||||
public function getMeta()
|
||||
{
|
||||
return Profile_list::pkeyGet(array('tagger' => $this->tagger, 'tag' => $this->tag));
|
||||
}
|
||||
|
||||
static function getSelfTagsArray(Profile $target)
|
||||
public static function getSelfTagsArray(Profile $target)
|
||||
{
|
||||
return self::getTagsArray($target->getID(), $target->getID(), $target);
|
||||
}
|
||||
|
||||
static function setSelfTags(Profile $target, array $newtags, array $privacy=array())
|
||||
public static function setSelfTags(Profile $target, array $newtags, array $privacy = [])
|
||||
{
|
||||
return self::setTags($target->getID(), $target->getID(), $newtags, $privacy);
|
||||
}
|
||||
|
||||
static function getTags($tagger, $tagged, $auth_user=null) {
|
||||
|
||||
public static function getTags($tagger, $tagged, $auth_user = null)
|
||||
{
|
||||
$profile_list = new Profile_list();
|
||||
$include_priv = 1;
|
||||
|
||||
if (!($auth_user instanceof User ||
|
||||
$auth_user instanceof Profile) ||
|
||||
($auth_user->id !== $tagger)) {
|
||||
|
||||
$profile_list->private = false;
|
||||
$include_priv = 0;
|
||||
}
|
||||
@ -81,7 +96,7 @@ class Profile_tag extends Managed_DataObject
|
||||
$qry = sprintf($qry, $tagger, $tagged);
|
||||
|
||||
if (!$include_priv) {
|
||||
$qry .= ' and profile_list.private = 0';
|
||||
$qry .= ' AND profile_list.private = FALSE';
|
||||
}
|
||||
|
||||
$profile_list->query($qry);
|
||||
@ -91,20 +106,23 @@ class Profile_tag extends Managed_DataObject
|
||||
return $profile_list;
|
||||
}
|
||||
|
||||
static function getTagsArray($tagger, $tagged, Profile $scoped=null)
|
||||
public static function getTagsArray($tagger, $tagged, Profile $scoped = null)
|
||||
{
|
||||
$ptag = new Profile_tag();
|
||||
|
||||
$qry = sprintf('select profile_tag.tag '.
|
||||
'from profile_tag join profile_list '.
|
||||
' on (profile_tag.tagger = profile_list.tagger ' .
|
||||
' and profile_tag.tag = profile_list.tag) ' .
|
||||
'where profile_tag.tagger = %d ' .
|
||||
'and profile_tag.tagged = %d ',
|
||||
$tagger, $tagged);
|
||||
$qry = sprintf(
|
||||
'SELECT profile_tag.tag '.
|
||||
'FROM profile_tag INNER JOIN profile_list '.
|
||||
' ON (profile_tag.tagger = profile_list.tagger ' .
|
||||
' and profile_tag.tag = profile_list.tag) ' .
|
||||
'WHERE profile_tag.tagger = %d ' .
|
||||
'AND profile_tag.tagged = %d ',
|
||||
$tagger,
|
||||
$tagged
|
||||
);
|
||||
|
||||
if (!$scoped instanceof Profile || $scoped->getID() !== $tagger) {
|
||||
$qry .= 'and profile_list.private = 0';
|
||||
$qry .= 'AND profile_list.private = FALSE';
|
||||
}
|
||||
|
||||
$tags = array();
|
||||
@ -118,8 +136,8 @@ class Profile_tag extends Managed_DataObject
|
||||
return $tags;
|
||||
}
|
||||
|
||||
static function setTags($tagger, $tagged, array $newtags, array $privacy=array()) {
|
||||
|
||||
public static function setTags($tagger, $tagged, array $newtags, array $privacy = [])
|
||||
{
|
||||
$newtags = array_unique($newtags);
|
||||
$oldtags = self::getTagsArray($tagger, $tagged, Profile::getByID($tagger));
|
||||
|
||||
@ -145,8 +163,8 @@ class Profile_tag extends Managed_DataObject
|
||||
}
|
||||
|
||||
# set a single tag
|
||||
static function setTag($tagger, $tagged, $tag, $desc=null, $private=false) {
|
||||
|
||||
public static function setTag($tagger, $tagged, $tag, $desc=null, $private = false)
|
||||
{
|
||||
$ptag = Profile_tag::pkeyGet(array('tagger' => $tagger,
|
||||
'tagged' => $tagged,
|
||||
'tag' => $tag));
|
||||
@ -160,7 +178,6 @@ class Profile_tag extends Managed_DataObject
|
||||
$tagged_profile = Profile::getByID($tagged);
|
||||
|
||||
if (Event::handle('StartTagProfile', array($tagger_profile, $tagged_profile, $tag))) {
|
||||
|
||||
if (!$tagger_profile->canTag($tagged_profile)) {
|
||||
// TRANS: Client exception thrown trying to set a tag for a user that cannot be tagged.
|
||||
throw new ClientException(_('You cannot tag this user.'));
|
||||
@ -172,10 +189,12 @@ class Profile_tag extends Managed_DataObject
|
||||
|
||||
if ($count >= common_config('peopletag', 'maxtags')) {
|
||||
// TRANS: Client exception thrown trying to set more tags than allowed.
|
||||
throw new ClientException(sprintf(_('You already have created %d or more tags ' .
|
||||
'which is the maximum allowed number of tags. ' .
|
||||
'Try using or deleting some existing tags.'),
|
||||
common_config('peopletag', 'maxtags')));
|
||||
throw new ClientException(sprintf(
|
||||
_('You already have created %d or more tags ' .
|
||||
'which is the maximum allowed number of tags. ' .
|
||||
'Try using or deleting some existing tags.'),
|
||||
common_config('peopletag', 'maxtags')
|
||||
));
|
||||
}
|
||||
|
||||
$plist = new Profile_list();
|
||||
@ -185,10 +204,13 @@ class Profile_tag extends Managed_DataObject
|
||||
|
||||
if ($profile_list->taggedCount() >= common_config('peopletag', 'maxpeople')) {
|
||||
// TRANS: Client exception thrown when trying to add more people than allowed to a list.
|
||||
throw new ClientException(sprintf(_('You already have %1$d or more people in list %2$s, ' .
|
||||
'which is the maximum allowed number. ' .
|
||||
'Try unlisting others first.'),
|
||||
common_config('peopletag', 'maxpeople'), $tag));
|
||||
throw new ClientException(sprintf(
|
||||
_('You already have %1$d or more people in list %2$s, ' .
|
||||
'which is the maximum allowed number. ' .
|
||||
'Try unlisting others first.'),
|
||||
common_config('peopletag', 'maxpeople'),
|
||||
$tag
|
||||
));
|
||||
}
|
||||
|
||||
$newtag = new Profile_tag();
|
||||
@ -221,7 +243,8 @@ class Profile_tag extends Managed_DataObject
|
||||
return $newtag;
|
||||
}
|
||||
|
||||
static function unTag($tagger, $tagged, $tag) {
|
||||
public static function unTag($tagger, $tagged, $tag)
|
||||
{
|
||||
$ptag = Profile_tag::pkeyGet(array('tagger' => $tagger,
|
||||
'tagged' => $tagged,
|
||||
'tag' => $tag));
|
||||
@ -247,13 +270,14 @@ class Profile_tag extends Managed_DataObject
|
||||
}
|
||||
|
||||
// @fixme: move this to Profile_list?
|
||||
static function cleanup($profile_list) {
|
||||
public static function cleanup($profile_list)
|
||||
{
|
||||
$ptag = new Profile_tag();
|
||||
$ptag->tagger = $profile_list->tagger;
|
||||
$ptag->tag = $profile_list->tag;
|
||||
$ptag->find();
|
||||
|
||||
while($ptag->fetch()) {
|
||||
while ($ptag->fetch()) {
|
||||
if (Event::handle('StartUntagProfile', array($ptag))) {
|
||||
$orig = clone($ptag);
|
||||
$result = $ptag->delete();
|
||||
@ -266,17 +290,18 @@ class Profile_tag extends Managed_DataObject
|
||||
}
|
||||
|
||||
// move a tag!
|
||||
static function moveTag($orig, $new) {
|
||||
public static function moveTag($orig, $new)
|
||||
{
|
||||
$tags = new Profile_tag();
|
||||
$qry = 'UPDATE profile_tag SET ' .
|
||||
'tag = "%s", tagger = "%s" ' .
|
||||
'WHERE tag = "%s" ' .
|
||||
'AND tagger = "%s"';
|
||||
$result = $tags->query(sprintf($qry,
|
||||
$tags->escape($new->tag),
|
||||
$tags->escape($new->tagger),
|
||||
$tags->escape($orig->tag),
|
||||
$tags->escape($orig->tagger)));
|
||||
$qry = "UPDATE profile_tag SET tag = '%s', tagger = '%s' " .
|
||||
"WHERE tag = '%s' AND tagger = '%s'";
|
||||
$result = $tags->query(sprintf(
|
||||
$qry,
|
||||
$tags->escape($new->tag),
|
||||
$tags->escape($new->tagger),
|
||||
$tags->escape($orig->tag),
|
||||
$tags->escape($orig->tagger)
|
||||
));
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($tags, 'UPDATE', __FILE__);
|
||||
@ -285,7 +310,8 @@ class Profile_tag extends Managed_DataObject
|
||||
return $result;
|
||||
}
|
||||
|
||||
static function blowCaches($tagger, $tagged) {
|
||||
public static function blowCaches($tagger, $tagged)
|
||||
{
|
||||
foreach (array(0, 1) as $perm) {
|
||||
self::blow(sprintf('profile_tag:tagger_tagged_privacy:%d-%d-%d', $tagger, $tagged, $perm));
|
||||
}
|
||||
@ -293,38 +319,43 @@ class Profile_tag extends Managed_DataObject
|
||||
}
|
||||
|
||||
// Return profiles with a given tag
|
||||
static function getTagged($tagger, $tag) {
|
||||
public static function getTagged($tagger, $tag)
|
||||
{
|
||||
$profile = new Profile();
|
||||
$profile->query('SELECT profile.* ' .
|
||||
'FROM profile JOIN profile_tag ' .
|
||||
'ON profile.id = profile_tag.tagged ' .
|
||||
'WHERE profile_tag.tagger = ' . $profile->escape($tagger) . ' ' .
|
||||
'AND profile_tag.tag = "' . $profile->escape($tag) . '" ');
|
||||
$tagged = array();
|
||||
"AND profile_tag.tag = '" . $profile->escape($tag) . "' ");
|
||||
$tagged = [];
|
||||
while ($profile->fetch()) {
|
||||
$tagged[] = clone($profile);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function insert()
|
||||
public function insert()
|
||||
{
|
||||
$result = parent::insert();
|
||||
if ($result) {
|
||||
self::blow('profile_list:tagged_count:%d:%s',
|
||||
$this->tagger,
|
||||
$this->tag);
|
||||
self::blow(
|
||||
'profile_list:tagged_count:%d:%s',
|
||||
$this->tagger,
|
||||
$this->tag
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function delete($useWhere=false)
|
||||
public function delete($useWhere = false)
|
||||
{
|
||||
$result = parent::delete($useWhere);
|
||||
if ($result !== false) {
|
||||
self::blow('profile_list:tagged_count:%d:%s',
|
||||
$this->tagger,
|
||||
$this->tag);
|
||||
self::blow(
|
||||
'profile_list:tagged_count:%d:%s',
|
||||
$this->tagger,
|
||||
$this->tag
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
@ -1,23 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @copyright 2008, 2009, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for subscription
|
||||
@ -30,8 +32,8 @@ class Subscription extends Managed_DataObject
|
||||
public $__table = 'subscription'; // table name
|
||||
public $subscriber; // int(4) primary_key not_null
|
||||
public $subscribed; // int(4) primary_key not_null
|
||||
public $jabber; // tinyint(1) default_1
|
||||
public $sms; // tinyint(1) default_1
|
||||
public $jabber; // bool default_true
|
||||
public $sms; // bool default_true
|
||||
public $token; // varchar(191) not 255 because utf8mb4 takes more space
|
||||
public $secret; // varchar(191) not 255 because utf8mb4 takes more space
|
||||
public $uri; // varchar(191) not 255 because utf8mb4 takes more space
|
||||
@ -44,8 +46,8 @@ class Subscription extends Managed_DataObject
|
||||
'fields' => array(
|
||||
'subscriber' => array('type' => 'int', 'not null' => true, 'description' => 'profile listening'),
|
||||
'subscribed' => array('type' => 'int', 'not null' => true, 'description' => 'profile being listened to'),
|
||||
'jabber' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'deliver jabber messages'),
|
||||
'sms' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'deliver sms messages'),
|
||||
'jabber' => array('type' => 'bool', 'default' => true, 'description' => 'deliver jabber messages'),
|
||||
'sms' => array('type' => 'bool', 'default' => true, 'description' => 'deliver sms messages'),
|
||||
'token' => array('type' => 'varchar', 'length' => 191, 'description' => 'authorization token'),
|
||||
'secret' => array('type' => 'varchar', 'length' => 191, 'description' => 'token secret'),
|
||||
'uri' => array('type' => 'varchar', 'length' => 191, 'description' => 'universally unique identifier'),
|
||||
@ -74,7 +76,7 @@ class Subscription extends Managed_DataObject
|
||||
* @return mixed Subscription or Subscription_queue: new subscription info
|
||||
*/
|
||||
|
||||
static function start(Profile $subscriber, Profile $other, $force=false)
|
||||
public static function start(Profile $subscriber, Profile $other, $force = false)
|
||||
{
|
||||
if (!$subscriber->hasRight(Right::SUBSCRIBE)) {
|
||||
// TRANS: Exception thrown when trying to subscribe while being banned from subscribing.
|
||||
@ -117,7 +119,6 @@ class Subscription extends Managed_DataObject
|
||||
$otherUser->autosubscribe &&
|
||||
!self::exists($other, $subscriber) &&
|
||||
!$subscriber->hasBlocked($other)) {
|
||||
|
||||
try {
|
||||
self::start($other, $subscriber);
|
||||
} catch (AlreadyFulfilledException $e) {
|
||||
@ -137,7 +138,7 @@ class Subscription extends Managed_DataObject
|
||||
return $sub;
|
||||
}
|
||||
|
||||
static function ensureStart(Profile $subscriber, Profile $other, $force=false)
|
||||
public static function ensureStart(Profile $subscriber, Profile $other, $force = false)
|
||||
{
|
||||
try {
|
||||
$sub = self::start($subscriber, $other, $force);
|
||||
@ -157,12 +158,14 @@ class Subscription extends Managed_DataObject
|
||||
|
||||
$sub->subscriber = $subscriber->getID();
|
||||
$sub->subscribed = $other->getID();
|
||||
$sub->jabber = 1;
|
||||
$sub->sms = 1;
|
||||
$sub->jabber = true;
|
||||
$sub->sms = true;
|
||||
$sub->created = common_sql_now();
|
||||
$sub->uri = self::newUri($subscriber,
|
||||
$other,
|
||||
$sub->created);
|
||||
$sub->uri = self::newUri(
|
||||
$subscriber,
|
||||
$other,
|
||||
$sub->created
|
||||
);
|
||||
|
||||
$result = $sub->insert();
|
||||
|
||||
@ -175,7 +178,7 @@ class Subscription extends Managed_DataObject
|
||||
return $sub;
|
||||
}
|
||||
|
||||
function notify()
|
||||
public function notify()
|
||||
{
|
||||
// XXX: add other notifications (Jabber, SMS) here
|
||||
// XXX: queue this and handle it offline
|
||||
@ -184,12 +187,11 @@ class Subscription extends Managed_DataObject
|
||||
$this->notifyEmail();
|
||||
}
|
||||
|
||||
function notifyEmail()
|
||||
public function notifyEmail()
|
||||
{
|
||||
$subscribedUser = User::getKV('id', $this->subscribed);
|
||||
|
||||
if ($subscribedUser instanceof User) {
|
||||
|
||||
$subscriber = Profile::getKV('id', $this->subscriber);
|
||||
|
||||
mail_subscribe_notify_profile($subscribedUser, $subscriber);
|
||||
@ -200,7 +202,7 @@ class Subscription extends Managed_DataObject
|
||||
* Cancel a subscription
|
||||
*
|
||||
*/
|
||||
static function cancel(Profile $subscriber, Profile $other)
|
||||
public static function cancel(Profile $subscriber, Profile $other)
|
||||
{
|
||||
if (!self::exists($subscriber, $other)) {
|
||||
// TRANS: Exception thrown when trying to unsibscribe without a subscription.
|
||||
@ -215,7 +217,6 @@ class Subscription extends Managed_DataObject
|
||||
}
|
||||
|
||||
if (Event::handle('StartUnsubscribe', array($subscriber, $other))) {
|
||||
|
||||
$sub = Subscription::pkeyGet(array('subscriber' => $subscriber->id,
|
||||
'subscribed' => $other->id));
|
||||
|
||||
@ -245,7 +246,7 @@ class Subscription extends Managed_DataObject
|
||||
return;
|
||||
}
|
||||
|
||||
static function exists(Profile $subscriber, Profile $other)
|
||||
public static function exists(Profile $subscriber, Profile $other)
|
||||
{
|
||||
try {
|
||||
$sub = self::getSubscription($subscriber, $other);
|
||||
@ -256,7 +257,7 @@ class Subscription extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
|
||||
static function getSubscription(Profile $subscriber, Profile $other)
|
||||
public static function getSubscription(Profile $subscriber, Profile $other)
|
||||
{
|
||||
// This is essentially a pkeyGet but we have an object to return in NoResultException
|
||||
$sub = new Subscription();
|
||||
@ -278,7 +279,7 @@ class Subscription extends Managed_DataObject
|
||||
return Profile::getByID($this->subscribed);
|
||||
}
|
||||
|
||||
function asActivity()
|
||||
public function asActivity()
|
||||
{
|
||||
$subscriber = $this->getSubscriber();
|
||||
$subscribed = $this->getSubscribed();
|
||||
@ -293,19 +294,25 @@ class Subscription extends Managed_DataObject
|
||||
|
||||
$act->time = strtotime($this->created);
|
||||
// TRANS: Activity title when subscribing to another person.
|
||||
$act->title = _m('TITLE','Follow');
|
||||
$act->title = _m('TITLE', 'Follow');
|
||||
// TRANS: Notification given when one person starts following another.
|
||||
// TRANS: %1$s is the subscriber, %2$s is the subscribed.
|
||||
$act->content = sprintf(_('%1$s is now following %2$s.'),
|
||||
$subscriber->getBestName(),
|
||||
$subscribed->getBestName());
|
||||
$act->content = sprintf(
|
||||
_('%1$s is now following %2$s.'),
|
||||
$subscriber->getBestName(),
|
||||
$subscribed->getBestName()
|
||||
);
|
||||
|
||||
$act->actor = $subscriber->asActivityObject();
|
||||
$act->objects[] = $subscribed->asActivityObject();
|
||||
|
||||
$url = common_local_url('AtomPubShowSubscription',
|
||||
array('subscriber' => $subscriber->id,
|
||||
'subscribed' => $subscribed->id));
|
||||
$url = common_local_url(
|
||||
'AtomPubShowSubscription',
|
||||
[
|
||||
'subscriber' => $subscriber->id,
|
||||
'subscribed' => $subscribed->id,
|
||||
]
|
||||
);
|
||||
|
||||
$act->selfLink = $url;
|
||||
$act->editLink = $url;
|
||||
@ -356,11 +363,13 @@ class Subscription extends Managed_DataObject
|
||||
|
||||
// The following are helper functions to the subscription lists,
|
||||
// notably the public ones get used in places such as Profile
|
||||
public static function getSubscribedIDs($profile_id, $offset, $limit) {
|
||||
public static function getSubscribedIDs($profile_id, $offset, $limit)
|
||||
{
|
||||
return self::getSubscriptionIDs('subscribed', $profile_id, $offset, $limit);
|
||||
}
|
||||
|
||||
public static function getSubscriberIDs($profile_id, $offset, $limit) {
|
||||
public static function getSubscriberIDs($profile_id, $offset, $limit)
|
||||
{
|
||||
return self::getSubscriptionIDs('subscriber', $profile_id, $offset, $limit);
|
||||
}
|
||||
|
||||
@ -397,7 +406,7 @@ class Subscription extends Managed_DataObject
|
||||
$sub = new Subscription();
|
||||
$sub->$by_type = $profile_id;
|
||||
$sub->selectAdd($get_type);
|
||||
$sub->whereAdd("{$get_type} != {$profile_id}");
|
||||
$sub->whereAdd($get_type . ' <> ' . $profile_id);
|
||||
$sub->orderBy('created DESC');
|
||||
$sub->limit($queryoffset, $querylimit);
|
||||
|
||||
@ -426,7 +435,7 @@ class Subscription extends Managed_DataObject
|
||||
*
|
||||
* @return boolean success flag.
|
||||
*/
|
||||
function update($dataObject=false)
|
||||
public function update($dataObject = false)
|
||||
{
|
||||
self::blow('subscription:by-subscriber:'.$this->subscriber);
|
||||
self::blow('subscription:by-subscribed:'.$this->subscribed);
|
||||
|
261
classes/User.php
261
classes/User.php
@ -1,23 +1,20 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for user
|
||||
@ -37,24 +34,24 @@ class User extends Managed_DataObject
|
||||
public $password; // varchar(191) not 255 because utf8mb4 takes more space
|
||||
public $email; // varchar(191) unique_key not 255 because utf8mb4 takes more space
|
||||
public $incomingemail; // varchar(191) unique_key not 255 because utf8mb4 takes more space
|
||||
public $emailnotifysub; // tinyint(1) default_1
|
||||
public $emailnotifyfav; // tinyint(1) default_1
|
||||
public $emailnotifynudge; // tinyint(1) default_1
|
||||
public $emailnotifymsg; // tinyint(1) default_1
|
||||
public $emailnotifyattn; // tinyint(1) default_1
|
||||
public $emailnotifysub; // bool default_true
|
||||
public $emailnotifyfav; // tinyint(1) default_null
|
||||
public $emailnotifynudge; // bool default_true
|
||||
public $emailnotifymsg; // bool default_true
|
||||
public $emailnotifyattn; // bool default_true
|
||||
public $language; // varchar(50)
|
||||
public $timezone; // varchar(50)
|
||||
public $emailpost; // tinyint(1) default_1
|
||||
public $emailpost; // bool default_true
|
||||
public $sms; // varchar(64) unique_key
|
||||
public $carrier; // int(4)
|
||||
public $smsnotify; // tinyint(1)
|
||||
public $smsreplies; // tinyint(1)
|
||||
public $smsnotify; // bool default_false
|
||||
public $smsreplies; // bool default_false
|
||||
public $smsemail; // varchar(191) not 255 because utf8mb4 takes more space
|
||||
public $uri; // varchar(191) unique_key not 255 because utf8mb4 takes more space
|
||||
public $autosubscribe; // tinyint(1)
|
||||
public $autosubscribe; // bool default_false
|
||||
public $subscribe_policy; // tinyint(1)
|
||||
public $urlshorteningservice; // varchar(50) default_ur1.ca
|
||||
public $private_stream; // tinyint(1) default_0
|
||||
public $private_stream; // bool default_false
|
||||
public $created; // datetime() not_null default_0000-00-00%2000%3A00%3A00
|
||||
public $modified; // datetime() not_null default_CURRENT_TIMESTAMP
|
||||
|
||||
@ -71,24 +68,24 @@ class User extends Managed_DataObject
|
||||
'password' => array('type' => 'varchar', 'length' => 191, 'description' => 'salted password, can be null for OpenID users'),
|
||||
'email' => array('type' => 'varchar', 'length' => 191, 'description' => 'email address for password recovery etc.'),
|
||||
'incomingemail' => array('type' => 'varchar', 'length' => 191, 'description' => 'email address for post-by-email'),
|
||||
'emailnotifysub' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of subscriptions'),
|
||||
'emailnotifysub' => array('type' => 'bool', 'default' => true, 'description' => 'Notify by email of subscriptions'),
|
||||
'emailnotifyfav' => array('type' => 'int', 'size' => 'tiny', 'default' => null, 'description' => 'Notify by email of favorites'),
|
||||
'emailnotifynudge' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of nudges'),
|
||||
'emailnotifymsg' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of direct messages'),
|
||||
'emailnotifyattn' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of @-replies'),
|
||||
'emailnotifynudge' => array('type' => 'bool', 'default' => true, 'description' => 'Notify by email of nudges'),
|
||||
'emailnotifymsg' => array('type' => 'bool', 'default' => true, 'description' => 'Notify by email of direct messages'),
|
||||
'emailnotifyattn' => array('type' => 'bool', 'default' => true, 'description' => 'Notify by email of @-replies'),
|
||||
'language' => array('type' => 'varchar', 'length' => 50, 'description' => 'preferred language'),
|
||||
'timezone' => array('type' => 'varchar', 'length' => 50, 'description' => 'timezone'),
|
||||
'emailpost' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Post by email'),
|
||||
'emailpost' => array('type' => 'bool', 'default' => true, 'description' => 'Post by email'),
|
||||
'sms' => array('type' => 'varchar', 'length' => 64, 'description' => 'sms phone number'),
|
||||
'carrier' => array('type' => 'int', 'description' => 'foreign key to sms_carrier'),
|
||||
'smsnotify' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'whether to send notices to SMS'),
|
||||
'smsreplies' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'whether to send notices to SMS on replies'),
|
||||
'smsnotify' => array('type' => 'bool', 'default' => false, 'description' => 'whether to send notices to SMS'),
|
||||
'smsreplies' => array('type' => 'bool', 'default' => false, 'description' => 'whether to send notices to SMS on replies'),
|
||||
'smsemail' => array('type' => 'varchar', 'length' => 191, 'description' => 'built from sms and carrier'),
|
||||
'uri' => array('type' => 'varchar', 'length' => 191, 'description' => 'universally unique identifier, usually a tag URI'),
|
||||
'autosubscribe' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'automatically subscribe to users who subscribe to us'),
|
||||
'autosubscribe' => array('type' => 'bool', 'default' => false, 'description' => 'automatically subscribe to users who subscribe to us'),
|
||||
'subscribe_policy' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => '0 = anybody can subscribe; 1 = require approval'),
|
||||
'urlshorteningservice' => array('type' => 'varchar', 'length' => 50, 'default' => 'internal', 'description' => 'service to use for auto-shortening URLs'),
|
||||
'private_stream' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'whether to limit all notices to followers only'),
|
||||
'private_stream' => array('type' => 'bool', 'default' => false, 'description' => 'whether to limit all notices to followers only'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'),
|
||||
),
|
||||
@ -144,7 +141,7 @@ class User extends Managed_DataObject
|
||||
return $this->getProfile()->getNickname();
|
||||
}
|
||||
|
||||
static function getByNickname($nickname)
|
||||
public static function getByNickname($nickname)
|
||||
{
|
||||
$user = User::getKV('nickname', $nickname);
|
||||
if (!$user instanceof User) {
|
||||
@ -154,12 +151,12 @@ class User extends Managed_DataObject
|
||||
return $user;
|
||||
}
|
||||
|
||||
function isSubscribed(Profile $other)
|
||||
public function isSubscribed(Profile $other)
|
||||
{
|
||||
return $this->getProfile()->isSubscribed($other);
|
||||
}
|
||||
|
||||
function hasPendingSubscription(Profile $other)
|
||||
public function hasPendingSubscription(Profile $other)
|
||||
{
|
||||
return $this->getProfile()->hasPendingSubscription($other);
|
||||
}
|
||||
@ -169,17 +166,17 @@ class User extends Managed_DataObject
|
||||
*
|
||||
* @return mixed Notice or null
|
||||
*/
|
||||
function getCurrentNotice()
|
||||
public function getCurrentNotice()
|
||||
{
|
||||
return $this->getProfile()->getCurrentNotice();
|
||||
}
|
||||
|
||||
function getCarrier()
|
||||
public function getCarrier()
|
||||
{
|
||||
return Sms_carrier::getKV('id', $this->carrier);
|
||||
}
|
||||
|
||||
function hasBlocked(Profile $other)
|
||||
public function hasBlocked(Profile $other)
|
||||
{
|
||||
return $this->getProfile()->hasBlocked($other);
|
||||
}
|
||||
@ -206,10 +203,9 @@ class User extends Managed_DataObject
|
||||
* @return User object
|
||||
* @throws Exception on failure
|
||||
*/
|
||||
static function register(array $fields, $accept_email_fail=false) {
|
||||
|
||||
public static function register(array $fields, $accept_email_fail = false)
|
||||
{
|
||||
// MAGICALLY put fields into current scope
|
||||
|
||||
extract($fields);
|
||||
|
||||
$profile = new Profile();
|
||||
@ -262,23 +258,22 @@ class User extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($email_confirmed) && $email_confirmed) {
|
||||
if (isset($email_confirmed) && $email_confirmed) {
|
||||
$user->email = $email;
|
||||
}
|
||||
|
||||
// Set default-on options here, otherwise they'll be disabled
|
||||
// initially for sites using caching, since the initial encache
|
||||
// doesn't know about the defaults in the database.
|
||||
$user->emailnotifysub = 1;
|
||||
$user->emailnotifynudge = 1;
|
||||
$user->emailnotifymsg = 1;
|
||||
$user->emailnotifyattn = 1;
|
||||
$user->emailpost = 1;
|
||||
$user->emailnotifysub = true;
|
||||
$user->emailnotifynudge = true;
|
||||
$user->emailnotifymsg = true;
|
||||
$user->emailnotifyattn = true;
|
||||
$user->emailpost = true;
|
||||
|
||||
$user->created = common_sql_now();
|
||||
|
||||
if (Event::handle('StartUserRegister', array($profile))) {
|
||||
|
||||
$profile->query('BEGIN');
|
||||
|
||||
$id = $profile->insert();
|
||||
@ -291,7 +286,7 @@ class User extends Managed_DataObject
|
||||
|
||||
// Necessary because id has been known to be reissued.
|
||||
if ($profile->hasRole(Profile_role::DELETED)) {
|
||||
$profile->revokeRole(Profile_role::DELETED);
|
||||
$profile->revokeRole(Profile_role::DELETED);
|
||||
}
|
||||
|
||||
$user->id = $id;
|
||||
@ -367,8 +362,11 @@ class User extends Managed_DataObject
|
||||
if (!empty($defnick)) {
|
||||
$defuser = User::getKV('nickname', $defnick);
|
||||
if (empty($defuser)) {
|
||||
common_log(LOG_WARNING, sprintf("Default user %s does not exist.", $defnick),
|
||||
__FILE__);
|
||||
common_log(
|
||||
LOG_WARNING,
|
||||
sprintf('Default user %s does not exist.', $defnick),
|
||||
__FILE__
|
||||
);
|
||||
} else {
|
||||
Subscription::ensureStart($profile, $defuser->getProfile());
|
||||
}
|
||||
@ -394,16 +392,23 @@ class User extends Managed_DataObject
|
||||
if (!empty($welcome)) {
|
||||
$welcomeuser = User::getKV('nickname', $welcome);
|
||||
if (empty($welcomeuser)) {
|
||||
common_log(LOG_WARNING, sprintf("Welcome user %s does not exist.", $defnick),
|
||||
__FILE__);
|
||||
common_log(
|
||||
LOG_WARNING,
|
||||
sprintf('Welcome user %s does not exist.', $defnick),
|
||||
__FILE__
|
||||
);
|
||||
} else {
|
||||
$notice = Notice::saveNew($welcomeuser->id,
|
||||
// TRANS: Notice given on user registration.
|
||||
// TRANS: %1$s is the sitename, $2$s is the registering user's nickname.
|
||||
sprintf(_('Welcome to %1$s, @%2$s!'),
|
||||
common_config('site', 'name'),
|
||||
$profile->getNickname()),
|
||||
'system');
|
||||
$notice = Notice::saveNew(
|
||||
$welcomeuser->id,
|
||||
// TRANS: Notice given on user registration.
|
||||
// TRANS: %1$s is the sitename, $2$s is the registering user's nickname.
|
||||
sprintf(
|
||||
_('Welcome to %1$s, @%2$s!'),
|
||||
common_config('site', 'name'),
|
||||
$profile->getNickname()
|
||||
),
|
||||
'system'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -418,9 +423,8 @@ class User extends Managed_DataObject
|
||||
}
|
||||
|
||||
// Things we do when the email changes
|
||||
function emailChanged()
|
||||
public function emailChanged()
|
||||
{
|
||||
|
||||
$invites = new Invitation();
|
||||
$invites->address = $this->email;
|
||||
$invites->address_type = 'email';
|
||||
@ -441,48 +445,53 @@ class User extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function mutuallySubscribed(Profile $other)
|
||||
public function mutuallySubscribed(Profile $other)
|
||||
{
|
||||
return $this->getProfile()->mutuallySubscribed($other);
|
||||
}
|
||||
|
||||
function mutuallySubscribedUsers()
|
||||
public function mutuallySubscribedUsers()
|
||||
{
|
||||
// 3-way join; probably should get cached
|
||||
$UT = common_config('db','type')=='pgsql'?'"user"':'user';
|
||||
$qry = "SELECT $UT.* " .
|
||||
"FROM subscription sub1 JOIN $UT ON sub1.subscribed = $UT.id " .
|
||||
"JOIN subscription sub2 ON $UT.id = sub2.subscriber " .
|
||||
'WHERE sub1.subscriber = %d and sub2.subscribed = %d ' .
|
||||
"ORDER BY $UT.nickname";
|
||||
$user = new User();
|
||||
$user->query(sprintf($qry, $this->id, $this->id));
|
||||
|
||||
// 3-way join; probably should get cached
|
||||
$user->query(sprintf(
|
||||
'SELECT %1$s.* ' .
|
||||
'FROM subscription AS sub1 INNER JOIN %1$s ON sub1.subscribed = %1$s.id ' .
|
||||
'INNER JOIN subscription AS sub2 ON %1$s.id = sub2.subscriber ' .
|
||||
'WHERE sub1.subscriber = %2$d AND sub2.subscribed = %2$d ' .
|
||||
'ORDER BY %1$s.nickname',
|
||||
$user->escapedTableName(),
|
||||
$this->id
|
||||
));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0)
|
||||
public function getReplies($offset = 0, $limit = NOTICES_PER_PAGE, $since_id = 0, $before_id = 0)
|
||||
{
|
||||
return $this->getProfile()->getReplies($offset, $limit, $since_id, $before_id);
|
||||
}
|
||||
|
||||
function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) {
|
||||
public function getTaggedNotices($tag, $offset = 0, $limit = NOTICES_PER_PAGE, $since_id = 0, $before_id = 0)
|
||||
{
|
||||
return $this->getProfile()->getTaggedNotices($tag, $offset, $limit, $since_id, $before_id);
|
||||
}
|
||||
|
||||
function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0)
|
||||
public function getNotices($offset = 0, $limit = NOTICES_PER_PAGE, $since_id = 0, $before_id = 0)
|
||||
{
|
||||
return $this->getProfile()->getNotices($offset, $limit, $since_id, $before_id);
|
||||
}
|
||||
|
||||
function block(Profile $other)
|
||||
public function block(Profile $other)
|
||||
{
|
||||
// Add a new block record
|
||||
|
||||
// no blocking (and thus unsubbing from) yourself
|
||||
|
||||
if ($this->id == $other->id) {
|
||||
common_log(LOG_WARNING,
|
||||
common_log(
|
||||
LOG_WARNING,
|
||||
sprintf(
|
||||
"Profile ID %d (%s) tried to block themself.",
|
||||
$this->id,
|
||||
@ -521,7 +530,7 @@ class User extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
|
||||
function unblock(Profile $other)
|
||||
public function unblock(Profile $other)
|
||||
{
|
||||
// Get the block record
|
||||
|
||||
@ -541,17 +550,17 @@ class User extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
|
||||
function isMember(User_group $group)
|
||||
public function isMember(User_group $group)
|
||||
{
|
||||
return $this->getProfile()->isMember($group);
|
||||
}
|
||||
|
||||
function isAdmin(User_group $group)
|
||||
public function isAdmin(User_group $group)
|
||||
{
|
||||
return $this->getProfile()->isAdmin($group);
|
||||
}
|
||||
|
||||
function getGroups($offset=0, $limit=null)
|
||||
public function getGroups($offset = 0, $limit = null)
|
||||
{
|
||||
return $this->getProfile()->getGroups($offset, $limit);
|
||||
}
|
||||
@ -563,7 +572,7 @@ class User extends Managed_DataObject
|
||||
* @param User_group $group
|
||||
* @return Group_member
|
||||
*/
|
||||
function joinGroup(User_group $group)
|
||||
public function joinGroup(User_group $group)
|
||||
{
|
||||
return $this->getProfile()->joinGroup($group);
|
||||
}
|
||||
@ -573,37 +582,37 @@ class User extends Managed_DataObject
|
||||
*
|
||||
* @param User_group $group
|
||||
*/
|
||||
function leaveGroup(User_group $group)
|
||||
public function leaveGroup(User_group $group)
|
||||
{
|
||||
return $this->getProfile()->leaveGroup($group);
|
||||
}
|
||||
|
||||
function getSubscribed($offset=0, $limit=null)
|
||||
public function getSubscribed($offset = 0, $limit = null)
|
||||
{
|
||||
return $this->getProfile()->getSubscribed($offset, $limit);
|
||||
}
|
||||
|
||||
function getSubscribers($offset=0, $limit=null)
|
||||
public function getSubscribers($offset = 0, $limit = null)
|
||||
{
|
||||
return $this->getProfile()->getSubscribers($offset, $limit);
|
||||
}
|
||||
|
||||
function getTaggedSubscribers($tag, $offset=0, $limit=null)
|
||||
public function getTaggedSubscribers($tag, $offset = 0, $limit = null)
|
||||
{
|
||||
return $this->getProfile()->getTaggedSubscribers($tag, $offset, $limit);
|
||||
}
|
||||
|
||||
function getTaggedSubscriptions($tag, $offset=0, $limit=null)
|
||||
public function getTaggedSubscriptions($tag, $offset = 0, $limit = null)
|
||||
{
|
||||
return $this->getProfile()->getTaggedSubscriptions($tag, $offset, $limit);
|
||||
}
|
||||
|
||||
function hasRight($right)
|
||||
public function hasRight($right)
|
||||
{
|
||||
return $this->getProfile()->hasRight($right);
|
||||
}
|
||||
|
||||
function delete($useWhere=false)
|
||||
public function delete($useWhere = false)
|
||||
{
|
||||
if (empty($this->id)) {
|
||||
common_log(LOG_WARNING, "Ambiguous User->delete(); skipping related tables.");
|
||||
@ -640,14 +649,14 @@ class User extends Managed_DataObject
|
||||
return parent::delete($useWhere);
|
||||
}
|
||||
|
||||
function _deleteTags()
|
||||
public function _deleteTags()
|
||||
{
|
||||
$tag = new Profile_tag();
|
||||
$tag->tagger = $this->id;
|
||||
$tag->delete();
|
||||
}
|
||||
|
||||
function _deleteBlocks()
|
||||
public function _deleteBlocks()
|
||||
{
|
||||
$block = new Profile_block();
|
||||
$block->blocker = $this->id;
|
||||
@ -655,32 +664,32 @@ class User extends Managed_DataObject
|
||||
// XXX delete group block? Reset blocker?
|
||||
}
|
||||
|
||||
function hasRole($name)
|
||||
public function hasRole($name)
|
||||
{
|
||||
return $this->getProfile()->hasRole($name);
|
||||
}
|
||||
|
||||
function grantRole($name)
|
||||
public function grantRole($name)
|
||||
{
|
||||
return $this->getProfile()->grantRole($name);
|
||||
}
|
||||
|
||||
function revokeRole($name)
|
||||
public function revokeRole($name)
|
||||
{
|
||||
return $this->getProfile()->revokeRole($name);
|
||||
}
|
||||
|
||||
function isSandboxed()
|
||||
public function isSandboxed()
|
||||
{
|
||||
return $this->getProfile()->isSandboxed();
|
||||
}
|
||||
|
||||
function isSilenced()
|
||||
public function isSilenced()
|
||||
{
|
||||
return $this->getProfile()->isSilenced();
|
||||
}
|
||||
|
||||
function receivesEmailNotifications()
|
||||
public function receivesEmailNotifications()
|
||||
{
|
||||
// We could do this in one large if statement, but that's not as easy to read
|
||||
// Don't send notifications if we don't know the user's email address or it is
|
||||
@ -695,7 +704,7 @@ class User extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
|
||||
function repeatedByMe($offset=0, $limit=20, $since_id=null, $max_id=null)
|
||||
public function repeatedByMe($offset = 0, $limit = 20, $since_id = null, $max_id = null)
|
||||
{
|
||||
// FIXME: Use another way to get Profile::current() since we
|
||||
// want to avoid confusion between session user and queue processing.
|
||||
@ -704,7 +713,7 @@ class User extends Managed_DataObject
|
||||
}
|
||||
|
||||
|
||||
function repeatsOfMe($offset=0, $limit=20, $since_id=null, $max_id=null)
|
||||
public function repeatsOfMe($offset = 0, $limit = 20, $since_id = null, $max_id = null)
|
||||
{
|
||||
// FIXME: Use another way to get Profile::current() since we
|
||||
// want to avoid confusion between session user and queue processing.
|
||||
@ -712,7 +721,7 @@ class User extends Managed_DataObject
|
||||
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
||||
}
|
||||
|
||||
public function repeatedToMe($offset=0, $limit=20, $since_id=null, $max_id=null)
|
||||
public function repeatedToMe($offset = 0, $limit = 20, $since_id = null, $max_id = null)
|
||||
{
|
||||
return $this->getProfile()->repeatedToMe($offset, $limit, $since_id, $max_id);
|
||||
}
|
||||
@ -791,7 +800,7 @@ class User extends Managed_DataObject
|
||||
* @throws ServerException if no valid single user account is present
|
||||
* @throws ServerException if called when not in single-user mode
|
||||
*/
|
||||
static function singleUserNickname()
|
||||
public static function singleUserNickname()
|
||||
{
|
||||
try {
|
||||
$user = User::singleUser();
|
||||
@ -828,7 +837,7 @@ class User extends Managed_DataObject
|
||||
* Get a list of OAuth client applications that have access to this
|
||||
* user's account.
|
||||
*/
|
||||
function getConnectedApps($offset = 0, $limit = null)
|
||||
public function getConnectedApps($offset = 0, $limit = null)
|
||||
{
|
||||
$qry =
|
||||
'SELECT u.* ' .
|
||||
@ -839,11 +848,7 @@ class User extends Managed_DataObject
|
||||
'ORDER BY u.created DESC ';
|
||||
|
||||
if ($offset > 0) {
|
||||
if (common_config('db','type') == 'pgsql') {
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
}
|
||||
|
||||
$apps = new Oauth_application_user();
|
||||
@ -863,14 +868,14 @@ class User extends Managed_DataObject
|
||||
* @return array of variable names to include in serialization.
|
||||
*/
|
||||
|
||||
function __sleep()
|
||||
public function __sleep()
|
||||
{
|
||||
$vars = parent::__sleep();
|
||||
$skip = array('_profile');
|
||||
return array_diff($vars, $skip);
|
||||
}
|
||||
|
||||
static function recoverPassword($nore)
|
||||
public static function recoverPassword($nore)
|
||||
{
|
||||
require_once INSTALLDIR . '/lib/util/mail.php';
|
||||
|
||||
@ -943,7 +948,7 @@ class User extends Managed_DataObject
|
||||
throw new ServerException(_('Error saving address confirmation.'));
|
||||
}
|
||||
|
||||
// @todo FIXME: needs i18n.
|
||||
// @todo FIXME: needs i18n.
|
||||
$body = "Hey, $user->nickname.";
|
||||
$body .= "\n\n";
|
||||
$body .= 'Someone just asked for a new password ' .
|
||||
@ -951,8 +956,10 @@ class User extends Managed_DataObject
|
||||
$body .= "\n\n";
|
||||
$body .= 'If it was you, and you want to confirm, use the URL below:';
|
||||
$body .= "\n\n";
|
||||
$body .= "\t".common_local_url('recoverpassword',
|
||||
array('code' => $confirm->code));
|
||||
$body .= "\t" . common_local_url(
|
||||
'recoverpassword',
|
||||
['code' => $confirm->code]
|
||||
);
|
||||
$body .= "\n\n";
|
||||
$body .= 'If not, just ignore this message.';
|
||||
$body .= "\n\n";
|
||||
@ -966,7 +973,7 @@ class User extends Managed_DataObject
|
||||
mail_to_user($user, _('Password recovery requested'), $body, $headers, $confirm->address);
|
||||
}
|
||||
|
||||
function streamModeOnly()
|
||||
public function streamModeOnly()
|
||||
{
|
||||
if (common_config('oldschool', 'enabled')) {
|
||||
$osp = Old_school_prefs::getKV('user_id', $this->id);
|
||||
@ -978,7 +985,7 @@ class User extends Managed_DataObject
|
||||
return false;
|
||||
}
|
||||
|
||||
function streamNicknames()
|
||||
public function streamNicknames()
|
||||
{
|
||||
if (common_config('oldschool', 'enabled')) {
|
||||
$osp = Old_school_prefs::getKV('user_id', $this->id);
|
||||
@ -989,7 +996,7 @@ class User extends Managed_DataObject
|
||||
return false;
|
||||
}
|
||||
|
||||
function registrationActivity()
|
||||
public function registrationActivity()
|
||||
{
|
||||
$profile = $this->getProfile();
|
||||
|
||||
@ -1007,16 +1014,20 @@ class User extends Managed_DataObject
|
||||
|
||||
$act->objects[] = $service;
|
||||
|
||||
$act->id = TagURI::mint('user:register:%d',
|
||||
$this->id);
|
||||
$act->id = TagURI::mint(
|
||||
'user:register:%d',
|
||||
$this->id
|
||||
);
|
||||
|
||||
$act->time = strtotime($this->created);
|
||||
|
||||
$act->title = _("Register");
|
||||
|
||||
$act->content = sprintf(_('%1$s joined %2$s.'),
|
||||
$profile->getBestName(),
|
||||
$service->title);
|
||||
$act->content = sprintf(
|
||||
_('%1$s joined %2$s.'),
|
||||
$profile->getBestName(),
|
||||
$service->title
|
||||
);
|
||||
return $act;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,24 @@
|
||||
<?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/>.
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Table Definition for user_group
|
||||
*/
|
||||
|
||||
class User_group extends Managed_DataObject
|
||||
{
|
||||
const JOIN_POLICY_OPEN = 0;
|
||||
@ -63,7 +79,7 @@ class User_group extends Managed_DataObject
|
||||
|
||||
'uri' => array('type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'),
|
||||
'mainpage' => array('type' => 'varchar', 'length' => 191, 'description' => 'page for group info to link to'),
|
||||
'join_policy' => array('type' => 'int', 'size' => 'tiny', 'description' => '0=open; 1=requires admin approval'),
|
||||
'join_policy' => array('type' => 'int', 'size' => 'tiny', 'description' => '0=open; 1=requires admin approval'),
|
||||
'force_scope' => array('type' => 'int', 'size' => 'tiny', 'description' => '0=never,1=sometimes,-1=always'),
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
@ -118,40 +134,38 @@ class User_group extends Managed_DataObject
|
||||
return Theme::path('default-avatar-'.$sizenames[$size].'.png');
|
||||
}
|
||||
|
||||
function homeUrl()
|
||||
public function homeUrl()
|
||||
{
|
||||
return $this->getProfile()->getUrl();
|
||||
}
|
||||
|
||||
function getUri()
|
||||
public function getUri()
|
||||
{
|
||||
$uri = null;
|
||||
if (Event::handle('StartUserGroupGetUri', array($this, &$uri))) {
|
||||
if (!empty($this->uri)) {
|
||||
$uri = $this->uri;
|
||||
} elseif ($this->isLocal()) {
|
||||
$uri = common_local_url('groupbyid',
|
||||
array('id' => $this->id));
|
||||
$uri = common_local_url('groupbyid', ['id' => $this->id]);
|
||||
}
|
||||
}
|
||||
Event::handle('EndUserGroupGetUri', array($this, &$uri));
|
||||
return $uri;
|
||||
}
|
||||
|
||||
function permalink()
|
||||
public function permalink()
|
||||
{
|
||||
$url = null;
|
||||
if (Event::handle('StartUserGroupPermalink', array($this, &$url))) {
|
||||
if ($this->isLocal()) {
|
||||
$url = common_local_url('groupbyid',
|
||||
array('id' => $this->id));
|
||||
$url = common_local_url('groupbyid', ['id' => $this->id]);
|
||||
}
|
||||
}
|
||||
Event::handle('EndUserGroupPermalink', array($this, &$url));
|
||||
return $url;
|
||||
}
|
||||
|
||||
function getNotices($offset, $limit, $since_id=null, $max_id=null)
|
||||
public function getNotices($offset, $limit, $since_id = null, $max_id = null)
|
||||
{
|
||||
// FIXME: Get the Profile::current() some other way, to avoid
|
||||
// possible confusion between current session and queue process.
|
||||
@ -160,29 +174,26 @@ class User_group extends Managed_DataObject
|
||||
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
||||
}
|
||||
|
||||
function getMembers($offset=0, $limit=null) {
|
||||
public function getMembers($offset = 0, $limit = null)
|
||||
{
|
||||
$ids = null;
|
||||
if (is_null($limit) || $offset + $limit > User_group::CACHE_WINDOW) {
|
||||
$ids = $this->getMemberIDs($offset,
|
||||
$limit);
|
||||
$ids = $this->getMemberIDs($offset, $limit);
|
||||
} else {
|
||||
$key = sprintf('group:member_ids:%d', $this->id);
|
||||
$window = self::cacheGet($key);
|
||||
if ($window === false) {
|
||||
$window = $this->getMemberIDs(0,
|
||||
User_group::CACHE_WINDOW);
|
||||
$window = $this->getMemberIDs(0, User_group::CACHE_WINDOW);
|
||||
self::cacheSet($key, $window);
|
||||
}
|
||||
|
||||
$ids = array_slice($window,
|
||||
$offset,
|
||||
$limit);
|
||||
$ids = array_slice($window, $offset, $limit);
|
||||
}
|
||||
|
||||
return Profile::multiGet('id', $ids);
|
||||
}
|
||||
|
||||
function getMemberIDs($offset=0, $limit=null)
|
||||
public function getMemberIDs($offset = 0, $limit = null)
|
||||
{
|
||||
$gm = new Group_member();
|
||||
|
||||
@ -215,7 +226,7 @@ class User_group extends Managed_DataObject
|
||||
* @param int $limit
|
||||
* @return Profile
|
||||
*/
|
||||
function getRequests($offset=0, $limit=null)
|
||||
public function getRequests($offset = 0, $limit = null)
|
||||
{
|
||||
$rq = new Group_join_queue();
|
||||
$rq->group_id = $this->id;
|
||||
@ -237,7 +248,7 @@ class User_group extends Managed_DataObject
|
||||
{
|
||||
$block = new Group_member();
|
||||
$block->group_id = $this->id;
|
||||
$block->is_admin = 1;
|
||||
$block->is_admin = true;
|
||||
|
||||
return $block->count();
|
||||
}
|
||||
@ -264,7 +275,7 @@ class User_group extends Managed_DataObject
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
function getBlockedCount()
|
||||
public function getBlockedCount()
|
||||
{
|
||||
// XXX: WORM cache this
|
||||
|
||||
@ -274,7 +285,7 @@ class User_group extends Managed_DataObject
|
||||
return $block->count();
|
||||
}
|
||||
|
||||
function getQueueCount()
|
||||
public function getQueueCount()
|
||||
{
|
||||
// XXX: WORM cache this
|
||||
|
||||
@ -284,11 +295,12 @@ class User_group extends Managed_DataObject
|
||||
return $queue->count();
|
||||
}
|
||||
|
||||
function getAdmins($offset=null, $limit=null) // offset is null because DataObject wants it, 0 would mean no results
|
||||
// offset is null because DataObject wants it, 0 would mean no results
|
||||
public function getAdmins($offset = null, $limit = null)
|
||||
{
|
||||
$admins = new Profile();
|
||||
$admins->joinAdd(array('id', 'group_member:profile_id'));
|
||||
$admins->whereAdd(sprintf('group_member.group_id = %u AND group_member.is_admin = 1', $this->id));
|
||||
$admins->whereAdd('group_member.group_id = ' . $this->id . ' AND group_member.is_admin = true');
|
||||
$admins->orderBy('group_member.modified ASC');
|
||||
$admins->limit($offset, $limit);
|
||||
$admins->find();
|
||||
@ -296,7 +308,8 @@ class User_group extends Managed_DataObject
|
||||
return $admins;
|
||||
}
|
||||
|
||||
function getBlocked($offset=null, $limit=null) // offset is null because DataObject wants it, 0 would mean no results
|
||||
// offset is null because DataObject wants it, 0 would mean no results
|
||||
public function getBlocked($offset = null, $limit = null)
|
||||
{
|
||||
$blocked = new Profile();
|
||||
$blocked->joinAdd(array('id', 'group_block:blocked'));
|
||||
@ -308,7 +321,7 @@ class User_group extends Managed_DataObject
|
||||
return $blocked;
|
||||
}
|
||||
|
||||
function setOriginal($filename)
|
||||
public function setOriginal($filename)
|
||||
{
|
||||
// This should be handled by the Profile->setOriginal function so user and group avatars are handled the same
|
||||
$imagefile = new ImageFile(null, Avatar::path($filename));
|
||||
@ -320,8 +333,12 @@ class User_group extends Managed_DataObject
|
||||
$orig = clone($this);
|
||||
$this->original_logo = Avatar::url($filename);
|
||||
foreach ($sizes as $name=>$size) {
|
||||
$filename = Avatar::filename($this->profile_id, image_type_to_extension($imagefile->preferredType()),
|
||||
$size, common_timestamp());
|
||||
$filename = Avatar::filename(
|
||||
$this->profile_id,
|
||||
image_type_to_extension($imagefile->preferredType()),
|
||||
$size,
|
||||
common_timestamp()
|
||||
);
|
||||
$imagefile->resizeTo(Avatar::path($filename), array('width'=>$size, 'height'=>$size));
|
||||
$this->$name = Avatar::url($filename);
|
||||
}
|
||||
@ -329,7 +346,7 @@ class User_group extends Managed_DataObject
|
||||
return $this->update($orig);
|
||||
}
|
||||
|
||||
function getBestName()
|
||||
public function getBestName()
|
||||
{
|
||||
return ($this->fullname) ? $this->fullname : $this->nickname;
|
||||
}
|
||||
@ -340,17 +357,17 @@ class User_group extends Managed_DataObject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getFancyName()
|
||||
public function getFancyName()
|
||||
{
|
||||
if ($this->fullname) {
|
||||
// TRANS: Full name of a profile or group followed by nickname in parens
|
||||
return sprintf(_m('FANCYNAME','%1$s (%2$s)'), $this->fullname, $this->nickname);
|
||||
return sprintf(_m('FANCYNAME', '%1$s (%2$s)'), $this->fullname, $this->nickname);
|
||||
} else {
|
||||
return $this->nickname;
|
||||
}
|
||||
}
|
||||
|
||||
function getAliases()
|
||||
public function getAliases()
|
||||
{
|
||||
$aliases = array();
|
||||
|
||||
@ -371,8 +388,8 @@ class User_group extends Managed_DataObject
|
||||
return $aliases;
|
||||
}
|
||||
|
||||
function setAliases($newaliases) {
|
||||
|
||||
public function setAliases($newaliases)
|
||||
{
|
||||
$newaliases = array_unique($newaliases);
|
||||
|
||||
$oldaliases = $this->getAliases();
|
||||
@ -413,7 +430,7 @@ class User_group extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
|
||||
static function getForNickname($nickname, Profile $profile=null)
|
||||
public static function getForNickname($nickname, Profile $profile = null)
|
||||
{
|
||||
$nickname = Nickname::normalize($nickname);
|
||||
|
||||
@ -440,24 +457,21 @@ class User_group extends Managed_DataObject
|
||||
return null;
|
||||
}
|
||||
|
||||
function getUserMembers()
|
||||
public function getUserMembers()
|
||||
{
|
||||
// XXX: cache this
|
||||
|
||||
$user = new User();
|
||||
if(common_config('db','quote_identifiers'))
|
||||
$user_table = '"user"';
|
||||
else $user_table = 'user';
|
||||
|
||||
$qry =
|
||||
'SELECT id ' .
|
||||
'FROM '. $user_table .' JOIN group_member '.
|
||||
'ON '. $user_table .'.id = group_member.profile_id ' .
|
||||
'WHERE group_member.group_id = %d ';
|
||||
$user->query(sprintf(
|
||||
'SELECT id FROM %1$s INNER JOIN group_member ' .
|
||||
'ON %1$s.id = group_member.profile_id ' .
|
||||
'WHERE group_member.group_id = %2$d ',
|
||||
$user->escapedTableName(),
|
||||
$this->id
|
||||
));
|
||||
|
||||
$user->query(sprintf($qry, $this->id));
|
||||
|
||||
$ids = array();
|
||||
$ids = [];
|
||||
|
||||
while ($user->fetch()) {
|
||||
$ids[] = $user->id;
|
||||
@ -468,7 +482,7 @@ class User_group extends Managed_DataObject
|
||||
return $ids;
|
||||
}
|
||||
|
||||
static function maxDescription()
|
||||
public static function maxDescription()
|
||||
{
|
||||
$desclimit = common_config('group', 'desclimit');
|
||||
// null => use global limit (distinct from 0!)
|
||||
@ -478,13 +492,13 @@ class User_group extends Managed_DataObject
|
||||
return $desclimit;
|
||||
}
|
||||
|
||||
static function descriptionTooLong($desc)
|
||||
public static function descriptionTooLong($desc)
|
||||
{
|
||||
$desclimit = self::maxDescription();
|
||||
return ($desclimit > 0 && !empty($desc) && (mb_strlen($desc) > $desclimit));
|
||||
}
|
||||
|
||||
function asAtomEntry($namespace=false, $source=false)
|
||||
public function asAtomEntry($namespace = false, $source = false)
|
||||
{
|
||||
$xs = new XMLStringer(true);
|
||||
|
||||
@ -528,7 +542,7 @@ class User_group extends Managed_DataObject
|
||||
return $xs->getString();
|
||||
}
|
||||
|
||||
function asAtomAuthor()
|
||||
public function asAtomAuthor()
|
||||
{
|
||||
$xs = new XMLStringer(true);
|
||||
|
||||
@ -551,20 +565,21 @@ class User_group extends Managed_DataObject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function asActivityNoun($element)
|
||||
public function asActivityNoun($element)
|
||||
{
|
||||
$noun = ActivityObject::fromGroup($this);
|
||||
return $noun->asString('activity:' . $element);
|
||||
}
|
||||
|
||||
function getAvatar()
|
||||
public function getAvatar()
|
||||
{
|
||||
return empty($this->homepage_logo)
|
||||
? User_group::defaultLogo(AVATAR_PROFILE_SIZE)
|
||||
: $this->homepage_logo;
|
||||
}
|
||||
|
||||
static function register($fields) {
|
||||
public static function register($fields)
|
||||
{
|
||||
if (!empty($fields['userid'])) {
|
||||
$profile = Profile::getKV('id', $fields['userid']);
|
||||
if ($profile && !$profile->hasRight(Right::CREATEGROUP)) {
|
||||
@ -580,18 +595,20 @@ class User_group extends Managed_DataObject
|
||||
// MAGICALLY put fields into current scope
|
||||
// @fixme kill extract(); it makes debugging absurdly hard
|
||||
|
||||
$defaults = array('nickname' => null,
|
||||
'fullname' => null,
|
||||
'homepage' => null,
|
||||
'description' => null,
|
||||
'location' => null,
|
||||
'uri' => null,
|
||||
'mainpage' => null,
|
||||
'aliases' => array(),
|
||||
'userid' => null);
|
||||
|
||||
$fields = array_merge($defaults, $fields);
|
||||
|
||||
$defaults = [
|
||||
'nickname' => null,
|
||||
'fullname' => null,
|
||||
'homepage' => null,
|
||||
'description' => null,
|
||||
'location' => null,
|
||||
'uri' => null,
|
||||
'mainpage' => null,
|
||||
'aliases' => [],
|
||||
'userid' => null,
|
||||
];
|
||||
|
||||
$fields = array_merge($defaults, $fields);
|
||||
|
||||
extract($fields);
|
||||
|
||||
$group = new User_group();
|
||||
@ -645,7 +662,6 @@ class User_group extends Managed_DataObject
|
||||
}
|
||||
|
||||
if (Event::handle('StartGroupSave', array(&$group))) {
|
||||
|
||||
$result = $group->insert();
|
||||
|
||||
if ($result === false) {
|
||||
@ -676,7 +692,7 @@ class User_group extends Managed_DataObject
|
||||
|
||||
$member->group_id = $group->id;
|
||||
$member->profile_id = $userid;
|
||||
$member->is_admin = 1;
|
||||
$member->is_admin = true;
|
||||
$member->created = $group->created;
|
||||
|
||||
$result = $member->insert();
|
||||
@ -721,7 +737,7 @@ class User_group extends Managed_DataObject
|
||||
* are not de-cached in the UI, including the sidebar lists on
|
||||
* GroupsAction
|
||||
*/
|
||||
function delete($useWhere=false)
|
||||
public function delete($useWhere = false)
|
||||
{
|
||||
if (empty($this->id)) {
|
||||
common_log(LOG_WARNING, "Ambiguous User_group->delete(); skipping related tables.");
|
||||
@ -813,7 +829,7 @@ class User_group extends Managed_DataObject
|
||||
return parent::update($dataObject);
|
||||
}
|
||||
|
||||
function isPrivate()
|
||||
public function isPrivate()
|
||||
{
|
||||
return ($this->join_policy == self::JOIN_POLICY_MODERATE &&
|
||||
intval($this->force_scope) === 1);
|
||||
@ -825,14 +841,16 @@ class User_group extends Managed_DataObject
|
||||
return ($local instanceof Local_group);
|
||||
}
|
||||
|
||||
static function groupsFromText($text, Profile $profile)
|
||||
public static function groupsFromText($text, Profile $profile)
|
||||
{
|
||||
$groups = array();
|
||||
|
||||
/* extract all !group */
|
||||
$count = preg_match_all('/(?:^|\s)!(' . Nickname::DISPLAY_FMT . ')/',
|
||||
strtolower($text),
|
||||
$match);
|
||||
$count = preg_match_all(
|
||||
'/(?:^|\s)!(' . Nickname::DISPLAY_FMT . ')/',
|
||||
strtolower($text),
|
||||
$match
|
||||
);
|
||||
|
||||
if (!$count) {
|
||||
return $groups;
|
||||
@ -848,7 +866,7 @@ class User_group extends Managed_DataObject
|
||||
return $groups;
|
||||
}
|
||||
|
||||
static function idsFromText($text, Profile $profile)
|
||||
public static function idsFromText($text, Profile $profile)
|
||||
{
|
||||
$ids = array();
|
||||
$groups = self::groupsFromText($text, $profile);
|
||||
|
@ -1,32 +1,31 @@
|
||||
<?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
|
||||
*
|
||||
* Data class for user IM preferences
|
||||
*
|
||||
* 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 Data
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @copyright 2009 StatusNet Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||
|
||||
class User_im_prefs extends Managed_DataObject
|
||||
@ -38,9 +37,9 @@ class User_im_prefs extends Managed_DataObject
|
||||
public $user_id; // int(4) primary_key not_null
|
||||
public $screenname; // varchar(191) not_null not 255 because utf8mb4 takes more space
|
||||
public $transport; // varchar(191) not_null not 255 because utf8mb4 takes more space
|
||||
public $notify; // tinyint(1)
|
||||
public $replies; // tinyint(1)
|
||||
public $updatefrompresence; // tinyint(1)
|
||||
public $notify; // bool not_null default_false
|
||||
public $replies; // bool not_null default_false
|
||||
public $updatefrompresence; // bool not_null default_false
|
||||
public $created; // datetime() not_null default_0000-00-00%2000%3A00%3A00
|
||||
public $modified; // datetime() not_null default_CURRENT_TIMESTAMP
|
||||
|
||||
@ -54,9 +53,9 @@ class User_im_prefs extends Managed_DataObject
|
||||
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user'),
|
||||
'screenname' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'screenname on this service'),
|
||||
'transport' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'transport (ex xmpp, aim)'),
|
||||
'notify' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Notify when a new notice is sent'),
|
||||
'replies' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to'),
|
||||
'updatefrompresence' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to.'),
|
||||
'notify' => array('type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Notify when a new notice is sent'),
|
||||
'replies' => array('type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Send replies from people not subscribed to'),
|
||||
'updatefrompresence' => array('type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Update from presence.'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'),
|
||||
),
|
||||
@ -69,5 +68,4 @@ class User_im_prefs extends Managed_DataObject
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,30 +1,27 @@
|
||||
<?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
|
||||
*
|
||||
* Data class for user location preferences
|
||||
*
|
||||
* 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 Data
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2009 StatusNet Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||
@ -36,7 +33,7 @@ class User_location_prefs extends Managed_DataObject
|
||||
|
||||
public $__table = 'user_location_prefs'; // table name
|
||||
public $user_id; // int(4) primary_key not_null
|
||||
public $share_location; // tinyint(1) default_1
|
||||
public $share_location; // bool default_true
|
||||
public $created; // datetime() not_null default_0000-00-00%2000%3A00%3A00
|
||||
public $modified; // datetime() not_null default_CURRENT_TIMESTAMP
|
||||
|
||||
@ -48,7 +45,7 @@ class User_location_prefs extends Managed_DataObject
|
||||
return array(
|
||||
'fields' => array(
|
||||
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user who has the preference'),
|
||||
'share_location' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Whether to share location data'),
|
||||
'share_location' => array('type' => 'bool', 'default' => true, 'description' => 'Whether to share location data'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'),
|
||||
),
|
||||
|
@ -1,9 +1,26 @@
|
||||
<?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/>.
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||
|
||||
/**
|
||||
* Table Definition for user_username
|
||||
*/
|
||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||
|
||||
class User_username extends Managed_DataObject
|
||||
{
|
||||
###START_AUTOCODE
|
||||
@ -23,8 +40,8 @@ class User_username extends Managed_DataObject
|
||||
{
|
||||
return array(
|
||||
'fields' => array(
|
||||
'provider_name' => array('type' => 'varchar', 'length' => 191, 'description' => 'provider name'),
|
||||
'username' => array('type' => 'varchar', 'length' => 191, 'description' => 'username'),
|
||||
'provider_name' => array('type' => 'varchar', 'not null' => true, 'length' => 191, 'description' => 'provider name'),
|
||||
'username' => array('type' => 'varchar', 'not null' => true, 'length' => 191, 'description' => 'username'),
|
||||
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice id this title relates to'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'),
|
||||
@ -46,7 +63,7 @@ class User_username extends Managed_DataObject
|
||||
* @param provider_name string name of the provider
|
||||
* @return mixed User_username instance if the registration succeeded, false if it did not
|
||||
*/
|
||||
static function register($user, $username, $provider_name)
|
||||
public static function register($user, $username, $provider_name)
|
||||
{
|
||||
$user_username = new User_username();
|
||||
$user_username->user_id = $user->id;
|
||||
@ -54,9 +71,9 @@ class User_username extends Managed_DataObject
|
||||
$user_username->username = $username;
|
||||
$user_username->created = common_sql_now();
|
||||
|
||||
if($user_username->insert()){
|
||||
if ($user_username->insert()) {
|
||||
return $user_username;
|
||||
}else{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
137
db/core.php
137
db/core.php
@ -1,13 +1,23 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
*
|
||||
* Some notes...
|
||||
*
|
||||
* Drupal docs don't list a bool type, but it might be nice to use rather than 'tinyint'
|
||||
* Note however that we use bitfields and things as well in tinyints, and PG's
|
||||
* "bool" type isn't 100% compatible with 0/1 checks. Just keeping tinyints. :)
|
||||
*
|
||||
* decimal <-> numeric
|
||||
*
|
||||
* MySQL 'timestamp' columns were formerly used for 'modified' files for their
|
||||
@ -29,64 +39,67 @@
|
||||
* double-check what we've been doing on postgres?
|
||||
*/
|
||||
|
||||
$classes = array('Schema_version',
|
||||
'Profile',
|
||||
'Avatar',
|
||||
'Sms_carrier',
|
||||
'User',
|
||||
'Subscription',
|
||||
'Group_join_queue',
|
||||
'Subscription_queue',
|
||||
'Oauth_token_association',
|
||||
'Notice',
|
||||
'Notice_location',
|
||||
'Notice_source',
|
||||
'Notice_prefs',
|
||||
'Reply',
|
||||
'Consumer',
|
||||
'Token',
|
||||
'Nonce',
|
||||
'Oauth_application',
|
||||
'Oauth_application_user',
|
||||
'Confirm_address',
|
||||
'Remember_me',
|
||||
'Queue_item',
|
||||
'Notice_tag',
|
||||
'Foreign_service',
|
||||
'Foreign_user',
|
||||
'Foreign_link',
|
||||
'Foreign_subscription',
|
||||
'Invitation',
|
||||
'Profile_prefs',
|
||||
'Profile_tag',
|
||||
'Profile_list',
|
||||
'Profile_tag_subscription',
|
||||
'Profile_block',
|
||||
'User_group',
|
||||
'Related_group',
|
||||
'Group_inbox',
|
||||
'Group_member',
|
||||
'File',
|
||||
'File_redirection',
|
||||
'File_thumbnail',
|
||||
'File_to_post',
|
||||
'Group_block',
|
||||
'Group_alias',
|
||||
'Session',
|
||||
'Config',
|
||||
'Profile_role',
|
||||
'Location_namespace',
|
||||
'Login_token',
|
||||
'User_location_prefs',
|
||||
'User_im_prefs',
|
||||
'Conversation',
|
||||
'Local_group',
|
||||
'User_urlshortener_prefs',
|
||||
'Old_school_prefs',
|
||||
'User_username',
|
||||
'Attention',
|
||||
);
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
$classes = [
|
||||
'Schema_version',
|
||||
'Profile',
|
||||
'Avatar',
|
||||
'Sms_carrier',
|
||||
'User',
|
||||
'User_group',
|
||||
'Subscription',
|
||||
'Group_join_queue',
|
||||
'Subscription_queue',
|
||||
'Consumer',
|
||||
'Oauth_application',
|
||||
'Oauth_token_association',
|
||||
'Conversation',
|
||||
'Notice',
|
||||
'Notice_location',
|
||||
'Notice_source',
|
||||
'Notice_prefs',
|
||||
'Reply',
|
||||
'Token',
|
||||
'Nonce',
|
||||
'Oauth_application_user',
|
||||
'Confirm_address',
|
||||
'Remember_me',
|
||||
'Queue_item',
|
||||
'Notice_tag',
|
||||
'Foreign_service',
|
||||
'Foreign_user',
|
||||
'Foreign_link',
|
||||
'Foreign_subscription',
|
||||
'Invitation',
|
||||
'Profile_prefs',
|
||||
'Profile_list',
|
||||
'Profile_tag',
|
||||
'Profile_tag_subscription',
|
||||
'Profile_block',
|
||||
'Related_group',
|
||||
'Group_inbox',
|
||||
'Group_member',
|
||||
'File',
|
||||
'File_redirection',
|
||||
'File_thumbnail',
|
||||
'File_to_post',
|
||||
'Group_block',
|
||||
'Group_alias',
|
||||
'Session',
|
||||
'Config',
|
||||
'Profile_role',
|
||||
'Location_namespace',
|
||||
'Login_token',
|
||||
'User_location_prefs',
|
||||
'User_im_prefs',
|
||||
'Local_group',
|
||||
'User_urlshortener_prefs',
|
||||
'Old_school_prefs',
|
||||
'User_username',
|
||||
'Attention'
|
||||
];
|
||||
|
||||
foreach ($classes as $cls) {
|
||||
$schema[strtolower($cls)] = call_user_func(array($cls, 'schemaDef'));
|
||||
$schema[strtolower($cls)] = call_user_func([$cls, 'schemaDef']);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ VALUES
|
||||
(100088, 'Orange (Poland)', '%s@orange.pl', now()),
|
||||
(100089, 'Personal (Argentina)', '%s@personal-net.com.ar', now()),
|
||||
(100090, 'Plus GSM (Poland)', '%s@text.plusgsm.pl', now()),
|
||||
(100091, 'President\'s Choice (Canada)', '%s@txt.bell.ca', now()),
|
||||
(100091, 'President''s Choice (Canada)', '%s@txt.bell.ca', now()),
|
||||
(100092, 'Qwest', '%s@qwestmp.com', now()),
|
||||
(100093, 'Rogers (Canada)', '%s@pcs.rogers.com', now()),
|
||||
(100094, 'Sasktel (Canada)', '%s@sms.sasktel.com', now()),
|
||||
|
@ -1787,12 +1787,34 @@ class DB_DataObject extends DB_DataObject_Overload
|
||||
// note: we dont declare this to keep the print_r size down.
|
||||
$_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid] = array_flip(array_keys($array));
|
||||
}
|
||||
|
||||
$dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'];
|
||||
if ($dbtype === 'pgsql') {
|
||||
if (($_DB_DATAOBJECT['CONFIG']['db_driver'] ?? 'DB') === 'DB') {
|
||||
$tableInfo = $result->tableInfo();
|
||||
} elseif ($result->db->supports('result_introspection')) { // MDB2
|
||||
$result->db->loadModule('Reverse', null, true);
|
||||
$tableInfo = $result->db->reverse->tableInfo($result);
|
||||
}
|
||||
}
|
||||
|
||||
$replace = array('.', ' ');
|
||||
foreach ($array as $k => $v) {
|
||||
foreach (array_keys($array) as $i => $k) {
|
||||
// use strpos as str_replace is slow.
|
||||
$kk = (strpos($k, '.') === false && strpos($k, ' ') === false) ?
|
||||
$k : str_replace($replace, '_', $k);
|
||||
|
||||
if ($dbtype === 'pgsql') {
|
||||
switch ($tableInfo[$i]['type']) {
|
||||
case 'bool':
|
||||
$array[$k] = str_replace(['t', 'f'], ['1', '0'], $array[$k]);
|
||||
break;
|
||||
case 'bytea':
|
||||
$array[$k] = pg_unescape_bytea($array[$k]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
|
||||
$this->debug("$kk = " . $array[$k], "fetchrow LINE", 3);
|
||||
}
|
||||
@ -2418,7 +2440,7 @@ class DB_DataObject extends DB_DataObject_Overload
|
||||
|
||||
case 'pgsql':
|
||||
if (!$seq) {
|
||||
$seq = $DB->getSequenceName(strtolower($this->tableName()));
|
||||
$seq = $DB->getSequenceName(strtolower($this->tableName() . '_' . $key));
|
||||
}
|
||||
$db_driver = empty($options['db_driver']) ? 'DB' : $options['db_driver'];
|
||||
$method = ($db_driver == 'DB') ? 'getOne' : 'queryOne';
|
||||
@ -2949,12 +2971,34 @@ class DB_DataObject extends DB_DataObject_Overload
|
||||
$this->raiseError("fetchrow: No results available", DB_DATAOBJECT_ERROR_NODATA);
|
||||
return false;
|
||||
}
|
||||
|
||||
$dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'];
|
||||
if ($dbtype === 'pgsql') {
|
||||
if (($_DB_DATAOBJECT['CONFIG']['db_driver'] ?? 'DB') === 'DB') {
|
||||
$tableInfo = $result->tableInfo();
|
||||
} elseif ($result->db->supports('result_introspection')) { // MDB2
|
||||
$result->db->loadModule('Reverse', null, true);
|
||||
$tableInfo = $result->db->reverse->tableInfo($result);
|
||||
}
|
||||
}
|
||||
|
||||
$replace = array('.', ' ');
|
||||
foreach ($array as $k => $v) {
|
||||
foreach (array_keys($array) as $i => $k) {
|
||||
// use strpos as str_replace is slow.
|
||||
$kk = (strpos($k, '.') === false && strpos($k, ' ') === false) ?
|
||||
$k : str_replace($replace, '_', $k);
|
||||
|
||||
if ($dbtype === 'pgsql') {
|
||||
switch ($tableInfo[$i]['type']) {
|
||||
case 'bool':
|
||||
$array[$k] = str_replace(['t', 'f'], ['1', '0'], $array[$k]);
|
||||
break;
|
||||
case 'bytea':
|
||||
$array[$k] = pg_unescape_bytea($array[$k]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
|
||||
$this->debug("$kk = " . $array[$k], "fetchrow LINE", 3);
|
||||
}
|
||||
|
@ -1,36 +1,31 @@
|
||||
<?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
|
||||
*
|
||||
* Base class for all actions (~views)
|
||||
*
|
||||
* 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 Action
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @copyright 2008 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Base class for all actions
|
||||
@ -41,14 +36,11 @@ if (!defined('GNUSOCIAL')) {
|
||||
* Actions are responsible for extracting and validating parameters; using
|
||||
* model classes to read and write to the database; and doing ouput.
|
||||
*
|
||||
* @category Output
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @category Output
|
||||
* @copyright 2008 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see HTMLOutputter
|
||||
* @see HTMLOutputter
|
||||
*/
|
||||
class Action extends HTMLOutputter // lawsuit
|
||||
{
|
||||
@ -1566,19 +1558,6 @@ class Action extends HTMLOutputter // lawsuit
|
||||
// needs to be defined by the class
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a cheap hack to avoid a bug in DB_DataObject
|
||||
* where '' is non-type-aware compared to 0, which means it
|
||||
* will always be true for values like false and 0 too...
|
||||
*
|
||||
* Upstream bug is::
|
||||
* https://pear.php.net/bugs/bug.php?id=20291
|
||||
*/
|
||||
public function booleanintstring($key, $def = false)
|
||||
{
|
||||
return $this->boolean($key, $def) ? '1' : '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer value of an argument
|
||||
*
|
||||
|
@ -17,9 +17,9 @@
|
||||
/**
|
||||
* Database schema for MariaDB
|
||||
*
|
||||
* @category Database
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @category Database
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
@ -38,21 +38,20 @@ defined('GNUSOCIAL') || die();
|
||||
*/
|
||||
class MysqlSchema extends Schema
|
||||
{
|
||||
static $_single = null;
|
||||
protected $conn = null;
|
||||
public static $_single = null;
|
||||
|
||||
/**
|
||||
* Main public entry point. Use this to get
|
||||
* the singleton object.
|
||||
*
|
||||
* @param null $conn
|
||||
* @param object|null $conn
|
||||
* @param string|null dummy param
|
||||
* @return Schema the (single) Schema object
|
||||
*/
|
||||
|
||||
static function get($conn = null)
|
||||
public static function get($conn = null, $_ = 'mysql')
|
||||
{
|
||||
if (empty(self::$_single)) {
|
||||
self::$_single = new Schema($conn);
|
||||
self::$_single = new Schema($conn, 'mysql');
|
||||
}
|
||||
return self::$_single;
|
||||
}
|
||||
@ -69,7 +68,6 @@ class MysqlSchema extends Schema
|
||||
* @throws PEAR_Exception
|
||||
* @throws SchemaTableMissingException
|
||||
*/
|
||||
|
||||
public function getTableDef($table)
|
||||
{
|
||||
$def = [];
|
||||
@ -82,7 +80,6 @@ class MysqlSchema extends Schema
|
||||
}
|
||||
|
||||
foreach ($columns as $row) {
|
||||
|
||||
$name = $row['COLUMN_NAME'];
|
||||
$field = [];
|
||||
|
||||
@ -109,14 +106,16 @@ class MysqlSchema extends Schema
|
||||
$field['not null'] = true;
|
||||
}
|
||||
if ($row['COLUMN_DEFAULT'] !== null) {
|
||||
// Hack for timestamp cols
|
||||
if ($type == 'timestamp' && $row['COLUMN_DEFAULT'] == 'CURRENT_TIMESTAMP') {
|
||||
// skip because timestamp is numerical, but it accepts datetime strings as well
|
||||
// Hack for timestamp columns
|
||||
if ($row['COLUMN_DEFAULT'] === 'current_timestamp()') {
|
||||
// skip timestamp columns as they get a CURRENT_TIMESTAMP default implicitly
|
||||
if ($type !== 'timestamp') {
|
||||
$field['default'] = 'CURRENT_TIMESTAMP';
|
||||
}
|
||||
} elseif ($this->isNumericType($type)) {
|
||||
$field['default'] = intval($row['COLUMN_DEFAULT']);
|
||||
} else {
|
||||
$field['default'] = $row['COLUMN_DEFAULT'];
|
||||
if ($this->isNumericType($type)) {
|
||||
$field['default'] = intval($field['default']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($row['COLUMN_KEY'] !== null) {
|
||||
@ -166,9 +165,9 @@ class MysqlSchema extends Schema
|
||||
|
||||
if ($name == 'PRIMARY') {
|
||||
$type = 'primary key';
|
||||
} else if ($row['Non_unique'] == 0) {
|
||||
} elseif ($row['Non_unique'] == 0) {
|
||||
$type = 'unique keys';
|
||||
} else if ($row['Index_type'] == 'FULLTEXT') {
|
||||
} elseif ($row['Index_type'] === 'FULLTEXT') {
|
||||
$type = 'fulltext indexes';
|
||||
} else {
|
||||
$type = 'indexes';
|
||||
@ -198,8 +197,7 @@ class MysqlSchema extends Schema
|
||||
* @throws PEAR_Exception
|
||||
* @throws SchemaTableMissingException
|
||||
*/
|
||||
|
||||
function getTableProperties($table, $props)
|
||||
public function getTableProperties($table, $props)
|
||||
{
|
||||
$data = $this->fetchMetaInfo($table, 'TABLES');
|
||||
if ($data) {
|
||||
@ -218,7 +216,7 @@ class MysqlSchema extends Schema
|
||||
* @return array of arrays
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
function fetchMetaInfo($table, $infoTable, $orderBy = null)
|
||||
public function fetchMetaInfo($table, $infoTable, $orderBy = null)
|
||||
{
|
||||
$query = "SELECT * FROM INFORMATION_SCHEMA.%s " .
|
||||
"WHERE TABLE_SCHEMA='%s' AND TABLE_NAME='%s'";
|
||||
@ -237,7 +235,7 @@ class MysqlSchema extends Schema
|
||||
* @return array of arrays
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
function fetchIndexInfo($table)
|
||||
public function fetchIndexInfo($table)
|
||||
{
|
||||
$query = "SHOW INDEX FROM `%s`";
|
||||
$sql = sprintf($query, $table);
|
||||
@ -253,7 +251,7 @@ class MysqlSchema extends Schema
|
||||
* @param string $name
|
||||
* @param array $def
|
||||
*/
|
||||
function appendCreateFulltextIndex(array &$statements, $table, $name, array $def)
|
||||
public function appendCreateFulltextIndex(array &$statements, $table, $name, array $def)
|
||||
{
|
||||
$statements[] = "CREATE FULLTEXT INDEX $name ON $table " . $this->buildIndexList($def);
|
||||
}
|
||||
@ -266,13 +264,13 @@ class MysqlSchema extends Schema
|
||||
* @return string;
|
||||
*
|
||||
*/
|
||||
function endCreateTable($name, array $def)
|
||||
public function endCreateTable($name, array $def)
|
||||
{
|
||||
$engine = $this->preferredEngine($def);
|
||||
return ") ENGINE=$engine CHARACTER SET utf8mb4 COLLATE utf8mb4_bin";
|
||||
}
|
||||
|
||||
function preferredEngine($def)
|
||||
public function preferredEngine($def)
|
||||
{
|
||||
/* MyISAM is no longer required for fulltext indexes, fortunately
|
||||
if (!empty($def['fulltext indexes'])) {
|
||||
@ -288,7 +286,7 @@ class MysqlSchema extends Schema
|
||||
* @param $columnName
|
||||
* @return string
|
||||
*/
|
||||
function _uniqueKey($tableName, $columnName)
|
||||
public function _uniqueKey($tableName, $columnName)
|
||||
{
|
||||
return $this->_key($tableName, $columnName);
|
||||
}
|
||||
@ -299,7 +297,7 @@ class MysqlSchema extends Schema
|
||||
* @param $columnName
|
||||
* @return string
|
||||
*/
|
||||
function _key($tableName, $columnName)
|
||||
public function _key($tableName, $columnName)
|
||||
{
|
||||
return "{$tableName}_{$columnName}_idx";
|
||||
}
|
||||
@ -310,7 +308,7 @@ class MysqlSchema extends Schema
|
||||
*
|
||||
* @param array $phrase
|
||||
*/
|
||||
function appendAlterDropPrimary(array &$phrase)
|
||||
public function appendAlterDropPrimary(array &$phrase, string $tableName)
|
||||
{
|
||||
$phrase[] = 'DROP PRIMARY KEY';
|
||||
}
|
||||
@ -322,7 +320,7 @@ class MysqlSchema extends Schema
|
||||
* @param array $phrase
|
||||
* @param string $keyName MySQL
|
||||
*/
|
||||
function appendAlterDropUnique(array &$phrase, $keyName)
|
||||
public function appendAlterDropUnique(array &$phrase, $keyName)
|
||||
{
|
||||
$phrase[] = 'DROP INDEX ' . $keyName;
|
||||
}
|
||||
@ -335,7 +333,7 @@ class MysqlSchema extends Schema
|
||||
* @param array $def
|
||||
* @throws Exception
|
||||
*/
|
||||
function appendAlterExtras(array &$phrase, $tableName, array $def)
|
||||
public function appendAlterExtras(array &$phrase, $tableName, array $def)
|
||||
{
|
||||
// Check for table properties: make sure we're using a sane
|
||||
// engine type and charset/collation.
|
||||
@ -370,15 +368,15 @@ class MysqlSchema extends Schema
|
||||
* Appropriate for use in CREATE TABLE or
|
||||
* ALTER TABLE statements.
|
||||
*
|
||||
* @param string $name column name to create
|
||||
* @param array $cd column to create
|
||||
*
|
||||
* @return string correct SQL for that column
|
||||
*/
|
||||
|
||||
function columnSql(array $cd)
|
||||
public function columnSql(string $name, array $cd)
|
||||
{
|
||||
$line = [];
|
||||
$line[] = parent::columnSql($cd);
|
||||
$line[] = parent::columnSql($name, $cd);
|
||||
|
||||
// This'll have been added from our transform of 'serial' type
|
||||
if (!empty($cd['auto_increment'])) {
|
||||
@ -393,12 +391,12 @@ class MysqlSchema extends Schema
|
||||
return implode(' ', $line);
|
||||
}
|
||||
|
||||
function mapType($column)
|
||||
public function mapType($column)
|
||||
{
|
||||
$map = [
|
||||
'serial' => 'int',
|
||||
'integer' => 'int',
|
||||
'numeric' => 'decimal'
|
||||
'bool' => 'tinyint',
|
||||
'numeric' => 'decimal',
|
||||
];
|
||||
|
||||
$type = $column['type'];
|
||||
@ -411,7 +409,9 @@ class MysqlSchema extends Schema
|
||||
if ($type == 'int' &&
|
||||
in_array($size, ['tiny', 'small', 'medium', 'big'])) {
|
||||
$type = $size . $type;
|
||||
} else if (in_array($type, ['blob', 'text']) &&
|
||||
} elseif ($type == 'float' && $size == 'big') {
|
||||
$type = 'double';
|
||||
} elseif (in_array($type, ['blob', 'text']) &&
|
||||
in_array($size, ['tiny', 'medium', 'long'])) {
|
||||
$type = $size . $type;
|
||||
}
|
||||
@ -420,13 +420,15 @@ class MysqlSchema extends Schema
|
||||
return $type;
|
||||
}
|
||||
|
||||
function typeAndSize($column)
|
||||
public function typeAndSize(string $name, array $column)
|
||||
{
|
||||
if ($column['type'] == 'enum') {
|
||||
$vals = array_map([$this, 'quote'], $column['enum']);
|
||||
if ($column['type'] === 'enum') {
|
||||
foreach ($column['enum'] as &$val) {
|
||||
$vals[] = "'" . $val . "'";
|
||||
}
|
||||
return 'enum(' . implode(',', $vals) . ')';
|
||||
} else if ($this->_isString($column)) {
|
||||
$col = parent::typeAndSize($column);
|
||||
} elseif ($this->_isString($column)) {
|
||||
$col = parent::typeAndSize($name, $column);
|
||||
if (!empty($column['charset'])) {
|
||||
$col .= ' CHARSET ' . $column['charset'];
|
||||
}
|
||||
@ -435,7 +437,7 @@ class MysqlSchema extends Schema
|
||||
}
|
||||
return $col;
|
||||
} else {
|
||||
return parent::typeAndSize($column);
|
||||
return parent::typeAndSize($name, $column);
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,7 +451,7 @@ class MysqlSchema extends Schema
|
||||
* @param array $tableDef
|
||||
* @return array
|
||||
*/
|
||||
function filterDef(array $tableDef)
|
||||
public function filterDef(array $tableDef)
|
||||
{
|
||||
$version = $this->conn->getVersion();
|
||||
foreach ($tableDef['fields'] as $name => &$col) {
|
||||
|
@ -17,11 +17,11 @@
|
||||
/**
|
||||
* Database schema for PostgreSQL
|
||||
*
|
||||
* @category Database
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Brenda Wallace <shiny@cpan.org>
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @category Database
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Brenda Wallace <shiny@cpan.org>
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
@ -40,6 +40,23 @@ defined('GNUSOCIAL') || die();
|
||||
*/
|
||||
class PgsqlSchema extends Schema
|
||||
{
|
||||
public static $_single = null;
|
||||
|
||||
/**
|
||||
* Main public entry point. Use this to get
|
||||
* the singleton object.
|
||||
*
|
||||
* @param object|null $conn
|
||||
* @param string|null dummy param
|
||||
* @return Schema the (single) Schema object
|
||||
*/
|
||||
public static function get($conn = null, $_ = 'pgsql')
|
||||
{
|
||||
if (empty(self::$_single)) {
|
||||
self::$_single = new Schema($conn, 'pgsql');
|
||||
}
|
||||
return self::$_single;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a table definition array for the table
|
||||
@ -52,7 +69,6 @@ class PgsqlSchema extends Schema
|
||||
* @return array tabledef for that table.
|
||||
* @throws SchemaTableMissingException
|
||||
*/
|
||||
|
||||
public function getTableDef($table)
|
||||
{
|
||||
$def = [];
|
||||
@ -68,14 +84,13 @@ class PgsqlSchema extends Schema
|
||||
$orderedFields = [];
|
||||
|
||||
foreach ($columns as $row) {
|
||||
|
||||
$name = $row['column_name'];
|
||||
$orderedFields[$row['ordinal_position']] = $name;
|
||||
|
||||
$field = [];
|
||||
$field['type'] = $type = $row['udt_name'];
|
||||
|
||||
if ($type == 'char' || $type == 'varchar') {
|
||||
if (in_array($type, ['char', 'bpchar', 'varchar'])) {
|
||||
if ($row['character_maximum_length'] !== null) {
|
||||
$field['length'] = intval($row['character_maximum_length']);
|
||||
}
|
||||
@ -106,7 +121,8 @@ class PgsqlSchema extends Schema
|
||||
// Pulling index info from pg_class & pg_index
|
||||
// This can give us primary & unique key info, but not foreign key constraints
|
||||
// so we exclude them and pick them up later.
|
||||
$indexInfo = $this->getIndexInfo($table);
|
||||
$indexInfo = $this->fetchIndexInfo($table);
|
||||
|
||||
foreach ($indexInfo as $row) {
|
||||
$keyName = $row['key_name'];
|
||||
|
||||
@ -146,8 +162,8 @@ class PgsqlSchema extends Schema
|
||||
// name hack -- is this reliable?
|
||||
if ($keyName == "{$table}_pkey") {
|
||||
$def['primary key'] = $cols;
|
||||
} else if (preg_match("/^{$table}_(.*)_fkey$/", $keyName, $matches)) {
|
||||
$fkey = $this->getForeignKeyInfo($table, $keyName);
|
||||
} elseif (preg_match("/^{$table}_(.*)_fkey$/", $keyName, $matches)) {
|
||||
$fkey = $this->fetchForeignKeyInfo($table, $keyName);
|
||||
$colMap = array_combine($cols, $fkey['col_names']);
|
||||
$def['foreign keys'][$keyName] = [$fkey['table_name'], $colMap];
|
||||
} else {
|
||||
@ -166,7 +182,7 @@ class PgsqlSchema extends Schema
|
||||
* @return array of arrays
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
function fetchMetaInfo($table, $infoTable, $orderBy = null)
|
||||
public function fetchMetaInfo($table, $infoTable, $orderBy = null)
|
||||
{
|
||||
$query = "SELECT * FROM information_schema.%s " .
|
||||
"WHERE table_name='%s'";
|
||||
@ -183,47 +199,42 @@ class PgsqlSchema extends Schema
|
||||
* @return array of arrays
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
function getIndexInfo($table)
|
||||
public function fetchIndexInfo(string $table): array
|
||||
{
|
||||
$query = 'SELECT ' .
|
||||
'(SELECT relname FROM pg_class WHERE oid=indexrelid) AS key_name, ' .
|
||||
'* FROM pg_index ' .
|
||||
'WHERE indrelid=(SELECT oid FROM pg_class WHERE relname=\'%s\') ' .
|
||||
'AND indisprimary=\'f\' AND indisunique=\'f\' ' .
|
||||
$query = 'SELECT indexname AS key_name, indexdef AS key_def, pg_index.* ' .
|
||||
'FROM pg_index INNER JOIN pg_indexes ON pg_index.indexrelid = CAST(pg_indexes.indexname AS regclass) ' .
|
||||
'WHERE tablename = \'%s\' AND indisprimary = FALSE AND indisunique = FALSE ' .
|
||||
'ORDER BY indrelid, indexrelid';
|
||||
$sql = sprintf($query, $table);
|
||||
return $this->fetchQueryData($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Column names from the foreign table can be resolved with a call to getTableColumnNames()
|
||||
* @param string $table
|
||||
* @param $constraint_name
|
||||
* @return array array of rows with keys: fkey_name, table_name, table_id, col_names (array of strings)
|
||||
* @param string $constraint_name
|
||||
* @return array array of rows with keys: table_name, col_names (array of strings)
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
function getForeignKeyInfo($table, $constraint_name)
|
||||
public function fetchForeignKeyInfo(string $table, string $constraint_name): array
|
||||
{
|
||||
// In a sane world, it'd be easier to query the column names directly.
|
||||
// But it's pretty hard to work with arrays such as col_indexes in direct SQL here.
|
||||
$query = 'SELECT ' .
|
||||
'(SELECT relname FROM pg_class WHERE oid=confrelid) AS table_name, ' .
|
||||
'(SELECT relname FROM pg_class WHERE oid = confrelid) AS table_name, ' .
|
||||
'confrelid AS table_id, ' .
|
||||
'(SELECT indkey FROM pg_index WHERE indexrelid=conindid) AS col_indexes ' .
|
||||
'(SELECT indkey FROM pg_index WHERE indexrelid = conindid) AS col_indices ' .
|
||||
'FROM pg_constraint ' .
|
||||
'WHERE conrelid=(SELECT oid FROM pg_class WHERE relname=\'%s\') ' .
|
||||
'AND conname=\'%s\' ' .
|
||||
'AND contype=\'f\'';
|
||||
'WHERE conrelid = CAST(\'%s\' AS regclass) AND conname = \'%s\' AND contype = \'f\'';
|
||||
$sql = sprintf($query, $table, $constraint_name);
|
||||
$data = $this->fetchQueryData($sql);
|
||||
if (count($data) < 1) {
|
||||
throw new Exception("Could not find foreign key " . $constraint_name . " on table " . $table);
|
||||
throw new Exception('Could not find foreign key ' . $constraint_name . ' on table ' . $table);
|
||||
}
|
||||
|
||||
$row = $data[0];
|
||||
return [
|
||||
'table_name' => $row['table_name'],
|
||||
'col_names' => $this->getTableColumnNames($row['table_id'], $row['col_indexes'])
|
||||
'col_names' => $this->getTableColumnNames($row['table_id'], $row['col_indices'])
|
||||
];
|
||||
}
|
||||
|
||||
@ -234,7 +245,7 @@ class PgsqlSchema extends Schema
|
||||
* @return array of strings
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
function getTableColumnNames($table_id, $col_indexes)
|
||||
public function getTableColumnNames($table_id, $col_indexes)
|
||||
{
|
||||
$indexes = array_map('intval', explode(' ', $col_indexes));
|
||||
$query = 'SELECT attnum AS col_index, attname AS col_name ' .
|
||||
@ -255,23 +266,6 @@ class PgsqlSchema extends Schema
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the (mostly) mysql-ish column types into somethings more standard
|
||||
* @param string column type
|
||||
*
|
||||
* @return string postgres happy column type
|
||||
*/
|
||||
private function _columnTypeTranslation($type)
|
||||
{
|
||||
$map = [
|
||||
'datetime' => 'timestamp',
|
||||
];
|
||||
if (!empty($map[$type])) {
|
||||
return $map[$type];
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the proper SQL for creating or
|
||||
* altering a column.
|
||||
@ -279,15 +273,15 @@ class PgsqlSchema extends Schema
|
||||
* Appropriate for use in CREATE TABLE or
|
||||
* ALTER TABLE statements.
|
||||
*
|
||||
* @param string $name column name to create
|
||||
* @param array $cd column to create
|
||||
*
|
||||
* @return string correct SQL for that column
|
||||
*/
|
||||
|
||||
function columnSql(array $cd)
|
||||
public function columnSql(string $name, array $cd)
|
||||
{
|
||||
$line = [];
|
||||
$line[] = parent::columnSql($cd);
|
||||
$line[] = parent::columnSql($name, $cd);
|
||||
|
||||
/*
|
||||
if ($table['foreign keys'][$name]) {
|
||||
@ -299,6 +293,16 @@ class PgsqlSchema extends Schema
|
||||
}
|
||||
*/
|
||||
|
||||
// This'll have been added from our transform of 'serial' type
|
||||
if (!empty($cd['auto_increment'])) {
|
||||
$line[] = 'GENERATED BY DEFAULT AS IDENTITY';
|
||||
} elseif (!empty($cd['enum'])) {
|
||||
foreach ($cd['enum'] as &$val) {
|
||||
$vals[] = "'" . $val . "'";
|
||||
}
|
||||
$line[] = 'CHECK (' . $name . ' IN (' . implode(',', $vals) . '))';
|
||||
}
|
||||
|
||||
return implode(' ', $line);
|
||||
}
|
||||
|
||||
@ -311,29 +315,35 @@ class PgsqlSchema extends Schema
|
||||
* @param array $old previous column definition as found in DB
|
||||
* @param array $cd current column definition
|
||||
*/
|
||||
function appendAlterModifyColumn(array &$phrase, $columnName, array $old, array $cd)
|
||||
public function appendAlterModifyColumn(array &$phrase, $columnName, array $old, array $cd)
|
||||
{
|
||||
$prefix = 'ALTER COLUMN ' . $this->quoteIdentifier($columnName) . ' ';
|
||||
|
||||
$oldType = $this->mapType($old);
|
||||
$newType = $this->mapType($cd);
|
||||
$oldType = $this->typeAndSize($columnName, $old);
|
||||
$newType = $this->typeAndSize($columnName, $cd);
|
||||
if ($oldType != $newType) {
|
||||
$phrase[] = $prefix . 'TYPE ' . $newType;
|
||||
}
|
||||
|
||||
if (!empty($old['not null']) && empty($cd['not null'])) {
|
||||
$phrase[] = $prefix . 'DROP NOT NULL';
|
||||
} else if (empty($old['not null']) && !empty($cd['not null'])) {
|
||||
} elseif (empty($old['not null']) && !empty($cd['not null'])) {
|
||||
$phrase[] = $prefix . 'SET NOT NULL';
|
||||
}
|
||||
|
||||
if (isset($old['default']) && !isset($cd['default'])) {
|
||||
$phrase[] = $prefix . 'DROP DEFAULT';
|
||||
} else if (!isset($old['default']) && isset($cd['default'])) {
|
||||
} elseif (!isset($old['default']) && isset($cd['default'])) {
|
||||
$phrase[] = $prefix . 'SET DEFAULT ' . $this->quoteDefaultValue($cd);
|
||||
}
|
||||
}
|
||||
|
||||
public function appendAlterDropPrimary(array &$phrase, string $tableName)
|
||||
{
|
||||
// name hack -- is this reliable?
|
||||
$phrase[] = 'DROP CONSTRAINT ' . $this->quoteIdentifier($tableName . '_pkey');
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an SQL statement to drop an index from a table.
|
||||
* Note that in PostgreSQL, index names are DB-unique.
|
||||
@ -342,29 +352,19 @@ class PgsqlSchema extends Schema
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
*/
|
||||
function appendDropIndex(array &$statements, $table, $name)
|
||||
public function appendDropIndex(array &$statements, $table, $name)
|
||||
{
|
||||
$statements[] = "DROP INDEX $name";
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote a db/table/column identifier if necessary.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
function quoteIdentifier($name)
|
||||
{
|
||||
return $this->conn->quoteIdentifier($name);
|
||||
}
|
||||
|
||||
function mapType($column)
|
||||
public function mapType($column)
|
||||
{
|
||||
$map = [
|
||||
'serial' => 'bigserial', // FIXME: creates the wrong name for the sequence for some internal sequence-lookup function, so better fix this to do the real 'create sequence' dance.
|
||||
'numeric' => 'decimal',
|
||||
'integer' => 'int',
|
||||
'char' => 'bpchar',
|
||||
'datetime' => 'timestamp',
|
||||
'blob' => 'bytea'
|
||||
'blob' => 'bytea',
|
||||
'enum' => 'text',
|
||||
];
|
||||
|
||||
$type = $column['type'];
|
||||
@ -372,32 +372,22 @@ class PgsqlSchema extends Schema
|
||||
$type = $map[$type];
|
||||
}
|
||||
|
||||
if ($type == 'int') {
|
||||
if (!empty($column['size'])) {
|
||||
$size = $column['size'];
|
||||
if ($size == 'small') {
|
||||
return 'int2';
|
||||
} else if ($size == 'big') {
|
||||
return 'int8';
|
||||
}
|
||||
$size = $column['size'] ?? null;
|
||||
if ($type === 'int') {
|
||||
if (in_array($size, ['tiny', 'small'])) {
|
||||
$type = 'int2';
|
||||
} elseif ($size === 'big') {
|
||||
$type = 'int8';
|
||||
} else {
|
||||
$type = 'int4';
|
||||
}
|
||||
return 'int4';
|
||||
} elseif ($type === 'float') {
|
||||
$type = ($size !== 'big') ? 'float4' : 'float8';
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
// @fixme need name... :P
|
||||
function typeAndSize($column)
|
||||
{
|
||||
if ($column['type'] == 'enum') {
|
||||
$vals = array_map([$this, 'quote'], $column['enum']);
|
||||
return "text check ($name in " . implode(',', $vals) . ')';
|
||||
} else {
|
||||
return parent::typeAndSize($column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the given table definition array to match features available
|
||||
* in this database.
|
||||
@ -408,23 +398,39 @@ class PgsqlSchema extends Schema
|
||||
* @param array $tableDef
|
||||
* @return array
|
||||
*/
|
||||
function filterDef(array $tableDef)
|
||||
public function filterDef(array $tableDef)
|
||||
{
|
||||
foreach ($tableDef['fields'] as $name => &$col) {
|
||||
// No convenient support for field descriptions
|
||||
unset($col['description']);
|
||||
|
||||
/*
|
||||
if (isset($col['size'])) {
|
||||
// Don't distinguish between tinyint and int.
|
||||
if ($col['size'] == 'tiny' && $col['type'] == 'int') {
|
||||
unset($col['size']);
|
||||
}
|
||||
switch ($col['type']) {
|
||||
case 'serial':
|
||||
$col['type'] = 'int';
|
||||
$col['auto_increment'] = true;
|
||||
break;
|
||||
case 'datetime':
|
||||
// Replace archaic MySQL-specific zero-dates with NULL
|
||||
if (($col['default'] ?? null) === '0000-00-00 00:00:00') {
|
||||
$col['default'] = null;
|
||||
$col['not null'] = false;
|
||||
}
|
||||
break;
|
||||
case 'timestamp':
|
||||
// In MariaDB: If the column does not permit NULL values,
|
||||
// assigning NULL (or not referencing the column at all
|
||||
// when inserting) will set the column to CURRENT_TIMESTAMP
|
||||
// FIXME: ON UPDATE CURRENT_TIMESTAMP
|
||||
if ($col['not null'] && !isset($col['default'])) {
|
||||
$col['default'] = 'CURRENT_TIMESTAMP';
|
||||
}
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
$col['type'] = $this->mapType($col);
|
||||
unset($col['size']);
|
||||
}
|
||||
|
||||
if (!empty($tableDef['primary key'])) {
|
||||
$tableDef['primary key'] = $this->filterKeyDef($tableDef['primary key']);
|
||||
}
|
||||
@ -443,7 +449,7 @@ class PgsqlSchema extends Schema
|
||||
* @param array $def
|
||||
* @return array
|
||||
*/
|
||||
function filterKeyDef(array $def)
|
||||
public function filterKeyDef(array $def)
|
||||
{
|
||||
// PostgreSQL doesn't like prefix lengths specified on keys...?
|
||||
foreach ($def as $i => $item) {
|
||||
|
@ -17,10 +17,10 @@
|
||||
/**
|
||||
* Database schema
|
||||
*
|
||||
* @category Database
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @category Database
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
@ -39,14 +39,13 @@ defined('GNUSOCIAL') || die();
|
||||
*/
|
||||
class Schema
|
||||
{
|
||||
static $_static = null;
|
||||
public static $_static = null;
|
||||
protected $conn = null;
|
||||
|
||||
/**
|
||||
* Constructor. Only run once for singleton object.
|
||||
* @param null $conn
|
||||
*/
|
||||
|
||||
protected function __construct($conn = null)
|
||||
{
|
||||
if (is_null($conn)) {
|
||||
@ -64,11 +63,11 @@ class Schema
|
||||
* Main public entry point. Use this to get
|
||||
* the schema object.
|
||||
*
|
||||
* @param null $conn
|
||||
* @param object|null $conn
|
||||
* @param string|null Force a database type (necessary for installation purposes in which we don't have a config.php)
|
||||
* @return Schema the Schema object for the connection
|
||||
*/
|
||||
|
||||
static function get($conn = null)
|
||||
public static function get($conn = null, $dbtype = null)
|
||||
{
|
||||
if (is_null($conn)) {
|
||||
$key = 'default';
|
||||
@ -76,9 +75,11 @@ class Schema
|
||||
$key = md5(serialize($conn->dsn));
|
||||
}
|
||||
|
||||
$type = common_config('db', 'type');
|
||||
if (is_null($dbtype)) {
|
||||
$dbtype = common_config('db', 'type');
|
||||
}
|
||||
if (empty(self::$_static[$key])) {
|
||||
$schemaClass = ucfirst($type) . 'Schema';
|
||||
$schemaClass = ucfirst($dbtype) . 'Schema';
|
||||
self::$_static[$key] = new $schemaClass($conn);
|
||||
}
|
||||
return self::$_static[$key];
|
||||
@ -95,7 +96,6 @@ class Schema
|
||||
* @return ColumnDef definition of the column or null
|
||||
* if not found.
|
||||
*/
|
||||
|
||||
public function getColumnDef($table, $column)
|
||||
{
|
||||
$td = $this->getTableDef($table);
|
||||
@ -120,7 +120,6 @@ class Schema
|
||||
* @return bool success flag
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
|
||||
public function createTable($tableName, $def)
|
||||
{
|
||||
$statements = $this->buildCreateTable($tableName, $def);
|
||||
@ -194,7 +193,7 @@ class Schema
|
||||
* @param array $def table definition
|
||||
* @return string
|
||||
*/
|
||||
function startCreateTable($name, array $def)
|
||||
public function startCreateTable($name, array $def)
|
||||
{
|
||||
return 'CREATE TABLE ' . $this->quoteIdentifier($name) . ' (';
|
||||
}
|
||||
@ -206,7 +205,7 @@ class Schema
|
||||
* @param array $def table definition
|
||||
* @return string
|
||||
*/
|
||||
function endCreateTable($name, array $def)
|
||||
public function endCreateTable($name, array $def)
|
||||
{
|
||||
return ')';
|
||||
}
|
||||
@ -218,9 +217,9 @@ class Schema
|
||||
* @param string $name
|
||||
* @param array $def
|
||||
*/
|
||||
function appendColumnDef(array &$sql, $name, array $def)
|
||||
public function appendColumnDef(array &$sql, string $name, array $def)
|
||||
{
|
||||
$sql[] = "$name " . $this->columnSql($def);
|
||||
$sql[] = $name . ' ' . $this->columnSql($name, $def);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,7 +229,7 @@ class Schema
|
||||
* @param array $sql
|
||||
* @param array $def
|
||||
*/
|
||||
function appendPrimaryKeyDef(array &$sql, array $def)
|
||||
public function appendPrimaryKeyDef(array &$sql, array $def)
|
||||
{
|
||||
$sql[] = "PRIMARY KEY " . $this->buildIndexList($def);
|
||||
}
|
||||
@ -243,7 +242,7 @@ class Schema
|
||||
* @param string $name
|
||||
* @param array $def
|
||||
*/
|
||||
function appendUniqueKeyDef(array &$sql, $name, array $def)
|
||||
public function appendUniqueKeyDef(array &$sql, $name, array $def)
|
||||
{
|
||||
$sql[] = "CONSTRAINT $name UNIQUE " . $this->buildIndexList($def);
|
||||
}
|
||||
@ -257,7 +256,7 @@ class Schema
|
||||
* @param array $def
|
||||
* @throws Exception
|
||||
*/
|
||||
function appendForeignKeyDef(array &$sql, $name, array $def)
|
||||
public function appendForeignKeyDef(array &$sql, $name, array $def)
|
||||
{
|
||||
if (count($def) != 2) {
|
||||
throw new Exception("Invalid foreign key def for $name: " . var_export($def, true));
|
||||
@ -265,11 +264,11 @@ class Schema
|
||||
list($refTable, $map) = $def;
|
||||
$srcCols = array_keys($map);
|
||||
$refCols = array_values($map);
|
||||
$sql[] = "CONSTRAINT $name FOREIGN KEY " .
|
||||
$sql[] = 'CONSTRAINT ' . $this->quoteIdentifier($name) . ' FOREIGN KEY ' .
|
||||
$this->buildIndexList($srcCols) .
|
||||
" REFERENCES " .
|
||||
' REFERENCES ' .
|
||||
$this->quoteIdentifier($refTable) .
|
||||
" " .
|
||||
' ' .
|
||||
$this->buildIndexList($refCols);
|
||||
}
|
||||
|
||||
@ -282,9 +281,10 @@ class Schema
|
||||
* @param string $name
|
||||
* @param array $def
|
||||
*/
|
||||
function appendCreateIndex(array &$statements, $table, $name, array $def)
|
||||
public function appendCreateIndex(array &$statements, $table, $name, array $def)
|
||||
{
|
||||
$statements[] = "CREATE INDEX $name ON $table " . $this->buildIndexList($def);
|
||||
$statements[] = 'CREATE INDEX ' . $name . ' ON ' .
|
||||
$this->quoteIdentifier($table) . ' ' . $this->buildIndexList($def);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -297,7 +297,7 @@ class Schema
|
||||
* @param array $def
|
||||
* @throws Exception
|
||||
*/
|
||||
function appendCreateFulltextIndex(array &$statements, $table, $name, array $def)
|
||||
public function appendCreateFulltextIndex(array &$statements, $table, $name, array $def)
|
||||
{
|
||||
throw new Exception("Fulltext index not supported in this database");
|
||||
}
|
||||
@ -309,18 +309,18 @@ class Schema
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
*/
|
||||
function appendDropIndex(array &$statements, $table, $name)
|
||||
public function appendDropIndex(array &$statements, $table, $name)
|
||||
{
|
||||
$statements[] = "DROP INDEX $name ON " . $this->quoteIdentifier($table);
|
||||
}
|
||||
|
||||
function buildIndexList(array $def)
|
||||
public function buildIndexList(array $def)
|
||||
{
|
||||
// @fixme
|
||||
return '(' . implode(',', array_map([$this, 'buildIndexItem'], $def)) . ')';
|
||||
}
|
||||
|
||||
function buildIndexItem($def)
|
||||
public function buildIndexItem($def)
|
||||
{
|
||||
if (is_array($def)) {
|
||||
list($name, $size) = $def;
|
||||
@ -339,12 +339,11 @@ class Schema
|
||||
* @return bool success flag
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
|
||||
public function dropTable($name)
|
||||
{
|
||||
global $_PEAR;
|
||||
|
||||
$res = $this->conn->query("DROP TABLE $name");
|
||||
$res = $this->conn->query('DROP TABLE ' . $this->quoteIdentifier($name));
|
||||
|
||||
if ($_PEAR->isError($res)) {
|
||||
PEAR_ErrorToPEAR_Exception($res);
|
||||
@ -369,11 +368,12 @@ class Schema
|
||||
* @return bool success flag
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
|
||||
public function createIndex($table, $columnNames, $name = null)
|
||||
{
|
||||
global $_PEAR;
|
||||
|
||||
$qry = [];
|
||||
|
||||
if (!is_array($columnNames)) {
|
||||
$columnNames = [$columnNames];
|
||||
}
|
||||
@ -382,9 +382,9 @@ class Schema
|
||||
$name = "{$table}_" . implode("_", $columnNames) . "_idx";
|
||||
}
|
||||
|
||||
$res = $this->conn->query("ALTER TABLE $table " .
|
||||
"ADD INDEX $name (" .
|
||||
implode(",", $columnNames) . ")");
|
||||
$this->appendCreateIndex($qry, $table, $name, $columnNames);
|
||||
|
||||
$res = $this->conn->query(implode('; ', $qry));
|
||||
|
||||
if ($_PEAR->isError($res)) {
|
||||
PEAR_ErrorToPEAR_Exception($res);
|
||||
@ -402,12 +402,14 @@ class Schema
|
||||
* @return bool success flag
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
|
||||
public function dropIndex($table, $name)
|
||||
{
|
||||
global $_PEAR;
|
||||
|
||||
$res = $this->conn->query("ALTER TABLE $table DROP INDEX $name");
|
||||
$res = $this->conn->query(
|
||||
'ALTER TABLE ' . $this->quoteIdentifier($table) .
|
||||
' DROP INDEX ' . $name
|
||||
);
|
||||
|
||||
if ($_PEAR->isError($res)) {
|
||||
PEAR_ErrorToPEAR_Exception($res);
|
||||
@ -426,12 +428,12 @@ class Schema
|
||||
* @return bool success flag
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
|
||||
public function addColumn($table, $columndef)
|
||||
{
|
||||
global $_PEAR;
|
||||
|
||||
$sql = "ALTER TABLE $table ADD COLUMN " . $this->_columnSql($columndef);
|
||||
$sql = 'ALTER TABLE ' . $this->quoteIdentifier($table) .
|
||||
' ADD COLUMN ' . $this->columnSql($name, $columndef);
|
||||
|
||||
$res = $this->conn->query($sql);
|
||||
|
||||
@ -453,13 +455,12 @@ class Schema
|
||||
* @return bool success flag
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
|
||||
public function modifyColumn($table, $columndef)
|
||||
{
|
||||
global $_PEAR;
|
||||
|
||||
$sql = "ALTER TABLE $table MODIFY COLUMN " .
|
||||
$this->_columnSql($columndef);
|
||||
$sql = 'ALTER TABLE ' . $this->quoteIdentifier($table) .
|
||||
' MODIFY COLUMN ' . $this->columnSql($name, $columndef);
|
||||
|
||||
$res = $this->conn->query($sql);
|
||||
|
||||
@ -481,12 +482,12 @@ class Schema
|
||||
* @return bool success flag
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
|
||||
public function dropColumn($table, $columnName)
|
||||
{
|
||||
global $_PEAR;
|
||||
|
||||
$sql = "ALTER TABLE $table DROP COLUMN $columnName";
|
||||
$sql = 'ALTER TABLE ' . $this->quoteIdentifier($table) .
|
||||
' DROP COLUMN ' . $columnName;
|
||||
|
||||
$res = $this->conn->query($sql);
|
||||
|
||||
@ -511,7 +512,6 @@ class Schema
|
||||
* @return bool success flag
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
|
||||
public function ensureTable($tableName, $def)
|
||||
{
|
||||
$statements = $this->buildEnsureTable($tableName, $def);
|
||||
@ -527,7 +527,7 @@ class Schema
|
||||
* @return bool success flag
|
||||
* @throws PEAR_Exception
|
||||
*/
|
||||
function runSqlSet(array $statements)
|
||||
public function runSqlSet(array $statements)
|
||||
{
|
||||
global $_PEAR;
|
||||
|
||||
@ -561,8 +561,7 @@ class Schema
|
||||
* @return array of SQL statements
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
function buildEnsureTable($tableName, array $def)
|
||||
public function buildEnsureTable($tableName, array $def)
|
||||
{
|
||||
try {
|
||||
$old = $this->getTableDef($tableName);
|
||||
@ -606,18 +605,24 @@ class Schema
|
||||
}
|
||||
|
||||
if (isset($old['primary key']) && (!isset($def['primary key']) || $def['primary key'] != $old['primary key'])) {
|
||||
$this->appendAlterDropPrimary($phrase);
|
||||
$this->appendAlterDropPrimary($phrase, $tableName);
|
||||
}
|
||||
|
||||
foreach ($fields['add'] as $columnName) {
|
||||
$this->appendAlterAddColumn($phrase, $columnName,
|
||||
$def['fields'][$columnName]);
|
||||
$this->appendAlterAddColumn(
|
||||
$phrase,
|
||||
$columnName,
|
||||
$def['fields'][$columnName]
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($fields['mod'] as $columnName) {
|
||||
$this->appendAlterModifyColumn($phrase, $columnName,
|
||||
$this->appendAlterModifyColumn(
|
||||
$phrase,
|
||||
$columnName,
|
||||
$old['fields'][$columnName],
|
||||
$def['fields'][$columnName]);
|
||||
$def['fields'][$columnName]
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($fields['del'] as $columnName) {
|
||||
@ -639,7 +644,8 @@ class Schema
|
||||
$this->appendAlterExtras($phrase, $tableName, $def);
|
||||
|
||||
if (count($phrase) > 0) {
|
||||
$sql = 'ALTER TABLE ' . $tableName . ' ' . implode(",\n", $phrase);
|
||||
$sql = 'ALTER TABLE ' . $this->quoteIdentifier($tableName) .
|
||||
' ' . implode(",\n", $phrase);
|
||||
$statements[] = $sql;
|
||||
}
|
||||
|
||||
@ -656,7 +662,7 @@ class Schema
|
||||
return $statements;
|
||||
}
|
||||
|
||||
function diffArrays($oldDef, $newDef, $section, $compareCallback = null)
|
||||
public function diffArrays($oldDef, $newDef, $section, $compareCallback = null)
|
||||
{
|
||||
$old = isset($oldDef[$section]) ? $oldDef[$section] : [];
|
||||
$new = isset($newDef[$section]) ? $newDef[$section] : [];
|
||||
@ -701,12 +707,12 @@ class Schema
|
||||
* @param string $columnName
|
||||
* @param array $cd
|
||||
*/
|
||||
function appendAlterAddColumn(array &$phrase, $columnName, array $cd)
|
||||
public function appendAlterAddColumn(array &$phrase, string $columnName, array $cd)
|
||||
{
|
||||
$phrase[] = 'ADD COLUMN ' .
|
||||
$this->quoteIdentifier($columnName) .
|
||||
' ' .
|
||||
$this->columnSql($cd);
|
||||
$this->columnSql($columnName, $cd);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -718,12 +724,12 @@ class Schema
|
||||
* @param array $old previous column definition as found in DB
|
||||
* @param array $cd current column definition
|
||||
*/
|
||||
function appendAlterModifyColumn(array &$phrase, $columnName, array $old, array $cd)
|
||||
public function appendAlterModifyColumn(array &$phrase, string $columnName, array $old, array $cd)
|
||||
{
|
||||
$phrase[] = 'MODIFY COLUMN ' .
|
||||
$this->quoteIdentifier($columnName) .
|
||||
' ' .
|
||||
$this->columnSql($cd);
|
||||
$this->columnSql($columnName, $cd);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -733,12 +739,12 @@ class Schema
|
||||
* @param array $phrase
|
||||
* @param string $columnName
|
||||
*/
|
||||
function appendAlterDropColumn(array &$phrase, $columnName)
|
||||
public function appendAlterDropColumn(array &$phrase, $columnName)
|
||||
{
|
||||
$phrase[] = 'DROP COLUMN ' . $this->quoteIdentifier($columnName);
|
||||
}
|
||||
|
||||
function appendAlterAddUnique(array &$phrase, $keyName, array $def)
|
||||
public function appendAlterAddUnique(array &$phrase, $keyName, array $def)
|
||||
{
|
||||
$sql = [];
|
||||
$sql[] = 'ADD';
|
||||
@ -746,7 +752,7 @@ class Schema
|
||||
$phrase[] = implode(' ', $sql);
|
||||
}
|
||||
|
||||
function appendAlterAddForeign(array &$phrase, $keyName, array $def)
|
||||
public function appendAlterAddForeign(array &$phrase, $keyName, array $def)
|
||||
{
|
||||
$sql = [];
|
||||
$sql[] = 'ADD';
|
||||
@ -754,7 +760,7 @@ class Schema
|
||||
$phrase[] = implode(' ', $sql);
|
||||
}
|
||||
|
||||
function appendAlterAddPrimary(array &$phrase, array $def)
|
||||
public function appendAlterAddPrimary(array &$phrase, array $def)
|
||||
{
|
||||
$sql = [];
|
||||
$sql[] = 'ADD';
|
||||
@ -762,22 +768,22 @@ class Schema
|
||||
$phrase[] = implode(' ', $sql);
|
||||
}
|
||||
|
||||
function appendAlterDropPrimary(array &$phrase)
|
||||
public function appendAlterDropPrimary(array &$phrase, string $tableName)
|
||||
{
|
||||
$phrase[] = 'DROP CONSTRAINT PRIMARY KEY';
|
||||
}
|
||||
|
||||
function appendAlterDropUnique(array &$phrase, $keyName)
|
||||
public function appendAlterDropUnique(array &$phrase, $keyName)
|
||||
{
|
||||
$phrase[] = 'DROP CONSTRAINT ' . $keyName;
|
||||
}
|
||||
|
||||
function appendAlterDropForeign(array &$phrase, $keyName)
|
||||
public function appendAlterDropForeign(array &$phrase, $keyName)
|
||||
{
|
||||
$phrase[] = 'DROP FOREIGN KEY ' . $keyName;
|
||||
}
|
||||
|
||||
function appendAlterExtras(array &$phrase, $tableName, array $def)
|
||||
public function appendAlterExtras(array &$phrase, $tableName, array $def)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
@ -788,21 +794,21 @@ class Schema
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
function quoteIdentifier($name)
|
||||
public function quoteIdentifier($name)
|
||||
{
|
||||
return $name;
|
||||
return $this->conn->quoteIdentifier($name);
|
||||
}
|
||||
|
||||
function quoteDefaultValue($cd)
|
||||
public function quoteDefaultValue($cd)
|
||||
{
|
||||
if (($cd['type'] == 'datetime' || $cd['type'] == 'timestamp') && $cd['default'] == 'CURRENT_TIMESTAMP') {
|
||||
if (in_array($cd['type'], ['datetime', 'timestamp']) && $cd['default'] === 'CURRENT_TIMESTAMP') {
|
||||
return $cd['default'];
|
||||
} else {
|
||||
return $this->quoteValue($cd['default']);
|
||||
}
|
||||
}
|
||||
|
||||
function quoteValue($val)
|
||||
public function quoteValue($val)
|
||||
{
|
||||
return $this->conn->quoteSmart($val);
|
||||
}
|
||||
@ -816,7 +822,7 @@ class Schema
|
||||
* @param array $b
|
||||
* @return bool
|
||||
*/
|
||||
function columnsEqual(array $a, array $b)
|
||||
public function columnsEqual(array $a, array $b)
|
||||
{
|
||||
return !array_diff_assoc($a, $b) && !array_diff_assoc($b, $a);
|
||||
}
|
||||
@ -829,7 +835,6 @@ class Schema
|
||||
*
|
||||
* @return array strings for name values
|
||||
*/
|
||||
|
||||
protected function _names($cds)
|
||||
{
|
||||
$names = [];
|
||||
@ -850,7 +855,6 @@ class Schema
|
||||
*
|
||||
* @return ColumnDef matching item or null if no match.
|
||||
*/
|
||||
|
||||
protected function _byName($cds, $name)
|
||||
{
|
||||
foreach ($cds as $cd) {
|
||||
@ -869,20 +873,20 @@ class Schema
|
||||
* Appropriate for use in CREATE TABLE or
|
||||
* ALTER TABLE statements.
|
||||
*
|
||||
* @param string $name column name to create
|
||||
* @param array $cd column to create
|
||||
*
|
||||
* @return string correct SQL for that column
|
||||
*/
|
||||
|
||||
function columnSql(array $cd)
|
||||
public function columnSql(string $name, array $cd)
|
||||
{
|
||||
$line = [];
|
||||
$line[] = $this->typeAndSize($cd);
|
||||
$line[] = $this->typeAndSize($name, $cd);
|
||||
|
||||
if (isset($cd['default'])) {
|
||||
$line[] = 'default';
|
||||
$line[] = $this->quoteDefaultValue($cd);
|
||||
} else if (!empty($cd['not null'])) {
|
||||
} elseif (!empty($cd['not null'])) {
|
||||
// Can't have both not null AND default!
|
||||
$line[] = 'not null';
|
||||
}
|
||||
@ -895,14 +899,14 @@ class Schema
|
||||
* @param string $column canonical type name in defs
|
||||
* @return string native DB type name
|
||||
*/
|
||||
function mapType($column)
|
||||
public function mapType($column)
|
||||
{
|
||||
return $column;
|
||||
}
|
||||
|
||||
function typeAndSize($column)
|
||||
public function typeAndSize(string $name, array $column)
|
||||
{
|
||||
//$type = $this->mapType($column);
|
||||
//$type = $this->mapType($column)['type'];
|
||||
$type = $column['type'];
|
||||
if (isset($column['size'])) {
|
||||
$type = $column['size'] . $type;
|
||||
@ -914,7 +918,7 @@ class Schema
|
||||
if (isset($column['scale'])) {
|
||||
$lengths[] = $column['scale'];
|
||||
}
|
||||
} else if (isset($column['length'])) {
|
||||
} elseif (isset($column['length'])) {
|
||||
$lengths[] = $column['length'];
|
||||
}
|
||||
|
||||
@ -977,12 +981,12 @@ class Schema
|
||||
$table['primary key'] = [];
|
||||
}
|
||||
$table['primary key'][] = $cd->name;
|
||||
} else if ($cd->key == 'MUL') {
|
||||
} elseif ($cd->key === 'MUL') {
|
||||
// Individual multiple-value indexes are only per-column
|
||||
// using the old ColumnDef syntax.
|
||||
$idx = "{$tableName}_{$cd->name}_idx";
|
||||
$table['indexes'][$idx] = [$cd->name];
|
||||
} else if ($cd->key == 'UNI') {
|
||||
} elseif ($cd->key === 'UNI') {
|
||||
// Individual unique-value indexes are only per-column
|
||||
// using the old ColumnDef syntax.
|
||||
$idx = "{$tableName}_{$cd->name}_idx";
|
||||
@ -1003,7 +1007,7 @@ class Schema
|
||||
* @param array $tableDef
|
||||
* @return array
|
||||
*/
|
||||
function filterDef(array $tableDef)
|
||||
public function filterDef(array $tableDef)
|
||||
{
|
||||
return $tableDef;
|
||||
}
|
||||
@ -1019,7 +1023,7 @@ class Schema
|
||||
*
|
||||
* @throws Exception on wildly invalid input
|
||||
*/
|
||||
function validateDef($tableName, array $def)
|
||||
public function validateDef($tableName, array $def)
|
||||
{
|
||||
if (isset($def[0]) && $def[0] instanceof ColumnDef) {
|
||||
$def = $this->oldToNew($tableName, $def);
|
||||
@ -1033,7 +1037,7 @@ class Schema
|
||||
return $def;
|
||||
}
|
||||
|
||||
function isNumericType($type)
|
||||
public function isNumericType($type)
|
||||
{
|
||||
$type = strtolower($type);
|
||||
$known = ['int', 'serial', 'numeric'];
|
||||
@ -1074,20 +1078,21 @@ class Schema
|
||||
$this->getTableDef($new_name);
|
||||
// New table exists, can't work
|
||||
throw new ServerException("Both table {$old_name} and {$new_name} exist. You're on your own.");
|
||||
} catch(SchemaTableMissingException $e) {
|
||||
} catch (SchemaTableMissingException $e) {
|
||||
// New table doesn't exist, carry on
|
||||
}
|
||||
} catch(SchemaTableMissingException $e) {
|
||||
} catch (SchemaTableMissingException $e) {
|
||||
// Already renamed, or no previous table, so we're done
|
||||
return true;
|
||||
}
|
||||
return $this->runSqlSet(["ALTER TABLE {$old_name} RENAME TO {$new_name};"]);
|
||||
return $this->runSqlSet([
|
||||
'ALTER TABLE ' . $this->quoteIdentifier($old_name) .
|
||||
' RENAME TO ' . $this->quoteIdentifier($new_name) . ';',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SchemaTableMissingException extends Exception
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
@ -1,77 +1,60 @@
|
||||
<?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
|
||||
*
|
||||
* Groups with the most members section
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Groups with the most members section
|
||||
*
|
||||
* @category Widget
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class GroupsByMembersSection extends GroupSection
|
||||
{
|
||||
function getGroups()
|
||||
public function getGroups()
|
||||
{
|
||||
$qry = 'SELECT user_group.*, count(*) as value ' .
|
||||
'FROM user_group JOIN group_member '.
|
||||
'ON user_group.id = group_member.group_id ' .
|
||||
'GROUP BY user_group.id,user_group.nickname,user_group.fullname,user_group.homepage,user_group.description,user_group.location,user_group.original_logo,user_group.homepage_logo,user_group.stream_logo,user_group.mini_logo,user_group.created,user_group.modified ' .
|
||||
'ORDER BY value DESC ';
|
||||
|
||||
$limit = GROUPS_PER_SECTION;
|
||||
$offset = 0;
|
||||
|
||||
if (common_config('db','type') == 'pgsql') {
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
$qry = 'SELECT user_group.*, COUNT(*) AS value ' .
|
||||
'FROM user_group INNER JOIN group_member '.
|
||||
'ON user_group.id = group_member.group_id ' .
|
||||
'GROUP BY user_group.id, user_group.nickname, user_group.fullname, user_group.homepage, user_group.description, user_group.location, user_group.original_logo, user_group.homepage_logo, user_group.stream_logo, user_group.mini_logo, user_group.created, user_group.modified ' .
|
||||
'ORDER BY value DESC LIMIT ' . $limit;
|
||||
|
||||
$group = Memcached_DataObject::cachedQuery('User_group',
|
||||
$qry,
|
||||
3600);
|
||||
$group = Memcached_DataObject::cachedQuery('User_group', $qry, 3600);
|
||||
return $group;
|
||||
}
|
||||
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Title for groups with the most members section.
|
||||
return _('Popular groups');
|
||||
}
|
||||
|
||||
function divId()
|
||||
public function divId()
|
||||
{
|
||||
return 'top_groups_by_member';
|
||||
}
|
||||
|
@ -44,20 +44,13 @@ class GroupsByPostsSection extends GroupSection
|
||||
{
|
||||
function getGroups()
|
||||
{
|
||||
$limit = GROUPS_PER_SECTION;
|
||||
|
||||
$qry = 'SELECT user_group.*, count(*) as value ' .
|
||||
'FROM user_group JOIN group_inbox '.
|
||||
'ON user_group.id = group_inbox.group_id ' .
|
||||
'GROUP BY user_group.id,user_group.nickname,user_group.fullname,user_group.homepage,user_group.description,user_group.location,user_group.original_logo,user_group.homepage_logo,user_group.stream_logo,user_group.mini_logo,user_group.created,user_group.modified ' .
|
||||
'ORDER BY value DESC ';
|
||||
|
||||
$limit = GROUPS_PER_SECTION;
|
||||
$offset = 0;
|
||||
|
||||
if (common_config('db','type') == 'pgsql') {
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
'ORDER BY value DESC LIMIT ' . $limit;
|
||||
|
||||
$group = Memcached_DataObject::cachedQuery('User_group',
|
||||
$qry,
|
||||
|
@ -1,51 +1,40 @@
|
||||
<?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) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Stream of notices for a profile's "all" feed
|
||||
*
|
||||
* 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 NoticeStream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @author Alexei Sorokin <sor.alexei@meowr.ru>
|
||||
* @author Stephane Berube <chimo@chromic.org>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @copyright 2014 Free Software Foundation, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Stream of notices for a profile's "all" feed
|
||||
*
|
||||
* @category General
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @author Alexei Sorokin <sor.alexei@meowr.ru>
|
||||
* @author chimo <chimo@chromic.org>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @copyright 2014 Free Software Foundation, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class InboxNoticeStream extends ScopingNoticeStream
|
||||
{
|
||||
@ -65,13 +54,9 @@ class InboxNoticeStream extends ScopingNoticeStream
|
||||
* Raw stream of notices for the target's inbox
|
||||
*
|
||||
* @category General
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @author Alexei Sorokin <sor.alexei@meowr.ru>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class RawInboxNoticeStream extends FullNoticeStream
|
||||
{
|
||||
@ -104,33 +89,39 @@ class RawInboxNoticeStream extends FullNoticeStream
|
||||
$notice = new Notice();
|
||||
$notice->selectAdd();
|
||||
$notice->selectAdd('id');
|
||||
$notice->whereAdd(sprintf('notice.created > "%s"', $notice->escape($this->target->created)));
|
||||
// Reply:: is a table of mentions
|
||||
// Subscription:: is a table of subscriptions (every user is subscribed to themselves)
|
||||
// Sort in descending order as id will give us even really old posts,
|
||||
// which were recently imported. For example, if a remote instance had
|
||||
// problems and just managed to post here.
|
||||
$notice->whereAdd(
|
||||
sprintf('id IN (SELECT DISTINCT id FROM (' .
|
||||
'(SELECT id FROM notice WHERE profile_id IN (SELECT subscribed FROM subscription WHERE subscriber = %1$d)) UNION ' .
|
||||
'(SELECT notice_id AS id FROM reply WHERE profile_id = %1$d) UNION ' .
|
||||
'(SELECT notice_id AS id FROM attention WHERE profile_id = %1$d) UNION ' .
|
||||
'(SELECT notice_id AS id FROM group_inbox WHERE group_id IN (SELECT group_id FROM group_member WHERE profile_id = %1$d)) ' .
|
||||
'ORDER BY id DESC) AS T)',
|
||||
$this->target->getID())
|
||||
$notice->_join .= sprintf(
|
||||
"\n" . 'NATURAL INNER JOIN (' .
|
||||
'(SELECT id FROM notice WHERE profile_id IN (SELECT subscribed FROM subscription WHERE subscriber = %1$d)) ' .
|
||||
'UNION (SELECT notice_id AS id FROM reply WHERE profile_id = %1$d) ' .
|
||||
'UNION (SELECT notice_id AS id FROM attention WHERE profile_id = %1$d) ' .
|
||||
'UNION (SELECT notice_id AS id FROM group_inbox WHERE group_id IN (SELECT group_id FROM group_member WHERE profile_id = %1$d))' .
|
||||
') AS t1',
|
||||
$this->target->getID()
|
||||
);
|
||||
|
||||
$notice->whereAdd(sprintf(
|
||||
"notice.created > TIMESTAMP '%s'",
|
||||
$notice->escape($this->target->created)
|
||||
));
|
||||
|
||||
if (!empty($since_id)) {
|
||||
$notice->whereAdd(sprintf('notice.id > %d', $since_id));
|
||||
$notice->whereAdd('id > ' . $since_id);
|
||||
}
|
||||
if (!empty($max_id)) {
|
||||
$notice->whereAdd(sprintf('notice.id <= %d', $max_id));
|
||||
$notice->whereAdd('id <= ' . $max_id);
|
||||
}
|
||||
|
||||
$notice->whereAdd('scope != ' . Notice::MESSAGE_SCOPE);
|
||||
$notice->whereAdd('scope <> ' . Notice::MESSAGE_SCOPE);
|
||||
|
||||
self::filterVerbs($notice, $this->selectVerbs);
|
||||
|
||||
// notice.id will give us even really old posts, which were recently
|
||||
// imported. For example if a remote instance had problems and just
|
||||
// managed to post here.
|
||||
$notice->orderBy('id DESC');
|
||||
|
||||
$notice->limit($offset, $limit);
|
||||
|
||||
if (!$notice->find()) {
|
||||
|
@ -1,31 +1,54 @@
|
||||
<?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/>.
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Raw public stream
|
||||
*
|
||||
* @category Stream
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class NetworkPublicNoticeStream extends ModeratedNoticeStream
|
||||
{
|
||||
function __construct(Profile $scoped=null)
|
||||
public function __construct(Profile $scoped = null)
|
||||
{
|
||||
parent::__construct(new CachingNoticeStream(new RawNetworkPublicNoticeStream(),
|
||||
'networkpublic'),
|
||||
$scoped);
|
||||
parent::__construct(
|
||||
new CachingNoticeStream(
|
||||
new RawNetworkPublicNoticeStream(),
|
||||
'networkpublic'
|
||||
),
|
||||
$scoped
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw public stream
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class RawNetworkPublicNoticeStream extends FullNoticeStream
|
||||
{
|
||||
function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
{
|
||||
$notice = new Notice();
|
||||
|
||||
@ -38,11 +61,11 @@ class RawNetworkPublicNoticeStream extends FullNoticeStream
|
||||
$notice->limit($offset, $limit);
|
||||
}
|
||||
|
||||
$notice->whereAdd('is_local ='. Notice::REMOTE);
|
||||
$notice->whereAdd('is_local = '. Notice::REMOTE);
|
||||
// -1 == blacklisted, -2 == gateway (i.e. Twitter)
|
||||
$notice->whereAdd('is_local !='. Notice::LOCAL_NONPUBLIC);
|
||||
$notice->whereAdd('is_local !='. Notice::GATEWAY);
|
||||
$notice->whereAdd('scope != ' . Notice::MESSAGE_SCOPE);
|
||||
$notice->whereAdd('is_local <> '. Notice::LOCAL_NONPUBLIC);
|
||||
$notice->whereAdd('is_local <> '. Notice::GATEWAY);
|
||||
$notice->whereAdd('scope <> ' . Notice::MESSAGE_SCOPE);
|
||||
|
||||
Notice::addWhereSinceId($notice, $since_id);
|
||||
Notice::addWhereMaxId($notice, $max_id);
|
||||
@ -58,7 +81,7 @@ class RawNetworkPublicNoticeStream extends FullNoticeStream
|
||||
}
|
||||
|
||||
$notice->free();
|
||||
$notice = NULL;
|
||||
$notice = null;
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
@ -1,53 +1,52 @@
|
||||
<?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) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Public stream
|
||||
*
|
||||
* 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 Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Public stream
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class PublicNoticeStream extends ModeratedNoticeStream
|
||||
{
|
||||
function __construct(Profile $scoped=null)
|
||||
public function __construct(Profile $scoped = null)
|
||||
{
|
||||
parent::__construct(new CachingNoticeStream(new RawPublicNoticeStream(),
|
||||
'public'),
|
||||
$scoped);
|
||||
parent::__construct(
|
||||
new CachingNoticeStream(
|
||||
new RawPublicNoticeStream(),
|
||||
'public'
|
||||
),
|
||||
$scoped
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,16 +54,15 @@ class PublicNoticeStream extends ModeratedNoticeStream
|
||||
* Raw public stream
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class RawPublicNoticeStream extends FullNoticeStream
|
||||
{
|
||||
function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
{
|
||||
$notice = new Notice();
|
||||
|
||||
@ -79,7 +77,7 @@ class RawPublicNoticeStream extends FullNoticeStream
|
||||
|
||||
// This feed always gives only local activities.
|
||||
$notice->whereAdd('is_local = ' . Notice::LOCAL_PUBLIC);
|
||||
$notice->whereAdd('scope != ' . Notice::MESSAGE_SCOPE);
|
||||
$notice->whereAdd('scope <> ' . Notice::MESSAGE_SCOPE);
|
||||
|
||||
Notice::addWhereSinceId($notice, $since_id);
|
||||
Notice::addWhereMaxId($notice, $max_id);
|
||||
@ -95,7 +93,7 @@ class RawPublicNoticeStream extends FullNoticeStream
|
||||
}
|
||||
|
||||
$notice->free();
|
||||
$notice = NULL;
|
||||
$notice = null;
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
@ -1,53 +1,52 @@
|
||||
<?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) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Stream of mentions of me
|
||||
*
|
||||
* 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 Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Stream of mentions of me
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class ReplyNoticeStream extends ScopingNoticeStream
|
||||
{
|
||||
function __construct($userId, Profile $scoped=null)
|
||||
public function __construct($userId, Profile $scoped = null)
|
||||
{
|
||||
parent::__construct(new CachingNoticeStream(new RawReplyNoticeStream($userId),
|
||||
'reply:stream:' . $userId),
|
||||
$scoped);
|
||||
parent::__construct(
|
||||
new CachingNoticeStream(
|
||||
new RawReplyNoticeStream($userId),
|
||||
'reply:stream:' . $userId
|
||||
),
|
||||
$scoped
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,24 +54,23 @@ class ReplyNoticeStream extends ScopingNoticeStream
|
||||
* Raw stream of mentions of me
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class RawReplyNoticeStream extends NoticeStream
|
||||
{
|
||||
protected $userId;
|
||||
|
||||
function __construct($userId)
|
||||
public function __construct($userId)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
{
|
||||
$reply = new Reply();
|
||||
|
||||
@ -94,14 +92,16 @@ class RawReplyNoticeStream extends NoticeStream
|
||||
$reply->whereAddIn('notice.verb', $filter, 'string');
|
||||
}
|
||||
|
||||
$filter = array_keys(array_filter($this->selectVerbs, function ($v) { return !$v; }));
|
||||
$filter = array_keys(array_filter($this->selectVerbs, function ($v) {
|
||||
return !$v;
|
||||
}));
|
||||
if (!empty($filter)) {
|
||||
// exclude verbs in selectVerbs with values that equate to false
|
||||
$reply->whereAddIn('!notice.verb', $filter, 'string');
|
||||
}
|
||||
}
|
||||
|
||||
$reply->whereAdd('notice.scope != ' . NOTICE::MESSAGE_SCOPE);
|
||||
$reply->whereAdd('notice.scope <> ' . NOTICE::MESSAGE_SCOPE);
|
||||
|
||||
$reply->orderBy('reply.modified DESC, reply.notice_id DESC');
|
||||
|
||||
|
@ -1,72 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Stream of notices for a list
|
||||
*
|
||||
* 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 Stream
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Stream of notices for a list
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Stream of notices for a list
|
||||
*
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class PeopletagNoticeStream extends ScopingNoticeStream
|
||||
{
|
||||
function __construct($plist, Profile $scoped=null)
|
||||
public function __construct($plist, Profile $scoped = null)
|
||||
{
|
||||
parent::__construct(new CachingNoticeStream(new RawPeopletagNoticeStream($plist),
|
||||
'profile_list:notice_ids:' . $plist->id),
|
||||
$scoped);
|
||||
parent::__construct(
|
||||
new CachingNoticeStream(
|
||||
new RawPeopletagNoticeStream($plist),
|
||||
'profile_list:notice_ids:' . $plist->id
|
||||
),
|
||||
$scoped
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream of notices for a list
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class RawPeopletagNoticeStream extends NoticeStream
|
||||
{
|
||||
protected $profile_list;
|
||||
|
||||
function __construct($profile_list)
|
||||
public function __construct($profile_list)
|
||||
{
|
||||
$this->profile_list = $profile_list;
|
||||
}
|
||||
@ -82,7 +73,7 @@ class RawPeopletagNoticeStream extends NoticeStream
|
||||
* @return array array of notice ids.
|
||||
*/
|
||||
|
||||
function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
{
|
||||
$notice = new Notice();
|
||||
|
||||
@ -94,7 +85,10 @@ class RawPeopletagNoticeStream extends NoticeStream
|
||||
$ptag->tagger = $this->profile_list->tagger;
|
||||
$notice->joinAdd(array('profile_id', 'profile_tag:tagged'));
|
||||
$notice->whereAdd('profile_tag.tagger = ' . $this->profile_list->tagger);
|
||||
$notice->whereAdd(sprintf('profile_tag.tag = "%s"', $this->profile_list->tag));
|
||||
$notice->whereAdd(sprintf(
|
||||
"profile_tag.tag = '%s'",
|
||||
$notice->escape($this->profile_list->tag)
|
||||
));
|
||||
|
||||
if ($since_id != 0) {
|
||||
$notice->whereAdd('notice.id > ' . $since_id);
|
||||
|
@ -1,65 +1,49 @@
|
||||
<?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
|
||||
*
|
||||
* Peopletags with the most subscribers section
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Peopletags with the most subscribers section
|
||||
*
|
||||
* @category Widget
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class PeopletagsBySubsSection extends PeopletagSection
|
||||
{
|
||||
function getPeopletags()
|
||||
{
|
||||
$qry = 'SELECT profile_list.*, subscriber_count as value ' .
|
||||
'FROM profile_list WHERE profile_list.private = false ' .
|
||||
'ORDER BY value DESC ';
|
||||
|
||||
$limit = PEOPLETAGS_PER_SECTION;
|
||||
$offset = 0;
|
||||
|
||||
if (common_config('db','type') == 'pgsql') {
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
$qry = 'SELECT profile_list.*, subscriber_count AS value ' .
|
||||
'FROM profile_list WHERE profile_list.private = FALSE ' .
|
||||
'ORDER BY value DESC ' .
|
||||
'LIMIT ' . $limit;
|
||||
|
||||
$peopletag = Memcached_DataObject::cachedQuery('Profile_list',
|
||||
$qry,
|
||||
3600);
|
||||
$peopletag = Memcached_DataObject::cachedQuery('Profile_list', $qry, 3600);
|
||||
return $peopletag;
|
||||
}
|
||||
|
||||
|
@ -1,59 +1,58 @@
|
||||
<?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) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Stream of notices by a profile
|
||||
*
|
||||
* 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 Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Stream of notices by a profile
|
||||
*
|
||||
* @category General
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class ProfileNoticeStream extends ScopingNoticeStream
|
||||
{
|
||||
protected $target;
|
||||
|
||||
function __construct(Profile $target, Profile $scoped=null)
|
||||
public function __construct(Profile $target, Profile $scoped = null)
|
||||
{
|
||||
$this->target = $target;
|
||||
parent::__construct(new CachingNoticeStream(new RawProfileNoticeStream($target),
|
||||
'profile:notice_ids:' . $target->getID()),
|
||||
$scoped);
|
||||
parent::__construct(
|
||||
new CachingNoticeStream(
|
||||
new RawProfileNoticeStream($target),
|
||||
'profile:notice_ids:' . $target->getID()
|
||||
),
|
||||
$scoped
|
||||
);
|
||||
}
|
||||
|
||||
function getNoticeIds($offset, $limit, $since_id=null, $max_id=null)
|
||||
public function getNoticeIds($offset, $limit, $since_id = null, $max_id = null)
|
||||
{
|
||||
if ($this->impossibleStream()) {
|
||||
return array();
|
||||
@ -62,7 +61,7 @@ class ProfileNoticeStream extends ScopingNoticeStream
|
||||
}
|
||||
}
|
||||
|
||||
function getNotices($offset, $limit, $since_id=null, $max_id=null)
|
||||
public function getNotices($offset, $limit, $since_id = null, $max_id = null)
|
||||
{
|
||||
if ($this->impossibleStream()) {
|
||||
throw new PrivateStreamException($this->target, $this->scoped);
|
||||
@ -71,7 +70,7 @@ class ProfileNoticeStream extends ScopingNoticeStream
|
||||
}
|
||||
}
|
||||
|
||||
function impossibleStream()
|
||||
public function impossibleStream()
|
||||
{
|
||||
if (!$this->target->readableBy($this->scoped)) {
|
||||
// cannot read because it's a private stream and either noone's logged in or they are not subscribers
|
||||
@ -82,12 +81,11 @@ class ProfileNoticeStream extends ScopingNoticeStream
|
||||
|
||||
if (common_config('notice', 'hidespam')) {
|
||||
// if this is a silenced user
|
||||
if ($this->target->hasRole(Profile_role::SILENCED)
|
||||
// and we are either not logged in
|
||||
&& (!$this->scoped instanceof Profile
|
||||
// or if we are, we are not logged in as the target, and we don't have right to review spam
|
||||
|| (!$this->scoped->sameAs($this->target) && !$this->scoped->hasRight(Right::REVIEWSPAM))
|
||||
)) {
|
||||
if ($this->target->hasRole(Profile_role::SILENCED) &&
|
||||
// and we are either not logged in
|
||||
(!$this->scoped instanceof Profile ||
|
||||
// or if we are, we are not logged in as the target, and we don't have right to review spam
|
||||
(!$this->scoped->sameAs($this->target) && !$this->scoped->hasRight(Right::REVIEWSPAM)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -100,11 +98,10 @@ class ProfileNoticeStream extends ScopingNoticeStream
|
||||
* Raw stream of notices by a profile
|
||||
*
|
||||
* @category General
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class RawProfileNoticeStream extends NoticeStream
|
||||
@ -112,13 +109,13 @@ class RawProfileNoticeStream extends NoticeStream
|
||||
protected $target;
|
||||
protected $selectVerbs = array(); // select all verbs
|
||||
|
||||
function __construct(Profile $target)
|
||||
public function __construct(Profile $target)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->target = $target;
|
||||
}
|
||||
|
||||
function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
{
|
||||
$notice = new Notice();
|
||||
|
||||
@ -127,7 +124,7 @@ class RawProfileNoticeStream extends NoticeStream
|
||||
$notice->selectAdd();
|
||||
$notice->selectAdd('id');
|
||||
|
||||
$notice->whereAdd('scope != ' . Notice::MESSAGE_SCOPE);
|
||||
$notice->whereAdd('scope <> ' . Notice::MESSAGE_SCOPE);
|
||||
|
||||
Notice::addWhereSinceId($notice, $since_id);
|
||||
Notice::addWhereMaxId($notice, $max_id);
|
||||
|
@ -1,47 +1,42 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class SearchEngine
|
||||
{
|
||||
protected $target;
|
||||
protected $table;
|
||||
|
||||
function __construct($target, $table)
|
||||
public function __construct($target, $table)
|
||||
{
|
||||
$this->target = $target;
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
function query($q)
|
||||
public function query($q)
|
||||
{
|
||||
}
|
||||
|
||||
function limit($offset, $count, $rss = false)
|
||||
public function limit($offset, $count, $rss = false)
|
||||
{
|
||||
return $this->target->limit($offset, $count);
|
||||
}
|
||||
|
||||
function set_sort_mode($mode)
|
||||
public function set_sort_mode($mode)
|
||||
{
|
||||
switch ($mode) {
|
||||
case 'chron':
|
||||
@ -75,42 +70,82 @@ class SearchEngine
|
||||
}
|
||||
}
|
||||
|
||||
class PostgreSQLSearch extends SearchEngine
|
||||
{
|
||||
public function query($q)
|
||||
{
|
||||
if ($this->table === 'profile') {
|
||||
$cols = implode(" || ' ' || ", array_map(
|
||||
function ($col) {
|
||||
return sprintf(
|
||||
"COALESCE(%s.%s, '')",
|
||||
common_database_tablename($this->table),
|
||||
$col
|
||||
);
|
||||
},
|
||||
['nickname', 'fullname', 'location', 'bio', 'homepage']
|
||||
));
|
||||
|
||||
$this->target->whereAdd(sprintf(
|
||||
'to_tsvector(\'english\', %2$s) @@ plainto_tsquery(\'%1$s\')',
|
||||
$this->target->escape($q, true),
|
||||
$cols
|
||||
));
|
||||
return true;
|
||||
} elseif ($this->table === 'notice') {
|
||||
// Don't show imported notices
|
||||
$this->target->whereAdd('notice.is_local <> ' . Notice::GATEWAY);
|
||||
|
||||
$this->target->whereAdd(sprintf(
|
||||
'to_tsvector(\'english\', content) @@ plainto_tsquery(\'%1$s\')',
|
||||
$this->target->escape($q, true)
|
||||
));
|
||||
return true;
|
||||
} else {
|
||||
throw new ServerException('Unknown table: ' . $this->table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MySQLSearch extends SearchEngine
|
||||
{
|
||||
function query($q)
|
||||
public function query($q)
|
||||
{
|
||||
if ('profile' === $this->table) {
|
||||
$this->target->whereAdd(
|
||||
sprintf('MATCH (%2$s.nickname, %2$s.fullname, %2$s.location, %2$s.bio, %2$s.homepage) ' .
|
||||
'AGAINST ("%1$s" IN BOOLEAN MODE)',
|
||||
$this->target->escape($q, true),
|
||||
$this->table)
|
||||
);
|
||||
if ($this->table === 'profile') {
|
||||
$this->target->whereAdd(sprintf(
|
||||
'MATCH (%2$s.nickname, %2$s.fullname, %2$s.location, %2$s.bio, %2$s.homepage) ' .
|
||||
'AGAINST (\'%1$s\' IN BOOLEAN MODE)',
|
||||
$this->target->escape($q, true),
|
||||
$this->table
|
||||
));
|
||||
if (strtolower($q) != $q) {
|
||||
$this->target->whereAdd(
|
||||
sprintf('MATCH (%2$s.nickname, %2$s.fullname, %2$s.location, %2$s.bio, %2$s.homepage) ' .
|
||||
'AGAINST ("%1$s" IN BOOLEAN MODE)',
|
||||
sprintf(
|
||||
'MATCH (%2$s.nickname, %2$s.fullname, %2$s.location, %2$s.bio, %2$s.homepage) ' .
|
||||
'AGAINST (\'%1$s\' IN BOOLEAN MODE)',
|
||||
$this->target->escape(strtolower($q), true),
|
||||
$this->table),
|
||||
$this->table
|
||||
),
|
||||
'OR'
|
||||
);
|
||||
}
|
||||
return true;
|
||||
} else if ('notice' === $this->table) {
|
||||
|
||||
} elseif ($this->table === 'notice') {
|
||||
// Don't show imported notices
|
||||
$this->target->whereAdd('notice.is_local != ' . Notice::GATEWAY);
|
||||
$this->target->whereAdd('notice.is_local <> ' . Notice::GATEWAY);
|
||||
|
||||
$this->target->whereAdd(
|
||||
sprintf('MATCH (%2$s.content) AGAINST ("%1$s" IN BOOLEAN MODE)',
|
||||
$this->target->escape($q, true),
|
||||
$this->table)
|
||||
);
|
||||
$this->target->whereAdd(sprintf(
|
||||
'MATCH (%2$s.content) AGAINST (\'%1$s\' IN BOOLEAN MODE)',
|
||||
$this->target->escape($q, true),
|
||||
$this->table
|
||||
));
|
||||
if (strtolower($q) != $q) {
|
||||
$this->target->whereAdd(
|
||||
sprintf('MATCH (%2$s.content) AGAINST ("%1$s" IN BOOLEAN MODE)',
|
||||
sprintf(
|
||||
'MATCH (%2$s.content) AGAINST (\'%1$s\' IN BOOLEAN MODE)',
|
||||
$this->target->escape(strtolower($q), true),
|
||||
$this->table),
|
||||
$this->table
|
||||
),
|
||||
'OR'
|
||||
);
|
||||
}
|
||||
@ -122,20 +157,22 @@ class MySQLSearch extends SearchEngine
|
||||
}
|
||||
}
|
||||
|
||||
class MySQLLikeSearch extends SearchEngine
|
||||
class SQLLikeSearch extends SearchEngine
|
||||
{
|
||||
function query($q)
|
||||
public function query($q)
|
||||
{
|
||||
if ('profile' === $this->table) {
|
||||
$qry = sprintf('(%2$s.nickname LIKE "%%%1$s%%" OR ' .
|
||||
' %2$s.fullname LIKE "%%%1$s%%" OR ' .
|
||||
' %2$s.location LIKE "%%%1$s%%" OR ' .
|
||||
' %2$s.bio LIKE "%%%1$s%%" OR ' .
|
||||
' %2$s.homepage LIKE "%%%1$s%%")',
|
||||
$this->target->escape($q, true),
|
||||
$this->table);
|
||||
} else if ('notice' === $this->table) {
|
||||
$qry = sprintf('content LIKE "%%%1$s%%"', $this->target->escape($q, true));
|
||||
if ($this->table === 'profile') {
|
||||
$qry = sprintf(
|
||||
'( %2$s.nickname LIKE \'%%%1$s%%\' ' .
|
||||
' OR %2$s.fullname LIKE \'%%%1$s%%\' ' .
|
||||
' OR %2$s.location LIKE \'%%%1$s%%\' ' .
|
||||
' OR %2$s.bio LIKE \'%%%1$s%%\' ' .
|
||||
' OR %2$s.homepage LIKE \'%%%1$s%%\')',
|
||||
$this->target->escape($q, true),
|
||||
$this->table
|
||||
);
|
||||
} elseif ($this->table === 'notice') {
|
||||
$qry = sprintf('content LIKE \'%%%1$s%%\'', $this->target->escape($q, true));
|
||||
} else {
|
||||
throw new ServerException('Unknown table: ' . $this->table);
|
||||
}
|
||||
@ -145,21 +182,3 @@ class MySQLLikeSearch extends SearchEngine
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class PGSearch extends SearchEngine
|
||||
{
|
||||
function query($q)
|
||||
{
|
||||
if ('profile' === $this->table) {
|
||||
return $this->target->whereAdd('textsearch @@ plainto_tsquery(\'' . $this->target->escape($q) . '\')');
|
||||
} else if ('notice' === $this->table) {
|
||||
|
||||
// XXX: We need to filter out gateway notices (notice.is_local = -2) --Zach
|
||||
|
||||
return $this->target->whereAdd('to_tsvector(\'english\', content) @@ plainto_tsquery(\'' . $this->target->escape($q) . '\')');
|
||||
} else {
|
||||
throw new ServerException('Unknown table: ' . $this->table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,48 +1,40 @@
|
||||
<?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
|
||||
*
|
||||
* Section for featured users
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Section for featured users
|
||||
*
|
||||
* @category Widget
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class FeaturedUsersSection extends ProfileSection
|
||||
{
|
||||
function show()
|
||||
public function show()
|
||||
{
|
||||
$featured_nicks = common_config('nickname', 'featured');
|
||||
if (empty($featured_nicks)) {
|
||||
@ -51,7 +43,7 @@ class FeaturedUsersSection extends ProfileSection
|
||||
parent::show();
|
||||
}
|
||||
|
||||
function getProfiles()
|
||||
public function getProfiles()
|
||||
{
|
||||
$featured_nicks = common_config('nickname', 'featured');
|
||||
|
||||
@ -65,43 +57,30 @@ class FeaturedUsersSection extends ProfileSection
|
||||
$quoted[] = "'$nick'";
|
||||
}
|
||||
|
||||
$table = "user";
|
||||
if(common_config('db','quote_identifiers')) {
|
||||
$table = '"' . $table . '"';
|
||||
}
|
||||
$table = common_database_tablename('user');
|
||||
$limit = PROFILES_PER_SECTION + 1;
|
||||
|
||||
$qry = 'SELECT profile.* ' .
|
||||
'FROM profile JOIN '. $table .' on profile.id = '. $table .'.id ' .
|
||||
'WHERE '. $table .'.nickname in (' . implode(',', $quoted) . ') ' .
|
||||
'ORDER BY profile.created DESC ';
|
||||
'FROM profile INNER JOIN ' . $table . ' ON profile.id = ' . $table . '.id ' .
|
||||
'WHERE ' . $table . '.nickname IN (' . implode(',', $quoted) . ') ' .
|
||||
'ORDER BY profile.created DESC LIMIT ' . $limit;
|
||||
|
||||
$limit = PROFILES_PER_SECTION + 1;
|
||||
$offset = 0;
|
||||
|
||||
if (common_config('db','type') == 'pgsql') {
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
|
||||
$profile = Memcached_DataObject::cachedQuery('Profile',
|
||||
$qry,
|
||||
6 * 3600);
|
||||
$profile = Memcached_DataObject::cachedQuery('Profile', $qry, 6 * 3600);
|
||||
return $profile;
|
||||
}
|
||||
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Title for featured users section.
|
||||
return _('Featured users');
|
||||
}
|
||||
|
||||
function divId()
|
||||
public function divId()
|
||||
{
|
||||
return 'featured_users';
|
||||
}
|
||||
|
||||
function moreUrl()
|
||||
public function moreUrl()
|
||||
{
|
||||
return common_local_url('featured');
|
||||
}
|
||||
|
@ -1,23 +1,25 @@
|
||||
<?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) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @copyright 2008, 2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
// 10x8
|
||||
|
||||
@ -36,12 +38,12 @@ class GalleryAction extends ProfileAction
|
||||
parent::handle();
|
||||
}
|
||||
|
||||
function showContent()
|
||||
public function showContent()
|
||||
{
|
||||
$this->showTagsDropdown();
|
||||
}
|
||||
|
||||
function showTagsDropdown()
|
||||
public function showTagsDropdown()
|
||||
{
|
||||
$tag = $this->trimmed('tag');
|
||||
|
||||
@ -59,13 +61,17 @@ class GalleryAction extends ProfileAction
|
||||
$this->elementStart('ul');
|
||||
$this->elementStart('li', array('id' => 'filter_tags_all',
|
||||
'class' => 'child_1'));
|
||||
$this->element('a',
|
||||
array('href' =>
|
||||
common_local_url($this->trimmed('action'),
|
||||
array('nickname' =>
|
||||
$this->target->getNickname()))),
|
||||
// TRANS: List element on gallery action page to show all tags.
|
||||
_m('TAGS','All'));
|
||||
$this->element(
|
||||
'a',
|
||||
[
|
||||
'href' => common_local_url(
|
||||
$this->trimmed('action'),
|
||||
['nickname' => $this->target->getNickname()]
|
||||
),
|
||||
],
|
||||
// TRANS: List element on gallery action page to show all tags.
|
||||
_m('TAGS', 'All')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li', array('id'=>'filter_tags_item'));
|
||||
$this->elementStart('form', array('name' => 'bytag',
|
||||
@ -76,12 +82,18 @@ class GalleryAction extends ProfileAction
|
||||
// TRANS: Fieldset legend on gallery action page.
|
||||
$this->element('legend', null, _('Select tag to filter'));
|
||||
// TRANS: Dropdown field label on gallery action page for a list containing tags.
|
||||
$this->dropdown('tag', _('Tag'), $content,
|
||||
// TRANS: Dropdown field title on gallery action page for a list containing tags.
|
||||
_('Choose a tag to narrow list.'), false, $tag);
|
||||
$this->dropdown(
|
||||
'tag',
|
||||
_('Tag'),
|
||||
$content,
|
||||
// TRANS: Dropdown field title on gallery action page for a list containing tags.
|
||||
_('Choose a tag to narrow list.'),
|
||||
false,
|
||||
$tag
|
||||
);
|
||||
$this->hidden('nickname', $this->target->getNickname());
|
||||
// TRANS: Submit button text on gallery action page.
|
||||
$this->submit('submit', _m('BUTTON','Go'));
|
||||
$this->submit('submit', _m('BUTTON', 'Go'));
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
$this->elementEnd('li');
|
||||
@ -92,7 +104,7 @@ class GalleryAction extends ProfileAction
|
||||
}
|
||||
|
||||
// Get list of tags we tagged other users with
|
||||
function getTags($lst, $usr)
|
||||
public function getTags($lst, $usr)
|
||||
{
|
||||
$profile_tag = new Notice_tag();
|
||||
$profile_tag->query('SELECT DISTINCT(tag) ' .
|
||||
@ -100,7 +112,7 @@ class GalleryAction extends ProfileAction
|
||||
'WHERE tagger = ' . $this->target->id . ' ' .
|
||||
'AND ' . $usr . ' = ' . $this->target->id . ' ' .
|
||||
'AND ' . $lst . ' = tagged ' .
|
||||
'AND tagger != tagged');
|
||||
'AND tagger <> tagged');
|
||||
$tags = array();
|
||||
while ($profile_tag->fetch()) {
|
||||
$tags[] = $profile_tag->tag;
|
||||
@ -109,12 +121,12 @@ class GalleryAction extends ProfileAction
|
||||
return $tags;
|
||||
}
|
||||
|
||||
function getAllTags()
|
||||
public function getAllTags()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
function showProfileBlock()
|
||||
public function showProfileBlock()
|
||||
{
|
||||
$block = new AccountProfileBlock($this, $this->target);
|
||||
$block->show();
|
||||
|
@ -1,35 +1,30 @@
|
||||
<?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
|
||||
*
|
||||
* Base class for sections showing lists of people
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Base class for sections
|
||||
@ -37,44 +32,32 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* These are the widgets that show interesting data about a person
|
||||
* group, or site.
|
||||
*
|
||||
* @category Widget
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class TopPostersSection extends ProfileSection
|
||||
{
|
||||
function getProfiles()
|
||||
public function getProfiles()
|
||||
{
|
||||
$qry = 'SELECT profile.*, count(*) as value ' .
|
||||
'FROM profile JOIN notice ON profile.id = notice.profile_id ' .
|
||||
(common_config('public', 'localonly') ? 'WHERE is_local = 1 ' : '') .
|
||||
'GROUP BY profile.id,nickname,fullname,profileurl,homepage,bio,location,profile.created,profile.modified,textsearch ' .
|
||||
'ORDER BY value DESC ';
|
||||
|
||||
$limit = PROFILES_PER_SECTION;
|
||||
$offset = 0;
|
||||
|
||||
if (common_config('db','type') == 'pgsql') {
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
$qry = 'SELECT profile.*, COUNT(*) AS value ' .
|
||||
'FROM profile JOIN notice ON profile.id = notice.profile_id ' .
|
||||
(common_config('public', 'localonly') ? 'WHERE is_local = 1 ' : '') .
|
||||
'GROUP BY profile.id, nickname, fullname, profileurl, homepage, bio, location, profile.created, profile.modified ' .
|
||||
'ORDER BY value DESC LIMIT ' . $limit;
|
||||
|
||||
$profile = Memcached_DataObject::cachedQuery('Profile',
|
||||
$qry,
|
||||
6 * 3600);
|
||||
$profile = Memcached_DataObject::cachedQuery('Profile', $qry, 6 * 3600);
|
||||
return $profile;
|
||||
}
|
||||
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Title for top posters section.
|
||||
return _('Top posters');
|
||||
}
|
||||
|
||||
function divId()
|
||||
public function divId()
|
||||
{
|
||||
return 'top_posters';
|
||||
}
|
||||
|
@ -1,76 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class Daemon
|
||||
{
|
||||
var $daemonize = true;
|
||||
var $_id = 'generic';
|
||||
public $daemonize = true;
|
||||
public $_id = 'generic';
|
||||
|
||||
function __construct($daemonize = true)
|
||||
public function __construct($daemonize = true)
|
||||
{
|
||||
$this->daemonize = $daemonize;
|
||||
}
|
||||
|
||||
function name()
|
||||
public function name()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
function get_id()
|
||||
public function get_id()
|
||||
{
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
function set_id($id)
|
||||
public function set_id($id)
|
||||
{
|
||||
$this->_id = $id;
|
||||
}
|
||||
|
||||
function background()
|
||||
public function background()
|
||||
{
|
||||
/*
|
||||
* This prefers to Starting PHP 5.4 (dotdeb), maybe earlier for some version/distrib
|
||||
* seems MySQL connection using mysqli driver get lost when fork.
|
||||
* Need to unset it so that child process recreate it.
|
||||
*
|
||||
* @todo FIXME cleaner way to do it ?
|
||||
*/
|
||||
global $_DB_DATAOBJECT;
|
||||
unset($_DB_DATAOBJECT['CONNECTIONS']);
|
||||
// Database connection will likely get lost after forking
|
||||
$this->resetDb();
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid < 0) { // error
|
||||
common_log(LOG_ERR, "Could not fork.");
|
||||
return false;
|
||||
} else if ($pid > 0) { // parent
|
||||
common_log(LOG_INFO, "Successfully forked.");
|
||||
exit(0);
|
||||
} else { // child
|
||||
return true;
|
||||
// Double-forking.
|
||||
foreach (['single', 'double'] as $v) {
|
||||
switch ($pid = pcntl_fork()) {
|
||||
case -1: // error
|
||||
common_log(LOG_ERR, 'Could not fork.');
|
||||
return false;
|
||||
case 0: // child
|
||||
if ($v === 'single') {
|
||||
posix_setsid();
|
||||
}
|
||||
break;
|
||||
default: // parent
|
||||
if ($v === 'double') {
|
||||
common_log(LOG_INFO, 'Successfully forked.');
|
||||
}
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function alreadyRunning()
|
||||
public function alreadyRunning()
|
||||
{
|
||||
$pidfilename = $this->pidFilename();
|
||||
|
||||
@ -89,7 +87,7 @@ class Daemon
|
||||
}
|
||||
}
|
||||
|
||||
function writePidFile()
|
||||
public function writePidFile()
|
||||
{
|
||||
$pidfilename = $this->pidFilename();
|
||||
|
||||
@ -100,7 +98,7 @@ class Daemon
|
||||
return file_put_contents($pidfilename, posix_getpid() . "\n");
|
||||
}
|
||||
|
||||
function clearPidFile()
|
||||
public function clearPidFile()
|
||||
{
|
||||
$pidfilename = $this->pidFilename();
|
||||
if (!$pidfilename) {
|
||||
@ -109,7 +107,7 @@ class Daemon
|
||||
return unlink($pidfilename);
|
||||
}
|
||||
|
||||
function pidFilename()
|
||||
public function pidFilename()
|
||||
{
|
||||
$piddir = common_config('daemon', 'piddir');
|
||||
if (!$piddir) {
|
||||
@ -122,15 +120,17 @@ class Daemon
|
||||
return $piddir . '/' . $name . '.pid';
|
||||
}
|
||||
|
||||
function changeUser()
|
||||
public function changeUser()
|
||||
{
|
||||
$groupname = common_config('daemon', 'group');
|
||||
|
||||
if ($groupname) {
|
||||
$group_info = posix_getgrnam($groupname);
|
||||
if (!$group_info) {
|
||||
common_log(LOG_WARNING,
|
||||
'Ignoring unknown group for daemon: ' . $groupname);
|
||||
common_log(
|
||||
LOG_WARNING,
|
||||
'Ignoring unknown group for daemon: ' . $groupname
|
||||
);
|
||||
} else {
|
||||
common_log(LOG_INFO, "Setting group to " . $groupname);
|
||||
posix_setgid($group_info['gid']);
|
||||
@ -142,8 +142,10 @@ class Daemon
|
||||
if ($username) {
|
||||
$user_info = posix_getpwnam($username);
|
||||
if (!$user_info) {
|
||||
common_log(LOG_WARNING,
|
||||
'Ignoring unknown user for daemon: ' . $username);
|
||||
common_log(
|
||||
LOG_WARNING,
|
||||
'Ignoring unknown user for daemon: ' . $username
|
||||
);
|
||||
} else {
|
||||
common_log(LOG_INFO, "Setting user to " . $username);
|
||||
posix_setuid($user_info['uid']);
|
||||
@ -151,7 +153,7 @@ class Daemon
|
||||
}
|
||||
}
|
||||
|
||||
function runOnce()
|
||||
public function runOnce()
|
||||
{
|
||||
if ($this->alreadyRunning()) {
|
||||
common_log(LOG_INFO, $this->name() . ' already running. Exiting.');
|
||||
@ -169,7 +171,7 @@ class Daemon
|
||||
$this->clearPidFile();
|
||||
}
|
||||
|
||||
function run()
|
||||
public function run()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1,29 +1,29 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* GNU social - a federating social network
|
||||
*
|
||||
*
|
||||
* 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 Config
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2008-2009, 2019 Free Software Foundation http://fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link https://www.gnu.org/software/social/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
$default =
|
||||
array('site' =>
|
||||
array('name' => 'Just another GNU social node',
|
||||
@ -74,7 +74,7 @@ $default =
|
||||
'mirror' => null,
|
||||
'utf8' => true,
|
||||
'db_driver' => 'DB', # XXX: JanRain libs only work with DB
|
||||
'quote_identifiers' => false,
|
||||
'quote_identifiers' => true,
|
||||
'type' => 'mysql',
|
||||
'schemacheck' => 'runtime', // 'runtime' or 'script'
|
||||
'annotate_queries' => false, // true to add caller comments to queries, eg /* POST Notice::saveNew */
|
||||
|
@ -68,11 +68,11 @@ abstract class Installer
|
||||
'check_module' => 'mysqli',
|
||||
'scheme' => 'mysqli', // DSN prefix for PEAR::DB
|
||||
],
|
||||
/*'pgsql' => [
|
||||
'name' => 'PostgreSQL',
|
||||
'pgsql' => [
|
||||
'name' => 'PostgreSQL 11+',
|
||||
'check_module' => 'pgsql',
|
||||
'scheme' => 'pgsql', // DSN prefix for PEAR::DB
|
||||
]*/
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
@ -304,20 +304,34 @@ abstract class Installer
|
||||
throw new Exception('Cannot connect to database: ' . $conn->getMessage());
|
||||
}
|
||||
|
||||
// ensure database encoding is UTF8
|
||||
$conn->query('SET NAMES utf8mb4');
|
||||
if ($this->dbtype == 'mysql') {
|
||||
$server_encoding = $conn->getRow("SHOW VARIABLES LIKE 'character_set_server'")[1];
|
||||
if ($server_encoding != 'utf8mb4') {
|
||||
$this->updateStatus("GNU social requires UTF8 character encoding. Your database is " . htmlentities($server_encoding));
|
||||
switch ($this->dbtype) {
|
||||
case 'pgsql':
|
||||
// ensure the database encoding is UTF8
|
||||
$conn->query("SET NAMES 'UTF8'");
|
||||
$server_encoding = $conn->getRow('SHOW server_encoding')[0];
|
||||
if ($server_encoding !== 'UTF8') {
|
||||
$this->updateStatus(
|
||||
'GNU social requires the UTF8 character encoding. Yours is ' .
|
||||
htmlentities($server_encoding)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'mysql':
|
||||
// ensure the database encoding is utf8mb4
|
||||
$conn->query("SET NAMES 'utf8mb4'");
|
||||
$server_encoding = $conn->getRow("SHOW VARIABLES LIKE 'character_set_server'")[1];
|
||||
if ($server_encoding !== 'utf8mb4') {
|
||||
$this->updateStatus(
|
||||
'GNU social requires the utf8mb4 character encoding. Yours is ' .
|
||||
htmlentities($server_encoding)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->updateStatus('Unknown DB type selected: ' . $this->dbtype);
|
||||
return false;
|
||||
}
|
||||
} elseif ($this->dbtype == 'pgsql') {
|
||||
$server_encoding = $conn->getRow('SHOW server_encoding')[0];
|
||||
if ($server_encoding != 'UTF8') {
|
||||
$this->updateStatus("GNU social requires UTF8 character encoding. Your database is " . htmlentities($server_encoding));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$res = $this->updateStatus("Creating database tables...");
|
||||
@ -362,7 +376,7 @@ abstract class Installer
|
||||
*/
|
||||
public function createCoreTables(DB_common $conn): bool
|
||||
{
|
||||
$schema = Schema::get($conn);
|
||||
$schema = Schema::get($conn, $this->dbtype);
|
||||
$tableDefs = $this->getCoreSchema();
|
||||
foreach ($tableDefs as $name => $def) {
|
||||
if (defined('DEBUG_INSTALLER')) {
|
||||
@ -446,7 +460,6 @@ abstract class Installer
|
||||
|
||||
// database
|
||||
"\$config['db']['database'] = {$vals['db_database']};\n\n" .
|
||||
($this->db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n" : '') .
|
||||
"\$config['db']['type'] = {$vals['db_type']};\n\n" .
|
||||
|
||||
"// Uncomment below for better performance. Just remember you must run\n" .
|
||||
@ -457,7 +470,7 @@ abstract class Installer
|
||||
$cfg = str_replace("\n", PHP_EOL, $cfg);
|
||||
|
||||
// write configuration file out to install directory
|
||||
$res = file_put_contents(INSTALLDIR . '/config.php', $cfg);
|
||||
$res = file_put_contents(INSTALLDIR . DIRECTORY_SEPARATOR . 'config.php', $cfg);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ class InternalSessionHandler implements SessionHandlerInterface
|
||||
$ids = [];
|
||||
|
||||
$session = new Session();
|
||||
$session->whereAdd('modified < "' . $epoch . '"');
|
||||
$session->whereAdd("modified < TIMESTAMP '" . $epoch . "'");
|
||||
$session->selectAdd();
|
||||
$session->selectAdd('id');
|
||||
|
||||
|
@ -1,36 +1,33 @@
|
||||
<?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
|
||||
*
|
||||
* utilities for sending email
|
||||
*
|
||||
* 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/>.
|
||||
* Utilities for sending email
|
||||
*
|
||||
* @category Mail
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @copyright 2008 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once 'Mail.php';
|
||||
|
||||
@ -49,8 +46,10 @@ function mail_backend()
|
||||
|
||||
if (!$backend) {
|
||||
$mail = new Mail();
|
||||
$backend = $mail->factory(common_config('mail', 'backend'),
|
||||
common_config('mail', 'params') ?: array());
|
||||
$backend = $mail->factory(
|
||||
common_config('mail', 'backend'),
|
||||
common_config('mail', 'params') ?: []
|
||||
);
|
||||
if ($_PEAR->isError($backend)) {
|
||||
throw new EmailException($backend->getMessage(), $backend->getCode());
|
||||
}
|
||||
@ -76,7 +75,7 @@ function mail_send($recipients, $headers, $body)
|
||||
$backend = mail_backend();
|
||||
|
||||
if (!isset($headers['Content-Type'])) {
|
||||
$headers['Content-Type'] = 'text/plain; charset=UTF-8';
|
||||
$headers['Content-Type'] = 'text/plain; charset=UTF-8';
|
||||
}
|
||||
|
||||
assert($backend); // throws an error if it's bad
|
||||
@ -124,7 +123,6 @@ function mail_notify_from()
|
||||
$notifyfrom = common_config('mail', 'notifyfrom');
|
||||
|
||||
if (!$notifyfrom) {
|
||||
|
||||
$domain = mail_domain();
|
||||
|
||||
$notifyfrom = '"'. str_replace('"', '\\"', common_config('site', 'name')) .'" <noreply@'.$domain.'>';
|
||||
@ -194,7 +192,6 @@ function mail_subscribe_notify_profile($listenee, $other)
|
||||
{
|
||||
if ($other->hasRight(Right::EMAILONSUBSCRIBE) &&
|
||||
$listenee->email && $listenee->emailnotifysub) {
|
||||
|
||||
$profile = $listenee->getProfile();
|
||||
|
||||
$name = $profile->getBestName();
|
||||
@ -211,15 +208,19 @@ function mail_subscribe_notify_profile($listenee, $other)
|
||||
$headers['To'] = $name . ' <' . $listenee->email . '>';
|
||||
// TRANS: Subject of new-subscriber notification e-mail.
|
||||
// TRANS: %1$s is the subscribing user's nickname, %2$s is the StatusNet sitename.
|
||||
$headers['Subject'] = sprintf(_('%1$s is now following you on %2$s.'),
|
||||
$other->getBestName(),
|
||||
common_config('site', 'name'));
|
||||
$headers['Subject'] = sprintf(
|
||||
_('%1$s is now following you on %2$s.'),
|
||||
$other->getBestName(),
|
||||
common_config('site', 'name')
|
||||
);
|
||||
|
||||
// TRANS: Main body of new-subscriber notification e-mail.
|
||||
// TRANS: %1$s is the subscriber's long name, %2$s is the StatusNet sitename.
|
||||
$body = sprintf(_('%1$s is now following you on %2$s.'),
|
||||
$long_name,
|
||||
common_config('site', 'name')) .
|
||||
$body = sprintf(
|
||||
_('%1$s is now following you on %2$s.'),
|
||||
$long_name,
|
||||
common_config('site', 'name')
|
||||
) .
|
||||
mail_profile_block($other) .
|
||||
mail_footer_block();
|
||||
|
||||
@ -233,7 +234,6 @@ function mail_subscribe_pending_notify_profile($listenee, $other)
|
||||
{
|
||||
if ($other->hasRight(Right::EMAILONSUBSCRIBE) &&
|
||||
$listenee->email && $listenee->emailnotifysub) {
|
||||
|
||||
$profile = $listenee->getProfile();
|
||||
|
||||
$name = $profile->getBestName();
|
||||
@ -251,18 +251,22 @@ function mail_subscribe_pending_notify_profile($listenee, $other)
|
||||
$headers['To'] = $name . ' <' . $listenee->email . '>';
|
||||
// TRANS: Subject of pending new-subscriber notification e-mail.
|
||||
// TRANS: %1$s is the subscribing user's nickname, %2$s is the StatusNet sitename.
|
||||
$headers['Subject'] = sprintf(_('%1$s would like to listen to '.
|
||||
$headers['Subject'] = sprintf(
|
||||
_('%1$s would like to listen to '.
|
||||
'your notices on %2$s.'),
|
||||
$other->getBestName(),
|
||||
common_config('site', 'name'));
|
||||
$other->getBestName(),
|
||||
common_config('site', 'name')
|
||||
);
|
||||
|
||||
// TRANS: Main body of pending new-subscriber notification e-mail.
|
||||
// TRANS: %1$s is the subscriber's long name, %2$s is the StatusNet sitename.
|
||||
$body = sprintf(_('%1$s would like to listen to your notices on %2$s. ' .
|
||||
$body = sprintf(
|
||||
_('%1$s would like to listen to your notices on %2$s. ' .
|
||||
'You may approve or reject their subscription at %3$s'),
|
||||
$long_name,
|
||||
common_config('site', 'name'),
|
||||
common_local_url('subqueue', array('nickname' => $listenee->nickname))) .
|
||||
$long_name,
|
||||
common_config('site', 'name'),
|
||||
common_local_url('subqueue', ['nickname' => $listenee->nickname])
|
||||
) .
|
||||
mail_profile_block($other) .
|
||||
mail_footer_block();
|
||||
|
||||
@ -277,13 +281,15 @@ function mail_footer_block()
|
||||
// TRANS: Common footer block for StatusNet notification emails.
|
||||
// TRANS: %1$s is the StatusNet sitename,
|
||||
// TRANS: %2$s is a link to the addressed user's e-mail settings.
|
||||
return "\n\n" . sprintf(_('Faithfully yours,'.
|
||||
"\n".'%1$s.'."\n\n".
|
||||
"----\n".
|
||||
"Change your email address or ".
|
||||
"notification options at ".'%2$s'),
|
||||
common_config('site', 'name'),
|
||||
common_local_url('emailsettings')) . "\n";
|
||||
return "\n\n" . sprintf(
|
||||
_('Faithfully yours,'.
|
||||
"\n".'%1$s.'."\n\n".
|
||||
"----\n".
|
||||
"Change your email address or ".
|
||||
"notification options at ".'%2$s'),
|
||||
common_config('site', 'name'),
|
||||
common_local_url('emailsettings')
|
||||
) . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -326,10 +332,12 @@ function mail_profile_block($profile)
|
||||
|
||||
// TRANS: This is a paragraph in a new-subscriber e-mail.
|
||||
// TRANS: %s is a URL where the subscriber can be reported as abusive.
|
||||
$out[] = sprintf(_('If you believe this account is being used abusively, ' .
|
||||
'you can block them from your subscribers list and ' .
|
||||
'report as spam to site administrators at %s.'),
|
||||
$blocklink);
|
||||
$out[] = sprintf(
|
||||
_('If you believe this account is being used abusively, ' .
|
||||
'you can block them from your subscribers list and ' .
|
||||
'report as spam to site administrators at %s.'),
|
||||
$blocklink
|
||||
);
|
||||
$out[] = "";
|
||||
|
||||
return implode("\n", $out);
|
||||
@ -354,18 +362,22 @@ function mail_new_incoming_notify($user)
|
||||
$headers['To'] = $name . ' <' . $user->email . '>';
|
||||
// TRANS: Subject of notification mail for new posting email address.
|
||||
// TRANS: %s is the StatusNet sitename.
|
||||
$headers['Subject'] = sprintf(_('New email address for posting to %s'),
|
||||
common_config('site', 'name'));
|
||||
$headers['Subject'] = sprintf(
|
||||
_('New email address for posting to %s'),
|
||||
common_config('site', 'name')
|
||||
);
|
||||
|
||||
// TRANS: Body of notification mail for new posting email address.
|
||||
// TRANS: %1$s is the StatusNet sitename, %2$s is the e-mail address to send
|
||||
// TRANS: to to post by e-mail, %3$s is a URL to more instructions.
|
||||
$body = sprintf(_("You have a new posting address on %1\$s.\n\n".
|
||||
"Send email to %2\$s to post new messages.\n\n".
|
||||
"More email instructions at %3\$s."),
|
||||
common_config('site', 'name'),
|
||||
$user->incomingemail,
|
||||
common_local_url('doc', array('title' => 'email'))) .
|
||||
$body = sprintf(
|
||||
_("You have a new posting address on %1\$s.\n\n".
|
||||
"Send email to %2\$s to post new messages.\n\n".
|
||||
"More email instructions at %3\$s."),
|
||||
common_config('site', 'name'),
|
||||
$user->incomingemail,
|
||||
common_local_url('doc', ['title' => 'email'])
|
||||
) .
|
||||
mail_footer_block();
|
||||
|
||||
mail_send($user->email, $headers, $body);
|
||||
@ -402,42 +414,58 @@ function mail_broadcast_notice_sms($notice)
|
||||
|
||||
$user = new User();
|
||||
|
||||
$UT = common_config('db','type')=='pgsql'?'"user"':'user';
|
||||
$replies = $notice->getReplies();
|
||||
$user->query('SELECT nickname, smsemail, incomingemail ' .
|
||||
"FROM $UT LEFT OUTER JOIN subscription " .
|
||||
"ON $UT.id = subscription.subscriber " .
|
||||
'AND subscription.subscribed = ' . $notice->profile_id . ' ' .
|
||||
'AND subscription.subscribed != subscription.subscriber ' .
|
||||
// Users (other than the sender) who `want SMS notices':
|
||||
"WHERE $UT.id != " . $notice->profile_id . ' ' .
|
||||
"AND $UT.smsemail IS NOT null " .
|
||||
"AND $UT.smsnotify = 1 " .
|
||||
// ... where either the user _is_ subscribed to the sender
|
||||
// (any of the "subscription" fields IS NOT null)
|
||||
// and wants to get SMS for all of this scribe's notices...
|
||||
'AND (subscription.sms = 1 ' .
|
||||
// ... or where the user was mentioned in
|
||||
// or replied-to with the notice:
|
||||
($replies ? sprintf("OR $UT.id in (%s)",
|
||||
implode(',', $replies))
|
||||
: '') .
|
||||
')');
|
||||
|
||||
$repliesQry = '';
|
||||
if (!empty($replies)) {
|
||||
$repliesQry = sprintf(
|
||||
'OR %s.id IN (%s)',
|
||||
$user->escapedTableName(),
|
||||
implode(',', $replies)
|
||||
);
|
||||
}
|
||||
|
||||
$user->query(sprintf(
|
||||
'SELECT nickname, smsemail, incomingemail ' .
|
||||
'FROM %1$s LEFT JOIN subscription ' .
|
||||
'ON %1$s.id = subscription.subscriber ' .
|
||||
'AND subscription.subscribed = %2$d ' .
|
||||
'AND subscription.subscribed <> subscription.subscriber ' .
|
||||
// Users (other than the sender) who `want SMS notices':
|
||||
'WHERE %1$s.id <> %2$d ' .
|
||||
'AND %1$s.smsemail IS NOT NULL ' .
|
||||
'AND %1$s.smsnotify = TRUE ' .
|
||||
// ... where either the user _is_ subscribed to the sender
|
||||
// (any of the "subscription" fields IS NOT NULL)
|
||||
// and wants to get SMS for all of this scribe's notices...
|
||||
'AND (subscription.sms = TRUE ' .
|
||||
// ... or where the user was mentioned in
|
||||
// or replied-to with the notice:
|
||||
$repliesQry .
|
||||
')',
|
||||
$user->escapedTableName(),
|
||||
$notice->profile_id
|
||||
));
|
||||
|
||||
while ($user->fetch()) {
|
||||
common_log(LOG_INFO,
|
||||
'Sending notice ' . $notice->id . ' to ' . $user->smsemail,
|
||||
__FILE__);
|
||||
$success = mail_send_sms_notice_address($notice,
|
||||
$user->smsemail,
|
||||
$user->incomingemail,
|
||||
$user->nickname);
|
||||
common_log(
|
||||
LOG_INFO,
|
||||
'Sending notice ' . $notice->id . ' to ' . $user->smsemail,
|
||||
__FILE__
|
||||
);
|
||||
$success = mail_send_sms_notice_address(
|
||||
$notice,
|
||||
$user->smsemail,
|
||||
$user->incomingemail,
|
||||
$user->nickname
|
||||
);
|
||||
if (!$success) {
|
||||
// XXX: Not sure, but I think that's the right thing to do
|
||||
common_log(LOG_WARNING,
|
||||
'Sending notice ' . $notice->id . ' to ' .
|
||||
$user->smsemail . ' FAILED, cancelling.',
|
||||
__FILE__);
|
||||
common_log(
|
||||
LOG_WARNING,
|
||||
'Sending notice ' . $notice->id . ' to ' . $user->smsemail . ' FAILED, canceling.',
|
||||
__FILE__
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -462,10 +490,12 @@ function mail_broadcast_notice_sms($notice)
|
||||
*/
|
||||
function mail_send_sms_notice($notice, $user)
|
||||
{
|
||||
return mail_send_sms_notice_address($notice,
|
||||
$user->smsemail,
|
||||
$user->incomingemail,
|
||||
$user->nickname);
|
||||
return mail_send_sms_notice_address(
|
||||
$notice,
|
||||
$user->smsemail,
|
||||
$user->incomingemail,
|
||||
$user->nickname
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -496,8 +526,7 @@ function mail_send_sms_notice_address($notice, $smsemail, $incomingemail, $nickn
|
||||
$headers['To'] = $to;
|
||||
// TRANS: Subject line for SMS-by-email notification messages.
|
||||
// TRANS: %s is the posting user's nickname.
|
||||
$headers['Subject'] = sprintf(_('%s status'),
|
||||
$other->getBestName());
|
||||
$headers['Subject'] = sprintf(_('%s status'), $other->getBestName());
|
||||
|
||||
$body = $notice->content;
|
||||
|
||||
@ -554,14 +583,16 @@ function mail_notify_nudge($from, $to)
|
||||
// TRANS: Body for 'nudge' notification email.
|
||||
// TRANS: %1$s is the nuding user's long name, $2$s is the nudging user's nickname,
|
||||
// TRANS: %3$s is a URL to post notices at.
|
||||
$body = sprintf(_("%1\$s (%2\$s) is wondering what you are up to ".
|
||||
"these days and is inviting you to post some news.\n\n".
|
||||
"So let's hear from you :)\n\n".
|
||||
"%3\$s\n\n".
|
||||
"Don't reply to this email; it won't get to them."),
|
||||
$from_profile->getBestName(),
|
||||
$from->nickname,
|
||||
common_local_url('all', array('nickname' => $to->nickname))) .
|
||||
$body = sprintf(
|
||||
_('%1$s (%2$s) is wondering what you are up to ' .
|
||||
"these days and is inviting you to post some news.\n\n" .
|
||||
"So let's hear from you :)\n\n" .
|
||||
"%3\$s\n\n" .
|
||||
"Don't reply to this email; it won't get to them."),
|
||||
$from_profile->getBestName(),
|
||||
$from->nickname,
|
||||
common_local_url('all', ['nickname' => $to->nickname])
|
||||
) .
|
||||
mail_footer_block();
|
||||
common_switch_locale();
|
||||
|
||||
@ -612,17 +643,19 @@ function mail_notify_message(Notice $message, Profile $from = null, ?array $to =
|
||||
// TRANS: Body for direct-message notification email.
|
||||
// TRANS: %1$s is the sending user's long name, %2$s is the sending user's nickname,
|
||||
// TRANS: %3$s is the message content, %4$s a URL to the message,
|
||||
$body = sprintf(_("%1\$s (%2\$s) sent you a private message:\n\n".
|
||||
"------------------------------------------------------\n".
|
||||
"%3\$s\n".
|
||||
"------------------------------------------------------\n\n".
|
||||
"You can reply to their message here:\n\n".
|
||||
"%4\$s\n\n".
|
||||
"Don't reply to this email; it won't get to them."),
|
||||
$from->getBestName(),
|
||||
$from->getNickname(),
|
||||
$message->getContent(),
|
||||
common_local_url('newmessage', ['to' => $from->getID()])) .
|
||||
$body = sprintf(
|
||||
_("%1\$s (%2\$s) sent you a private message:\n\n".
|
||||
"------------------------------------------------------\n".
|
||||
"%3\$s\n".
|
||||
"------------------------------------------------------\n\n".
|
||||
"You can reply to their message here:\n\n".
|
||||
"%4\$s\n\n".
|
||||
"Don't reply to this email; it won't get to them."),
|
||||
$from->getBestName(),
|
||||
$from->getNickname(),
|
||||
$message->getContent(),
|
||||
common_local_url('newmessage', ['to' => $from->getID()])
|
||||
) .
|
||||
mail_footer_block();
|
||||
|
||||
$headers = _mail_prepare_headers('message', $t->getNickname(), $from->getNickname());
|
||||
@ -675,8 +708,11 @@ function mail_notify_attn(Profile $rcpt, Notice $notice)
|
||||
common_switch_locale($user->language);
|
||||
|
||||
if ($notice->hasConversation()) {
|
||||
$conversationUrl = common_local_url('conversation',
|
||||
array('id' => $notice->conversation)).'#notice-'.$notice->getID();
|
||||
$conversationUrl = common_local_url(
|
||||
'conversation',
|
||||
['id' => $notice->conversation]
|
||||
) . '#notice-'.$notice->getID();
|
||||
|
||||
// TRANS: Line in @-reply notification e-mail. %s is conversation URL.
|
||||
$conversationEmailText = sprintf(_("The full conversation can be read here:\n\n".
|
||||
"\t%s"), $conversationUrl) . "\n\n";
|
||||
@ -688,32 +724,40 @@ function mail_notify_attn(Profile $rcpt, Notice $notice)
|
||||
// TRANS: %1$s is the "fancy name" for a profile.
|
||||
$subject = sprintf(_('%1$s sent a notice to your attention'), $sender->getFancyName());
|
||||
|
||||
// TRANS: Body of @-reply notification e-mail.
|
||||
// TRANS: %1$s is the sending user's name, $2$s is the StatusNet sitename,
|
||||
// TRANS: %3$s is a URL to the notice, %4$s is the notice text,
|
||||
// TRANS: %5$s is the text "The full conversation can be read here:" and a URL to the full conversion if it exists (otherwise empty),
|
||||
// TRANS: %6$s is a URL to reply to the notice, %7$s is a URL to all @-replies for the addressed user,
|
||||
$body = sprintf(_("%1\$s just sent a notice to your attention (an '@-reply') on %2\$s.\n\n".
|
||||
"The notice is here:\n\n".
|
||||
"\t%3\$s\n\n" .
|
||||
"It reads:\n\n".
|
||||
"\t%4\$s\n\n" .
|
||||
"%5\$s" .
|
||||
"You can reply back here:\n\n".
|
||||
"\t%6\$s\n\n" .
|
||||
"The list of all @-replies for you here:\n\n" .
|
||||
"%7\$s"),
|
||||
$sender->getFancyName(),//%1
|
||||
common_config('site', 'name'),//%2
|
||||
common_local_url('shownotice',
|
||||
array('notice' => $notice->getID())),//%3
|
||||
$notice->getContent(),//%4
|
||||
$conversationEmailText,//%5
|
||||
common_local_url('newnotice',
|
||||
array('replyto' => $sender->getNickname(), 'inreplyto' => $notice->getID())),//%6
|
||||
common_local_url('replies',
|
||||
array('nickname' => $rcpt->getNickname()))) . //%7
|
||||
mail_footer_block();
|
||||
// TRANS: Body of @-reply notification e-mail.
|
||||
// TRANS: %1$s is the sending user's name, $2$s is the GNU social sitename,
|
||||
// TRANS: %3$s is a URL to the notice, %4$s is the notice text,
|
||||
// TRANS: %5$s is the text "The full conversation can be read here:" and a URL to the full conversion if it exists (otherwise empty),
|
||||
// TRANS: %6$s is a URL to reply to the notice, %7$s is a URL to all @-replies for the addressed user,
|
||||
$body = sprintf(
|
||||
_("%1\$s just sent a notice to your attention (an '@-reply') on %2\$s.\n\n".
|
||||
"The notice is here:\n\n".
|
||||
"\t%3\$s\n\n" .
|
||||
"It reads:\n\n".
|
||||
"\t%4\$s\n\n" .
|
||||
"%5\$s" .
|
||||
"You can reply back here:\n\n".
|
||||
"\t%6\$s\n\n" .
|
||||
"The list of all @-replies for you here:\n\n" .
|
||||
"%7\$s"),
|
||||
$sender->getFancyName(), //%1
|
||||
common_config('site', 'name'), //%2
|
||||
common_local_url(
|
||||
'shownotice',
|
||||
['notice' => $notice->getID()]
|
||||
), //%3
|
||||
$notice->getContent(), //%4
|
||||
$conversationEmailText, //%5
|
||||
common_local_url(
|
||||
'newnotice',
|
||||
['replyto' => $sender->getNickname(), 'inreplyto' => $notice->getID()]
|
||||
), //%6
|
||||
common_local_url(
|
||||
'replies',
|
||||
['nickname' => $rcpt->getNickname()]
|
||||
)
|
||||
) . //%7
|
||||
mail_footer_block();
|
||||
$headers = _mail_prepare_headers('mention', $rcpt->getNickname(), $sender->getNickname());
|
||||
|
||||
common_switch_locale();
|
||||
@ -764,20 +808,23 @@ function mail_notify_group_join($group, $joiner)
|
||||
$headers['To'] = $admin->getBestName() . ' <' . $adminUser->email . '>';
|
||||
// TRANS: Subject of group join notification e-mail.
|
||||
// TRANS: %1$s is the joining user's nickname, %2$s is the group name, and %3$s is the StatusNet sitename.
|
||||
$headers['Subject'] = sprintf(_('%1$s has joined '.
|
||||
'your group %2$s on %3$s'),
|
||||
$joiner->getBestName(),
|
||||
$group->getBestName(),
|
||||
common_config('site', 'name'));
|
||||
$headers['Subject'] = sprintf(
|
||||
_('%1$s has joined your group %2$s on %3$s'),
|
||||
$joiner->getBestName(),
|
||||
$group->getBestName(),
|
||||
common_config('site', 'name')
|
||||
);
|
||||
|
||||
// TRANS: Main body of group join notification e-mail.
|
||||
// TRANS: %1$s is the subscriber's long name, %2$s is the group name, and %3$s is the StatusNet sitename,
|
||||
// TRANS: %4$s is a block of profile info about the subscriber.
|
||||
// TRANS: %5$s is a link to the addressed user's e-mail settings.
|
||||
$body = sprintf(_('%1$s has joined your group %2$s on %3$s.'),
|
||||
$joiner->getFancyName(),
|
||||
$group->getFancyName(),
|
||||
common_config('site', 'name')) .
|
||||
$body = sprintf(
|
||||
_('%1$s has joined your group %2$s on %3$s.'),
|
||||
$joiner->getFancyName(),
|
||||
$group->getFancyName(),
|
||||
common_config('site', 'name')
|
||||
) .
|
||||
mail_profile_block($joiner) .
|
||||
mail_footer_block();
|
||||
|
||||
@ -811,20 +858,24 @@ function mail_notify_group_join_pending($group, $joiner)
|
||||
$headers['To'] = $admin->getBestName() . ' <' . $adminUser->email . '>';
|
||||
// TRANS: Subject of pending group join request notification e-mail.
|
||||
// TRANS: %1$s is the joining user's nickname, %2$s is the group name, and %3$s is the StatusNet sitename.
|
||||
$headers['Subject'] = sprintf(_('%1$s wants to join your group %2$s on %3$s.'),
|
||||
$joiner->getBestName(),
|
||||
$group->getBestName(),
|
||||
common_config('site', 'name'));
|
||||
$headers['Subject'] = sprintf(
|
||||
_('%1$s wants to join your group %2$s on %3$s.'),
|
||||
$joiner->getBestName(),
|
||||
$group->getBestName(),
|
||||
common_config('site', 'name')
|
||||
);
|
||||
|
||||
// TRANS: Main body of pending group join request notification e-mail.
|
||||
// TRANS: %1$s is the subscriber's long name, %2$s is the group name, and %3$s is the StatusNet sitename,
|
||||
// TRANS: %4$s is the URL to the moderation queue page.
|
||||
$body = sprintf(_('%1$s would like to join your group %2$s on %3$s. ' .
|
||||
'You may approve or reject their group membership at %4$s'),
|
||||
$joiner->getFancyName(),
|
||||
$group->getFancyName(),
|
||||
common_config('site', 'name'),
|
||||
common_local_url('groupqueue', array('nickname' => $group->nickname))) .
|
||||
$body = sprintf(
|
||||
_('%1$s would like to join your group %2$s on %3$s. ' .
|
||||
'You may approve or reject their group membership at %4$s'),
|
||||
$joiner->getFancyName(),
|
||||
$group->getFancyName(),
|
||||
common_config('site', 'name'),
|
||||
common_local_url('groupqueue', ['nickname' => $group->nickname])
|
||||
) .
|
||||
mail_profile_block($joiner) .
|
||||
mail_footer_block();
|
||||
|
||||
|
@ -1,21 +1,20 @@
|
||||
<?php
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Base class for daemon that can launch one or more processing threads,
|
||||
@ -24,7 +23,7 @@
|
||||
* This is mainly intended for indefinite workloads such as monitoring
|
||||
* a queue or maintaining an IM channel.
|
||||
*
|
||||
* Child classes should implement the
|
||||
* Child classes should implement the
|
||||
*
|
||||
* We can then pass individual items through the QueueHandler subclasses
|
||||
* they belong to. We additionally can handle queues for multiple sites.
|
||||
@ -34,14 +33,14 @@
|
||||
*/
|
||||
abstract class SpawningDaemon extends Daemon
|
||||
{
|
||||
protected $threads=1;
|
||||
protected $threads = 1;
|
||||
|
||||
const EXIT_OK = 0;
|
||||
const EXIT_ERR = 1;
|
||||
const EXIT_SHUTDOWN = 100;
|
||||
const EXIT_RESTART = 101;
|
||||
|
||||
function __construct($id=null, $daemonize=true, $threads=1)
|
||||
public function __construct($id = null, $daemonize = true, $threads = 1)
|
||||
{
|
||||
parent::__construct($daemonize);
|
||||
|
||||
@ -56,7 +55,7 @@ abstract class SpawningDaemon extends Daemon
|
||||
*
|
||||
* @return int exit code; use self::EXIT_SHUTDOWN to request not to respawn.
|
||||
*/
|
||||
public abstract function runThread();
|
||||
abstract public function runThread();
|
||||
|
||||
/**
|
||||
* Spawn one or more background processes and let them start running.
|
||||
@ -69,17 +68,17 @@ abstract class SpawningDaemon extends Daemon
|
||||
* though ParallelizingDaemon is probably better for workloads
|
||||
* that have forseeable endpoints.
|
||||
*/
|
||||
function run()
|
||||
public function run()
|
||||
{
|
||||
$this->initPipes();
|
||||
|
||||
$children = array();
|
||||
$children = [];
|
||||
for ($i = 1; $i <= $this->threads; $i++) {
|
||||
$pid = pcntl_fork();
|
||||
if ($pid < 0) {
|
||||
$this->log(LOG_ERR, "Couldn't fork for thread $i; aborting\n");
|
||||
exit(1);
|
||||
} else if ($pid == 0) {
|
||||
} elseif ($pid === 0) {
|
||||
$this->initAndRunChild($i);
|
||||
} else {
|
||||
$this->log(LOG_INFO, "Spawned thread $i as pid $pid");
|
||||
@ -87,7 +86,7 @@ abstract class SpawningDaemon extends Daemon
|
||||
}
|
||||
sleep(common_config('queue', 'spawndelay'));
|
||||
}
|
||||
|
||||
|
||||
$this->log(LOG_INFO, "Waiting for children to complete.");
|
||||
while (count($children) > 0) {
|
||||
$status = null;
|
||||
@ -101,7 +100,7 @@ abstract class SpawningDaemon extends Daemon
|
||||
if (pcntl_wifexited($status)) {
|
||||
$exitCode = pcntl_wexitstatus($status);
|
||||
$info = "status $exitCode";
|
||||
} else if (pcntl_wifsignaled($status)) {
|
||||
} elseif (pcntl_wifsignaled($status)) {
|
||||
$exitCode = self::EXIT_ERR;
|
||||
$signal = pcntl_wtermsig($status);
|
||||
$info = "signal $signal";
|
||||
@ -114,7 +113,7 @@ abstract class SpawningDaemon extends Daemon
|
||||
$pid = pcntl_fork();
|
||||
if ($pid < 0) {
|
||||
$this->log(LOG_ERR, "Couldn't fork to respawn thread $i; aborting thread.\n");
|
||||
} else if ($pid == 0) {
|
||||
} elseif ($pid === 0) {
|
||||
$this->initAndRunChild($i);
|
||||
} else {
|
||||
$this->log(LOG_INFO, "Respawned thread $i as pid $pid");
|
||||
@ -134,7 +133,7 @@ abstract class SpawningDaemon extends Daemon
|
||||
* Create an IPC socket pair which child processes can use to detect
|
||||
* if the parent process has been killed.
|
||||
*/
|
||||
function initPipes()
|
||||
public function initPipes()
|
||||
{
|
||||
$sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
|
||||
if ($sockets) {
|
||||
@ -197,10 +196,19 @@ abstract class SpawningDaemon extends Daemon
|
||||
*/
|
||||
protected function resetDb()
|
||||
{
|
||||
// @fixme do we need to explicitly open the db too
|
||||
// or is this implied?
|
||||
global $_DB_DATAOBJECT;
|
||||
unset($_DB_DATAOBJECT['CONNECTIONS']);
|
||||
|
||||
// Can't be called statically
|
||||
$user = new User();
|
||||
$conn = $user->getDatabaseConnection();
|
||||
$conn->disconnect();
|
||||
|
||||
// Remove the disconnected connection from the list
|
||||
foreach ($_DB_DATAOBJECT['CONNECTIONS'] as $k => $v) {
|
||||
if ($v === $conn) {
|
||||
unset($_DB_DATAOBJECT['CONNECTIONS'][$k]);
|
||||
}
|
||||
}
|
||||
|
||||
// Reconnect main memcached, or threads will stomp on
|
||||
// each other and corrupt their requests.
|
||||
@ -216,14 +224,13 @@ abstract class SpawningDaemon extends Daemon
|
||||
}
|
||||
}
|
||||
|
||||
function log($level, $msg)
|
||||
public function log($level, $msg)
|
||||
{
|
||||
common_log($level, get_class($this) . ' ('. $this->get_id() .'): '.$msg);
|
||||
}
|
||||
|
||||
function name()
|
||||
public function name()
|
||||
{
|
||||
return strtolower(get_class($this).'.'.$this->get_id());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,24 +1,23 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008-2011, 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/>.
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
/* XXX: break up into separate modules (HTTP, user, files) */
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Show a server error.
|
||||
*/
|
||||
@ -52,12 +51,14 @@ function common_init_locale($language=null)
|
||||
}
|
||||
putenv('LANGUAGE='.$language);
|
||||
putenv('LANG='.$language);
|
||||
$ok = setlocale(LC_ALL,
|
||||
$language . ".utf8",
|
||||
$language . ".UTF8",
|
||||
$language . ".utf-8",
|
||||
$language . ".UTF-8",
|
||||
$language);
|
||||
$ok = setlocale(
|
||||
LC_ALL,
|
||||
$language . '.utf8',
|
||||
$language . '.UTF8',
|
||||
$language . '.utf-8',
|
||||
$language . '.UTF-8',
|
||||
$language
|
||||
);
|
||||
|
||||
return $ok;
|
||||
}
|
||||
@ -356,12 +357,14 @@ function common_set_cookie($key, $value, $expiration=0)
|
||||
} else {
|
||||
$cookiepath = '/';
|
||||
}
|
||||
return setcookie($key,
|
||||
$value,
|
||||
$expiration,
|
||||
$cookiepath,
|
||||
$server,
|
||||
GNUsocial::useHTTPS());
|
||||
return setcookie(
|
||||
$key,
|
||||
$value,
|
||||
$expiration,
|
||||
$cookiepath,
|
||||
$server,
|
||||
GNUsocial::useHTTPS()
|
||||
);
|
||||
}
|
||||
|
||||
define('REMEMBERME', 'rememberme');
|
||||
@ -592,7 +595,6 @@ function common_to_alphanumeric($str)
|
||||
|
||||
function common_purify($html, array $args=[])
|
||||
{
|
||||
|
||||
$cfg = \HTMLPurifier_Config::createDefault();
|
||||
/**
|
||||
* rel values that should be avoided since they can be used to infer
|
||||
@ -839,9 +841,10 @@ function common_find_mentions($text, Profile $sender, Notice $parent=null)
|
||||
}
|
||||
$tagged = $sender->getTaggedSubscribers($tag);
|
||||
|
||||
$url = common_local_url('showprofiletag',
|
||||
['nickname' => $sender->getNickname(),
|
||||
'tag' => $tag]);
|
||||
$url = common_local_url(
|
||||
'showprofiletag',
|
||||
['nickname' => $sender->getNickname(), 'tag' => $tag]
|
||||
);
|
||||
|
||||
$mentions[] = ['mentioned' => $tagged,
|
||||
'type' => 'list',
|
||||
@ -888,17 +891,21 @@ function common_find_mentions($text, Profile $sender, Notice $parent=null)
|
||||
function common_find_mentions_raw($text, $preMention='@')
|
||||
{
|
||||
$tmatches = [];
|
||||
preg_match_all('/^T (' . Nickname::DISPLAY_FMT . ') /',
|
||||
$text,
|
||||
$tmatches,
|
||||
PREG_OFFSET_CAPTURE);
|
||||
preg_match_all(
|
||||
'/^T (' . Nickname::DISPLAY_FMT . ') /',
|
||||
$text,
|
||||
$tmatches,
|
||||
PREG_OFFSET_CAPTURE
|
||||
);
|
||||
|
||||
$atmatches = [];
|
||||
// the regexp's "(?!\@)" makes sure it doesn't matches the single "@remote" in "@remote@server.com"
|
||||
preg_match_all('/'.Nickname::BEFORE_MENTIONS.preg_quote($preMention, '/').'(' . Nickname::DISPLAY_FMT . ')\b(?!\@)/',
|
||||
$text,
|
||||
$atmatches,
|
||||
PREG_OFFSET_CAPTURE);
|
||||
preg_match_all(
|
||||
'/' . Nickname::BEFORE_MENTIONS . preg_quote($preMention, '/') . '(' . Nickname::DISPLAY_FMT . ')\b(?!\@)/',
|
||||
$text,
|
||||
$atmatches,
|
||||
PREG_OFFSET_CAPTURE
|
||||
);
|
||||
|
||||
$matches = array_merge($tmatches[1], $atmatches[1]);
|
||||
return $matches;
|
||||
@ -961,7 +968,8 @@ function common_url_schemes($filter = null)
|
||||
$schemes,
|
||||
function ($scheme) use ($filter) {
|
||||
return is_null($filter) || ($scheme & $filter);
|
||||
})
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -1339,8 +1347,10 @@ function common_relative_profile($sender, $nickname, $dt=null)
|
||||
|
||||
// Try to find profiles this profile is subscribed to that have this nickname
|
||||
$recipient = new Profile();
|
||||
// XXX: use a join instead of a subquery
|
||||
$recipient->whereAdd('EXISTS (SELECT subscribed from subscription where subscriber = '.intval($sender->id).' and subscribed = id)', 'AND');
|
||||
$recipient->whereAdd(
|
||||
sprintf('id IN (SELECT subscribed FROM subscription WHERE subscriber = %d)', $sender->id),
|
||||
'AND'
|
||||
);
|
||||
$recipient->whereAdd("nickname = '" . $recipient->escape($nickname) . "'", 'AND');
|
||||
if ($recipient->find(true)) {
|
||||
// XXX: should probably differentiate between profiles with
|
||||
@ -1349,8 +1359,10 @@ function common_relative_profile($sender, $nickname, $dt=null)
|
||||
}
|
||||
// Try to find profiles that listen to this profile and that have this nickname
|
||||
$recipient = new Profile();
|
||||
// XXX: use a join instead of a subquery
|
||||
$recipient->whereAdd('EXISTS (SELECT subscriber from subscription where subscribed = '.intval($sender->id).' and subscriber = id)', 'AND');
|
||||
$recipient->whereAdd(
|
||||
sprintf('id IN (SELECT subscriber FROM subscription WHERE subscribed = %d)', $sender->id),
|
||||
'AND'
|
||||
);
|
||||
$recipient->whereAdd("nickname = '" . $recipient->escape($nickname) . "'", 'AND');
|
||||
if ($recipient->find(true)) {
|
||||
// XXX: should probably differentiate between profiles with
|
||||
@ -1701,11 +1713,13 @@ function common_enqueue_notice($notice)
|
||||
|
||||
function common_profile_url($nickname)
|
||||
{
|
||||
return common_local_url('showstream',
|
||||
['nickname' => $nickname],
|
||||
null,
|
||||
null,
|
||||
false);
|
||||
return common_local_url(
|
||||
'showstream',
|
||||
['nickname' => $nickname],
|
||||
null,
|
||||
null,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2210,11 +2224,13 @@ function common_remove_magic_from_request()
|
||||
|
||||
function common_user_uri(&$user)
|
||||
{
|
||||
return common_local_url('userbyid',
|
||||
['id' => $user->id],
|
||||
null,
|
||||
null,
|
||||
false);
|
||||
return common_local_url(
|
||||
'userbyid',
|
||||
['id' => $user->id],
|
||||
null,
|
||||
null,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2225,11 +2241,12 @@ function common_user_uri(&$user)
|
||||
* alphanums and remove lookalikes (0, O, 1, I) = 32 chars = 5 bits to make it easy for the user to type in
|
||||
* @return string confirmation_code of length $bits/5
|
||||
*/
|
||||
function common_confirmation_code($bits, $codechars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ') {
|
||||
function common_confirmation_code($bits, $codechars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ')
|
||||
{
|
||||
$chars = ceil($bits/5);
|
||||
$codechars_length = strlen($codechars)-1;
|
||||
$code = '';
|
||||
for($i = 0; $i < $chars; ++$i) {
|
||||
for ($i = 0; $i < $chars; ++$i) {
|
||||
$random_char = $codechars[random_int(0, $codechars_length)];
|
||||
$code .= $random_char;
|
||||
}
|
||||
@ -2403,15 +2420,13 @@ function common_compatible_license($from, $to)
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a quoted table name, if required according to config
|
||||
* returns a quoted table name
|
||||
*/
|
||||
function common_database_tablename($tablename)
|
||||
{
|
||||
if (common_config('db', 'quote_identifiers')) {
|
||||
$tablename = '"'. $tablename .'"';
|
||||
}
|
||||
//table prefixes could be added here later
|
||||
return $tablename;
|
||||
$schema = Schema::get();
|
||||
// table prefixes could be added here later
|
||||
return $schema->quoteIdentifier($tablename);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2692,10 +2707,13 @@ function _common_size_str_to_int($size): int
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function common_get_preferred_php_upload_limit(): int {
|
||||
return min(_common_size_str_to_int(ini_get('post_max_size')),
|
||||
_common_size_str_to_int(ini_get('upload_max_filesize')),
|
||||
_common_size_str_to_int(ini_get('memory_limit')));
|
||||
function common_get_preferred_php_upload_limit(): int
|
||||
{
|
||||
return min(
|
||||
_common_size_str_to_int(ini_get('post_max_size')),
|
||||
_common_size_str_to_int(ini_get('upload_max_filesize')),
|
||||
_common_size_str_to_int(ini_get('memory_limit'))
|
||||
);
|
||||
}
|
||||
|
||||
function html_sprintf()
|
||||
|
@ -1,28 +1,28 @@
|
||||
<?php
|
||||
/*
|
||||
* GNU Social - a federating social network
|
||||
* Copyright (C) 2014, Free Software Foundation, 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); }
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @package Activity
|
||||
* @maintainer Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @package Favorite
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class FavoriteModule extends ActivityVerbHandlerModule
|
||||
{
|
||||
const PLUGIN_VERSION = '2.0.0';
|
||||
@ -93,15 +93,14 @@ class FavoriteModule extends ActivityVerbHandlerModule
|
||||
while ($fave->fetch()) {
|
||||
try {
|
||||
$fave->decache();
|
||||
$fave->query(sprintf('UPDATE fave '.
|
||||
'SET uri = "%s", '.
|
||||
' modified = "%s" '.
|
||||
'WHERE user_id = %d '.
|
||||
'AND notice_id = %d',
|
||||
Fave::newUri($fave->getActor(), $fave->getTarget(), $fave->modified),
|
||||
common_sql_date(strtotime($fave->modified)),
|
||||
$fave->user_id,
|
||||
$fave->notice_id));
|
||||
$fave->query(sprintf(
|
||||
"UPDATE fave SET uri = '%s', modified = TIMESTAMP '%s' " .
|
||||
'WHERE user_id = %d AND notice_id = %d',
|
||||
Fave::newUri($fave->getActor(), $fave->getTarget(), $fave->modified),
|
||||
common_sql_date(strtotime($fave->modified)),
|
||||
$fave->user_id,
|
||||
$fave->notice_id
|
||||
));
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_ERR, "Error updating fave URI: " . $e->getMessage());
|
||||
}
|
||||
@ -114,77 +113,129 @@ class FavoriteModule extends ActivityVerbHandlerModule
|
||||
public function onRouterInitialized(URLMapper $m)
|
||||
{
|
||||
// Web UI actions
|
||||
$m->connect('main/favor',
|
||||
['action' => 'favor']);
|
||||
$m->connect('main/disfavor',
|
||||
['action' => 'disfavor']);
|
||||
$m->connect(
|
||||
'main/favor',
|
||||
['action' => 'favor']
|
||||
);
|
||||
$m->connect(
|
||||
'main/disfavor',
|
||||
['action' => 'disfavor']
|
||||
);
|
||||
|
||||
if (common_config('singleuser', 'enabled')) {
|
||||
$nickname = User::singleUserNickname();
|
||||
|
||||
$m->connect('favorites',
|
||||
['action' => 'showfavorites',
|
||||
'nickname' => $nickname]);
|
||||
$m->connect('favoritesrss',
|
||||
['action' => 'favoritesrss',
|
||||
'nickname' => $nickname]);
|
||||
$m->connect(
|
||||
'favorites',
|
||||
[
|
||||
'action' => 'showfavorites',
|
||||
'nickname' => $nickname,
|
||||
]
|
||||
);
|
||||
$m->connect(
|
||||
'favoritesrss',
|
||||
[
|
||||
'action' => 'favoritesrss',
|
||||
'nickname' => $nickname,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$m->connect('favoritedrss',
|
||||
['action' => 'favoritedrss']);
|
||||
$m->connect('favorited/',
|
||||
['action' => 'favorited']);
|
||||
$m->connect('favorited',
|
||||
['action' => 'favorited']);
|
||||
$m->connect(
|
||||
'favoritedrss',
|
||||
['action' => 'favoritedrss']
|
||||
);
|
||||
$m->connect(
|
||||
'favorited/',
|
||||
['action' => 'favorited']
|
||||
);
|
||||
$m->connect(
|
||||
'favorited',
|
||||
['action' => 'favorited']
|
||||
);
|
||||
|
||||
$m->connect(':nickname/favorites',
|
||||
['action' => 'showfavorites'],
|
||||
['nickname' => Nickname::DISPLAY_FMT]);
|
||||
$m->connect(':nickname/favorites/rss',
|
||||
['action' => 'favoritesrss'],
|
||||
['nickname' => Nickname::DISPLAY_FMT]);
|
||||
$m->connect(
|
||||
':nickname/favorites',
|
||||
['action' => 'showfavorites'],
|
||||
['nickname' => Nickname::DISPLAY_FMT]
|
||||
);
|
||||
$m->connect(
|
||||
':nickname/favorites/rss',
|
||||
['action' => 'favoritesrss'],
|
||||
['nickname' => Nickname::DISPLAY_FMT]
|
||||
);
|
||||
}
|
||||
|
||||
// Favorites for API
|
||||
$m->connect('api/favorites/create.:format',
|
||||
['action' => 'ApiFavoriteCreate'],
|
||||
['format' => '(xml|json)']);
|
||||
$m->connect('api/favorites/destroy.:format',
|
||||
['action' => 'ApiFavoriteDestroy'],
|
||||
['format' => '(xml|json)']);
|
||||
$m->connect('api/favorites/list.:format',
|
||||
['action' => 'ApiTimelineFavorites'],
|
||||
['format' => '(xml|json|rss|atom|as)']);
|
||||
$m->connect('api/favorites/:id.:format',
|
||||
['action' => 'ApiTimelineFavorites'],
|
||||
['id' => Nickname::INPUT_FMT,
|
||||
'format' => '(xml|json|rss|atom|as)']);
|
||||
$m->connect('api/favorites.:format',
|
||||
['action' => 'ApiTimelineFavorites'],
|
||||
['format' => '(xml|json|rss|atom|as)']);
|
||||
$m->connect('api/favorites/create/:id.:format',
|
||||
['action' => 'ApiFavoriteCreate'],
|
||||
['id' => '[0-9]+',
|
||||
'format' => '(xml|json)']);
|
||||
$m->connect('api/favorites/destroy/:id.:format',
|
||||
['action' => 'ApiFavoriteDestroy'],
|
||||
['id' => '[0-9]+',
|
||||
'format' => '(xml|json)']);
|
||||
$m->connect(
|
||||
'api/favorites/create.:format',
|
||||
['action' => 'ApiFavoriteCreate'],
|
||||
['format' => '(xml|json)']
|
||||
);
|
||||
$m->connect(
|
||||
'api/favorites/destroy.:format',
|
||||
['action' => 'ApiFavoriteDestroy'],
|
||||
['format' => '(xml|json)']
|
||||
);
|
||||
$m->connect(
|
||||
'api/favorites/list.:format',
|
||||
['action' => 'ApiTimelineFavorites'],
|
||||
['format' => '(xml|json|rss|atom|as)']
|
||||
);
|
||||
$m->connect(
|
||||
'api/favorites/:id.:format',
|
||||
['action' => 'ApiTimelineFavorites'],
|
||||
[
|
||||
'id' => Nickname::INPUT_FMT,
|
||||
'format' => '(xml|json|rss|atom|as)',
|
||||
]
|
||||
);
|
||||
$m->connect(
|
||||
'api/favorites.:format',
|
||||
['action' => 'ApiTimelineFavorites'],
|
||||
['format' => '(xml|json|rss|atom|as)']
|
||||
);
|
||||
$m->connect(
|
||||
'api/favorites/create/:id.:format',
|
||||
['action' => 'ApiFavoriteCreate'],
|
||||
[
|
||||
'id' => '[0-9]+',
|
||||
'format' => '(xml|json)',
|
||||
]
|
||||
);
|
||||
$m->connect(
|
||||
'api/favorites/destroy/:id.:format',
|
||||
['action' => 'ApiFavoriteDestroy'],
|
||||
[
|
||||
'id' => '[0-9]+',
|
||||
'format' => '(xml|json)',
|
||||
]
|
||||
);
|
||||
|
||||
// AtomPub API
|
||||
$m->connect('api/statusnet/app/favorites/:profile/:notice.atom',
|
||||
['action' => 'AtomPubShowFavorite'],
|
||||
['profile' => '[0-9]+',
|
||||
'notice' => '[0-9]+']);
|
||||
$m->connect(
|
||||
'api/statusnet/app/favorites/:profile/:notice.atom',
|
||||
['action' => 'AtomPubShowFavorite'],
|
||||
[
|
||||
'profile' => '[0-9]+',
|
||||
'notice' => '[0-9]+',
|
||||
]
|
||||
);
|
||||
|
||||
$m->connect('api/statusnet/app/favorites/:profile.atom',
|
||||
['action' => 'AtomPubFavoriteFeed'],
|
||||
['profile' => '[0-9]+']);
|
||||
$m->connect(
|
||||
'api/statusnet/app/favorites/:profile.atom',
|
||||
['action' => 'AtomPubFavoriteFeed'],
|
||||
['profile' => '[0-9]+']
|
||||
);
|
||||
|
||||
// Required for qvitter API
|
||||
$m->connect('api/statuses/favs/:id.:format',
|
||||
['action' => 'ApiStatusesFavs'],
|
||||
['id' => '[0-9]+',
|
||||
'format' => '(xml|json)']);
|
||||
$m->connect(
|
||||
'api/statuses/favs/:id.:format',
|
||||
['action' => 'ApiStatusesFavs'],
|
||||
[
|
||||
'id' => '[0-9]+',
|
||||
'format' => '(xml|json)',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// FIXME: Set this to abstract public in lib/modules/ActivityHandlerPlugin.php when all plugins have migrated!
|
||||
@ -443,10 +494,12 @@ class FavoriteModule extends ActivityVerbHandlerModule
|
||||
$emailfave = $scoped->getConfigPref('email', 'notify_fave') ? 1 : 0;
|
||||
|
||||
$action->elementStart('li');
|
||||
$action->checkbox('email-notify_fave',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone adds my notice as a favorite.'),
|
||||
$emailfave);
|
||||
$action->checkbox(
|
||||
'email-notify_fave',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone adds my notice as a favorite.'),
|
||||
$emailfave
|
||||
);
|
||||
$action->elementEnd('li');
|
||||
|
||||
return true;
|
||||
@ -454,9 +507,9 @@ class FavoriteModule extends ActivityVerbHandlerModule
|
||||
|
||||
public function onStartEmailSaveForm(Action $action, Profile $scoped)
|
||||
{
|
||||
$emailfave = $action->booleanintstring('email-notify_fave');
|
||||
$emailfave = $action->boolean('email-notify_fave');
|
||||
try {
|
||||
if ($emailfave == $scoped->getPref('email', 'notify_fave')) {
|
||||
if ($emailfave == (bool) $scoped->getPref('email', 'notify_fave')) {
|
||||
// No need to update setting
|
||||
return true;
|
||||
}
|
||||
@ -473,24 +526,31 @@ class FavoriteModule extends ActivityVerbHandlerModule
|
||||
|
||||
public function onEndPersonalGroupNav(Menu $menu, Profile $target, Profile $scoped=null)
|
||||
{
|
||||
$menu->out->menuItem(common_local_url('showfavorites', array('nickname' => $target->getNickname())),
|
||||
// TRANS: Menu item in personal group navigation menu.
|
||||
_m('MENU','Favorites'),
|
||||
// @todo i18n FIXME: Need to make this two messages.
|
||||
// TRANS: Menu item title in personal group navigation menu.
|
||||
// TRANS: %s is a username.
|
||||
sprintf(_('%s\'s favorite notices'), $target->getBestName()),
|
||||
$scoped instanceof Profile && $target->id === $scoped->id && $menu->actionName =='showfavorites',
|
||||
'nav_timeline_favorites');
|
||||
$menu->out->menuItem(
|
||||
common_local_url('showfavorites', ['nickname' => $target->getNickname()]),
|
||||
// TRANS: Menu item in personal group navigation menu.
|
||||
_m('MENU', 'Favorites'),
|
||||
// @todo i18n FIXME: Need to make this two messages.
|
||||
// TRANS: Menu item title in personal group navigation menu.
|
||||
// TRANS: %s is a username.
|
||||
sprintf(_('%s\'s favorite notices'), $target->getBestName()),
|
||||
($scoped instanceof Profile && $target->id === $scoped->id && $menu->actionName === 'showfavorites'),
|
||||
'nav_timeline_favorites'
|
||||
);
|
||||
}
|
||||
|
||||
public function onEndPublicGroupNav(Menu $menu)
|
||||
{
|
||||
if (!common_config('singleuser', 'enabled')) {
|
||||
// TRANS: Menu item in search group navigation panel.
|
||||
$menu->out->menuItem(common_local_url('favorited'), _m('MENU','Popular'),
|
||||
// TRANS: Menu item title in search group navigation panel.
|
||||
_('Popular notices'), $menu->actionName == 'favorited', 'nav_timeline_favorited');
|
||||
$menu->out->menuItem(
|
||||
common_local_url('favorited'),
|
||||
_m('MENU', 'Popular'),
|
||||
// TRANS: Menu item title in search group navigation panel.
|
||||
_('Popular notices'),
|
||||
($menu->actionName === 'favorited'),
|
||||
'nav_timeline_favorited'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -519,7 +579,7 @@ class FavoriteModule extends ActivityVerbHandlerModule
|
||||
{
|
||||
if ($action->isPost()) {
|
||||
// The below tests are only for presenting to the user. POSTs which inflict
|
||||
// duplicate favorite entries are handled with AlreadyFulfilledException.
|
||||
// duplicate favorite entries are handled with AlreadyFulfilledException.
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -529,9 +589,13 @@ class FavoriteModule extends ActivityVerbHandlerModule
|
||||
switch (true) {
|
||||
case $exists && ActivityUtils::compareVerbs($verb, array(ActivityVerb::FAVORITE, ActivityVerb::LIKE)):
|
||||
case !$exists && ActivityUtils::compareVerbs($verb, array(ActivityVerb::UNFAVORITE, ActivityVerb::UNLIKE)):
|
||||
common_redirect(common_local_url('activityverb',
|
||||
array('id' => $target->getID(),
|
||||
'verb' => ActivityUtils::resolveUri($expected_verb, true))));
|
||||
common_redirect(common_local_url(
|
||||
'activityverb',
|
||||
[
|
||||
'id' => $target->getID(),
|
||||
'verb' => ActivityUtils::resolveUri($expected_verb, true),
|
||||
]
|
||||
));
|
||||
break;
|
||||
default:
|
||||
// No need to redirect as we are on the correct action already.
|
||||
@ -617,23 +681,23 @@ function mail_notify_fave(User $rcpt, Profile $sender, Notice $notice)
|
||||
// TRANS: %3$s is a URL to the faved notice, %4$s is the faved notice text,
|
||||
// TRANS: %5$s is a URL to all faves of the adding user, %6$s is the StatusNet sitename,
|
||||
// TRANS: %7$s is the adding user's nickname.
|
||||
$body = sprintf(_("%1\$s (@%7\$s) just added your notice from %2\$s".
|
||||
" as one of their favorites.\n\n" .
|
||||
"The URL of your notice is:\n\n" .
|
||||
"%3\$s\n\n" .
|
||||
"The text of your notice is:\n\n" .
|
||||
"%4\$s\n\n" .
|
||||
"You can see the list of %1\$s's favorites here:\n\n" .
|
||||
"%5\$s"),
|
||||
$bestname,
|
||||
common_exact_date($notice->created),
|
||||
common_local_url('shownotice',
|
||||
array('notice' => $notice->id)),
|
||||
$notice->content,
|
||||
common_local_url('showfavorites',
|
||||
array('nickname' => $sender->getNickname())),
|
||||
common_config('site', 'name'),
|
||||
$sender->getNickname()) .
|
||||
$body = sprintf(
|
||||
_("%1\$s (@%7\$s) just added your notice from %2\$s".
|
||||
" as one of their favorites.\n\n" .
|
||||
"The URL of your notice is:\n\n" .
|
||||
"%3\$s\n\n" .
|
||||
"The text of your notice is:\n\n" .
|
||||
"%4\$s\n\n" .
|
||||
"You can see the list of %1\$s's favorites here:\n\n" .
|
||||
"%5\$s"),
|
||||
$bestname,
|
||||
common_exact_date($notice->created),
|
||||
common_local_url('shownotice', ['notice' => $notice->id]),
|
||||
$notice->content,
|
||||
common_local_url('showfavorites', ['nickname' => $sender->getNickname()]),
|
||||
common_config('site', 'name'),
|
||||
$sender->getNickname()
|
||||
) .
|
||||
mail_footer_block();
|
||||
|
||||
$headers = _mail_prepare_headers('fave', $rcpt->getNickname(), $sender->getNickname());
|
||||
|
@ -1,48 +1,43 @@
|
||||
<?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) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Notice stream for favorites
|
||||
*
|
||||
* 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 Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Notice stream for favorites
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class FaveNoticeStream extends ScopingNoticeStream
|
||||
{
|
||||
function __construct(Profile $target, Profile $scoped=null)
|
||||
public function __construct(Profile $target, Profile $scoped = null)
|
||||
{
|
||||
$stream = new RawFaveNoticeStream($target, $scoped);
|
||||
if ($target->sameAs($scoped)) {
|
||||
@ -58,11 +53,10 @@ class FaveNoticeStream extends ScopingNoticeStream
|
||||
* Raw notice stream for favorites
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class RawFaveNoticeStream extends NoticeStream
|
||||
{
|
||||
@ -71,7 +65,7 @@ class RawFaveNoticeStream extends NoticeStream
|
||||
|
||||
protected $selectVerbs = array();
|
||||
|
||||
function __construct(Profile $target, Profile $scoped=null)
|
||||
public function __construct(Profile $target, Profile $scoped = null)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
@ -92,7 +86,7 @@ class RawFaveNoticeStream extends NoticeStream
|
||||
* @param <type> $max_id
|
||||
* @return <type>
|
||||
*/
|
||||
function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
{
|
||||
$fav = new Fave();
|
||||
$qry = null;
|
||||
@ -101,10 +95,10 @@ class RawFaveNoticeStream extends NoticeStream
|
||||
$qry = 'SELECT fave.* FROM fave ';
|
||||
$qry .= 'WHERE fave.user_id = ' . $this->user_id . ' ';
|
||||
} else {
|
||||
$qry = 'SELECT fave.* FROM fave ';
|
||||
$qry .= 'INNER JOIN notice ON fave.notice_id = notice.id ';
|
||||
$qry .= 'WHERE fave.user_id = ' . $this->user_id . ' ';
|
||||
$qry .= 'AND notice.is_local != ' . Notice::GATEWAY . ' ';
|
||||
$qry = 'SELECT fave.* FROM fave ';
|
||||
$qry .= 'INNER JOIN notice ON fave.notice_id = notice.id ';
|
||||
$qry .= 'WHERE fave.user_id = ' . $this->user_id . ' ';
|
||||
$qry .= 'AND notice.is_local <> ' . Notice::GATEWAY . ' ';
|
||||
}
|
||||
|
||||
if ($since_id != 0) {
|
||||
@ -137,4 +131,3 @@ class RawFaveNoticeStream extends NoticeStream
|
||||
return $ids;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,9 +51,9 @@ class Activitypub_pending_follow_requests extends Managed_DataObject
|
||||
{
|
||||
return [
|
||||
'fields' => [
|
||||
'local_profile_id' => ['type' => 'integer', 'not null' => true],
|
||||
'remote_profile_id' => ['type' => 'integer', 'not null' => true],
|
||||
'relation_id' => ['type' => 'serial', 'not null' => true],
|
||||
'local_profile_id' => ['type' => 'int', 'not null' => true],
|
||||
'remote_profile_id' => ['type' => 'int', 'not null' => true],
|
||||
'relation_id' => ['type' => 'serial', 'not null' => true],
|
||||
],
|
||||
'primary key' => ['relation_id'],
|
||||
'foreign keys' => [
|
||||
|
@ -61,7 +61,7 @@ class Activitypub_profile extends Managed_DataObject
|
||||
return [
|
||||
'fields' => [
|
||||
'uri' => ['type' => 'text', 'not null' => true],
|
||||
'profile_id' => ['type' => 'integer'],
|
||||
'profile_id' => ['type' => 'int', 'not null' => true],
|
||||
'inboxuri' => ['type' => 'text', 'not null' => true],
|
||||
'sharedInboxuri' => ['type' => 'text'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
|
@ -53,7 +53,7 @@ class Activitypub_rsa extends Managed_DataObject
|
||||
{
|
||||
return [
|
||||
'fields' => [
|
||||
'profile_id' => ['type' => 'integer'],
|
||||
'profile_id' => ['type' => 'int', 'not null' => true],
|
||||
'private_key' => ['type' => 'text'],
|
||||
'public_key' => ['type' => 'text', 'not null' => true],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
|
@ -1,47 +1,38 @@
|
||||
<?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) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Score of a notice by activity spam service
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Score of a notice per the activity spam service
|
||||
*
|
||||
* @category Spam
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class Spam_score extends Managed_DataObject
|
||||
{
|
||||
@ -54,7 +45,6 @@ class Spam_score extends Managed_DataObject
|
||||
|
||||
public static function save($notice, $result)
|
||||
{
|
||||
|
||||
$orig = null;
|
||||
$score = Spam_score::getKV('notice_id', $notice->id);
|
||||
|
||||
@ -93,12 +83,13 @@ class Spam_score extends Managed_DataObject
|
||||
'notice_id' => array('type' => 'int',
|
||||
'not null' => true,
|
||||
'description' => 'notice getting scored'),
|
||||
'score' => array('type' => 'double',
|
||||
'score' => array('type' => 'float',
|
||||
'size' => 'big',
|
||||
'not null' => true,
|
||||
'description' => 'score for the notice (0.0, 1.0)'),
|
||||
'scaled' => array('type' => 'int',
|
||||
'description' => 'scaled score for the notice (0, 10000)'),
|
||||
'is_spam' => array('type' => 'tinyint',
|
||||
'is_spam' => array('type' => 'bool',
|
||||
'description' => 'flag for spamosity'),
|
||||
'created' => array('type' => 'datetime',
|
||||
'not null' => true,
|
||||
@ -146,7 +137,7 @@ class Spam_score extends Managed_DataObject
|
||||
if ($score->find()) {
|
||||
while ($score->fetch()) {
|
||||
$orig = clone($score);
|
||||
$score->is_spam = ($score->score >= 0.90) ? 1 : 0;
|
||||
$score->is_spam = ($score->score >= 0.90) ? true : false;
|
||||
$score->update($orig);
|
||||
}
|
||||
}
|
||||
@ -169,9 +160,8 @@ class Spam_score extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function saveNew($notice, $result)
|
||||
public function saveNew($notice, $result)
|
||||
{
|
||||
|
||||
$score = new Spam_score();
|
||||
|
||||
$score->notice_id = $notice->id;
|
@ -1,52 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2012, StatusNet, Inc.
|
||||
*
|
||||
* Spam notice stream
|
||||
*
|
||||
* 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
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2012 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Spam notice stream
|
||||
*
|
||||
* @category Spam
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2012 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Spam notice stream
|
||||
*
|
||||
* @copyright 2012 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
*/
|
||||
class SpamNoticeStream extends ScopingNoticeStream
|
||||
{
|
||||
function __construct(Profile $scoped=null)
|
||||
public function __construct(Profile $scoped = null)
|
||||
{
|
||||
parent::__construct(new CachingNoticeStream(new RawSpamNoticeStream(), 'spam_score:notice_ids'),
|
||||
$scoped);
|
||||
parent::__construct(
|
||||
new CachingNoticeStream(new RawSpamNoticeStream(), 'spam_score:notice_ids'),
|
||||
$scoped
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,20 +47,16 @@ class SpamNoticeStream extends ScopingNoticeStream
|
||||
* Raw stream of spammy notices
|
||||
*
|
||||
* @category Stream
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class RawSpamNoticeStream extends NoticeStream
|
||||
{
|
||||
function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
public function getNoticeIds($offset, $limit, $since_id, $max_id)
|
||||
{
|
||||
$ss = new Spam_score();
|
||||
|
||||
$ss->is_spam = 1;
|
||||
$ss->is_spam = true;
|
||||
|
||||
$ss->selectAdd();
|
||||
$ss->selectAdd('notice_id');
|
||||
|
@ -1,20 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2013 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/>.
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @copyright 2013 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
|
||||
@ -33,13 +35,13 @@ END_OF_SILENCESPAMMER_HELP;
|
||||
|
||||
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||
|
||||
function testAllUsers($filter, $minimum, $percent) {
|
||||
function testAllUsers($filter, $minimum, $percent)
|
||||
{
|
||||
$found = false;
|
||||
$offset = 0;
|
||||
$limit = 1000;
|
||||
|
||||
do {
|
||||
|
||||
$user = new User();
|
||||
$user->orderBy('created');
|
||||
$user->limit($offset, $limit);
|
||||
@ -56,37 +58,36 @@ function testAllUsers($filter, $minimum, $percent) {
|
||||
}
|
||||
$offset += $found;
|
||||
}
|
||||
|
||||
} while ($found > 0);
|
||||
}
|
||||
|
||||
function silencespammer($filter, $user, $minimum, $percent) {
|
||||
|
||||
function silencespammer($filter, $user, $minimum, $percent)
|
||||
{
|
||||
printfnq("Testing user %s\n", $user->nickname);
|
||||
|
||||
$profile = Profile::getKV('id', $user->id);
|
||||
|
||||
if ($profile->isSilenced()) {
|
||||
printfnq("Already silenced %s\n", $user->nickname);
|
||||
return;
|
||||
printfnq("Already silenced %s\n", $user->nickname);
|
||||
return;
|
||||
}
|
||||
|
||||
$cnt = $profile->noticeCount();
|
||||
|
||||
if ($cnt < $minimum) {
|
||||
printfnq("Only %d notices posted (minimum %d); skipping\n", $cnt, $minimum);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
$ss = new Spam_score();
|
||||
|
||||
$ss->query(sprintf("SELECT count(*) as spam_count ".
|
||||
"FROM notice join spam_score on notice.id = spam_score.notice_id ".
|
||||
"WHERE notice.profile_id = %d AND spam_score.is_spam = 1", $profile->id));
|
||||
'WHERE notice.profile_id = %d AND spam_score.is_spam = TRUE', $profile->id));
|
||||
|
||||
while ($ss->fetch()) {
|
||||
$spam_count = $ss->spam_count;
|
||||
}
|
||||
}
|
||||
|
||||
$spam_percent = ($spam_count * 100.0 / $cnt);
|
||||
|
||||
@ -94,10 +95,10 @@ function silencespammer($filter, $user, $minimum, $percent) {
|
||||
printfnq("Silencing user %s (%d/%d = %0.2f%% spam)\n", $user->nickname, $spam_count, $cnt, $spam_percent);
|
||||
try {
|
||||
$profile->silence();
|
||||
} catch(Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
printfnq("Error: %s", $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -1,33 +1,32 @@
|
||||
<?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
|
||||
*
|
||||
* Simple-minded queue manager for storing items in the database
|
||||
*
|
||||
* 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 QueueManager
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class DBQueueManager extends QueueManager
|
||||
{
|
||||
/**
|
||||
@ -39,7 +38,7 @@ class DBQueueManager extends QueueManager
|
||||
{
|
||||
$qi = new Queue_item();
|
||||
|
||||
$qi->frame = $this->encode($object);
|
||||
$qi->frame = DB_DataObject_Cast::blob($this->encode($object));
|
||||
$qi->transport = $queue;
|
||||
$qi->created = common_sql_now();
|
||||
$result = $qi->insert();
|
||||
@ -121,7 +120,8 @@ class DBQueueManager extends QueueManager
|
||||
|
||||
// What to do if no handler was found. For example, the OpportunisticQM
|
||||
// should avoid deleting items just because it can't reach XMPP queues etc.
|
||||
protected function noHandlerFound(Queue_item $qi, $rep=null) {
|
||||
protected function noHandlerFound(Queue_item $qi, $rep = null)
|
||||
{
|
||||
$this->_log(LOG_INFO, "[{$qi->transport}:{$rep}] No handler for queue {$qi->transport}; discarding.");
|
||||
$this->_done($qi);
|
||||
}
|
||||
|
@ -1,31 +1,31 @@
|
||||
<?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) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Data class for email reminders
|
||||
*
|
||||
* 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 Data
|
||||
* @package EmailReminder
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class Email_reminder extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'email_reminder';
|
||||
@ -46,8 +46,8 @@ class Email_reminder extends Managed_DataObject
|
||||
* @param int $days Number of days after the code was created
|
||||
* @return boolean true if any Email_reminder records were found
|
||||
*/
|
||||
static function needsReminder($type, $object, $days = null) {
|
||||
|
||||
public static function needsReminder($type, $object, $days = null)
|
||||
{
|
||||
$reminder = new Email_reminder();
|
||||
$reminder->type = $type;
|
||||
$reminder->code = $object->code;
|
||||
@ -72,8 +72,8 @@ class Email_reminder extends Managed_DataObject
|
||||
* @param int $days Number of days after the code was created
|
||||
* @return int $result row ID of the new reminder record
|
||||
*/
|
||||
static function recordReminder($type, $object, $days) {
|
||||
|
||||
public static function recordReminder($type, $object, $days)
|
||||
{
|
||||
$reminder = new Email_reminder();
|
||||
$reminder->type = $type;
|
||||
$reminder->code = $object->code;
|
||||
@ -83,9 +83,9 @@ class Email_reminder extends Managed_DataObject
|
||||
|
||||
if (empty($result)) {
|
||||
common_log_db_error($reminder, 'INSERT', __FILE__);
|
||||
throw new ServerException(
|
||||
// TRANS: Server exception thrown when a reminder record could not be inserted into the database.
|
||||
_m('Database error inserting reminder record.')
|
||||
throw new ServerException(
|
||||
// TRANS: Server exception thrown when a reminder record could not be inserted into the database.
|
||||
_m('Database error inserting reminder record.')
|
||||
);
|
||||
}
|
||||
|
||||
@ -108,13 +108,13 @@ class Email_reminder extends Managed_DataObject
|
||||
),
|
||||
'code' => array(
|
||||
'type' => 'varchar',
|
||||
'not null' => 'true',
|
||||
'not null' => true,
|
||||
'length' => 191,
|
||||
'description' => 'confirmation code'
|
||||
),
|
||||
'days' => array(
|
||||
'type' => 'int',
|
||||
'not null' => 'true',
|
||||
'not null' => true,
|
||||
'description' => 'number of days since code creation'
|
||||
),
|
||||
'sent' => array(
|
||||
|
@ -1,45 +1,38 @@
|
||||
<?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
|
||||
*
|
||||
* Handler for reminder queue items which send reminder emails to all users
|
||||
* we would like to complete a given process (e.g.: registration).
|
||||
*
|
||||
* 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 Email
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Handler for reminder queue items which send reminder emails to all users
|
||||
* we would like to complete a given process (e.g.: registration)
|
||||
*
|
||||
* @category Email
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class SiteConfirmReminderHandler extends QueueHandler
|
||||
{
|
||||
@ -52,7 +45,7 @@ class SiteConfirmReminderHandler extends QueueHandler
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function transport()
|
||||
public function transport()
|
||||
{
|
||||
return 'siterem';
|
||||
}
|
||||
@ -63,14 +56,14 @@ class SiteConfirmReminderHandler extends QueueHandler
|
||||
* @param array $remitem type of reminder to send and any special options
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
function handle($remitem) : bool
|
||||
public function handle($remitem): bool
|
||||
{
|
||||
list($type, $opts) = $remitem;
|
||||
|
||||
$qm = QueueManager::get();
|
||||
|
||||
try {
|
||||
switch($type) {
|
||||
switch ($type) {
|
||||
case UserConfirmRegReminderHandler::REGISTER_REMINDER:
|
||||
$confirm = new Confirm_address();
|
||||
$confirm->address_type = $type;
|
||||
@ -87,7 +80,11 @@ class SiteConfirmReminderHandler extends QueueHandler
|
||||
case UserInviteReminderHandler::INVITE_REMINDER:
|
||||
$invitation = new Invitation();
|
||||
// Only send one reminder (the latest one), regardless of how many invitations a user has
|
||||
$sql = 'SELECT * FROM (SELECT * FROM invitation WHERE registered_user_id IS NULL ORDER BY created DESC) invitees GROUP BY invitees.address';
|
||||
$sql = 'SELECT * FROM invitation ' .
|
||||
'WHERE (address, created) IN ' .
|
||||
'(SELECT address, MAX(created) FROM invitation GROUP BY address) AND ' .
|
||||
'registered_user_id IS NULL ' .
|
||||
'ORDER BY created DESC';
|
||||
$invitation->query($sql);
|
||||
while ($invitation->fetch()) {
|
||||
try {
|
||||
|
@ -1,35 +1,30 @@
|
||||
<?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 email summary status
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Data
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 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/>.
|
||||
* @category Data
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2010, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||
|
||||
@ -38,19 +33,17 @@ require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||
*
|
||||
* Email summary information for users
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @category Action
|
||||
* @copyright 2010, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class Email_summary_status extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'email_summary_status'; // table name
|
||||
public $user_id; // int(4) primary_key not_null
|
||||
public $send_summary; // tinyint not_null
|
||||
public $send_summary; // bool not_null default_true
|
||||
public $last_summary_id; // int(4) null
|
||||
public $created; // datetime not_null
|
||||
public $modified; // datetime not_null
|
||||
@ -60,9 +53,9 @@ class Email_summary_status extends Managed_DataObject
|
||||
return array(
|
||||
'fields' => array(
|
||||
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user id'),
|
||||
'send_summary' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'not null' => true, 'description' => 'whether to send a summary or not'),
|
||||
'send_summary' => array('type' => 'bool', 'default' => true, 'not null' => true, 'description' => 'whether to send a summary or not'),
|
||||
'last_summary_id' => array('type' => 'int', 'description' => 'last summary id'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
|
||||
),
|
||||
'primary key' => array('user_id'),
|
||||
@ -79,7 +72,7 @@ class Email_summary_status extends Managed_DataObject
|
||||
*
|
||||
* @return int flag for whether to send this user a summary email
|
||||
*/
|
||||
static function getSendSummary($user_id)
|
||||
public static function getSendSummary($user_id)
|
||||
{
|
||||
$ess = Email_summary_status::getKV('user_id', $user_id);
|
||||
|
||||
@ -97,7 +90,7 @@ class Email_summary_status extends Managed_DataObject
|
||||
*
|
||||
* @return Email_summary_status instance for this user, with count already incremented.
|
||||
*/
|
||||
static function getLastSummaryID($user_id)
|
||||
public static function getLastSummaryID($user_id)
|
||||
{
|
||||
$ess = Email_summary_status::getKV('user_id', $user_id);
|
||||
|
||||
|
@ -94,8 +94,10 @@ class Happening extends Managed_DataObject
|
||||
'unique keys' => array(
|
||||
'happening_uri_key' => array('uri'),
|
||||
),
|
||||
'foreign keys' => array('happening_profile_id__key' => array('profile', array('profile_id' => 'id')),
|
||||
'happening_uri__key' => array('notice', array('uri' => 'uri'))),
|
||||
'foreign keys' => array(
|
||||
'happening_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
|
||||
'happening_uri_fkey' => array('notice', array('uri' => 'uri'))
|
||||
),
|
||||
'indexes' => array('happening_created_idx' => array('created'),
|
||||
'happening_start_end_idx' => array('start_time', 'end_time')),
|
||||
);
|
||||
|
@ -85,8 +85,10 @@ class RSVP extends Managed_DataObject
|
||||
'rsvp_uri_key' => array('uri'),
|
||||
'rsvp_profile_event_key' => array('profile_id', 'event_uri'),
|
||||
),
|
||||
'foreign keys' => array('rsvp_event_uri_key' => array('happening', array('event_uri' => 'uri')),
|
||||
'rsvp_profile_id__key' => array('profile', array('profile_id' => 'id'))),
|
||||
'foreign keys' => array(
|
||||
'rsvp_event_uri_fkey' => array('happening', array('event_uri' => 'uri')),
|
||||
'rsvp_profile_id_fkey' => array('profile', array('profile_id' => 'id'))
|
||||
),
|
||||
'indexes' => array('rsvp_created_idx' => array('created')),
|
||||
);
|
||||
}
|
||||
|
@ -1,36 +1,30 @@
|
||||
<?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
|
||||
*
|
||||
* Action for showing Twitter-like JSON search results
|
||||
*
|
||||
* 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 Search
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
class UserautocompleteAction extends Action
|
||||
{
|
||||
@ -44,7 +38,7 @@ class UserautocompleteAction extends Action
|
||||
* @return boolean true if nothing goes wrong
|
||||
* @throws ClientException
|
||||
*/
|
||||
public function prepare(array $args = array())
|
||||
public function prepare(array $args = [])
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->query = $this->trimmed('term');
|
||||
@ -87,7 +81,7 @@ class UserautocompleteAction extends Action
|
||||
. ' AND LEFT(LOWER(profile.nickname), '
|
||||
. strlen($this->query)
|
||||
. ') = \'%s\' '
|
||||
. ' LIMIT 0, 10';
|
||||
. ' LIMIT 10';
|
||||
|
||||
$profile->query(sprintf($sql, $this->query));
|
||||
}
|
||||
|
@ -1,35 +1,30 @@
|
||||
<?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 counting greetings
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Data
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 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/>.
|
||||
* @category Data
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2009, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||
|
||||
@ -44,19 +39,17 @@ require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||
* extension of DB_DataObject that provides caching, internationalization,
|
||||
* and other bits of good functionality to StatusNet-specific data classes.
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @category Action
|
||||
* @copyright 2009, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class User_followeveryone_prefs extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'user_followeveryone_prefs'; // table name
|
||||
public $user_id; // int(4) primary_key not_null
|
||||
public $followeveryone; // tinyint(1)
|
||||
public $followeveryone; // bool default_true
|
||||
public $created; // datetime() not_null
|
||||
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
|
||||
|
||||
@ -65,7 +58,7 @@ class User_followeveryone_prefs extends Managed_DataObject
|
||||
return array(
|
||||
'fields' => array(
|
||||
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user id'),
|
||||
'followeveryone' => array('type' => 'int', 'default' => 1, 'size' => 'tiny', 'description' => 'whether to follow everyone'),
|
||||
'followeveryone' => array('type' => 'bool', 'default' => true, 'description' => 'whether to follow everyone'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
|
||||
),
|
||||
@ -76,7 +69,7 @@ class User_followeveryone_prefs extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
static function followEveryone($user_id)
|
||||
public static function followEveryone($user_id)
|
||||
{
|
||||
$ufep = self::getKV('user_id', $user_id);
|
||||
|
||||
@ -87,7 +80,7 @@ class User_followeveryone_prefs extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
static function savePref($user_id, $followEveryone)
|
||||
public static function savePref($user_id, $followEveryone)
|
||||
{
|
||||
$ufep = self::getKV('user_id', $user_id);
|
||||
|
||||
|
@ -62,33 +62,22 @@ class GroupFavoritedAction extends ShowgroupAction
|
||||
$groupId = (int)$this->group->id;
|
||||
$weightexpr = common_sql_weight('fave.modified', common_config('popular', 'dropoff'));
|
||||
$cutoff = sprintf(
|
||||
"fave.modified > '%s'",
|
||||
"fave.modified > TIMESTAMP '%s'",
|
||||
common_sql_date(time() - common_config('popular', 'cutoff'))
|
||||
);
|
||||
|
||||
$qry = 'SELECT notice.*, ' .
|
||||
$weightexpr . ' as weight ' .
|
||||
'FROM notice ' .
|
||||
"JOIN group_inbox ON notice.id = group_inbox.notice_id " .
|
||||
'JOIN fave ON notice.id = fave.notice_id ' .
|
||||
"WHERE $cutoff AND group_id = $groupId " .
|
||||
'GROUP BY id,profile_id,uri,content,rendered,url,created,notice.modified,reply_to,is_local,source,notice.conversation ' .
|
||||
'ORDER BY weight DESC';
|
||||
|
||||
$offset = ($this->page - 1) * NOTICES_PER_PAGE;
|
||||
$limit = NOTICES_PER_PAGE + 1;
|
||||
|
||||
if (common_config('db', 'type') == 'pgsql') {
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
$qry = 'SELECT notice.*, ' . $weightexpr . ' AS weight ' .
|
||||
'FROM notice ' .
|
||||
'INNER JOIN group_inbox ON notice.id = group_inbox.notice_id ' .
|
||||
'INNER JOIN fave ON notice.id = fave.notice_id ' .
|
||||
'WHERE ' . $cutoff . ' AND group_id = ' . $groupId . ' ' .
|
||||
'GROUP BY id, profile_id, uri, content, rendered, url, created, notice.modified, reply_to, is_local, source, notice.conversation ' .
|
||||
'ORDER BY weight DESC LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
|
||||
$notice = Memcached_DataObject::cachedQuery(
|
||||
'Notice',
|
||||
$qry,
|
||||
600
|
||||
);
|
||||
$notice = Memcached_DataObject::cachedQuery('Notice', $qry, 600);
|
||||
|
||||
$nl = new NoticeList($notice, $this);
|
||||
|
||||
|
@ -1,52 +1,37 @@
|
||||
<?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) 2012, StatusNet, Inc.
|
||||
*
|
||||
* ModLogPlugin.php
|
||||
*
|
||||
* 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 Moderation
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2012 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
// This check helps protect against security problems;
|
||||
// your code file can't be executed directly from the web.
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Moderation logging
|
||||
*
|
||||
* Shows a history of moderation for this user in the sidebar
|
||||
*
|
||||
* @category Moderation
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2012 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
class ModLogPlugin extends Plugin
|
||||
{
|
||||
const PLUGIN_VERSION = '2.0.0';
|
||||
@ -63,7 +48,7 @@ class ModLogPlugin extends Plugin
|
||||
* @return boolean hook value; true means continue processing, false means stop.
|
||||
*/
|
||||
|
||||
function onCheckSchema()
|
||||
public function onCheckSchema()
|
||||
{
|
||||
$schema = Schema::get();
|
||||
|
||||
@ -72,7 +57,7 @@ class ModLogPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndGrantRole($profile, $role)
|
||||
public function onEndGrantRole($profile, $role)
|
||||
{
|
||||
$modlog = new ModLog();
|
||||
|
||||
@ -86,7 +71,7 @@ class ModLogPlugin extends Plugin
|
||||
}
|
||||
|
||||
$modlog->role = $role;
|
||||
$modlog->is_grant = 1;
|
||||
$modlog->is_grant = true;
|
||||
$modlog->created = common_sql_now();
|
||||
|
||||
$modlog->insert();
|
||||
@ -94,7 +79,7 @@ class ModLogPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndRevokeRole($profile, $role)
|
||||
public function onEndRevokeRole($profile, $role)
|
||||
{
|
||||
$modlog = new ModLog();
|
||||
|
||||
@ -109,7 +94,7 @@ class ModLogPlugin extends Plugin
|
||||
}
|
||||
|
||||
$modlog->role = $role;
|
||||
$modlog->is_grant = 0;
|
||||
$modlog->is_grant = false;
|
||||
$modlog->created = common_sql_now();
|
||||
|
||||
$modlog->insert();
|
||||
@ -117,7 +102,7 @@ class ModLogPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndShowSections(Action $action)
|
||||
public function onEndShowSections(Action $action)
|
||||
{
|
||||
if (!$action instanceof ShowstreamAction) {
|
||||
// early return for actions we're not interested in
|
||||
@ -140,7 +125,6 @@ class ModLogPlugin extends Plugin
|
||||
$cnt = $ml->find();
|
||||
|
||||
if ($cnt > 0) {
|
||||
|
||||
$action->elementStart('div', array('id' => 'entity_mod_log',
|
||||
'class' => 'section'));
|
||||
|
||||
@ -158,9 +142,14 @@ class ModLogPlugin extends Plugin
|
||||
if (empty($mod)) {
|
||||
$action->text(_('[unknown]'));
|
||||
} else {
|
||||
$action->element('a', array('href' => $mod->getUrl(),
|
||||
'title' => $mod->getFullname()),
|
||||
$mod->getNickname());
|
||||
$action->element(
|
||||
'a',
|
||||
[
|
||||
'href' => $mod->getUrl(),
|
||||
'title' => $mod->getFullname(),
|
||||
],
|
||||
$mod->getNickname()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$action->text(_('[unknown]'));
|
||||
@ -175,7 +164,8 @@ class ModLogPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
function onUserRightsCheck($profile, $right, &$result) {
|
||||
public function onUserRightsCheck($profile, $right, &$result)
|
||||
{
|
||||
switch ($right) {
|
||||
case self::VIEWMODLOG:
|
||||
$result = ($profile->hasRole(Profile_role::MODERATOR) || $profile->hasRole('modhelper'));
|
||||
|
@ -1,49 +1,37 @@
|
||||
<?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) 2012, StatusNet, Inc.
|
||||
*
|
||||
* ModLog.php -- data object to store moderation logs
|
||||
*
|
||||
* 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/>.
|
||||
* Data object to store moderation logs
|
||||
*
|
||||
* @category Moderation
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2012 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Class comment here
|
||||
* @copyright 2012 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @category Category here
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
|
||||
class ModLog extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'mod_log'; // table name
|
||||
@ -52,7 +40,7 @@ class ModLog extends Managed_DataObject
|
||||
public $profile_id; // profile id
|
||||
public $moderator_id; // profile id
|
||||
public $role; // the role
|
||||
public $grant; // 1 = grant, 0 = revoke
|
||||
public $is_grant; // true = grant, false = revoke
|
||||
public $created; // datetime
|
||||
|
||||
/**
|
||||
@ -75,9 +63,8 @@ class ModLog extends Managed_DataObject
|
||||
'length' => 32,
|
||||
'not null' => true,
|
||||
'description' => 'role granted or revoked'),
|
||||
'is_grant' => array('type' => 'int',
|
||||
'size' => 'tiny',
|
||||
'default' => 1,
|
||||
'is_grant' => array('type' => 'bool',
|
||||
'default' => true,
|
||||
'description' => 'Was this a grant or revocation of a role'),
|
||||
'created' => array('type' => 'datetime',
|
||||
'not null' => true,
|
||||
@ -86,7 +73,7 @@ class ModLog extends Managed_DataObject
|
||||
'primary key' => array('id'),
|
||||
'foreign keys' => array(
|
||||
'mod_log_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
|
||||
'mod_log_moderator_id_fkey' => array('user', array('user_id' => 'id'))
|
||||
'mod_log_moderator_id_fkey' => array('user', array('moderator_id' => 'id'))
|
||||
),
|
||||
'indexes' => array(
|
||||
'mod_log_profile_id_created_idx' => array('profile_id', 'created'),
|
||||
|
@ -326,15 +326,18 @@ class Nodeinfo_2_0Action extends Action
|
||||
*/
|
||||
public function getActiveUsers(int $days): int
|
||||
{
|
||||
$userTable = common_database_tablename('user');
|
||||
$query = "
|
||||
SELECT COUNT(DISTINCT profile_id) as active_users_count
|
||||
SELECT COUNT(DISTINCT profile_id) AS active_users_count
|
||||
FROM (
|
||||
SELECT profile_id FROM notice WHERE notice.created >= NOW() - INTERVAL {$days} DAY AND notice.is_local = 1
|
||||
SELECT profile_id FROM notice
|
||||
WHERE notice.created >= (CURRENT_TIMESTAMP - INTERVAL '{$days}' DAY) AND notice.is_local = 1
|
||||
UNION ALL
|
||||
SELECT user_id FROM fave INNER JOIN user ON fave.user_id = user.id WHERE fave.created >= NOW() - INTERVAL {$days} DAY
|
||||
SELECT user_id FROM fave INNER JOIN {$userTable} ON fave.user_id = {$userTable}.id
|
||||
WHERE fave.created >= (CURRENT_TIMESTAMP - INTERVAL '{$days}' DAY)
|
||||
UNION ALL
|
||||
SELECT id FROM user WHERE user.created >= NOW() - INTERVAL {$days} DAY
|
||||
) as source";
|
||||
SELECT id FROM {$userTable} WHERE {$userTable}.created >= (CURRENT_TIMESTAMP - INTERVAL '{$days}' DAY)
|
||||
) AS source";
|
||||
|
||||
$activeUsersCount = new DB_DataObject();
|
||||
$activeUsersCount->query($query);
|
||||
|
@ -1,32 +1,31 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2009-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/>.
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* OStatusPlugin implementation for GNU Social
|
||||
*
|
||||
* Depends on: WebFinger plugin
|
||||
*
|
||||
* @package OStatusPlugin
|
||||
* @maintainer Brion Vibber <brion@status.net>
|
||||
* @package OStatusPlugin
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once __DIR__ . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'util.php';
|
||||
|
||||
@ -43,44 +42,68 @@ class OStatusPlugin extends Plugin
|
||||
public function onRouterInitialized(URLMapper $m)
|
||||
{
|
||||
// Discovery actions
|
||||
$m->connect('main/ostatustag',
|
||||
['action' => 'ostatustag']);
|
||||
$m->connect('main/ostatustag?nickname=:nickname',
|
||||
['action' => 'ostatustag'],
|
||||
['nickname' => '[A-Za-z0-9_-]+']);
|
||||
$m->connect('main/ostatus/group/:group',
|
||||
['action' => 'ostatusinit'],
|
||||
['group' => '[A-Za-z0-9_-]+']);
|
||||
$m->connect('main/ostatus/peopletag/:peopletag/tagger/:tagger',
|
||||
['action' => 'ostatusinit'],
|
||||
['tagger' => '[A-Za-z0-9_-]+',
|
||||
'peopletag' => '[A-Za-z0-9_-]+']);
|
||||
$m->connect('main/ostatus',
|
||||
['action' => 'ostatusinit']);
|
||||
$m->connect(
|
||||
'main/ostatustag',
|
||||
['action' => 'ostatustag']
|
||||
);
|
||||
$m->connect(
|
||||
'main/ostatustag?nickname=:nickname',
|
||||
['action' => 'ostatustag'],
|
||||
['nickname' => '[A-Za-z0-9_-]+']
|
||||
);
|
||||
$m->connect(
|
||||
'main/ostatus/group/:group',
|
||||
['action' => 'ostatusinit'],
|
||||
['group' => '[A-Za-z0-9_-]+']
|
||||
);
|
||||
$m->connect(
|
||||
'main/ostatus/peopletag/:peopletag/tagger/:tagger',
|
||||
['action' => 'ostatusinit'],
|
||||
[
|
||||
'tagger' => '[A-Za-z0-9_-]+',
|
||||
'peopletag' => '[A-Za-z0-9_-]+',
|
||||
]
|
||||
);
|
||||
$m->connect(
|
||||
'main/ostatus',
|
||||
['action' => 'ostatusinit']
|
||||
);
|
||||
|
||||
// Remote subscription actions
|
||||
$m->connect('main/ostatusgroup',
|
||||
['action' => 'ostatusgroup']);
|
||||
$m->connect('main/ostatuspeopletag',
|
||||
['action' => 'ostatuspeopletag']);
|
||||
$m->connect(
|
||||
'main/ostatusgroup',
|
||||
['action' => 'ostatusgroup']
|
||||
);
|
||||
$m->connect(
|
||||
'main/ostatuspeopletag',
|
||||
['action' => 'ostatuspeopletag']
|
||||
);
|
||||
|
||||
// WebSub actions
|
||||
$m->connect('main/push/hub', ['action' => 'pushhub']);
|
||||
|
||||
$m->connect('main/push/callback/:feed',
|
||||
['action' => 'pushcallback'],
|
||||
['feed' => '[0-9]+']);
|
||||
$m->connect(
|
||||
'main/push/callback/:feed',
|
||||
['action' => 'pushcallback'],
|
||||
['feed' => '[0-9]+']
|
||||
);
|
||||
|
||||
// Salmon endpoint
|
||||
$m->connect('main/salmon/user/:id',
|
||||
['action' => 'usersalmon'],
|
||||
['id' => '[0-9]+']);
|
||||
$m->connect('main/salmon/group/:id',
|
||||
['action' => 'groupsalmon'],
|
||||
['id' => '[0-9]+']);
|
||||
$m->connect('main/salmon/peopletag/:id',
|
||||
['action' => 'peopletagsalmon'],
|
||||
['id' => '[0-9]+']);
|
||||
$m->connect(
|
||||
'main/salmon/user/:id',
|
||||
['action' => 'usersalmon'],
|
||||
['id' => '[0-9]+']
|
||||
);
|
||||
$m->connect(
|
||||
'main/salmon/group/:id',
|
||||
['action' => 'groupsalmon'],
|
||||
['id' => '[0-9]+']
|
||||
);
|
||||
$m->connect(
|
||||
'main/salmon/peopletag/:id',
|
||||
['action' => 'peopletagsalmon'],
|
||||
['id' => '[0-9]+']
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -89,7 +112,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param QueueManager $qm
|
||||
* @return boolean hook return
|
||||
*/
|
||||
function onEndInitializeQueueManager(QueueManager $qm)
|
||||
public function onEndInitializeQueueManager(QueueManager $qm)
|
||||
{
|
||||
// Prepare outgoing distributions after notice save.
|
||||
$qm->connect('ostatus', 'OStatusQueueHandler');
|
||||
@ -114,7 +137,7 @@ class OStatusPlugin extends Plugin
|
||||
/**
|
||||
* Put saved notices into the queue for pubsub distribution.
|
||||
*/
|
||||
function onStartEnqueueNotice($notice, &$transports)
|
||||
public function onStartEnqueueNotice($notice, &$transports)
|
||||
{
|
||||
if ($notice->inScope(null) && $notice->getProfile()->hasRight(Right::PUBLICNOTICE)) {
|
||||
$transports[] = 'ostatus';
|
||||
@ -131,7 +154,7 @@ class OStatusPlugin extends Plugin
|
||||
* Set up a WebSub hub link to our internal link for canonical timeline
|
||||
* Atom feeds for users and groups.
|
||||
*/
|
||||
function onStartApiAtom($feed)
|
||||
public function onStartApiAtom($feed)
|
||||
{
|
||||
$id = null;
|
||||
|
||||
@ -140,11 +163,11 @@ class OStatusPlugin extends Plugin
|
||||
$user = $feed->getUser();
|
||||
$id = $user->id;
|
||||
$profile = $user->getProfile();
|
||||
} else if ($feed instanceof AtomGroupNoticeFeed) {
|
||||
} elseif ($feed instanceof AtomGroupNoticeFeed) {
|
||||
$salmonAction = 'groupsalmon';
|
||||
$group = $feed->getGroup();
|
||||
$id = $group->id;
|
||||
} else if ($feed instanceof AtomListNoticeFeed) {
|
||||
} elseif ($feed instanceof AtomListNoticeFeed) {
|
||||
$salmonAction = 'peopletagsalmon';
|
||||
$peopletag = $feed->getList();
|
||||
$id = $peopletag->id;
|
||||
@ -179,25 +202,32 @@ class OStatusPlugin extends Plugin
|
||||
* @param Profile $profile
|
||||
* @return bool hook return value
|
||||
*/
|
||||
function onStartProfileRemoteSubscribe(HTMLOutputter $output, Profile $profile): bool
|
||||
public function onStartProfileRemoteSubscribe(HTMLOutputter $output, Profile $profile): bool
|
||||
{
|
||||
$this->onStartProfileListItemActionElements($output);
|
||||
return true;
|
||||
}
|
||||
|
||||
function onStartGroupSubscribe($widget, $group)
|
||||
public function onStartGroupSubscribe($widget, $group)
|
||||
{
|
||||
$cur = common_current_user();
|
||||
|
||||
if (empty($cur)) {
|
||||
$widget->out->elementStart('li', 'entity_subscribe');
|
||||
|
||||
$url = common_local_url('ostatusinit',
|
||||
array('group' => $group->nickname));
|
||||
$widget->out->element('a', array('href' => $url,
|
||||
'class' => 'entity_remote_subscribe'),
|
||||
// TRANS: Link to subscribe to a remote entity.
|
||||
_m('Subscribe'));
|
||||
$url = common_local_url(
|
||||
'ostatusinit',
|
||||
['group' => $group->nickname]
|
||||
);
|
||||
$widget->out->element(
|
||||
'a',
|
||||
[
|
||||
'href' => $url,
|
||||
'class' => 'entity_remote_subscribe',
|
||||
],
|
||||
// TRANS: Link to subscribe to a remote entity.
|
||||
_m('Subscribe')
|
||||
);
|
||||
|
||||
$widget->out->elementEnd('li');
|
||||
return false;
|
||||
@ -206,19 +236,26 @@ class OStatusPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
function onStartSubscribePeopletagForm($output, $peopletag)
|
||||
public function onStartSubscribePeopletagForm($output, $peopletag)
|
||||
{
|
||||
$cur = common_current_user();
|
||||
|
||||
if (empty($cur)) {
|
||||
$output->elementStart('li', 'entity_subscribe');
|
||||
$profile = $peopletag->getTagger();
|
||||
$url = common_local_url('ostatusinit',
|
||||
array('tagger' => $profile->nickname, 'peopletag' => $peopletag->tag));
|
||||
$output->element('a', array('href' => $url,
|
||||
'class' => 'entity_remote_subscribe'),
|
||||
// TRANS: Link to subscribe to a remote entity.
|
||||
_m('Subscribe'));
|
||||
$url = common_local_url(
|
||||
'ostatusinit',
|
||||
['tagger' => $profile->nickname, 'peopletag' => $peopletag->tag]
|
||||
);
|
||||
$output->element(
|
||||
'a',
|
||||
[
|
||||
'href' => $url,
|
||||
'class' => 'entity_remote_subscribe',
|
||||
],
|
||||
// TRANS: Link to subscribe to a remote entity.
|
||||
_m('Subscribe')
|
||||
);
|
||||
|
||||
$output->elementEnd('li');
|
||||
return false;
|
||||
@ -230,10 +267,11 @@ class OStatusPlugin extends Plugin
|
||||
/*
|
||||
* If the field being looked for is URI look for the profile
|
||||
*/
|
||||
function onStartProfileCompletionSearch($action, $profile, $search_engine) {
|
||||
public function onStartProfileCompletionSearch($action, $profile, $search_engine)
|
||||
{
|
||||
if ($action->field == 'uri') {
|
||||
$profile->joinAdd(array('id', 'user:id'));
|
||||
$profile->whereAdd('uri LIKE "%' . $profile->escape($q) . '%"');
|
||||
$profile->joinAdd(['id', 'user:id']);
|
||||
$profile->whereAdd("uri LIKE '%" . $profile->escape($q) . "%'");
|
||||
$profile->query();
|
||||
|
||||
$validate = new Validate();
|
||||
@ -242,17 +280,16 @@ class OStatusPlugin extends Plugin
|
||||
try {
|
||||
if ($validate->email($q)) {
|
||||
$oprofile = Ostatus_profile::ensureWebfinger($q);
|
||||
} else if ($validate->uri($q)) {
|
||||
} elseif ($validate->uri($q)) {
|
||||
$oprofile = Ostatus_profile::ensureProfileURL($q);
|
||||
} else {
|
||||
// TRANS: Exception in OStatus when invalid URI was entered.
|
||||
throw new Exception(_m('Invalid URI.'));
|
||||
}
|
||||
return $this->filter(array($oprofile->localProfile()));
|
||||
|
||||
} catch (Exception $e) {
|
||||
// TRANS: Error message in OStatus plugin. Do not translate the domain names example.com
|
||||
// TRANS: and example.net, as these are official standard domain names for use in examples.
|
||||
// TRANS: Error message in OStatus plugin. Do not translate the domain names example.com
|
||||
// TRANS: and example.net, as these are official standard domain names for use in examples.
|
||||
$this->msg = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname.");
|
||||
return array();
|
||||
}
|
||||
@ -269,13 +306,15 @@ class OStatusPlugin extends Plugin
|
||||
*
|
||||
* @return array The matching IDs (without $preMention) and each respective position in the given string.
|
||||
*/
|
||||
static function extractWebfingerIds($text, $preMention='@')
|
||||
public static function extractWebfingerIds($text, $preMention = '@')
|
||||
{
|
||||
$wmatches = array();
|
||||
$result = preg_match_all('/(?<!\S)'.preg_quote($preMention, '/').'('.Nickname::WEBFINGER_FMT.')/',
|
||||
$text,
|
||||
$wmatches,
|
||||
PREG_OFFSET_CAPTURE);
|
||||
$result = preg_match_all(
|
||||
'/(?<!\S)' . preg_quote($preMention, '/') . '(' . Nickname::WEBFINGER_FMT . ')/',
|
||||
$text,
|
||||
$wmatches,
|
||||
PREG_OFFSET_CAPTURE
|
||||
);
|
||||
if ($result === false) {
|
||||
common_log(LOG_ERR, __METHOD__ . ': Error parsing webfinger IDs from text (preg_last_error=='.preg_last_error().').');
|
||||
return [];
|
||||
@ -292,15 +331,17 @@ class OStatusPlugin extends Plugin
|
||||
*
|
||||
* @return array The matching URLs (without @ or acct:) and each respective position in the given string.
|
||||
*/
|
||||
static function extractUrlMentions($text, $preMention='@')
|
||||
public static function extractUrlMentions($text, $preMention = '@')
|
||||
{
|
||||
$wmatches = array();
|
||||
// In the regexp below we need to match / _before_ URL_REGEX_VALID_PATH_CHARS because it otherwise gets merged
|
||||
// with the TLD before (but / is in URL_REGEX_VALID_PATH_CHARS anyway, it's just its positioning that is important)
|
||||
$result = preg_match_all('/(?:^|\s+)'.preg_quote($preMention, '/').'('.URL_REGEX_DOMAIN_NAME.'(?:\/['.URL_REGEX_VALID_PATH_CHARS.']*)*)/',
|
||||
$text,
|
||||
$wmatches,
|
||||
PREG_OFFSET_CAPTURE);
|
||||
$result = preg_match_all(
|
||||
'/(?:^|\s+)' . preg_quote($preMention, '/') . '(' . URL_REGEX_DOMAIN_NAME . '(?:\/[' . URL_REGEX_VALID_PATH_CHARS . ']*)*)/',
|
||||
$text,
|
||||
$wmatches,
|
||||
PREG_OFFSET_CAPTURE
|
||||
);
|
||||
if ($result === false) {
|
||||
common_log(LOG_ERR, __METHOD__ . ': Error parsing profile URL mentions from text (preg_last_error=='.preg_last_error().').');
|
||||
return [];
|
||||
@ -319,7 +360,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param array &$mention in/out param: set of found mentions
|
||||
* @return boolean hook return value
|
||||
*/
|
||||
function onEndFindMentions(Profile $sender, $text, &$mentions)
|
||||
public function onEndFindMentions(Profile $sender, $text, &$mentions)
|
||||
{
|
||||
$matches = array();
|
||||
|
||||
@ -472,7 +513,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param Profile &$profile
|
||||
* @return hook return code
|
||||
*/
|
||||
function onStartCommandGetProfile($command, $arg, &$profile)
|
||||
public function onStartCommandGetProfile($command, $arg, &$profile)
|
||||
{
|
||||
$oprofile = $this->pullRemoteProfile($arg);
|
||||
if ($oprofile instanceof Ostatus_profile && !$oprofile->isGroup()) {
|
||||
@ -499,7 +540,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param User_group &$group
|
||||
* @return hook return code
|
||||
*/
|
||||
function onStartCommandGetGroup($command, $arg, &$group)
|
||||
public function onStartCommandGetGroup($command, $arg, &$group)
|
||||
{
|
||||
$oprofile = $this->pullRemoteProfile($arg);
|
||||
if ($oprofile instanceof Ostatus_profile && $oprofile->isGroup()) {
|
||||
@ -546,21 +587,24 @@ class OStatusPlugin extends Plugin
|
||||
return null;
|
||||
}
|
||||
|
||||
function onEndProfileSettingsActions($out) {
|
||||
public function onEndProfileSettingsActions($out) {
|
||||
$siteName = common_config('site', 'name');
|
||||
$js = 'navigator.registerContentHandler("application/vnd.mozilla.maybe.feed", "'.addslashes(common_local_url('RemoteFollowSub', null, array('profile' => '%s'))).'", "'.addslashes($siteName).'")';
|
||||
$out->elementStart('li');
|
||||
$out->element('a',
|
||||
array('href' => 'javascript:'.$js),
|
||||
// TRANS: Option in profile settings to add this instance to Firefox as a feedreader
|
||||
_('Add to Firefox as feedreader'));
|
||||
$out->element(
|
||||
'a',
|
||||
['href' => 'javascript:' . $js],
|
||||
// TRANS: Option in profile settings to add this instance to Firefox as a feedreader
|
||||
_('Add to Firefox as feedreader')
|
||||
);
|
||||
$out->elementEnd('li');
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure necessary tables are filled out.
|
||||
*/
|
||||
function onCheckSchema() {
|
||||
public function onCheckSchema()
|
||||
{
|
||||
$schema = Schema::get();
|
||||
$schema->ensureTable('ostatus_profile', Ostatus_profile::schemaDef());
|
||||
$schema->ensureTable('feedsub', FeedSub::schemaDef());
|
||||
@ -569,12 +613,14 @@ class OStatusPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEndShowStylesheets(Action $action) {
|
||||
public function onEndShowStylesheets(Action $action)
|
||||
{
|
||||
$action->cssLink($this->path('theme/base/css/ostatus.css'));
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndShowStatusNetScripts($action) {
|
||||
public function onEndShowStatusNetScripts($action)
|
||||
{
|
||||
$action->script($this->path('js/ostatus.js'));
|
||||
return true;
|
||||
}
|
||||
@ -589,7 +635,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param string out &$title
|
||||
* @return mixed hook return code
|
||||
*/
|
||||
function onStartNoticeSourceLink($notice, &$name, &$url, &$title)
|
||||
public function onStartNoticeSourceLink($notice, &$name, &$url, &$title)
|
||||
{
|
||||
// If we don't handle this, keep the event handler going
|
||||
if (!in_array($notice->source, array('ostatus', 'share'))) {
|
||||
@ -626,7 +672,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param DOMDocument $feed
|
||||
* @return mixed hook return code
|
||||
*/
|
||||
function onStartFeedSubReceive($feedsub, $feed)
|
||||
public function onStartFeedSubReceive($feedsub, $feed)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('feeduri', $feedsub->uri);
|
||||
if ($oprofile instanceof Ostatus_profile) {
|
||||
@ -645,7 +691,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param integer $count in/out
|
||||
* @return mixed hook return code
|
||||
*/
|
||||
function onFeedSubSubscriberCount($feedsub, &$count)
|
||||
public function onFeedSubSubscriberCount($feedsub, &$count)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('feeduri', $feedsub->uri);
|
||||
if ($oprofile instanceof Ostatus_profile) {
|
||||
@ -668,7 +714,7 @@ class OStatusPlugin extends Plugin
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
function onStartSubscribe(Profile $profile, Profile $other)
|
||||
public function onStartSubscribe(Profile $profile, Profile $other)
|
||||
{
|
||||
if (!$profile->isLocal()) {
|
||||
return true;
|
||||
@ -693,7 +739,7 @@ class OStatusPlugin extends Plugin
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
function onEndSubscribe(Profile $profile, Profile $other)
|
||||
public function onEndSubscribe(Profile $profile, Profile $other)
|
||||
{
|
||||
if (!$profile->isLocal()) {
|
||||
return true;
|
||||
@ -722,7 +768,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param Profile $other
|
||||
* @return hook return value
|
||||
*/
|
||||
function onEndUnsubscribe(Profile $profile, Profile $other)
|
||||
public function onEndUnsubscribe(Profile $profile, Profile $other)
|
||||
{
|
||||
if (!$profile->isLocal()) {
|
||||
return true;
|
||||
@ -740,19 +786,23 @@ class OStatusPlugin extends Plugin
|
||||
|
||||
$act->verb = ActivityVerb::UNFOLLOW;
|
||||
|
||||
$act->id = TagURI::mint('unfollow:%d:%d:%s',
|
||||
$profile->id,
|
||||
$other->id,
|
||||
common_date_iso8601(time()));
|
||||
$act->id = TagURI::mint(
|
||||
'unfollow:%d:%d:%s',
|
||||
$profile->id,
|
||||
$other->id,
|
||||
common_date_iso8601(time())
|
||||
);
|
||||
|
||||
$act->time = time();
|
||||
// TRANS: Title for unfollowing a remote profile.
|
||||
$act->title = _m('TITLE','Unfollow');
|
||||
$act->title = _m('TITLE', 'Unfollow');
|
||||
// TRANS: Success message for unsubscribe from user attempt through OStatus.
|
||||
// TRANS: %1$s is the unsubscriber's name, %2$s is the unsubscribed user's name.
|
||||
$act->content = sprintf(_m('%1$s stopped following %2$s.'),
|
||||
$profile->getBestName(),
|
||||
$other->getBestName());
|
||||
$act->content = sprintf(
|
||||
_m('%1$s stopped following %2$s.'),
|
||||
$profile->getBestName(),
|
||||
$other->getBestName()
|
||||
);
|
||||
|
||||
$act->actor = $profile->asActivityObject();
|
||||
$act->objects[] = $other->asActivityObject();
|
||||
@ -773,7 +823,7 @@ class OStatusPlugin extends Plugin
|
||||
* @return mixed hook return value
|
||||
* @throws Exception of various kinds, some from $oprofile->subscribe();
|
||||
*/
|
||||
function onStartJoinGroup($group, $profile)
|
||||
public function onStartJoinGroup($group, $profile)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('group_id', $group->id);
|
||||
if (!$oprofile instanceof Ostatus_profile) {
|
||||
@ -786,10 +836,12 @@ class OStatusPlugin extends Plugin
|
||||
// has not yet been created.
|
||||
|
||||
$act = new Activity();
|
||||
$act->id = TagURI::mint('join:%d:%d:%s',
|
||||
$profile->id,
|
||||
$group->id,
|
||||
common_date_iso8601(time()));
|
||||
$act->id = TagURI::mint(
|
||||
'join:%d:%d:%s',
|
||||
$profile->id,
|
||||
$group->id,
|
||||
common_date_iso8601(time())
|
||||
);
|
||||
|
||||
$act->actor = $profile->asActivityObject();
|
||||
$act->verb = ActivityVerb::JOIN;
|
||||
@ -797,12 +849,14 @@ class OStatusPlugin extends Plugin
|
||||
|
||||
$act->time = time();
|
||||
// TRANS: Title for joining a remote groep.
|
||||
$act->title = _m('TITLE','Join');
|
||||
$act->title = _m('TITLE', 'Join');
|
||||
// TRANS: Success message for subscribe to group attempt through OStatus.
|
||||
// TRANS: %1$s is the member name, %2$s is the subscribed group's name.
|
||||
$act->content = sprintf(_m('%1$s has joined group %2$s.'),
|
||||
$profile->getBestName(),
|
||||
$oprofile->getBestName());
|
||||
$act->content = sprintf(
|
||||
_m('%1$s has joined group %2$s.'),
|
||||
$profile->getBestName(),
|
||||
$oprofile->getBestName()
|
||||
);
|
||||
|
||||
if ($oprofile->notifyActivity($act, $profile)) {
|
||||
return true;
|
||||
@ -827,7 +881,7 @@ class OStatusPlugin extends Plugin
|
||||
*
|
||||
* @return mixed hook return value
|
||||
*/
|
||||
function onEndLeaveGroup($group, $profile)
|
||||
public function onEndLeaveGroup($group, $profile)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('group_id', $group->id);
|
||||
if (!$oprofile instanceof Ostatus_profile) {
|
||||
@ -840,10 +894,12 @@ class OStatusPlugin extends Plugin
|
||||
$member = $profile;
|
||||
|
||||
$act = new Activity();
|
||||
$act->id = TagURI::mint('leave:%d:%d:%s',
|
||||
$member->id,
|
||||
$group->id,
|
||||
common_date_iso8601(time()));
|
||||
$act->id = TagURI::mint(
|
||||
'leave:%d:%d:%s',
|
||||
$member->id,
|
||||
$group->id,
|
||||
common_date_iso8601(time())
|
||||
);
|
||||
|
||||
$act->actor = $member->asActivityObject();
|
||||
$act->verb = ActivityVerb::LEAVE;
|
||||
@ -851,12 +907,14 @@ class OStatusPlugin extends Plugin
|
||||
|
||||
$act->time = time();
|
||||
// TRANS: Title for leaving a remote group.
|
||||
$act->title = _m('TITLE','Leave');
|
||||
$act->title = _m('TITLE', 'Leave');
|
||||
// TRANS: Success message for unsubscribe from group attempt through OStatus.
|
||||
// TRANS: %1$s is the member name, %2$s is the unsubscribed group's name.
|
||||
$act->content = sprintf(_m('%1$s has left group %2$s.'),
|
||||
$member->getBestName(),
|
||||
$oprofile->getBestName());
|
||||
$act->content = sprintf(
|
||||
_m('%1$s has left group %2$s.'),
|
||||
$member->getBestName(),
|
||||
$oprofile->getBestName()
|
||||
);
|
||||
|
||||
$oprofile->notifyActivity($act, $member);
|
||||
}
|
||||
@ -873,7 +931,7 @@ class OStatusPlugin extends Plugin
|
||||
* @throws Exception of various kinds, some from $oprofile->subscribe();
|
||||
*/
|
||||
|
||||
function onStartSubscribePeopletag($peopletag, $user)
|
||||
public function onStartSubscribePeopletag($peopletag, $user)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('peopletag_id', $peopletag->id);
|
||||
if (!$oprofile instanceof Ostatus_profile) {
|
||||
@ -886,10 +944,12 @@ class OStatusPlugin extends Plugin
|
||||
$tagger = Profile::getKV($peopletag->tagger);
|
||||
|
||||
$act = new Activity();
|
||||
$act->id = TagURI::mint('subscribe_peopletag:%d:%d:%s',
|
||||
$sub->id,
|
||||
$peopletag->id,
|
||||
common_date_iso8601(time()));
|
||||
$act->id = TagURI::mint(
|
||||
'subscribe_peopletag:%d:%d:%s',
|
||||
$sub->id,
|
||||
$peopletag->id,
|
||||
common_date_iso8601(time())
|
||||
);
|
||||
|
||||
$act->actor = $sub->asActivityObject();
|
||||
$act->verb = ActivityVerb::FOLLOW;
|
||||
@ -897,13 +957,15 @@ class OStatusPlugin extends Plugin
|
||||
|
||||
$act->time = time();
|
||||
// TRANS: Title for following a remote list.
|
||||
$act->title = _m('TITLE','Follow list');
|
||||
$act->title = _m('TITLE', 'Follow list');
|
||||
// TRANS: Success message for remote list follow through OStatus.
|
||||
// TRANS: %1$s is the subscriber name, %2$s is the list, %3$s is the lister's name.
|
||||
$act->content = sprintf(_m('%1$s is now following people listed in %2$s by %3$s.'),
|
||||
$sub->getBestName(),
|
||||
$oprofile->getBestName(),
|
||||
$tagger->getBestName());
|
||||
$act->content = sprintf(
|
||||
_m('%1$s is now following people listed in %2$s by %3$s.'),
|
||||
$sub->getBestName(),
|
||||
$oprofile->getBestName(),
|
||||
$tagger->getBestName()
|
||||
);
|
||||
|
||||
if ($oprofile->notifyActivity($act, $sub)) {
|
||||
return true;
|
||||
@ -924,7 +986,7 @@ class OStatusPlugin extends Plugin
|
||||
* @return mixed hook return value
|
||||
*/
|
||||
|
||||
function onEndUnsubscribePeopletag($peopletag, $user)
|
||||
public function onEndUnsubscribePeopletag($peopletag, $user)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('peopletag_id', $peopletag->id);
|
||||
if (!$oprofile instanceof Ostatus_profile) {
|
||||
@ -938,10 +1000,12 @@ class OStatusPlugin extends Plugin
|
||||
$tagger = Profile::getKV($peopletag->tagger);
|
||||
|
||||
$act = new Activity();
|
||||
$act->id = TagURI::mint('unsubscribe_peopletag:%d:%d:%s',
|
||||
$sub->id,
|
||||
$peopletag->id,
|
||||
common_date_iso8601(time()));
|
||||
$act->id = TagURI::mint(
|
||||
'unsubscribe_peopletag:%d:%d:%s',
|
||||
$sub->id,
|
||||
$peopletag->id,
|
||||
common_date_iso8601(time())
|
||||
);
|
||||
|
||||
$act->actor = $member->asActivityObject();
|
||||
$act->verb = ActivityVerb::UNFOLLOW;
|
||||
@ -952,10 +1016,12 @@ class OStatusPlugin extends Plugin
|
||||
$act->title = _m('Unfollow list');
|
||||
// TRANS: Success message for remote list unfollow through OStatus.
|
||||
// TRANS: %1$s is the subscriber name, %2$s is the list, %3$s is the lister's name.
|
||||
$act->content = sprintf(_m('%1$s stopped following the list %2$s by %3$s.'),
|
||||
$sub->getBestName(),
|
||||
$oprofile->getBestName(),
|
||||
$tagger->getBestName());
|
||||
$act->content = sprintf(
|
||||
_m('%1$s stopped following the list %2$s by %3$s.'),
|
||||
$sub->getBestName(),
|
||||
$oprofile->getBestName(),
|
||||
$tagger->getBestName()
|
||||
);
|
||||
|
||||
$oprofile->notifyActivity($act, $user);
|
||||
}
|
||||
@ -967,7 +1033,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param Notice $notice being favored
|
||||
* @return hook return value
|
||||
*/
|
||||
function onEndFavorNotice(Profile $profile, Notice $notice)
|
||||
public function onEndFavorNotice(Profile $profile, Notice $notice)
|
||||
{
|
||||
// Only distribute local users' favor actions, remote users
|
||||
// will have already distributed theirs.
|
||||
@ -1005,7 +1071,7 @@ class OStatusPlugin extends Plugin
|
||||
* @return hook return value
|
||||
* @throws Exception of various kinds, some from $oprofile->subscribe();
|
||||
*/
|
||||
function onEndTagProfile($ptag)
|
||||
public function onEndTagProfile($ptag)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('profile_id', $ptag->tagged);
|
||||
if (!$oprofile instanceof Ostatus_profile) {
|
||||
@ -1023,18 +1089,23 @@ class OStatusPlugin extends Plugin
|
||||
$tagged = Profile::getKV('id', $ptag->tagged);
|
||||
|
||||
$act->verb = ActivityVerb::TAG;
|
||||
$act->id = TagURI::mint('tag_profile:%d:%d:%s',
|
||||
$plist->tagger, $plist->id,
|
||||
common_date_iso8601(time()));
|
||||
$act->id = TagURI::mint(
|
||||
'tag_profile:%d:%d:%s',
|
||||
$plist->tagger,
|
||||
$plist->id,
|
||||
common_date_iso8601(time())
|
||||
);
|
||||
$act->time = time();
|
||||
// TRANS: Title for listing a remote profile.
|
||||
$act->title = _m('TITLE','List');
|
||||
$act->title = _m('TITLE', 'List');
|
||||
// TRANS: Success message for remote list addition through OStatus.
|
||||
// TRANS: %1$s is the list creator's name, %2$s is the added list member, %3$s is the list name.
|
||||
$act->content = sprintf(_m('%1$s listed %2$s in the list %3$s.'),
|
||||
$tagger->getBestName(),
|
||||
$tagged->getBestName(),
|
||||
$plist->getBestName());
|
||||
$act->content = sprintf(
|
||||
_m('%1$s listed %2$s in the list %3$s.'),
|
||||
$tagger->getBestName(),
|
||||
$tagged->getBestName(),
|
||||
$plist->getBestName()
|
||||
);
|
||||
|
||||
$act->actor = $tagger->asActivityObject();
|
||||
$act->objects = array($tagged->asActivityObject());
|
||||
@ -1056,7 +1127,7 @@ class OStatusPlugin extends Plugin
|
||||
* @param Profile_tag $ptag the people tag that was deleted
|
||||
* @return hook return value
|
||||
*/
|
||||
function onEndUntagProfile($ptag)
|
||||
public function onEndUntagProfile($ptag)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('profile_id', $ptag->tagged);
|
||||
if (!$oprofile instanceof Ostatus_profile) {
|
||||
@ -1074,18 +1145,23 @@ class OStatusPlugin extends Plugin
|
||||
$tagged = Profile::getKV('id', $ptag->tagged);
|
||||
|
||||
$act->verb = ActivityVerb::UNTAG;
|
||||
$act->id = TagURI::mint('untag_profile:%d:%d:%s',
|
||||
$plist->tagger, $plist->id,
|
||||
common_date_iso8601(time()));
|
||||
$act->id = TagURI::mint(
|
||||
'untag_profile:%d:%d:%s',
|
||||
$plist->tagger,
|
||||
$plist->id,
|
||||
common_date_iso8601(time())
|
||||
);
|
||||
$act->time = time();
|
||||
// TRANS: Title for unlisting a remote profile.
|
||||
$act->title = _m('TITLE','Unlist');
|
||||
$act->title = _m('TITLE', 'Unlist');
|
||||
// TRANS: Success message for remote list removal through OStatus.
|
||||
// TRANS: %1$s is the list creator's name, %2$s is the removed list member, %3$s is the list name.
|
||||
$act->content = sprintf(_m('%1$s removed %2$s from the list %3$s.'),
|
||||
$tagger->getBestName(),
|
||||
$tagged->getBestName(),
|
||||
$plist->getBestName());
|
||||
$act->content = sprintf(
|
||||
_m('%1$s removed %2$s from the list %3$s.'),
|
||||
$tagger->getBestName(),
|
||||
$tagged->getBestName(),
|
||||
$plist->getBestName()
|
||||
);
|
||||
|
||||
$act->actor = $tagger->asActivityObject();
|
||||
$act->objects = array($tagged->asActivityObject());
|
||||
@ -1107,7 +1183,7 @@ class OStatusPlugin extends Plugin
|
||||
*
|
||||
* @return hook return value
|
||||
*/
|
||||
function onEndDisfavorNotice(Profile $profile, Notice $notice)
|
||||
public function onEndDisfavorNotice(Profile $profile, Notice $notice)
|
||||
{
|
||||
// Only distribute local users' disfavor actions, remote users
|
||||
// will have already distributed theirs.
|
||||
@ -1123,18 +1199,22 @@ class OStatusPlugin extends Plugin
|
||||
$act = new Activity();
|
||||
|
||||
$act->verb = ActivityVerb::UNFAVORITE;
|
||||
$act->id = TagURI::mint('disfavor:%d:%d:%s',
|
||||
$profile->id,
|
||||
$notice->id,
|
||||
common_date_iso8601(time()));
|
||||
$act->id = TagURI::mint(
|
||||
'disfavor:%d:%d:%s',
|
||||
$profile->id,
|
||||
$notice->id,
|
||||
common_date_iso8601(time())
|
||||
);
|
||||
$act->time = time();
|
||||
// TRANS: Title for unliking a remote notice.
|
||||
$act->title = _m('Unlike');
|
||||
// TRANS: Success message for remove a favorite notice through OStatus.
|
||||
// TRANS: %1$s is the unfavoring user's name, %2$s is URI to the no longer favored notice.
|
||||
$act->content = sprintf(_m('%1$s no longer likes %2$s.'),
|
||||
$profile->getBestName(),
|
||||
$notice->getUrl());
|
||||
$act->content = sprintf(
|
||||
_m('%1$s no longer likes %2$s.'),
|
||||
$profile->getBestName(),
|
||||
$notice->getUrl()
|
||||
);
|
||||
|
||||
$act->actor = $profile->asActivityObject();
|
||||
$act->objects[] = $notice->asActivityObject();
|
||||
@ -1144,7 +1224,7 @@ class OStatusPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
function onStartGetProfileUri($profile, &$uri)
|
||||
public function onStartGetProfileUri($profile, &$uri)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('profile_id', $profile->id);
|
||||
if ($oprofile instanceof Ostatus_profile) {
|
||||
@ -1154,12 +1234,12 @@ class OStatusPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
function onStartUserGroupHomeUrl($group, &$url)
|
||||
public function onStartUserGroupHomeUrl($group, &$url)
|
||||
{
|
||||
return $this->onStartUserGroupPermalink($group, $url);
|
||||
}
|
||||
|
||||
function onStartUserGroupPermalink($group, &$url)
|
||||
public function onStartUserGroupPermalink($group, &$url)
|
||||
{
|
||||
$oprofile = Ostatus_profile::getKV('group_id', $group->id);
|
||||
if ($oprofile instanceof Ostatus_profile) {
|
||||
@ -1170,21 +1250,21 @@ class OStatusPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
function onStartShowUserGroupsContent($action)
|
||||
public function onStartShowUserGroupsContent($action)
|
||||
{
|
||||
$this->showEntityRemoteSubscribe($action);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndShowGroupsMiniList($action)
|
||||
public function onEndShowGroupsMiniList($action)
|
||||
{
|
||||
$this->showEntityRemoteSubscribe($action);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function showEntityRemoteSubscribe($action)
|
||||
public function showEntityRemoteSubscribe($action)
|
||||
{
|
||||
if (!$action->getScoped() instanceof Profile) {
|
||||
// early return if we're not logged in
|
||||
@ -1195,10 +1275,15 @@ class OStatusPlugin extends Plugin
|
||||
$action->elementStart('div', 'entity_actions');
|
||||
$action->elementStart('p', array('id' => 'entity_remote_subscribe',
|
||||
'class' => 'entity_subscribe'));
|
||||
$action->element('a', array('href' => common_local_url('ostatusgroup'),
|
||||
'class' => 'entity_remote_subscribe'),
|
||||
// TRANS: Link text for link to remote subscribe.
|
||||
_m('Remote'));
|
||||
$action->element(
|
||||
'a',
|
||||
[
|
||||
'href' => common_local_url('ostatusgroup'),
|
||||
'class' => 'entity_remote_subscribe',
|
||||
],
|
||||
// TRANS: Link text for link to remote subscribe.
|
||||
_m('Remote')
|
||||
);
|
||||
$action->elementEnd('p');
|
||||
$action->elementEnd('div');
|
||||
}
|
||||
@ -1208,7 +1293,7 @@ class OStatusPlugin extends Plugin
|
||||
* Ping remote profiles with updates to this profile.
|
||||
* Salmon pings are queued for background processing.
|
||||
*/
|
||||
function onEndBroadcastProfile(Profile $profile)
|
||||
public function onEndBroadcastProfile(Profile $profile)
|
||||
{
|
||||
$user = User::getKV('id', $profile->id);
|
||||
|
||||
@ -1233,16 +1318,20 @@ class OStatusPlugin extends Plugin
|
||||
$act = new Activity();
|
||||
|
||||
$act->verb = ActivityVerb::UPDATE_PROFILE;
|
||||
$act->id = TagURI::mint('update-profile:%d:%s',
|
||||
$profile->id,
|
||||
common_date_iso8601(time()));
|
||||
$act->id = TagURI::mint(
|
||||
'update-profile:%d:%s',
|
||||
$profile->id,
|
||||
common_date_iso8601(time())
|
||||
);
|
||||
$act->time = time();
|
||||
// TRANS: Title for activity.
|
||||
$act->title = _m('Profile update');
|
||||
// TRANS: Ping text for remote profile update through OStatus.
|
||||
// TRANS: %s is user that updated their profile.
|
||||
$act->content = sprintf(_m('%s has updated their profile page.'),
|
||||
$profile->getBestName());
|
||||
$act->content = sprintf(
|
||||
_m('%s has updated their profile page.'),
|
||||
$profile->getBestName()
|
||||
);
|
||||
|
||||
$act->actor = $profile->asActivityObject();
|
||||
$act->objects[] = $act->actor;
|
||||
@ -1254,7 +1343,7 @@ class OStatusPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndShowAccountProfileBlock(HTMLOutputter $out, Profile $profile)
|
||||
public function onEndShowAccountProfileBlock(HTMLOutputter $out, Profile $profile)
|
||||
{
|
||||
if ($profile->isLocal()) {
|
||||
return true;
|
||||
@ -1288,7 +1377,7 @@ class OStatusPlugin extends Plugin
|
||||
}
|
||||
|
||||
// FIXME: This one can accept both an Action and a Widget. Confusing! Refactor to (HTMLOutputter $out, Profile $target)!
|
||||
function onStartProfileListItemActionElements($item)
|
||||
public function onStartProfileListItemActionElements($item)
|
||||
{
|
||||
if (common_logged_in()) {
|
||||
// only non-logged in users get to see the "remote subscribe" form
|
||||
@ -1314,8 +1403,10 @@ class OStatusPlugin extends Plugin
|
||||
$output->elementStart('li', 'entity_tag');
|
||||
$url = common_local_url('ostatustag', ['nickname' => $target->getNickname()]);
|
||||
$output->element('a',
|
||||
['href' => $url,
|
||||
'class' => 'entity_remote_tag'],
|
||||
[
|
||||
'href' => $url,
|
||||
'class' => 'entity_remote_tag',
|
||||
],
|
||||
// TRANS: Link text for a user to list an OStatus user.
|
||||
_m('List'));
|
||||
$output->elementEnd('li');
|
||||
@ -1388,7 +1479,7 @@ class OStatusPlugin extends Plugin
|
||||
return false;
|
||||
}
|
||||
|
||||
function onStartGetProfileFromURI($uri, &$profile)
|
||||
public function onStartGetProfileFromURI($uri, &$profile)
|
||||
{
|
||||
// Don't want to do Web-based discovery on our own server,
|
||||
// so we check locally first. This duplicates the functionality
|
||||
@ -1417,7 +1508,7 @@ class OStatusPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
function onEndWebFingerNoticeLinks(XML_XRD $xrd, Notice $target)
|
||||
public function onEndWebFingerNoticeLinks(XML_XRD $xrd, Notice $target)
|
||||
{
|
||||
$salmon_url = null;
|
||||
$actor = $target->getProfile();
|
||||
@ -1439,16 +1530,19 @@ class OStatusPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndWebFingerProfileLinks(XML_XRD $xrd, Profile $target)
|
||||
public function onEndWebFingerProfileLinks(XML_XRD $xrd, Profile $target)
|
||||
{
|
||||
if ($target->getObjectType() === ActivityObject::PERSON) {
|
||||
$this->addWebFingerPersonLinks($xrd, $target);
|
||||
} elseif ($target->getObjectType() === ActivityObject::GROUP) {
|
||||
$xrd->links[] = new XML_XRD_Element_Link(Discovery::UPDATESFROM,
|
||||
common_local_url('ApiTimelineGroup',
|
||||
array('id' => $target->getGroup()->getID(), 'format' => 'atom')),
|
||||
'application/atom+xml');
|
||||
|
||||
$xrd->links[] = new XML_XRD_Element_Link(
|
||||
Discovery::UPDATESFROM,
|
||||
common_local_url(
|
||||
'ApiTimelineGroup',
|
||||
['id' => $target->getGroup()->getID(), 'format' => 'atom']
|
||||
),
|
||||
'application/atom+xml'
|
||||
);
|
||||
}
|
||||
|
||||
// Salmon
|
||||
@ -1479,10 +1573,14 @@ class OStatusPlugin extends Plugin
|
||||
|
||||
protected function addWebFingerPersonLinks(XML_XRD $xrd, Profile $target)
|
||||
{
|
||||
$xrd->links[] = new XML_XRD_Element_Link(Discovery::UPDATESFROM,
|
||||
common_local_url('ApiTimelineUser',
|
||||
array('id' => $target->id, 'format' => 'atom')),
|
||||
'application/atom+xml');
|
||||
$xrd->links[] = new XML_XRD_Element_Link(
|
||||
Discovery::UPDATESFROM,
|
||||
common_local_url(
|
||||
'ApiTimelineUser',
|
||||
['id' => $target->id, 'format' => 'atom']
|
||||
),
|
||||
'application/atom+xml'
|
||||
);
|
||||
|
||||
// Get this profile's keypair
|
||||
$magicsig = Magicsig::getKV('user_id', $target->id);
|
||||
@ -1494,8 +1592,10 @@ class OStatusPlugin extends Plugin
|
||||
return false; // value doesn't mean anything, just figured I'd indicate this function didn't do anything
|
||||
}
|
||||
if (Event::handle('StartAttachPubkeyToUserXRD', array($magicsig, $xrd, $target))) {
|
||||
$xrd->links[] = new XML_XRD_Element_Link(Magicsig::PUBLICKEYREL,
|
||||
'data:application/magic-public-key,'. $magicsig->toString());
|
||||
$xrd->links[] = new XML_XRD_Element_Link(
|
||||
Magicsig::PUBLICKEYREL,
|
||||
'data:application/magic-public-key,' . $magicsig->toString()
|
||||
);
|
||||
// The following event handles plugins like Diaspora which add their own version of the Magicsig pubkey
|
||||
Event::handle('EndAttachPubkeyToUserXRD', array($magicsig, $xrd, $target));
|
||||
}
|
||||
@ -1507,7 +1607,7 @@ class OStatusPlugin extends Plugin
|
||||
}
|
||||
|
||||
// FIXME: Maybe this shouldn't be so authoritative that it breaks other remote profile lookups?
|
||||
static public function onCheckActivityAuthorship(Activity $activity, Profile &$profile)
|
||||
public static function onCheckActivityAuthorship(Activity $activity, Profile &$profile)
|
||||
{
|
||||
try {
|
||||
$oprofile = Ostatus_profile::ensureProfileURL($profile->getUrl());
|
||||
@ -1562,8 +1662,13 @@ class OStatusPlugin extends Plugin
|
||||
// 201 Created is what Mastodon returns when it's ok
|
||||
// 202 Accepted is what we get from Diaspora, also good
|
||||
if (!in_array($response->getStatus(), array(200, 201, 202))) {
|
||||
common_log(LOG_ERR, sprintf('Salmon (from profile %d) endpoint %s returned status %s: %s',
|
||||
$magic_env->getActor()->getID(), $endpoint_uri, $response->getStatus(), $response->getBody()));
|
||||
common_log(LOG_ERR, sprintf(
|
||||
'Salmon (from profile %d) endpoint %s returned status %s: %s',
|
||||
$magic_env->getActor()->getID(),
|
||||
$endpoint_uri,
|
||||
$response->getStatus(),
|
||||
$response->getBody()
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,32 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2009-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); }
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @package OStatusPlugin
|
||||
* @maintainer Brion Vibber <brion@status.net>
|
||||
* FeedSub handles low-level WebSub (PubSubHubbub/PuSH) subscriptions.
|
||||
* Higher-level behavior building OStatus stuff on top is handled
|
||||
* under Ostatus_profile.
|
||||
*
|
||||
* @package OStatusPlugin
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/*
|
||||
WebSub (previously PubSubHubbub/PuSH) subscription flow:
|
||||
|
||||
@ -37,14 +40,8 @@ WebSub (previously PubSubHubbub/PuSH) subscription flow:
|
||||
|
||||
main/push/callback
|
||||
hub sends us updates via POST
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* FeedSub handles low-level WebSub (PubSubHubbub/PuSH) subscriptions.
|
||||
* Higher-level behavior building OStatus stuff on top is handled
|
||||
* under Ostatus_profile.
|
||||
*/
|
||||
class FeedSub extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'feedsub';
|
||||
@ -71,7 +68,7 @@ class FeedSub extends Managed_DataObject
|
||||
'uri' => array('type' => 'varchar', 'not null' => true, 'length' => 191, 'description' => 'FeedSub uri'),
|
||||
'huburi' => array('type' => 'text', 'description' => 'FeedSub hub-uri'),
|
||||
'secret' => array('type' => 'text', 'description' => 'FeedSub stored secret'),
|
||||
'sub_state' => array('type' => 'enum("subscribe","active","unsubscribe","inactive","nohub")', 'not null' => true, 'description' => 'subscription state'),
|
||||
'sub_state' => array('type' => 'enum', 'enum' => array('subscribe', 'active', 'unsubscribe', 'inactive', 'nohub'), 'not null' => true, 'description' => 'subscription state'),
|
||||
'sub_start' => array('type' => 'datetime', 'description' => 'subscription start'),
|
||||
'sub_end' => array('type' => 'datetime', 'description' => 'subscription end'),
|
||||
'last_update' => array('type' => 'datetime', 'description' => 'when this record was last updated'),
|
||||
@ -96,7 +93,7 @@ class FeedSub extends Managed_DataObject
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
function getLeaseRemaining()
|
||||
public function getLeaseRemaining()
|
||||
{
|
||||
if (empty($this->sub_end)) {
|
||||
return null;
|
||||
@ -118,8 +115,8 @@ class FeedSub extends Managed_DataObject
|
||||
if (empty($this->huburi)
|
||||
&& (!common_config('feedsub', 'fallback_hub')
|
||||
|| $this->sub_state === 'nohub')) {
|
||||
// Here we have no huburi set. Also, either there is no
|
||||
// fallback hub configured or sub_state is "nohub".
|
||||
// Here we have no huburi set. Also, either there is no
|
||||
// fallback hub configured or sub_state is "nohub".
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -180,7 +177,6 @@ class FeedSub extends Managed_DataObject
|
||||
try {
|
||||
// discover the hub uri
|
||||
$feedsub->ensureHub();
|
||||
|
||||
} catch (FeedSubNoHubException $e) {
|
||||
// Only throw this exception if we can't handle huburi-less feeds
|
||||
// (i.e. we have a fallback hub or we can do feed polling (nohub)
|
||||
@ -263,7 +259,7 @@ class FeedSub extends Managed_DataObject
|
||||
*/
|
||||
public function subscribe($rediscovered=false)
|
||||
{
|
||||
if ($this->sub_state && $this->sub_state != 'inactive') {
|
||||
if ($this->sub_state !== 'inactive') {
|
||||
common_log(LOG_WARNING, sprintf('Attempting to (re)start WebSub subscription to %s in unexpected state %s', $this->getUri(), $this->sub_state));
|
||||
}
|
||||
|
||||
@ -276,7 +272,7 @@ class FeedSub extends Managed_DataObject
|
||||
if (common_config('feedsub', 'fallback_hub')) {
|
||||
// No native hub on this feed?
|
||||
// Use our fallback hub, which handles polling on our behalf.
|
||||
} else if (common_config('feedsub', 'nohub')) {
|
||||
} elseif (common_config('feedsub', 'nohub')) {
|
||||
// For this to actually work, we'll need some polling mechanism.
|
||||
// The FeedPoller plugin should take care of it.
|
||||
return;
|
||||
@ -298,7 +294,8 @@ class FeedSub extends Managed_DataObject
|
||||
*
|
||||
* @throws ServerException if feed state is not valid
|
||||
*/
|
||||
public function unsubscribe() {
|
||||
public function unsubscribe()
|
||||
{
|
||||
if ($this->sub_state != 'active') {
|
||||
common_log(LOG_WARNING, sprintf('Attempting to (re)end WebSub subscription to %s in unexpected state %s', $this->getUri(), $this->sub_state));
|
||||
}
|
||||
@ -344,7 +341,7 @@ class FeedSub extends Managed_DataObject
|
||||
*/
|
||||
public function garbageCollect()
|
||||
{
|
||||
if ($this->sub_state == '' || $this->sub_state == 'inactive') {
|
||||
if ($this->sub_state === 'inactive') {
|
||||
// No active WebSub subscription, we can just leave it be.
|
||||
return true;
|
||||
}
|
||||
@ -366,12 +363,12 @@ class FeedSub extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
|
||||
static public function renewalCheck()
|
||||
public static function renewalCheck()
|
||||
{
|
||||
$fs = new FeedSub();
|
||||
// the "" empty string check is because we historically haven't saved unsubscribed feeds as NULL
|
||||
$fs->whereAdd('sub_end IS NOT NULL AND sub_end!="" AND sub_end < NOW() + INTERVAL 1 day');
|
||||
if (!$fs->find()) { // find can be both false and 0, depending on why nothing was found
|
||||
$fs->whereAdd("sub_end IS NOT NULL AND sub_end < (CURRENT_TIMESTAMP + INTERVAL '1' DAY)");
|
||||
// find can be both false and 0, depending on why nothing was found
|
||||
if (!$fs->find()) {
|
||||
throw new NoResultException($fs);
|
||||
}
|
||||
return $fs;
|
||||
@ -437,10 +434,10 @@ class FeedSub extends Managed_DataObject
|
||||
if ($status == 202 || $status == 204) {
|
||||
common_log(LOG_INFO, __METHOD__ . ': sub req ok, awaiting verification callback');
|
||||
return;
|
||||
} else if ($status >= 200 && $status < 300) {
|
||||
} elseif ($status >= 200 && $status < 300) {
|
||||
common_log(LOG_ERR, __METHOD__ . ": sub req returned unexpected HTTP $status: " . $response->getBody());
|
||||
$msg = sprintf(_m("Unexpected HTTP status: %d"), $status);
|
||||
} else if ($status == 422 && !$rediscovered) {
|
||||
} elseif ($status == 422 && !$rediscovered) {
|
||||
// Error code regarding something wrong in the data (it seems
|
||||
// that we're talking to a WebSub hub at least, so let's check
|
||||
// our own data to be sure we're not mistaken somehow, which
|
||||
@ -482,7 +479,8 @@ class FeedSub extends Managed_DataObject
|
||||
if ($lease_seconds > 0) {
|
||||
$this->sub_end = common_sql_date(time() + $lease_seconds);
|
||||
} else {
|
||||
$this->sub_end = null; // Backwards compatibility to StatusNet (PuSH <0.4 supported permanent subs)
|
||||
// Backwards compatibility to StatusNet (PuSH <0.4 supported permanent subs)
|
||||
$this->sub_end = DB_DataObject_Cast::sql('NULL');
|
||||
}
|
||||
$this->modified = common_sql_now();
|
||||
|
||||
@ -498,11 +496,10 @@ class FeedSub extends Managed_DataObject
|
||||
{
|
||||
$original = clone($this);
|
||||
|
||||
// @fixme these should all be null, but DB_DataObject doesn't save null values...?????
|
||||
$this->secret = '';
|
||||
$this->sub_state = '';
|
||||
$this->sub_start = '';
|
||||
$this->sub_end = '';
|
||||
$this->secret = DB_DataObject_Cast::sql('NULL');
|
||||
$this->sub_state = 'inactive';
|
||||
$this->sub_start = DB_DataObject_Cast::sql('NULL');
|
||||
$this->sub_end = DB_DataObject_Cast::sql('NULL');
|
||||
$this->modified = common_sql_now();
|
||||
|
||||
return $this->update($original);
|
||||
@ -544,7 +541,6 @@ class FeedSub extends Managed_DataObject
|
||||
}
|
||||
|
||||
$this->receiveFeed($post);
|
||||
|
||||
} catch (FeedSubBadPushSignatureException $e) {
|
||||
// We got a signature, so something could be wrong. Let's check to see if
|
||||
// maybe upstream has switched to another hub. Let's fetch feed and then
|
||||
@ -628,7 +624,6 @@ class FeedSub extends Managed_DataObject
|
||||
throw new FeedSubBadPushSignatureException('Incoming WebSub push signature did not match expected HMAC hash.');
|
||||
}
|
||||
return true;
|
||||
|
||||
} else {
|
||||
common_log(LOG_ERR, sprintf(__METHOD__.': ignoring WebSub push with bogus HMAC==', _ve($hmac)));
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class HubSub extends Managed_DataObject
|
||||
'secret' => array('type' => 'text', 'description' => 'HubSub stored secret'),
|
||||
'sub_start' => array('type' => 'datetime', 'description' => 'subscription start'),
|
||||
'sub_end' => array('type' => 'datetime', 'description' => 'subscription end'),
|
||||
'errors' => array('type' => 'integer', 'not null' => true, 'default' => 0, 'description' => 'Queue handling error count, is reset on success.'),
|
||||
'errors' => array('type' => 'int', 'not null' => true, 'default' => 0, 'description' => 'Queue handling error count, is reset on success.'),
|
||||
'error_start' => array('type' => 'datetime', 'default' => null, 'description' => 'time of first error since latest success, should be null if no errors have been counted'),
|
||||
'last_error' => array('type' => 'datetime', 'default' => null, 'description' => 'time of last failure, if ever'),
|
||||
'last_error_msg' => array('type' => 'text', 'default' => null, 'description' => 'Last error _message_'),
|
||||
|
@ -51,9 +51,9 @@ class Ostatus_profile extends Managed_DataObject
|
||||
return array(
|
||||
'fields' => array(
|
||||
'uri' => array('type' => 'varchar', 'length' => 191, 'not null' => true),
|
||||
'profile_id' => array('type' => 'integer'),
|
||||
'group_id' => array('type' => 'integer'),
|
||||
'peopletag_id' => array('type' => 'integer'),
|
||||
'profile_id' => array('type' => 'int'),
|
||||
'group_id' => array('type' => 'int'),
|
||||
'peopletag_id' => array('type' => 'int'),
|
||||
'feeduri' => array('type' => 'varchar', 'length' => 191),
|
||||
'salmonuri' => array('type' => 'varchar', 'length' => 191),
|
||||
'avatar' => array('type' => 'text'),
|
||||
|
@ -1,24 +1,26 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - a 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/>.
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Run this from INSTALLDIR/plugins/OStatus/scripts
|
||||
*/
|
||||
|
||||
@ -53,7 +55,7 @@ echo "Looking for feed subscriptions with dirty no good huburis...\n";
|
||||
|
||||
$feedsub = new FeedSub();
|
||||
$feedsub->sub_state = 'subscribe';
|
||||
$feedsub->whereAdd('created < DATE_SUB(NOW(), INTERVAL 1 HOUR)');
|
||||
$feedsub->whereAdd("created < (CURRENT_TIMESTAMP - INTERVAL '1' HOUR)");
|
||||
$feedsub->find();
|
||||
$cnt = 0;
|
||||
|
||||
|
@ -1,21 +1,23 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - a 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/>.
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
|
||||
@ -39,7 +41,8 @@ END_OF_HELP;
|
||||
|
||||
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||
|
||||
function showProfileInfo(Ostatus_profile $oprofile) {
|
||||
function showProfileInfo(Ostatus_profile $oprofile)
|
||||
{
|
||||
if ($oprofile->isGroup()) {
|
||||
echo "group\n";
|
||||
} else {
|
||||
@ -51,7 +54,8 @@ function showProfileInfo(Ostatus_profile $oprofile) {
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function fixProfile(Ostatus_profile $oprofile) {
|
||||
function fixProfile(Ostatus_profile $oprofile)
|
||||
{
|
||||
echo "Before:\n";
|
||||
showProfileInfo($oprofile);
|
||||
|
||||
@ -102,10 +106,10 @@ if (have_option('all')) {
|
||||
echo "Failed on URI=="._ve($oprofile->uri).": {$e->getMessage()}\n";
|
||||
}
|
||||
}
|
||||
} else if (have_option('suspicious')) {
|
||||
} elseif (have_option('suspicious')) {
|
||||
$oprofile = new Ostatus_profile();
|
||||
$oprofile->joinAdd(array('profile_id', 'profile:id'));
|
||||
$oprofile->whereAdd("nickname rlike '^[0-9]$'");
|
||||
$oprofile->joinAdd(['profile_id', 'profile:id']);
|
||||
$oprofile->whereAdd("CHAR_LENGTH(nickname) = 1 AND nickname BETWEEN '0' AND '9'");
|
||||
$oprofile->find();
|
||||
echo "Found $oprofile->N matching profiles:\n\n";
|
||||
while ($oprofile->fetch()) {
|
||||
@ -116,7 +120,7 @@ if (have_option('all')) {
|
||||
echo "Failed on URI=="._ve($oprofile->uri).": {$e->getMessage()}\n";
|
||||
}
|
||||
}
|
||||
} else if (!empty($args[0]) && $validate->uri($args[0])) {
|
||||
} elseif (!empty($args[0]) && $validate->uri($args[0])) {
|
||||
$uri = $args[0];
|
||||
$oprofile = Ostatus_profile::getKV('uri', $uri);
|
||||
|
||||
|
@ -1,35 +1,30 @@
|
||||
<?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
|
||||
*
|
||||
* Settings for OpenID
|
||||
*
|
||||
* 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 Settings
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR.'/plugins/OpenID/openid.php';
|
||||
|
||||
@ -38,11 +33,8 @@ require_once INSTALLDIR.'/plugins/OpenID/openid.php';
|
||||
*
|
||||
* Lets users add, edit and delete OpenIDs from their account
|
||||
*
|
||||
* @category Settings
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class OpenidsettingsAction extends SettingsAction
|
||||
{
|
||||
@ -100,17 +92,26 @@ class OpenidsettingsAction extends SettingsAction
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label.
|
||||
$this->input('openid_url', _m('OpenID URL'), null,
|
||||
// TRANS: Form guide.
|
||||
_m('An OpenID URL which identifies you.'),
|
||||
null, true,
|
||||
['placeholder'=>'https://example.com/you']);
|
||||
$this->input(
|
||||
'openid_url',
|
||||
_m('OpenID URL'),
|
||||
null,
|
||||
// TRANS: Form guide.
|
||||
_m('An OpenID URL which identifies you.'),
|
||||
null,
|
||||
true,
|
||||
['placeholder' => 'https://example.com/you']
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label.
|
||||
$this->checkbox('openid-synch', _m('Synchronize Account'), false,
|
||||
// TRANS: Form guide.
|
||||
_m('Synchronize GNU social profile with this OpenID identity.'));
|
||||
$this->checkbox(
|
||||
'openid-synch',
|
||||
_m('Synchronize Account'),
|
||||
false,
|
||||
// TRANS: Form guide.
|
||||
_m('Synchronize GNU social profile with this OpenID identity.')
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
// TRANS: Button text for adding an OpenID URL.
|
||||
@ -129,13 +130,16 @@ class OpenidsettingsAction extends SettingsAction
|
||||
$this->element('h2', null, _m('HEADER', 'OpenID Actions'));
|
||||
|
||||
if ($cnt == 1 && !$this->scoped->hasPassword()) {
|
||||
$this->element('p', 'form_guide',
|
||||
// TRANS: Form guide.
|
||||
_m('You can\'t remove your main OpenID account ' .
|
||||
'without either adding a password to your ' .
|
||||
'GNU social account or another OpenID account. ' .
|
||||
'You can synchronize your profile with your ' .
|
||||
'OpenID by clicking the button labeled "Synchronize".'));
|
||||
$this->element(
|
||||
'p',
|
||||
'form_guide',
|
||||
// TRANS: Form guide.
|
||||
_m('You can\'t remove your main OpenID account ' .
|
||||
'without either adding a password to your ' .
|
||||
'GNU social account or another OpenID account. ' .
|
||||
'You can synchronize your profile with your ' .
|
||||
'OpenID by clicking the button labeled "Synchronize".')
|
||||
);
|
||||
|
||||
if ($oid->fetch()) {
|
||||
$this->elementStart('form', ['method' => 'POST',
|
||||
@ -152,12 +156,15 @@ class OpenidsettingsAction extends SettingsAction
|
||||
$this->elementEnd('form');
|
||||
}
|
||||
} else {
|
||||
$this->element('p', 'form_guide',
|
||||
// TRANS: Form guide.
|
||||
_m('You can remove an OpenID from your account ' .
|
||||
'by clicking the button labeled "Remove". ' .
|
||||
'You can synchronize your profile with an OpenID ' .
|
||||
'by clicking the button labeled "Synchronize".'));
|
||||
$this->element(
|
||||
'p',
|
||||
'form_guide',
|
||||
// TRANS: Form guide.
|
||||
_m('You can remove an OpenID from your account ' .
|
||||
'by clicking the button labeled "Remove". ' .
|
||||
'You can synchronize your profile with an OpenID ' .
|
||||
'by clicking the button labeled "Synchronize".')
|
||||
);
|
||||
$idx = 0;
|
||||
|
||||
while ($oid->fetch()) {
|
||||
@ -191,26 +198,38 @@ class OpenidsettingsAction extends SettingsAction
|
||||
// TRANS: Fieldset legend.
|
||||
$this->element('legend', null, _m('OpenID Trusted Sites'));
|
||||
$this->hidden('token', common_session_token());
|
||||
$this->element('p', 'form_guide',
|
||||
// TRANS: Form guide.
|
||||
_m('The following sites are allowed to access your ' .
|
||||
'identity and log you in. You can remove a site from ' .
|
||||
'this list to deny it access to your OpenID.'));
|
||||
$this->element(
|
||||
'p',
|
||||
'form_guide',
|
||||
// TRANS: Form guide.
|
||||
_m('The following sites are allowed to access your ' .
|
||||
'identity and log you in. You can remove a site from ' .
|
||||
'this list to deny it access to your OpenID.')
|
||||
);
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$user_openid_trustroot = new User_openid_trustroot();
|
||||
$user_openid_trustroot->user_id = $this->scoped->getID();
|
||||
if ($user_openid_trustroot->find()) {
|
||||
while ($user_openid_trustroot->fetch()) {
|
||||
$this->elementStart('li');
|
||||
$this->element('input', ['name' => 'openid_trustroot[]',
|
||||
'type' => 'checkbox',
|
||||
'class' => 'checkbox',
|
||||
'value' => $user_openid_trustroot->trustroot,
|
||||
'id' => 'openid_trustroot_' . crc32($user_openid_trustroot->trustroot)]);
|
||||
$this->element('label',
|
||||
['class'=>'checkbox',
|
||||
'for' => 'openid_trustroot_' . crc32($user_openid_trustroot->trustroot)],
|
||||
$user_openid_trustroot->trustroot);
|
||||
$this->element(
|
||||
'input',
|
||||
[
|
||||
'name' => 'openid_trustroot[]',
|
||||
'type' => 'checkbox',
|
||||
'class' => 'checkbox',
|
||||
'value' => $user_openid_trustroot->trustroot,
|
||||
'id' => 'openid_trustroot_' . crc32($user_openid_trustroot->trustroot),
|
||||
]
|
||||
);
|
||||
$this->element(
|
||||
'label',
|
||||
[
|
||||
'class'=>'checkbox',
|
||||
'for' => 'openid_trustroot_' . crc32($user_openid_trustroot->trustroot),
|
||||
],
|
||||
$user_openid_trustroot->trustroot
|
||||
);
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
}
|
||||
@ -363,7 +382,7 @@ class OpenidsettingsAction extends SettingsAction
|
||||
$orig = clone($prefs);
|
||||
}
|
||||
|
||||
$prefs->hide_profile_link = $this->booleanintstring('hide_profile_link');
|
||||
$prefs->hide_profile_link = $this->boolean('hide_profile_link');
|
||||
|
||||
if ($orig instanceof User_openid_prefs) {
|
||||
$prefs->update($orig);
|
||||
|
@ -63,12 +63,12 @@ class User_openid_prefs extends Managed_DataObject
|
||||
'description' => 'Per-user preferences for OpenID display',
|
||||
'fields' => [
|
||||
'user_id' => [
|
||||
'type' => 'integer',
|
||||
'type' => 'int',
|
||||
'not null' => true,
|
||||
'description' => 'User whose prefs we are saving'
|
||||
],
|
||||
'hide_profile_link' => [
|
||||
'type' => 'integer',
|
||||
'type' => 'int',
|
||||
'not null' => true,
|
||||
'default' => 0,
|
||||
'description' => 'Whether to hide profile links from profile block'
|
||||
|
@ -1,25 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @copyright 2008, 2009 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once('Auth/OpenID.php');
|
||||
require_once('Auth/OpenID/Consumer.php');
|
||||
@ -49,19 +49,19 @@ function oid_store()
|
||||
}
|
||||
$db = DB::connect($dsn, $options);
|
||||
|
||||
if (PEAR::isError($db)) {
|
||||
if ((new PEAR)->isError($db)) {
|
||||
throw new ServerException($db->getMessage());
|
||||
}
|
||||
|
||||
switch (common_config('db', 'type')) {
|
||||
case 'pgsql':
|
||||
$store = new Auth_OpenID_PostgreSQLStore($db);
|
||||
break;
|
||||
case 'mysql':
|
||||
$store = new Auth_OpenID_MySQLStore($db);
|
||||
break;
|
||||
case 'postgresql':
|
||||
$store = new Auth_OpenID_PostgreSQLStore($db);
|
||||
break;
|
||||
default:
|
||||
throw new ServerException(_m('Unknown DB type for OpenID.'));
|
||||
throw new ServerException('Unknown DB type selected.');
|
||||
}
|
||||
}
|
||||
return $store;
|
||||
@ -90,9 +90,11 @@ function oid_clear_last()
|
||||
|
||||
function oid_set_last($openid_url)
|
||||
{
|
||||
common_set_cookie(OPENID_COOKIE_KEY,
|
||||
$openid_url,
|
||||
time() + OPENID_COOKIE_EXPIRY);
|
||||
common_set_cookie(
|
||||
OPENID_COOKIE_KEY,
|
||||
$openid_url,
|
||||
time() + OPENID_COOKIE_EXPIRY
|
||||
);
|
||||
}
|
||||
|
||||
function oid_get_last()
|
||||
@ -119,7 +121,7 @@ function oid_link_user($id, $canonical, $display)
|
||||
$oid->created = common_sql_now();
|
||||
|
||||
if (!$oid->insert()) {
|
||||
$err = &$_PEAR->getStaticProperty('DB_DataObject','lastError');
|
||||
$err = &$_PEAR->getStaticProperty('DB_DataObject', 'lastError');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -149,9 +151,11 @@ function oid_check_immediate($openid_url, $backto=null)
|
||||
|
||||
$_SESSION['openid_immediate_backto'] = $backto;
|
||||
|
||||
oid_authenticate($openid_url,
|
||||
'finishimmediate',
|
||||
true);
|
||||
oid_authenticate(
|
||||
$openid_url,
|
||||
'finishimmediate',
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
function oid_authenticate($openid_url, $returnto, $immediate=false)
|
||||
@ -177,23 +181,27 @@ function oid_authenticate($openid_url, $returnto, $immediate=false)
|
||||
common_log(LOG_ERR, __METHOD__ . ": mystery fail contacting $openid_url");
|
||||
// TRANS: OpenID plugin message. Given when an OpenID is not valid.
|
||||
throw new ServerException(_m('Not a valid OpenID.'));
|
||||
} else if (Auth_OpenID::isFailure($auth_request)) {
|
||||
} elseif (Auth_OpenID::isFailure($auth_request)) {
|
||||
common_log(LOG_ERR, __METHOD__ . ": OpenID fail to $openid_url: $auth_request->message");
|
||||
// TRANS: OpenID plugin server error. Given when the OpenID authentication request fails.
|
||||
// TRANS: %s is the failure message.
|
||||
throw new ServerException(sprintf(_m('OpenID failure: %s.'), $auth_request->message));
|
||||
}
|
||||
|
||||
$sreg_request = Auth_OpenID_SRegRequest::build(// Required
|
||||
array(),
|
||||
// Optional
|
||||
array('nickname',
|
||||
'email',
|
||||
'fullname',
|
||||
'language',
|
||||
'timezone',
|
||||
'postcode',
|
||||
'country'));
|
||||
$sreg_request = Auth_OpenID_SRegRequest::build(
|
||||
// Required
|
||||
[],
|
||||
// Optional
|
||||
[
|
||||
'nickname',
|
||||
'email',
|
||||
'fullname',
|
||||
'language',
|
||||
'timezone',
|
||||
'postcode',
|
||||
'country',
|
||||
]
|
||||
);
|
||||
|
||||
if ($sreg_request) {
|
||||
$auth_request->addExtension($sreg_request);
|
||||
@ -224,9 +232,11 @@ function oid_authenticate($openid_url, $returnto, $immediate=false)
|
||||
// autosubmitter for now.
|
||||
//
|
||||
//if ($auth_request->shouldSendRedirect()) {
|
||||
$redirect_url = $auth_request->redirectURL($trust_root,
|
||||
$process_url,
|
||||
$immediate);
|
||||
$redirect_url = $auth_request->redirectURL(
|
||||
$trust_root,
|
||||
$process_url,
|
||||
$immediate
|
||||
);
|
||||
if (Auth_OpenID::isFailure($redirect_url)) {
|
||||
// TRANS: OpenID plugin server error. Given when the OpenID authentication request cannot be redirected.
|
||||
// TRANS: %s is the failure message.
|
||||
@ -266,11 +276,14 @@ function oid_authenticate($openid_url, $returnto, $immediate=false)
|
||||
|
||||
function _oid_print_instructions()
|
||||
{
|
||||
common_element('div', 'instructions',
|
||||
// TRANS: OpenID plugin user instructions.
|
||||
_m('This form should automatically submit itself. '.
|
||||
'If not, click the submit button to go to your '.
|
||||
'OpenID provider.'));
|
||||
common_element(
|
||||
'div',
|
||||
'instructions',
|
||||
// TRANS: OpenID plugin user instructions.
|
||||
_m('This form should automatically submit itself. '.
|
||||
'If not, click the submit button to go to your '.
|
||||
'OpenID provider.')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -382,22 +395,22 @@ function oid_check_teams($response)
|
||||
|
||||
class AutosubmitAction extends Action
|
||||
{
|
||||
var $form_html = null;
|
||||
var $form_id = null;
|
||||
public $form_html = null;
|
||||
public $form_id = null;
|
||||
|
||||
function handle()
|
||||
public function handle()
|
||||
{
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Title
|
||||
return _m('OpenID Login Submission');
|
||||
}
|
||||
|
||||
function showContent()
|
||||
public function showContent()
|
||||
{
|
||||
$this->raw('<p style="margin: 20px 80px">');
|
||||
// @todo FIXME: This would be better using standard CSS class, but the present theme's a bit scary.
|
||||
@ -414,10 +427,13 @@ class AutosubmitAction extends Action
|
||||
$this->raw($this->form_html);
|
||||
}
|
||||
|
||||
function showScripts()
|
||||
public function showScripts()
|
||||
{
|
||||
parent::showScripts();
|
||||
$this->element('script', null,
|
||||
'document.getElementById(\'' . $this->form_id . '\').submit();');
|
||||
$this->element(
|
||||
'script',
|
||||
null,
|
||||
'document.getElementById(\'' . $this->form_id . '\').submit();'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +1,38 @@
|
||||
<?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 to mark notices as bookmarks
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PollPlugin
|
||||
* @package StatusNet
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, 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/>.
|
||||
* @category PollPlugin
|
||||
* @package GNUsocial
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* For storing the poll options and such
|
||||
*
|
||||
* @category PollPlugin
|
||||
* @package StatusNet
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class Poll extends Managed_DataObject
|
||||
{
|
||||
@ -136,7 +128,9 @@ class Poll extends Managed_DataObject
|
||||
$pr = new Poll_response();
|
||||
$pr->poll_id = $this->id;
|
||||
$pr->groupBy('selection');
|
||||
$pr->selectAdd('count(profile_id) as votes');
|
||||
$pr->selectAdd();
|
||||
$pr->selectAdd('selection');
|
||||
$pr->selectAdd('COUNT(profile_id) AS votes');
|
||||
$pr->find();
|
||||
|
||||
$raw = array();
|
||||
|
@ -1,46 +1,38 @@
|
||||
<?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 to record responses to polls
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PollPlugin
|
||||
* @package StatusNet
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, 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/>.
|
||||
* @category PollPlugin
|
||||
* @package GNUsocial
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @copyright 2011, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* For storing the poll options and such
|
||||
*
|
||||
* @category PollPlugin
|
||||
* @package StatusNet
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @copyright 2011, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class Poll_response extends Managed_DataObject
|
||||
{
|
||||
@ -69,7 +61,7 @@ class Poll_response extends Managed_DataObject
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'unique keys' => array(
|
||||
'poll_uri_key' => array('uri'),
|
||||
'poll_response_uri_key' => array('uri'),
|
||||
'poll_response_poll_id_profile_id_key' => array('poll_id', 'profile_id'),
|
||||
),
|
||||
'indexes' => array(
|
||||
|
@ -1,44 +1,37 @@
|
||||
<?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 to record user prefs for polls
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PollPlugin
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2012, 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/>.
|
||||
* @category PollPlugin
|
||||
* @package GNUsocial
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2012, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* For storing the poll prefs
|
||||
*
|
||||
* @category PollPlugin
|
||||
* @package StatusNet
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @copyright 2012, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
@ -46,7 +39,7 @@ class User_poll_prefs extends Managed_DataObject
|
||||
{
|
||||
public $__table = 'user_poll_prefs'; // table name
|
||||
public $user_id; // int id
|
||||
public $hide_responses; // boolean
|
||||
public $hide_responses; // bool
|
||||
public $created; // datetime
|
||||
public $modified; // datetime
|
||||
|
||||
@ -59,7 +52,7 @@ class User_poll_prefs extends Managed_DataObject
|
||||
'description' => 'Record of user preferences for polls',
|
||||
'fields' => array(
|
||||
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user id'),
|
||||
'hide_responses' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'Hide all poll responses'),
|
||||
'hide_responses' => array('type' => 'bool', 'default' => false, 'description' => 'Hide all poll responses'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
|
||||
),
|
||||
|
@ -1,47 +1,36 @@
|
||||
<?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) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Close a question to further answers
|
||||
*
|
||||
* 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 QnA
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or late
|
||||
*/
|
||||
if (!defined('STATUSNET')) {
|
||||
// This check helps protect against security problems;
|
||||
// your code file can't be executed directly from the web.
|
||||
exit(1);
|
||||
}
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Close a question to new answers
|
||||
*
|
||||
* @category QnA
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or late
|
||||
*/
|
||||
class QnaclosequestionAction extends Action
|
||||
{
|
||||
@ -57,7 +46,7 @@ class QnaclosequestionAction extends Action
|
||||
*
|
||||
* @return string Action title
|
||||
*/
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Page title for close a question
|
||||
return _m('Close question');
|
||||
@ -71,7 +60,7 @@ class QnaclosequestionAction extends Action
|
||||
* @return boolean true
|
||||
* @throws ClientException
|
||||
*/
|
||||
function prepare(array $args = [])
|
||||
public function prepare(array $args = [])
|
||||
{
|
||||
parent::prepare($args);
|
||||
if ($this->boolean('ajax')) {
|
||||
@ -107,7 +96,7 @@ class QnaclosequestionAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle()
|
||||
public function handle()
|
||||
{
|
||||
parent::handle();
|
||||
|
||||
@ -125,7 +114,7 @@ class QnaclosequestionAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function closeQuestion()
|
||||
public function closeQuestion()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
@ -136,9 +125,8 @@ class QnaclosequestionAction extends Action
|
||||
}
|
||||
|
||||
$orig = clone($this->question);
|
||||
$this->question->closed = 1;
|
||||
$this->question->closed = true;
|
||||
$this->question->update($orig);
|
||||
|
||||
} catch (ClientException $ce) {
|
||||
$this->error = $ce->getMessage();
|
||||
$this->showPage();
|
||||
@ -166,7 +154,7 @@ class QnaclosequestionAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showContent()
|
||||
public function showContent()
|
||||
{
|
||||
if (!empty($this->error)) {
|
||||
$this->element('p', 'error', $this->error);
|
||||
@ -184,7 +172,7 @@ class QnaclosequestionAction extends Action
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
public function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
|
@ -1,47 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Revise an answer
|
||||
*
|
||||
* 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 QnA
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
if (!defined('STATUSNET')) {
|
||||
// This check helps protect against security problems;
|
||||
// your code file can't be executed directly from the web.
|
||||
exit(1);
|
||||
}
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Revise an answer
|
||||
*
|
||||
* @category QnA
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Revise an answer
|
||||
*
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class QnareviseanswerAction extends Action
|
||||
{
|
||||
@ -56,7 +45,7 @@ class QnareviseanswerAction extends Action
|
||||
*
|
||||
* @return string Action title
|
||||
*/
|
||||
function title()
|
||||
public function title()
|
||||
{
|
||||
// TRANS: Page title for revising a question
|
||||
return _m('Revise answer');
|
||||
@ -70,7 +59,7 @@ class QnareviseanswerAction extends Action
|
||||
* @return boolean true
|
||||
* @throws ClientException
|
||||
*/
|
||||
function prepare(array $args = [])
|
||||
public function prepare(array $args = [])
|
||||
{
|
||||
parent::prepare($args);
|
||||
if ($this->boolean('ajax')) {
|
||||
@ -110,7 +99,7 @@ class QnareviseanswerAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle()
|
||||
public function handle()
|
||||
{
|
||||
parent::handle();
|
||||
|
||||
@ -119,7 +108,7 @@ class QnareviseanswerAction extends Action
|
||||
if ($this->arg('revise')) {
|
||||
$this->showContent();
|
||||
return;
|
||||
} else if ($this->arg('best')) {
|
||||
} elseif ($this->arg('best')) {
|
||||
if ($this->user->id == $this->question->profile_id) {
|
||||
$this->markBest();
|
||||
return;
|
||||
@ -138,7 +127,7 @@ class QnareviseanswerAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showContent()
|
||||
public function showContent()
|
||||
{
|
||||
if (!empty($this->error)) {
|
||||
$this->element('p', 'error', $this->error);
|
||||
@ -154,7 +143,7 @@ class QnareviseanswerAction extends Action
|
||||
return;
|
||||
}
|
||||
|
||||
function showAjaxReviseForm()
|
||||
public function showAjaxReviseForm()
|
||||
{
|
||||
$this->startHTML('text/xml;charset=utf-8');
|
||||
$this->elementStart('head');
|
||||
@ -173,7 +162,7 @@ class QnareviseanswerAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function markBest()
|
||||
public function markBest()
|
||||
{
|
||||
$question = $this->question;
|
||||
$answer = $this->answer;
|
||||
@ -181,12 +170,12 @@ class QnareviseanswerAction extends Action
|
||||
try {
|
||||
// close the question to further answers
|
||||
$orig = clone($question);
|
||||
$question->closed = 1;
|
||||
$question->closed = true;
|
||||
$result = $question->update($orig);
|
||||
|
||||
// mark this answer an the best answer
|
||||
$orig = clone($answer);
|
||||
$answer->best = 1;
|
||||
$answer->best = true;
|
||||
$result = $answer->update($orig);
|
||||
} catch (ClientException $ce) {
|
||||
$this->error = $ce->getMessage();
|
||||
@ -215,7 +204,7 @@ class QnareviseanswerAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function reviseAnswer()
|
||||
public function reviseAnswer()
|
||||
{
|
||||
$answer = $this->answer;
|
||||
|
||||
@ -255,7 +244,7 @@ class QnareviseanswerAction extends Action
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
public function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
|
@ -1,46 +1,38 @@
|
||||
<?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 to save answers to questions
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category QnA
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, 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/>.
|
||||
* @category QnA
|
||||
* @package GNUsocial
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('STATUSNET') || die();
|
||||
|
||||
/**
|
||||
* For storing answers
|
||||
*
|
||||
* @category QnA
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class QnA_Answer extends Managed_DataObject
|
||||
{
|
||||
@ -51,7 +43,7 @@ class QnA_Answer extends Managed_DataObject
|
||||
public $uri; // varchar(191) not 255 because utf8mb4 takes more space
|
||||
public $question_id; // char(36) -> question.id UUID
|
||||
public $profile_id; // int -> question.id
|
||||
public $best; // (boolean) int -> whether the question asker has marked this as the best answer
|
||||
public $best; // bool -> whether the question asker has marked this as the best answer
|
||||
public $revisions; // int -> count of revisions to this answer
|
||||
public $content; // text -> response text
|
||||
public $created; // datetime
|
||||
@ -82,18 +74,18 @@ class QnA_Answer extends Managed_DataObject
|
||||
'description' => 'UUID of question being responded to',
|
||||
),
|
||||
'content' => array('type' => 'text'), // got a better name?
|
||||
'best' => array('type' => 'int', 'size' => 'tiny'),
|
||||
'best' => array('type' => 'bool'),
|
||||
'revisions' => array('type' => 'int'),
|
||||
'profile_id' => array('type' => 'int'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true),
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'unique keys' => array(
|
||||
'question_uri_key' => array('uri'),
|
||||
'question_id_profile_id_key' => array('question_id', 'profile_id'),
|
||||
'qna_answer_uri_key' => array('uri'),
|
||||
'qna_answer_question_id_profile_id_key' => array('question_id', 'profile_id'),
|
||||
),
|
||||
'indexes' => array(
|
||||
'profile_id_question_id_index' => array('profile_id', 'question_id'),
|
||||
'qna_answer_profile_id_question_id_idx' => array('profile_id', 'question_id'),
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -105,7 +97,7 @@ class QnA_Answer extends Managed_DataObject
|
||||
*
|
||||
* @return QnA_Answer found response or null
|
||||
*/
|
||||
static function getByNotice($notice)
|
||||
public static function getByNotice($notice)
|
||||
{
|
||||
$answer = self::getKV('uri', $notice->uri);
|
||||
if (empty($answer)) {
|
||||
@ -119,17 +111,17 @@ class QnA_Answer extends Managed_DataObject
|
||||
*
|
||||
* @return Notice
|
||||
*/
|
||||
function getNotice()
|
||||
public function getNotice()
|
||||
{
|
||||
return Notice::getKV('uri', $this->uri);
|
||||
}
|
||||
|
||||
static function fromNotice($notice)
|
||||
public static function fromNotice($notice)
|
||||
{
|
||||
return QnA_Answer::getKV('uri', $notice->uri);
|
||||
}
|
||||
|
||||
function getUrl()
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->getNotice()->getUrl();
|
||||
}
|
||||
@ -139,29 +131,29 @@ class QnA_Answer extends Managed_DataObject
|
||||
*
|
||||
* @return QnA_Question
|
||||
*/
|
||||
function getQuestion()
|
||||
public function getQuestion()
|
||||
{
|
||||
$question = QnA_Question::getKV('id', $this->question_id);
|
||||
if (empty($question)) {
|
||||
// TRANS: Exception thown when getting a question with a non-existing ID.
|
||||
// TRANS: %s is the non-existing question ID.
|
||||
throw new Exception(sprintf(_m('No question with ID %s'),$this->question_id));
|
||||
throw new Exception(sprintf(_m('No question with ID %s'), $this->question_id));
|
||||
}
|
||||
return $question;
|
||||
}
|
||||
|
||||
function getProfile()
|
||||
public function getProfile()
|
||||
{
|
||||
$profile = Profile::getKV('id', $this->profile_id);
|
||||
if (empty($profile)) {
|
||||
// TRANS: Exception thown when getting a profile with a non-existing ID.
|
||||
// TRANS: %s is the non-existing profile ID.
|
||||
throw new Exception(sprintf(_m('No profile with ID %s'),$this->profile_id));
|
||||
throw new Exception(sprintf(_m('No profile with ID %s'), $this->profile_id));
|
||||
}
|
||||
return $profile;
|
||||
}
|
||||
|
||||
function asHTML()
|
||||
public function asHTML()
|
||||
{
|
||||
return self::toHTML(
|
||||
$this->getProfile(),
|
||||
@ -170,7 +162,7 @@ class QnA_Answer extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
function asString()
|
||||
public function asString()
|
||||
{
|
||||
return self::toString(
|
||||
$this->getProfile(),
|
||||
@ -179,7 +171,7 @@ class QnA_Answer extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
static function toHTML($profile, $question, $answer)
|
||||
public static function toHTML($profile, $question, $answer)
|
||||
{
|
||||
$notice = $question->getNotice();
|
||||
|
||||
@ -201,7 +193,7 @@ class QnA_Answer extends Managed_DataObject
|
||||
htmlspecialchars(
|
||||
// Notification of how often an answer was revised.
|
||||
// TRANS: %s is the number of answer revisions.
|
||||
sprintf(_m('%s revision','%s revisions',$answer->revisions), $answer->revisions)
|
||||
sprintf(_m('%s revision', '%s revisions', $answer->revisions), $answer->revisions)
|
||||
)
|
||||
);
|
||||
$out->elementEnd('span');
|
||||
@ -212,7 +204,7 @@ class QnA_Answer extends Managed_DataObject
|
||||
return $out->getString();
|
||||
}
|
||||
|
||||
static function toString($profile, $question, $answer)
|
||||
public static function toString($profile, $question, $answer)
|
||||
{
|
||||
// @todo FIXME: unused variable?
|
||||
$notice = $question->getNotice();
|
||||
@ -237,7 +229,7 @@ class QnA_Answer extends Managed_DataObject
|
||||
*
|
||||
* @return Notice saved notice
|
||||
*/
|
||||
static function saveNew($profile, $question, $text, $options = null)
|
||||
public static function saveNew($profile, $question, $text, $options = null)
|
||||
{
|
||||
if (empty($options)) {
|
||||
$options = array();
|
||||
@ -248,7 +240,7 @@ class QnA_Answer extends Managed_DataObject
|
||||
$answer->profile_id = $profile->id;
|
||||
$answer->question_id = $question->id;
|
||||
$answer->revisions = 0;
|
||||
$answer->best = 0;
|
||||
$answer->best = false;
|
||||
$answer->content = $text;
|
||||
$answer->created = common_sql_now();
|
||||
$answer->uri = common_local_url(
|
||||
|
@ -1,46 +1,38 @@
|
||||
<?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 to mark a notice as a question
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category QnA
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, 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/>.
|
||||
* @category QnA
|
||||
* @package GNUsocial
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* For storing a question
|
||||
*
|
||||
* @category QnA
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class QnA_Question extends Managed_DataObject
|
||||
{
|
||||
@ -52,7 +44,7 @@ class QnA_Question extends Managed_DataObject
|
||||
public $profile_id; // int -> profile.id
|
||||
public $title; // text
|
||||
public $description; // text
|
||||
public $closed; // int (boolean) whether a question is closed
|
||||
public $closed; // bool -> whether a question is closed
|
||||
public $created; // datetime
|
||||
|
||||
/**
|
||||
@ -76,7 +68,7 @@ class QnA_Question extends Managed_DataObject
|
||||
),
|
||||
'profile_id' => array('type' => 'int'),
|
||||
'title' => array('type' => 'text'),
|
||||
'closed' => array('type' => 'int', 'size' => 'tiny'),
|
||||
'closed' => array('type' => 'bool'),
|
||||
'description' => array('type' => 'text'),
|
||||
'created' => array(
|
||||
'type' => 'datetime',
|
||||
@ -85,7 +77,7 @@ class QnA_Question extends Managed_DataObject
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'unique keys' => array(
|
||||
'question_uri_key' => array('uri'),
|
||||
'qna_question_uri_key' => array('uri'),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -97,28 +89,28 @@ class QnA_Question extends Managed_DataObject
|
||||
*
|
||||
* @return Question found question or null
|
||||
*/
|
||||
static function getByNotice($notice)
|
||||
public static function getByNotice($notice)
|
||||
{
|
||||
return self::getKV('uri', $notice->uri);
|
||||
}
|
||||
|
||||
function getNotice()
|
||||
public function getNotice()
|
||||
{
|
||||
return Notice::getKV('uri', $this->uri);
|
||||
}
|
||||
|
||||
function getUrl()
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->getNotice()->getUrl();
|
||||
}
|
||||
|
||||
function getProfile()
|
||||
public function getProfile()
|
||||
{
|
||||
$profile = Profile::getKV('id', $this->profile_id);
|
||||
if (empty($profile)) {
|
||||
// TRANS: Exception trown when getting a profile for a non-existing ID.
|
||||
// TRANS: %s is the provided profile ID.
|
||||
throw new Exception(sprintf(_m('No profile with ID %s'),$this->profile_id));
|
||||
throw new Exception(sprintf(_m('No profile with ID %s'), $this->profile_id));
|
||||
}
|
||||
return $profile;
|
||||
}
|
||||
@ -130,7 +122,7 @@ class QnA_Question extends Managed_DataObject
|
||||
*
|
||||
* @return Answer object or null
|
||||
*/
|
||||
function getAnswer(Profile $profile)
|
||||
public function getAnswer(Profile $profile)
|
||||
{
|
||||
$a = new QnA_Answer();
|
||||
$a->question_id = $this->id;
|
||||
@ -143,7 +135,7 @@ class QnA_Question extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function getAnswers()
|
||||
public function getAnswers()
|
||||
{
|
||||
$a = new QnA_Answer();
|
||||
$a->question_id = $this->id;
|
||||
@ -155,7 +147,7 @@ class QnA_Question extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function countAnswers()
|
||||
public function countAnswers()
|
||||
{
|
||||
$a = new QnA_Answer();
|
||||
|
||||
@ -164,22 +156,22 @@ class QnA_Question extends Managed_DataObject
|
||||
return $a->count();
|
||||
}
|
||||
|
||||
static function fromNotice($notice)
|
||||
public static function fromNotice($notice)
|
||||
{
|
||||
return QnA_Question::getKV('uri', $notice->uri);
|
||||
}
|
||||
|
||||
function asHTML()
|
||||
public function asHTML()
|
||||
{
|
||||
return self::toHTML($this->getProfile(), $this);
|
||||
}
|
||||
|
||||
function asString()
|
||||
public function asString()
|
||||
{
|
||||
return self::toString($this->getProfile(), $this);
|
||||
}
|
||||
|
||||
static function toHTML($profile, $question)
|
||||
public static function toHTML($profile, $question)
|
||||
{
|
||||
$notice = $question->getNotice();
|
||||
|
||||
@ -205,7 +197,7 @@ class QnA_Question extends Managed_DataObject
|
||||
$out->elementStart('span', 'answer-count');
|
||||
// TRANS: Number of given answers to a question.
|
||||
// TRANS: %s is the number of given answers.
|
||||
$out->text(sprintf(_m('%s answer','%s answers',$cnt), $cnt));
|
||||
$out->text(sprintf(_m('%s answer', '%s answers', $cnt), $cnt));
|
||||
$out->elementEnd('span');
|
||||
}
|
||||
|
||||
@ -221,7 +213,7 @@ class QnA_Question extends Managed_DataObject
|
||||
return $out->getString();
|
||||
}
|
||||
|
||||
static function toString($profile, $question, $answers)
|
||||
public static function toString($profile, $question, $answers)
|
||||
{
|
||||
return sprintf(htmlspecialchars($question->description));
|
||||
}
|
||||
@ -237,7 +229,7 @@ class QnA_Question extends Managed_DataObject
|
||||
*
|
||||
* @return Notice saved notice
|
||||
*/
|
||||
static function saveNew($profile, $title, $description, $options = array())
|
||||
public static function saveNew($profile, $title, $description, $options = [])
|
||||
{
|
||||
$q = new QnA_Question();
|
||||
|
||||
|
@ -1,46 +1,38 @@
|
||||
<?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 to save users votes for
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category QnA
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, 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/>.
|
||||
* @category QnA
|
||||
* @package GNUsocial
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* For storing votes on question and answers
|
||||
*
|
||||
* @category QnA
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class QnA_Vote extends Managed_DataObject
|
||||
{
|
||||
@ -87,11 +79,11 @@ class QnA_Vote extends Managed_DataObject
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'indexes' => array(
|
||||
'profile_id_question_Id_index' => array(
|
||||
'qna_vote_profile_id_question_id_idx' => array(
|
||||
'profile_id',
|
||||
'question_id'
|
||||
),
|
||||
'profile_id_question_Id_index' => array(
|
||||
'qna_vote_profile_id_question_id_idx' => array(
|
||||
'profile_id',
|
||||
'answer_id'
|
||||
)
|
||||
@ -110,7 +102,7 @@ class QnA_Vote extends Managed_DataObject
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
static function save($profile, $question, $answer, $vote)
|
||||
public static function save($profile, $question, $answer, $vote)
|
||||
{
|
||||
$v = new QnA_Vote();
|
||||
$v->id = UUID::gen();
|
||||
|
@ -1,36 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, StatusNet, Inc.
|
||||
*
|
||||
* A channel for real-time browser data
|
||||
*
|
||||
* 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 Realtime
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* A channel for real-time browser data
|
||||
@ -38,11 +20,20 @@ if (!defined('STATUSNET')) {
|
||||
* For each user currently browsing the site, we want to know which page they're on
|
||||
* so we can send real-time updates to their browser.
|
||||
*
|
||||
* @category Realtime
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
* @category Realtime
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* A channel for real-time browser data
|
||||
*
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
@ -88,7 +79,7 @@ class Realtime_channel extends Managed_DataObject
|
||||
'length' => 32,
|
||||
'not null' => true,
|
||||
'description' => 'shared secret key for this channel'),
|
||||
'audience' => array('type' => 'integer',
|
||||
'audience' => array('type' => 'int',
|
||||
'not null' => true,
|
||||
'default' => 0,
|
||||
'description' => 'reference count'),
|
||||
@ -111,7 +102,7 @@ class Realtime_channel extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
static function saveNew($user_id, $action, $arg1, $arg2)
|
||||
public static function saveNew($user_id, $action, $arg1, $arg2)
|
||||
{
|
||||
$channel = new Realtime_channel();
|
||||
|
||||
@ -131,7 +122,7 @@ class Realtime_channel extends Managed_DataObject
|
||||
return $channel;
|
||||
}
|
||||
|
||||
static function getChannel($user_id, $action, $arg1, $arg2)
|
||||
public static function getChannel($user_id, $action, $arg1, $arg2)
|
||||
{
|
||||
$channel = self::fetchChannel($user_id, $action, $arg1, $arg2);
|
||||
|
||||
@ -152,7 +143,7 @@ class Realtime_channel extends Managed_DataObject
|
||||
return $channel;
|
||||
}
|
||||
|
||||
static function getAllChannels($action, $arg1, $arg2)
|
||||
public static function getAllChannels($action, $arg1, $arg2)
|
||||
{
|
||||
$channel = new Realtime_channel();
|
||||
|
||||
@ -170,9 +161,9 @@ class Realtime_channel extends Managed_DataObject
|
||||
$channel->arg2 = $arg2;
|
||||
}
|
||||
|
||||
$channel->whereAdd('modified > "' . common_sql_date(time() - self::TIMEOUT) . '"');
|
||||
$channel->whereAdd(sprintf("modified > TIMESTAMP '%s'", common_sql_date(time() - self::TIMEOUT)));
|
||||
|
||||
$channels = array();
|
||||
$channels = [];
|
||||
|
||||
if ($channel->find()) {
|
||||
$channels = $channel->fetchAll();
|
||||
@ -181,7 +172,7 @@ class Realtime_channel extends Managed_DataObject
|
||||
return $channels;
|
||||
}
|
||||
|
||||
static function fetchChannel($user_id, $action, $arg1, $arg2)
|
||||
public static function fetchChannel($user_id, $action, $arg1, $arg2)
|
||||
{
|
||||
$channel = new Realtime_channel();
|
||||
|
||||
@ -213,7 +204,7 @@ class Realtime_channel extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
function increment()
|
||||
public function increment()
|
||||
{
|
||||
// XXX: race
|
||||
$orig = clone($this);
|
||||
@ -222,7 +213,7 @@ class Realtime_channel extends Managed_DataObject
|
||||
$this->update($orig);
|
||||
}
|
||||
|
||||
function touch()
|
||||
public function touch()
|
||||
{
|
||||
// XXX: race
|
||||
$orig = clone($this);
|
||||
@ -230,7 +221,7 @@ class Realtime_channel extends Managed_DataObject
|
||||
$this->update($orig);
|
||||
}
|
||||
|
||||
function decrement()
|
||||
public function decrement()
|
||||
{
|
||||
// XXX: race
|
||||
if ($this->audience == 1) {
|
||||
|
@ -1,23 +1,27 @@
|
||||
#!/usr/bin/env 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 - a distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Script to print out current version of the software
|
||||
*
|
||||
* 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/>.
|
||||
* @package Realtime
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2011, StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
define('INSTALLDIR', realpath(__DIR__ . '/../../..'));
|
||||
@ -42,7 +46,7 @@ function cleanupChannels()
|
||||
$rc->selectAdd();
|
||||
$rc->selectAdd('channel_key');
|
||||
|
||||
$rc->whereAdd('modified < "' . common_sql_date(time() - Realtime_channel::TIMEOUT) . '"');
|
||||
$rc->whereAdd(sprintf("modified < TIMESTAMP '%s'", common_sql_date(time() - Realtime_channel::TIMEOUT)));
|
||||
|
||||
if ($rc->find()) {
|
||||
$keys = $rc->fetchAll();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user