forked from GNUsocial/gnu-social
[DATABASE] Extracted schemaDef method from old files and refactored onto new files
This commit is contained in:
parent
c38b9a1503
commit
8d41944f90
@ -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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
62
src/Entity/ConfirmAddress.php
Normal file
62
src/Entity/ConfirmAddress.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -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...";
|
||||
}
|
||||
}
|
||||
|
60
src/Entity/FileRedirection.php
Normal file
60
src/Entity/FileRedirection.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
65
src/Entity/FileThumbnail.php
Normal file
65
src/Entity/FileThumbnail.php
Normal 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
62
src/Entity/FileToPost.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
70
src/Entity/ForeignLink.php
Normal file
70
src/Entity/ForeignLink.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
59
src/Entity/ForeignService.php
Normal file
59
src/Entity/ForeignService.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
65
src/Entity/ForeignSubscription.php
Normal file
65
src/Entity/ForeignSubscription.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
63
src/Entity/ForeignUser.php
Normal file
63
src/Entity/ForeignUser.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
60
src/Entity/GroupAlias.php
Normal 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
60
src/Entity/GroupBlock.php
Normal 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
64
src/Entity/GroupInbox.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
63
src/Entity/GroupJoinQueue.php
Normal file
63
src/Entity/GroupJoinQueue.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
71
src/Entity/GroupMember.php
Normal file
71
src/Entity/GroupMember.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
62
src/Entity/LocalGroup.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
55
src/Entity/LocationNamespace.php
Normal file
55
src/Entity/LocationNamespace.php
Normal 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'],
|
||||
];
|
||||
}
|
||||
}
|
@ -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
58
src/Entity/LoginToken.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
@ -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
63
src/Entity/NoticeLocation.php
Normal file
63
src/Entity/NoticeLocation.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
65
src/Entity/NoticePrefs.php
Normal file
65
src/Entity/NoticePrefs.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
57
src/Entity/NoticeSource.php
Normal file
57
src/Entity/NoticeSource.php
Normal 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
63
src/Entity/NoticeTag.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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'),
|
||||
);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
73
src/Entity/OauthApplication.php
Normal file
73
src/Entity/OauthApplication.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
61
src/Entity/OauthApplicationUser.php
Normal file
61
src/Entity/OauthApplicationUser.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
61
src/Entity/OauthTokenAssociation.php
Normal file
61
src/Entity/OauthTokenAssociation.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
66
src/Entity/OldSchoolPrefs.php
Normal file
66
src/Entity/OldSchoolPrefs.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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
58
src/Entity/ProfileBlock.php
Normal file
58
src/Entity/ProfileBlock.php
Normal 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'],
|
||||
];
|
||||
}
|
||||
}
|
77
src/Entity/ProfileList.php
Normal file
77
src/Entity/ProfileList.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
63
src/Entity/ProfilePrefs.php
Normal file
63
src/Entity/ProfilePrefs.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
58
src/Entity/ProfileRole.php
Normal file
58
src/Entity/ProfileRole.php
Normal 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
65
src/Entity/ProfileTag.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
65
src/Entity/ProfileTagSubscription.php
Normal file
65
src/Entity/ProfileTagSubscription.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
59
src/Entity/QueueItem.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
59
src/Entity/RelatedGroup.php
Normal file
59
src/Entity/RelatedGroup.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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
57
src/Entity/RememberMe.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
55
src/Entity/SchemaVersion.php
Normal file
55
src/Entity/SchemaVersion.php
Normal 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'],
|
||||
];
|
||||
}
|
||||
}
|
@ -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'),
|
||||
);
|
||||
}
|
||||
}
|
@ -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
59
src/Entity/SmsCarrier.php
Normal 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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
63
src/Entity/SubscriptionQueue.php
Normal file
63
src/Entity/SubscriptionQueue.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
57
src/Entity/UnavailableStatusNetwork.php
Normal file
57
src/Entity/UnavailableStatusNetwork.php
Normal 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'],
|
||||
];
|
||||
}
|
||||
}
|
@ -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'),
|
||||
);
|
||||
}
|
||||
}
|
@ -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
83
src/Entity/UserGroup.php
Normal 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
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
63
src/Entity/UserImPrefs.php
Normal file
63
src/Entity/UserImPrefs.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
56
src/Entity/UserLocationPrefs.php
Normal file
56
src/Entity/UserLocationPrefs.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
60
src/Entity/UserUrlshortenerPrefs.php
Normal file
60
src/Entity/UserUrlshortenerPrefs.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
62
src/Entity/UserUsername.php
Normal file
62
src/Entity/UserUsername.php
Normal 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']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user