[DATABASE] Extracted schemaDef method from old files and refactored onto new files

This commit is contained in:
Hugo Sales 2020-03-29 18:33:16 +00:00 committed by Hugo Sales
parent c38b9a1503
commit 8d41944f90
Signed by untrusted user: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
105 changed files with 3313 additions and 15745 deletions

View File

@ -1,80 +1,65 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/*
* Data class for Attentions
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* @category Data
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for attentions
*
* @category DB
* @package GNUsocial
* @copyright 2014 Free Software Foundation, Inc http://www.fsf.org
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 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 Attention extends Managed_DataObject
class Attention
{
public $__table = 'attention'; // table name
public $notice_id; // int(4) primary_key not_null
public $profile_id; // int(4) primary_key not_null
public $reason; // varchar(191)
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
// AUTOCODE BEGIN
public static function schemaDef()
// AUTOCODE END
public static function schemaDef(): array
{
return array(
return [
'name' => 'attention',
'description' => 'Notice attentions to profiles (that are not a mention and not result of a subscription)',
'fields' => array(
'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice_id to give attention'),
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'profile_id for feed receiver'),
'reason' => array('type' => 'varchar', 'length' => 191, 'description' => 'Optional reason why this was brought to the attention of profile_id'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('notice_id', 'profile_id'),
'foreign keys' => array(
'attention_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
'attention_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
),
'indexes' => array(
'attention_profile_id_idx' => array('profile_id'),
),
);
}
public static function saveNew(Notice $notice, Profile $target, $reason=null)
{
try {
$att = Attention::getByKeys(['notice_id'=>$notice->getID(), 'profile_id'=>$target->getID()]);
throw new AlreadyFulfilledException('Attention already exists with reason: '._ve($att->reason));
} catch (NoResultException $e) {
$att = new Attention();
$att->notice_id = $notice->getID();
$att->profile_id = $target->getID();
$att->reason = $reason;
$att->created = common_sql_now();
$result = $att->insert();
if ($result === false) {
throw new Exception('Failed Attention::saveNew for notice id=='.$notice->getID().' target id=='.$target->getID().', reason=="'.$reason.'"');
}
}
self::blow('attention:stream:%d', $target->getID());
return $att;
'fields' => [
'notice_id' => ['type' => 'int', 'not null' => true, 'description' => 'notice_id to give attention'],
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'profile_id for feed receiver'],
'reason' => ['type' => 'varchar', 'length' => 191, 'description' => 'Optional reason why this was brought to the attention of profile_id'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['notice_id', 'profile_id'],
'foreign keys' => [
'attention_notice_id_fkey' => ['notice', ['notice_id' => 'id']],
'attention_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
],
'indexes' => [
'attention_notice_id_idx' => ['notice_id'],
'attention_profile_id_idx' => ['profile_id'],
],
];
}
}

View File

@ -1,277 +1,68 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
defined('GNUSOCIAL') || die();
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Table Definition for avatar
* Entity for user's avatar
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class Avatar extends Managed_DataObject
class Avatar
{
public $__table = 'avatar'; // table name
public $profile_id; // int(4) primary_key not_null
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()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
// AUTOCODE BEGIN
public static function schemaDef()
// AUTOCODE END
public static function schemaDef(): array
{
return array(
'fields' => array(
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
'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'),
'filename' => array('type' => 'varchar', 'length' => 191, 'description' => 'local filename, if local'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('profile_id', 'width', 'height'),
'unique keys' => array(
// 'avatar_filename_key' => array('filename'),
),
'foreign keys' => array(
'avatar_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
),
);
}
// We clean up the file, too
public function delete($useWhere = false)
{
$filename = $this->filename;
if (file_exists(Avatar::path($filename))) {
@unlink(Avatar::path($filename));
}
return parent::delete($useWhere);
}
/*
* 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)
{
try {
$avatars = self::getProfileAvatars($target);
foreach ($avatars as $avatar) {
if ($avatar->original && !$original) {
continue;
}
$avatar->delete();
}
} catch (NoAvatarException $e) {
// There are no avatars to delete, a sort of success.
}
return true;
}
protected static $_avatars = [];
/*
* Get an avatar by profile. Currently can't call newSize with $height
*/
public static function byProfile(Profile $target, $width=null, $height=null)
{
$width = intval($width);
$height = !is_null($height) ? intval($height) : null;
if (is_null($height)) {
$height = $width;
}
$size = "{$width}x{$height}";
if (!isset(self::$_avatars[$target->id])) {
self::$_avatars[$target->id] = array();
} elseif (isset(self::$_avatars[$target->id][$size])) {
return self::$_avatars[$target->id][$size];
}
$avatar = null;
if (Event::handle('StartProfileGetAvatar', array($target, $width, &$avatar))) {
$avatar = self::pkeyGet(
array(
'profile_id' => $target->id,
'width' => $width,
'height' => $height,
)
);
Event::handle('EndProfileGetAvatar', array($target, $width, &$avatar));
}
if (is_null($avatar)) {
// Obviously we can't find an avatar, so let's resize the original!
$avatar = Avatar::newSize($target, $width);
} elseif (!($avatar instanceof Avatar)) {
throw new NoAvatarException($target, $avatar);
}
self::$_avatars[$target->id]["{$avatar->width}x{$avatar->height}"] = $avatar;
return $avatar;
}
public static function getUploaded(Profile $target)
{
$avatar = new Avatar();
$avatar->profile_id = $target->id;
$avatar->original = true;
if (!$avatar->find(true)) {
throw new NoAvatarException($target, $avatar);
}
if (!file_exists(Avatar::path($avatar->filename))) {
// The delete call may be odd for, say, unmounted filesystems
// that cause a file to currently not exist, but actually it does...
$avatar->delete();
throw new NoAvatarException($target, $avatar);
}
return $avatar;
}
public static function getProfileAvatars(Profile $target)
{
$avatar = new Avatar();
$avatar->profile_id = $target->id;
if (!$avatar->find()) {
throw new NoAvatarException($target, $avatar);
}
return $avatar->fetchAll();
}
/**
* Where should the avatar go for this user?
* @param int $id user id
* @param string $extension file extension
* @param int|null $size file size
* @param string|null $extra extra bit for the filename
* @return string
*/
public static function filename(int $id, string $extension, ?int $size = null, ?string $extra = null)
{
if ($size) {
return $id . '-' . $size . (($extra) ? ('-' . $extra) : '') . $extension;
} else {
return $id . '-original' . (($extra) ? ('-' . $extra) : '') . $extension;
}
}
public static function path($filename)
{
$dir = common_config('avatar', 'dir');
if ($dir[strlen($dir)-1] != '/') {
$dir .= '/';
}
return $dir . $filename;
}
public static function url($filename)
{
$path = common_config('avatar', 'url_base');
if ($path[strlen($path)-1] != '/') {
$path .= '/';
}
if ($path[0] != '/') {
$path = '/'.$path;
}
$server = common_config('avatar', 'server');
if (empty($server)) {
$server = common_config('site', 'server');
}
$ssl = (common_config('avatar', 'ssl') || GNUsocial::useHTTPS());
$protocol = ($ssl) ? 'https' : 'http';
return $protocol.'://'.$server.$path.$filename;
}
public function displayUrl()
{
return Avatar::url($this->filename);
}
public static function urlByProfile(Profile $target, $width = null, $height = null)
{
try {
return self::byProfile($target, $width, $height)->displayUrl();
} catch (Exception $e) {
return self::defaultImage($width);
}
}
public static function defaultImage($size = null)
{
if (is_null($size)) {
$size = AVATAR_PROFILE_SIZE;
}
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
AVATAR_STREAM_SIZE => 'stream',
AVATAR_MINI_SIZE => 'mini');
return Theme::path('default-avatar-'.$sizenames[$size].'.png');
}
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
throw new Exception(_m('Avatar size too large'));
}
// So far we only have square avatars and I don't have time to
// rewrite support for non-square ones right now ;)
$height = $width;
$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()
);
$imagefile->resizeTo(Avatar::path($filename), array('width'=>$width, 'height'=>$height));
$scaled = clone($original);
$scaled->original = false;
$scaled->width = $width;
$scaled->height = $height;
$scaled->filename = $filename;
$scaled->created = common_sql_now();
if (!$scaled->insert()) {
// TRANS: An error message when unable to insert avatar data into the db
throw new Exception(_m('Could not insert new avatar data to database'));
}
// Return the new avatar object
return $scaled;
return [
'name' => 'avatar',
'fields' => [
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'],
'original' => ['type' => 'bool', 'default' => false, 'description' => 'uploaded by user or generated?'],
'width' => ['type' => 'int', 'not null' => true, 'description' => 'image width'],
'height' => ['type' => 'int', 'not null' => true, 'description' => 'image height'],
'mediatype' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'file type'],
'filename' => ['type' => 'varchar', 'length' => 191, 'description' => 'local filename, if local'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['profile_id', 'width', 'height'],
'unique keys' => [
// 'avatar_filename_key' => array('filename'),
],
'foreign keys' => [
'avatar_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
],
'indexes' => [
'avatar_profile_id_idx' => ['profile_id'],
],
];
}
}

View File

@ -1,164 +1,54 @@
<?php
/*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, 2009, Control Yourself, Inc.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* This program is free software: you can redistribute it and/or modify
* 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.
*
* This program is distributed in the hope that it will be useful,
* 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
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
if (!defined('GNUSOCIAL')) { exit(1); }
namespace App\Entity;
/**
* Table Definition for config
* Entity for app configuration
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class Config extends Managed_DataObject
class Config
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
// AUTOCODE BEGIN
public $__table = 'config'; // table name
public $section; // varchar(32) primary_key not_null
public $setting; // varchar(32) primary_key not_null
public $value; // text
// AUTOCODE END
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
public static function schemaDef(): array
{
return array(
'fields' => array(
'section' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'default' => '', 'description' => 'configuration section'),
'setting' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'default' => '', 'description' => 'configuration setting'),
'value' => array('type' => 'text', 'description' => 'configuration value'),
),
'primary key' => array('section', 'setting'),
);
return [
'name' => 'config',
'fields' => [
'section' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'default' => '', 'description' => 'configuration section'],
'setting' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'default' => '', 'description' => 'configuration setting'],
'value' => ['type' => 'text', 'description' => 'configuration value'],
],
'primary key' => ['section', 'setting'],
];
}
const settingsKey = 'config:settings';
static function loadSettings()
{
try {
$settings = self::_getSettings();
if (!empty($settings)) {
self::_applySettings($settings);
}
} catch (Exception $e) {
return;
}
}
static function _getSettings()
{
$c = self::memcache();
if (!empty($c)) {
$settings = $c->get(Cache::key(self::settingsKey));
if ($settings !== false) {
return $settings;
}
}
$settings = array();
$config = new Config();
$config->find();
while ($config->fetch()) {
$settings[] = array($config->section, $config->setting, $config->value);
}
$config->free();
if (!empty($c)) {
$c->set(Cache::key(self::settingsKey), $settings);
}
return $settings;
}
static function _applySettings($settings)
{
global $config;
foreach ($settings as $s) {
list($section, $setting, $value) = $s;
$config[$section][$setting] = $value;
}
}
function insert()
{
$result = parent::insert();
if ($result) {
Config::_blowSettingsCache();
}
return $result;
}
function delete($useWhere=false)
{
$result = parent::delete($useWhere);
if ($result !== false) {
Config::_blowSettingsCache();
}
return $result;
}
function update($dataObject=false)
{
$result = parent::update($dataObject);
if ($result !== false) {
Config::_blowSettingsCache();
}
return $result;
}
static function save($section, $setting, $value)
{
$result = null;
$config = Config::pkeyGet(array('section' => $section,
'setting' => $setting));
if (!empty($config)) {
$orig = clone($config);
$config->value = $value;
$result = $config->update($orig);
} else {
$config = new Config();
$config->section = $section;
$config->setting = $setting;
$config->value = $value;
$result = $config->insert();
}
return $result;
}
function _blowSettingsCache()
{
$c = self::memcache();
if (!empty($c)) {
$c->delete(Cache::key(self::settingsKey));
}
}
}
}

View File

@ -0,0 +1,62 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for user's email confimation
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ConfirmAddress
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'confirm_address',
'fields' => [
'code' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'good random code'],
'user_id' => ['type' => 'int', 'default' => 0, 'description' => 'user who requested confirmation'],
'address' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'address (email, xmpp, SMS, etc.)'],
'address_extra' => ['type' => 'varchar', 'length' => 191, 'description' => 'carrier ID, for SMS'],
'address_type' => ['type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'],
'claimed' => ['type' => 'datetime', 'description' => 'date this was claimed for queueing'],
'sent' => ['type' => 'datetime', 'description' => 'date this was sent for queueing'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['code'],
'foreign keys' => [
'confirm_address_user_id_fkey' => ['user', ['user_id' => 'id']],
],
];
}
}

View File

@ -1,183 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for confirm_address
*/
defined('GNUSOCIAL') || die();
class Confirm_address extends Managed_DataObject
{
public $__table = 'confirm_address'; // table name
public $code; // varchar(32) primary_key not_null
public $user_id; // int()
public $address; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $address_extra; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $address_type; // varchar(8) not_null
public $claimed; // datetime()
public $sent; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
public static function schemaDef()
{
return array(
'fields' => array(
'code' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'good random code'),
'user_id' => array('type' => 'int', 'description' => 'user who requested confirmation'),
'address' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'address (email, xmpp, SMS, etc.)'),
'address_extra' => array('type' => 'varchar', 'length' => 191, 'description' => 'carrier ID, for SMS'),
'address_type' => array('type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'),
'claimed' => array('type' => 'datetime', 'description' => 'date this was claimed for queueing'),
'sent' => array('type' => 'datetime', 'description' => 'date this was sent for queueing'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('code'),
'foreign keys' => array(
'confirm_address_user_id_fkey' => array('user', array('user_id' => 'id')),
),
'indexes' => array(
'confirm_address_user_id_idx' => array('user_id'),
),
);
}
public static function getByAddress($address, $addressType)
{
$ca = new Confirm_address();
$ca->address = $address;
$ca->address_type = $addressType;
if (!$ca->find(true)) {
throw new NoResultException($ca);
}
return $ca;
}
public static function saveNew($user, $address, $addressType, $extra = null)
{
$ca = new Confirm_address();
if (!empty($user)) {
$ca->user_id = $user->id;
}
$ca->address = $address;
$ca->address_type = $addressType;
$ca->address_extra = $extra;
$ca->code = common_confirmation_code(64);
$ca->insert();
return $ca;
}
public function getAddress()
{
return $this->address;
}
public function getAddressType()
{
return $this->address_type;
}
public function getCode()
{
return $this->code;
}
public function getProfile()
{
return Profile::getByID($this->user_id);
}
public function getUrl()
{
return common_local_url('confirmaddress', array('code' => $this->code));
}
/**
* Supply arguments in $args. Currently known args:
* headers Array with headers (only used for email)
* nickname How we great the user (defaults to nickname, but can be any string)
* sitename Name we sign the email with (defaults to sitename, but can be any string)
* url The confirmation address URL.
*/
public function sendConfirmation(array $args = [])
{
common_debug('Sending confirmation URL for user '._ve($this->user_id).' using '._ve($this->address_type));
$defaults = [
'headers' => [],
'nickname' => $this->getProfile()->getNickname(),
'sitename' => common_config('site', 'name'),
'url' => $this->getUrl(),
];
foreach (array_keys($defaults) as $key) {
if (!isset($args[$key])) {
$args[$key] = $defaults[$key];
}
}
switch ($this->getAddressType()) {
case 'email':
$this->sendEmailConfirmation($args);
break;
default:
throw ServerException('Unable to handle confirm_address address type: '._ve($this->address_type));
}
}
public function sendEmailConfirmation(array $args = [])
{
// TRANS: Subject for address confirmation email.
$subject = _('Email address confirmation');
// TRANS: Body for address confirmation email.
// TRANS: %1$s is the addressed user's nickname, %2$s is the StatusNet sitename,
// TRANS: %3$s is the URL to confirm at.
$body = sprintf(
_("Hey, %1\$s.\n\n" .
"Someone just entered this email address on %2\$s.\n\n" .
"If it was you, and you want to confirm your entry, ".
"use the URL below:\n\n\t%3\$s\n\n" .
"If not, just ignore this message.\n\n".
"Thanks for your time, \n%2\$s\n"),
$args['nickname'],
$args['sitename'],
$args['url']
);
require_once INSTALLDIR . '/lib/util/mail.php';
return mail_to_user($this->getProfile()->getUser(), $subject, $body, $args['headers'], $this->getAddress());
}
public function delete($useWhere = false)
{
$result = parent::delete($useWhere);
if ($result === false) {
common_log_db_error($confirm, 'DELETE', __FILE__);
// TRANS: Server error displayed when an address confirmation code deletion from the
// TRANS: database fails in the contact address confirmation action.
throw new ServerException(_('Could not delete address confirmation.'));
}
return $result;
}
}

View File

@ -1,95 +1,57 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Table Definition for consumer
* Entity for OAuth consumer
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 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 Consumer extends Managed_DataObject
class Consumer
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
// AUTOCODE BEGIN
public $__table = 'consumer'; // table name
public $consumer_key; // varchar(191) primary_key not_null not 255 because utf8mb4 takes more space
public $consumer_secret; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $seed; // char(32) not_null
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
// AUTOCODE END
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
public static function schemaDef(): array
{
return array(
return [
'name' => 'consumer',
'description' => 'OAuth consumer record',
'fields' => array(
'consumer_key' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'unique identifier, root URL'),
'consumer_secret' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'secret value'),
'seed' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'seed for new tokens by this consumer'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('consumer_key'),
);
}
public static function generateNew()
{
$cons = new Consumer();
$rand = common_random_hexstr(16);
$cons->seed = $rand;
$cons->consumer_key = md5(time() + $rand);
$cons->consumer_secret = md5(md5(time() + time() + $rand));
$cons->created = common_sql_now();
return $cons;
}
/**
* Delete a Consumer and related tokens and nonces
*
* XXX: Should this happen in an OAuthDataStore instead?
*
*/
public function delete($useWhere = false)
{
// XXX: Is there any reason NOT to do this kind of cleanup?
$this->deleteTokens();
$this->deleteNonces();
return parent::delete($useWhere);
}
private function deleteTokens()
{
$token = new Token();
$token->consumer_key = $this->consumer_key;
$token->delete();
}
private function deleteNonces()
{
$nonce = new Nonce();
$nonce->consumer_key = $this->consumer_key;
$nonce->delete();
'fields' => [
'consumer_key' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'unique identifier, root URL'],
'consumer_secret' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'secret value'],
'seed' => ['type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'seed for new tokens by this consumer'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['consumer_key'],
];
}
}

View File

@ -1,172 +1,57 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Data class for Conversations
*
* @category Data
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2010 StatusNet Inc.
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Conversation extends Managed_DataObject
class Conversation
{
public $__table = 'conversation'; // table name
public $id; // int(4) primary_key not_null auto_increment
public $uri; // varchar(191) unique_key not 255 because utf8mb4 takes more space
public $url; // varchar(191) unique_key not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
// AUTOCODE BEGIN
public static function schemaDef()
// AUTOCODE END
public static function schemaDef(): array
{
return array(
'fields' => array(
'id' => array('type' => 'serial', 'not null' => true, 'description' => 'Unique identifier, (again) unrelated to notice id since 2016-01-06'),
'uri' => array('type' => 'varchar', 'not null'=>true, 'length' => 191, 'description' => 'URI of the conversation'),
'url' => array('type' => 'varchar', 'length' => 191, 'description' => 'Resolvable URL, preferrably remote (local can be generated on the fly)'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('id'),
'unique keys' => array(
'conversation_uri_key' => array('uri'),
),
);
}
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'] ?? false) {
// since we already have auto incrementing ('serial') we can continue
return;
}
// The conversation will be recreated in upgrade.php, which will
// generate a new URI, but that's collateral damage for you.
$conv = new Conversation();
$conv->id = 0;
if ($conv->find()) {
while ($conv->fetch()) {
// Since we have filtered on 0 this only deletes such entries
// which I have been afraid wouldn't work, but apparently does!
// (I thought it would act as null or something and find _all_ conversation entries)
$conv->delete();
}
}
}
/**
* Factory method for creating a new conversation.
*
* Use this for locally initiated conversations. Remote notices should
* preferrably supply their own conversation URIs in the OStatus feed.
*
* @return Conversation the new conversation DO
*/
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();
$conv->created = $created ?: common_sql_now();
if ($ctx instanceof ActivityContext) {
$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)
);
// locally generated Conversation objects don't get static URLs stored
$conv->url = $conv->sqlValue('NULL');
}
// This insert throws exceptions on failure
$conv->insert();
return $conv;
}
public static function noticeCount($id)
{
$keypart = sprintf('conversation:notice_count:%d', $id);
$cnt = self::cacheGet($keypart);
if ($cnt !== false) {
return $cnt;
}
$notice = new Notice();
$notice->conversation = $id;
$notice->whereAddIn('verb', array(ActivityVerb::POST, ActivityUtils::resolveUri(ActivityVerb::POST, true)), $notice->columnType('verb'));
$cnt = $notice->count();
self::cacheSet($keypart, $cnt);
return $cnt;
}
public static function getUrlFromNotice(Notice $notice, $anchor = true)
{
$conv = Conversation::getByID($notice->conversation);
return $conv->getUrl($anchor ? $notice->getID() : null);
}
public function getUri()
{
return $this->uri;
}
public function getUrl($noticeId=null)
{
// FIXME: the URL router should take notice-id as an argument...
return common_local_url('conversation', array('id' => $this->getID())) .
($noticeId===null ? '' : "#notice-{$noticeId}");
}
// FIXME: ...will 500 ever be too low? Taken from ConversationAction::MAX_NOTICES
public function getNotices(Profile $scoped=null, $offset=0, $limit=500)
{
$stream = new ConversationNoticeStream($this->getID(), $scoped);
$notices = $stream->getNotices($offset, $limit);
return $notices;
}
public function insert()
{
$result = parent::insert();
if ($result === false) {
common_log_db_error($this, 'INSERT', __FILE__);
throw new ServerException(_('Failed to insert Conversation into database'));
}
return $result;
return [
'name' => 'conversation',
'fields' => [
'id' => ['type' => 'serial', 'not null' => true, 'description' => 'Unique identifier, (again) unrelated to notice id since 2016-01-06'],
'uri' => ['type' => 'varchar', 'not null' => true, 'length' => 191, 'description' => 'URI of the conversation'],
'url' => ['type' => 'varchar', 'length' => 191, 'description' => 'Resolvable URL, preferrably remote (local can be generated on the fly)'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['id'],
'unique keys' => [
'conversation_uri_key' => ['uri'],
],
];
}
}

View File

@ -1,35 +1,41 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* @category Files
* Entity for uploaded files
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @author Miguel Dantas <biodantas@gmail.com>
* @copyright 2008-2009, 2019 Free Software Foundation http://fsf.org
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
/**
* Table Definition for file
*/
class File extends Managed_DataObject
class File
{
<<<<<<< HEAD
public $__table = 'file'; // table name
public $id; // int(4) primary_key not_null
public $urlhash; // varchar(64) unique_key
@ -882,132 +888,38 @@ class File extends Managed_DataObject
'File_redirection',
'File_thumbnail',
'File_to_post'
=======
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'file',
'fields' => [
'id' => ['type' => 'serial', 'not null' => true],
'urlhash' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'sha256 of destination URL (url field)'],
'url' => ['type' => 'text', 'description' => 'destination URL after following possible redirections'],
'filehash' => ['type' => 'varchar', 'length' => 64, 'not null' => false, 'description' => 'sha256 of the file contents, only for locally stored files of course'],
'mimetype' => ['type' => 'varchar', 'length' => 50, 'description' => 'mime type of resource'],
'size' => ['type' => 'int', 'description' => 'size of resource when available'],
'title' => ['type' => 'text', 'description' => 'title of resource when available'],
'date' => ['type' => 'int', 'description' => 'date of resource according to http query'],
'protected' => ['type' => 'int', 'description' => 'true when URL is private (needs login)'],
'filename' => ['type' => 'text', 'description' => 'if file is stored locally (too) this is the filename'],
'width' => ['type' => 'int', 'description' => 'width in pixels, if it can be described as such and data is available'],
'height' => ['type' => 'int', 'description' => 'height in pixels, if it can be described as such and data is available'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['id'],
'unique keys' => [
'file_urlhash_key' => ['urlhash'],
],
'indexes' => [
'file_filehash_idx' => ['filehash'],
],
>>>>>>> ecc5139ce5 ([DATABASE] Extracted schemaDef method from old files and refactored onto new files)
];
Event::handle('FileDeleteRelated', [$this, &$related]);
foreach ($related as $cls) {
$inst = new $cls();
$inst->file_id = $this->id;
if ($inst->find()) {
while ($inst->fetch()) {
$inst->delete();
}
}
}
// And finally remove the entry from the database
return parent::delete($useWhere);
}
public function getTitle()
{
$title = $this->title ?: MediaFile::getDisplayName($this);
return $title ?: null;
}
public function setTitle($title)
{
$orig = clone($this);
$this->title = mb_strlen($title) > 0 ? $title : null;
return $this->update($orig);
}
public static function hashurl($url)
{
if (empty($url)) {
throw new Exception('No URL provided to hash algorithm.');
}
return hash(self::URLHASH_ALG, $url);
}
public static function beforeSchemaUpdate()
{
$table = strtolower(get_called_class());
$schema = Schema::get();
$schemadef = $schema->getTableDef($table);
// 2015-02-19 We have to upgrade our table definitions to have the urlhash field populated
if (isset($schemadef['fields']['urlhash']) && isset($schemadef['unique keys']['file_urlhash_key'])) {
// We already have the urlhash field, so no need to migrate it.
return;
}
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(*) 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
// so we'll cut it. We could save the original URL, but there is
// no guarantee it is complete anyway since the previous max was 255 chars.
$dupfile = new File();
// First we find file entries that would be duplicates of this when shortened
// ... and we'll just throw the dupes out the window for now! It's already so borken.
$dupfile->query(sprintf('SELECT * FROM file WHERE LEFT(url, 191) = %1$s', $dupfile->_quote($file->shortenedurl)));
// Leave one of the URLs in the database by using ->find(true) (fetches first entry)
if ($dupfile->find(true)) {
print "\nShortening url entry for $table id: {$file->id} [";
$orig = clone($dupfile);
$origurl = $dupfile->url; // save for logging purposes
$dupfile->url = $file->shortenedurl; // make sure it's only 191 chars from now on
$dupfile->update($orig);
print "\nDeleting duplicate entries of too long URL on $table id: {$file->id} [";
// only start deleting with this fetch.
while ($dupfile->fetch()) {
common_log(LOG_INFO, sprintf('Deleting duplicate File entry of %1$d: %2$d (original URL: %3$s collides with these first 191 characters: %4$s', $dupfile->id, $file->id, $origurl, $file->shortenedurl));
print ".";
$dupfile->delete();
}
print "]\n";
} else {
print "\nWarning! URL suddenly disappeared from database: {$file->url}\n";
}
}
echo "...and now all the non-duplicates which are longer than 191 characters...\n";
$file->query('UPDATE file SET url = LEFT(url, 191) WHERE LENGTH(url) > 191');
echo "\n...now running hacky pre-schemaupdate change for $table:";
// 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' => false, // this is because when adding column, all entries will _be_ NULL!
'description' => 'sha256 of destination URL (url field)',
);
$schemadef['fields']['url'] = array(
'type' => 'text',
'description' => 'destination URL after following possible redirections',
);
unset($schemadef['unique keys']);
$schema->ensureTable($table, $schemadef);
echo "DONE.\n";
$classname = ucfirst($table);
$tablefix = new $classname;
// urlhash is hash('sha256', $url) in the File table
echo "Updating urlhash fields in $table table...";
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, modified = CURRENT_TIMESTAMP;',
$tablefix->escapedTableName(),
$url_sha256
));
echo "DONE.\n";
echo "Resuming core schema upgrade...";
}
}

View File

@ -0,0 +1,60 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for File redirects
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class FileRedirection
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'file_redirection',
'fields' => [
'urlhash' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'sha256 hash of the URL'],
'url' => ['type' => 'text', 'description' => 'short URL (or any other kind of redirect) for file (id)'],
'file_id' => ['type' => 'int', 'description' => 'short URL for what URL/file'],
'redirections' => ['type' => 'int', 'description' => 'redirect count'],
'httpcode' => ['type' => 'int', 'description' => 'HTTP status code (20x, 30x, etc.)'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['urlhash'],
'foreign keys' => [
'file_redirection_file_id_fkey' => ['file', ['file_id' => 'id']],
],
];
}
}

View File

@ -0,0 +1,65 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for File thumbnails
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class FileThumbnail
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'file_thumbnail',
'fields' => [
'file_id' => ['type' => 'int', 'not null' => true, 'description' => 'thumbnail for what URL/file'],
'urlhash' => ['type' => 'varchar', 'length' => 64, 'description' => 'sha256 of url field if non-empty'],
'url' => ['type' => 'text', 'description' => 'URL of thumbnail'],
'filename' => ['type' => 'text', 'description' => 'if stored locally, filename is put here'],
'width' => ['type' => 'int', 'not null' => true, 'description' => 'width of thumbnail'],
'height' => ['type' => 'int', 'not null' => true, 'description' => 'height of thumbnail'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['file_id', 'width', 'height'],
'indexes' => [
'file_thumbnail_file_id_idx' => ['file_id'],
'file_thumbnail_urlhash_idx' => ['urlhash'],
],
'foreign keys' => [
'file_thumbnail_file_id_fkey' => ['file', ['file_id' => 'id']],
],
];
}
}

62
src/Entity/FileToPost.php Normal file
View File

@ -0,0 +1,62 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for relating a file to a post
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class FileToPost
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'file_to_post',
'fields' => [
'file_id' => ['type' => 'int', 'not null' => true, 'description' => 'id of URL/file'],
'post_id' => ['type' => 'int', 'not null' => true, 'description' => 'id of the notice it belongs to'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['file_id', 'post_id'],
'foreign keys' => [
'file_to_post_file_id_fkey' => ['file', ['file_id' => 'id']],
'file_to_post_post_id_fkey' => ['notice', ['post_id' => 'id']],
],
'indexes' => [
'file_id_idx' => ['file_id'],
'post_id_idx' => ['post_id'],
],
];
}
}

View File

@ -1,490 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
defined('GNUSOCIAL') || die();
/**
* Table Definition for file_redirection
*/
class File_redirection extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'file_redirection'; // table name
public $urlhash; // varchar(64) primary_key not_null
public $url; // text
public $file_id; // int(4)
public $redirections; // int(4)
public $httpcode; // int(4)
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
protected $file; /* Cache the associated file sometimes */
public static function schemaDef()
{
return array(
'fields' => array(
'urlhash' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'sha256 hash of the URL'),
'url' => array('type' => 'text', 'description' => 'short URL (or any other kind of redirect) for file (id)'),
'file_id' => array('type' => 'int', 'description' => 'short URL for what URL/file'),
'redirections' => array('type' => 'int', 'description' => 'redirect count'),
'httpcode' => array('type' => 'int', 'description' => 'HTTP status code (20x, 30x, etc.)'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('urlhash'),
'foreign keys' => array(
'file_redirection_file_id_fkey' => array('file', array('file_id' => 'id')),
),
'indexes' => array(
'file_redirection_file_id_idx' => array('file_id'),
),
);
}
public static function getByUrl($url)
{
return self::getByPK(array('urlhash' => File::hashurl($url)));
}
public static function _commonHttp($url, $redirs)
{
$request = new HTTPClient($url);
$request->setConfig(array(
'connect_timeout' => 10, // # seconds to wait
'max_redirs' => $redirs, // # max number of http redirections to follow
'follow_redirects' => false, // We follow redirects ourselves in lib/httpclient.php
'store_body' => false, // We won't need body content here.
));
return $request;
}
/**
* Check if this URL is a redirect and return redir info.
*
* Most code should call File_redirection::where instead, to check if we
* already know that redirection and avoid extra hits to the web.
*
* The URL is hit and any redirects are followed, up to 10 levels or until
* a protected URL is reached.
*
* @param string $in_url
* @return mixed one of:
* string - target URL, if this is a direct link or can't be followed
* array - redirect info if this is an *unknown* redirect:
* associative array with the following elements:
* code: HTTP status code
* redirects: count of redirects followed
* url: URL string of final target
* type (optional): MIME type from Content-Type header
* size (optional): byte size from Content-Length header
* time (optional): timestamp from Last-Modified header
*/
public static function lookupWhere($short_url, $redirs = 10, $protected = false)
{
if ($redirs < 0) {
return false;
}
if (strpos($short_url, '://') === false) {
return $short_url;
}
try {
$request = self::_commonHttp($short_url, $redirs);
// Don't include body in output
$request->setMethod(HTTP_Request2::METHOD_HEAD);
$response = $request->send();
if (405 == $response->getStatus() || 204 == $response->getStatus()) {
// HTTP 405 Unsupported Method
// Server doesn't support HEAD method? Can this really happen?
// We'll try again as a GET and ignore the response data.
//
// HTTP 204 No Content
// YFrog sends 204 responses back for our HEAD checks, which
// seems like it may be a logic error in their servers. If
// we get a 204 back, re-run it as a GET... if there's really
// no content it'll be cheap. :)
$request = self::_commonHttp($short_url, $redirs);
$response = $request->send();
} elseif (400 == $response->getStatus()) {
throw new Exception('Got error 400 on HEAD request, will not go further.');
}
} catch (Exception $e) {
// Invalid URL or failure to reach server
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 ($response->getRedirectCount() && File::isProtected($response->getEffectiveUrl())) {
$return_url = $response->redirUrls[$response->getRedirectCount() - 1];
} else {
$return_url = $response->getEffectiveUrl();
}
$ret = array('code' => $response->getStatus()
, 'redirects' => $response->getRedirectCount()
, 'url' => $return_url);
$type = $response->getHeader('Content-Type');
if ($type) {
$ret['type'] = $type;
}
if ($protected) {
$ret['protected'] = true;
}
$size = $response->getHeader('Content-Length'); // @fixme bytes?
if ($size) {
$ret['size'] = $size;
}
$time = $response->getHeader('Last-Modified');
if ($time) {
$ret['time'] = strtotime($time);
}
return $ret;
}
/**
* Check if this URL is a redirect and return redir info.
* If a File record is present for this URL, it is not considered a redirect.
* If a File_redirection record is present for this URL, the recorded target is returned.
*
* If no File or File_redirect record is present, the URL is hit and any
* redirects are followed, up to 10 levels or until a protected URL is
* reached.
*
* @param string $in_url
* @param boolean $discover true to attempt dereferencing the redirect if we don't know it already
* @return File_redirection
*/
public static function where($in_url, $discover = true)
{
$redir = new File_redirection();
$redir->url = $in_url;
$redir->urlhash = File::hashurl($redir->url);
$redir->redirections = 0;
try {
$r = File_redirection::getByUrl($in_url);
try {
$f = File::getByID($r->file_id);
$r->file = $f;
$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...'
);
$r->delete();
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 {
$f = File::getByUrl($in_url);
$redir->file_id = $f->id;
$redir->file = $f;
return $redir;
} 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
$redir_info = File_redirection::lookupWhere($in_url);
if (is_string($redir_info)) {
$redir_info = array('url' => $redir_info);
}
// the last url in the redirection chain can actually be a redirect!
// this is the case with local /attachment/{file_id} links
// in that case we have the file id already
try {
$r = File_redirection::getByUrl($redir_info['url']);
$f = File::getKV('id', $r->file_id);
if ($f instanceof File) {
$redir->file = $f;
$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...'
);
$r->delete();
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']);
} 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) {
try {
$file_redir = File_redirection::getByUrl($in_url);
} catch (NoResultException $e) {
$file_redir = new File_redirection();
$file_redir->urlhash = File::hashurl($in_url);
$file_redir->url = $in_url;
$file_redir->file_id = $redir->file->getID();
$file_redir->insert();
$file_redir->redir_url = $redir->file->url;
}
$file_redir->file = $redir->file;
return $file_redir;
}
}
return $redir;
}
/**
* Shorten a URL with the current user's configured shortening
* options, if applicable.
*
* If it cannot be shortened or the "short" URL is longer than the
* original, the original is returned.
*
* If the referenced item has not been seen before, embedding data
* may be saved.
*
* @param string $long_url
* @param User $user whose shortening options to use; defaults to the current web session user
* @return string
*/
public static function makeShort($long_url, $user = null)
{
$canon = File_redirection::_canonUrl($long_url);
$short_url = File_redirection::_userMakeShort($canon, $user);
// Did we get one? Is it shorter?
return !empty($short_url) ? $short_url : $long_url;
}
/**
* Shorten a URL with the current user's configured shortening
* options, if applicable.
*
* If it cannot be shortened or the "short" URL is longer than the
* original, the original is returned.
*
* If the referenced item has not been seen before, embedding data
* may be saved.
*
* @param string $long_url
* @return string
*/
public static function forceShort($long_url, $user)
{
$canon = File_redirection::_canonUrl($long_url);
$short_url = File_redirection::_userMakeShort($canon, $user, true);
// Did we get one? Is it shorter?
return !empty($short_url) ? $short_url : $long_url;
}
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;
// store it
try {
$file = File::getByUrl($long_url);
} catch (NoResultException $e) {
// Check if the target URL is itself a redirect...
// This should already have happened in processNew in common_shorten_url()
$redir = File_redirection::where($long_url);
$file = $redir->file;
}
// Now we definitely have a File object in $file
try {
$file_redir = File_redirection::getByUrl($short_url);
} catch (NoResultException $e) {
$file_redir = new File_redirection();
$file_redir->urlhash = File::hashurl($short_url);
$file_redir->url = $short_url;
$file_redir->file_id = $file->getID();
$file_redir->insert();
}
return $short_url;
}
return null;
}
/**
* Basic attempt to canonicalize a URL, cleaning up some standard variants
* such as funny syntax or a missing path. Used internally when cleaning
* up URLs for storage and following redirect chains.
*
* Note that despite being on File_redirect, this function DOES NOT perform
* any dereferencing of redirects.
*
* @param string $in_url input URL
* @param string $default_scheme if given a bare link; defaults to 'http://'
* @return string
*/
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'])) {
list($scheme) = explode(':', $in_url, 2);
switch (strtolower($scheme)) {
case 'fax':
case 'tel':
$out_url = str_replace('.-()', '', $out_url);
break;
// non-HTTP schemes, so no redirects
case 'bitcoin':
case 'mailto':
case 'aim':
case 'jabber':
case 'xmpp':
// don't touch anything
break;
// URLs without domain name, so no redirects
case 'magnet':
// don't touch anything
break;
// URLs with coordinates, not browsable domain names
case 'geo':
// don't touch anything
break;
default:
$out_url = $default_scheme . ltrim($out_url, '/');
$p = parse_url($out_url);
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['path'])) {
$out_url .= '/';
}
}
return $out_url;
}
public static function saveNew($data, $file_id, $url)
{
$file_redir = new File_redirection;
$file_redir->urlhash = File::hashurl($url);
$file_redir->url = $url;
$file_redir->file_id = $file_id;
$file_redir->redirections = intval($data['redirects']);
$file_redir->httpcode = intval($data['code']);
$file_redir->insert();
}
public static function beforeSchemaUpdate()
{
$table = strtolower(get_called_class());
$schema = Schema::get();
$schemadef = $schema->getTableDef($table);
// 2015-02-19 We have to upgrade our table definitions to have the urlhash field populated
if (isset($schemadef['fields']['urlhash']) && in_array('urlhash', $schemadef['primary key'])) {
// We already have the urlhash field, so no need to migrate it.
return;
}
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'] = [
'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";
$classname = ucfirst($table);
$tablefix = new $classname;
// urlhash is hash('sha256', $url) in the File table
echo "Updating urlhash fields in $table table...";
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, modified = CURRENT_TIMESTAMP;',
$tablefix->escapedTableName(),
$url_sha256
));
echo "DONE.\n";
echo "Resuming core schema upgrade...";
}
public function getFile()
{
if (!$this->file instanceof File) {
$this->file = File::getByID($this->file_id);
}
return $this->file;
}
}

View File

@ -1,114 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for file_to_post
*
* @copyright 2008, 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class File_to_post extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'file_to_post'; // table name
public $file_id; // int(4) primary_key not_null
public $post_id; // int(4) primary_key not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'file_id' => array('type' => 'int', 'not null' => true, 'description' => 'id of URL/file'),
'post_id' => array('type' => 'int', 'not null' => true, 'description' => 'id of the notice it belongs to'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('file_id', 'post_id'),
'foreign keys' => array(
'file_to_post_file_id_fkey' => array('file', array('file_id' => 'id')),
'file_to_post_post_id_fkey' => array('notice', array('post_id' => 'id')),
),
'indexes' => array(
'file_to_post_post_id_idx' => array('post_id'),
),
);
}
public static function processNew(File $file, Notice $notice)
{
static $seen = array();
$file_id = $file->getID();
$notice_id = $notice->getID();
if (!array_key_exists($notice_id, $seen)) {
$seen[$notice_id] = array();
}
if (empty($seen[$notice_id]) || !in_array($file_id, $seen[$notice_id])) {
try {
$f2p = File_to_post::getByPK(array('post_id' => $notice_id,
'file_id' => $file_id));
} catch (NoResultException $e) {
$f2p = new File_to_post;
$f2p->file_id = $file_id;
$f2p->post_id = $notice_id;
$f2p->insert();
$file->blowCache();
}
$seen[$notice_id][] = $file_id;
}
}
public static function getNoticeIDsByFile(File $file)
{
$f2p = new File_to_post();
$f2p->selectAdd();
$f2p->selectAdd('post_id');
$f2p->file_id = $file->getID();
$ids = array();
if (!$f2p->find()) {
throw new NoResultException($f2p);
}
return $f2p->fetchAll('post_id');
}
public function delete($useWhere = false)
{
try {
$f = File::getByID($this->file_id);
$f->blowCache();
} catch (NoResultException $e) {
// ...alright, that's weird, but no File to delete anyway.
}
return parent::delete($useWhere);
}
}

View File

@ -0,0 +1,70 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for user's foreign profile
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ForeignLink
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'foreign_link',
'fields' => [
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'link to user on this system, if exists'],
'foreign_id' => ['type' => 'int', 'size' => 'big', 'unsigned' => true, 'not null' => true, 'description' => 'link to user on foreign service, if exists'],
'service' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to service'],
'credentials' => ['type' => 'varchar', 'length' => 191, 'description' => 'authc credentials, typically a password'],
'noticesync' => ['type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'notice synchronization, bit 1 = sync outgoing, bit 2 = sync incoming, bit 3 = filter local replies'],
'friendsync' => ['type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 2, 'description' => 'friend synchronization, bit 1 = sync outgoing, bit 2 = sync incoming'],
'profilesync' => ['type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'profile synchronization, bit 1 = sync outgoing, bit 2 = sync incoming'],
'last_noticesync' => ['type' => 'datetime', 'description' => 'last time notices were imported'],
'last_friendsync' => ['type' => 'datetime', 'description' => 'last time friends were imported'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['user_id', 'foreign_id', 'service'],
'foreign keys' => [
'foreign_link_user_id_fkey' => ['user', ['user_id' => 'id']],
'foreign_link_foreign_id_fkey' => ['foreign_user', ['foreign_id' => 'id', 'service' => 'service']],
'foreign_link_service_fkey' => ['foreign_service', ['service' => 'id']],
],
'indexes' => [
'foreign_user_user_id_idx' => ['user_id'],
],
];
}
}

View File

@ -0,0 +1,59 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for foreign services
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ForeignService
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'foreign_service',
'fields' => [
'id' => ['type' => 'int', 'not null' => true, 'description' => 'numeric key for service'],
'name' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'name of the service'],
'description' => ['type' => 'varchar', 'length' => 191, 'description' => 'description'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['id'],
'unique keys' => [
'foreign_service_name_key' => ['name'],
],
];
}
}

View File

@ -0,0 +1,65 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for user's foreign subscriptions
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ForeignSubscription
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'foreign_subscription',
'fields' => [
'service' => ['type' => 'int', 'not null' => true, 'description' => 'service where relationship happens'],
'subscriber' => ['type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'subscriber on foreign service'],
'subscribed' => ['type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'subscribed user'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
],
'primary key' => ['service', 'subscriber', 'subscribed'],
'foreign keys' => [
'foreign_subscription_service_fkey' => ['foreign_service', ['service' => 'id']],
'foreign_subscription_subscriber_fkey' => ['foreign_user', ['subscriber' => 'id', 'service' => 'service']],
'foreign_subscription_subscribed_fkey' => ['foreign_user', ['subscribed' => 'id', 'service' => 'service']],
],
'indexes' => [
'foreign_subscription_subscriber_idx' => ['service', 'subscriber'],
'foreign_subscription_subscribed_idx' => ['service', 'subscribed'],
],
];
}
}

View File

@ -0,0 +1,63 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Foreign Users
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ForeignUser
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'foreign_user',
'fields' => [
'id' => ['type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'unique numeric key on foreign service'],
'service' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to service'],
'uri' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'identifying URI'],
'nickname' => ['type' => 'varchar', 'length' => 191, 'description' => 'nickname on foreign service'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['id', 'service'],
'foreign keys' => [
'foreign_user_service_fkey' => ['foreign_service', ['service' => 'id']],
],
'unique keys' => [
'foreign_user_uri_key' => ['uri'],
],
];
}
}

View File

@ -1,187 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for foreign_link
*/
defined('GNUSOCIAL') || die();
class Foreign_link extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'foreign_link'; // table name
public $user_id; // int(4) primary_key not_null
public $foreign_id; // bigint(8) primary_key not_null unsigned
public $service; // int(4) primary_key not_null
public $credentials; // blob
public $noticesync; // tinyint(1) not_null default_1
public $friendsync; // tinyint(1) not_null default_2
public $profilesync; // tinyint(1) not_null default_1
public $last_noticesync; // datetime()
public $last_friendsync; // datetime()
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'link to user on this system, if exists'),
'foreign_id' => array('type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'link to user on foreign service, if exists'),
'service' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to service'),
'credentials' => array('type' => 'blob', 'description' => 'authc credentials, typically a password'),
'noticesync' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'notice synchronization, bit 1 = sync outgoing, bit 2 = sync incoming, bit 3 = filter local replies'),
'friendsync' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 2, 'description' => 'friend synchronization, bit 1 = sync outgoing, bit 2 = sync incoming'),
'profilesync' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'profile synchronization, bit 1 = sync outgoing, bit 2 = sync incoming'),
'last_noticesync' => array('type' => 'datetime', 'description' => 'last time notices were imported'),
'last_friendsync' => array('type' => 'datetime', 'description' => 'last time friends were imported'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('user_id', 'foreign_id', 'service'),
'foreign keys' => array(
'foreign_link_user_id_fkey' => array('user', array('user_id' => 'id')),
'foreign_link_foreign_id_service_fkey' => array('foreign_user', array('foreign_id' => 'id', 'service' => 'service')),
'foreign_link_service_fkey' => array('foreign_service', array('service' => 'id')),
),
'indexes' => array(
'foreign_link_foreign_id_service_idx' => array('foreign_id', 'service'),
'foreign_link_service_idx' => array('service'),
),
);
}
public static function getByUserID($user_id, $service)
{
if (empty($user_id) || empty($service)) {
throw new ServerException('Empty user_id or service for Foreign_link::getByUserID');
}
$flink = new Foreign_link();
$flink->service = $service;
$flink->user_id = $user_id;
$flink->limit(1);
if (!$flink->find(true)) {
throw new NoResultException($flink);
}
return $flink;
}
public static function getByForeignID($foreign_id, $service)
{
if (empty($foreign_id) || empty($service)) {
throw new ServerException('Empty foreign_id or service for Foreign_link::getByForeignID');
}
$flink = new Foreign_link();
$flink->service = $service;
$flink->foreign_id = $foreign_id;
$flink->limit(1);
if (!$flink->find(true)) {
throw new NoResultException($flink);
}
return $flink;
}
public function set_flags($noticesend, $noticerecv, $replysync, $repeatsync, $friendsync)
{
if ($noticesend) {
$this->noticesync |= FOREIGN_NOTICE_SEND;
} else {
$this->noticesync &= ~FOREIGN_NOTICE_SEND;
}
if ($noticerecv) {
$this->noticesync |= FOREIGN_NOTICE_RECV;
} else {
$this->noticesync &= ~FOREIGN_NOTICE_RECV;
}
if ($replysync) {
$this->noticesync |= FOREIGN_NOTICE_SEND_REPLY;
} else {
$this->noticesync &= ~FOREIGN_NOTICE_SEND_REPLY;
}
if ($repeatsync) {
$this->noticesync |= FOREIGN_NOTICE_SEND_REPEAT;
} else {
$this->noticesync &= ~FOREIGN_NOTICE_SEND_REPEAT;
}
if ($friendsync) {
$this->friendsync |= FOREIGN_FRIEND_RECV;
} else {
$this->friendsync &= ~FOREIGN_FRIEND_RECV;
}
$this->profilesync = 0;
}
// Convenience methods
public function getForeignUser()
{
$fuser = new Foreign_user();
$fuser->service = $this->service;
$fuser->id = $this->foreign_id;
$fuser->limit(1);
if (!$fuser->find(true)) {
throw new NoResultException($fuser);
}
return $fuser;
}
public function getUser()
{
return Profile::getByID($this->user_id)->getUser();
}
public function getProfile()
{
return Profile::getByID($this->user_id);
}
// Make sure we only ever delete one record at a time
public function safeDelete()
{
if (!empty($this->user_id)
&& !empty($this->foreign_id)
&& !empty($this->service)) {
return $this->delete();
} else {
common_debug(
LOG_WARNING,
'Foreign_link::safeDelete() tried to delete a '
. 'Foreign_link without a fully specified compound key: '
. var_export($this, true)
);
return false;
}
}
}

View File

@ -1,54 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for foreign_service
*/
defined('GNUSOCIAL') || die();
class Foreign_service extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'foreign_service'; // table name
public $id; // int(4) primary_key not_null
public $name; // varchar(32) unique_key not_null
public $description; // varchar(191) not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'id' => array('type' => 'int', 'not null' => true, 'description' => 'numeric key for service'),
'name' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'name of the service'),
'description' => array('type' => 'varchar', 'length' => 191, 'description' => 'description'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('id'),
'unique keys' => array(
'foreign_service_name_key' => array('name'),
),
);
}
}

View File

@ -1,60 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for foreign_subscription
*/
defined('GNUSOCIAL') || die();
class Foreign_subscription extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'foreign_subscription'; // table name
public $service; // int(4) primary_key not_null
public $subscriber; // int(4) primary_key not_null
public $subscribed; // int(4) primary_key not_null
public $created; // datetime()
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'service' => array('type' => 'int', 'not null' => true, 'description' => 'service where relationship happens'),
'subscriber' => array('type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'subscriber on foreign service'),
'subscribed' => array('type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'subscribed user'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
),
'primary key' => array('service', 'subscriber', 'subscribed'),
'foreign keys' => array(
'foreign_subscription_service_fkey' => array('foreign_service', array('service' => 'id')),
'foreign_subscription_subscriber_service_fkey' => array('foreign_user', array('subscriber' => 'id', 'service' => 'service')),
'foreign_subscription_subscribed_service_fkey' => array('foreign_user', array('subscribed' => 'id', 'service' => 'service')),
),
'indexes' => array(
'foreign_subscription_subscriber_service_idx' => array('subscriber', 'service'),
'foreign_subscription_subscribed_service_idx' => array('subscribed', 'service'),
'foreign_subscription_service_subscribed_idx' => array('service', 'subscribed'),
),
);
}
}

View File

@ -1,98 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for foreign_user
*/
defined('GNUSOCIAL') || die();
class Foreign_user extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'foreign_user'; // table name
public $id; // bigint(8) primary_key not_null
public $service; // int(4) primary_key not_null
public $uri; // varchar(191) unique_key not_null not 255 because utf8mb4 takes more space
public $nickname; // varchar(191) not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'id' => array('type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'unique numeric key on foreign service'),
'service' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to service'),
'uri' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'identifying URI'),
'nickname' => array('type' => 'varchar', 'length' => 191, 'description' => 'nickname on foreign service'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('id', 'service'),
'foreign keys' => array(
'foreign_user_service_fkey' => array('foreign_service', array('service' => 'id')),
),
'unique keys' => array(
'foreign_user_uri_key' => array('uri'),
),
'indexes' => array(
'foreign_user_service_idx' => array('service'),
),
);
}
public static function getForeignUser($id, $service)
{
if (empty($id) || empty($service)) {
throw new ServerException('Empty foreign user id or service for Foreign_user::getForeignUser');
}
$fuser = new Foreign_user();
$fuser->id = $id;
$fuser->service = $service;
$fuser->limit(1);
if (!$fuser->find(true)) {
throw new NoResultException($fuser);
}
return $fuser;
}
public static function getByNickname($nickname, $service)
{
if (empty($nickname) || empty($service)) {
throw new ServerException('Empty nickname or service for Foreign_user::getByNickname');
}
$fuser = new Foreign_user();
$fuser->service = $service;
$fuser->nickname = $nickname;
$fuser->limit(1);
if (!$fuser->find(true)) {
throw new NoResultException($fuser);
}
return $fuser;
}
}

View File

@ -1,234 +0,0 @@
<?php
if (!defined('GNUSOCIAL')) { exit(1); }
class GS_DataObject extends DB_DataObject
{
public function _autoloadClass($class, $table=false)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::_autoloadClass($class, $table);
// reset
error_reporting($old);
return $res;
}
// wraps the _connect call so we don't throw E_STRICT warnings during it
public function _connect()
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::_connect();
// reset
error_reporting($old);
return $res;
}
// wraps the _loadConfig call so we don't throw E_STRICT warnings during it
// doesn't actually return anything, but we'll follow the same model as the rest of the wrappers
public function _loadConfig()
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::_loadConfig();
// reset
error_reporting($old);
return $res;
}
// wraps the count call so we don't throw E_STRICT warnings during it
public function count($countWhat = false,$whereAddOnly = false)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::count($countWhat, $whereAddOnly);
// reset
error_reporting($old);
return $res;
}
static public function debugLevel($v = null)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::debugLevel($v);
// reset
error_reporting($old);
return $res;
}
// delete calls PEAR::isError from DB_DataObject, so let's make that disappear too
public function delete($useWhere = false)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::delete($useWhere);
// reset
error_reporting($old);
return $res;
}
static public function factory($table = '')
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::factory($table);
// reset
error_reporting($old);
return $res;
}
public function get($k = null, $v = null)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::get($k, $v);
// reset
error_reporting($old);
return $res;
}
public function fetch()
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::fetch();
// reset
error_reporting($old);
return $res;
}
public function find($n = false)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::find($n);
// reset
error_reporting($old);
return $res;
}
public function fetchRow($row = null)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::fetchRow($row);
// reset
error_reporting($old);
return $res;
}
// insert calls PEAR::isError from DB_DataObject, so let's make that disappear too
public function insert()
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::insert();
// reset
error_reporting($old);
return $res;
}
// DB_DataObject's joinAdd calls DB_DataObject::factory explicitly, so our factory-override doesn't work
public function joinAdd($obj = false, $joinType='INNER', $joinAs=false, $joinCol=false)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::joinAdd($obj, $joinType, $joinAs, $joinCol);
// reset
error_reporting($old);
return $res;
}
public function links()
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::links();
// reset
error_reporting($old);
return $res;
}
// wraps the update call so we don't throw E_STRICT warnings during it
public function update($dataObject = false)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::update($dataObject);
// reset
error_reporting($old);
return $res;
}
static public function staticGet($class, $k, $v = null)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::staticGet($class, $k, $v);
// reset
error_reporting($old);
return $res;
}
public function staticGetAutoloadTable($table)
{
// avoid those annoying PEAR::DB strict standards warnings it causes
$old = error_reporting();
error_reporting(error_reporting() & ~E_STRICT);
$res = parent::staticGetAutoloadTable($table);
// reset
error_reporting($old);
return $res;
}
}

60
src/Entity/GroupAlias.php Normal file
View File

@ -0,0 +1,60 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Group Alias
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class GroupAlias
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'group_alias',
'fields' => [
'alias' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'additional nickname for the group'],
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'group profile is blocked from'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date alias was created'],
],
'primary key' => ['alias'],
'foreign keys' => [
'group_alias_group_id_fkey' => ['user_group', ['group_id' => 'id']],
],
'indexes' => [
'group_alias_group_id_idx' => ['group_id'],
],
];
}
}

60
src/Entity/GroupBlock.php Normal file
View File

@ -0,0 +1,60 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Group Block
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class GroupBlock
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'group_block',
'fields' => [
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'group profile is blocked from'],
'blocked' => ['type' => 'int', 'not null' => true, 'description' => 'profile that is blocked'],
'blocker' => ['type' => 'int', 'not null' => true, 'description' => 'user making the block'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date of blocking'],
],
'primary key' => ['group_id', 'blocked'],
'foreign keys' => [
'group_block_group_id_fkey' => ['user_group', ['group_id' => 'id']],
'group_block_blocked_fkey' => ['profile', ['blocked' => 'id']],
'group_block_blocker_fkey' => ['user', ['blocker' => 'id']],
],
];
}
}

64
src/Entity/GroupInbox.php Normal file
View File

@ -0,0 +1,64 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Group's inbox
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class GroupInbox
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'group_inbox',
'description' => 'Many-many table listing notices posted to a given group, or which groups a given notice was posted to.',
'fields' => [
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'group receiving the message'],
'notice_id' => ['type' => 'int', 'not null' => true, 'description' => 'notice received'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date the notice was created'],
],
'primary key' => ['group_id', 'notice_id'],
'foreign keys' => [
'group_inbox_group_id_fkey' => ['user_group', ['group_id' => 'id']],
'group_inbox_notice_id_fkey' => ['notice', ['notice_id' => 'id']],
],
'indexes' => [
'group_inbox_created_idx' => ['created'],
'group_inbox_notice_id_idx' => ['notice_id'],
'group_inbox_group_id_created_notice_id_idx' => ['group_id', 'created', 'notice_id'],
],
];
}
}

View File

@ -0,0 +1,63 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Queue on joining a group
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class GroupJoinQueue
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'group_join_queue',
'description' => 'Holder for group join requests awaiting moderation.',
'fields' => [
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'remote or local profile making the request'],
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'remote or local group to join, if any'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
],
'primary key' => ['profile_id', 'group_id'],
'indexes' => [
'group_join_queue_profile_id_created_idx' => ['profile_id', 'created'],
'group_join_queue_group_id_created_idx' => ['group_id', 'created'],
],
'foreign keys' => [
'group_join_queue_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
'group_join_queue_group_id_fkey' => ['user_group', ['group_id' => 'id']],
],
];
}
}

View File

@ -0,0 +1,71 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for a Group Member
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class GroupMember
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'group_member',
'fields' => [
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'],
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'],
'is_admin' => ['type' => 'bool', 'default' => false, 'description' => 'is this user an admin?'],
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['group_id', 'profile_id'],
'unique keys' => [
'group_member_uri_key' => ['uri'],
],
'foreign keys' => [
'group_member_group_id_fkey' => ['user_group', ['group_id' => 'id']],
'group_member_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
],
'indexes' => [
// @fixme probably we want a (profile_id, created) index here?
'group_member_profile_id_idx' => ['profile_id'],
'group_member_created_idx' => ['created'],
'group_member_profile_id_created_idx' => ['profile_id', 'created'],
'group_member_group_id_created_idx' => ['group_id', 'created'],
],
];
}
}

View File

@ -1,65 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for group_alias
*
* @copyright 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Group_alias extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'group_alias'; // table name
public $alias; // varchar(64) primary_key not_null
public $group_id; // int(4) not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'alias' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'additional nickname for the group'),
'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group profile is blocked from'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date alias was created'),
),
'primary key' => array('alias'),
'foreign keys' => array(
'group_alias_group_id_fkey' => array('user_group', array('group_id' => 'id')),
),
'indexes' => array(
'group_alias_group_id_idx' => array('group_id'),
),
);
}
public function getProfile()
{
$group = User_group::getKV('id', $this->group_id);
if (!($group instanceof User_group)) {
return null; // TODO: Throw exception when other code is ready
}
return $group->getProfile();
}
}

View File

@ -1,132 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for group_block
*
* @package GNUsocial
* @author Evan Prodromou <evan@status.net>
* @copyright 2008, 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Group_block extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'group_block'; // table name
public $group_id; // int(4) primary_key not_null
public $blocked; // int(4) primary_key not_null
public $blocker; // int(4) not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group profile is blocked from'),
'blocked' => array('type' => 'int', 'not null' => true, 'description' => 'profile that is blocked'),
'blocker' => array('type' => 'int', 'not null' => true, 'description' => 'user making the block'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date of blocking'),
),
'primary key' => array('group_id', 'blocked'),
'foreign keys' => array(
'group_block_group_id_fkey' => array('user_group', array('group_id' => 'id')),
'group_block_blocked_fkey' => array('profile', array('blocked' => 'id')),
'group_block_blocker_fkey' => array('user', array('blocker' => 'id')),
),
'indexes' => array(
'group_block_blocked_idx' => array('blocked'),
'group_block_blocker_idx' => array('blocker'),
),
);
}
public static function isBlocked($group, $profile)
{
$block = Group_block::pkeyGet([
'group_id' => $group->id,
'blocked' => $profile->id,
]);
return !empty($block);
}
public static function blockProfile($group, $profile, $blocker)
{
// Insert the block
$block = new Group_block();
$block->query('START TRANSACTION');
$block->group_id = $group->id;
$block->blocked = $profile->id;
$block->blocker = $blocker->id;
$result = $block->insert();
if ($result === false) {
common_log_db_error($block, 'INSERT', __FILE__);
return null;
}
// Delete membership if any
$member = new Group_member();
$member->group_id = $group->id;
$member->profile_id = $profile->id;
if ($member->find(true)) {
$result = $member->delete();
if ($result === false) {
common_log_db_error($member, 'DELETE', __FILE__);
return null;
}
}
// Commit, since both have been done
$block->query('COMMIT');
return $block;
}
public static function unblockProfile($group, $profile)
{
$block = Group_block::pkeyGet(array('group_id' => $group->id,
'blocked' => $profile->id));
if (empty($block)) {
return null;
}
$result = $block->delete();
if (!$result) {
common_log_db_error($block, 'DELETE', __FILE__);
return null;
}
return true;
}
}

View File

@ -1,57 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for group_inbox
*/
defined('GNUSOCIAL') || die();
class Group_inbox extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'group_inbox'; // table name
public $group_id; // int(4) primary_key not_null
public $notice_id; // int(4) primary_key not_null
public $created; // datetime()
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'description' => 'Many-many table listing notices posted to a given group, or which groups a given notice was posted to.',
'fields' => array(
'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group receiving the message'),
'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice received'),
'created' => array('type' => 'datetime', 'description' => 'date the notice was created'),
),
'primary key' => array('group_id', 'notice_id'),
'foreign keys' => array(
'group_inbox_group_id_fkey' => array('user_group', array('group_id' => 'id')),
'group_inbox_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
),
'indexes' => array(
'group_inbox_created_idx' => array('created'),
'group_inbox_notice_id_idx' => array('notice_id'),
'group_inbox_group_id_created_notice_id_idx' => array('group_id', 'created', 'notice_id'),
),
);
}
}

View File

@ -1,139 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for request_queue
*/
defined('GNUSOCIAL') || die();
class Group_join_queue extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'group_join_queue'; // table name
public $profile_id;
public $group_id;
public $created;
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'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', 'not null' => true, 'description' => 'remote or local group to join, if any'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
),
'primary key' => array('profile_id', 'group_id'),
'indexes' => array(
'group_join_queue_profile_id_created_idx' => array('profile_id', 'created'),
'group_join_queue_group_id_created_idx' => array('group_id', 'created'),
),
'foreign keys' => array(
'group_join_queue_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
'group_join_queue_group_id_fkey' => array('user_group', array('group_id' => 'id')),
)
);
}
public static function saveNew(Profile $profile, User_group $group)
{
$rq = new Group_join_queue();
$rq->profile_id = $profile->id;
$rq->group_id = $group->id;
$rq->created = common_sql_now();
$rq->insert();
return $rq;
}
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));
}
return $member;
}
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));
}
return $group;
}
/**
* Abort the pending group join...
*/
public function abort()
{
$profile = $this->getMember();
$group = $this->getGroup();
if (Event::handle('StartCancelJoinGroup', array($profile, $group))) {
$this->delete();
Event::handle('EndCancelJoinGroup', array($profile, $group));
}
}
/**
* Complete a pending group join...
*
* @return Group_member object on success
*/
public function complete()
{
$join = null;
$profile = $this->getMember();
$group = $this->getGroup();
if (Event::handle('StartJoinGroup', array($profile, $group))) {
$join = Group_member::join($group->id, $profile->id);
$this->delete();
Event::handle('EndJoinGroup', array($profile, $group));
}
if (!$join) {
throw new Exception('Internal error: group join failed.');
}
$join->notify();
return $join;
}
/**
* Send notifications via email etc to group administrators about
* this exciting new pending moderation queue item!
*/
public function notify()
{
$joiner = Profile::getKV('id', $this->profile_id);
$group = User_group::getKV('id', $this->group_id);
mail_notify_group_join_pending($group, $joiner);
}
}

View File

@ -1,232 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
defined('GNUSOCIAL') || die();
/**
* Table Definition for group_member
*/
class Group_member extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
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; // bool default_false
public $uri; // varchar(191) not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'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' => 'bool', 'default' => false, 'description' => 'is this user an admin?'),
'uri' => array('type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('group_id', 'profile_id'),
'unique keys' => array(
'group_member_uri_key' => array('uri'),
),
'foreign keys' => array(
'group_member_group_id_fkey' => array('user_group', array('group_id' => 'id')),
'group_member_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
),
'indexes' => array(
'group_member_profile_id_created_group_id_idx' => array('profile_id', 'created', 'group_id'),
'group_member_group_id_created_profile_id_idx' => array('profile_id', 'created', 'group_id'),
),
);
}
/**
* Method to add a user to a group.
* In most cases, you should call Profile->joinGroup() instead.
*
* @param integer $group_id Group to add to
* @param integer $profile_id Profile being added
*
* @return Group_member new membership object
*/
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
);
$result = $member->insert();
if (!$result) {
common_log_db_error($member, 'INSERT', __FILE__);
// TRANS: Exception thrown when joining a group fails.
throw new Exception(_("Group join failed."));
}
return $member;
}
public static function leave($group_id, $profile_id)
{
$member = Group_member::pkeyGet(array('group_id' => $group_id,
'profile_id' => $profile_id));
if (empty($member)) {
// TRANS: Exception thrown when trying to leave a group the user is not a member of.
throw new Exception(_("Not part of group."));
}
$result = $member->delete();
if (!$result) {
common_log_db_error($member, 'INSERT', __FILE__);
// TRANS: Exception thrown when trying to leave a group fails.
throw new Exception(_("Group leave failed."));
}
return true;
}
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));
}
return $member;
}
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));
}
return $group;
}
/**
* Get stream of memberships by member
*
* @param integer $memberId profile ID of the member to fetch for
* @param integer $offset offset from start of stream to get
* @param integer $limit number of memberships to get
*
* @return Group_member stream of memberships, use fetch() to iterate
*/
public static function byMember($memberId, $offset = 0, $limit = GROUPS_PER_PAGE)
{
$membership = new Group_member();
$membership->profile_id = $memberId;
$membership->orderBy('created DESC, group_id DESC');
$membership->limit($offset, $limit);
$membership->find();
return $membership;
}
public function asActivity()
{
$member = $this->getMember();
if (!$member) {
throw new Exception("No such member: " . $this->profile_id);
}
$group = $this->getGroup();
if (!$group) {
throw new Exception("No such group: " . $this->group_id);
}
$act = new Activity();
$act->id = $this->getUri();
$act->actor = $member->asActivityObject();
$act->verb = ActivityVerb::JOIN;
$act->objects[] = ActivityObject::fromGroup($group);
$act->time = strtotime($this->created);
// TRANS: Activity title.
$act->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(
_('%1$s has joined group %2$s.'),
$member->getBestName(),
$group->getBestName()
);
$url = common_local_url(
'AtomPubShowMembership',
[
'profile' => $member->id,
'group' => $group->id,
]
);
$act->selfLink = $url;
$act->editLink = $url;
return $act;
}
/**
* Send notifications via email etc to group administrators about
* this exciting new membership!
*/
public function notify()
{
mail_notify_group_join($this->getGroup(), $this->getMember());
}
public function getUri()
{
return $this->uri ?: self::newUri($this->getMember(), $this->getGroup()->getProfile(), $this->created);
}
}

View File

@ -1,70 +1,66 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Table Definition for invitation
* Entity for user invitations
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 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 Invitation extends Managed_DataObject
class Invitation
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
// AUTOCODE BEGIN
public $__table = 'invitation'; // table name
public $code; // varchar(32) primary_key not_null
public $user_id; // int(4) not_null
public $address; // varchar(191) multiple_key not_null not 255 because utf8mb4 takes more space
public $address_type; // varchar(8) multiple_key not_null
public $registered_user_id; // int(4) not_null
public $created; // datetime()
// AUTOCODE END
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public function convert($user)
public static function schemaDef(): array
{
$orig = clone($this);
$this->registered_user_id = $user->id;
return $this->update($orig);
}
public static function schemaDef()
{
return array(
'fields' => array(
'code' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'random code for an invitation'),
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'who sent the invitation'),
'address' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'invitation sent to'),
'address_type' => array('type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'registered_user_id' => array('type' => 'int', 'not null' => false, 'description' => 'if the invitation is converted, who the new user is'),
),
'primary key' => array('code'),
'foreign keys' => array(
'invitation_user_id_fkey' => array('user', array('user_id' => 'id')),
'invitation_registered_user_id_fkey' => array('user', array('registered_user_id' => 'id')),
),
'indexes' => array(
'invitation_address_address_type_idx' => array('address', 'address_type'),
'invitation_user_id_idx' => array('user_id'),
'invitation_registered_user_id_idx' => array('registered_user_id'),
),
);
return [
'name' => 'invitation',
'fields' => [
'code' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'random code for an invitation'],
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'who sent the invitation'],
'address' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'invitation sent to'],
'address_type' => ['type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'registered_user_id' => ['type' => 'int', 'not null' => false, 'description' => 'if the invitation is converted, who the new user is'],
],
'primary key' => ['code'],
'foreign keys' => [
'invitation_user_id_fkey' => ['user', ['user_id' => 'id']],
'invitation_registered_user_id_fkey' => ['user', ['registered_user_id' => 'id']],
],
'indexes' => [
'invitation_address_idx' => ['address', 'address_type'],
'invitation_user_id_idx' => ['user_id'],
'invitation_registered_user_id_idx' => ['registered_user_id'],
],
];
}
}

62
src/Entity/LocalGroup.php Normal file
View File

@ -0,0 +1,62 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for local groups
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class LocalGroup
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'local_group',
'description' => 'Record for a user group on the local site, with some additional info not in user_group',
'fields' => [
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'group represented'],
'nickname' => ['type' => 'varchar', 'length' => 64, 'description' => 'group represented'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['group_id'],
'foreign keys' => [
'local_group_group_id_fkey' => ['user_group', ['group_id' => 'id']],
],
'unique keys' => [
'local_group_nickname_key' => ['nickname'],
],
];
}
}

View File

@ -1,100 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for local_group
*/
defined('GNUSOCIAL') || die();
class Local_group extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'local_group'; // table name
public $group_id; // int(4) primary_key not_null
public $nickname; // varchar(64) unique_key
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'description' => 'Record for a user group on the local site, with some additional info not in user_group',
'fields' => array(
'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group represented'),
'nickname' => array('type' => 'varchar', 'length' => 64, 'description' => 'group represented'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('group_id'),
'foreign keys' => array(
'local_group_group_id_fkey' => array('user_group', array('group_id' => 'id')),
),
'unique keys' => array(
'local_group_nickname_key' => array('nickname'),
),
);
}
public function getProfile()
{
return $this->getGroup()->getProfile();
}
public function getGroup()
{
$group = new User_group();
$group->id = $this->group_id;
$group->find(true);
if (!$group instanceof User_group) {
common_log(LOG_ERR, 'User_group does not exist for Local_group: '.$this->group_id);
throw new NoSuchGroupException(array('id' => $this->group_id));
}
return $group;
}
public function setNickname($nickname)
{
$this->decache();
$modified = common_sql_now();
$result = $this->query(sprintf(
<<<'END'
UPDATE local_group SET nickname = %1$s, modified = %2$s
WHERE group_id = %3$d;
END,
$this->_quote($nickname),
$this->_quote($modified),
$this->group_id
));
if ($result) {
$this->nickname = $nickname;
$this->modified = $modified;
$this->encache();
} else {
common_log_db_error($local, 'UPDATE', __FILE__);
// TRANS: Server exception thrown when updating a local group fails.
throw new ServerException(_('Could not update local group.'));
}
return $result;
}
}

View File

@ -0,0 +1,55 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for location namespace
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class LocationNamespace
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'location_namespace',
'fields' => [
'id' => ['type' => 'int', 'not null' => true, 'description' => 'identity for this namespace'],
'description' => ['type' => 'varchar', 'length' => 191, 'description' => 'description of the namespace'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date the record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['id'],
];
}
}

View File

@ -1,52 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/*
* Table Definition for location_namespace
*
* @copyright 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Location_namespace extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'location_namespace'; // table name
public $id; // int(4) primary_key not_null
public $description; // varchar(191)
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'id' => array('type' => 'int', 'not null' => true, 'description' => 'identity for this namespace'),
'description' => array('type' => 'varchar', 'length' => 191, 'description' => 'description of the namespace'),
'created' => array('type' => 'datetime', 'description' => 'date the record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('id'),
);
}
}

58
src/Entity/LoginToken.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Login tokens
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class LoginToken
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'login_token',
'fields' => [
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'user owning this token'],
'token' => ['type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'token useable for logging in'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['user_id'],
'foreign keys' => [
'login_token_user_id_fkey' => ['user', ['user_id' => 'id']],
],
];
}
}

View File

@ -1,86 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for login_token
*
* @copyright 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Login_token extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'login_token'; // table name
public $user_id; // int(4) primary_key not_null
public $token; // char(32) not_null
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user owning this token'),
'token' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'token useable for logging in'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('user_id'),
'foreign keys' => array(
'login_token_user_id_fkey' => array('user', array('user_id' => 'id')),
),
);
}
const TIMEOUT = 120; // seconds after which to timeout the token
public function makeNew($user)
{
$login_token = Login_token::getKV('user_id', $user->id);
if (!empty($login_token)) {
$login_token->delete();
}
$login_token = new Login_token();
$login_token->user_id = $user->id;
$login_token->token = common_random_hexstr(16);
$login_token->created = common_sql_now();
$result = $login_token->insert();
if (!$result) {
common_log_db_error($login_token, 'INSERT', __FILE__);
// TRANS: Exception thrown when trying creating a login token failed.
// TRANS: %s is the user nickname for which token creation failed.
throw new Exception(sprintf(
_('Could not create login token for %s'),
$user->nickname
));
}
return $login_token;
}
}

View File

@ -1,715 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Wrapper for Memcached_DataObject which knows its own schema definition.
* Builds its own damn settings from a schema definition.
*
* @package GNUsocial
* @author Brion Vibber <brion@status.net>
* @copyright 2010 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
abstract class Managed_DataObject extends Memcached_DataObject
{
/**
* The One True Thingy that must be defined and declared.
*/
public static function schemaDef()
{
throw new MethodNotImplementedException(__METHOD__);
}
/**
* Get an instance by key
*
* @param string $k Key to use to lookup (usually 'id' for this class)
* @param mixed $v Value to lookup
*
* @return get_called_class() object if found, or null for no hits
*
*/
public static function getKV($k, $v = null)
{
return parent::getClassKV(get_called_class(), $k, $v);
}
/**
* Get an instance by compound key
*
* This is a utility method to get a single instance with a given set of
* key-value pairs. Usually used for the primary key for a compound key; thus
* the name.
*
* @param array $kv array of key-value mappings
*
* @return get_called_class() object if found, or null for no hits
*
*/
public static function pkeyGet(array $kv)
{
return parent::pkeyGetClass(get_called_class(), $kv);
}
public static function pkeyCols()
{
return parent::pkeyColsClass(get_called_class());
}
/**
* Get multiple items from the database by key
*
* @param string $keyCol name of column for key
* @param array $keyVals key values to fetch
* @param bool $skipNulls return only non-null results
* @param bool $preserve return the same tuples as input
* @return object An object with tuples to be fetched, in order
*/
public static function multiGet(
string $keyCol,
array $keyVals,
bool $skipNulls = true,
bool $preserve = false
): object {
return parent::multiGetClass(
get_called_class(),
$keyCol,
$keyVals,
$skipNulls,
$preserve
);
}
/**
* Get multiple items from the database by key
*
* @param string $keyCol name of column for key
* @param array $keyVals key values to fetch
* @param array $otherCols Other columns to hold fixed
*
* @return array Array mapping $keyVals to objects, or null if not found
*/
public static function pivotGet($keyCol, array $keyVals, array $otherCols = [])
{
return parent::pivotGetClass(get_called_class(), $keyCol, $keyVals, $otherCols);
}
/**
* Get a multi-instance object
*
* This is a utility method to get multiple instances with a given set of
* values for a specific column.
*
* @param string $keyCol key column name
* @param array $keyVals array of key values
*
* @return get_called_class() object with multiple instances if found,
* Exception is thrown when no entries are found.
*
*/
public static function listFind($keyCol, array $keyVals)
{
return parent::listFindClass(get_called_class(), $keyCol, $keyVals);
}
/**
* Get a multi-instance object separated into an array
*
* This is a utility method to get multiple instances with a given set of
* values for a specific key column. Usually used for the primary key when
* multiple values are desired. Result is an array.
*
* @param string $keyCol key column name
* @param array $keyVals array of key values
*
* @return array with an get_called_class() object for each $keyVals entry
*
*/
public static function listGet($keyCol, array $keyVals)
{
return parent::listGetClass(get_called_class(), $keyCol, $keyVals);
}
/**
* get/set an associative array of table columns
*
* @access public
* @return array (associative)
*/
public function table()
{
$table = static::schemaDef();
return array_map(array($this, 'columnBitmap'), $table['fields']);
}
/**
* get/set an array of table primary keys
*
* Key info is pulled from the table definition array.
*
* @access private
* @return array
*/
public function keys()
{
return array_keys($this->keyTypes());
}
/**
* Get a sequence key
*
* Returns the first serial column defined in the table, if any.
*
* @access private
* @return array (column,use_native,sequence_name)
*/
public function sequenceKey()
{
$table = static::schemaDef();
foreach ($table['fields'] as $name => $column) {
if ($column['type'] == 'serial') {
// We have a serial/autoincrement column.
// Declare it to be a native sequence!
return array($name, true, false);
}
}
// No sequence key on this table.
return array(false, false, false);
}
/**
* Return key definitions for DB_DataObject and Memcache_DataObject.
*
* DB_DataObject needs to know about keys that the table has; this function
* defines them.
*
* @return array key definitions
*/
public function keyTypes()
{
$table = static::schemaDef();
$keys = array();
if (!empty($table['unique keys'])) {
foreach ($table['unique keys'] as $idx => $fields) {
foreach ($fields as $name) {
$keys[$name] = 'U';
}
}
}
if (!empty($table['primary key'])) {
foreach ($table['primary key'] as $name) {
$keys[$name] = 'K';
}
}
return $keys;
}
/**
* Build the appropriate DB_DataObject bitfield map for this field.
*
* @param array $column
* @return int
*/
public function columnBitmap($column)
{
$type = $column['type'];
// For quoting style...
$intTypes = [
'int',
'float',
'serial',
'numeric'
];
if (in_array($type, $intTypes)) {
$style = DB_DATAOBJECT_INT;
} else {
$style = DB_DATAOBJECT_STR;
}
// Data type formatting style...
$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,
];
if (isset($formatStyles[$type])) {
$style |= $formatStyles[$type];
}
// Nullable?
if (!empty($column['not null'])) {
$style |= DB_DATAOBJECT_NOTNULL;
}
return $style;
}
public function links()
{
$links = array();
$table = static::schemaDef();
foreach ($table['foreign keys'] as $keyname => $keydef) {
if (count($keydef) == 2 && is_string($keydef[0]) && is_array($keydef[1]) && count($keydef[1]) == 1) {
if (isset($keydef[1][0])) {
$links[$keydef[1][0]] = $keydef[0].':'.$keydef[1][1];
}
}
}
return $links;
}
/**
* Return a list of all primary/unique keys / vals that will be used for
* caching. This will understand compound unique keys, which
* Memcached_DataObject doesn't have enough info to handle properly.
*
* @return array of strings
* @throws MethodNotImplementedException
* @throws ServerException
*/
public function _allCacheKeys()
{
$table = static::schemaDef();
$ckeys = array();
if (!empty($table['unique keys'])) {
$keyNames = $table['unique keys'];
foreach ($keyNames as $idx => $fields) {
$val = array();
foreach ($fields as $name) {
$val[$name] = self::valueString($this->$name);
}
$ckeys[] = self::multicacheKey($this->tableName(), $val);
}
}
if (!empty($table['primary key'])) {
$fields = $table['primary key'];
$val = array();
foreach ($fields as $name) {
$val[$name] = self::valueString($this->$name);
}
$ckeys[] = self::multicacheKey($this->tableName(), $val);
}
return $ckeys;
}
/**
* Returns an object by looking at the primary key column(s).
*
* Will require all primary key columns to be defined in an associative array
* and ignore any keys which are not part of the primary key.
*
* Will NOT accept NULL values as part of primary key.
*
* @param array $vals Must match all primary key columns for the dataobject.
*
* @return Managed_DataObject of the get_called_class() type
* @throws NoResultException if no object with that primary key
*/
public static function getByPK(array $vals)
{
$classname = get_called_class();
$pkey = static::pkeyCols();
if (is_null($pkey)) {
throw new ServerException("Failed to get primary key columns for class '{$classname}'");
}
$object = new $classname();
foreach ($pkey as $col) {
if (!array_key_exists($col, $vals)) {
throw new ServerException("Missing primary key column '{$col}' for ".get_called_class()." among provided keys: ".implode(',', array_keys($vals)));
} elseif (is_null($vals[$col])) {
throw new ServerException("NULL values not allowed in getByPK for column '{$col}'");
}
$object->$col = $vals[$col];
}
if (!$object->find(true)) {
throw new NoResultException($object);
}
return $object;
}
/**
* Returns an object by looking at given unique key columns.
*
* Will NOT accept NULL values for a unique key column. Ignores non-key values.
*
* @param array $vals All array keys which are set must be non-null.
*
* @return Managed_DataObject of the get_called_class() type
* @throws NoResultException if no object with that primary key
*/
public static function getByKeys(array $vals)
{
$classname = get_called_class();
$object = new $classname();
$keys = $object->keys();
if (is_null($keys)) {
throw new ServerException("Failed to get key columns for class '{$classname}'");
}
foreach ($keys as $col) {
if (!array_key_exists($col, $vals)) {
continue;
} elseif (is_null($vals[$col])) {
throw new ServerException("NULL values not allowed in getByKeys for column '{$col}'");
}
$object->$col = $vals[$col];
}
if (!$object->find(true)) {
throw new NoResultException($object);
}
return $object;
}
public static function getByID($id)
{
if (!property_exists(get_called_class(), 'id')) {
throw new ServerException('Trying to get undefined property of dataobject class.');
}
if (empty($id)) {
throw new EmptyPkeyValueException(get_called_class(), 'id');
}
// getByPK throws exception if id is null
// or if the class does not have a single 'id' column as primary key
return static::getByPK(array('id' => $id));
}
public static function getByUri($uri)
{
if (!property_exists(get_called_class(), 'uri')) {
throw new ServerException('Trying to get undefined property of dataobject class.');
}
if (empty($uri)) {
throw new EmptyPkeyValueException(get_called_class(), 'uri');
}
$class = get_called_class();
$obj = new $class();
$obj->uri = $uri;
if (!$obj->find(true)) {
throw new NoResultException($obj);
}
return $obj;
}
/**
* Returns an ID, checked that it is set and reasonably valid
*
* If this dataobject uses a special id field (not 'id'), just
* implement your ID getting method in the child class.
*
* @return int ID of dataobject
* @throws Exception (when ID is not available or not set yet)
*/
public function getID()
{
// FIXME: Make these exceptions more specific (their own classes)
if (!isset($this->id)) {
throw new Exception('No ID set.');
} elseif (empty($this->id)) {
throw new Exception('Empty ID for object! (not inserted yet?).');
}
return intval($this->id);
}
/**
* Check whether the column is NULL in SQL
*
* @param string $key column property name
*
* @return bool
*/
public function isNull(string $key): bool
{
if (array_key_exists($key, get_object_vars($this))
&& is_null($this->$key)) {
// If there was no fetch, this is a false positive.
return true;
} elseif (is_object($this->$key)
&& $this->$key instanceof DB_DataObject_Cast
&& $this->$key->type === 'sql') {
// This is cast to raw SQL, let's see if it's NULL.
return (strcasecmp($this->$key->value, 'NULL') == 0);
} elseif (DB_DataObject::_is_null($this, $key)) {
// DataObject's NULL magic should be disabled,
// this is just for completeness.
return true;
}
return false;
}
/**
* WARNING: Only use this on Profile and Notice. We should probably do
* this with traits/"implements" or whatever, but that's over the top
* right now, I'm just throwing this in here to avoid code duplication
* in Profile and Notice classes.
*/
public function getAliases()
{
return array_keys($this->getAliasesWithIDs());
}
public function getAliasesWithIDs()
{
$aliases = array();
$aliases[$this->getUri()] = $this->getID();
try {
$aliases[$this->getUrl()] = $this->getID();
} catch (InvalidUrlException $e) {
// getUrl failed because no valid URL could be returned, just ignore it
}
if (common_config('fix', 'fancyurls')) {
/**
* Here we add some hacky hotfixes for remote lookups that have been taught the
* (at least now) wrong URI but it's still obviously the same user. Such as:
* - https://site.example/user/1 even if the client requests https://site.example/index.php/user/1
* - https://site.example/user/1 even if the client requests https://site.example//index.php/user/1
* - https://site.example/index.php/user/1 even if the client requests https://site.example/user/1
* - https://site.example/index.php/user/1 even if the client requests https://site.example///index.php/user/1
*/
foreach ($aliases as $alias=>$id) {
try {
// get a "fancy url" version of the alias, even without index.php/
$alt_url = common_fake_local_fancy_url($alias);
// store this as well so remote sites can be sure we really are the same profile
$aliases[$alt_url] = $id;
} catch (Exception $e) {
// Apparently we couldn't rewrite that, the $alias was as the function wanted it to be
}
try {
// get a non-"fancy url" version of the alias, i.e. add index.php/
$alt_url = common_fake_local_nonfancy_url($alias);
// store this as well so remote sites can be sure we really are the same profile
$aliases[$alt_url] = $id;
} catch (Exception $e) {
// Apparently we couldn't rewrite that, the $alias was as the function wanted it to be
}
}
}
return $aliases;
}
/**
* Set the attribute defined as "timestamp" to CURRENT_TIMESTAMP.
* This is hooked in update() and updateWithKeys() to update "modified".
*
* @access private
* @return void
*/
private function updateAutoTimestamps(): void
{
$table = static::schemaDef();
foreach ($table['fields'] as $name => $col) {
if ($col['type'] === 'timestamp'
&& !array_key_exists('default', $col)
&& !isset($this->$name)) {
$this->$name = common_sql_now();
}
}
}
/**
* update() won't write key columns, so we have to do it ourselves.
* This also automatically calls "update" _before_ it sets the keys.
* FIXME: This only works with single-column primary keys so far! Beware!
*
* @param Managed_DataObject $orig Must be "instanceof" $this
* @param string $pid Primary ID column (no escaping is done on column name!)
* @return bool|void
* @throws MethodNotImplementedException
* @throws ServerException
*/
public function updateWithKeys(Managed_DataObject $orig, ?string $pid = null)
{
if (!$orig instanceof $this) {
throw new ServerException('Tried updating a DataObject with a different class than itself.');
}
if ($this->N <1) {
throw new ServerException('DataObject must be the result of a query (N>=1) before updateWithKeys()');
}
$this->onUpdateKeys($orig);
// do it in a transaction
$this->query('START TRANSACTION');
// ON UPDATE CURRENT_TIMESTAMP behaviour
// @fixme Should the value be reverted back if transaction failed?
$this->updateAutoTimestamps();
$parts = [];
foreach ($this->keys() as $k) {
$v = $this->table()[$k];
if ($this->$k !== $orig->$k) {
if (is_object($this->$k) && $this->$k instanceof DB_DataObject_Cast) {
$value = $this->$k->toString($v, $this->getDatabaseConnection());
} elseif (DB_DataObject::_is_null($this, $k)) {
$value = 'NULL';
} elseif ($v & DB_DATAOBJECT_STR) { // if a string
$value = $this->_quote((string) $this->$k);
} else {
$value = (int) $this->$k;
}
$parts[] = "{$k} = {$value}";
}
}
if (count($parts) == 0) {
// No changes to keys, it's safe to run ->update(...)
if ($this->update($orig) === false) {
common_log_db_error($this, 'UPDATE', __FILE__);
// rollback as something bad occurred
$this->query('ROLLBACK');
throw new ServerException("Could not UPDATE non-keys for {$this->tableName()}");
}
$orig->decache();
$this->encache();
// commit our db transaction since we won't reach the COMMIT below
$this->query('COMMIT');
// @FIXME return true only if something changed (otherwise 0)
return true;
}
if ($pid === null) {
$schema = static::schemaDef();
$pid = $schema['primary key'];
unset($schema);
}
$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',
$this->escapedTableName(),
implode(', ', $parts),
implode(' AND ', $pidWhere)
);
$result = $this->query($qry);
if ($result === false) {
common_log_db_error($this, 'UPDATE', __FILE__);
// rollback as something bad occurred
$this->query('ROLLBACK');
throw new ServerException("Could not UPDATE key fields for {$this->tableName()}");
}
// Update non-keys too, if the previous endeavour worked.
// The ->update call uses "$this" values for keys, that's why we can't do this until
// the keys are updated (because they might differ from $orig and update the wrong entries).
if ($this->update($orig) === false) {
common_log_db_error($this, 'UPDATE', __FILE__);
// rollback as something bad occurred
$this->query('ROLLBACK');
throw new ServerException("Could not UPDATE non-keys for {$this->tableName()}");
}
$orig->decache();
$this->encache();
// commit our db transaction
$this->query('COMMIT');
// @FIXME return true only if something changed (otherwise 0)
return $result;
}
public static function beforeSchemaUpdate()
{
// NOOP
}
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)
);
}
protected function onInsert()
{
// NOOP by default
}
protected function onUpdate($dataObject=false)
{
// NOOP by default
}
protected function onUpdateKeys(Managed_DataObject $orig)
{
// NOOP by default
}
public function insert()
{
$this->onInsert();
$result = parent::insert();
// Make this object aware of the changed "modified" attribute.
// Sets it approximately to the same value as DEFAULT CURRENT_TIMESTAMP
// just did (@fixme).
if ($result) {
$this->updateAutoTimestamps();
}
return $result;
}
public function update($dataObject = false)
{
$this->onUpdate($dataObject);
// ON UPDATE CURRENT_TIMESTAMP behaviour
// @fixme Should the value be reverted back if transaction failed?
$this->updateAutoTimestamps();
return parent::update($dataObject);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +1,58 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Table Definition for nonce
* Entity for nonce
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 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 Nonce extends Managed_DataObject
class Nonce
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
// AUTOCODE BEGIN
public $__table = 'nonce'; // table name
public $consumer_key; // varchar(191) primary_key not_null not 255 because utf8mb4 takes more space
public $tok; // char(32)
public $nonce; // char(32) primary_key not_null
public $ts; // datetime() primary_key not_null
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
// AUTOCODE END
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
/**
* Compatibility hack for PHP 5.3
*
* The statusnet.links.ini entry cannot be read because "," is no longer
* allowed in key names when read by parse_ini_file().
*
* @return array
* @access public
*/
public function links()
public static function schemaDef(): array
{
return array('consumer_key,token' => 'token:consumer_key,token');
}
public static function schemaDef()
{
return array(
return [
'name' => 'nonce',
'description' => 'OAuth nonce record',
'fields' => array(
'consumer_key' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'unique identifier, root URL'),
'tok' => array('type' => 'char', 'length' => 32, 'description' => 'buggy old value, ignored'),
'nonce' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'nonce'),
'ts' => array('type' => 'datetime', 'not null' => true, 'description' => 'timestamp sent'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('consumer_key', 'ts', 'nonce'),
);
'fields' => [
'consumer_key' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'unique identifier, root URL'],
'tok' => ['type' => 'char', 'length' => 32, 'description' => 'buggy old value, ignored'],
'nonce' => ['type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'nonce'],
'ts' => ['type' => 'datetime', 'not null' => true, 'description' => 'timestamp sent'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['consumer_key', 'ts', 'nonce'],
];
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Notice's location
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class NoticeLocation
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'notice_location',
'fields' => [
'notice_id' => ['type' => 'int', 'not null' => true, 'description' => 'notice that is the reply'],
'lat' => ['type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'],
'lon' => ['type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'],
'location_id' => ['type' => 'int', 'description' => 'location id if possible'],
'location_ns' => ['type' => 'int', 'description' => 'namespace for location'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['notice_id'],
'foreign keys' => [
'notice_location_notice_id_fkey' => ['notice', ['notice_id' => 'id']],
],
'indexes' => [
'notice_location_location_id_idx' => ['location_id'],
],
];
}
}

View File

@ -0,0 +1,65 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Notice preferences
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @license 2018 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class NoticePrefs
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'notice_prefs',
'fields' => [
'notice_id' => ['type' => 'int', 'not null' => true, 'description' => 'user'],
'namespace' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'namespace, like pluginname or category'],
'topic' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'preference key, i.e. description, age...'],
'data' => ['type' => 'blob', 'description' => 'topic data, may be anything'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['notice_id', 'namespace', 'topic'],
'foreign keys' => [
'notice_prefs_notice_id_fkey' => ['notice', ['notice_id' => 'id']],
],
'indexes' => [
'notice_prefs_notice_id_idx' => ['notice_id'],
],
];
}
}

View File

@ -0,0 +1,57 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Notices sources
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class NoticeSource
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'notice_source',
'fields' => [
'code' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'source code'],
'name' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'name of the source'],
'url' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'url to link to'],
'notice_id' => ['type' => 'int', 'not null' => true, 'default' => 0, 'description' => 'date this record was created'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['code'],
];
}
}

63
src/Entity/NoticeTag.php Normal file
View File

@ -0,0 +1,63 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Notice Tag
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class NoticeTag
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'notice_tag',
'description' => 'Hash tags',
'fields' => [
'tag' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'],
'notice_id' => ['type' => 'int', 'not null' => true, 'description' => 'notice tagged'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
],
'primary key' => ['tag', 'notice_id'],
'foreign keys' => [
'notice_tag_notice_id_fkey' => ['notice', ['notice_id' => 'id']],
],
'indexes' => [
'notice_tag_created_idx' => ['created'],
'notice_tag_notice_id_idx' => ['notice_id'],
'notice_tag_tag_created_notice_id_idx' => ['tag', 'created', 'notice_id'],
],
];
}
}

View File

@ -1,92 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for notice_location
*/
defined('GNUSOCIAL') || die();
class Notice_location extends Managed_DataObject
{
public $__table = 'notice_location'; // table name
public $notice_id; // int(4) primary_key not_null
public $lat; // decimal(10,7)
public $lon; // decimal(10,7)
public $location_id; // int(4)
public $location_ns; // int(4)
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
public static function schemaDef()
{
return array(
'fields' => array(
'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice that is the reply'),
'lat' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'),
'lon' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'),
'location_id' => array('type' => 'int', 'description' => 'location id if possible'),
'location_ns' => array('type' => 'int', 'description' => 'namespace for location'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('notice_id'),
'foreign keys' => array(
'notice_location_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
),
'indexes' => array(
'notice_location_location_id_idx' => array('location_id'),
),
);
}
public static function locFromStored(Notice $stored)
{
$loc = new Notice_location();
$loc->notice_id = $stored->getID();
if (!$loc->find(true)) {
throw new NoResultException($loc);
}
return $loc->asLocation();
}
public static function fromLocation(Location $location)
{
$notloc = new Notice_location();
$notloc->lat = $location->lat;
$notloc->lon = $location->lon;
$notloc->location_ns = $location->location_ns;
$notloc->location_id = $location->location_id;
return $notloc;
}
public function asLocation()
{
$location = null;
if (!empty($this->location_id) && !empty($this->location_ns)) {
$location = Location::fromId($this->location_id, $this->location_ns);
}
if (is_null($location)) { // no ID, or Location::fromId() failed
$location = Location::fromLatLon($this->lat, $this->lon);
}
if (is_null($location)) {
throw new ServerException('Location could not be looked up from existing data.');
}
return $location;
}
}

View File

@ -1,175 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Data class for Notice preferences
*
* @category Data
* @package GNUsocial
* @author Mikael Nordfeldth <mmn@hethane.se>
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @copyright 2013 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Notice_prefs extends Managed_DataObject
{
public $__table = 'notice_prefs'; // table name
public $notice_id; // int(4) primary_key not_null
public $namespace; // varchar(191) not_null
public $topic; // varchar(191) not_null
public $data; // text
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
public static function schemaDef()
{
return array(
'fields' => array(
'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'user'),
'namespace' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'namespace, like pluginname or category'),
'topic' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'preference key, i.e. description, age...'),
'data' => array('type' => 'blob', 'description' => 'topic data, may be anything'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('notice_id', 'namespace', 'topic'),
'foreign keys' => array(
'notice_prefs_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
),
);
}
public static function getNamespacePrefs(Notice $notice, $namespace, array $topic = [])
{
if (empty($topic)) {
$prefs = new Notice_prefs();
$prefs->notice_id = $notice->getID();
$prefs->namespace = $namespace;
$prefs->find();
} else {
$prefs = self::pivotGet('notice_id', $notice->getID(), array('namespace'=>$namespace, 'topic'=>$topic));
}
if (empty($prefs->N)) {
throw new NoResultException($prefs);
}
return $prefs;
}
public static function getNamespace(Notice $notice, $namespace, array $topic = [])
{
$prefs = self::getNamespacePrefs($notice, $namespace, $topic);
return $prefs->fetchAll();
}
public static function getAll(Notice $notice)
{
try {
$prefs = self::listFind('notice_id', array($notice->getID()));
} catch (NoResultException $e) {
return array();
}
$list = array();
while ($prefs->fetch()) {
if (!isset($list[$prefs->namespace])) {
$list[$prefs->namespace] = array();
}
$list[$prefs->namespace][$prefs->topic] = $prefs->data;
}
return $list;
}
public static function getTopic(Notice $notice, $namespace, $topic)
{
return self::getByPK([
'notice_id' => $notice->getID(),
'namespace' => $namespace,
'topic' => $topic,
]);
}
public static function getData(Notice $notice, $namespace, $topic, $def = null)
{
try {
$pref = self::getTopic($notice, $namespace, $topic);
} catch (NoResultException $e) {
if ($def === null) {
// If no default value was set, continue the exception.
throw $e;
}
// If there was a default value, return that.
return $def;
}
return $pref->data;
}
public static function getConfigData(Notice $notice, $namespace, $topic)
{
try {
$data = self::getData($notice, $namespace, $topic);
} catch (NoResultException $e) {
$data = common_config($namespace, $topic);
}
return $data;
}
/*
* Sets a notice preference based on Notice, namespace and topic
*
* @param Notice $notice Which notice this is for
* @param string $namespace Under which namespace (pluginname etc.)
* @param string $topic Preference name (think key in key-val store)
* @param string $data Data to be put into preference storage, null means delete
*
* @return true if changes are made, false if no action taken
* @throws ServerException if preference could not be saved
*/
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 = DB_DataObject_Cast::blob($data);
$pref->update($orig);
}
return true;
} catch (NoResultException $e) {
if (is_null($data)) {
return false; // No action taken
}
}
$pref = new Notice_prefs();
$pref->notice_id = $notice->getID();
$pref->namespace = $namespace;
$pref->topic = $topic;
$pref->data = DB_DataObject_Cast::blob($data);
$pref->created = common_sql_now();
if ($pref->insert() === false) {
throw new ServerException('Could not save notice preference.');
}
return true;
}
}

View File

@ -1,52 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for notice_source
*/
defined('GNUSOCIAL') || die();
class Notice_source extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'notice_source'; // table name
public $code; // varchar(32) primary_key not_null
public $name; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $url; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'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, 'default' => 0, 'description' => 'notice id'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('code'),
);
}
}

View File

@ -1,97 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/*
* @copyright 2008, 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Notice_tag extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'notice_tag'; // table name
public $tag; // varchar(64) primary_key not_null
public $notice_id; // int(4) primary_key not_null
public $created; // datetime()
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'description' => 'Hash tags',
'fields' => array(
'tag' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'),
'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice tagged'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
),
'primary key' => array('tag', 'notice_id'),
'foreign keys' => array(
'notice_tag_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
),
'indexes' => array(
'notice_tag_created_idx' => array('created'),
'notice_tag_notice_id_idx' => array('notice_id'),
'notice_tag_tag_created_notice_id_idx' => array('tag', 'created', 'notice_id')
),
);
}
public static function getStream(
$tag,
$offset = 0,
$limit = 20,
$sinceId = 0,
$maxId = 0
) {
// FIXME: Get the Profile::current value some other way
// to avoid confusino between queue processing and session.
$stream = new TagNoticeStream($tag, Profile::current());
return $stream;
}
public function blowCache($blowLast = false)
{
self::blow('notice_tag:notice_ids:%s', Cache::keyize($this->tag));
if ($blowLast) {
self::blow('notice_tag:notice_ids:%s;last', Cache::keyize($this->tag));
}
}
public static function url($tag)
{
if (common_config('singleuser', 'enabled')) {
// Regular TagAction isn't set up in 1user mode
$nickname = User::singleUserNickname();
$url = common_local_url(
'showstream',
[
'nickname' => $nickname,
'tag' => $tag,
]
);
} else {
$url = common_local_url('tag', ['tag' => $tag]);
}
return $url;
}
}

View File

@ -0,0 +1,73 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for OAuth Application
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class OauthApplication
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'oauth_application',
'description' => 'OAuth application registration record',
'fields' => [
'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'],
'owner' => ['type' => 'int', 'not null' => true, 'description' => 'owner of the application'],
'consumer_key' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'application consumer key'],
'name' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'name of the application'],
'description' => ['type' => 'varchar', 'length' => 191, 'description' => 'description of the application'],
'icon' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'default' => '/theme/base/default-avatar-stream.png', 'description' => 'application icon'],
'source_url' => ['type' => 'varchar', 'length' => 191, 'description' => 'application homepage - used for source link'],
'organization' => ['type' => 'varchar', 'length' => 191, 'description' => 'name of the organization running the application'],
'homepage' => ['type' => 'varchar', 'length' => 191, 'description' => 'homepage for the organization'],
'callback_url' => ['type' => 'varchar', 'length' => 191, 'description' => 'url to redirect to after authentication'],
'type' => ['type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'type of app, 1 = browser, 2 = desktop'],
'access_type' => ['type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'default access type, bit 1 = read, bit 2 = write'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['id'],
'unique keys' => [
'oauth_application_name_key' => ['name'], // in the long run, we should perhaps not force these unique, and use another source id
],
'foreign keys' => [
'oauth_application_owner_fkey' => ['profile', ['owner' => 'id']], // Are remote users allowed to create oauth application records?
'oauth_application_consumer_key_fkey' => ['consumer', ['consumer_key' => 'consumer_key']],
],
];
}
}

View File

@ -0,0 +1,61 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for OAuth Application User
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class OauthApplicationUser
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'oauth_application_user',
'fields' => [
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'user of the application'],
'application_id' => ['type' => 'int', 'not null' => true, 'description' => 'id of the application'],
'access_type' => ['type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'access type, bit 1 = read, bit 2 = write'],
'token' => ['type' => 'varchar', 'length' => 191, 'description' => 'request or access token'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['profile_id', 'application_id'],
'foreign keys' => [
'oauth_application_user_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
'oauth_application_user_application_id_fkey' => ['oauth_application', ['application_id' => 'id']],
],
];
}
}

View File

@ -0,0 +1,61 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for association between OAuth and internal token
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class OauthTokenAssociation
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'oauth_token_association',
'description' => 'Associate an application ID and profile ID with an OAuth token',
'fields' => [
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'associated user'],
'application_id' => ['type' => 'int', 'not null' => true, 'description' => 'the application'],
'token' => ['type' => 'varchar', 'length' => '191', 'not null' => true, 'description' => 'token used for this association'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['profile_id', 'application_id', 'token'],
'foreign keys' => [
'oauth_token_association_profile_fkey' => ['profile', ['profile_id' => 'id']],
'oauth_token_association_application_fkey' => ['oauth_application', ['application_id' => 'id']],
],
];
}
}

View File

@ -1,209 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for oauth_application
*/
defined('GNUSOCIAL') || die();
class Oauth_application extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'oauth_application'; // table name
public $id; // int(4) primary_key not_null
public $owner; // int(4) not_null
public $consumer_key; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $name; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $description; // varchar(191) not 255 because utf8mb4 takes more space
public $icon; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $source_url; // varchar(191) not 255 because utf8mb4 takes more space
public $organization; // varchar(191) not 255 because utf8mb4 takes more space
public $homepage; // varchar(191) not 255 because utf8mb4 takes more space
public $callback_url; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $type; // tinyint(1)
public $access_type; // tinyint(1)
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
// Bit flags
public static $readAccess = 1;
public static $writeAccess = 2;
public static $browser = 1;
public static $desktop = 2;
public function getConsumer()
{
return Consumer::getKV('consumer_key', $this->consumer_key);
}
public static function maxDesc()
{
// This used to default to textlimit or allow unlimited descriptions,
// but this isn't part of a notice and the field's limited to 191 chars
// in the DB, so those seem silly. (utf8mb4 takes up more space, so can't use 255)
//
// Now just defaulting to 191 max unless a smaller application desclimit
// is actually set. Setting to 0 will use the maximum.
$max = 191;
$desclimit = intval(common_config('application', 'desclimit'));
if ($desclimit > 0 && $desclimit < $max) {
return $desclimit;
} else {
return $max;
}
}
public static function descriptionTooLong($desc)
{
$desclimit = self::maxDesc();
return ($desclimit > 0 && !empty($desc) && (mb_strlen($desc) > $desclimit));
}
public function setAccessFlags($read, $write)
{
if ($read) {
$this->access_type |= self::$readAccess;
} else {
$this->access_type &= ~self::$readAccess;
}
if ($write) {
$this->access_type |= self::$writeAccess;
} else {
$this->access_type &= ~self::$writeAccess;
}
}
public function setOriginal($filename)
{
$imagefile = new ImageFile(null, Avatar::path($filename));
// XXX: Do we want to have a bunch of different size icons? homepage, stream, mini?
// or just one and control size via CSS? --Zach
$orig = clone($this);
$this->icon = Avatar::url($filename);
common_debug(common_log_objstring($this));
return $this->update($orig);
}
public static function getByConsumerKey($key)
{
if (empty($key)) {
return null;
}
$app = new Oauth_application();
$app->consumer_key = $key;
$app->limit(1);
$result = $app->find(true);
return empty($result) ? null : $app;
}
/**
* Handle an image upload
*
* Does all the magic for handling an image upload, and crops the
* image by default.
*
* @return void
*/
public function uploadLogo()
{
if ($_FILES['app_icon']['error'] == UPLOAD_ERR_OK) {
try {
$imagefile = ImageFile::fromUpload('app_icon');
} catch (Exception $e) {
common_debug("damn that sucks");
$this->showForm($e->getMessage());
return;
}
$filename = Avatar::filename(
$this->id,
image_type_to_extension($imagefile->type),
null,
'oauth-app-icon-' . common_timestamp()
);
$filepath = Avatar::path($filename);
move_uploaded_file($imagefile->filepath, $filepath);
$this->setOriginal($filename);
}
}
public function delete($useWhere = false)
{
$this->deleteAppUsers();
$consumer = $this->getConsumer();
$consumer->delete();
return parent::delete($useWhere);
}
private function deleteAppUsers()
{
$oauser = new Oauth_application_user();
$oauser->application_id = $this->id;
$oauser->delete();
}
public static function schemaDef()
{
return array(
'description' => 'OAuth application registration record',
'fields' => array(
'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
'owner' => array('type' => 'int', 'not null' => true, 'description' => 'owner of the application'),
'consumer_key' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'application consumer key'),
'name' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'name of the application'),
'description' => array('type' => 'varchar', 'length' => 191, 'description' => 'description of the application'),
'icon' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'default' => '/theme/base/default-avatar-stream.png', 'description' => 'application icon'),
'source_url' => array('type' => 'varchar', 'length' => 191, 'description' => 'application homepage - used for source link'),
'organization' => array('type' => 'varchar', 'length' => 191, 'description' => 'name of the organization running the application'),
'homepage' => array('type' => 'varchar', 'length' => 191, 'description' => 'homepage for the organization'),
'callback_url' => array('type' => 'varchar', 'length' => 191, 'description' => 'url to redirect to after authentication'),
'type' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'type of app, 1 = browser, 2 = desktop'),
'access_type' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'default access type, bit 1 = read, bit 2 = write'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('id'),
'unique keys' => array(
'oauth_application_name_key' => array('name'), // in the long run, we should perhaps not force these unique, and use another source id
),
'foreign keys' => array(
'oauth_application_owner_fkey' => array('profile', array('owner' => 'id')), // Are remote users allowed to create oauth application records?
'oauth_application_consumer_key_fkey' => array('consumer', array('consumer_key' => 'consumer_key')),
),
'indexes' => array(
'oauth_application_owner_idx' => array('owner'),
'oauth_application_consumer_key_idx' => array('consumer_key'),
),
);
}
}

View File

@ -1,107 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for oauth_application_user
*/
defined('GNUSOCIAL') || die();
class Oauth_application_user extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'oauth_application_user'; // table name
public $profile_id; // int(4) primary_key not_null
public $application_id; // int(4) primary_key not_null
public $access_type; // tinyint(1)
public $token; // varchar(191) not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'user of the application'),
'application_id' => array('type' => 'int', 'not null' => true, 'description' => 'id of the application'),
'access_type' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'access type, bit 1 = read, bit 2 = write'),
'token' => array('type' => 'varchar', 'length' => 191, 'description' => 'request or access token'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('profile_id', 'application_id'),
'foreign keys' => array(
'oauth_application_user_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
'oauth_application_user_application_id_fkey' => array('oauth_application', array('application_id' => 'id')),
),
'indexes' => array(
'oauth_application_user_application_id_idx' => array('application_id'),
),
);
}
public static function getByUserAndToken($user, $token)
{
if (empty($user) || empty($token)) {
return null;
}
$oau = new Oauth_application_user();
$oau->profile_id = $user->id;
$oau->token = $token;
$oau->limit(1);
$result = $oau->find(true);
return empty($result) ? null : $oau;
}
public function updateKeys(&$orig)
{
$this->_connect();
$parts = array();
foreach (array('profile_id', 'application_id', 'token', 'access_type') as $k) {
if (strcmp($this->$k, $orig->$k) != 0) {
$parts[] = $k . ' = ' . $this->_quote($this->$k);
}
}
if (count($parts) == 0) {
// No changes
return true;
}
$toupdate = implode(', ', $parts);
$toupdate .= ', modified = CURRENT_TIMESTAMP';
$table = $this->tableName();
$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) {
$this->encache();
}
return $result;
}
}

View File

@ -1,76 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for oauth_association
*/
defined('GNUSOCIAL') || die();
class Oauth_token_association extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'oauth_token_association'; // table name
public $profile_id; // int(4) primary_key not_null
public $application_id; // int(4) primary_key not_null
public $token; // varchar(191) primary key not null not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function getByUserAndToken($user, $token)
{
if (empty($user) || empty($token)) {
return null;
}
$oau = new oauth_request_token();
$oau->profile_id = $user->id;
$oau->token = $token;
$oau->limit(1);
$result = $oau->find(true);
return empty($result) ? null : $oau;
}
public static function schemaDef()
{
return array(
'description' => 'Associate an application ID and profile ID with an OAuth token',
'fields' => array(
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'associated user'),
'application_id' => array('type' => 'int', 'not null' => true, 'description' => 'the application'),
'token' => array('type' => 'varchar', 'length' => '191', 'not null' => true, 'description' => 'token used for this association'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('profile_id', 'application_id', 'token'),
'foreign keys' => array(
'oauth_token_association_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
'oauth_token_association_application_id_fkey' => array('oauth_application', array('application_id' => 'id')),
),
'indexes' => array(
'oauth_token_association_application_id_idx' => array('application_id'),
),
);
}
}

View File

@ -0,0 +1,66 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Separate table for storing UI preferences
*
* @category DB
* @package GNUsocial
*
* @deprecated
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class OldSchoolPrefs
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'old_school_prefs',
'fields' => [
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'user who has the preference'],
'stream_mode_only' => ['type' => 'bool',
'default' => true,
'description' => 'No conversation streams', ],
'conversation_tree' => ['type' => 'bool',
'default' => true,
'description' => 'Hierarchical tree view for conversations', ],
'stream_nicknames' => ['type' => 'bool',
'default' => true,
'description' => 'Show nicknames for authors and addressees in streams', ],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['user_id'],
'foreign keys' => [
'old_school_prefs_user_id_fkey' => ['user', ['user_id' => 'id']],
],
];
}
}

View File

@ -1,69 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Older-style UI preferences
*
* @category UI
* @package GNUsocial
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
/**
* Separate table for storing UI preferences
*
* @copyright 2011 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class Old_school_prefs extends Managed_DataObject
{
public $__table = 'old_school_prefs'; // table name
public $user_id;
public $stream_mode_only;
public $conversation_tree;
public $stream_nicknames;
public $created;
public $modified;
public static function schemaDef()
{
return array(
'fields' => array(
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user who has the preference'),
'stream_mode_only' => array('type' => 'bool',
'default' => true,
'description' => 'No conversation streams'),
'conversation_tree' => array('type' => 'bool',
'default' => true,
'description' => 'Hierarchical tree view for conversations'),
'stream_nicknames' => array('type' => 'bool',
'default' => true,
'description' => 'Show nicknames for authors and addressees in streams'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('user_id'),
'foreign keys' => array(
'old_school_prefs_user_id_fkey' => array('user', array('user_id' => 'id')),
),
);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for User's Profile Block
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ProfileBlock
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'profile_block',
'fields' => [
'blocker' => ['type' => 'int', 'not null' => true, 'description' => 'user making the block'],
'blocked' => ['type' => 'int', 'not null' => true, 'description' => 'profile that is blocked'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date of blocking'],
],
'foreign keys' => [
'profile_block_blocker_fkey' => ['user', ['blocker' => 'id']],
'profile_block_blocked_fkey' => ['profile', ['blocked' => 'id']],
],
'primary key' => ['blocker', 'blocked'],
];
}
}

View File

@ -0,0 +1,77 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for List of profiles
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ProfileList
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'profile_list',
'fields' => [
'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'],
'tagger' => ['type' => 'int', 'not null' => true, 'description' => 'user making the tag'],
'tag' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'people tag'],
'description' => ['type' => 'text', 'description' => 'description of the people tag'],
'private' => ['type' => 'bool', 'default' => false, 'description' => 'is this tag private'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date the tag was added'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date the tag was modified'],
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'],
'mainpage' => ['type' => 'varchar', 'length' => 191, 'description' => 'page to link to'],
'tagged_count' => ['type' => 'int', 'default' => 0, 'description' => 'number of people tagged with this tag by this user'],
'subscriber_count' => ['type' => 'int', 'default' => 0, 'description' => 'number of subscribers to this tag'],
],
'primary key' => ['tagger', 'tag'],
'unique keys' => [
'profile_list_id_key' => ['id'],
],
'foreign keys' => [
'profile_list_tagger_fkey' => ['profile', ['tagger' => 'id']],
],
'indexes' => [
'profile_list_modified_idx' => ['modified'],
'profile_list_tag_idx' => ['tag'],
'profile_list_tagger_tag_idx' => ['tagger', 'tag'],
'profile_list_tagged_count_idx' => ['tagged_count'],
'profile_list_subscriber_count_idx' => ['subscriber_count'],
],
];
}
}

View File

@ -0,0 +1,63 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Data class for Profile preferences
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ProfilePrefs
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'profile_prefs',
'fields' => [
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'user'],
'namespace' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'namespace, like pluginname or category'],
'topic' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'preference key, i.e. description, age...'],
'data' => ['type' => 'blob', 'description' => 'topic data, may be anything'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['profile_id', 'namespace', 'topic'],
'foreign keys' => [
'profile_prefs_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
],
'indexes' => [
'profile_prefs_profile_id_idx' => ['profile_id'],
],
];
}
}

View File

@ -0,0 +1,58 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for user profile role
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ProfileRole
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'profile_role',
'fields' => [
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'account having the role'],
'role' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'string representing the role'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date the role was granted'],
],
'primary key' => ['profile_id', 'role'],
'foreign keys' => [
'profile_role_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
],
'indexes' => ['profile_role_role_created_profile_id_idx' => ['role', 'created', 'profile_id']],
];
}
}

65
src/Entity/ProfileTag.php Normal file
View File

@ -0,0 +1,65 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Profile Tag
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ProfileTag
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'profile_tag',
'fields' => [
'tagger' => ['type' => 'int', 'not null' => true, 'description' => 'user making the tag'],
'tagged' => ['type' => 'int', 'not null' => true, 'description' => 'profile tagged'],
'tag' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date the tag was added'],
],
'primary key' => ['tagger', 'tagged', 'tag'],
'foreign keys' => [
'profile_tag_tagger_fkey' => ['profile', ['tagger' => 'id']],
'profile_tag_tagged_fkey' => ['profile', ['tagged' => 'id']],
],
'indexes' => [
'profile_tag_modified_idx' => ['modified'],
'profile_tag_tagger_tag_idx' => ['tagger', 'tag'],
'profile_tag_tagged_idx' => ['tagged'],
],
];
}
}

View File

@ -0,0 +1,65 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Profile Tag Subscription
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class ProfileTagSubscription
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'profile_tag_subscription',
'fields' => [
'profile_tag_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to profile_tag'],
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['profile_tag_id', 'profile_id'],
'foreign keys' => [
'profile_tag_subscription_profile_list_id_fkey' => ['profile_list', ['profile_tag_id' => 'id']],
'profile_tag_subscription_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
],
'indexes' => [
// @fixme probably we want a (profile_id, created) index here?
'profile_tag_subscription_profile_id_idx' => ['profile_id'],
'profile_tag_subscription_created_idx' => ['created'],
],
];
}
}

View File

@ -1,63 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/*
* Table Definition for profile_block
*
* @copyright 2008, 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Profile_block extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'profile_block'; // table name
public $blocker; // int(4) primary_key not_null
public $blocked; // int(4) primary_key not_null
public $modified; // datetime() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'blocker' => array('type' => 'int', 'not null' => true, 'description' => 'user making the block'),
'blocked' => array('type' => 'int', 'not null' => true, 'description' => 'profile that is blocked'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date of blocking'),
),
'foreign keys' => array(
'profile_block_blocker_fkey' => array('user', array('blocker' => 'id')),
'profile_block_blocked_fkey' => array('profile', array('blocked' => 'id')),
),
'primary key' => array('blocker', 'blocked'),
'indexes' => array(
'profile_block_blocked_idx' => array('blocked'),
),
);
}
public static function exists(Profile $blocker, Profile $blocked)
{
return Profile_block::pkeyGet(array('blocker' => $blocker->id,
'blocked' => $blocked->id));
}
}

View File

@ -1,949 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* @category Notices
* @package GNUsocial
* @author Shashi Gowda <connect2shashi@gmail.com>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Profile_list extends Managed_DataObject
{
public $__table = 'profile_list'; // table name
public $id; // int(4) primary_key not_null
public $tagger; // int(4)
public $tag; // varchar(64)
public $description; // text
public $private; // bool default_false
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
public $uri; // varchar(191) unique_key not 255 because utf8mb4 takes more space
public $mainpage; // varchar(191) not 255 because utf8mb4 takes more space
public $tagged_count; // smallint
public $subscriber_count; // smallint
public static function schemaDef()
{
return array(
'fields' => array(
'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
'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' => 'bool', 'default' => false, 'description' => 'is this tag private'),
'created' => array('type' => 'datetime', 'description' => 'date the tag was added'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date the tag was modified'),
'uri' => array('type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'),
'mainpage' => array('type' => 'varchar', 'length' => 191, 'description' => 'page to link to'),
'tagged_count' => array('type' => 'int', 'default' => 0, 'description' => 'number of people tagged with this tag by this user'),
'subscriber_count' => array('type' => 'int', 'default' => 0, 'description' => 'number of subscribers to this tag'),
),
'primary key' => array('tagger', 'tag'),
'unique keys' => array(
'profile_list_id_key' => array('id'),
),
'foreign keys' => array(
'profile_list_tagger_fkey' => array('profile', array('tagger' => 'id')),
),
'indexes' => array(
'profile_list_modified_id_idx' => array('modified', 'id'),
'profile_list_tag_idx' => array('tag'),
'profile_list_tagged_count_idx' => array('tagged_count'),
'profile_list_subscriber_count_idx' => array('subscriber_count'),
),
);
}
/**
* get the tagger of this profile_list object
*
* @return Profile the tagger
*/
public function getTagger()
{
return Profile::getByID($this->tagger);
}
/**
* return a string to identify this
* profile_list in the user interface etc.
*
* @return String
*/
public function getBestName()
{
return $this->tag;
}
/**
* return a uri string for this profile_list
*
* @return String uri
*/
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',
['id' => $this->id, 'tagger_id' => $this->tagger]
);
}
}
Event::handle('EndProfiletagGetUri', array($this, &$uri));
return $uri;
}
/**
* return a url to the homepage of this item
*
* @return String home url
*/
public function homeUrl()
{
$url = null;
if (Event::handle('StartUserPeopletagHomeUrl', array($this, &$url))) {
// normally stored in mainpage, but older ones may be null
if (!empty($this->mainpage)) {
$url = $this->mainpage;
} else {
$url = common_local_url(
'showprofiletag',
[
'nickname' => $this->getTagger()->nickname,
'tag' => $this->tag,
]
);
}
}
Event::handle('EndUserPeopletagHomeUrl', array($this, &$url));
return $url;
}
/**
* return an immutable url for this object
*
* @return String permalink
*/
public function permalink()
{
$url = null;
if (Event::handle('StartProfiletagPermalink', array($this, &$url))) {
$url = common_local_url(
'profiletagbyid',
['id' => $this->id]
);
}
Event::handle('EndProfiletagPermalink', array($this, &$url));
return $url;
}
/**
* Query notices by users associated with this tag,
* but first check the cache before hitting the DB.
*
* @param integer $offset offset
* @param integer $limit maximum no of results
* @param integer $since_id=null since this id
* @param integer $max_id=null maximum id in result
*
* @return Notice the query
*/
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.
$stream = new PeopletagNoticeStream($this, Profile::current());
return $stream->getNotices($offset, $limit, $since_id, $max_id);
}
/**
* Get subscribers (local and remote) to this people tag
* Order by reverse chronology
*
* @param integer $offset offset
* @param integer $limit maximum no of results
* @param integer $since_id=null since unix timestamp
* @param integer $upto=null maximum unix timestamp when subscription was made
*
* @return Profile results
*/
public function getSubscribers(int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
{
$subs = new Profile();
$subs->joinAdd(
array('id', 'profile_tag_subscription:profile_id')
);
$subs->whereAdd('profile_tag_subscription.profile_tag_id = ' . $this->id);
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);
}
if ($upto != 0) {
$subs->whereAdd('cursor <= ' . $upto);
}
if (!is_null($limit)) {
$subs->limit($offset, $limit);
}
$subs->orderBy('profile_tag_subscription.created DESC, profile.id DESC');
$subs->find();
return $subs;
}
/**
* Get all and only local subscribers to this people tag
* used for distributing notices to user inboxes.
*
* @return array ids of users
*/
public function getUserSubscribers()
{
// XXX: cache this
$user = new User();
$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
));
$ids = [];
while ($user->fetch()) {
$ids[] = $user->id;
}
$user->free();
return $ids;
}
/**
* Check to see if a given profile has
* subscribed to this people tag's timeline
*
* @param mixed $id User or Profile object or integer id
*
* @return boolean subscription status
*/
public function hasSubscriber($id)
{
if (!is_numeric($id)) {
$id = $id->id;
}
$sub = Profile_tag_subscription::pkeyGet(array('profile_tag_id' => $this->id,
'profile_id' => $id));
return !empty($sub);
}
/**
* Get profiles tagged with this people tag,
* include modified timestamp as a "cursor" field
* order by descending order of modified time
*
* @param integer $offset offset
* @param integer $limit maximum no of results
* @param integer $since_id=null since unix timestamp
* @param integer $upto=null maximum unix timestamp when subscription was made
*
* @return Profile results
*/
public function getTagged(int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
{
$tagged = new Profile();
$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`");
}
$tagged->whereAdd('profile_tag.tagger = '.$this->tagger);
$tagged->whereAdd("profile_tag.tag = '{$this->tag}'");
if ($since != 0) {
$tagged->whereAdd('cursor > ' . $since);
}
if ($upto != 0) {
$tagged->whereAdd('cursor <= ' . $upto);
}
if (!is_null($limit)) {
$tagged->limit($offset, $limit);
}
$tagged->orderBy('profile_tag.modified DESC, profile_tag.tagged DESC');
$tagged->find();
return $tagged;
}
/**
* Gracefully delete one or many people tags
* along with their members and subscriptions data
*
* @return boolean success
*/
public function delete($useWhere = false)
{
// force delete one item at a time.
if (empty($this->id)) {
$this->find();
while ($this->fetch()) {
$this->delete();
}
}
Profile_tag::cleanup($this);
Profile_tag_subscription::cleanup($this);
self::blow('profile:lists:%d', $this->tagger);
return parent::delete($useWhere);
}
/**
* Update a people tag gracefully
* also change "tag" fields in profile_tag table
*
* @param Profile_list $dataObject Object's original form
*
* @return boolean success
*/
public function update($dataObject = false)
{
if (!is_object($dataObject) && !$dataObject instanceof Profile_list) {
return parent::update($dataObject);
}
$result = true;
// 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) {
$existing = Profile_list::getByTaggerAndTag($this->tagger, $this->tag);
if (!empty($existing)) {
// TRANS: Server exception.
throw new ServerException(_('The tag you are trying to rename ' .
'to already exists.'));
}
// move the tag
// XXX: allow OStatus plugin to send out profile tag
$result = Profile_tag::moveTag($dataObject, $this);
}
return parent::update($dataObject);
}
/**
* return an xml string representing this people tag
* as the author of an atom feed
*
* @return string atom author element
*/
public function asAtomAuthor()
{
$xs = new XMLStringer(true);
$tagger = $this->getTagger();
$xs->elementStart('author');
$xs->element('name', null, '@' . $tagger->nickname . '/' . $this->tag);
$xs->element('uri', null, $this->permalink());
$xs->elementEnd('author');
return $xs->getString();
}
/**
* return an xml string to represent this people tag
* as a noun in an activitystreams feed.
*
* @param string $element the xml tag
*
* @return string activitystreams noun
*/
public function asActivityNoun($element)
{
$noun = ActivityObject::fromPeopletag($this);
return $noun->asString('activity:' . $element);
}
/**
* get the cached number of profiles tagged with this
* people tag, re-count if the argument is true.
*
* @param boolean $recount whether to ignore cache
*
* @return integer count
*/
public function taggedCount($recount = false)
{
$keypart = sprintf(
'profile_list:tagged_count:%d:%s',
$this->tagger,
$this->tag
);
$count = self::cacheGet($keypart);
if ($count === false) {
$tags = new Profile_tag();
$tags->tag = $this->tag;
$tags->tagger = $this->tagger;
$count = $tags->count('distinct tagged');
self::cacheSet($keypart, $count);
}
return $count;
}
/**
* get the cached number of profiles subscribed to this
* people tag, re-count if the argument is true.
*
* @param boolean $recount whether to ignore cache
*
* @return integer count
*/
public function subscriberCount($recount = false)
{
$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');
self::cacheSet($keypart, $count);
}
return $count;
}
/**
* get the cached number of profiles subscribed to this
* people tag, re-count if the argument is true.
*
* @param boolean $recount whether to ignore cache
*
* @return integer count
*/
public function blowNoticeStreamCache($all = false)
{
self::blow('profile_list:notice_ids:%d', $this->id);
if ($all) {
self::blow('profile_list:notice_ids:%d;last', $this->id);
}
}
/**
* get the Profile_list object by the
* given tagger and with given tag
*
* @param integer $tagger the id of the creator profile
* @param integer $tag the tag
*
* @return integer count
*/
public static function getByTaggerAndTag($tagger, $tag)
{
$ptag = Profile_list::pkeyGet(array('tagger' => $tagger, 'tag' => $tag));
return $ptag;
}
/**
* create a profile_list record for a tag, tagger pair
* if it doesn't exist, return it.
*
* @param integer $tagger the tagger
* @param string $tag the tag
* @param string $description description
* @param boolean $private protected or not
*
* @return Profile_list the people tag object
*/
public static function ensureTag($tagger, $tag, $description = null, $private = false)
{
$ptag = Profile_list::getByTaggerAndTag($tagger, $tag);
if (empty($ptag->id)) {
$args = array(
'tag' => $tag,
'tagger' => $tagger,
'description' => $description,
'private' => $private
);
$new_tag = Profile_list::saveNew($args);
return $new_tag;
}
return $ptag;
}
/**
* get the maximum number of characters
* that can be used in the description of
* a people tag.
*
* determined by $config['peopletag']['desclimit']
* if not set, falls back to $config['site']['textlimit']
*
* @return integer maximum number of characters
*/
public static function maxDescription()
{
$desclimit = common_config('peopletag', 'desclimit');
// null => use global limit (distinct from 0!)
if (is_null($desclimit)) {
$desclimit = common_config('site', 'textlimit');
}
return $desclimit;
}
/**
* check if the length of given text exceeds
* character limit.
*
* @param string $desc the description
*
* @return boolean is the descripition too long?
*/
public static function descriptionTooLong($desc)
{
$desclimit = self::maxDescription();
return ($desclimit > 0 && !empty($desc) && (mb_strlen($desc) > $desclimit));
}
/**
* save a new people tag, this should be always used
* since it makes uri, homeurl, created and modified
* timestamps and performs checks.
*
* @param array $fields an array with fields and their values
*
* @return mixed Profile_list on success, false on fail
*/
public static function saveNew(array $fields)
{
extract($fields);
$ptag = new Profile_list();
$ptag->query('START TRANSACTION');
if (empty($tagger)) {
// TRANS: Server exception saving new tag without having a tagger specified.
throw new Exception(_('No tagger specified.'));
}
if (empty($tag)) {
// TRANS: Server exception saving new tag without having a tag specified.
throw new Exception(_('No tag specified.'));
}
if (empty($mainpage)) {
$mainpage = null;
}
if (empty($uri)) {
// fill in later...
$uri = null;
}
if (empty($mainpage)) {
$mainpage = null;
}
if (empty($description)) {
$description = null;
}
if (empty($private)) {
$private = false;
}
$ptag->tagger = $tagger;
$ptag->tag = $tag;
$ptag->description = $description;
$ptag->private = $private;
$ptag->uri = $uri;
$ptag->mainpage = $mainpage;
$ptag->created = common_sql_now();
$ptag->modified = common_sql_now();
$result = $ptag->insert();
if (!$result) {
common_log_db_error($ptag, 'INSERT', __FILE__);
// TRANS: Server exception saving new tag.
throw new ServerException(_('Could not create profile tag.'));
}
if (!isset($uri) || empty($uri)) {
$orig = clone($ptag);
$ptag->uri = common_local_url('profiletagbyid', array('id' => $ptag->id, 'tagger_id' => $ptag->tagger));
$result = $ptag->update($orig);
if (!$result) {
common_log_db_error($ptag, 'UPDATE', __FILE__);
// TRANS: Server exception saving new tag.
throw new ServerException(_('Could not set profile tag URI.'));
}
}
if (!isset($mainpage) || empty($mainpage)) {
$orig = clone($ptag);
$user = User::getKV('id', $ptag->tagger);
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
}
$result = $ptag->update($orig);
if (!$result) {
common_log_db_error($ptag, 'UPDATE', __FILE__);
// TRANS: Server exception saving new tag.
throw new ServerException(_('Could not set profile tag mainpage.'));
}
}
return $ptag;
}
/**
* get all items at given cursor position for api
*
* @param callback $fn a function that takes the following arguments in order:
* $offset, $limit, $since_id, $max_id
* and returns a Profile_list object after making the DB query
* @param array $args arguments required for $fn
* @param integer $cursor the cursor
* @param integer $count max. number of results
*
* Algorithm:
* - if cursor is 0, return empty list
* - if cursor is -1, get first 21 items, next_cursor = 20th prev_cursor = 0
* - if cursor is +ve get 22 consecutive items before starting at cursor
* - return items[1..20] if items[0] == cursor else return items[0..21]
* - prev_cursor = items[1]
* - next_cursor = id of the last item being returned
*
* - if cursor is -ve get 22 consecutive items after cursor starting at cursor
* - return items[1..20]
*
* @returns array (array (mixed items), int next_cursor, int previous_cursor)
*/
// XXX: This should be in Memcached_DataObject... eventually
public static function getAtCursor($fn, array $args, $cursor, $count = 20)
{
$items = array();
$since_id = 0;
$max_id = 0;
$next_cursor = 0;
$prev_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()) {
$items[] = clone($list);
}
if ((isset($items[0]->cursor) && $items[0]->cursor == $cursor) ||
$items[0]->id == $cursor) {
array_shift($items);
$prev_cursor = isset($items[0]->cursor) ?
-$items[0]->cursor : -$items[0]->id;
} else {
if (count($items) > $count+1) {
array_shift($items);
}
// this means the cursor item has been deleted, check to see if there are more
$fn_args = array_merge($args, array(0, 1, $cursor));
$more = call_user_func($fn, $fn_args);
if (!$more->fetch() || empty($more)) {
// no more items.
$prev_cursor = 0;
} else {
$prev_cursor = isset($items[0]->cursor) ?
-$items[0]->cursor : -$items[0]->id;
}
}
if (count($items)==$count+1) {
// this means there is a next page.
$next = array_pop($items);
$next_cursor = isset($next->cursor) ?
$items[$count-1]->cursor : $items[$count-1]->id;
}
} 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()) {
$items[] = clone($list);
}
$end = count($items)-1;
if ((isset($items[$end]->cursor) && $items[$end]->cursor == $cursor) ||
$items[$end]->id == $cursor) {
array_pop($items);
$next_cursor = isset($items[$end-1]->cursor) ?
$items[$end-1]->cursor : $items[$end-1]->id;
} else {
$next_cursor = isset($items[$end]->cursor) ?
$items[$end]->cursor : $items[$end]->id;
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));
$more = call_user_func_array($fn, $fn_args);
if (!$more->fetch() || empty($more)) {
$next_cursor = 0;
}
}
if (count($items) == $count+1) {
// this means there is a previous page.
$prev = array_shift($items);
$prev_cursor = isset($prev->cursor) ?
-$items[0]->cursor : -$items[0]->id;
}
} elseif ($cursor == -1) {
$fn_args = array_merge($args, array(0, $count+1));
$list = call_user_func_array($fn, $fn_args);
while ($list->fetch()) {
$items[] = clone($list);
}
if (count($items)==$count+1) {
$next = array_pop($items);
if (isset($next->cursor)) {
$next_cursor = $items[$count-1]->cursor;
} else {
$next_cursor = $items[$count-1]->id;
}
}
}
return array($items, $next_cursor, $prev_cursor);
}
/**
* save a collection of people tags into the cache
*
* @param string $ckey cache key
* @param Profile_list &$tag the results to store
* @param integer $offset offset for slicing results
* @param integer $limit maximum number of results
*
* @return boolean success
*/
public static function setCache($ckey, &$tag, $offset = 0, $limit = null)
{
$cache = Cache::instance();
if (empty($cache)) {
return false;
}
$str = '';
$tags = array();
while ($tag->fetch()) {
$str .= $tag->tagger . ':' . $tag->tag . ';';
$tags[] = clone($tag);
}
$str = substr($str, 0, -1);
if ($offset>=0 && !is_null($limit)) {
$tags = array_slice($tags, $offset, $limit);
}
$tag = new ArrayWrapper($tags);
return self::cacheSet($ckey, $str);
}
/**
* get people tags from the cache
*
* @param string $ckey cache key
* @param integer $offset offset for slicing
* @param integer $limit limit
*
* @return Profile_list results
*/
public static function getCached($ckey, $offset = 0, $limit = null)
{
$keys_str = self::cacheGet($ckey);
if ($keys_str === false) {
return false;
}
$pairs = explode(';', $keys_str);
$keys = array();
foreach ($pairs as $pair) {
$keys[] = explode(':', $pair);
}
if ($offset>=0 && !is_null($limit)) {
$keys = array_slice($keys, $offset, $limit);
}
return self::getByKeys($keys);
}
/**
* get Profile_list objects from the database
* given their (tag, tagger) key pairs.
*
* @param array $keys array of array(tagger, tag)
*
* @return Profile_list results
*/
public static function getByKeys(array $keys)
{
$cache = Cache::instance();
if (!empty($cache)) {
$tags = array();
foreach ($keys as $key) {
$t = Profile_list::getByTaggerAndTag($key[0], $key[1]);
if (!empty($t)) {
$tags[] = $t;
}
}
return new ArrayWrapper($tags);
} else {
$tag = new Profile_list();
if (empty($keys)) {
//if no IDs requested, just return the tag object
return $tag;
}
$pairs = array();
foreach ($keys as $key) {
$pairs[] = '(' . $key[0] . ', "' . $key[1] . '")';
}
$tag->whereAdd('(tagger, tag) in (' . implode(', ', $pairs) . ')');
$tag->find();
$temp = array();
while ($tag->fetch()) {
$temp[$tag->tagger.'-'.$tag->tag] = clone($tag);
}
$wrapped = array();
foreach ($keys as $key) {
$id = $key[0].'-'.$key[1];
if (array_key_exists($id, $temp)) {
$wrapped[] = $temp[$id];
}
}
return new ArrayWrapper($wrapped);
}
}
public function insert()
{
$result = parent::insert();
if ($result) {
self::blow('profile:lists:%d', $this->tagger);
}
return $result;
}
}

View File

@ -1,172 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Data class for Profile preferences
*
* @category Data
* @package GNUsocial
* @author Mikael Nordfeldth <mmn@hethane.se>
* @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
public $profile_id; // int(4) primary_key not_null
public $namespace; // varchar(191) not_null
public $topic; // varchar(191) not_null
public $data; // text
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
public static function schemaDef()
{
return array(
'fields' => array(
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'user'),
'namespace' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'namespace, like pluginname or category'),
'topic' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'preference key, i.e. description, age...'),
'data' => array('type' => 'blob', 'description' => 'topic data, may be anything'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('profile_id', 'namespace', 'topic'),
'foreign keys' => array(
'profile_prefs_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
),
);
}
public static function getNamespacePrefs(Profile $profile, $namespace, array $topic = [])
{
if (empty($topic)) {
$prefs = new Profile_prefs();
$prefs->profile_id = $profile->getID();
$prefs->namespace = $namespace;
$prefs->find();
} else {
$prefs = self::pivotGet('profile_id', $profile->getID(), array('namespace'=>$namespace, 'topic'=>$topic));
}
if (empty($prefs->N)) {
throw new NoResultException($prefs);
}
return $prefs;
}
public static function getNamespace(Profile $profile, $namespace, array $topic = [])
{
$prefs = self::getNamespacePrefs($profile, $namespace, $topic);
return $prefs->fetchAll();
}
public static function getAll(Profile $profile)
{
try {
$prefs = self::listFind('profile_id', array($profile->getID()));
} catch (NoResultException $e) {
return array();
}
$list = array();
while ($prefs->fetch()) {
if (!isset($list[$prefs->namespace])) {
$list[$prefs->namespace] = array();
}
$list[$prefs->namespace][$prefs->topic] = $prefs->data;
}
return $list;
}
public static function getTopic(Profile $profile, $namespace, $topic)
{
return Profile_prefs::getByPK(array('profile_id' => $profile->getID(),
'namespace' => $namespace,
'topic' => $topic));
}
public static function getData(Profile $profile, $namespace, $topic, $def = null)
{
try {
$pref = self::getTopic($profile, $namespace, $topic);
} catch (NoResultException $e) {
if ($def === null) {
// If no default value was set, continue the exception.
throw $e;
}
// If there was a default value, return that.
return $def;
}
return $pref->data;
}
public static function getConfigData(Profile $profile, $namespace, $topic)
{
try {
$data = self::getData($profile, $namespace, $topic);
} catch (NoResultException $e) {
$data = common_config($namespace, $topic);
}
return $data;
}
/*
* Sets a profile preference based on Profile, namespace and topic
*
* @param Profile $profile Which profile this is for
* @param string $namespace Under which namespace (pluginname etc.)
* @param string $topic Preference name (think key in key-val store)
* @param string $data Data to be put into preference storage, null means delete
*
* @return true if changes are made, false if no action taken
* @throws ServerException if preference could not be saved
*/
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 = DB_DataObject_Cast::blob($data);
$pref->update($orig);
}
return true;
} catch (NoResultException $e) {
if (is_null($data)) {
return false; // No action taken
}
}
$pref = new Profile_prefs();
$pref->profile_id = $profile->getID();
$pref->namespace = $namespace;
$pref->topic = $topic;
$pref->data = DB_DataObject_Cast::blob($data);
$pref->created = common_sql_now();
if ($pref->insert() === false) {
throw new ServerException('Could not save profile preference.');
}
return true;
}
}

View File

@ -1,78 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/*
* Table Definition for profile_role
*
* @copyright 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Profile_role extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'profile_role'; // table name
public $profile_id; // int(4) primary_key not_null
public $role; // varchar(32) primary_key not_null
public $created; // datetime()
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'account having the role'),
'role' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'string representing the role'),
'created' => array('type' => 'datetime', 'description' => 'date the role was granted'),
),
'primary key' => array('profile_id', 'role'),
'foreign keys' => array(
'profile_role_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
),
'indexes' => array('profile_role_role_created_profile_id_idx' => array('role', 'created', 'profile_id')),
);
}
const OWNER = 'owner';
const MODERATOR = 'moderator';
const ADMINISTRATOR = 'administrator';
const SANDBOXED = 'sandboxed';
const SILENCED = 'silenced';
const DELETED = 'deleted'; // Pending final deletion of notices...
public static function isValid($role)
{
// @fixme could probably pull this from class constants
$known = array(self::OWNER,
self::MODERATOR,
self::ADMINISTRATOR,
self::SANDBOXED,
self::SILENCED);
return in_array($role, $known);
}
public static function isSettable($role)
{
$allowedRoles = array('administrator', 'moderator');
return self::isValid($role) && in_array($role, $allowedRoles);
}
}

View File

@ -1,363 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
defined('GNUSOCIAL') || die();
/**
* Table Definition for profile_tag
*/
class Profile_tag extends Managed_DataObject
{
public $__table = 'profile_tag'; // table name
public $tagger; // int(4) primary_key not_null
public $tagged; // int(4) primary_key not_null
public $tag; // varchar(64) primary_key not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
public static function schemaDef()
{
return array(
'fields' => array(
'tagger' => array('type' => 'int', 'not null' => true, 'description' => 'user making the tag'),
'tagged' => array('type' => 'int', 'not null' => true, 'description' => 'profile tagged'),
'tag' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date the tag was added'),
),
'primary key' => array('tagger', 'tagged', 'tag'),
'foreign keys' => array(
'profile_tag_tagger_fkey' => array('profile', array('tagger' => 'id')),
'profile_tag_tagged_fkey' => array('profile', array('tagged' => 'id')),
),
'indexes' => array(
'profile_tag_modified_tagged_idx' => array('modified', 'tagged'),
'profile_tag_tagger_tag_idx' => array('tagger', 'tag'),
'profile_tag_tagged_idx' => array('tagged'),
),
);
}
public function links()
{
return array('tagger,tag' => 'profile_list:tagger,tag');
}
public function getMeta()
{
return Profile_list::pkeyGet(array('tagger' => $this->tagger, 'tag' => $this->tag));
}
public static function getSelfTagsArray(Profile $target)
{
return self::getTagsArray($target->getID(), $target->getID(), $target);
}
public static function setSelfTags(Profile $target, array $newtags, array $privacy = [])
{
return self::setTags($target->getID(), $target->getID(), $newtags, $privacy);
}
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;
}
$key = sprintf('profile_tag:tagger_tagged_privacy:%d-%d-%d', $tagger, $tagged, $include_priv);
$tags = Profile_list::getCached($key);
if ($tags !== false) {
return $tags;
}
$qry = 'select profile_list.* from profile_list left join '.
'profile_tag on (profile_list.tag = profile_tag.tag and '.
'profile_list.tagger = profile_tag.tagger) where '.
'profile_tag.tagger = %d and profile_tag.tagged = %d ';
$qry = sprintf($qry, $tagger, $tagged);
if (!$include_priv) {
$qry .= ' AND profile_list.private IS NOT TRUE';
}
$profile_list->query($qry);
Profile_list::setCache($key, $profile_list);
return $profile_list;
}
public static function getTagsArray($tagger, $tagged, Profile $scoped = null)
{
$ptag = new Profile_tag();
$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 IS NOT TRUE';
}
$tags = array();
$ptag->query($qry);
while ($ptag->fetch()) {
$tags[] = $ptag->tag;
}
return $tags;
}
public static function setTags($tagger, $tagged, array $newtags, array $privacy = [])
{
$newtags = array_unique($newtags);
$oldtags = self::getTagsArray($tagger, $tagged, Profile::getByID($tagger));
$ptag = new Profile_tag();
// Delete stuff that's in old and not in new
$to_delete = array_diff($oldtags, $newtags);
// Insert stuff that's in new and not in old
$to_insert = array_diff($newtags, $oldtags);
foreach ($to_delete as $deltag) {
self::unTag($tagger, $tagged, $deltag);
}
foreach ($to_insert as $instag) {
$private = isset($privacy[$instag]) ? $privacy[$instag] : false;
self::setTag($tagger, $tagged, $instag, null, $private);
}
return true;
}
# set a single tag
public static function setTag($tagger, $tagged, $tag, $desc=null, $private = false)
{
$ptag = Profile_tag::pkeyGet(array('tagger' => $tagger,
'tagged' => $tagged,
'tag' => $tag));
# if tag already exists, return it
if ($ptag instanceof Profile_tag) {
return $ptag;
}
$tagger_profile = Profile::getByID($tagger);
$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.'));
}
$tags = new Profile_list();
$tags->tagger = $tagger;
$count = (int) $tags->count('distinct tag');
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')
));
}
$plist = new Profile_list();
$plist->query('START TRANSACTION');
$profile_list = Profile_list::ensureTag($tagger, $tag, $desc, $private);
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
));
}
$newtag = new Profile_tag();
$newtag->tagger = $tagger;
$newtag->tagged = $tagged;
$newtag->tag = $tag;
$result = $newtag->insert();
if (!$result) {
common_log_db_error($newtag, 'INSERT', __FILE__);
$plist->query('ROLLBACK');
return false;
}
try {
$plist->query('COMMIT');
Event::handle('EndTagProfile', array($newtag));
} catch (Exception $e) {
$newtag->delete();
$profile_list->delete();
throw $e;
}
$profile_list->taggedCount(true);
self::blowCaches($tagger, $tagged);
}
return $newtag;
}
public static function unTag($tagger, $tagged, $tag)
{
$ptag = Profile_tag::pkeyGet(array('tagger' => $tagger,
'tagged' => $tagged,
'tag' => $tag));
if (!$ptag) {
return true;
}
if (Event::handle('StartUntagProfile', array($ptag))) {
$orig = clone($ptag);
$result = $ptag->delete();
if ($result === false) {
common_log_db_error($this, 'DELETE', __FILE__);
return false;
}
Event::handle('EndUntagProfile', array($orig));
$profile_list = Profile_list::pkeyGet(array('tag' => $tag, 'tagger' => $tagger));
if (!empty($profile_list)) {
$profile_list->taggedCount(true);
}
self::blowCaches($tagger, $tagged);
return true;
}
}
// @fixme: move this to 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()) {
if (Event::handle('StartUntagProfile', array($ptag))) {
$orig = clone($ptag);
$result = $ptag->delete();
if (!$result) {
common_log_db_error($this, 'DELETE', __FILE__);
}
Event::handle('EndUntagProfile', array($orig));
}
}
}
// move a tag!
public static function moveTag($orig, $new)
{
$tags = new Profile_tag();
$result = $tags->query(sprintf(
<<<'END'
UPDATE profile_tag
SET tag = %1$s, tagger = %2$s, modified = CURRENT_TIMESTAMP
WHERE tag = %3$s AND tagger = %4$s
END,
$tags->_quote($new->tag),
$tags->_quote($new->tagger),
$tags->_quote($orig->tag),
$tags->_quote($orig->tagger)
));
if ($result === false) {
common_log_db_error($tags, 'UPDATE', __FILE__);
throw new Exception('Could not move Profile_tag, see db log for details.');
}
return $result;
}
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));
}
return true;
}
// Return profiles with a given 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 = [];
while ($profile->fetch()) {
$tagged[] = clone($profile);
}
return true;
}
public function insert()
{
$result = parent::insert();
if ($result) {
self::blow(
'profile_list:tagged_count:%d:%s',
$this->tagger,
$this->tag
);
}
return $result;
}
public function delete($useWhere = false)
{
$result = parent::delete($useWhere);
if ($result !== false) {
self::blow(
'profile_list:tagged_count:%d:%s',
$this->tagger,
$this->tag
);
}
return $result;
}
}

View File

@ -1,158 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for profile_tag_subscription
*/
defined('GNUSOCIAL') || die();
class Profile_tag_subscription extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'profile_tag_subscription'; // table name
public $profile_tag_id; // int(4) not_null
public $profile_id; // int(4) not_null
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'profile_tag_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile_tag'),
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('profile_tag_id', 'profile_id'),
'foreign keys' => array(
'profile_tag_subscription_profile_tag_id_fkey' => array('profile_list', array('profile_tag_id' => 'id')),
'profile_tag_subscription_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
),
'indexes' => array(
'profile_tag_subscription_profile_id_created_profile_tag_id_idx' => array('profile_id', 'created', 'profile_tag_id'),
),
);
}
public static function add($peopletag, $profile)
{
if ($peopletag->private) {
return false;
}
if (Event::handle('StartSubscribePeopletag', array($peopletag, $profile))) {
$args = array('profile_tag_id' => $peopletag->id,
'profile_id' => $profile->id);
$existing = Profile_tag_subscription::pkeyGet($args);
if (!empty($existing)) {
return $existing;
}
$sub = new Profile_tag_subscription();
$sub->profile_tag_id = $peopletag->id;
$sub->profile_id = $profile->id;
$sub->created = common_sql_now();
$result = $sub->insert();
if (!$result) {
common_log_db_error($sub, 'INSERT', __FILE__);
// TRANS: Exception thrown when inserting a list subscription in the database fails.
throw new Exception(_('Adding list subscription failed.'));
}
$ptag = Profile_list::getKV('id', $peopletag->id);
$ptag->subscriberCount(true);
Event::handle('EndSubscribePeopletag', array($peopletag, $profile));
return $ptag;
}
}
public static function remove($peopletag, $profile)
{
$sub = Profile_tag_subscription::pkeyGet(array('profile_tag_id' => $peopletag->id,
'profile_id' => $profile->id));
if (empty($sub)) {
// silence is golden?
return true;
}
if (Event::handle('StartUnsubscribePeopletag', array($peopletag, $profile))) {
$result = $sub->delete();
if (!$result) {
common_log_db_error($sub, 'DELETE', __FILE__);
// TRANS: Exception thrown when deleting a list subscription from the database fails.
throw new Exception(_('Removing list subscription failed.'));
}
$peopletag->subscriberCount(true);
Event::handle('EndUnsubscribePeopletag', array($peopletag, $profile));
return true;
}
}
// called if a tag gets deleted / made private
public static function cleanup($profile_list)
{
$subs = new self();
$subs->profile_tag_id = $profile_list->id;
$subs->find();
while ($subs->fetch()) {
$profile = Profile::getKV('id', $subs->profile_id);
Event::handle('StartUnsubscribePeopletag', array($profile_list, $profile));
// Delete anyway
$subs->delete();
Event::handle('StartUnsubscribePeopletag', array($profile_list, $profile));
}
}
public function insert()
{
$result = parent::insert();
if ($result) {
self::blow(
'profile_list:subscriber_count:%d',
$this->profile_tag_id
);
}
return $result;
}
public function delete($useWhere = false)
{
$result = parent::delete($useWhere);
if ($result !== false) {
self::blow(
'profile_list:subscriber_count:%d',
$this->profile_tag_id
);
}
return $result;
}
}

59
src/Entity/QueueItem.php Normal file
View File

@ -0,0 +1,59 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for a Queue Item
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class QueueItem
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'queue_item',
'fields' => [
'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'],
'frame' => ['type' => 'blob', 'not null' => true, 'description' => 'data: object reference or opaque string'],
'transport' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'queue for what? "email", "xmpp", "sms", "irc", ...'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'claimed' => ['type' => 'datetime', 'description' => 'date this item was claimed'],
],
'primary key' => ['id'],
'indexes' => [
'queue_item_created_idx' => ['created'],
],
];
}
}

View File

@ -1,122 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for queue_item
*/
defined('GNUSOCIAL') || die();
class Queue_item extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'queue_item'; // table name
public $id; // int(4) primary_key not_null
public $frame; // blob not_null
public $transport; // varchar(32)
public $created; // datetime()
public $claimed; // datetime()
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
'frame' => array('type' => 'blob', 'not null' => true, 'description' => 'data: object reference or opaque string'),
'transport' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'queue for what? "email", "xmpp", "sms", "irc", ...'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'claimed' => array('type' => 'datetime', 'description' => 'date this item was claimed'),
),
'primary key' => array('id'),
'indexes' => array(
'queue_item_created_id_idx' => array('created', 'id'),
),
);
}
/**
* @param mixed $transports name of a single queue or array of queues to pull from
* If not specified, checks all queues in the system.
*/
public static function top($transports = null, array $ignored_transports = [])
{
$qi = new Queue_item();
if ($transports) {
if (is_array($transports)) {
$qi->whereAddIn(
'transport',
$transports,
$qi->columnType('transport')
);
} else {
$qi->transport = $transports;
}
}
if (!empty($ignored_transports)) {
$qi->whereAddIn(
'!transport',
$ignored_transports,
$qi->columnType('transport')
);
}
$qi->whereAdd('claimed IS NULL');
$qi->orderBy('created, id');
$qi->limit(1);
$cnt = $qi->find(true);
if ($cnt) {
// XXX: potential race condition
// can we force it to only update if claimed is still null
// (or old)?
common_log(LOG_INFO, 'claiming queue item id = ' . $qi->getID() . ' for transport ' . $qi->transport);
$orig = clone($qi);
$qi->claimed = common_sql_now();
$result = $qi->update($orig);
if ($result) {
common_log(LOG_DEBUG, 'claim succeeded.');
return $qi;
} else {
common_log(LOG_ERR, 'claim of queue item id= ' . $qi->getID() . ' for transport ' . $qi->transport . ' failed.');
}
}
unset($qi);
return null;
}
/**
* Release a claimed item.
*/
public function releaseClaim()
{
// @fixme Consider $this->sqlValue('NULL')
$ret = $this->query(sprintf(
'UPDATE queue_item SET claimed = NULL WHERE id = %d',
$this->getID()
));
if ($ret) {
$this->claimed = null;
$this->encache();
}
}
}

View File

@ -0,0 +1,59 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for related groups
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class RelatedGroup
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'related_group',
// @fixme description for related_group?
'fields' => [
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'],
'related_group_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
],
'primary key' => ['group_id', 'related_group_id'],
'foreign keys' => [
'related_group_group_id_fkey' => ['user_group', ['group_id' => 'id']],
'related_group_related_group_id_fkey' => ['user_group', ['related_group_id' => 'id']],
],
];
}
}

View File

@ -1,55 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for related_group
*/
defined('GNUSOCIAL') || die();
class Related_group extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'related_group'; // table name
public $group_id; // int(4) primary_key not_null
public $related_group_id; // int(4) primary_key not_null
public $created; // datetime()
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
// @fixme description for related_group?
'fields' => array(
'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'),
'related_group_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
),
'primary key' => array('group_id', 'related_group_id'),
'foreign keys' => array(
'related_group_group_id_fkey' => array('user_group', array('group_id' => 'id')),
'related_group_related_group_id_fkey' => array('user_group', array('related_group_id' => 'id')),
),
'indexes' => array(
'related_group_related_group_id_idx' => array('related_group_id'),
),
);
}
}

57
src/Entity/RememberMe.php Normal file
View File

@ -0,0 +1,57 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for user remember me
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class RememberMe
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'remember_me',
'fields' => [
'code' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'good random code'],
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'user who is logged in'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['code'],
'foreign keys' => [
'remember_me_user_id_fkey' => ['user', ['user_id' => 'id']],
],
];
}
}

View File

@ -1,53 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for remember_me
*/
defined('GNUSOCIAL') || die();
class Remember_me extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'remember_me'; // table name
public $code; // varchar(32) primary_key not_null
public $user_id; // int(4) not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'fields' => array(
'code' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'good random code'),
'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user who is logged in'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('code'),
'foreign keys' => array(
'remember_me_user_id_fkey' => array('user', array('user_id' => 'id')),
),
'indexes' => array(
'remember_me_user_id_idx' => array('user_id'),
),
);
}
}

View File

@ -1,85 +1,65 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Table Definition for reply
* Entity for Notice reply
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 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 Reply extends Managed_DataObject
class Reply
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
// AUTOCODE BEGIN
public $__table = 'reply'; // table name
public $notice_id; // int(4) primary_key not_null
public $profile_id; // int(4) primary_key not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
public $replied_id; // int(4)
// AUTOCODE END
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
public static function schemaDef(): array
{
return array(
'fields' => array(
'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice that is the reply'),
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'profile replied to'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
'replied_id' => array('type' => 'int', 'description' => 'notice replied to (not used, see notice.reply_to)'),
),
'primary key' => array('notice_id', 'profile_id'),
'foreign keys' => array(
'reply_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
'reply_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
),
'indexes' => array(
'reply_profile_id_idx' => array('profile_id'),
'reply_replied_id_idx' => array('replied_id'),
'reply_profile_id_modified_notice_id_idx' => array('profile_id', 'modified', 'notice_id')
),
);
}
/**
* Wrapper for record insertion to update related caches
*/
public function insert()
{
$result = parent::insert();
if ($result) {
self::blow('reply:stream:%d', $this->profile_id);
}
return $result;
}
public static function stream(
$user_id,
$offset = 0,
$limit = NOTICES_PER_PAGE,
$since_id = 0,
$max_id = 0
) {
// FIXME: Use some other method to get Profile::current() in order
// to avoid confusion between background processing and session user.
$stream = new ReplyNoticeStream($user_id, Profile::current());
return $stream->getNotices($offset, $limit, $since_id, $max_id);
return [
'name' => 'reply',
'fields' => [
'notice_id' => ['type' => 'int', 'not null' => true, 'description' => 'notice that is the reply'],
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'profile replied to'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
'replied_id' => ['type' => 'int', 'description' => 'notice replied to (not used, see notice.reply_to)'],
],
'primary key' => ['notice_id', 'profile_id'],
'foreign keys' => [
'reply_notice_id_fkey' => ['notice', ['notice_id' => 'id']],
'reply_profile_id_fkey' => ['profile', ['profile_id' => 'id']],
],
'indexes' => [
'reply_notice_id_idx' => ['notice_id'],
'reply_profile_id_idx' => ['profile_id'],
'reply_replied_id_idx' => ['replied_id'],
'reply_profile_id_modified_notice_id_idx' => ['profile_id', 'modified', 'notice_id'],
],
];
}
}

View File

@ -1,309 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/*
* @copyright 2010 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
/**
* Extended DB_DataObject to improve a few things:
* - free global resources from destructor
* - remove bogus global references from serialized objects
* - don't leak memory when loading already-used .ini files
* (eg when using the same schema on thousands of databases)
*/
class Safe_DataObject extends GS_DataObject
{
/**
* Destructor to free global memory resources associated with
* this data object when it's unset or goes out of scope.
* DB_DataObject doesn't do this yet by itself.
*/
public function __destruct()
{
$this->free();
if (method_exists('DB_DataObject', '__destruct')) {
parent::__destruct();
}
}
/**
* Magic function called at clone() time.
*
* We use this to drop connection with some global resources.
* This supports the fairly common pattern where individual
* items being read in a loop via a single object are cloned
* for individual processing, then fall out of scope when the
* loop comes around again.
*
* As that triggers the destructor, we want to make sure that
* the original object doesn't have its database result killed.
* It will still be freed properly when the original object
* gets destroyed.
*/
public function __clone()
{
$this->_DB_resultid = false;
}
/**
* Magic function called at serialize() time.
*
* We use this to drop a couple process-specific references
* from DB_DataObject which can cause trouble in future
* processes.
*
* @return array of variable names to include in serialization.
*/
public function __sleep()
{
$vars = array_keys(get_object_vars($this));
$skip = array('_DB_resultid', '_link_loaded');
return array_diff($vars, $skip);
}
/**
* Magic function called at unserialize() time.
*
* Clean out some process-specific variables which might
* be floating around from a previous process's cached
* objects.
*
* Old cached objects may still have them.
*/
public function __wakeup()
{
// Refers to global state info from a previous process.
// Clear this out so we don't accidentally break global
// state in *this* process.
$this->_DB_resultid = null;
// We don't have any local DBO refs, so clear these out.
$this->_link_loaded = false;
}
/**
* Magic function called when someone attempts to call a method
* that doesn't exist. DB_DataObject uses this to implement
* setters and getters for fields, but neglects to throw an error
* when you just misspell an actual method name. This leads to
* silent failures which can cause all kinds of havoc.
*
* @param string $method
* @param array $params
* @return mixed
* @throws Exception
*/
public function __call($method, $params)
{
$return = null;
// Yes, that's _call with one underscore, which does the
// actual implementation.
if ($this->_call($method, $params, $return)) {
return $return;
} else {
// Low level exception. No need for i18n as discussed with Brion.
throw new Exception('Call to undefined method ' .
get_class($this) . '::' . $method);
}
}
/**
* Work around memory-leak bugs...
* Had to copy-paste the whole function in order to patch a couple lines of it.
* Would be nice if this code was better factored.
*
* @param optional string name of database to assign / read
* @param optional array structure of database, and keys
* @param optional array table links
*
* @access public
* @return true or PEAR:error on wrong paramenters.. or false if no file exists..
* or the array(tablename => array(column_name=>type)) if called with 1 argument.. (databasename)
*/
public function databaseStructure()
{
global $_DB_DATAOBJECT;
if (!empty($args = func_get_args())) {
if (count($args) == 1) {
// this returns all the tables and their structure..
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug(
'Loading Generator as databaseStructure called with args',
1
);
}
$x = new DB_DataObject;
$x->_database = $args[0];
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$tables = $DB->getListOf('tables');
class_exists('DB_DataObject_Generator') ? '' :
require_once 'DB/DataObject/Generator.php';
foreach ($tables as $table) {
$y = new DB_DataObject_Generator;
$y->fillTableSchema($x->_database, $table);
}
return $_DB_DATAOBJECT['INI'][$x->_database];
} else {
$_DB_DATAOBJECT['INI'][$args[0]] = isset($_DB_DATAOBJECT['INI'][$args[0]]) ?
$_DB_DATAOBJECT['INI'][$args[0]] + $args[1] : $args[1];
if (isset($args[1])) {
$_DB_DATAOBJECT['LINKS'][$args[0]] = isset($_DB_DATAOBJECT['LINKS'][$args[0]]) ?
$_DB_DATAOBJECT['LINKS'][$args[0]] + $args[2] : $args[2];
}
return true;
}
}
if (!$this->_database) {
$this->_connect();
}
// loaded already?
if (!empty($_DB_DATAOBJECT['INI'][$this->_database])) {
// database loaded - but this is table is not available..
if (
empty($_DB_DATAOBJECT['INI'][$this->_database][$this->tableName()])
&& !empty($_DB_DATAOBJECT['CONFIG']['proxy'])
) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug('Loading Generator to fetch Schema', 1);
}
class_exists('DB_DataObject_Generator') ? '' :
require_once 'DB/DataObject/Generator.php';
$x = new DB_DataObject_Generator;
$x->fillTableSchema($this->_database, $this->tableName());
}
return true;
}
if (empty($_DB_DATAOBJECT['CONFIG'])) {
self::_loadConfig();
}
// if you supply this with arguments, then it will take those
// as the database and links array...
$schemas = isset($_DB_DATAOBJECT['CONFIG']['schema_location']) ?
array("{$_DB_DATAOBJECT['CONFIG']['schema_location']}/{$this->_database}.ini") :
array() ;
if (isset($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"])) {
$schemas = is_array($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]) ?
$_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"] :
explode(PATH_SEPARATOR, $_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]);
}
/* BEGIN CHANGED FROM UPSTREAM */
$_DB_DATAOBJECT['INI'][$this->_database] = $this->parseIniFiles($schemas);
/* END CHANGED FROM UPSTREAM */
// now have we loaded the structure..
if (!empty($_DB_DATAOBJECT['INI'][$this->_database][$this->tableName()])) {
return true;
}
// - if not try building it..
if (!empty($_DB_DATAOBJECT['CONFIG']['proxy'])) {
class_exists('DB_DataObject_Generator') ? '' :
require_once 'DB/DataObject/Generator.php';
$x = new DB_DataObject_Generator;
$x->fillTableSchema($this->_database, $this->tableName());
// should this fail!!!???
return true;
}
$this->debug(
"Can't find database schema: {$this->_database}/{$this->tableName()}\n"
. 'in links file data: '
. print_r($_DB_DATAOBJECT['INI'], true),
'databaseStructure',
5
);
// we have to die here!! - it causes chaos if we don't (including looping forever!)
// Low level exception. No need for i18n as discussed with Brion.
$this->raiseError(
'Unable to load schema for database and table '
. '(turn debugging up to 5 for full error message)',
DB_DATAOBJECT_ERROR_INVALIDARGS,
PEAR_ERROR_DIE
);
return false;
}
/** For parseIniFiles */
protected static $iniCache = array();
/**
* When switching site configurations, DB_DataObject was loading its
* .ini files over and over, leaking gobs of memory.
* This refactored helper function uses a local cache of .ini files
* to minimize the leaks.
*
* @param array of .ini file names $schemas
* @return array
*/
protected function parseIniFiles(array $schemas)
{
$key = implode("|", $schemas);
if (!isset(Safe_DataObject::$iniCache[$key])) {
$data = array();
foreach ($schemas as $ini) {
if (file_exists($ini) && is_file($ini)) {
$data = array_merge($data, parse_ini_file($ini, true));
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
if (!is_readable($ini)) {
$this->debug(
"ini file is not readable: {$ini}",
'databaseStructure',
1
);
} else {
$this->debug(
"Loaded ini file: {$ini}",
'databaseStructure',
1
);
}
}
} else {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug(
"Missing ini file: {$ini}",
'databaseStructure',
1
);
}
}
}
Safe_DataObject::$iniCache[$key] = $data;
}
return Safe_DataObject::$iniCache[$key];
}
}

View File

@ -0,0 +1,55 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for the Schema Version
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class SchemaVersion
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'schema_version',
'description' => 'To avoid checking database structure all the time, we store a checksum of the expected schema info for each table here. If it has not changed since the last time we checked the table, we can leave it as is.',
'fields' => [
'table_name' => ['type' => 'varchar', 'length' => '64', 'not null' => true, 'description' => 'Table name'],
'checksum' => ['type' => 'varchar', 'length' => '64', 'not null' => true, 'description' => 'Checksum of schema array; a mismatch indicates we should check the table more thoroughly.'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['table_name'],
];
}
}

View File

@ -1,48 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for schema_version
*/
defined('GNUSOCIAL') || die();
class Schema_version extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'schema_version'; // table name
public $table_name; // varchar(64) primary_key not_null
public $checksum; // varchar(128) not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
{
return array(
'description' => 'To avoid checking database structure all the time, we store a checksum of the expected schema info for each table here. If it has not changed since the last time we checked the table, we can leave it as is.',
'fields' => array(
'table_name' => array('type' => 'varchar', 'length' => '64', 'not null' => true, 'description' => 'Table name'),
'checksum' => array('type' => 'varchar', 'length' => '128', 'not null' => true, 'description' => 'Checksum of schema array; a mismatch indicates we should check the table more thoroughly.'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('table_name'),
);
}
}

View File

@ -1,84 +1,59 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Table Definition for session
* Entity for Superclass representing a saved session as it exists in the database.
*
* @category DB
* @package GNUsocial
* @author Evan Prodromou
* @author Brion Vibber
* @author Mikael Nordfeldth
* @author Sorokin Alexei
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
/**
* Superclass representing a saved session as it exists in the database.
*
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class Session extends Managed_DataObject
class Session
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
// AUTOCODE BEGIN
public $__table = 'session'; // table name
public $id; // varchar(32) primary_key not_null
public $session_data; // text()
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
// AUTOCODE END
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
/**
* Returns an array describing how the session is stored in the database.
*
* @return array
*/
public static function schemaDef()
public static function schemaDef(): array
{
return [
'fields' => [
'id' => ['type' => 'varchar', 'length' => 128, 'not null' => true, 'description' => 'session ID'],
'id' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'session ID'],
'session_data' => ['type' => 'text', 'description' => 'session data'],
'created' => ['type' => 'datetime', 'description' => 'date this record was created'],
'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['id'],
'indexes' => [
'indexes' => [
'session_modified_idx' => ['modified'],
],
];
}
/**
* New code should NOT call this function.
* Dummy function for backwards compatibility with older plugins like Qvitter.
* Stuff to do before the request teardown.
*
* @return void
*/
public static function cleanup()
{
session_write_close();
}
}

59
src/Entity/SmsCarrier.php Normal file
View File

@ -0,0 +1,59 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for SMS carriers
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class SmsCarrier
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'sms_carrier',
'fields' => [
'id' => ['type' => 'int', 'not null' => true, 'description' => 'primary key for SMS carrier'],
'name' => ['type' => 'varchar', 'length' => 64, 'description' => 'name of the carrier'],
'email_pattern' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'sprintf pattern for making an email address from a phone number'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['id'],
'unique keys' => [
'sms_carrier_name_key' => ['name'],
],
];
}
}

View File

@ -1,59 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for sms_carrier
*/
defined('GNUSOCIAL') || die();
class Sms_carrier extends Managed_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'sms_carrier'; // table name
public $id; // int(4) primary_key not_null
public $name; // varchar(64) unique_key
public $email_pattern; // varchar(191) not_null not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public function toEmailAddress($sms)
{
return sprintf($this->email_pattern, $sms);
}
public static function schemaDef()
{
return array(
'fields' => array(
'id' => array('type' => 'int', 'not null' => true, 'description' => 'primary key for SMS carrier'),
'name' => array('type' => 'varchar', 'length' => 64, 'description' => 'name of the carrier'),
'email_pattern' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'sprintf pattern for making an email address from a phone number'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('id'),
'unique keys' => array(
'sms_carrier_name_key' => array('name'),
),
);
}
}

View File

@ -1,388 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for status_network
*
* @copyright 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
class Status_network extends Safe_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'status_network'; // table name
public $site_id; // int(4) primary_key not_null
public $nickname; // varchar(64) unique_key not_null
public $hostname; // varchar(191) unique_key not 255 because utf8mb4 takes more space
public $pathname; // varchar(191) unique_key not 255 because utf8mb4 takes more space
public $dbhost; // varchar(191) not 255 because utf8mb4 takes more space
public $dbuser; // varchar(191) not 255 because utf8mb4 takes more space
public $dbpass; // varchar(191) not 255 because utf8mb4 takes more space
public $dbname; // varchar(191) not 255 because utf8mb4 takes more space
public $sitename; // varchar(191) not 255 because utf8mb4 takes more space
public $theme; // varchar(191) not 255 because utf8mb4 takes more space
public $logo; // varchar(191) not 255 because utf8mb4 takes more space
public $created; // datetime() not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */
public static function getKV($k, $v = null)
{
// TODO: This must probably be turned into a non-static call
$i = DB_DataObject::staticGet('Status_network', $k, $v);
// Don't use local process cache; if we're fetching multiple
// times it's because we're reloading it in a long-running
// process; we need a fresh copy!
global $_DB_DATAOBJECT;
unset($_DB_DATAOBJECT['CACHE']['status_network']);
return $i;
}
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
// XXX: made public so Status_network_tag can eff with it
public static $cache = null;
public static $cacheInitialized = false;
public static $base = null;
public static $wildcard = null;
/**
* @param string $dbhost
* @param string $dbuser
* @param string $dbpass
* @param string $dbname
* @param array $servers memcached servers to use for caching config info
*/
public static function setupDB(
$dbhost,
$dbuser,
$dbpass,
$dbname,
array $servers
) {
global $config;
$config['db']['database_'.$dbname] = "mysqli://$dbuser:$dbpass@$dbhost/$dbname";
$config['db']['ini_'.$dbname] = INSTALLDIR.'/classes/status_network.ini';
foreach (array('status_network', 'status_network_tag', 'unavailable_status_network') as $table) {
$config['db']['table_'.$table] = $dbname;
}
if (class_exists('Memcache')) {
self::$cache = new Memcache();
// If we're a parent command-line process we need
// to be able to close out the connection after
// forking, so disable persistence.
//
// We'll turn it back on again the second time
// through which will either be in a child process,
// or a single-process script which is switching
// configurations.
$persist = php_sapi_name() != 'cli' || self::$cacheInitialized;
if (!is_array($servers)) {
$servers = array($servers);
}
foreach ($servers as $server) {
$parts = explode(':', $server);
$server = $parts[0];
if (count($parts) > 1) {
$port = $parts[1];
} else {
$port = 11211;
}
self::$cache->addServer($server, $port, $persist);
}
self::$cacheInitialized = true;
}
self::$base = $dbname;
}
public static function cacheKey($k, $v)
{
return 'gnusocial:' . self::$base . ':status_network:'.$k.':'.$v;
}
public static function memGet($k, $v)
{
if (!self::$cache) {
return self::getKV($k, $v);
}
$ck = self::cacheKey($k, $v);
$sn = self::$cache->get($ck);
if (empty($sn)) {
$sn = self::getKV($k, $v);
if (!empty($sn)) {
self::$cache->set($ck, clone($sn));
}
}
return $sn;
}
public function decache()
{
if (self::$cache) {
$keys = array('nickname', 'hostname', 'pathname');
foreach ($keys as $k) {
$ck = self::cacheKey($k, $this->$k);
self::$cache->delete($ck);
}
}
}
public function update($dataObject = false)
{
if (is_object($dataObject)) {
// might be different keys
$dataObject->decache();
}
return parent::update($dataObject);
}
/**
* DB_DataObject doesn't allow updating keys (even non-primary)
*/
public function updateKeys(&$orig)
{
$this->_connect();
foreach (array('hostname', 'pathname') as $k) {
if (strcmp($this->$k, $orig->$k) != 0) {
$parts[] = $k . ' = ' . $this->_quote($this->$k);
}
}
if (count($parts) == 0) {
// No changes
return true;
}
$toupdate = implode(', ', $parts);
$table = common_database_tablename($this->tableName());
$qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
' WHERE nickname = ' . $this->_quote($this->nickname);
$orig->decache();
$result = $this->query($qry);
$this->decache();
return $result;
}
public function delete($useWhere = false)
{
// while we still have the values!
$this->decache();
return parent::delete($useWhere);
}
/**
* @param string $servername hostname
* @param string $wildcard hostname suffix to match wildcard config
* @return mixed Status_network or null
*/
public static function getFromHostname($servername, $wildcard)
{
$sn = null;
if (0 == strncasecmp(strrev($wildcard), strrev($servername), strlen($wildcard))) {
// special case for exact match
if (0 == strcasecmp($servername, $wildcard)) {
$sn = self::memGet('nickname', '');
} else {
$parts = explode('.', $servername);
$sn = self::memGet('nickname', strtolower($parts[0]));
}
} else {
$sn = self::memGet('hostname', strtolower($servername));
if (empty($sn)) {
// Try for a no-www address
if (0 == strncasecmp($servername, 'www.', 4)) {
$sn = self::memGet('hostname', strtolower(substr($servername, 4)));
}
}
}
return $sn;
}
/**
* @param string $servername hostname
* @param string $pathname URL base path
* @param string $wildcard hostname suffix to match wildcard config
*/
public static function setupSite($servername, $pathname, $wildcard)
{
global $config;
$sn = null;
// XXX I18N, probably not crucial for hostnames
// XXX This probably needs a tune up
$sn = self::getFromHostname($servername, $wildcard);
if (!empty($sn)) {
// Redirect to the right URL
if (!empty($sn->hostname) &&
empty($_SERVER['HTTPS']) &&
0 != strcasecmp($sn->hostname, $servername)) {
$sn->redirectTo('http://'.$sn->hostname.$_SERVER['REQUEST_URI']);
} elseif (
!empty($_SERVER['HTTPS'])
&& strcasecmp($sn->hostname, $servername) !== 0
&& strcasecmp($sn->nickname . '.' . $wildcard, $servername) !== 0
) {
$sn->redirectTo(
"https://{$sn->nickname}.{$wildcard}{$_SERVER['REQUEST_URI']}"
);
}
$dbhost = (empty($sn->dbhost)) ? 'localhost' : $sn->dbhost;
$dbuser = (empty($sn->dbuser)) ? $sn->nickname : $sn->dbuser;
$dbpass = $sn->dbpass;
$dbname = (empty($sn->dbname)) ? $sn->nickname : $sn->dbname;
$config['db']['database'] = "mysqli://$dbuser:$dbpass@$dbhost/$dbname";
$config['site']['name'] = $sn->sitename;
$config['site']['nickname'] = $sn->nickname;
self::$wildcard = $wildcard;
$config['site']['wildcard'] =& self::$wildcard;
if (!empty($sn->hostname)) {
$config['site']['server'] = $sn->hostname;
}
if (!empty($sn->theme)) {
$config['site']['theme'] = $sn->theme;
}
if (!empty($sn->logo)) {
$config['site']['logo'] = $sn->logo;
}
return $sn;
} else {
return null;
}
}
// Code partially mooked from http://www.richler.de/en/php-redirect/
// (C) 2006 by Heiko Richler http://www.richler.de/
// LGPL
public function redirectTo($destination)
{
$old = 'http'.
(($_SERVER['HTTPS'] == 'on') ? 'S' : '').
'://'.
$_SERVER['HTTP_HOST'].
$_SERVER['REQUEST_URI'].
$_SERVER['QUERY_STRING'];
if ($old == $destination) { // this would be a loop!
// error_log(...) ?
return false;
}
http_response_code(301);
header("Location: {$destination}");
echo "<a href='{$destination}'>{$destination}</a>\n";
exit;
}
public function getServerName()
{
if (!empty($this->hostname)) {
return $this->hostname;
} else {
return $this->nickname . '.' . self::$wildcard;
}
}
/**
* Return site meta-info tags as an array
* @return array of strings
*/
public function getTags()
{
return Status_network_tag::getTags($this->site_id);
}
/**
* Save a given set of tags
* @param array tags
* @fixme only add/remove differentials
*/
public function setTags(array $tags)
{
$this->clearTags();
foreach ($tags as $tag) {
if (!empty($tag)) {
$snt = new Status_network_tag();
$snt->site_id = $this->site_id;
$snt->tag = $tag;
$snt->created = common_sql_now();
$id = $snt->insert();
if (!$id) {
// TRANS: Exception thrown when a tag cannot be saved.
throw new Exception(_("Unable to save tag."));
}
}
}
return true;
}
public function clearTags()
{
$tag = new Status_network_tag();
$tag->site_id = $this->site_id;
if ($tag->find()) {
while ($tag->fetch()) {
$tag->delete();
}
}
$tag->free();
}
/**
* Check if this site record has a particular meta-info tag attached.
* @param string $tag
* @return bool
*/
public function hasTag($tag)
{
return in_array($tag, $this->getTags());
}
}

View File

@ -1,144 +0,0 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, 2010 StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('STATUSNET')) { exit(1); }
class Status_network_tag extends Safe_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'status_network_tag'; // table name
public $site_id; // int(4) primary_key not_null
public $tag; // varchar(64) primary_key not_null
public $created; // datetime() not_null default_0000-00-00%2000%3A00%3A00
function __construct()
{
global $config;
global $_DB_DATAOBJECT;
$sn = new Status_network();
$sn->_connect();
$config['db']['table_'. $this->tableName()] = $sn->_database;
$this->_connect();
}
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
/* Static get */
static function getKV($k,$v=null)
{
// TODO: This probably has to be converted to a non-static call
$i = DB_DataObject::staticGet('Status_network_tag',$k,$v);
// Don't use local process cache; if we're fetching multiple
// times it's because we're reloading it in a long-running
// process; we need a fresh copy!
global $_DB_DATAOBJECT;
unset($_DB_DATAOBJECT['CACHE']['status_network_tag']);
return $i;
}
static function pkeyGet($kv)
{
return Memcached_DataObject::pkeyGetClass('Status_network_tag', $kv);
}
/**
* Fetch the (possibly cached) tag entries for the given site id.
* Uses status_network's cache settings.
*
* @param string $site_id
* @return array of strings
*/
static function getTags($site_id)
{
$key = 'status_network_tags:' . $site_id;
if (Status_network::$cache) {
$packed = Status_network::$cache->get($key);
if (is_string($packed)) {
if ($packed == '') {
return array();
} else {
return explode('|', $packed);
}
}
}
$result = array();
$tags = new Status_network_tag();
$tags->site_id = $site_id;
if ($tags->find()) {
while ($tags->fetch()) {
$result[] = $tags->tag;
}
}
if (Status_network::$cache) {
$packed = implode('|', $result);
Status_network::$cache->set($key, $packed, 0, 3600);
}
return $result;
}
/**
* Drop the cached tag entries for this site.
* Needed after inserting/deleting a tag entry.
*/
function decache()
{
$key = 'status_network_tags:' . $this->site_id;
if (Status_network::$cache || Status_network::$cacheInitialized) {
// FIXME: this was causing errors, so I'm hiding them.
// I'm a big chicken and lazy.
@Status_network::$cache->delete($key);
}
}
function insert()
{
$ret = parent::insert();
$this->decache();
return $ret;
}
function delete($useWhere=false)
{
$this->decache();
return parent::delete($useWhere);
}
static function withTag($tag)
{
$snt = new Status_network_tag();
$snt->tag = $tag;
$snt->find();
return $snt;
}
}

View File

@ -1,31 +1,41 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* @copyright 2008, 2009 StatusNet, Inc.
* Entity for subscription
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
/**
* Table Definition for subscription
*/
class Subscription extends Managed_DataObject
class Subscription
{
<<<<<<< HEAD
const CACHE_WINDOW = 201;
const FORCE = true;
@ -446,5 +456,36 @@ class Subscription extends Managed_DataObject
public function getUri()
{
return $this->uri ?: self::newUri($this->getSubscriber(), $this->getSubscribed(), $this->created);
=======
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'subscription',
'fields' => [
'subscriber' => ['type' => 'int', 'not null' => true, 'description' => 'profile listening'],
'subscribed' => ['type' => 'int', 'not null' => true, 'description' => 'profile being listened to'],
'jabber' => ['type' => 'bool', 'default' => true, 'description' => 'deliver jabber messages'],
'sms' => ['type' => 'bool', 'default' => true, 'description' => 'deliver sms messages'],
'token' => ['type' => 'varchar', 'length' => 191, 'description' => 'authorization token'],
'secret' => ['type' => 'varchar', 'length' => 191, 'description' => 'token secret'],
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universally unique identifier'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['subscriber', 'subscribed'],
'unique keys' => [
'subscription_uri_key' => ['uri'],
],
'indexes' => [
'subscription_subscriber_idx' => ['subscriber', 'created'],
'subscription_subscribed_idx' => ['subscribed', 'created'],
'subscription_token_idx' => ['token'],
],
];
>>>>>>> e4b74a6aaf ([DATABASE] Extracted schemaDef method from old files and refactored onto new files)
}
}

View File

@ -0,0 +1,63 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for Subscription queue
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class SubscriptionQueue
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'subscription_queue',
'description' => 'Holder for subscription requests awaiting moderation.',
'fields' => [
'subscriber' => ['type' => 'int', 'not null' => true, 'description' => 'remote or local profile making the request'],
'subscribed' => ['type' => 'int', 'not null' => true, 'description' => 'remote or local profile being subscribed to'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
],
'primary key' => ['subscriber', 'subscribed'],
'indexes' => [
'subscription_queue_subscriber_created_idx' => ['subscriber', 'created'],
'subscription_queue_subscribed_created_idx' => ['subscribed', 'created'],
],
'foreign keys' => [
'subscription_queue_subscriber_fkey' => ['profile', ['subscriber' => 'id']],
'subscription_queue_subscribed_fkey' => ['profile', ['subscribed' => 'id']],
],
];
}
}

View File

@ -1,124 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for subscription_queue
*/
defined('GNUSOCIAL') || die();
class Subscription_queue extends Managed_DataObject
{
public $__table = 'subscription_queue'; // table name
public $subscriber;
public $subscribed;
public $created;
public static function schemaDef()
{
return array(
'description' => 'Holder for subscription requests awaiting moderation.',
'fields' => array(
'subscriber' => array('type' => 'int', 'not null' => true, 'description' => 'remote or local profile making the request'),
'subscribed' => array('type' => 'int', 'not null' => true, 'description' => 'remote or local profile being subscribed to'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
),
'primary key' => array('subscriber', 'subscribed'),
'indexes' => array(
'subscription_queue_subscriber_created_idx' => array('subscriber', 'created'),
'subscription_queue_subscribed_created_idx' => array('subscribed', 'created'),
),
'foreign keys' => array(
'subscription_queue_subscriber_fkey' => array('profile', array('subscriber' => 'id')),
'subscription_queue_subscribed_fkey' => array('profile', array('subscribed' => 'id')),
)
);
}
public static function saveNew(Profile $subscriber, Profile $subscribed)
{
if (self::exists($subscriber, $subscribed)) {
throw new AlreadyFulfilledException(_('This subscription request is already in progress.'));
}
$rq = new Subscription_queue();
$rq->subscriber = $subscriber->id;
$rq->subscribed = $subscribed->id;
$rq->created = common_sql_now();
$rq->insert();
return $rq;
}
public static function exists(Profile $subscriber, Profile $other)
{
$sub = Subscription_queue::pkeyGet(array('subscriber' => $subscriber->getID(),
'subscribed' => $other->getID()));
return ($sub instanceof Subscription_queue);
}
public static function getSubQueue(Profile $subscriber, Profile $other)
{
// This is essentially a pkeyGet but we have an object to return in NoResultException
$sub = new Subscription_queue();
$sub->subscriber = $subscriber->id;
$sub->subscribed = $other->id;
if (!$sub->find(true)) {
throw new NoResultException($sub);
}
return $sub;
}
/**
* Complete a pending subscription, as we've got approval of some sort.
*
* @return Subscription
*/
public function complete()
{
$subscriber = Profile::getKV('id', $this->subscriber);
$subscribed = Profile::getKV('id', $this->subscribed);
try {
$sub = Subscription::start($subscriber, $subscribed, Subscription::FORCE);
$this->delete();
} catch (AlreadyFulfilledException $e) {
common_debug('Tried to start a subscription which already existed.');
}
return $sub;
}
/**
* Cancel an outstanding subscription request to the other profile.
*/
public function abort()
{
$subscriber = Profile::getKV('id', $this->subscriber);
$subscribed = Profile::getKV('id', $this->subscribed);
if (Event::handle('StartCancelSubscription', array($subscriber, $subscribed))) {
$this->delete();
Event::handle('EndCancelSubscription', array($subscriber, $subscribed));
}
}
/**
* Send notifications via email etc to group administrators about
* this exciting new pending moderation queue item!
*/
public function notify()
{
$other = Profile::getKV('id', $this->subscriber);
$listenee = User::getKV('id', $this->subscribed);
mail_subscribe_pending_notify_profile($listenee, $other);
}
}

View File

@ -1,62 +1,64 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Table Definition for token
* Entity for User token
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 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 Token extends Managed_DataObject
class Token
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
// AUTOCODE BEGIN
public $__table = 'token'; // table name
public $consumer_key; // varchar(191) primary_key not_null not 255 because utf8mb4 takes more space
public $tok; // char(32) primary_key not_null
public $secret; // char(32) not_null
public $type; // tinyint(1) not_null
public $state; // tinyint(1)
public $verifier; // varchar(191) not 255 because utf8mb4 takes more space
public $verified_callback; // varchar(191) not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
// AUTOCODE END
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
public static function schemaDef(): array
{
return array(
return [
'name' => 'token',
'description' => 'OAuth token record',
'fields' => array(
'consumer_key' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'unique identifier, root URL'),
'tok' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'identifying value'),
'secret' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'secret value'),
'type' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'request or access'),
'state' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'for requests, 0 = initial, 1 = authorized, 2 = used'),
'verifier' => array('type' => 'varchar', 'length' => 191, 'description' => 'verifier string for OAuth 1.0a'),
'verified_callback' => array('type' => 'varchar', 'length' => 191, 'description' => 'verified callback URL for OAuth 1.0a'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
'primary key' => array('consumer_key', 'tok'),
'foreign keys' => array(
'token_consumer_key_fkey' => array('consumer', array('consumer_key' => 'consumer_key')),
),
);
'fields' => [
'consumer_key' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'unique identifier, root URL'],
'tok' => ['type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'identifying value'],
'secret' => ['type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'secret value'],
'type' => ['type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'request or access'],
'state' => ['type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'for requests, 0 = initial, 1 = authorized, 2 = used'],
'verifier' => ['type' => 'varchar', 'length' => 191, 'description' => 'verifier string for OAuth 1.0a'],
'verified_callback' => ['type' => 'varchar', 'length' => 191, 'description' => 'verified callback URL for OAuth 1.0a'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['consumer_key', 'tok'],
'foreign keys' => [
'token_consumer_key_fkey' => ['consumer', ['consumer_key' => 'consumer_key']],
],
];
}
}

View File

@ -0,0 +1,57 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity that Keeps a list of unavailable status network names
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class UnavailableStatusNetwork
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'unavailable_status_network',
'description' => 'An unavailable status network nickname',
'fields' => [
'nickname' => ['type' => 'varchar',
'length' => 64,
'not null' => true, 'description' => 'nickname not to use', ],
'created' => ['type' => 'datetime',
'not null' => true, 'default' => '0000-00-00 00:00:00', ],
],
'primary key' => ['nickname'],
];
}
}

View File

@ -1,63 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Data class for unavailable status networks
*
* @category Data
* @package GNUsocial
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
/**
* Keeps a list of unavailable status network names
*
* @category Data
* @package GNUsocial
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*
* @see Managed_DataObject
*/
class Unavailable_status_network extends Managed_DataObject
{
public $__table = 'unavailable_status_network'; // table name
public $nickname; // varchar(64) UUID
public $created; // datetime()
/**
* The One True Thingy that must be defined and declared.
*/
public static function schemaDef()
{
return array(
'description' => 'An unavailable status network nickname',
'fields' => array(
'nickname' => array('type' => 'varchar',
'length' => 64,
'not null' => true, 'description' => 'nickname not to use'),
'created' => array('type' => 'datetime'),
),
'primary key' => array('nickname'),
);
}
}

View File

@ -1,67 +1,50 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
defined('GNUSOCIAL') || die();
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Table Definition for user
* Entity for users
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class User extends Managed_DataObject
class User
{
const SUBSCRIBE_POLICY_OPEN = 0;
const SUBSCRIBE_POLICY_MODERATE = 1;
// AUTOCODE BEGIN
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
// AUTOCODE END
public $__table = 'user'; // table name
public $id; // int(4) primary_key not_null
public $nickname; // varchar(64) unique_key
public $password; // text
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; // 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; // bool default_true
public $sms; // varchar(64) unique_key
public $carrier; // int(4)
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; // bool default_false
public $subscribe_policy; // tinyint(1)
public $urlshorteningservice; // varchar(50) default_ur1.ca
public $private_stream; // bool default_false
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public static function schemaDef()
public static function schemaDef(): array
{
return array(
return [
'name' => 'user',
'description' => 'local users',
<<<<<<< HEAD
'fields' => array(
'id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
'nickname' => array('type' => 'varchar', 'length' => 64, 'description' => 'nickname or username, duped in profile'),
@ -1079,5 +1062,51 @@ class User extends Managed_DataObject
public function setPref($namespace, $topic, $data)
{
return $this->getProfile()->setPref($namespace, $topic, $data);
=======
'fields' => [
'id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'],
'nickname' => ['type' => 'varchar', 'length' => 64, 'description' => 'nickname or username, duped in profile'],
'password' => ['type' => 'varchar', 'length' => 191, 'description' => 'salted password, can be null for OpenID users'],
'email' => ['type' => 'varchar', 'length' => 191, 'description' => 'email address for password recovery etc.'],
'incomingemail' => ['type' => 'varchar', 'length' => 191, 'description' => 'email address for post-by-email'],
'emailnotifysub' => ['type' => 'bool', 'default' => true, 'description' => 'Notify by email of subscriptions'],
'emailnotifyfav' => ['type' => 'int', 'size' => 'tiny', 'default' => null, 'description' => 'Notify by email of favorites'],
'emailnotifynudge' => ['type' => 'bool', 'default' => true, 'description' => 'Notify by email of nudges'],
'emailnotifymsg' => ['type' => 'bool', 'default' => true, 'description' => 'Notify by email of direct messages'],
'emailnotifyattn' => ['type' => 'bool', 'default' => true, 'description' => 'Notify by email of @-replies'],
'language' => ['type' => 'varchar', 'length' => 50, 'description' => 'preferred language'],
'timezone' => ['type' => 'varchar', 'length' => 50, 'description' => 'timezone'],
'emailpost' => ['type' => 'bool', 'default' => true, 'description' => 'Post by email'],
'sms' => ['type' => 'varchar', 'length' => 64, 'description' => 'sms phone number'],
'carrier' => ['type' => 'int', 'description' => 'foreign key to sms_carrier'],
'smsnotify' => ['type' => 'bool', 'default' => false, 'description' => 'whether to send notices to SMS'],
'smsreplies' => ['type' => 'bool', 'default' => false, 'description' => 'whether to send notices to SMS on replies'],
'smsemail' => ['type' => 'varchar', 'length' => 191, 'description' => 'built from sms and carrier'],
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universally unique identifier, usually a tag URI'],
'autosubscribe' => ['type' => 'bool', 'default' => false, 'description' => 'automatically subscribe to users who subscribe to us'],
'subscribe_policy' => ['type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => '0 = anybody can subscribe; 1 = require approval'],
'urlshorteningservice' => ['type' => 'varchar', 'length' => 50, 'default' => 'internal', 'description' => 'service to use for auto-shortening URLs'],
'private_stream' => ['type' => 'bool', 'default' => false, 'description' => 'whether to limit all notices to followers only'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['id'],
'unique keys' => [
'user_nickname_key' => ['nickname'],
'user_email_key' => ['email'],
'user_incomingemail_key' => ['incomingemail'],
'user_sms_key' => ['sms'],
'user_uri_key' => ['uri'],
],
'foreign keys' => [
'user_id_fkey' => ['profile', ['id' => 'id']],
'user_carrier_fkey' => ['sms_carrier', ['carrier' => 'id']],
],
'indexes' => [
'user_created_idx' => ['created'],
'user_smsemail_idx' => ['smsemail'],
],
];
>>>>>>> e4b74a6aaf ([DATABASE] Extracted schemaDef method from old files and refactored onto new files)
}
}

83
src/Entity/UserGroup.php Normal file
View File

@ -0,0 +1,83 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for groups a user is in
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class UserGroup
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'user_group',
'fields' => [
'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'],
'profile_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'],
'nickname' => ['type' => 'varchar', 'length' => 64, 'description' => 'nickname for addressing'],
'fullname' => ['type' => 'varchar', 'length' => 191, 'description' => 'display name'],
'homepage' => ['type' => 'varchar', 'length' => 191, 'description' => 'URL, cached so we dont regenerate'],
'description' => ['type' => 'text', 'description' => 'group description'],
'location' => ['type' => 'varchar', 'length' => 191, 'description' => 'related physical location, if any'],
'original_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'original size logo'],
'homepage_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'homepage (profile) size logo'],
'stream_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'stream-sized logo'],
'mini_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'mini logo'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'],
'mainpage' => ['type' => 'varchar', 'length' => 191, 'description' => 'page for group info to link to'],
'join_policy' => ['type' => 'int', 'size' => 'tiny', 'description' => '0=open; 1=requires admin approval'],
'force_scope' => ['type' => 'int', 'size' => 'tiny', 'description' => '0=never,1=sometimes,-1=always'],
],
'primary key' => ['id'],
'unique keys' => [
'user_group_uri_key' => ['uri'],
// when it's safe and everyone's run upgrade.php 'user_profile_id_key' => array('profile_id'),
],
'foreign keys' => [
'user_group_id_fkey' => ['profile', ['profile_id' => 'id']],
],
'indexes' => [
'user_group_nickname_idx' => ['nickname'],
'user_group_profile_id_idx' => ['profile_id'], //make this unique in future
],
];
}
}

View File

@ -0,0 +1,63 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for user IM preferences
*
* @category DB
* @package GNUsocial
*
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2009 StatusNet Inc.
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class UserImPrefs
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'user_im_prefs',
'fields' => [
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'user'],
'screenname' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'screenname on this service'],
'transport' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'transport (ex xmpp, aim)'],
'notify' => ['type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Notify when a new notice is sent'],
'replies' => ['type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Send replies from people not subscribed to'],
'updatefrompresence' => ['type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Update from presence.'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['user_id', 'transport'],
'unique keys' => [
'transport_screenname_key' => ['transport', 'screenname'],
],
'foreign keys' => [
'user_im_prefs_user_id_fkey' => ['user', ['user_id' => 'id']],
],
];
}
}

View File

@ -0,0 +1,56 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for user location preferences
*
* @category DB
* @package GNUsocial
*
* @author Evan Prodromou <evan@status.net>
* @copyright 2009 StatusNet Inc.
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class UserLocationPrefs
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'user_location_prefs',
'fields' => [
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'user who has the preference'],
'share_location' => ['type' => 'bool', 'default' => true, 'description' => 'Whether to share location data'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['user_id'],
'foreign keys' => [
'user_location_prefs_user_id_fkey' => ['user', ['user_id' => 'id']],
],
];
}
}

View File

@ -0,0 +1,60 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for user's url shortener preferences
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class UserUrlshortenerPrefs
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'user_urlshortener_prefs',
'fields' => [
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'user'],
'urlshorteningservice' => ['type' => 'varchar', 'length' => 50, 'default' => 'internal', 'description' => 'service to use for auto-shortening URLs'],
'maxurllength' => ['type' => 'int', 'not null' => true, 'description' => 'urls greater than this length will be shortened, 0 = always, null = never'],
'maxnoticelength' => ['type' => 'int', 'not null' => true, 'description' => 'notices with content greater than this value will have all urls shortened, 0 = always, -1 = only if notice text is longer than max allowed'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['user_id'],
'foreign keys' => [
'user_urlshortener_prefs_user_id_fkey' => ['user', ['user_id' => 'id']],
],
];
}
}

View File

@ -0,0 +1,62 @@
<?php
/* {{{ License
* This file is part of GNU social - https://www.gnu.org/software/social
*
* GNU social is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNU social is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with GNU social. If not, see <http://www.gnu.org/licenses/>.
}}} */
namespace App\Entity;
/**
* Entity for association between user and username
*
* @category DB
* @package GNUsocial
*
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet Inc.
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @author Hugo Sales <hugo@fc.up.pt>
* @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class UserUsername
{
// AUTOCODE BEGIN
// AUTOCODE END
public static function schemaDef(): array
{
return [
'name' => 'user_username',
'fields' => [
'provider_name' => ['type' => 'varchar', 'not null' => true, 'length' => 191, 'description' => 'provider name'],
'username' => ['type' => 'varchar', 'not null' => true, 'length' => 191, 'description' => 'username'],
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'notice id this title relates to'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => '0000-00-00 00:00:00', 'description' => 'date this record was created'],
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
],
'primary key' => ['provider_name', 'username'],
'indexes' => [
'user_id_idx' => ['user_id'],
],
'foreign keys' => [
'user_username_user_id_fkey' => ['user', ['user_id' => 'id']],
],
];
}
}

View File

@ -1,887 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
defined('GNUSOCIAL') || die();
/**
* Table Definition for user_group
*/
class User_group extends Managed_DataObject
{
const JOIN_POLICY_OPEN = 0;
const JOIN_POLICY_MODERATE = 1;
const CACHE_WINDOW = 201;
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'user_group'; // table name
public $id; // int(4) primary_key not_null
public $profile_id; // int(4) primary_key not_null
public $nickname; // varchar(64)
public $fullname; // varchar(191) not 255 because utf8mb4 takes more space
public $homepage; // varchar(191) not 255 because utf8mb4 takes more space
public $description; // text
public $location; // varchar(191) not 255 because utf8mb4 takes more space
public $original_logo; // varchar(191) not 255 because utf8mb4 takes more space
public $homepage_logo; // varchar(191) not 255 because utf8mb4 takes more space
public $stream_logo; // varchar(191) not 255 because utf8mb4 takes more space
public $mini_logo; // varchar(191) not 255 because utf8mb4 takes more space
public $created; // datetime()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
public $uri; // varchar(191) unique_key not 255 because utf8mb4 takes more space
public $mainpage; // varchar(191) not 255 because utf8mb4 takes more space
public $join_policy; // tinyint
public $force_scope; // tinyint
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
public function getObjectType()
{
return ActivityObject::GROUP;
}
public static function schemaDef()
{
return array(
'fields' => array(
'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
'nickname' => array('type' => 'varchar', 'length' => 64, 'description' => 'nickname for addressing'),
'fullname' => array('type' => 'varchar', 'length' => 191, 'description' => 'display name'),
'homepage' => array('type' => 'varchar', 'length' => 191, 'description' => 'URL, cached so we dont regenerate'),
'description' => array('type' => 'text', 'description' => 'group description'),
'location' => array('type' => 'varchar', 'length' => 191, 'description' => 'related physical location, if any'),
'original_logo' => array('type' => 'varchar', 'length' => 191, 'description' => 'original size logo'),
'homepage_logo' => array('type' => 'varchar', 'length' => 191, 'description' => 'homepage (profile) size logo'),
'stream_logo' => array('type' => 'varchar', 'length' => 191, 'description' => 'stream-sized logo'),
'mini_logo' => array('type' => 'varchar', 'length' => 191, 'description' => 'mini logo'),
'created' => array('type' => 'datetime', 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
'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'),
'force_scope' => array('type' => 'int', 'size' => 'tiny', 'description' => '0=never,1=sometimes,-1=always'),
),
'primary key' => array('id'),
'unique keys' => array(
'user_group_uri_key' => array('uri'),
// when it's safe and everyone's run upgrade.php 'user_profile_id_key' => array('profile_id'),
),
'foreign keys' => array(
'user_group_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
),
'indexes' => array(
'user_group_nickname_idx' => array('nickname'),
'user_group_created_id_idx' => array('created', 'id'),
'user_group_profile_id_idx' => array('profile_id'), //make this unique in future
),
);
}
protected $_profile = array();
/**
* @return Profile
*
* @throws GroupNoProfileException if user has no profile
*/
public function getProfile()
{
if (!isset($this->_profile[$this->profile_id])) {
$profile = Profile::getKV('id', $this->profile_id);
if (!$profile instanceof Profile) {
throw new GroupNoProfileException($this);
}
$this->_profile[$this->profile_id] = $profile;
}
return $this->_profile[$this->profile_id];
}
public function getNickname()
{
return $this->getProfile()->getNickname();
}
public function getFullname()
{
return $this->getProfile()->getFullname();
}
public static function defaultLogo($size)
{
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
AVATAR_STREAM_SIZE => 'stream',
AVATAR_MINI_SIZE => 'mini');
return Theme::path('default-avatar-'.$sizenames[$size].'.png');
}
public function homeUrl()
{
return $this->getProfile()->getUrl();
}
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', ['id' => $this->id]);
}
}
Event::handle('EndUserGroupGetUri', array($this, &$uri));
return $uri;
}
public function permalink()
{
$url = null;
if (Event::handle('StartUserGroupPermalink', array($this, &$url))) {
if ($this->isLocal()) {
$url = common_local_url('groupbyid', ['id' => $this->id]);
}
}
Event::handle('EndUserGroupPermalink', array($this, &$url));
return $url;
}
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.
$stream = new GroupNoticeStream($this, Profile::current());
return $stream->getNotices($offset, $limit, $since_id, $max_id);
}
public function getMembers($offset = 0, $limit = null)
{
$ids = null;
if (is_null($limit) || $offset + $limit > User_group::CACHE_WINDOW) {
$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);
self::cacheSet($key, $window);
}
$ids = array_slice($window, $offset, $limit);
}
return Profile::multiGet('id', $ids);
}
public function getMemberIDs($offset = 0, $limit = null)
{
$gm = new Group_member();
$gm->selectAdd();
$gm->selectAdd('profile_id');
$gm->group_id = $this->id;
$gm->orderBy('created DESC, profile_id DESC');
if (!is_null($limit)) {
$gm->limit($offset, $limit);
}
$ids = array();
if ($gm->find()) {
while ($gm->fetch()) {
$ids[] = $gm->profile_id;
}
}
return $ids;
}
/**
* Get pending members, who have not yet been approved.
*
* @param int $offset
* @param int $limit
* @return Profile
*/
public function getRequests($offset = 0, $limit = null)
{
$rq = new Group_join_queue();
$rq->group_id = $this->id;
$members = new Profile();
$members->joinAdd(['id', $rq, 'profile_id']);
if ($limit != null) {
$members->limit($offset, $limit);
}
$members->find();
return $members;
}
public function getAdminCount()
{
$block = new Group_member();
$block->group_id = $this->id;
$block->is_admin = true;
return $block->count();
}
public function getMemberCount()
{
$key = sprintf("group:member_count:%d", $this->id);
$cnt = self::cacheGet($key);
if (is_integer($cnt)) {
return (int) $cnt;
}
$mem = new Group_member();
$mem->group_id = $this->id;
// XXX: why 'distinct'?
$cnt = (int) $mem->count('distinct profile_id');
self::cacheSet($key, $cnt);
return $cnt;
}
public function getBlockedCount()
{
// XXX: WORM cache this
$block = new Group_block();
$block->group_id = $this->id;
return $block->count();
}
public function getQueueCount()
{
// XXX: WORM cache this
$queue = new Group_join_queue();
$queue->group_id = $this->id;
return $queue->count();
}
// offset is null because DataObject wants it, 0 would mean no results
public function getAdmins($offset = null, $limit = null)
{
$admins = new Profile();
$admins->joinAdd(['id', 'group_member:profile_id']);
$admins->whereAdd(sprintf(
'group_member.group_id = %d AND group_member.is_admin IS TRUE',
$this->getID()
));
$admins->orderBy('group_member.modified, group_member.profile_id');
$admins->limit($offset, $limit);
$admins->find();
return $admins;
}
// 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'));
$blocked->whereAdd(sprintf('group_block.group_id = %u', $this->id));
$blocked->orderBy('group_block.modified DESC, group_block.blocked DESC');
$blocked->limit($offset, $limit);
$blocked->find();
return $blocked;
}
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));
$sizes = array('homepage_logo' => AVATAR_PROFILE_SIZE,
'stream_logo' => AVATAR_STREAM_SIZE,
'mini_logo' => AVATAR_MINI_SIZE);
$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()
);
$imagefile->resizeTo(Avatar::path($filename), array('width'=>$size, 'height'=>$size));
$this->$name = Avatar::url($filename);
}
common_debug(common_log_objstring($this));
return $this->update($orig);
}
public function getBestName()
{
return ($this->fullname) ? $this->fullname : $this->nickname;
}
/**
* Gets the full name (if filled) with nickname as a parenthetical, or the nickname alone
* if no fullname is provided.
*
* @return string
*/
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);
} else {
return $this->nickname;
}
}
public function getAliases()
{
$aliases = array();
// XXX: cache this
$alias = new Group_alias();
$alias->group_id = $this->id;
if ($alias->find()) {
while ($alias->fetch()) {
$aliases[] = $alias->alias;
}
}
$alias->free();
return $aliases;
}
public function setAliases($newaliases)
{
$newaliases = array_unique($newaliases);
$oldaliases = $this->getAliases();
// Delete stuff that's old that not in new
$to_delete = array_diff($oldaliases, $newaliases);
// Insert stuff that's in new and not in old
$to_insert = array_diff($newaliases, $oldaliases);
$alias = new Group_alias();
$alias->group_id = $this->id;
foreach ($to_delete as $delalias) {
$alias->alias = $delalias;
$result = $alias->delete();
if (!$result) {
common_log_db_error($alias, 'DELETE', __FILE__);
return false;
}
}
foreach ($to_insert as $insalias) {
if ($insalias === $this->nickname) {
continue;
}
$alias->alias = Nickname::normalize($insalias, true);
$result = $alias->insert();
if (!$result) {
common_log_db_error($alias, 'INSERT', __FILE__);
return false;
}
}
return true;
}
public static function getForNickname($nickname, Profile $profile = null)
{
$nickname = Nickname::normalize($nickname);
// Are there any matching remote groups this profile's in?
if ($profile instanceof Profile) {
$group = $profile->getGroups(0, null);
while ($group instanceof User_group && $group->fetch()) {
if ($group->nickname == $nickname) {
// @fixme is this the best way?
return clone($group);
}
}
}
// If not, check local groups.
$group = Local_group::getKV('nickname', $nickname);
if ($group instanceof Local_group) {
return User_group::getKV('id', $group->group_id);
}
$alias = Group_alias::getKV('alias', $nickname);
if ($alias instanceof Group_alias) {
return User_group::getKV('id', $alias->group_id);
}
return null;
}
public function getUserMembers()
{
// XXX: cache this
$user = new User();
$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
));
$ids = [];
while ($user->fetch()) {
$ids[] = $user->id;
}
$user->free();
return $ids;
}
public static function maxDescription()
{
$desclimit = common_config('group', 'desclimit');
// null => use global limit (distinct from 0!)
if (is_null($desclimit)) {
$desclimit = common_config('site', 'textlimit');
}
return $desclimit;
}
public static function descriptionTooLong($desc)
{
$desclimit = self::maxDescription();
return ($desclimit > 0 && !empty($desc) && (mb_strlen($desc) > $desclimit));
}
public function asAtomEntry($namespace = false, $source = false)
{
$xs = new XMLStringer(true);
if ($namespace) {
$attrs = array('xmlns' => 'http://www.w3.org/2005/Atom',
'xmlns:thr' => 'http://purl.org/syndication/thread/1.0');
} else {
$attrs = array();
}
$xs->elementStart('entry', $attrs);
if ($source) {
$xs->elementStart('source');
$xs->element('id', null, $this->permalink());
$xs->element('title', null, $profile->nickname . " - " . common_config('site', 'name'));
$xs->element('link', array('href' => $this->permalink()));
$xs->element('updated', null, $this->modified);
$xs->elementEnd('source');
}
$xs->element('title', null, $this->nickname);
$xs->element('summary', null, common_xml_safe_str($this->description));
$xs->element('link', array('rel' => 'alternate',
'href' => $this->permalink()));
$xs->element('id', null, $this->permalink());
$xs->element('published', null, common_date_w3dtf($this->created));
$xs->element('updated', null, common_date_w3dtf($this->modified));
$xs->element(
'content',
array('type' => 'html'),
common_xml_safe_str($this->description)
);
$xs->elementEnd('entry');
return $xs->getString();
}
public function asAtomAuthor()
{
$xs = new XMLStringer(true);
$xs->elementStart('author');
$xs->element('name', null, $this->nickname);
$xs->element('uri', null, $this->permalink());
$xs->elementEnd('author');
return $xs->getString();
}
/**
* Returns an XML string fragment with group information as an
* Activity Streams noun object with the given element type.
*
* Assumes that 'activity', 'georss', and 'poco' namespace has been
* previously defined.
*
* @param string $element one of 'actor', 'subject', 'object', 'target'
*
* @return string
*/
public function asActivityNoun($element)
{
$noun = ActivityObject::fromGroup($this);
return $noun->asString('activity:' . $element);
}
public function getAvatar()
{
return empty($this->homepage_logo)
? User_group::defaultLogo(AVATAR_PROFILE_SIZE)
: $this->homepage_logo;
}
public static function register($fields)
{
if (!empty($fields['userid'])) {
$profile = Profile::getKV('id', $fields['userid']);
if ($profile && !$profile->hasRight(Right::CREATEGROUP)) {
common_log(LOG_WARNING, "Attempted group creation from banned user: " . $profile->nickname);
// TRANS: Client exception thrown when a user tries to create a group while banned.
throw new ClientException(_('You are not allowed to create groups on this site.'), 403);
}
}
$fields['nickname'] = Nickname::normalize($fields['nickname']);
// MAGICALLY put fields into current scope
// @fixme kill extract(); it makes debugging absurdly hard
$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();
if (empty($uri)) {
// fill in later...
$uri = null;
}
if (empty($mainpage)) {
$mainpage = common_local_url('showgroup', array('nickname' => $nickname));
}
// We must create a new, incrementally assigned profile_id
$profile = new Profile();
$profile->nickname = $nickname;
$profile->fullname = $fullname;
$profile->profileurl = $mainpage;
$profile->homepage = $homepage;
$profile->bio = $description;
$profile->location = $location;
$profile->created = common_sql_now();
$group->nickname = $profile->nickname;
$group->fullname = $profile->fullname;
$group->homepage = $profile->homepage;
$group->description = $profile->bio;
$group->location = $profile->location;
$group->mainpage = $profile->profileurl;
$group->created = $profile->created;
$profile->query('START TRANSACTION');
$id = $profile->insert();
if ($id === false) {
$profile->query('ROLLBACK');
throw new ServerException(_('Profile insertion failed'));
}
$group->profile_id = $id;
$group->uri = $uri;
if (isset($fields['join_policy'])) {
$group->join_policy = intval($fields['join_policy']);
} else {
$group->join_policy = 0;
}
if (isset($fields['force_scope'])) {
$group->force_scope = intval($fields['force_scope']);
} else {
$group->force_scope = 0;
}
if (Event::handle('StartGroupSave', array(&$group))) {
$result = $group->insert();
if ($result === false) {
common_log_db_error($group, 'INSERT', __FILE__);
// TRANS: Server exception thrown when creating a group failed.
throw new ServerException(_('Could not create group.'));
}
if (!isset($uri) || empty($uri)) {
$orig = clone($group);
$group->uri = common_local_url('groupbyid', array('id' => $group->id));
$result = $group->update($orig);
if (!$result) {
common_log_db_error($group, 'UPDATE', __FILE__);
// TRANS: Server exception thrown when updating a group URI failed.
throw new ServerException(_('Could not set group URI.'));
}
}
$result = $group->setAliases($aliases);
if (!$result) {
// TRANS: Server exception thrown when creating group aliases failed.
throw new ServerException(_('Could not create aliases.'));
}
$member = new Group_member();
$member->group_id = $group->id;
$member->profile_id = $userid;
$member->is_admin = true;
$member->created = $group->created;
$result = $member->insert();
if (!$result) {
common_log_db_error($member, 'INSERT', __FILE__);
// TRANS: Server exception thrown when setting group membership failed.
throw new ServerException(_('Could not set group membership.'));
}
self::blow('profile:groups:%d', $userid);
if ($local) {
$local_group = new Local_group();
$local_group->group_id = $group->id;
$local_group->nickname = $nickname;
$local_group->created = common_sql_now();
$result = $local_group->insert();
if (!$result) {
common_log_db_error($local_group, 'INSERT', __FILE__);
// TRANS: Server exception thrown when saving local group information failed.
throw new ServerException(_('Could not save local group info.'));
}
}
Event::handle('EndGroupSave', array($group));
}
$profile->query('COMMIT');
return $group;
}
/**
* Handle cascading deletion, on the model of notice and profile.
*
* This should handle freeing up cached entries for the group's
* id, nickname, URI, and aliases. There may be other areas that
* are not de-cached in the UI, including the sidebar lists on
* GroupsAction
*/
public function delete($useWhere = false)
{
if (empty($this->id)) {
common_log(LOG_WARNING, "Ambiguous User_group->delete(); skipping related tables.");
return parent::delete($useWhere);
}
// Safe to delete in bulk for now
$related = array('Group_inbox',
'Group_block',
'Group_member',
'Related_group');
Event::handle('UserGroupDeleteRelated', array($this, &$related));
foreach ($related as $cls) {
$inst = new $cls();
$inst->group_id = $this->id;
if ($inst->find()) {
while ($inst->fetch()) {
$dup = clone($inst);
$dup->delete();
}
}
}
// And related groups in the other direction...
$inst = new Related_group();
$inst->related_group_id = $this->id;
$inst->delete();
// Aliases and the local_group entry need to be cleared explicitly
// or we'll miss clearing some cache keys; that can make it hard
// to create a new group with one of those names or aliases.
$this->setAliases(array());
// $this->isLocal() but we're using the resulting object
$local = Local_group::getKV('group_id', $this->id);
if ($local instanceof Local_group) {
$local->delete();
}
$result = parent::delete($useWhere);
try {
$profile = $this->getProfile();
$profile->delete();
} catch (GroupNoProfileException $unp) {
common_log(
LOG_INFO,
"Group {$this->nickname} has no profile; continuing deletion."
);
}
// blow the cached ids
self::blow('user_group:notice_ids:%d', $this->id);
return $result;
}
public function update($dataObject=false)
{
// Whenever the User_group is updated, find the Local_group
// and update its nickname too.
if ($this->nickname != $dataObject->nickname) {
$local = Local_group::getKV('group_id', $this->id);
if ($local instanceof Local_group) {
common_debug("Updating Local_group ({$this->id}) nickname from {$dataObject->nickname} to {$this->nickname}");
$local->setNickname($this->nickname);
}
}
// Also make sure the Profile table is up to date!
$fields = array(/*group field => profile field*/
'nickname' => 'nickname',
'fullname' => 'fullname',
'mainpage' => 'profileurl',
'homepage' => 'homepage',
'description' => 'bio',
'location' => 'location',
'created' => 'created',
'modified' => 'modified',
);
$profile = $this->getProfile();
$origpro = clone($profile);
foreach ($fields as $gf=>$pf) {
$profile->$pf = $this->$gf;
}
if ($profile->update($origpro) === false) {
throw new ServerException(_('Unable to update profile'));
}
return parent::update($dataObject);
}
public function isPrivate()
{
return ($this->join_policy == self::JOIN_POLICY_MODERATE &&
intval($this->force_scope) === 1);
}
public function isLocal()
{
$local = Local_group::getKV('group_id', $this->id);
return ($local instanceof Local_group);
}
public static function groupsFromText($text, Profile $profile)
{
$groups = array();
/* extract all !group */
$count = preg_match_all(
'/(?:^|\s)!(' . Nickname::DISPLAY_FMT . ')/',
strtolower($text),
$match
);
if (!$count) {
return $groups;
}
foreach (array_unique($match[1]) as $nickname) {
$group = self::getForNickname($nickname, $profile);
if ($group instanceof User_group && $profile->isMember($group)) {
$groups[] = clone($group);
}
}
return $groups;
}
public static function idsFromText($text, Profile $profile)
{
$ids = array();
$groups = self::groupsFromText($text, $profile);
foreach ($groups as $group) {
$ids[$group->id] = true;
}
return array_keys($ids);
}
}

Some files were not shown because too many files have changed in this diff Show More