diff --git a/DOCUMENTATION/SYSTEM_ADMINISTRATORS/CONFIGURE.md b/DOCUMENTATION/SYSTEM_ADMINISTRATORS/CONFIGURE.md index dce3ffa905..6a386821d0 100644 --- a/DOCUMENTATION/SYSTEM_ADMINISTRATORS/CONFIGURE.md +++ b/DOCUMENTATION/SYSTEM_ADMINISTRATORS/CONFIGURE.md @@ -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 diff --git a/actions/apigrouplistall.php b/actions/apigrouplistall.php index 90f8eed8fa..556306f0bf 100644 --- a/actions/apigrouplistall.php +++ b/actions/apigrouplistall.php @@ -1,55 +1,45 @@ . + /** - * 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 . - * * @category API - * @package StatusNet + * @package GNUsocial * @author Craig Andrews * @author Evan Prodromou * @author Jeffery To * @author Zach Copley * @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 - * @author Evan Prodromou - * @author Jeffery To - * @author Zach Copley - * @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( diff --git a/actions/emailsettings.php b/actions/emailsettings.php index b5933fdb65..1a81304f56 100644 --- a/actions/emailsettings.php +++ b/actions/emailsettings.php @@ -1,48 +1,40 @@ . + /** - * 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 . - * * @category Settings - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @author Zach Copley * @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 - * @author Zach Copley - * @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(); diff --git a/actions/featured.php b/actions/featured.php index f5aaaa130f..b4273a5d4e 100644 --- a/actions/featured.php +++ b/actions/featured.php @@ -1,36 +1,31 @@ . + /** - * 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 . - * * @category Public - * @package StatusNet + * @package GNUsocial * @author Zach Copley * @author Evan Prodromou * @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 - * @author Evan Prodromou - * @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' + ); } } } diff --git a/actions/makeadmin.php b/actions/makeadmin.php index 1bb830f81e..74bbda9a75 100644 --- a/actions/makeadmin.php +++ b/actions/makeadmin.php @@ -1,50 +1,41 @@ - * @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 . - */ - -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 . /** * Make another user an admin of a group * - * @category Action - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ + * @category Action + * @package GNUsocial + * @author Evan Prodromou + * @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] + ); } - } diff --git a/actions/profilesettings.php b/actions/profilesettings.php index a1d947530c..fe31c6c0d6 100644 --- a/actions/profilesettings.php +++ b/actions/profilesettings.php @@ -1,46 +1,38 @@ . + /** - * 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 . - * * @category Settings - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @author Zach Copley * @author Sarven Capadisli * @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 - * @author Zach Copley - * @author Sarven Capadisli - * @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)); diff --git a/actions/selftag.php b/actions/selftag.php index 2fb3b49078..1cf549b8ea 100644 --- a/actions/selftag.php +++ b/actions/selftag.php @@ -1,53 +1,45 @@ . + /** - * 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 . - * * @category Action - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @author Zach Copley * @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 - * @author Zach Copley - * @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(); diff --git a/actions/smssettings.php b/actions/smssettings.php index c002474ce2..1b1909f74b 100644 --- a/actions/smssettings.php +++ b/actions/smssettings.php @@ -1,46 +1,39 @@ . + /** - * 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 . - * - * @category Settings - * @package StatusNet + * @category Setting + * @package GNUsocial * @author Evan Prodromou * @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 - * @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(); diff --git a/actions/sup.php b/actions/sup.php index 5e26e8b106..cf78a2f7d3 100644 --- a/actions/sup.php +++ b/actions/sup.php @@ -1,28 +1,25 @@ . - */ +// 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 . -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; } diff --git a/classes/Avatar.php b/classes/Avatar.php index 5557533ed0..cbb3fc1e5e 100644 --- a/classes/Avatar.php +++ b/classes/Avatar.php @@ -1,6 +1,20 @@ . -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); diff --git a/classes/Conversation.php b/classes/Conversation.php index 04e3daf3ca..4251ba2efa 100644 --- a/classes/Conversation.php +++ b/classes/Conversation.php @@ -1,35 +1,32 @@ . + /** - * 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 . - * * @category Data - * @package StatusNet + * @package GNUsocial * @author Zach Copley * @author Mikael Nordfeldth * @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); diff --git a/classes/File.php b/classes/File.php index 7420eee977..34dba9ae58 100644 --- a/classes/File.php +++ b/classes/File.php @@ -1,29 +1,26 @@ . + /** - * 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 . - * * @category Files * @package GNUsocial * @author Mikael Nordfeldth * @author Miguel Dantas * @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..."; diff --git a/classes/File_redirection.php b/classes/File_redirection.php index d35c608565..fa58f422df 100644 --- a/classes/File_redirection.php +++ b/classes/File_redirection.php @@ -1,28 +1,24 @@ . - */ +// 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 . -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); } diff --git a/classes/File_thumbnail.php b/classes/File_thumbnail.php index 0d084a5784..f93250d832 100644 --- a/classes/File_thumbnail.php +++ b/classes/File_thumbnail.php @@ -1,28 +1,29 @@ . + /* - * 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 . + * @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.'); diff --git a/classes/Group_join_queue.php b/classes/Group_join_queue.php index c4f703b749..8756aab0c3 100644 --- a/classes/Group_join_queue.php +++ b/classes/Group_join_queue.php @@ -1,4 +1,21 @@ . + +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(); diff --git a/classes/Group_member.php b/classes/Group_member.php index f84db6439c..ba12efaf3b 100644 --- a/classes/Group_member.php +++ b/classes/Group_member.php @@ -1,4 +1,21 @@ . + +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); } diff --git a/classes/Managed_DataObject.php b/classes/Managed_DataObject.php index 8c9a55f2b6..5684d8080a 100644 --- a/classes/Managed_DataObject.php +++ b/classes/Managed_DataObject.php @@ -1,28 +1,31 @@ . - */ +// 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 . /** * Wrapper for Memcached_DataObject which knows its own schema definition. * Builds its own damn settings from a schema definition. * - * @author Brion Vibber + * @package GNUsocial + * @author Brion Vibber + * @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() diff --git a/classes/Memcached_DataObject.php b/classes/Memcached_DataObject.php index a4687aeae6..e6dc4d1fc0 100644 --- a/classes/Memcached_DataObject.php +++ b/classes/Memcached_DataObject.php @@ -1,23 +1,25 @@ . +// 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 . + +/** + * @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) { diff --git a/classes/Notice.php b/classes/Notice.php index b78d621c01..4b6f7ee19a 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1,40 +1,39 @@ . + /** - * 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 . - * - * @category Notices - * @package StatusNet - * @author Brenda Wallace - * @author Christopher Vollick - * @author CiaranG - * @author Craig Andrews - * @author Evan Prodromou - * @author Gina Haeussge - * @author Jeffery To - * @author Mike Cochrane - * @author Robin Millette - * @author Sarven Capadisli - * @author Tom Adams - * @author Mikael Nordfeldth + * @category Notices + * @package GNUsocial + * @author Brenda Wallace + * @author Christopher Vollick + * @author CiaranG + * @author Craig Andrews + * @author Evan Prodromou + * @author Gina Haeussge + * @author Jeffery To + * @author Mike Cochrane + * @author Robin Millette + * @author Sarven Capadisli + * @author Tom Adams + * @author Mikael Nordfeldth * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org - * @license GNU Affero General Public License http://www.gnu.org/licenses/ + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ -if (!defined('GNUSOCIAL')) { exit(1); } +defined('GNUSOCIAL') || die(); /** * Table Definition for notice @@ -171,8 +170,8 @@ class Notice extends Managed_DataObject $result = null; if (!$delete_event || Event::handle('DeleteNoticeAsProfile', array($this, $actor, &$result))) { - // If $delete_event is true, we run the event. If the Event then - // returns false it is assumed everything was handled properly + // If $delete_event is true, we run the event. If the Event then + // returns false it is assumed everything was handled properly // and the notice was deleted. $result = $this->delete(); } @@ -215,7 +214,7 @@ class Notice extends Managed_DataObject * * @param string $uri A unique identifier for a resource (notice in this case) */ - static function fromUri($uri) + public static function fromUri($uri) { $notice = null; @@ -255,9 +254,11 @@ class Notice extends Managed_DataObject if (Event::handle('GetNoticeTitle', array($this, &$title)) && $imply) { // TRANS: Title of a notice posted without a title value. // TRANS: %1$s is a user name, %2$s is the notice creation date/time. - $title = sprintf(_('%1$s\'s status on %2$s'), - $this->getProfile()->getFancyName(), - common_exact_date($this->created)); + $title = sprintf( + _('%1$s\'s status on %2$s'), + $this->getProfile()->getFancyName(), + common_exact_date($this->created) + ); } return $title; } @@ -274,9 +275,11 @@ class Notice extends Managed_DataObject // update to include rendered content on-the-fly, so we don't have to have a fix-up script in upgrade.php common_debug('Rendering notice '.$this->getID().' as it had no rendered HTML content.'); $orig = clone($this); - $this->rendered = common_render_content($this->getContent(), - $this->getProfile(), - $this->hasParent() ? $this->getParent() : null); + $this->rendered = common_render_content( + $this->getContent(), + $this->getProfile(), + ($this->hasParent() ? $this->getParent() : null) + ); $this->update($orig); } return $this->rendered; @@ -336,7 +339,8 @@ class Notice extends Managed_DataObject return $selfLink; } - public function getObjectType($canonical=false) { + public function getObjectType($canonical = false) + { if (is_null($this->object_type) || $this->object_type==='') { throw new NoObjectTypeException($this); } @@ -355,7 +359,7 @@ class Notice extends Managed_DataObject /** * Extract #hashtags from this notice's content and save them to the database. */ - function saveTags() + public function saveTags() { /* extract all #hastags */ $count = preg_match_all('/(?:^|\s)#([\pL\pN_\-\.]{1,64})/u', strtolower($this->content), $match); @@ -371,16 +375,16 @@ class Notice extends Managed_DataObject * Record the given set of hash tags in the db for this notice. * Given tag strings will be normalized and checked for dupes. */ - function saveKnownTags($hashtags) + public function saveKnownTags($hashtags) { //turn each into their canonical tag //this is needed to remove dupes before saving e.g. #hash.tag = #hashtag - for($i=0; $isaveTag($hashtag); self::blow('profile:notice_ids_tagged:%d:%s', $this->profile_id, $hashtag); } @@ -391,7 +395,7 @@ class Notice extends Managed_DataObject * Record a single hash tag as associated with this notice. * Tag format and uniqueness must be validated by caller. */ - function saveTag($hashtag) + public function saveTag($hashtag) { $tag = new Notice_tag(); $tag->notice_id = $this->id; @@ -401,8 +405,10 @@ class Notice extends Managed_DataObject if (!$id) { // TRANS: Server exception. %s are the error details. - throw new ServerException(sprintf(_('Database error inserting hashtag: %s.'), - $last_error->message)); + throw new ServerException(sprintf( + _('Database error inserting hashtag: %s.'), + $last_error->message + )); return; } @@ -455,7 +461,8 @@ class Notice extends Managed_DataObject * @return Notice * @throws ClientException */ - static function saveNew($profile_id, $content, $source, array $options=null) { + public static function saveNew($profile_id, $content, $source, array $options = null) + { $defaults = array('uri' => null, 'url' => null, 'self' => null, @@ -602,8 +609,11 @@ class Notice extends Managed_DataObject if (!$reply->inScope($profile)) { // TRANS: Client error displayed when trying to reply to a notice a the target has no access to. // TRANS: %1$s is a user nickname, %2$d is a notice ID (number). - throw new ClientException(sprintf(_('%1$s has no access to notice %2$d.'), - $profile->nickname, $reply->id), 403); + throw new ClientException(sprintf( + _('%1$s has no access to notice %2$d.'), + $profile->nickname, + $reply->id + ), 403); } // If it's a repeat, the reply_to should be to the original @@ -676,9 +686,11 @@ class Notice extends Managed_DataObject if (!empty($rendered)) { $notice->rendered = $rendered; } else { - $notice->rendered = common_render_content($final, - $notice->getProfile(), - $notice->hasParent() ? $notice->getParent() : null); + $notice->rendered = common_render_content( + $final, + $notice->getProfile(), + ($notice->hasParent() ? $notice->getParent() : null) + ); } if (empty($verb)) { @@ -769,7 +781,7 @@ class Notice extends Managed_DataObject return $notice; } - static function saveActivity(Activity $act, Profile $actor, array $options=array()) + public static function saveActivity(Activity $act, Profile $actor, array $options = []) { // First check if we're going to let this Activity through from the specific actor if (!$actor->hasRight(Right::NEWNOTICE)) { @@ -1065,7 +1077,6 @@ class Notice extends Managed_DataObject // the activityverb is a POST (since stuff like repeat, favorite etc. // reasonably handle notifications themselves. if (ActivityUtils::compareVerbs($stored->verb, array(ActivityVerb::POST))) { - if (!empty($tags)) { $stored->saveKnownTags($tags); } else { @@ -1091,7 +1102,8 @@ class Notice extends Managed_DataObject return $stored; } - static public function figureOutScope(Profile $actor, array $groups, $scope=null) { + public static function figureOutScope(Profile $actor, array $groups, $scope = null) + { $scope = is_null($scope) ? self::defaultScope() : intval($scope); // For private streams @@ -1121,7 +1133,7 @@ class Notice extends Managed_DataObject return $scope; } - function blowOnInsert($conversation = false) + public function blowOnInsert($conversation = false) { $this->blowStream('profile:notice_ids:%d', $this->profile_id); @@ -1166,7 +1178,7 @@ class Notice extends Managed_DataObject * Clear cache entries related to this notice at delete time. * Necessary to avoid breaking paging on public, profile timelines. */ - function blowOnDelete() + public function blowOnDelete() { $this->blowOnInsert(); @@ -1190,7 +1202,7 @@ class Notice extends Managed_DataObject } } - function blowStream() + public function blowStream() { $c = self::memcache(); @@ -1229,7 +1241,8 @@ class Notice extends Managed_DataObject * * @return void */ - function saveUrls() { + public function saveUrls() + { if (common_config('attachments', 'process_links')) { common_replace_urls_callback($this->content, array($this, 'saveUrl'), $this); } @@ -1243,7 +1256,7 @@ class Notice extends Managed_DataObject * * @return void */ - function saveKnownUrls($urls) + public function saveKnownUrls($urls) { if (common_config('attachments', 'process_links')) { // @fixme validation? @@ -1256,7 +1269,8 @@ class Notice extends Managed_DataObject /** * @private callback */ - function saveUrl($url, Notice $notice) { + public function saveUrl($url, Notice $notice) + { try { File::processNew($url, $notice); } catch (ServerException $e) { @@ -1264,7 +1278,8 @@ class Notice extends Managed_DataObject } } - static function checkDupes($profile_id, $content) { + public static function checkDupes($profile_id, $content) + { $profile = Profile::getKV($profile_id); if (!$profile instanceof Profile) { return false; @@ -1275,7 +1290,7 @@ class Notice extends Managed_DataObject while ($notice->fetch()) { if (time() - strtotime($notice->created) >= common_config('site', 'dupelimit')) { return true; - } else if ($notice->content == $content) { + } elseif ($notice->content === $content) { return false; } } @@ -1292,7 +1307,8 @@ class Notice extends Managed_DataObject return ($cnt == 0); } - static function checkEditThrottle($profile_id) { + public static function checkEditThrottle($profile_id) + { $profile = Profile::getKV($profile_id); if (!$profile instanceof Profile) { return false; @@ -1310,34 +1326,35 @@ class Notice extends Managed_DataObject return true; } - protected $_attachments = array(); + protected $_attachments = []; - function attachments() { - if (isset($this->_attachments[$this->id])) { + public function attachments() + { + if (isset($this->_attachments[$this->id])) { return $this->_attachments[$this->id]; } $f2ps = File_to_post::listGet('post_id', array($this->id)); - $ids = array(); - foreach ($f2ps[$this->id] as $f2p) { + $ids = []; + foreach ($f2ps[$this->id] as $f2p) { $ids[] = $f2p->file_id; } return $this->_setAttachments(File::multiGet('id', $ids)->fetchAll()); } - public function _setAttachments(array $attachments) - { - return $this->_attachments[$this->id] = $attachments; - } + public function _setAttachments(array $attachments) + { + return $this->_attachments[$this->id] = $attachments; + } - static function publicStream($offset=0, $limit=20, $since_id=null, $max_id=null) + public static function publicStream($offset = 0, $limit = 20, $since_id = null, $max_id = null) { $stream = new PublicNoticeStream(); return $stream->getNotices($offset, $limit, $since_id, $max_id); } - static function conversationStream($id, $offset=0, $limit=20, $since_id=null, $max_id=null, Profile $scoped=null) + public static function conversationStream($id, $offset = 0, $limit = 20, $since_id = null, $max_id = null, Profile $scoped = null) { $stream = new ConversationNoticeStream($id, $scoped); return $stream->getNotices($offset, $limit, $since_id, $max_id); @@ -1349,7 +1366,7 @@ class Notice extends Managed_DataObject * @return boolean true if other messages exist in the same * conversation, false if this is the only one */ - function hasConversation() + public function hasConversation() { if (empty($this->conversation)) { // this notice is not part of a conversation apparently @@ -1370,7 +1387,7 @@ class Notice extends Managed_DataObject * * @return Notice or null */ - function conversationRoot($profile=-1) + public function conversationRoot($profile = -1) { // XXX: can this happen? @@ -1405,9 +1422,11 @@ class Notice extends Managed_DataObject if (is_null($profile)) { $keypart = sprintf('notice:conversation_root:%d:null', $this->id); } else { - $keypart = sprintf('notice:conversation_root:%d:%d', - $this->id, - $profile->id); + $keypart = sprintf( + 'notice:conversation_root:%d:%d', + $this->id, + $profile->id + ); } $root = self::cacheGet($keypart); @@ -1452,7 +1471,7 @@ class Notice extends Managed_DataObject * if left empty, will be loaded from reply records * @return array associating recipient user IDs with an inbox source constant */ - function whoGets(array $groups=null, array $recipients=null) + public function whoGets(array $groups = null, array $recipients = null) { $c = self::memcache(); @@ -1471,7 +1490,6 @@ class Notice extends Managed_DataObject // Give plugins a chance to add folks in at start... if (Event::handle('StartNoticeWhoGets', array($this, &$ni))) { - $users = $this->getSubscribedUsers(); foreach ($users as $id) { $ni[$id] = NOTICE_INBOX_SOURCE_SUB; @@ -1539,23 +1557,19 @@ class Notice extends Managed_DataObject return $ni; } - function getSubscribedUsers() + public function getSubscribedUsers() { $user = new User(); - if(common_config('db','quote_identifiers')) - $user_table = '"user"'; - else $user_table = 'user'; + $user->query(sprintf( + 'SELECT id FROM %1$s INNER JOIN subscription ' . + 'ON %1$s.id = subscription.subscriber ' . + 'WHERE subscription.subscribed = %2$d ', + $user->escapedTableName(), + $this->profile_id + )); - $qry = - 'SELECT id ' . - 'FROM '. $user_table .' JOIN subscription '. - 'ON '. $user_table .'.id = subscription.subscriber ' . - 'WHERE subscription.subscribed = %d '; - - $user->query(sprintf($qry, $this->profile_id)); - - $ids = array(); + $ids = []; while ($user->fetch()) { $ids[] = $user->id; @@ -1566,14 +1580,14 @@ class Notice extends Managed_DataObject return $ids; } - function getProfileTags() + public function getProfileTags() { $ptags = array(); try { $profile = $this->getProfile(); $list = $profile->getOtherTags($profile); - while($list->fetch()) { + while ($list->fetch()) { $ptags[] = clone($list); } } catch (Exception $e) { @@ -1605,7 +1619,7 @@ class Notice extends Managed_DataObject * best with generalizations on user_group to support * remote groups better. */ - function saveKnownGroups(array $group_ids) + public function saveKnownGroups(array $group_ids) { $groups = array(); foreach (array_unique($group_ids) as $id) { @@ -1637,13 +1651,12 @@ class Notice extends Managed_DataObject return $groups; } - function addToGroupInbox(User_group $group) + public function addToGroupInbox(User_group $group) { $gi = Group_inbox::pkeyGet(array('group_id' => $group->id, 'notice_id' => $this->id)); if (!$gi instanceof Group_inbox) { - $gi = new Group_inbox(); $gi->group_id = $group->id; @@ -1664,7 +1677,7 @@ class Notice extends Managed_DataObject return true; } - function saveAttentions(array $uris) + public function saveAttentions(array $uris) { foreach ($uris as $uri=>$type) { try { @@ -1677,7 +1690,7 @@ class Notice extends Managed_DataObject try { $this->saveAttention($target); } catch (AlreadyFulfilledException $e) { - common_debug('Attention already exists: '.var_export($e->getMessage(),true)); + common_debug('Attention already exists: ' . var_export($e->getMessage(), true)); } catch (Exception $e) { common_log(LOG_ERR, "Could not save notice id=={$this->getID()} attention for profile id=={$target->getID()}: {$e->getMessage()}"); } @@ -1688,7 +1701,7 @@ class Notice extends Managed_DataObject * Saves an attention for a profile (user or group) which means * it shows up in their home feed and such. */ - function saveAttention(Profile $target, $reason=null) + public function saveAttention(Profile $target, $reason = null) { if ($target->isGroup()) { // FIXME: Make sure we check (for both local and remote) users are in the groups they send to! @@ -1723,7 +1736,7 @@ class Notice extends Managed_DataObject * * @param array $uris Array of unique identifier URIs for recipients */ - function saveKnownReplies(array $uris) + public function saveKnownReplies(array $uris) { if (empty($uris)) { return; @@ -1759,7 +1772,7 @@ class Notice extends Managed_DataObject * @return array of integer profile IDs */ - function saveReplies() + public function saveReplies() { $sender = $this->getProfile(); @@ -1786,7 +1799,6 @@ class Notice extends Managed_DataObject $mentions = common_find_mentions($this->content, $sender, $parent); foreach ($mentions as $mention) { - foreach ($mention['mentioned'] as $mentioned) { // skip if they're already covered @@ -1810,7 +1822,7 @@ class Notice extends Managed_DataObject return $recipientIds; } - function saveReply($profileId) + public function saveReply($profileId) { $reply = new Reply(); @@ -1830,7 +1842,7 @@ class Notice extends Managed_DataObject * * @return array of integer profile ids (also group profiles) */ - function getAttentionProfileIDs() + public function getAttentionProfileIDs() { if (!isset($this->_attentionids[$this->getID()])) { $atts = Attention::multiGet('notice_id', array($this->getID())); @@ -1847,7 +1859,7 @@ class Notice extends Managed_DataObject * * @return array of integer profile ids */ - function getReplies() + public function getReplies() { if (!isset($this->_replies[$this->getID()])) { $mentions = Reply::multiGet('notice_id', array($this->getID())); @@ -1856,7 +1868,7 @@ class Notice extends Managed_DataObject return $this->_replies[$this->getID()]; } - function _setReplies($replies) + public function _setReplies($replies) { $this->_replies[$this->getID()] = $replies; } @@ -1866,7 +1878,7 @@ class Notice extends Managed_DataObject * * @return array of Profiles */ - function getAttentionProfiles() + public function getAttentionProfiles() { $ids = array_unique(array_merge($this->getReplies(), $this->getGroupProfileIDs(), $this->getAttentionProfileIDs())); @@ -1881,7 +1893,7 @@ class Notice extends Managed_DataObject * Replies must already have been saved; this is expected to be run * from the distrib queue handler. */ - function sendReplyNotifications() + public function sendReplyNotifications() { // Don't send reply notifications for repeats if ($this->isRepeat()) { @@ -1910,13 +1922,13 @@ class Notice extends Managed_DataObject * @return array of Group _profile_ IDs */ - function getGroupProfileIDs() + public function getGroupProfileIDs() { $ids = array(); - foreach ($this->getGroups() as $group) { - $ids[] = $group->profile_id; - } + foreach ($this->getGroups() as $group) { + $ids[] = $group->profile_id; + } return $ids; } @@ -1930,7 +1942,7 @@ class Notice extends Managed_DataObject protected $_groups = array(); - function getGroups() + public function getGroups() { // Don't save groups for repeats @@ -1944,18 +1956,18 @@ class Notice extends Managed_DataObject $gis = Group_inbox::listGet('notice_id', array($this->id)); - $ids = array(); + $ids = []; - foreach ($gis[$this->id] as $gi) { - $ids[] = $gi->group_id; - } + foreach ($gis[$this->id] as $gi) { + $ids[] = $gi->group_id; + } - $groups = User_group::multiGet('id', $ids); - $this->_groups[$this->id] = $groups->fetchAll(); - return $this->_groups[$this->id]; + $groups = User_group::multiGet('id', $ids); + $this->_groups[$this->id] = $groups->fetchAll(); + return $this->_groups[$this->id]; } - function _setGroups($groups) + public function _setGroups($groups) { $this->_groups[$this->id] = $groups; } @@ -1970,7 +1982,7 @@ class Notice extends Managed_DataObject * @throws ServerException */ - function asActivity(Profile $scoped=null) + public function asActivity(Profile $scoped = null) { $act = self::cacheGet(Cache::codeKey('notice:as-activity:'.$this->id)); @@ -1980,7 +1992,6 @@ class Notice extends Managed_DataObject $act = new Activity(); if (Event::handle('StartNoticeAsActivity', array($this, $act, $scoped))) { - $act->id = $this->uri; $act->time = strtotime($this->created); try { @@ -2085,7 +2096,6 @@ class Notice extends Managed_DataObject $atom_feed = $profile->getAtomFeed(); if (!empty($atom_feed)) { - $act->source = new ActivitySource(); // XXX: we should store the actual feed ID @@ -2134,10 +2144,7 @@ class Notice extends Managed_DataObject // This has gotten way too long. Needs to be sliced up into functional bits // or ideally exported to a utility class. - function asAtomEntry($namespace=false, - $source=false, - $author=true, - Profile $scoped=null) + public function asAtomEntry($namespace = false, $source = false, $author = true, Profile $scoped = null) { $act = $this->asActivity($scoped); $act->extra[] = $this->noticeInfo($scoped); @@ -2155,7 +2162,7 @@ class Notice extends Managed_DataObject * @return array representation of element */ - function noticeInfo(Profile $scoped=null) + public function noticeInfo(Profile $scoped = null) { // local notice ID (useful to clients for ordering) @@ -2200,7 +2207,7 @@ class Notice extends Managed_DataObject * @return string */ - function asActivityNoun($element) + public function asActivityNoun($element) { $noun = $this->asActivityObject(); return $noun->asString('activity:' . $element); @@ -2250,7 +2257,7 @@ class Notice extends Managed_DataObject * @return integer ID of replied-to notice, or null for not a reply. */ - static function getInlineReplyTo(Profile $sender, $content) + public static function getInlineReplyTo(Profile $sender, $content) { // Is there an initial @ or T? if (preg_match('/^T ([A-Z0-9]{1,64}) /', $content, $match) @@ -2276,7 +2283,7 @@ class Notice extends Managed_DataObject return null; } - static function maxContent() + public static function maxContent() { $contentlimit = common_config('notice', 'contentlimit'); // null => use global limit (distinct from 0!) @@ -2286,7 +2293,7 @@ class Notice extends Managed_DataObject return $contentlimit; } - static function contentTooLong($content) + public static function contentTooLong($content) { $contentlimit = self::maxContent(); return ($contentlimit > 0 && !empty($content) && (mb_strlen($content) > $contentlimit)); @@ -2301,15 +2308,17 @@ class Notice extends Managed_DataObject * * @throws Exception on failure or permission problems */ - function repeat(Profile $repeater, $source) + public function repeat(Profile $repeater, $source) { $author = $this->getProfile(); // TRANS: Message used to repeat a notice. RT is the abbreviation of 'retweet'. // TRANS: %1$s is the repeated user's name, %2$s is the repeated notice. - $content = sprintf(_('RT @%1$s %2$s'), - $author->getNickname(), - $this->content); + $content = sprintf( + _('RT @%1$s %2$s'), + $author->getNickname(), + $this->content + ); $maxlen = self::maxContent(); if ($maxlen > 0 && mb_strlen($content) > $maxlen) { @@ -2324,16 +2333,17 @@ class Notice extends Managed_DataObject // Scope is same as this one's - return self::saveNew($repeater->id, - $content, - $source, - array('repeat_of' => $this->id, - 'scope' => $this->scope)); + return self::saveNew( + $repeater->id, + $content, + $source, + ['repeat_of' => $this->id, 'scope' => $this->scope] + ); } // These are supposed to be in chron order! - function repeatStream($limit=100) + public function repeatStream($limit = 100) { $cache = Cache::instance(); @@ -2342,11 +2352,11 @@ class Notice extends Managed_DataObject } else { $idstr = $cache->get(Cache::key('notice:repeats:'.$this->id)); if ($idstr !== false) { - if (empty($idstr)) { - $ids = array(); - } else { - $ids = explode(',', $idstr); - } + if (!empty($idstr)) { + $ids = explode(',', $idstr); + } else { + $ids = []; + } } else { $ids = $this->_repeatStreamDirect(100); $cache->set(Cache::key('notice:repeats:'.$this->id), implode(',', $ids)); @@ -2360,7 +2370,7 @@ class Notice extends Managed_DataObject return NoticeStream::getStreamByIds($ids); } - function _repeatStreamDirect($limit) + public function _repeatStreamDirect($limit) { $notice = new Notice(); @@ -2378,7 +2388,7 @@ class Notice extends Managed_DataObject return $notice->fetchAll('id'); } - static function locationOptions($lat, $lon, $location_id, $location_ns, $profile = null) + public static function locationOptions($lat, $lon, $location_id, $location_ns, $profile = null) { $options = array(); @@ -2392,8 +2402,7 @@ class Notice extends Managed_DataObject $options['lat'] = $location->lat; $options['lon'] = $location->lon; } - - } else if (!empty($lat) && !empty($lon)) { + } elseif (!empty($lat) && !empty($lon)) { $options['lat'] = $lat; $options['lon'] = $lon; @@ -2403,7 +2412,7 @@ class Notice extends Managed_DataObject $options['location_id'] = $location->location_id; $options['location_ns'] = $location->location_ns; } - } else if (!empty($profile)) { + } elseif (!empty($profile)) { if (isset($profile->lat) && isset($profile->lon)) { $options['lat'] = $profile->lat; $options['lon'] = $profile->lon; @@ -2418,7 +2427,7 @@ class Notice extends Managed_DataObject return $options; } - function clearAttentions() + public function clearAttentions() { $att = new Attention(); $att->notice_id = $this->getID(); @@ -2432,7 +2441,7 @@ class Notice extends Managed_DataObject } } - function clearReplies() + public function clearReplies() { $replyNotice = new Notice(); $replyNotice->reply_to = $this->id; @@ -2453,7 +2462,7 @@ class Notice extends Managed_DataObject $reply->notice_id = $this->id; if ($reply->find()) { - while($reply->fetch()) { + while ($reply->fetch()) { self::blow('reply:stream:%d', $reply->profile_id); $reply->delete(); } @@ -2462,7 +2471,7 @@ class Notice extends Managed_DataObject $reply->free(); } - function clearLocation() + public function clearLocation() { $loc = new Notice_location(); $loc->notice_id = $this->id; @@ -2472,7 +2481,7 @@ class Notice extends Managed_DataObject } } - function clearFiles() + public function clearFiles() { $f2p = new File_to_post(); @@ -2487,7 +2496,7 @@ class Notice extends Managed_DataObject // ...and related (actual) files } - function clearRepeats() + public function clearRepeats() { $repeatNotice = new Notice(); $repeatNotice->repeat_of = $this->id; @@ -2503,7 +2512,7 @@ class Notice extends Managed_DataObject } } - function clearTags() + public function clearTags() { $tag = new Notice_tag(); $tag->notice_id = $this->id; @@ -2521,7 +2530,7 @@ class Notice extends Managed_DataObject $tag->free(); } - function clearGroupInboxes() + public function clearGroupInboxes() { $gi = new Group_inbox(); @@ -2537,7 +2546,7 @@ class Notice extends Managed_DataObject $gi->free(); } - function distribute() + public function distribute() { // We always insert for the author so they don't // have to wait @@ -2563,7 +2572,7 @@ class Notice extends Managed_DataObject } } - function insert() + public function insert() { $result = parent::insert(); @@ -2578,9 +2587,10 @@ class Notice extends Managed_DataObject if (!empty($this->repeat_of)) { $c = self::memcache(); if (!empty($c)) { - $ck = self::multicacheKey('Notice', - array('profile_id' => $this->profile_id, - 'repeat_of' => $this->repeat_of)); + $ck = self::multicacheKey( + 'Notice', + ['profile_id' => $this->profile_id, 'repeat_of' => $this->repeat_of] + ); $c->delete($ck); } } @@ -2593,10 +2603,14 @@ class Notice extends Managed_DataObject // We can only get here if it's a local notice, since remote notices // should've bailed out earlier due to lacking a URI. if (empty($this->uri)) { - $this->uri = sprintf('%s%s=%d:%s=%s', - TagURI::mint(), - 'noticeId', $this->id, - 'objectType', $this->getObjectType(true)); + $this->uri = sprintf( + '%s%s=%d:%s=%s', + TagURI::mint(), + 'noticeId', + $this->id, + 'objectType', + $this->getObjectType(true) + ); $changed = true; } @@ -2617,7 +2631,7 @@ class Notice extends Managed_DataObject * @return Notice_source $ns A notice source object. 'code' is the only attribute * guaranteed to be populated. */ - function getSource() + public function getSource() { if (empty($this->source)) { return false; @@ -2708,7 +2722,7 @@ class Notice extends Managed_DataObject return $tags; } - static private function utcDate($dt) + private static function utcDate($dt) { $dateStr = date('d F Y H:i:s', strtotime($dt)); $d = new DateTime($dateStr, new DateTimeZone('UTC')); @@ -2841,7 +2855,7 @@ class Notice extends Managed_DataObject * * @return boolean whether the profile is in the notice's scope */ - function inScope($profile) + public function inScope($profile) { if (is_null($profile)) { $keypart = sprintf('notice:in-scope-for:%d:null', $this->id); @@ -2889,7 +2903,6 @@ class Notice extends Managed_DataObject // Only for users mentioned in the notice if ($scope & Notice::ADDRESSEE_SCOPE) { - $reply = Reply::pkeyGet(array('notice_id' => $this->id, 'profile_id' => $profile->id)); @@ -2920,7 +2933,6 @@ class Notice extends Managed_DataObject } if ($scope & Notice::FOLLOWER_SCOPE || $this->getProfile()->isPrivateStream()) { - if (!Subscription::exists($profile, $this->getProfile())) { return false; } @@ -2929,15 +2941,15 @@ class Notice extends Managed_DataObject return !$this->isHiddenSpam($profile); } - function isHiddenSpam($profile) { + public function isHiddenSpam($profile) + { // Hide posts by silenced users from everyone but moderators. if (common_config('notice', 'hidespam')) { - try { $author = $this->getProfile(); - } catch(Exception $e) { + } catch (Exception $e) { // If we can't get an author, keep it hidden. // XXX: technically not spam, but, whatever. return true; @@ -2977,7 +2989,7 @@ class Notice extends Managed_DataObject // the timeline will not display correctly. try { $reply_to_id = self::getByID($this->reply_to); - } catch(Exception $e){ + } catch (Exception $e) { throw new NoParentNoticeException($this); } @@ -2994,106 +3006,103 @@ class Notice extends Managed_DataObject * @return array of variable names to include in serialization. */ - function __sleep() + public function __sleep() { $vars = parent::__sleep(); $skip = array('_profile', '_groups', '_attachments', '_faves', '_replies', '_repeats'); return array_diff($vars, $skip); } - static function defaultScope() + public static function defaultScope() { - $scope = common_config('notice', 'defaultscope'); - if (is_null($scope)) { - if (common_config('site', 'private')) { - $scope = 1; - } else { - $scope = 0; - } - } - return $scope; + $scope = common_config('notice', 'defaultscope'); + if (is_null($scope)) { + if (common_config('site', 'private')) { + $scope = 1; + } else { + $scope = 0; + } + } + return $scope; } - static function fillProfiles($notices) - { - $map = self::getProfiles($notices); - foreach ($notices as $entry=>$notice) { + public static function fillProfiles($notices) + { + $map = self::getProfiles($notices); + foreach ($notices as $entry => $notice) { try { - if (array_key_exists($notice->profile_id, $map)) { - $notice->_setProfile($map[$notice->profile_id]); - } + if (array_key_exists($notice->profile_id, $map)) { + $notice->_setProfile($map[$notice->profile_id]); + } } catch (NoProfileException $e) { common_log(LOG_WARNING, "Failed to fill profile in Notice with non-existing entry for profile_id: {$e->profile_id}"); unset($notices[$entry]); } - } + } - return array_values($map); - } - - static function getProfiles(&$notices) - { - $ids = array(); - foreach ($notices as $notice) { - $ids[] = $notice->profile_id; - } - $ids = array_unique($ids); - return Profile::pivotGet('id', $ids); - } - - static function fillGroups(&$notices) - { - $ids = self::_idsOf($notices); - $gis = Group_inbox::listGet('notice_id', $ids); - $gids = array(); - - foreach ($gis as $id => $gi) { - foreach ($gi as $g) - { - $gids[] = $g->group_id; - } - } - - $gids = array_unique($gids); - $group = User_group::pivotGet('id', $gids); - foreach ($notices as $notice) - { - $grps = array(); - $gi = $gis[$notice->id]; - foreach ($gi as $g) { - $grps[] = $group[$g->group_id]; - } - $notice->_setGroups($grps); - } - } - - static function _idsOf(array &$notices) - { - $ids = array(); - foreach ($notices as $notice) { - $ids[$notice->id] = true; - } - return array_keys($ids); + return array_values($map); } - static function fillAttachments(&$notices) + public static function getProfiles(&$notices) + { + $ids = []; + foreach ($notices as $notice) { + $ids[] = $notice->profile_id; + } + $ids = array_unique($ids); + return Profile::pivotGet('id', $ids); + } + + public static function fillGroups(&$notices) + { + $ids = self::_idsOf($notices); + $gis = Group_inbox::listGet('notice_id', $ids); + $gids = []; + + foreach ($gis as $id => $gi) { + foreach ($gi as $g) { + $gids[] = $g->group_id; + } + } + + $gids = array_unique($gids); + $group = User_group::pivotGet('id', $gids); + foreach ($notices as $notice) { + $grps = []; + $gi = $gis[$notice->id]; + foreach ($gi as $g) { + $grps[] = $group[$g->group_id]; + } + $notice->_setGroups($grps); + } + } + + public static function _idsOf(array &$notices) + { + $ids = []; + foreach ($notices as $notice) { + $ids[$notice->id] = true; + } + return array_keys($ids); + } + + public static function fillAttachments(&$notices) { $ids = self::_idsOf($notices); $f2pMap = File_to_post::listGet('post_id', $ids); - $fileIds = array(); - foreach ($f2pMap as $noticeId => $f2ps) { + $fileIds = []; + foreach ($f2pMap as $noticeId => $f2ps) { foreach ($f2ps as $f2p) { $fileIds[] = $f2p->file_id; } } $fileIds = array_unique($fileIds); - $fileMap = File::pivotGet('id', $fileIds); - foreach ($notices as $notice) - { - $files = array(); - $f2ps = $f2pMap[$notice->id]; - foreach ($f2ps as $f2p) { + $fileMap = File::pivotGet('id', $fileIds); + foreach ($notices as $notice) { + $files = []; + $f2ps = $f2pMap[$notice->id]; + foreach ($f2ps as $f2p) { if (!isset($fileMap[$f2p->file_id])) { // We have probably deleted value from fileMap since // it as a NULL entry (see the following elseif). @@ -3107,13 +3116,13 @@ class Notice extends Managed_DataObject unset($fileMap[$f2p->file_id]); continue; } - $files[] = $fileMap[$f2p->file_id]; - } - $notice->_setAttachments($files); - } + $files[] = $fileMap[$f2p->file_id]; + } + $notice->_setAttachments($files); + } } - static function fillReplies(&$notices) + public static function fillReplies(&$notices) { $ids = self::_idsOf($notices); $replyMap = Reply::listGet('notice_id', $ids); @@ -3127,7 +3136,7 @@ class Notice extends Managed_DataObject } } - static public function beforeSchemaUpdate() + public static function beforeSchemaUpdate() { $table = strtolower(get_called_class()); $schema = Schema::get(); @@ -3146,12 +3155,14 @@ class Notice extends Managed_DataObject echo "\nFound old $table table, moving location data to 'notice_location' table... (this will probably take a LONG time, but can be aborted and continued)"; $notice = new Notice(); - $notice->query(sprintf('SELECT id, lat, lon, location_id, location_ns FROM %1$s ' . - 'WHERE lat IS NOT NULL ' . - 'OR lon IS NOT NULL ' . - 'OR location_id IS NOT NULL ' . - 'OR location_ns IS NOT NULL', - $schema->quoteIdentifier($table))); + $notice->query(sprintf( + 'SELECT id, lat, lon, location_id, location_ns FROM %1$s ' . + 'WHERE lat IS NOT NULL ' . + 'OR lon IS NOT NULL ' . + 'OR location_id IS NOT NULL ' . + 'OR location_ns IS NOT NULL', + common_database_tablename($table) + )); print "\nFound {$notice->N} notices with location data, inserting"; while ($notice->fetch()) { $notloc = Notice_location::getKV('notice_id', $notice->id); @@ -3230,10 +3241,12 @@ class Notice extends Managed_DataObject } unset($notice); $notice = new Notice(); - $notice->query(sprintf('UPDATE %1$s SET %2$s=NULL WHERE id IN (%3$s)', - $notice->escapedTableName(), - $field, - implode(',', $ids))); + $notice->query(sprintf( + 'UPDATE %1$s SET %2$s = NULL WHERE id IN (%3$s)', + $notice->escapedTableName(), + $field, + implode(',', $ids) + )); break; default: throw new ServerException('The programmer sucks, invalid action name when fixing table.'); @@ -3245,11 +3258,13 @@ class Notice extends Managed_DataObject } } - public function delPref($namespace, $topic) { + public function delPref($namespace, $topic) + { return Notice_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 Notice_prefs::getData directly try { return Notice_prefs::getData($this, $namespace, $topic, $default); @@ -3264,7 +3279,8 @@ class Notice extends Managed_DataObject return Notice_prefs::getConfigData($this, $namespace, $topic); } - public function setPref($namespace, $topic, $data) { + public function setPref($namespace, $topic, $data) + { return Notice_prefs::setData($this, $namespace, $topic, $data); } } diff --git a/classes/Notice_prefs.php b/classes/Notice_prefs.php index a13d2c44b3..e2c96f482d 100644 --- a/classes/Notice_prefs.php +++ b/classes/Notice_prefs.php @@ -1,32 +1,32 @@ . + /** - * 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 . - * * @category Data * @package GNUsocial * @author Mikael Nordfeldth - * @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 + * @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) { diff --git a/classes/Notice_source.php b/classes/Notice_source.php index 43a8263d85..03f3ca1498 100644 --- a/classes/Notice_source.php +++ b/classes/Notice_source.php @@ -1,9 +1,26 @@ . + +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'), ), diff --git a/classes/Oauth_application_user.php b/classes/Oauth_application_user.php index 402afbc4c2..3fc64c7941 100644 --- a/classes/Oauth_application_user.php +++ b/classes/Oauth_application_user.php @@ -1,9 +1,26 @@ . + +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) { diff --git a/classes/Oauth_token_association.php b/classes/Oauth_token_association.php index 8c444e3b14..7ad0186614 100644 --- a/classes/Oauth_token_association.php +++ b/classes/Oauth_token_association.php @@ -1,9 +1,26 @@ . + +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')), ) ); } diff --git a/classes/Old_school_prefs.php b/classes/Old_school_prefs.php index 52f72eaa5c..44303b959c 100644 --- a/classes/Old_school_prefs.php +++ b/classes/Old_school_prefs.php @@ -1,48 +1,36 @@ . + /** - * 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 . * * @category UI - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 * @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'), diff --git a/classes/Profile.php b/classes/Profile.php index 4b5badc663..17fe104070 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -1,23 +1,25 @@ . +// 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 . + +/** + * @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 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); } diff --git a/classes/Profile_list.php b/classes/Profile_list.php index 8c9aa49d78..4e8b231e19 100644 --- a/classes/Profile_list.php +++ b/classes/Profile_list.php @@ -1,27 +1,28 @@ . + /** - * 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 . - * - * @category Notices - * @package StatusNet - * @author Shashi Gowda - * @license GNU Affero General Public License http://www.gnu.org/licenses/ + * @category Notices + * @package GNUsocial + * @author Shashi Gowda + * @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) { diff --git a/classes/Profile_prefs.php b/classes/Profile_prefs.php index d9fcca8baf..d8ad9aab35 100644 --- a/classes/Profile_prefs.php +++ b/classes/Profile_prefs.php @@ -1,32 +1,31 @@ . + /** - * 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 . - * * @category Data * @package GNUsocial * @author Mikael Nordfeldth - * @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) { diff --git a/classes/Profile_tag.php b/classes/Profile_tag.php index bf466e624c..02fae227a4 100644 --- a/classes/Profile_tag.php +++ b/classes/Profile_tag.php @@ -1,8 +1,24 @@ . + +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; } diff --git a/classes/Subscription.php b/classes/Subscription.php index bc707bb16a..f075acb33c 100644 --- a/classes/Subscription.php +++ b/classes/Subscription.php @@ -1,23 +1,25 @@ . +// 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 . + +/** + * @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); diff --git a/classes/User.php b/classes/User.php index 7774ef53ca..46d28443a1 100644 --- a/classes/User.php +++ b/classes/User.php @@ -1,23 +1,20 @@ . - */ +// 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 . -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; } diff --git a/classes/User_group.php b/classes/User_group.php index 21a1068616..92ea7ce151 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -1,8 +1,24 @@ . + +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); diff --git a/classes/User_im_prefs.php b/classes/User_im_prefs.php index af11f7b2f4..11a8bedc4b 100644 --- a/classes/User_im_prefs.php +++ b/classes/User_im_prefs.php @@ -1,32 +1,31 @@ . + /** - * 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 . - * * @category Data - * @package StatusNet + * @package GNUsocial * @author Craig Andrews * @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 ), ); } - } diff --git a/classes/User_location_prefs.php b/classes/User_location_prefs.php index a55804f776..b825999e21 100644 --- a/classes/User_location_prefs.php +++ b/classes/User_location_prefs.php @@ -1,30 +1,27 @@ . + /** - * 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 . - * * @category Data - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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'), ), diff --git a/classes/User_username.php b/classes/User_username.php index 4cb0a3b6a7..6b7d3728b8 100644 --- a/classes/User_username.php +++ b/classes/User_username.php @@ -1,9 +1,26 @@ . + +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; } } diff --git a/db/core.php b/db/core.php index 56213eb338..958ace0bbf 100644 --- a/db/core.php +++ b/db/core.php @@ -1,13 +1,23 @@ . /** * * 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']); } diff --git a/db/sms_carrier.sql b/db/sms_carrier.sql index 14074e7189..59848d1c19 100644 --- a/db/sms_carrier.sql +++ b/db/sms_carrier.sql @@ -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()), diff --git a/extlib/DB/DataObject.php b/extlib/DB/DataObject.php index bf16d87eba..f9678983c4 100644 --- a/extlib/DB/DataObject.php +++ b/extlib/DB/DataObject.php @@ -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); } diff --git a/lib/action/action.php b/lib/action/action.php index 1f50351d3a..a768264357 100644 --- a/lib/action/action.php +++ b/lib/action/action.php @@ -1,36 +1,31 @@ . + /** - * 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 . - * * @category Action - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @author Sarven Capadisli * @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 - * @author Sarven Capadisli - * @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 * diff --git a/lib/database/mysqlschema.php b/lib/database/mysqlschema.php index bd4ac34a3d..1be6ad6977 100644 --- a/lib/database/mysqlschema.php +++ b/lib/database/mysqlschema.php @@ -17,9 +17,9 @@ /** * Database schema for MariaDB * - * @category Database - * @package GNUsocial - * @author Evan Prodromou + * @category Database + * @package GNUsocial + * @author Evan Prodromou * @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) { diff --git a/lib/database/pgsqlschema.php b/lib/database/pgsqlschema.php index 15dcf97d82..1923c121d7 100644 --- a/lib/database/pgsqlschema.php +++ b/lib/database/pgsqlschema.php @@ -17,11 +17,11 @@ /** * Database schema for PostgreSQL * - * @category Database - * @package GNUsocial - * @author Evan Prodromou - * @author Brenda Wallace - * @author Brion Vibber + * @category Database + * @package GNUsocial + * @author Evan Prodromou + * @author Brenda Wallace + * @author Brion Vibber * @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) { diff --git a/lib/database/schema.php b/lib/database/schema.php index 1b0a38ea8b..6c6ac4e6a6 100644 --- a/lib/database/schema.php +++ b/lib/database/schema.php @@ -17,10 +17,10 @@ /** * Database schema * - * @category Database - * @package GNUsocial - * @author Evan Prodromou - * @author Brion Vibber + * @category Database + * @package GNUsocial + * @author Evan Prodromou + * @author Brion Vibber * @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 } - diff --git a/lib/groups/groupsbymemberssection.php b/lib/groups/groupsbymemberssection.php index 9b1bac2154..ef04468b17 100644 --- a/lib/groups/groupsbymemberssection.php +++ b/lib/groups/groupsbymemberssection.php @@ -1,77 +1,60 @@ . + /** - * 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 . - * * @category Widget - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 - * @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'; } diff --git a/lib/groups/groupsbypostssection.php b/lib/groups/groupsbypostssection.php index d0fadcb450..e2a75eedec 100644 --- a/lib/groups/groupsbypostssection.php +++ b/lib/groups/groupsbypostssection.php @@ -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, diff --git a/lib/notices/inboxnoticestream.php b/lib/notices/inboxnoticestream.php index d99e427efc..4083ef247c 100644 --- a/lib/notices/inboxnoticestream.php +++ b/lib/notices/inboxnoticestream.php @@ -1,51 +1,40 @@ . + /** - * 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 . - * * @category NoticeStream - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @author Mikael Nordfeldth * @author Alexei Sorokin + * @author Stephane Berube * @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 - * @author Mikael Nordfeldth - * @author Alexei Sorokin - * @author chimo * @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 - * @author Mikael Nordfeldth - * @author Alexei Sorokin * @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()) { diff --git a/lib/notices/networkpublicnoticestream.php b/lib/notices/networkpublicnoticestream.php index b77f879dc8..c69a23a1ff 100644 --- a/lib/notices/networkpublicnoticestream.php +++ b/lib/notices/networkpublicnoticestream.php @@ -1,31 +1,54 @@ . -if (!defined('GNUSOCIAL')) { exit(1); } +defined('GNUSOCIAL') || die(); + +/** + * Raw public stream + * + * @category Stream + * @package GNUsocial + * @author Evan Prodromou + * @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 * @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; } diff --git a/lib/notices/publicnoticestream.php b/lib/notices/publicnoticestream.php index 158fd1a839..4ab0ebda64 100644 --- a/lib/notices/publicnoticestream.php +++ b/lib/notices/publicnoticestream.php @@ -1,53 +1,52 @@ . + /** - * 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 . * * @category Stream - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 * @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 * @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; } diff --git a/lib/notices/replynoticestream.php b/lib/notices/replynoticestream.php index 3bc192d330..70a35bb4e7 100644 --- a/lib/notices/replynoticestream.php +++ b/lib/notices/replynoticestream.php @@ -1,53 +1,52 @@ . + /** - * 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 . * * @category Stream - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 * @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 * @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'); diff --git a/lib/profile/peopletagnoticestream.php b/lib/profile/peopletagnoticestream.php index cc453bf1f8..de908e9acf 100644 --- a/lib/profile/peopletagnoticestream.php +++ b/lib/profile/peopletagnoticestream.php @@ -1,72 +1,63 @@ . - * - * @category Stream - * @package StatusNet - * @author Evan Prodromou - * @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 . /** * Stream of notices for a list * * @category Stream - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @author Shashi Gowda * @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 - * @author Shashi Gowda * @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); diff --git a/lib/profile/peopletagsbysubssection.php b/lib/profile/peopletagsbysubssection.php index 761f88851f..a1c737208a 100644 --- a/lib/profile/peopletagsbysubssection.php +++ b/lib/profile/peopletagsbysubssection.php @@ -1,65 +1,49 @@ . + /** - * 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 . - * * @category Widget - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 - * @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; } diff --git a/lib/profile/profilenoticestream.php b/lib/profile/profilenoticestream.php index 91eef03cc9..5100293e51 100644 --- a/lib/profile/profilenoticestream.php +++ b/lib/profile/profilenoticestream.php @@ -1,59 +1,58 @@ . + /** - * 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 . - * * @category Stream - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 * @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 * @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); diff --git a/lib/search/search_engines.php b/lib/search/search_engines.php index 4ced45cac7..070c0760d1 100644 --- a/lib/search/search_engines.php +++ b/lib/search/search_engines.php @@ -1,47 +1,42 @@ . - */ +// 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 . -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); - } - } -} - diff --git a/lib/ui/featureduserssection.php b/lib/ui/featureduserssection.php index 1b0718a05f..30b6cc4c60 100644 --- a/lib/ui/featureduserssection.php +++ b/lib/ui/featureduserssection.php @@ -1,48 +1,40 @@ . + /** - * 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 . - * * @category Widget - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 - * @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'); } diff --git a/lib/ui/galleryaction.php b/lib/ui/galleryaction.php index 5dd0cfcfa7..b1cffb9c09 100644 --- a/lib/ui/galleryaction.php +++ b/lib/ui/galleryaction.php @@ -1,23 +1,25 @@ . + /** - * 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 . + * @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(); diff --git a/lib/ui/topposterssection.php b/lib/ui/topposterssection.php index c621504215..65ce7a2223 100644 --- a/lib/ui/topposterssection.php +++ b/lib/ui/topposterssection.php @@ -1,35 +1,30 @@ . + /** - * 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 . - * * @category Widget - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 - * @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'; } diff --git a/lib/util/daemon.php b/lib/util/daemon.php index eaeecc1058..fa1e47cfcd 100644 --- a/lib/util/daemon.php +++ b/lib/util/daemon.php @@ -1,76 +1,74 @@ . - */ +// 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 . -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; } diff --git a/lib/util/default.php b/lib/util/default.php index dfefaf2958..6c94960f5e 100644 --- a/lib/util/default.php +++ b/lib/util/default.php @@ -1,29 +1,29 @@ . + /** - * 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 . - * * @category Config * @package GNUsocial * @author Evan Prodromou * @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 */ diff --git a/lib/util/installer.php b/lib/util/installer.php index b297ad191a..9115ebdec4 100644 --- a/lib/util/installer.php +++ b/lib/util/installer.php @@ -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; } diff --git a/lib/util/internalsessionhandler.php b/lib/util/internalsessionhandler.php index 981adf29ad..87dd9c8bac 100644 --- a/lib/util/internalsessionhandler.php +++ b/lib/util/internalsessionhandler.php @@ -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'); diff --git a/lib/util/mail.php b/lib/util/mail.php index b51406dbad..18c00f1d2e 100644 --- a/lib/util/mail.php +++ b/lib/util/mail.php @@ -1,36 +1,33 @@ . + /** - * 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 . + * Utilities for sending email * * @category Mail - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @author Zach Copley * @author Robin Millette * @author Sarven Capadisli * @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')) .'" '; @@ -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(); diff --git a/lib/util/spawningdaemon.php b/lib/util/spawningdaemon.php index 732237403d..3eb5e72e4b 100644 --- a/lib/util/spawningdaemon.php +++ b/lib/util/spawningdaemon.php @@ -1,21 +1,20 @@ . - */ +// 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 . + +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()); } } - diff --git a/lib/util/util.php b/lib/util/util.php index efd33568f5..9f36292029 100644 --- a/lib/util/util.php +++ b/lib/util/util.php @@ -1,24 +1,23 @@ . - */ +// 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 . /* 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() diff --git a/modules/Favorite/FavoriteModule.php b/modules/Favorite/FavoriteModule.php index e969939b21..3bd7e7a6cd 100644 --- a/modules/Favorite/FavoriteModule.php +++ b/modules/Favorite/FavoriteModule.php @@ -1,28 +1,28 @@ . - */ - -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 . /** - * @package Activity - * @maintainer Mikael Nordfeldth + * @package Favorite + * @author Mikael Nordfeldth + * @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()); diff --git a/modules/Favorite/lib/favenoticestream.php b/modules/Favorite/lib/favenoticestream.php index 814ce92500..6d2fa372e3 100644 --- a/modules/Favorite/lib/favenoticestream.php +++ b/modules/Favorite/lib/favenoticestream.php @@ -1,48 +1,43 @@ . + /** - * 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 . * * @category Stream - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 * @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 * @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 $max_id * @return */ - 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; } } - diff --git a/plugins/ActivityPub/classes/Activitypub_pending_follow_requests.php b/plugins/ActivityPub/classes/Activitypub_pending_follow_requests.php index 27f8097015..80f3cae151 100644 --- a/plugins/ActivityPub/classes/Activitypub_pending_follow_requests.php +++ b/plugins/ActivityPub/classes/Activitypub_pending_follow_requests.php @@ -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' => [ diff --git a/plugins/ActivityPub/classes/Activitypub_profile.php b/plugins/ActivityPub/classes/Activitypub_profile.php index 80c73d8b09..5891b0b4ee 100644 --- a/plugins/ActivityPub/classes/Activitypub_profile.php +++ b/plugins/ActivityPub/classes/Activitypub_profile.php @@ -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'], diff --git a/plugins/ActivityPub/classes/Activitypub_rsa.php b/plugins/ActivityPub/classes/Activitypub_rsa.php index 80d638bb94..b93ee23f3f 100644 --- a/plugins/ActivityPub/classes/Activitypub_rsa.php +++ b/plugins/ActivityPub/classes/Activitypub_rsa.php @@ -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'], diff --git a/plugins/ActivitySpam/classes/spam_score.php b/plugins/ActivitySpam/classes/Spam_score.php similarity index 77% rename from plugins/ActivitySpam/classes/spam_score.php rename to plugins/ActivitySpam/classes/Spam_score.php index 36e03aa9a8..8c4e735373 100644 --- a/plugins/ActivitySpam/classes/spam_score.php +++ b/plugins/ActivitySpam/classes/Spam_score.php @@ -1,47 +1,38 @@ . + /** - * 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 . - * * @category Spam - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 - * @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; diff --git a/plugins/ActivitySpam/lib/spamnoticestream.php b/plugins/ActivitySpam/lib/spamnoticestream.php index d19814509c..19bc73a2d7 100644 --- a/plugins/ActivitySpam/lib/spamnoticestream.php +++ b/plugins/ActivitySpam/lib/spamnoticestream.php @@ -1,52 +1,45 @@ . - * - * @category Spam - * @package StatusNet - * @author Evan Prodromou - * @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 . /** * Spam notice stream * * @category Spam - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 * @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'); diff --git a/plugins/ActivitySpam/scripts/silencespammer.php b/plugins/ActivitySpam/scripts/silencespammer.php index 3a5e585fd5..d63995d9bb 100644 --- a/plugins/ActivitySpam/scripts/silencespammer.php +++ b/plugins/ActivitySpam/scripts/silencespammer.php @@ -1,20 +1,22 @@ . +// 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 . + +/** + * @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 { diff --git a/plugins/DBQueue/classes/DBQueueManager.php b/plugins/DBQueue/classes/DBQueueManager.php index bf8e7fe5d4..fcf9cf8526 100644 --- a/plugins/DBQueue/classes/DBQueueManager.php +++ b/plugins/DBQueue/classes/DBQueueManager.php @@ -1,33 +1,32 @@ . + /** - * 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 . - * * @category QueueManager - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @author Brion Vibber * @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); } diff --git a/plugins/EmailReminder/classes/Email_reminder.php b/plugins/EmailReminder/classes/Email_reminder.php index 7af2cdf5e6..700a3aa20a 100644 --- a/plugins/EmailReminder/classes/Email_reminder.php +++ b/plugins/EmailReminder/classes/Email_reminder.php @@ -1,31 +1,31 @@ . + /** - * 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 . - * * @category Data * @package EmailReminder * @author Zach Copley * @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( diff --git a/plugins/EmailReminder/lib/siteconfirmreminderhandler.php b/plugins/EmailReminder/lib/siteconfirmreminderhandler.php index df83ea3e3c..59531950d4 100644 --- a/plugins/EmailReminder/lib/siteconfirmreminderhandler.php +++ b/plugins/EmailReminder/lib/siteconfirmreminderhandler.php @@ -1,45 +1,38 @@ . + /* - * 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 . - * * @category Email - * @package StatusNet + * @package GNUsocial * @author Zach Copley * @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 * @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 { diff --git a/plugins/EmailSummary/classes/Email_summary_status.php b/plugins/EmailSummary/classes/Email_summary_status.php index 460053f9f8..a2e65d2ca2 100644 --- a/plugins/EmailSummary/classes/Email_summary_status.php +++ b/plugins/EmailSummary/classes/Email_summary_status.php @@ -1,35 +1,30 @@ . + /** * Data class for email summary status * - * PHP version 5 - * - * @category Data - * @package StatusNet - * @author Evan Prodromou - * @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 . + * @category Data + * @package GNUsocial + * @author Evan Prodromou + * @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 - * @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); diff --git a/plugins/Event/classes/Happening.php b/plugins/Event/classes/Happening.php index 646a7e6d1e..574efc8260 100644 --- a/plugins/Event/classes/Happening.php +++ b/plugins/Event/classes/Happening.php @@ -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')), ); diff --git a/plugins/Event/classes/RSVP.php b/plugins/Event/classes/RSVP.php index f2ab8f0aa3..aaa850a258 100644 --- a/plugins/Event/classes/RSVP.php +++ b/plugins/Event/classes/RSVP.php @@ -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')), ); } diff --git a/plugins/ExtendedProfile/actions/userautocomplete.php b/plugins/ExtendedProfile/actions/userautocomplete.php index 46257fc595..a2109516cb 100644 --- a/plugins/ExtendedProfile/actions/userautocomplete.php +++ b/plugins/ExtendedProfile/actions/userautocomplete.php @@ -1,36 +1,30 @@ . + /** - * 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 . - * * @category Search - * @package StatusNet + * @package GNUsocial * @author Zach Copley * @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)); } diff --git a/plugins/FollowEveryone/classes/User_followeveryone_prefs.php b/plugins/FollowEveryone/classes/User_followeveryone_prefs.php index c1a654df92..3c9b0917c2 100644 --- a/plugins/FollowEveryone/classes/User_followeveryone_prefs.php +++ b/plugins/FollowEveryone/classes/User_followeveryone_prefs.php @@ -1,35 +1,30 @@ . + /** * Data class for counting greetings * - * PHP version 5 - * - * @category Data - * @package StatusNet - * @author Evan Prodromou - * @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 . + * @category Data + * @package GNUsocial + * @author Evan Prodromou + * @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 - * @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); diff --git a/plugins/GroupFavorited/actions/groupfavorited.php b/plugins/GroupFavorited/actions/groupfavorited.php index 3799f3a2f6..0141c6a79e 100644 --- a/plugins/GroupFavorited/actions/groupfavorited.php +++ b/plugins/GroupFavorited/actions/groupfavorited.php @@ -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); diff --git a/plugins/ModLog/ModLogPlugin.php b/plugins/ModLog/ModLogPlugin.php index d805dba408..44a5529e90 100644 --- a/plugins/ModLog/ModLogPlugin.php +++ b/plugins/ModLog/ModLogPlugin.php @@ -1,52 +1,37 @@ . + /** - * 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 . - * * @category Moderation - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 * @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')); diff --git a/plugins/ModLog/classes/ModLog.php b/plugins/ModLog/classes/ModLog.php index 606b786b29..c315ff8f08 100644 --- a/plugins/ModLog/classes/ModLog.php +++ b/plugins/ModLog/classes/ModLog.php @@ -1,49 +1,37 @@ . + /** - * 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 . + * Data object to store moderation logs * * @category Moderation - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 - * @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'), diff --git a/plugins/Nodeinfo/actions/nodeinfo_2_0.php b/plugins/Nodeinfo/actions/nodeinfo_2_0.php index 2150bfb5e8..f49b9462ce 100644 --- a/plugins/Nodeinfo/actions/nodeinfo_2_0.php +++ b/plugins/Nodeinfo/actions/nodeinfo_2_0.php @@ -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); diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index 1f3f409f8b..831a191aa7 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -1,32 +1,31 @@ . - */ +// 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 . /** * OStatusPlugin implementation for GNU Social - * * Depends on: WebFinger plugin * - * @package OStatusPlugin - * @maintainer Brion Vibber + * @package OStatusPlugin + * @author Brion Vibber + * @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('/(?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; } diff --git a/plugins/OStatus/classes/FeedSub.php b/plugins/OStatus/classes/FeedSub.php index c734da80b1..c2a88eabf4 100644 --- a/plugins/OStatus/classes/FeedSub.php +++ b/plugins/OStatus/classes/FeedSub.php @@ -1,29 +1,32 @@ . - */ - -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 . /** - * @package OStatusPlugin - * @maintainer Brion Vibber + * 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 + * @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))); } diff --git a/plugins/OStatus/classes/HubSub.php b/plugins/OStatus/classes/HubSub.php index 28ea1fd9d6..6a62cab7ae 100644 --- a/plugins/OStatus/classes/HubSub.php +++ b/plugins/OStatus/classes/HubSub.php @@ -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_'), diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 4b47197a8c..0dcfb3d95b 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -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'), diff --git a/plugins/OStatus/scripts/rm_bad_feedsubs.php b/plugins/OStatus/scripts/rm_bad_feedsubs.php index ce1698a60c..81d6eb1bda 100755 --- a/plugins/OStatus/scripts/rm_bad_feedsubs.php +++ b/plugins/OStatus/scripts/rm_bad_feedsubs.php @@ -1,24 +1,26 @@ #!/usr/bin/env 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 . + +/** + * @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; diff --git a/plugins/OStatus/scripts/update-profile-data.php b/plugins/OStatus/scripts/update-profile-data.php index 5b3e00e9fc..a6454bca7d 100755 --- a/plugins/OStatus/scripts/update-profile-data.php +++ b/plugins/OStatus/scripts/update-profile-data.php @@ -1,21 +1,23 @@ #!/usr/bin/env 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 . + +/** + * @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); diff --git a/plugins/OpenID/actions/openidsettings.php b/plugins/OpenID/actions/openidsettings.php index c3573f9b25..4bc212b028 100644 --- a/plugins/OpenID/actions/openidsettings.php +++ b/plugins/OpenID/actions/openidsettings.php @@ -1,35 +1,30 @@ . + /** - * 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 . - * * @category Settings - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 - * @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); diff --git a/plugins/OpenID/classes/User_openid_prefs.php b/plugins/OpenID/classes/User_openid_prefs.php index ae0b9e2fbf..0d1d999ed8 100644 --- a/plugins/OpenID/classes/User_openid_prefs.php +++ b/plugins/OpenID/classes/User_openid_prefs.php @@ -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' diff --git a/plugins/OpenID/openid.php b/plugins/OpenID/openid.php index 964d098030..5237cc81ea 100644 --- a/plugins/OpenID/openid.php +++ b/plugins/OpenID/openid.php @@ -1,25 +1,25 @@ . +// 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 . + +/** + * @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('

'); // @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();' + ); } } diff --git a/plugins/Poll/classes/Poll.php b/plugins/Poll/classes/Poll.php index 6a97a52441..2a3c679dde 100644 --- a/plugins/Poll/classes/Poll.php +++ b/plugins/Poll/classes/Poll.php @@ -1,46 +1,38 @@ . + /** * Data class to mark notices as bookmarks * - * PHP version 5 - * - * @category PollPlugin - * @package StatusNet - * @author Brion Vibber - * @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 . + * @category PollPlugin + * @package GNUsocial + * @author Brion Vibber + * @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 - * @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(); diff --git a/plugins/Poll/classes/Poll_response.php b/plugins/Poll/classes/Poll_response.php index 1997f4b64f..91f6a7cf14 100644 --- a/plugins/Poll/classes/Poll_response.php +++ b/plugins/Poll/classes/Poll_response.php @@ -1,46 +1,38 @@ . + /** * Data class to record responses to polls * - * PHP version 5 - * - * @category PollPlugin - * @package StatusNet - * @author Brion Vibber - * @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 . + * @category PollPlugin + * @package GNUsocial + * @author Brion Vibber + * @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 - * @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( diff --git a/plugins/Poll/classes/User_poll_prefs.php b/plugins/Poll/classes/User_poll_prefs.php index 450a6b9cfb..cf3272e2bc 100644 --- a/plugins/Poll/classes/User_poll_prefs.php +++ b/plugins/Poll/classes/User_poll_prefs.php @@ -1,44 +1,37 @@ . + /** * Data class to record user prefs for polls * - * PHP version 5 - * - * @category PollPlugin - * @package StatusNet - * @author Evan Prodromou - * @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 . + * @category PollPlugin + * @package GNUsocial + * @author Brion Vibber + * @author Evan Prodromou + * @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 - * @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'), ), diff --git a/plugins/QnA/actions/qnaclosequestion.php b/plugins/QnA/actions/qnaclosequestion.php index 4c2abb6536..57ab3ee1fd 100644 --- a/plugins/QnA/actions/qnaclosequestion.php +++ b/plugins/QnA/actions/qnaclosequestion.php @@ -1,47 +1,36 @@ . + /** - * 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 . - * * @category QnA - * @package StatusNet + * @package GNUsocial * @author Zach Copley * @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 * @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') { diff --git a/plugins/QnA/actions/qnareviseanswer.php b/plugins/QnA/actions/qnareviseanswer.php index e23195531f..7ae912c68d 100644 --- a/plugins/QnA/actions/qnareviseanswer.php +++ b/plugins/QnA/actions/qnareviseanswer.php @@ -1,47 +1,36 @@ . - * - * @category QnA - * @package StatusNet - * @author Zach Copley - * @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 . /** * Revise an answer * * @category QnA - * @package StatusNet + * @package GNUsocial * @author Zach Copley + * @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') { diff --git a/plugins/QnA/classes/QnA_Answer.php b/plugins/QnA/classes/QnA_Answer.php index 2aa69cf5a3..a2e1c81f86 100644 --- a/plugins/QnA/classes/QnA_Answer.php +++ b/plugins/QnA/classes/QnA_Answer.php @@ -1,46 +1,38 @@ . + /** * Data class to save answers to questions * - * PHP version 5 - * - * @category QnA - * @package StatusNet - * @author Zach Copley - * @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 . + * @category QnA + * @package GNUsocial + * @author Zach Copley + * @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 - * @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( diff --git a/plugins/QnA/classes/QnA_Question.php b/plugins/QnA/classes/QnA_Question.php index b531838677..81ea0cdb56 100644 --- a/plugins/QnA/classes/QnA_Question.php +++ b/plugins/QnA/classes/QnA_Question.php @@ -1,46 +1,38 @@ . + /** * Data class to mark a notice as a question * - * PHP version 5 - * - * @category QnA - * @package StatusNet - * @author Zach Copley - * @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 . + * @category QnA + * @package GNUsocial + * @author Zach Copley + * @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 - * @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(); diff --git a/plugins/QnA/classes/QnA_Vote.php b/plugins/QnA/classes/QnA_Vote.php index 13679acd2c..7a1d0911f6 100644 --- a/plugins/QnA/classes/QnA_Vote.php +++ b/plugins/QnA/classes/QnA_Vote.php @@ -1,46 +1,38 @@ . + /** * Data class to save users votes for * - * PHP version 5 - * - * @category QnA - * @package StatusNet - * @author Zach Copley - * @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 . + * @category QnA + * @package GNUsocial + * @author Zach Copley + * @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 - * @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(); diff --git a/plugins/Realtime/classes/Realtime_channel.php b/plugins/Realtime/classes/Realtime_channel.php index 7541593433..e8431d0728 100644 --- a/plugins/Realtime/classes/Realtime_channel.php +++ b/plugins/Realtime/classes/Realtime_channel.php @@ -1,36 +1,18 @@ . - * - * @category Realtime - * @package StatusNet - * @author Evan Prodromou - * @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 . /** * 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 - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ + * @category Realtime + * @package GNUsocial + * @author Evan Prodromou + * @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) { diff --git a/plugins/Realtime/scripts/cleanupchannels.php b/plugins/Realtime/scripts/cleanupchannels.php index 4aa0a4ba50..31ed304d4a 100755 --- a/plugins/Realtime/scripts/cleanupchannels.php +++ b/plugins/Realtime/scripts/cleanupchannels.php @@ -1,23 +1,27 @@ #!/usr/bin/env php . + /* - * 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 . + * @package Realtime + * @author Mikael Nordfeldth + * @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(); diff --git a/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php b/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php index a4a544784a..819b01b07b 100644 --- a/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php +++ b/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php @@ -1,55 +1,43 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * * Plugin that requires the user to have a validated email address before they * can post notices * - * 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 . - * * @category Plugin - * @package StatusNet + * @package GNUsocial * @author Craig Andrews * @author Brion Vibber * @author Evan Prodromou + * @author Mikael Nordfeldth * @copyright 2011 StatusNet Inc. http://status.net/ - * @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/ + * @copyright 2009-2013 Free Software Foundation, Inc http://www.fsf.org + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} +defined('GNUSOCIAL') || die(); /** * Plugin for requiring a validated email before posting. * * Enable this plugin using addPlugin('RequireValidatedEmail'); - * - * @category Plugin - * @package StatusNet - * @author Craig Andrews - * @author Brion Vibber - * @author Evan Prodromou - * @author Mikael Nordfeldth * @copyright 2009-2013 Free Software Foundation, Inc http://www.fsf.org * @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 */ class RequireValidatedEmailPlugin extends Plugin { @@ -84,8 +72,10 @@ class RequireValidatedEmailPlugin extends Plugin public function onRouterInitialized(URLMapper $m) { - $m->('main/confirmfirst/:code', - ['action' => 'confirmfirstemail']); + $m->connect( + 'main/confirmfirst/:code', + ['action' => 'confirmfirstemail'] + ); return true; } @@ -121,7 +111,7 @@ class RequireValidatedEmailPlugin extends Plugin * * @return bool hook result code */ - function onStartRegisterUser(&$user, &$profile) + public function onStartRegisterUser(&$user, &$profile) { $email = $user->email; @@ -153,8 +143,10 @@ class RequireValidatedEmailPlugin extends Plugin // that somebody's ok despite a non-validated email. // @todo FIXME: This isn't how to do it! Use Start*/End* instead - Event::handle('RequireValidatedEmailPlugin_Override', - array($user, &$knownGood)); + Event::handle( + 'RequireValidatedEmailPlugin_Override', + [$user, &$knownGood] + ); return $knownGood; } @@ -188,7 +180,7 @@ class RequireValidatedEmailPlugin extends Plugin * * @return bool true if user has a trusted OpenID. */ - function hasTrustedOpenID(User $user) + public function hasTrustedOpenID(User $user) { if ($this->trustedOpenIDs && class_exists('User_openid')) { foreach ($this->trustedOpenIDs as $regex) { @@ -240,7 +232,7 @@ class RequireValidatedEmailPlugin extends Plugin * * @return boolean hook value */ - function onStartMakeEntryForm($tag, $action, &$form) + public function onStartMakeEntryForm($tag, $action, &$form) { $user = common_current_user(); if (!empty($user)) { @@ -259,7 +251,7 @@ class RequireValidatedEmailPlugin extends Plugin * @param boolean $result if overriding, set to true/false has right * @return boolean hook result value */ - function onUserRightsCheck(Profile $profile, $right, &$result) + public function onUserRightsCheck(Profile $profile, $right, &$result) { if ($right == Right::CREATEGROUP || ($this->disallowLogin && ($right == Right::WEBLOGIN || $right == Right::API))) { @@ -272,7 +264,7 @@ class RequireValidatedEmailPlugin extends Plugin return true; } - function onLoginAction($action, &$login) + public function onLoginAction($action, &$login) { if ($action == 'confirmfirstemail') { $login = true; diff --git a/plugins/SearchSub/SearchSubPlugin.php b/plugins/SearchSub/SearchSubPlugin.php index ad5acd4221..86da11a0ed 100644 --- a/plugins/SearchSub/SearchSubPlugin.php +++ b/plugins/SearchSub/SearchSubPlugin.php @@ -110,6 +110,8 @@ class SearchSubPlugin extends Plugin // with a lot of searches! $sub = new SearchSub(); $sub->groupBy('search'); + $sub->selectAdd(); + $sub->selectAdd('search'); $sub->find(); while ($sub->fetch()) { $search = $sub->search; diff --git a/plugins/SensitiveContent/actions/sensitivecontentsettings.php b/plugins/SensitiveContent/actions/sensitivecontentsettings.php index 482a893958..0c7171bc0a 100644 --- a/plugins/SensitiveContent/actions/sensitivecontentsettings.php +++ b/plugins/SensitiveContent/actions/sensitivecontentsettings.php @@ -1,51 +1,72 @@ . -if (!defined('GNUSOCIAL')) { exit(1); } +defined('GNUSOCIAL') || die(); class SensitiveContentSettingsAction extends SettingsAction { - function title() - { - return _m('Sensitive content settings'); - } + public function title() + { + return _m('Sensitive content settings'); + } - function getInstructions() - { - return _m('Set preferences for display of "sensitive" content'); - } + public function getInstructions() + { + return _m('Set preferences for display of "sensitive" content'); + } - function showContent() - { + public function showContent() + { + $user = $this->scoped->getUser(); - $user = $this->scoped->getUser(); + $this->elementStart( + 'form', + [ + 'method' => 'post', + 'id' => 'sensitivecontent', + 'class' => 'form_settings', + 'action' => common_local_url('sensitivecontentsettings'), + ] + ); - $this->elementStart('form', array('method' => 'post', - 'id' => 'sensitivecontent', - 'class' => 'form_settings', - 'action' => common_local_url('sensitivecontentsettings'))); + $this->elementStart('fieldset'); + $this->hidden('token', common_session_token()); + $this->elementStart('ul', 'form_data'); - $this->elementStart('fieldset'); - $this->hidden('token', common_session_token()); - $this->elementStart('ul', 'form_data'); - - $this->elementStart('li'); - $this->checkbox('hidesensitive', _('Hide attachments in posts hashtagged #NSFW'), - ($this->arg('hidesensitive')) ? - $this->boolean('hidesensitive') : $this->scoped->getPref('MoonMan','hide_sensitive',0)); - $this->elementEnd('li'); + $this->elementStart('li'); + $this->checkbox( + 'hidesensitive', + _('Hide attachments in posts hashtagged #NSFW'), + ($this->arg('hidesensitive') ? + $this->boolean('hidesensitive') : $this->scoped->getPref('MoonMan', 'hide_sensitive', 0)) + ); + $this->elementEnd('li'); - $this->elementEnd('ul'); - $this->submit('save', _m('BUTTON','Save')); + $this->elementEnd('ul'); + $this->submit('save', _m('BUTTON', 'Save')); - $this->elementEnd('fieldset'); - $this->elementEnd('form'); - } + $this->elementEnd('fieldset'); + $this->elementEnd('form'); + } - function doPost() - { - $hidesensitive = $this->booleanintstring('hidesensitive'); - $this->scoped->setPref('MoonMan','hide_sensitive', $hidesensitive); - return _('Settings saved.'); - } + public function doPost() + { + $hidesensitive = $this->boolean('hidesensitive') ? '1' : '0'; + $this->scoped->setPref('MoonMan', 'hide_sensitive', $hidesensitive); + return _('Settings saved.'); + } } diff --git a/plugins/Sitemap/SitemapPlugin.php b/plugins/Sitemap/SitemapPlugin.php index 1cb70d6509..9b15ec2d6c 100644 --- a/plugins/Sitemap/SitemapPlugin.php +++ b/plugins/Sitemap/SitemapPlugin.php @@ -1,48 +1,35 @@ . + /** - * StatusNet - the distributed open-source microblogging tool - * Copyright (C) 2010, StatusNet, Inc. - * * Creates a dynamic sitemap for a StatusNet site * - * 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 . - * - * @category Sample - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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 */ -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(); /** * Sitemap plugin * - * @category Sample - * @package StatusNet - * @author Evan Prodromou * @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 SitemapPlugin extends Plugin { @@ -58,7 +45,7 @@ class SitemapPlugin extends Plugin * * @return boolean hook value. */ - function onEndRobotsTxt($action) + public function onEndRobotsTxt($action) { $url = common_local_url('sitemapindex'); @@ -76,25 +63,37 @@ class SitemapPlugin extends Plugin */ public function onRouterInitialized(URLMapper $m) { - $m->connect('sitemapindex.xml', - ['action' => 'sitemapindex']); + $m->connect( + 'sitemapindex.xml', + ['action' => 'sitemapindex'] + ); - $m->connect('notice-sitemap-:year-:month-:day-:index.xml', - ['action' => 'noticesitemap'], - ['year' => '[0-9]{4}', - 'month' => '[01][0-9]', - 'day' => '[0123][0-9]', - 'index' => '[1-9][0-9]*']); + $m->connect( + 'notice-sitemap-:year-:month-:day-:index.xml', + ['action' => 'noticesitemap'], + [ + 'year' => '[0-9]{4}', + 'month' => '[01][0-9]', + 'day' => '[0123][0-9]', + 'index' => '[1-9][0-9]*', + ] + ); - $m->connect('user-sitemap-:year-:month-:day-:index.xml', - ['action' => 'usersitemap'), - ['year' => '[0-9]{4}', - 'month' => '[01][0-9]', - 'day' => '[0123][0-9]', - 'index' => '[1-9][0-9]*']); + $m->connect( + 'user-sitemap-:year-:month-:day-:index.xml', + ['action' => 'usersitemap'], + [ + 'year' => '[0-9]{4}', + 'month' => '[01][0-9]', + 'day' => '[0123][0-9]', + 'index' => '[1-9][0-9]*', + ] + ); - $m->connect('panel/sitemap', - ['action' => 'sitemapadminpanel']); + $m->connect( + 'panel/sitemap', + ['action' => 'sitemapadminpanel'] + ); return true; } @@ -109,7 +108,7 @@ class SitemapPlugin extends Plugin * * @return boolean hook value. */ - function onStartShowHeadElements($action) + public function onStartShowHeadElements($action) { $actionName = $action->trimmed('action'); @@ -119,7 +118,6 @@ class SitemapPlugin extends Plugin if (($singleUser && $actionName == 'showstream') || (!$singleUser && $actionName == 'public')) { - $keys = array('yahookey' => 'y_key', 'bingkey' => 'msvalidate.01'); // XXX: is this the same for all sites? @@ -146,7 +144,7 @@ class SitemapPlugin extends Plugin * * @return boolean hook value; true means continue processing, false means stop. */ - function onCheckSchema() + public function onCheckSchema() { $schema = Schema::get(); @@ -155,13 +153,19 @@ class SitemapPlugin extends Plugin return true; } - function onEndAdminPanelNav($menu) { + public function onEndAdminPanelNav($menu) + { if (AdminPanelAction::canAdmin('sitemap')) { // TRANS: Menu item title/tooltip $menu_title = _m('Sitemap configuration'); // TRANS: Menu item for site administration - $menu->out->menuItem(common_local_url('sitemapadminpanel'), _m('MENU','Sitemap'), - $menu_title, $action_name == 'sitemapadminpanel', 'nav_sitemap_admin_panel'); + $menu->out->menuItem( + common_local_url('sitemapadminpanel'), + _m('MENU', 'Sitemap'), + $menu_title, + ($action_name === 'sitemapadminpanel'), + 'nav_sitemap_admin_panel' + ); } return true; } diff --git a/plugins/Sitemap/classes/Sitemap_notice_count.php b/plugins/Sitemap/classes/Sitemap_notice_count.php index 9e523dfbc7..9cc5faeb3e 100644 --- a/plugins/Sitemap/classes/Sitemap_notice_count.php +++ b/plugins/Sitemap/classes/Sitemap_notice_count.php @@ -1,35 +1,30 @@ . + /** * Data class for counting notice postings by date * - * PHP version 5 - * - * @category Data - * @package StatusNet - * @author Evan Prodromou - * @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 . + * @category Data + * @package GNUsocial + * @author Evan Prodromou + * @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'; @@ -43,11 +38,8 @@ require_once INSTALLDIR . '/classes/Memcached_DataObject.php'; * of notices posted on that day. Since, after the end of the day, * this number doesn't change, it's a good candidate for persistent caching. * - * @category Data - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ + * @copyright 2010, StatusNet, Inc. + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * * @see DB_DataObject */ @@ -73,7 +65,7 @@ class Sitemap_notice_count extends Managed_DataObject ); } - static function getAll() + public static function getAll() { $noticeCounts = self::cacheGet('sitemap:notice:counts'); @@ -90,9 +82,9 @@ class Sitemap_notice_count extends Managed_DataObject if (!$n) { // No counts saved yet $noticeCounts = self::initializeCounts(); - } else if ($snc->notice_date < $today) { // There are counts but not up to today + } elseif ($snc->notice_date < $today) { // There are counts but not up to today $noticeCounts = self::fillInCounts($snc->notice_date); - } else if ($snc->notice_date == $today) { // Refresh today's + } elseif ($snc->notice_date === $today) { // Refresh today's $noticeCounts[$today] = self::updateToday(); } @@ -110,7 +102,7 @@ class Sitemap_notice_count extends Managed_DataObject return $noticeCounts; } - static function initializeCounts() + public static function initializeCounts() { $firstDate = self::getFirstDate(); // awww $today = self::today(); @@ -126,7 +118,7 @@ class Sitemap_notice_count extends Managed_DataObject return $counts; } - static function fillInCounts($lastDate) + public static function fillInCounts($lastDate) { $today = self::today(); @@ -145,7 +137,7 @@ class Sitemap_notice_count extends Managed_DataObject return $counts; } - static function updateToday() + public static function updateToday() { $today = self::today(); @@ -155,17 +147,20 @@ class Sitemap_notice_count extends Managed_DataObject return $n; } - static function getCount($d) + public static function getCount($d) { $notice = new Notice(); - $notice->whereAdd('created BETWEEN "'.$d.' 00:00:00" AND "'.self::incrementDay($d).' 00:00:00"'); + $notice->whereAdd( + "created BETWEEN TIMESTAMP '" . $d . " 00:00:00' AND " . + "TIMESTAMP '" . self::incrementDay($d) . " 00:00:00'" + ); $notice->whereAdd('is_local = ' . Notice::LOCAL_PUBLIC); $n = $notice->count(); return $n; } - static function insertCount($d, $n) + public static function insertCount($d, $n) { $snc = new Sitemap_notice_count(); @@ -180,7 +175,7 @@ class Sitemap_notice_count extends Managed_DataObject } } - static function updateCount($d, $n) + public static function updateCount($d, $n) { $snc = Sitemap_notice_count::getKV('notice_date', DB_DataObject_Cast::date($d)); @@ -202,23 +197,23 @@ class Sitemap_notice_count extends Managed_DataObject } } - static function incrementDay($d) + public static function incrementDay($d) { $dt = self::dateStrToInt($d); return self::dateIntToStr($dt + 24 * 60 * 60); } - static function dateStrToInt($d) + public static function dateStrToInt($d) { return strtotime($d.' 00:00:00'); } - static function dateIntToStr($dt) + public static function dateIntToStr($dt) { return date('Y-m-d', $dt); } - static function getFirstDate() + public static function getFirstDate() { $n = new Notice(); @@ -233,7 +228,7 @@ class Sitemap_notice_count extends Managed_DataObject } } - static function today() + public static function today() { return self::dateIntToStr(time()); } diff --git a/plugins/Sitemap/classes/Sitemap_user_count.php b/plugins/Sitemap/classes/Sitemap_user_count.php index 865cf246e7..7e22ef15ac 100644 --- a/plugins/Sitemap/classes/Sitemap_user_count.php +++ b/plugins/Sitemap/classes/Sitemap_user_count.php @@ -1,35 +1,30 @@ . + /** * Data class for counting user registrations by date * - * PHP version 5 - * - * @category Data - * @package StatusNet - * @author Evan Prodromou - * @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 . + * @category Data + * @package GNUsocial + * @author Evan Prodromou + * @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'; @@ -39,11 +34,8 @@ require_once INSTALLDIR . '/classes/Memcached_DataObject.php'; * We make a separate sitemap for each user registered by date. * To save ourselves some processing effort, we cache this data * - * @category Action - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ + * @copyright 2010, StatusNet, Inc. + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * * @see DB_DataObject */ @@ -69,12 +61,11 @@ class Sitemap_user_count extends Managed_DataObject ); } - static function getAll() + public static function getAll() { $userCounts = self::cacheGet('sitemap:user:counts'); if ($userCounts === false) { - $suc = new Sitemap_user_count(); $suc->orderBy('registration_date DESC'); @@ -87,9 +78,9 @@ class Sitemap_user_count extends Managed_DataObject if (!$n) { // No counts saved yet $userCounts = self::initializeCounts(); - } else if ($suc->registration_date < $today) { // There are counts but not up to today + } elseif ($suc->registration_date < $today) { // There are counts but not up to today $userCounts = self::fillInCounts($suc->registration_date); - } else if ($suc->registration_date == $today) { // Refresh today's + } elseif ($suc->registration_date === $today) { // Refresh today's $userCounts[$today] = self::updateToday(); } @@ -107,7 +98,7 @@ class Sitemap_user_count extends Managed_DataObject return $userCounts; } - static function initializeCounts() + public static function initializeCounts() { $firstDate = self::getFirstDate(); // awww $today = self::today(); @@ -123,7 +114,7 @@ class Sitemap_user_count extends Managed_DataObject return $counts; } - static function fillInCounts($lastDate) + public static function fillInCounts($lastDate) { $today = self::today(); @@ -142,7 +133,7 @@ class Sitemap_user_count extends Managed_DataObject return $counts; } - static function updateToday() + public static function updateToday() { $today = self::today(); @@ -152,16 +143,19 @@ class Sitemap_user_count extends Managed_DataObject return $n; } - static function getCount($d) + public static function getCount($d) { $user = new User(); - $user->whereAdd('created BETWEEN "'.$d.' 00:00:00" AND "'.self::incrementDay($d).' 00:00:00"'); + $user->whereAdd( + "created BETWEEN TIMESTAMP '" . $d . " 00:00:00' AND " . + "TIMESTAMP '" . self::incrementDay($d) . " 00:00:00'" + ); $n = $user->count(); return $n; } - static function insertCount($d, $n) + public static function insertCount($d, $n) { $suc = new Sitemap_user_count(); @@ -175,7 +169,7 @@ class Sitemap_user_count extends Managed_DataObject } } - static function updateCount($d, $n) + public static function updateCount($d, $n) { $suc = Sitemap_user_count::getKV('registration_date', DB_DataObject_Cast::date($d)); @@ -196,23 +190,23 @@ class Sitemap_user_count extends Managed_DataObject } } - static function incrementDay($d) + public static function incrementDay($d) { $dt = self::dateStrToInt($d); return self::dateIntToStr($dt + 24 * 60 * 60); } - static function dateStrToInt($d) + public static function dateStrToInt($d) { return strtotime($d.' 00:00:00'); } - static function dateIntToStr($dt) + public static function dateIntToStr($dt) { return date('Y-m-d', $dt); } - static function getFirstDate() + public static function getFirstDate() { $u = new User(); $u->selectAdd(); @@ -225,7 +219,7 @@ class Sitemap_user_count extends Managed_DataObject } } - static function today() + public static function today() { return self::dateIntToStr(time()); } diff --git a/plugins/SlicedFavorites/actions/favoritedslice.php b/plugins/SlicedFavorites/actions/favoritedslice.php index 31e93cd396..3e8339a313 100644 --- a/plugins/SlicedFavorites/actions/favoritedslice.php +++ b/plugins/SlicedFavorites/actions/favoritedslice.php @@ -1,40 +1,36 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * * List of popular notices * - * 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 . - * * @category Public - * @package StatusNet + * @package GNUsocial * @author Zach Copley * @author Evan Prodromou * @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(); class FavoritedSliceAction extends FavoritedAction { - private $includeUsers = array(), $excludeUsers = array(); + private $includeUsers = []; + private $excludeUsers = []; /** * Take arguments for running @@ -45,7 +41,7 @@ class FavoritedSliceAction extends FavoritedAction * * @todo move queries from showContent() to here */ - function prepare(array $args = array()) + public function prepare(array $args = []) { parent::prepare($args); @@ -72,7 +68,7 @@ class FavoritedSliceAction extends FavoritedAction * * @return void */ - function showContent() + public function showContent() { $slice = $this->sliceWhereClause(); if (!$slice) { @@ -80,28 +76,21 @@ class FavoritedSliceAction extends FavoritedAction } $weightexpr = common_sql_weight('fave.modified', common_config('popular', 'dropoff')); - $cutoff = sprintf("fave.modified > '%s'", - common_sql_date(time() - common_config('popular', 'cutoff'))); - - $qry = 'SELECT notice.*, '. - $weightexpr . ' as weight ' . - 'FROM notice JOIN fave ON notice.id = fave.notice_id ' . - "WHERE $cutoff AND $slice " . - 'GROUP BY id,profile_id,uri,content,rendered,url,created,notice.modified,reply_to,is_local,source,notice.conversation ' . - 'ORDER BY weight DESC'; + $cutoff = sprintf( + "fave.modified > TIMESTAMP '%s'", + common_sql_date(time() - common_config('popular', 'cutoff')) + ); $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 fave ON notice.id = fave.notice_id ' . + 'WHERE ' . $cutoff . ' AND ' . $slice . ' ' . + '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); @@ -111,8 +100,12 @@ class FavoritedSliceAction extends FavoritedAction $this->showEmptyList(); } - $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE, - $this->page, 'favorited'); + $this->pagination( + $this->page > 1, + $cnt > NOTICES_PER_PAGE, + $this->page, + 'favorited' + ); } private function sliceWhereClause() @@ -122,11 +115,11 @@ class FavoritedSliceAction extends FavoritedAction if (count($include) == 1) { return "profile_id = " . intval($include[0]); - } else if (count($include) > 1) { + } elseif (count($include) > 1) { return "profile_id IN (" . implode(',', $include) . ")"; - } else if (count($exclude) == 1) { + } elseif (count($exclude) === 1) { return "profile_id != " . intval($exclude[0]); - } else if (count($exclude) > 1) { + } elseif (count($exclude) > 1) { return "profile_id NOT IN (" . implode(',', $exclude) . ")"; } else { return false; diff --git a/plugins/SphinxSearch/README b/plugins/SphinxSearch/README index 873a8cf692..a8e0d20d8b 100644 --- a/plugins/SphinxSearch/README +++ b/plugins/SphinxSearch/README @@ -22,7 +22,7 @@ client side, which itself depends on the sphinx development files. "pecl install sphinx" should take care of that. Add "extension=sphinx.so" to your php.ini and reload apache to enable it. -You can update your MySQL or Postgresql databases to drop their fulltext +You can update your MariaDB or PostgreSQL databases to drop their fulltext search indexes, since they're now provided by sphinx. diff --git a/plugins/TagCloud/lib/grouptagcloudsection.php b/plugins/TagCloud/lib/grouptagcloudsection.php index 5ed14560ce..d83ded10b5 100644 --- a/plugins/TagCloud/lib/grouptagcloudsection.php +++ b/plugins/TagCloud/lib/grouptagcloudsection.php @@ -1,35 +1,30 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * * Personal tag cloud 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 . - * * @category Widget - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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(); /** * Group tag cloud section @@ -42,22 +37,22 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { */ class GroupTagCloudSection extends TagCloudSection { - var $group = null; + public $group = null; - function __construct($out=null, $group=null) + public function __construct($out = null, $group = null) { parent::__construct($out); $this->group = $group; } - function title() + public function title() { // TRANS: Title for group tag cloud section. // TRANS: %s is a group name. return _('Tags'); } - function getTags() + public function getTags() { $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff')); // @fixme should we use the cutoff too? Doesn't help with indexing per-group. @@ -75,31 +70,22 @@ class GroupTagCloudSection extends TagCloudSection } $namestring = implode(',', $quoted); - - $qry = 'SELECT notice_tag.tag, '. - $weightexpr . ' as weight ' . - 'FROM notice_tag JOIN notice ' . - 'ON notice_tag.notice_id = notice.id ' . - 'JOIN group_inbox on group_inbox.notice_id = notice.id ' . - 'WHERE group_inbox.group_id = %d ' . - 'AND notice_tag.tag not in (%s) '. - 'GROUP BY notice_tag.tag ' . - 'ORDER BY weight DESC '; - $limit = TAGS_PER_SECTION; - $offset = 0; - if (common_config('db','type') == 'pgsql') { - $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; - } else { - $qry .= ' LIMIT ' . $offset . ', ' . $limit; - } + $qry = 'SELECT notice_tag.tag, ' . $weightexpr . ' AS weight ' . + 'FROM notice_tag INNER JOIN notice ' . + 'ON notice_tag.notice_id = notice.id ' . + 'INNER JOIN group_inbox ON group_inbox.notice_id = notice.id ' . + 'WHERE group_inbox.group_id = %d ' . + 'AND notice_tag.tag NOT IN (%s) '. + 'GROUP BY notice_tag.tag ' . + 'ORDER BY weight DESC LIMIT ' . $limit; - $tag = Memcached_DataObject::cachedQuery('Notice_tag', - sprintf($qry, - $this->group->id, - $namestring), - 3600); + $tag = Memcached_DataObject::cachedQuery( + 'Notice_tag', + sprintf($qry, $this->group->id, $namestring), + 3600 + ); return $tag; } } diff --git a/plugins/TagCloud/lib/inboxtagcloudsection.php b/plugins/TagCloud/lib/inboxtagcloudsection.php index 4268ee4854..ba89bd5b7f 100644 --- a/plugins/TagCloud/lib/inboxtagcloudsection.php +++ b/plugins/TagCloud/lib/inboxtagcloudsection.php @@ -1,42 +1,36 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * * Personal tag cloud 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 . - * * @category Widget - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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('GNUSOCIAL')) { exit(1); } +defined('GNUSOCIAL') || die(); /** * Personal tag cloud section * - * @category Widget - * @package StatusNet - * @author Evan Prodromou - * @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 InboxTagCloudSection extends TagCloudSection { @@ -44,19 +38,19 @@ class InboxTagCloudSection extends TagCloudSection protected $target = null; - function __construct($out=null, Profile $target) + public function __construct($out = null, Profile $target) { parent::__construct($out); $this->target = $target; } - function title() + public function title() { // TRANS: Title for inbox tag cloud section. return _m('TITLE', 'Trends'); } - function getTags() + public function getTags() { // FIXME: Get the Profile::current() value some other way // to avoid confusion between background stuff and session. @@ -70,22 +64,15 @@ class InboxTagCloudSection extends TagCloudSection $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff')); // @fixme should we use the cutoff too? Doesn't help with indexing per-user. + $limit = TAGS_PER_SECTION; + $qry = 'SELECT notice_tag.tag, '. $weightexpr . ' as weight ' . 'FROM notice_tag JOIN notice ' . 'ON notice_tag.notice_id = notice.id ' . 'WHERE notice.id in (' . implode(',', $ids) . ')'. 'GROUP BY notice_tag.tag ' . - 'ORDER BY weight DESC '; - - $limit = TAGS_PER_SECTION; - $offset = 0; - - if (common_config('db','type') == 'pgsql') { - $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; - } else { - $qry .= ' LIMIT ' . $offset . ', ' . $limit; - } + 'ORDER BY weight DESC LIMIT ' . $limit; $t = new Notice_tag(); @@ -101,7 +88,7 @@ class InboxTagCloudSection extends TagCloudSection return new ArrayWrapper($tag); } - function showMore() + public function showMore() { } } diff --git a/plugins/TagCloud/lib/personaltagcloudsection.php b/plugins/TagCloud/lib/personaltagcloudsection.php index e46aa2d662..f99a7d3825 100644 --- a/plugins/TagCloud/lib/personaltagcloudsection.php +++ b/plugins/TagCloud/lib/personaltagcloudsection.php @@ -1,85 +1,72 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * * Personal tag cloud 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 . - * * @category Widget - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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('GNUSOCIAL')) { exit(1); } +defined('GNUSOCIAL') || die(); /** * Personal tag cloud section * - * @category Widget - * @package StatusNet - * @author Evan Prodromou - * @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 PersonalTagCloudSection extends TagCloudSection { protected $profile = null; - function __construct(HTMLOutputter $out, Profile $profile) + public function __construct(HTMLOutputter $out, Profile $profile) { parent::__construct($out); $this->profile = $profile; } - function title() + public function title() { // TRANS: Title for personal tag cloud section. - return _m('TITLE','Tags'); + return _m('TITLE', 'Tags'); } - function getTags() + public function getTags() { $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff')); // @fixme should we use the cutoff too? Doesn't help with indexing per-user. - $qry = 'SELECT notice_tag.tag, '. - $weightexpr . ' as weight ' . - 'FROM notice_tag JOIN notice ' . - 'ON notice_tag.notice_id = notice.id ' . - 'WHERE notice.profile_id = %d ' . - 'GROUP BY notice_tag.tag ' . - 'ORDER BY weight DESC '; - $limit = TAGS_PER_SECTION; - $offset = 0; - if (common_config('db','type') == 'pgsql') { - $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; - } else { - $qry .= ' LIMIT ' . $offset . ', ' . $limit; - } + $qry = 'SELECT notice_tag.tag, ' . $weightexpr . ' AS weight ' . + 'FROM notice_tag INNER JOIN notice ' . + 'ON notice_tag.notice_id = notice.id ' . + 'WHERE notice.profile_id = %d ' . + 'GROUP BY notice_tag.tag ' . + 'ORDER BY weight DESC LIMIT ' . $limit; - $tag = Memcached_DataObject::cachedQuery('Notice_tag', - sprintf($qry, - $this->profile->getID()), - 3600); + $tag = Memcached_DataObject::cachedQuery( + 'Notice_tag', + sprintf($qry, $this->profile->getID()), + 3600 + ); return $tag; } } diff --git a/plugins/TagCloud/lib/publictagcloudsection.php b/plugins/TagCloud/lib/publictagcloudsection.php index bf88091a90..d7fd597baa 100644 --- a/plugins/TagCloud/lib/publictagcloudsection.php +++ b/plugins/TagCloud/lib/publictagcloudsection.php @@ -1,59 +1,51 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * * Public tag cloud 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 . - * * @category Widget - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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(); /** * Public tag cloud section * - * @category Widget - * @package StatusNet - * @author Evan Prodromou - * @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 PublicTagCloudSection extends TagCloudSection { - function __construct($out=null) + public function __construct($out = null) { parent::__construct($out); } - function title() + public function title() { // TRANS: Title for inbox tag cloud section. return _m('TITLE', 'Trends'); } - function getTags() + public function getTags() { $profile = Profile::current(); @@ -66,7 +58,6 @@ class PublicTagCloudSection extends TagCloudSection $tag = Memcached_DataObject::cacheGet($keypart); if ($tag === false) { - $stream = new PublicNoticeStream($profile); $ids = $stream->getNoticeIds(0, 500, null, null); @@ -77,22 +68,14 @@ class PublicTagCloudSection extends TagCloudSection $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff')); // @fixme should we use the cutoff too? Doesn't help with indexing per-user. - $qry = 'SELECT notice_tag.tag, '. - $weightexpr . ' as weight ' . + $limit = TAGS_PER_SECTION; + + $qry = 'SELECT notice_tag.tag, ' . $weightexpr . ' AS weight ' . 'FROM notice_tag JOIN notice ' . 'ON notice_tag.notice_id = notice.id ' . 'WHERE notice.id in (' . implode(',', $ids) . ') '. 'GROUP BY notice_tag.tag ' . - 'ORDER BY weight DESC '; - - $limit = TAGS_PER_SECTION; - $offset = 0; - - if (common_config('db','type') == 'pgsql') { - $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; - } else { - $qry .= ' LIMIT ' . $offset . ', ' . $limit; - } + 'ORDER BY weight DESC LIMIT ' . $limit; $t = new Notice_tag(); @@ -111,7 +94,7 @@ class PublicTagCloudSection extends TagCloudSection return new ArrayWrapper($tag); } - function showMore() + public function showMore() { } } diff --git a/plugins/TagCloud/lib/subpeopletagcloudsection.php b/plugins/TagCloud/lib/subpeopletagcloudsection.php index b23a82240d..59ad1949b1 100644 --- a/plugins/TagCloud/lib/subpeopletagcloudsection.php +++ b/plugins/TagCloud/lib/subpeopletagcloudsection.php @@ -1,77 +1,64 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * * Personal tag cloud 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 . - * * @category Widget - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @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(); /** * Personal tag cloud section * - * @category Widget - * @package StatusNet - * @author Evan Prodromou - * @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 SubPeopleTagCloudSection extends TagCloudSection { - function getTags() + public function getTags() { $qry = $this->query(); - $limit = TAGS_PER_SECTION; - $offset = 0; + $qry .= ' LIMIT ' . TAGS_PER_SECTION; - if (common_config('db','type') == 'pgsql') { - $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; - } else { - $qry .= ' LIMIT ' . $offset . ', ' . $limit; - } - - $profile_tag = Memcached_DataObject::cachedQuery('Profile_tag', - sprintf($qry, - $this->out->user->id)); + $profile_tag = Memcached_DataObject::cachedQuery( + 'Profile_tag', + sprintf($qry, $this->out->user->id) + ); return $profile_tag; } - function tagUrl($tag) { + public function tagUrl($tag) + { return common_local_url('peopletag', array('tag' => $tag)); } - function showTag($tag, $weight, $relative) { + public function showTag($tag, $weight, $relative) + { $rel = 'tag-cloud-'; - $rel .= 1+intval(7 * $relative * $weight - 0.01); + $rel .= 1 + (int) (7 * $relative * $weight - 0.01); $this->out->elementStart('li', $rel); $this->out->element('a', array('href' => $this->tagUrl($tag)), $tag); $this->out->elementEnd('li'); } } - diff --git a/plugins/TwitterBridge/classes/Twitter_synch_status.php b/plugins/TwitterBridge/classes/Twitter_synch_status.php index 28f60b9b3e..af871e0f02 100644 --- a/plugins/TwitterBridge/classes/Twitter_synch_status.php +++ b/plugins/TwitterBridge/classes/Twitter_synch_status.php @@ -1,35 +1,30 @@ . + /** * Store last-touched ID for various timelines * - * PHP version 5 - * - * @category Data - * @package StatusNet - * @author Evan Prodromou - * @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 . + * @category Data + * @package GNUsocial + * @author Evan Prodromou + * @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'; @@ -40,13 +35,11 @@ require_once INSTALLDIR . '/classes/Memcached_DataObject.php'; * So, we store the last ID we see from a timeline, and store it. Next time * around, we use that ID in the since_id parameter. * - * @category Action - * @package StatusNet - * @author Evan Prodromou - * @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 Twitter_synch_status extends Managed_DataObject { @@ -62,7 +55,7 @@ class Twitter_synch_status extends Managed_DataObject return array( 'fields' => array( 'foreign_id' => array('type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'Foreign message ID'), - 'timeline' => array('type' => 'varchar', 'length' => 191, 'description' => 'timeline name'), + 'timeline' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'timeline name'), 'last_id' => array('type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'last id fetched'), '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'), @@ -71,7 +64,7 @@ class Twitter_synch_status extends Managed_DataObject ); } - static function getLastId($foreign_id, $timeline) + public static function getLastId($foreign_id, $timeline) { $tss = self::pkeyGet(array('foreign_id' => $foreign_id, 'timeline' => $timeline)); @@ -83,7 +76,7 @@ class Twitter_synch_status extends Managed_DataObject } } - static function setLastId($foreign_id, $timeline, $last_id) + public static function setLastId($foreign_id, $timeline, $last_id) { $tss = self::pkeyGet(array('foreign_id' => $foreign_id, 'timeline' => $timeline)); diff --git a/plugins/TwitterBridge/lib/twitterimport.php b/plugins/TwitterBridge/lib/twitterimport.php index cdbe4a3a69..57ed90fc38 100644 --- a/plugins/TwitterBridge/lib/twitterimport.php +++ b/plugins/TwitterBridge/lib/twitterimport.php @@ -1,35 +1,30 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * - * 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 . - * * @category Plugin - * @package StatusNet + * @package GNUsocial * @author Zach Copley * @author Julien C * @author Brion Vibber * @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 */ -if (!defined('STATUSNET')) { - exit(1); -} +defined('GNUSOCIAL') || die(); require_once dirname(__DIR__) . '/twitter.php'; @@ -38,14 +33,8 @@ require_once dirname(__DIR__) . '/twitter.php'; * Is used by both the polling twitterstatusfetcher.php daemon, and the * in-progress streaming import. * - * @category Plugin - * @package StatusNet - * @author Zach Copley - * @author Julien C - * @author Brion Vibber - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - * @link http://twitter.com/ + * @copyright 2009-2010 StatusNet, Inc. + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ class TwitterImport { @@ -74,12 +63,12 @@ class TwitterImport return $notice; } - function name() + public function name() { return get_class($this); } - function saveStatus($status) + public function saveStatus($status) { $profile = $this->ensureProfile($status->user); @@ -103,7 +92,7 @@ class TwitterImport } $dupe = Notice::getKV('uri', $statusUri); - if($dupe instanceof Notice) { + if ($dupe instanceof Notice) { // Add it to our record Notice_to_status::saveNew($dupe->id, $statusId); common_log( @@ -123,24 +112,29 @@ class TwitterImport $author = $original->getProfile(); // TRANS: Message used to repeat a notice. RT is the abbreviation of 'retweet'. // TRANS: %1$s is the repeated user's name, %2$s is the repeated notice. - $content = sprintf(_m('RT @%1$s %2$s'), - $author->nickname, - $original->content); + $content = sprintf( + _m('RT @%1$s %2$s'), + $author->nickname, + $original->content + ); if (Notice::contentTooLong($content)) { $contentlimit = Notice::maxContent(); $content = mb_substr($content, 0, $contentlimit - 4) . ' ...'; } - $repeat = Notice::saveNew($profile->id, - $content, - 'twitter', - array('repeat_of' => $original->id, - 'uri' => $statusUri, - 'is_local' => Notice::GATEWAY, - 'object_type' => ActivityObject::NOTE, - 'verb' => ActivityVerb::POST - )); + $repeat = Notice::saveNew( + $profile->id, + $content, + 'twitter', + [ + 'repeat_of' => $original->id, + 'uri' => $statusUri, + 'is_local' => Notice::GATEWAY, + 'object_type' => ActivityObject::NOTE, + 'verb' => ActivityVerb::POST, + ] + ); common_log(LOG_INFO, "Saved {$repeat->id} as a repeat of {$original->id}"); Notice_to_status::saveNew($repeat->id, $statusId); return $repeat; @@ -183,11 +177,10 @@ class TwitterImport $notice->is_local = Notice::GATEWAY; - $notice->content = html_entity_decode($this->linkify($status, FALSE), ENT_QUOTES, 'UTF-8'); - $notice->rendered = $this->linkify($status, TRUE); + $notice->content = html_entity_decode($this->linkify($status, false), ENT_QUOTES, 'UTF-8'); + $notice->rendered = $this->linkify($status, true); if (Event::handle('StartNoticeSave', array(&$notice))) { - if (empty($notice->conversation)) { $conv = Conversation::create(); common_log(LOG_INFO, "No known conversation for status {$statusId} so a new one ({$conv->getID()}) was created."); @@ -221,7 +214,7 @@ class TwitterImport * * @return string URI */ - function makeStatusURI($username, $id) + public function makeStatusURI($username, $id) { return 'https://twitter.com/' . $username @@ -283,7 +276,7 @@ class TwitterImport if (empty($id)) { throw new Exception('Failed insert'); } - } catch(Exception $e) { + } catch (Exception $e) { common_log(LOG_WARNING, __METHOD__ . " Couldn't insert profile: " . $e->getMessage()); common_log_db_error($profile, 'INSERT', __FILE__); $profile->query("ROLLBACK"); @@ -314,8 +307,13 @@ class TwitterImport if ($avatar->filename === $filename) { return null; } - common_debug(__METHOD__ . " - Updating profile avatar (profile_id={$profile->id}) " . - "from {$avatar->filename} to {$filename}"); + common_debug(sprintf( + '%s - Updating profile avatar (profile_id=%d) from %s to %s', + __METHOD__, + $profile->id, + $avatar->filename, + $filename + )); // else we continue with creating a new avatar } catch (NoAvatarException $e) { // Avatar was not found. We can catch NoAvatarException or FileNotFoundException @@ -367,7 +365,7 @@ class TwitterImport $avatar = new Avatar(); $avatar->profile_id = $profile->id; - $avatar->original = 1; // this is an original/"uploaded" avatar + $avatar->original = true; // this is an original/"uploaded" avatar $avatar->mediatype = $mediatype; $avatar->filename = $filename; $avatar->width = $this->avatarsize; @@ -416,7 +414,7 @@ class TwitterImport const HASHTAG = 2; const MENTION = 3; - function linkify($status, $html = FALSE) + public function linkify($status, $html = false) { $text = $status->text; @@ -424,10 +422,20 @@ class TwitterImport $statusId = twitter_id($status); common_log(LOG_WARNING, "No entities data for {$statusId}; trying to fake up links ourselves."); $text = common_replace_urls_callback($text, 'common_linkify'); - $text = preg_replace_callback('/(^|\"\;|\'|\(|\[|\{|\s+)#([\pL\pN_\-\.]{1,64})/', - function ($m) { return $m[1].'#'.TwitterStatusFetcher::tagLink($m[2]); }, $text); - $text = preg_replace_callback('/(^|\s+)@([a-z0-9A-Z_]{1,64})/', - function ($m) { return $m[1].'@'.TwitterStatusFetcher::atLink($m[2]); }, $text); + $text = preg_replace_callback( + '/(^|\"\;|\'|\(|\[|\{|\s+)#([\pL\pN_\-\.]{1,64})/', + function ($m) { + return $m[1] . '#'.TwitterStatusFetcher::tagLink($m[2]); + }, + $text + ); + $text = preg_replace_callback( + '/(^|\s+)@([a-z0-9A-Z_]{1,64})/', + function ($m) { + return $m[1] . '@'.TwitterStatusFetcher::atLink($m[2]); + }, + $text + ); return $text; } @@ -472,21 +480,21 @@ class TwitterImport $cursor = $start; } $orig = $this->twitEscape(mb_substr($text, $start, $end - $start)); - switch($type) { + switch ($type) { case self::URL: $linkText = $this->makeUrlLink($object, $orig, $html); break; case self::HASHTAG: if ($html) { $linkText = $this->makeHashtagLink($object, $orig); - }else{ + } else { $linkText = $orig; } break; case self::MENTION: if ($html) { $linkText = $this->makeMentionLink($object, $orig); - }else{ + } else { $linkText = $orig; } break; @@ -503,7 +511,7 @@ class TwitterImport return $result; } - function twitEscape($str) + public function twitEscape($str) { // Twitter seems to preemptive turn < and > into < and > // but doesn't for &, so while you may have some magic protection @@ -516,31 +524,31 @@ class TwitterImport return htmlspecialchars(html_entity_decode($str, ENT_COMPAT, 'UTF-8')); } - function makeUrlLink($object, $orig, $html) + public function makeUrlLink($object, $orig, $html) { if ($html) { return ''.htmlspecialchars($object->display_url).''; - }else{ + } else { return htmlspecialchars($object->expanded_url); } } - function makeHashtagLink($object, $orig) + public function makeHashtagLink($object, $orig) { return "#" . self::tagLink($object->text, substr($orig, 1)); } - function makeMentionLink($object, $orig) + public function makeMentionLink($object, $orig) { return "@".self::atLink($object->screen_name, $object->name, substr($orig, 1)); } - static function tagLink($tag, $orig) + public static function tagLink($tag, $orig) { return "{$orig}"; } - static function atLink($screenName, $fullName, $orig) + public static function atLink($screenName, $fullName, $orig) { if (!empty($fullName)) { return "{$orig}"; @@ -549,7 +557,7 @@ class TwitterImport } } - function saveStatusMentions($notice, $status) + public function saveStatusMentions($notice, $status) { $mentions = array(); @@ -582,7 +590,7 @@ class TwitterImport * @param Notice $notice * @param object $status */ - function saveStatusAttachments(Notice $notice, $status) + public function saveStatusAttachments(Notice $notice, $status) { if (common_config('attachments', 'process_links')) { if (!empty($status->entities) && !empty($status->entities->urls)) { diff --git a/plugins/TwitterBridge/scripts/initialize_notice_to_status.php b/plugins/TwitterBridge/scripts/initialize_notice_to_status.php index f4a60c479d..14e56a1191 100755 --- a/plugins/TwitterBridge/scripts/initialize_notice_to_status.php +++ b/plugins/TwitterBridge/scripts/initialize_notice_to_status.php @@ -1,21 +1,25 @@ #!/usr/bin/env 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 . + +/** + * @package TwitterBridge + * @author Evan Prodromou + * @copyright 2010, StatusNet, Inc. + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..')); @@ -37,11 +41,13 @@ require_once INSTALLDIR.'/scripts/commandline.inc'; $n = new Notice(); -$n->query('SELECT notice.id, notice.uri ' . - 'FROM notice LEFT JOIN notice_to_status ' . - 'ON notice.id = notice_to_status.notice_id ' . - 'WHERE notice.source = "twitter"' . - 'AND notice_to_status.status_id IS NULL'); +$n->query( + 'SELECT notice.id, notice.uri ' . + 'FROM notice LEFT JOIN notice_to_status ' . + 'ON notice.id = notice_to_status.notice_id ' . + "WHERE notice.source = 'twitter'" . + 'AND notice_to_status.status_id IS NULL' +); while ($n->fetch()) { if (preg_match('/^http://twitter.com(/#!)?/[\w_.]+/status/(\d+)$/', $n->uri, $match)) { diff --git a/scripts/allsites.php b/scripts/allsites.php index c23685c721..b65b57597c 100755 --- a/scripts/allsites.php +++ b/scripts/allsites.php @@ -1,21 +1,25 @@ #!/usr/bin/env 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 . + +/** + * @package GNUsocial + * @author Evan Prodromou + * @copyright 2009, StatusNet, Inc. + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ // Abort if called from a web server @@ -37,8 +41,8 @@ ENDOFHELP; require_once INSTALLDIR.'/scripts/commandline.inc'; -function print_all_sites() { - +function print_all_sites() +{ $sn = new Status_network(); if ($sn->find()) { @@ -49,14 +53,16 @@ function print_all_sites() { return; } -function print_tagged_sites($tag) { - +function print_tagged_sites($tag) +{ $sn = new Status_network(); - $sn->query('select status_network.nickname '. - 'from status_network join status_network_tag '. - 'on status_network.site_id = status_network_tag.site_id '. - 'where status_network_tag.tag = "' . $tag . '"'); + $sn->query( + 'SELECT status_network.nickname '. + 'FROM status_network INNER JOIN status_network_tag '. + 'ON status_network.site_id = status_network_tag.site_id '. + "WHERE status_network_tag.tag = '" . $sn->escape($tag) . "'" + ); while ($sn->fetch()) { print "$sn->nickname\n"; @@ -65,16 +71,18 @@ function print_tagged_sites($tag) { return; } -function print_untagged_sites($tag) { - +function print_untagged_sites($tag) +{ $sn = new Status_network(); - $sn->query('select status_network.nickname '. - 'from status_network '. - 'where not exists '. - '(select tag from status_network_tag '. - 'where site_id = status_network.site_id '. - 'and tag = "'.$tag.'")'); + $sn->query( + 'SELECT status_network.nickname '. + 'FROM status_network '. + 'WHERE NOT EXISTS '. + '(SELECT tag FROM status_network_tag '. + 'WHERE site_id = status_network.site_id '. + "AND tag = '" . $sn->escape($tag) . "')" + ); while ($sn->fetch()) { print "$sn->nickname\n"; @@ -86,7 +94,7 @@ function print_untagged_sites($tag) { if (have_option('t', 'tagged')) { $tag = get_option_value('t', 'tagged'); print_tagged_sites($tag); -} else if (have_option('w', 'not-tagged')) { +} elseif (have_option('w', 'not-tagged')) { $tag = get_option_value('w', 'not-tagged'); print_untagged_sites($tag); } else { diff --git a/scripts/makegroupadmin.php b/scripts/makegroupadmin.php index 58277c9ea2..4e2eb4ed32 100755 --- a/scripts/makegroupadmin.php +++ b/scripts/makegroupadmin.php @@ -1,21 +1,25 @@ #!/usr/bin/env 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 . + +/** + * @package GNUsocial + * @author Evan Prodromou + * @copyright 2008, 2009 StatusNet, Inc. + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ define('INSTALLDIR', dirname(__DIR__)); @@ -44,7 +48,6 @@ if (empty($nickname) || empty($groupname)) { } try { - $user = User::getKV('nickname', $nickname); if (empty($user)) { @@ -78,12 +81,11 @@ try { $orig = clone($member); - $member->is_admin = 1; + $member->is_admin = true; if (!$member->update($orig)) { throw new Exception("Can't make '$nickname' admin of '$groupname'."); } - } catch (Exception $e) { print $e->getMessage() . "\n"; exit(1); diff --git a/scripts/remove_duplicate_file_urls.php b/scripts/remove_duplicate_file_urls.php index 9754820d98..5a36bc9d68 100755 --- a/scripts/remove_duplicate_file_urls.php +++ b/scripts/remove_duplicate_file_urls.php @@ -1,21 +1,23 @@ #!/usr/bin/env 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 . + +/** + * @copyright 2008, 2009 StatusNet, Inc. + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ define('INSTALLDIR', dirname(__DIR__)); @@ -44,7 +46,7 @@ if (!have_option('y', 'yes')) { } $file = new File(); -$file->query('SELECT id, url, COUNT(*) AS c FROM file GROUP BY url HAVING c > 1'); +$file->query('SELECT url FROM file GROUP BY url HAVING COUNT(*) > 1'); print "\nFound {$file->N} URLs with duplicate entries in file table"; while ($file->fetch()) { // We've got a URL that is duplicated in the file table @@ -54,7 +56,7 @@ while ($file->fetch()) { print "\nDeleting duplicate entries in file table for URL: {$file->url} ["; // Leave one of the URLs in the database by using ->find(true) // and only deleting starting with this fetch. - while($dupfile->fetch()) { + while ($dupfile->fetch()) { print "."; $dupfile->delete(); } @@ -65,7 +67,7 @@ while ($file->fetch()) { } $file = new File_redirection(); -$file->query('SELECT file_id, url, COUNT(*) AS c FROM file_redirection GROUP BY url HAVING c > 1'); +$file->query('SELECT url FROM file_redirection GROUP BY url HAVING COUNT(*) > 1'); print "\nFound {$file->N} URLs with duplicate entries in file_redirection table"; while ($file->fetch()) { // We've got a URL that is duplicated in the file_redirection table @@ -75,7 +77,7 @@ while ($file->fetch()) { print "\nDeleting duplicate entries in file table for URL: {$file->url} ["; // Leave one of the URLs in the database by using ->find(true) // and only deleting starting with this fetch. - while($dupfile->fetch()) { + while ($dupfile->fetch()) { print "."; $dupfile->delete(); } diff --git a/scripts/resend_confirm_address.php b/scripts/resend_confirm_address.php index 0c7b54c11f..449d1b1edf 100755 --- a/scripts/resend_confirm_address.php +++ b/scripts/resend_confirm_address.php @@ -1,5 +1,19 @@ #!/usr/bin/env php . define('INSTALLDIR', dirname(__DIR__)); define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public'); @@ -17,7 +31,7 @@ all lingering confirmations. NOTE: You probably want to do something like this to your database first so only relatively fresh accounts get resent this: - DELETE FROM confirm_address WHERE modified < DATE_SUB(NOW(), INTERVAL 1 month); + DELETE FROM confirm_address WHERE modified < (CURRENT_TIMESTAMP - INTERVAL '1' MONTH); Options: diff --git a/scripts/upgrade.php b/scripts/upgrade.php index 92e1c87c9d..1178d59769 100755 --- a/scripts/upgrade.php +++ b/scripts/upgrade.php @@ -249,7 +249,7 @@ function fixupConversationURIs() while ($conv->fetch()) { $uri = common_local_url('conversation', ['id' => $conv->id]); $sql = sprintf( - 'UPDATE conversation SET uri="%1$s" WHERE id="%2$d";', + 'UPDATE conversation SET uri = \'%1$s\' WHERE id = %2$d;', $conv->escape($uri), $conv->id ); @@ -379,7 +379,7 @@ function initSubscriptionURI() $sub->decache(); $sub->query(sprintf( 'UPDATE subscription '. - 'SET uri = "%s" '. + "SET uri = '%s' " . 'WHERE subscriber = %d '. 'AND subscribed = %d', $sub->escape(Subscription::newUri($sub->getSubscriber(), $sub->getSubscribed(), $sub->created)), @@ -408,7 +408,7 @@ function initGroupMemberURI() $mem->decache(); $mem->query(sprintf( 'UPDATE group_member '. - 'SET uri = "%s" '. + "SET uri = '%s' " . 'WHERE profile_id = %d ' . 'AND group_id = %d', Group_member::newUri(Profile::getByID($mem->profile_id), User_group::getByID($mem->group_id), $mem->created), @@ -443,7 +443,7 @@ function initProfileLists() $plist->tagger = $ptag->tagger; $plist->tag = $ptag->tag; - $plist->private = 0; + $plist->private = false; $plist->created = common_sql_now(); $plist->modified = $plist->created; $plist->mainpage = common_local_url( @@ -537,7 +537,7 @@ function deleteLocalFileThumbnailsWithoutFilename() while ($file->fetch()) { $thumbs = new File_thumbnail(); $thumbs->file_id = $file->id; - $thumbs->whereAdd('filename IS NULL OR filename = ""'); + $thumbs->whereAdd("filename IS NULL OR filename = ''"); // Checking if there were any File_thumbnail entries without filename if (!$thumbs->find()) { continue; @@ -560,7 +560,7 @@ function deleteMissingLocalFileThumbnails() printfnq("Removing all local File_thumbnail entries without existing files..."); $thumbs = new File_thumbnail(); - $thumbs->whereAdd('filename IS NOT NULL AND filename != ""'); + $thumbs->whereAdd("filename IS NOT NULL AND filename != ''"); // Checking if there were any File_thumbnail entries without filename if ($thumbs->find()) { while ($thumbs->fetch()) { @@ -583,7 +583,7 @@ function setFilehashOnLocalFiles() printfnq('Ensuring all local files have the filehash field set...'); $file = new File(); - $file->whereAdd('filename IS NOT NULL AND filename != ""'); // local files + $file->whereAdd("filename IS NOT NULL AND filename != ''"); // local files $file->whereAdd('filehash IS NULL', 'AND'); // without filehash value if ($file->find()) { @@ -605,11 +605,27 @@ function fixupFileThumbnailUrlhash() { printfnq("Setting urlhash for File_thumbnail entries: "); + 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 Exception('Unknown DB type selected.'); + } + $thumb = new File_thumbnail(); - $thumb->query('UPDATE '.$thumb->escapedTableName().' SET urlhash=SHA2(url, 256) WHERE'. - ' url IS NOT NULL AND'. // find all entries with a url value - ' url != "" AND'. // precaution against non-null empty strings - ' urlhash IS NULL'); // but don't touch those we've already calculated + $thumb->query(sprintf( + 'UPDATE %1$s ' . + 'SET urlhash = %2$s ' . + 'WHERE url IS NOT NULL ' . // find all entries with a url value + "AND url <> '' " . // precaution against non-null empty strings + 'AND urlhash IS NULL', // but don't touch those we've already calculated + $thumb->escapedTableName(), + $url_sha256 + )); printfnq("DONE.\n"); }