forked from GNUsocial/gnu-social
[MEDIA] Rename File to Attachment
This commit is contained in:
parent
dc5bdfa1fb
commit
5579f4fa5d
@ -25,8 +25,8 @@ use App\Core\Cache;
|
|||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use function App\Core\I18n\_m;
|
use function App\Core\I18n\_m;
|
||||||
use App\Core\Log;
|
use App\Core\Log;
|
||||||
|
use App\Entity\Attachment;
|
||||||
use App\Entity\Avatar;
|
use App\Entity\Avatar;
|
||||||
use App\Entity\File;
|
|
||||||
use App\Util\Common;
|
use App\Util\Common;
|
||||||
use App\Util\Exception\ClientException;
|
use App\Util\Exception\ClientException;
|
||||||
use Component\Media\Exception\NoAvatarException;
|
use Component\Media\Exception\NoAvatarException;
|
||||||
@ -43,20 +43,21 @@ abstract class Utils
|
|||||||
/**
|
/**
|
||||||
* Perform file validation (checks and normalization) and store the given file
|
* Perform file validation (checks and normalization) and store the given file
|
||||||
*/
|
*/
|
||||||
public static function validateAndStoreFile(SymfonyFile $sfile,
|
public static function validateAndStoreAttachment(SymfonyFile $sfile,
|
||||||
string $dest_dir,
|
string $dest_dir,
|
||||||
?string $title = null,
|
?string $title = null,
|
||||||
bool $is_local = true,
|
bool $is_local = true,
|
||||||
?int $actor_id = null): File
|
?int $actor_id = null): Attachment
|
||||||
{
|
{
|
||||||
// The following properly gets the mimetype with `file` or other
|
// The following properly gets the mimetype with `file` or other
|
||||||
// available methods, so should be safe
|
// available methods, so should be safe
|
||||||
$hash = hash_file(File::FILEHASH_ALGO, $sfile->getPathname());
|
$hash = hash_file(Attachment::FILEHASH_ALGO, $sfile->getPathname());
|
||||||
$file = File::create([
|
$file = Attachment::create([
|
||||||
'file_hash' => $hash,
|
'file_hash' => $hash,
|
||||||
'actor_id' => $actor_id,
|
'actor_id' => $actor_id,
|
||||||
'mimetype' => $sfile->getMimeType(),
|
'mimetype' => $sfile->getMimeType(),
|
||||||
'title' => $title ?: _m('Untitled attachment'),
|
'title' => $title ?: _m('Untitled attachment'),
|
||||||
|
'filename' => $hash,
|
||||||
'is_local' => $is_local,
|
'is_local' => $is_local,
|
||||||
]);
|
]);
|
||||||
$sfile->move($dest_dir, $hash);
|
$sfile->move($dest_dir, $hash);
|
||||||
@ -77,7 +78,7 @@ abstract class Utils
|
|||||||
[
|
[
|
||||||
'Content-Description' => 'File Transfer',
|
'Content-Description' => 'File Transfer',
|
||||||
'Content-Type' => $mimetype,
|
'Content-Type' => $mimetype,
|
||||||
'Content-Disposition' => HeaderUtils::makeDisposition($disposition, $output_filename ?: _m('untitled')),
|
'Content-Disposition' => HeaderUtils::makeDisposition($disposition, $output_filename ?: _m('Untitled attachment')),
|
||||||
'Cache-Control' => 'public',
|
'Cache-Control' => 'public',
|
||||||
],
|
],
|
||||||
$public = true,
|
$public = true,
|
||||||
@ -122,9 +123,9 @@ abstract class Utils
|
|||||||
$id,
|
$id,
|
||||||
Cache::get("file-info-{$id}",
|
Cache::get("file-info-{$id}",
|
||||||
function () use ($id) {
|
function () use ($id) {
|
||||||
return DB::dql('select f.file_hash, f.mimetype, f.title ' .
|
return DB::dql('select at.file_hash, at.mimetype, at.title ' .
|
||||||
'from App\\Entity\\File f ' .
|
'from App\\Entity\\Attachment at ' .
|
||||||
'where f.id = :id',
|
'where at.id = :id',
|
||||||
['id' => $id]);
|
['id' => $id]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -192,7 +193,7 @@ abstract class Utils
|
|||||||
Cache::get("avatar-file-info-{$nickname}",
|
Cache::get("avatar-file-info-{$nickname}",
|
||||||
function () use ($nickname) {
|
function () use ($nickname) {
|
||||||
return DB::dql('select f.file_hash, f.mimetype, f.title ' .
|
return DB::dql('select f.file_hash, f.mimetype, f.title ' .
|
||||||
'from App\\Entity\\File f ' .
|
'from App\\Entity\\Attachment f ' .
|
||||||
'join App\\Entity\\Avatar a with f.id = a.file_id ' .
|
'join App\\Entity\\Avatar a with f.id = a.file_id ' .
|
||||||
'join App\\Entity\\GSActor g with g.id = a.gsactor_id ' .
|
'join App\\Entity\\GSActor g with g.id = a.gsactor_id ' .
|
||||||
'where g.nickname = :nickname',
|
'where g.nickname = :nickname',
|
||||||
|
@ -41,7 +41,6 @@ use App\Core\Form;
|
|||||||
use function App\Core\I18n\_m;
|
use function App\Core\I18n\_m;
|
||||||
use App\Core\Log;
|
use App\Core\Log;
|
||||||
use App\Entity\Avatar;
|
use App\Entity\Avatar;
|
||||||
use App\Entity\File;
|
|
||||||
use App\Util\ClientException;
|
use App\Util\ClientException;
|
||||||
use App\Util\Common;
|
use App\Util\Common;
|
||||||
use App\Util\Form\ArrayTransformer;
|
use App\Util\Form\ArrayTransformer;
|
||||||
@ -147,7 +146,7 @@ class UserPanel extends AbstractController
|
|||||||
}
|
}
|
||||||
$user = Common::user();
|
$user = Common::user();
|
||||||
$actor_id = $user->getId();
|
$actor_id = $user->getId();
|
||||||
$file = Media::validateAndStoreFile($sfile, Common::config('avatar', 'dir'), $title = null, $is_local = true, $use_unique = $actor_id);
|
$file = Media::validateAndStoreAttachment($sfile, Common::config('avatar', 'dir'), $title = null, $is_local = true, $use_unique = $actor_id);
|
||||||
$old_file = null;
|
$old_file = null;
|
||||||
$avatar = DB::find('avatar', ['gsactor_id' => $actor_id]);
|
$avatar = DB::find('avatar', ['gsactor_id' => $actor_id]);
|
||||||
// Must get old id before inserting another one
|
// Must get old id before inserting another one
|
||||||
|
@ -52,6 +52,7 @@ class Attachment extends Entity
|
|||||||
private ?string $filename;
|
private ?string $filename;
|
||||||
private ?bool $is_local;
|
private ?bool $is_local;
|
||||||
private ?int $source;
|
private ?int $source;
|
||||||
|
private ?int $scope;
|
||||||
private DateTimeInterface $modified;
|
private DateTimeInterface $modified;
|
||||||
|
|
||||||
public function setId(int $id): self
|
public function setId(int $id): self
|
||||||
@ -164,6 +165,17 @@ class Attachment extends Entity
|
|||||||
return $this->source;
|
return $this->source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setScope(?int $scope): self
|
||||||
|
{
|
||||||
|
$this->scope = $scope;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScope(): ?int
|
||||||
|
{
|
||||||
|
return $this->scope;
|
||||||
|
}
|
||||||
|
|
||||||
public function setModified(DateTimeInterface $modified): self
|
public function setModified(DateTimeInterface $modified): self
|
||||||
{
|
{
|
||||||
$this->modified = $modified;
|
$this->modified = $modified;
|
||||||
@ -217,9 +229,8 @@ class Attachment extends Entity
|
|||||||
|
|
||||||
public static function schemaDef(): array
|
public static function schemaDef(): array
|
||||||
{
|
{
|
||||||
// TODO add scope
|
|
||||||
return [
|
return [
|
||||||
'name' => 'file',
|
'name' => 'attachment',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'id' => ['type' => 'serial', 'not null' => true],
|
'id' => ['type' => 'serial', 'not null' => true],
|
||||||
'remote_url' => ['type' => 'text', 'description' => 'URL after following possible redirections'],
|
'remote_url' => ['type' => 'text', 'description' => 'URL after following possible redirections'],
|
||||||
@ -231,6 +242,7 @@ class Attachment extends Entity
|
|||||||
'filename' => ['type' => 'varchar', 'length' => 191, 'description' => 'title of resource when available'],
|
'filename' => ['type' => 'varchar', 'length' => 191, 'description' => 'title of resource when available'],
|
||||||
'is_local' => ['type' => 'bool', 'description' => 'whether the file is stored locally'],
|
'is_local' => ['type' => 'bool', 'description' => 'whether the file is stored locally'],
|
||||||
'source' => ['type' => 'int', 'default' => null, 'description' => 'Source of the Attachment (upload, TFN, embed)'],
|
'source' => ['type' => 'int', 'default' => null, 'description' => 'Source of the Attachment (upload, TFN, embed)'],
|
||||||
|
'scope' => ['type' => 'int', 'default' => null, 'description' => 'visibility scope for this attachment'],
|
||||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||||
],
|
],
|
||||||
'primary key' => ['id'],
|
'primary key' => ['id'],
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// {{{ License
|
// {{{ License
|
||||||
|
|
||||||
// This file is part of GNU social - https://www.gnu.org/software/social
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
//
|
//
|
||||||
// GNU social is free software: you can redistribute it and/or modify
|
// GNU social is free software: you can redistribute it and/or modify
|
||||||
@ -15,6 +16,7 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
@ -23,7 +25,7 @@ use App\Core\Entity;
|
|||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity for File thumbnails
|
* Entity for Attachment thumbnails
|
||||||
*
|
*
|
||||||
* @category DB
|
* @category DB
|
||||||
* @package GNUsocial
|
* @package GNUsocial
|
||||||
@ -39,20 +41,20 @@ use DateTimeInterface;
|
|||||||
class AttachmentThumbnail extends Entity
|
class AttachmentThumbnail extends Entity
|
||||||
{
|
{
|
||||||
// {{{ Autocode
|
// {{{ Autocode
|
||||||
private int $file_id;
|
private int $attachment_id;
|
||||||
private int $width;
|
private int $width;
|
||||||
private int $height;
|
private int $height;
|
||||||
private DateTimeInterface $modified;
|
private DateTimeInterface $modified;
|
||||||
|
|
||||||
public function setFileId(int $file_id): self
|
public function setAttachmentId(int $attachment_id): self
|
||||||
{
|
{
|
||||||
$this->file_id = $file_id;
|
$this->attachment_id = $attachment_id;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFileId(): int
|
public function getAttachmentId(): int
|
||||||
{
|
{
|
||||||
return $this->file_id;
|
return $this->attachment_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setWidth(int $width): self
|
public function setWidth(int $width): self
|
||||||
@ -91,28 +93,27 @@ class AttachmentThumbnail extends Entity
|
|||||||
// }}} Autocode
|
// }}} Autocode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a file thumbnail. This table doesn't own all the files, only itself
|
* Delete a attachment thumbnail. This table doesn't own all the attachments, only itself
|
||||||
*/
|
*/
|
||||||
public function delete(bool $flush = false, bool $delete_files_now = false, bool $cascading = false): string
|
public function delete(bool $flush = false, bool $delete_attachments_now = false, bool $cascading = false): string
|
||||||
{
|
{
|
||||||
// TODO Implement deleting file thumbnails
|
// TODO Implement deleting attachment thumbnails
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function schemaDef(): array
|
public static function schemaDef(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => 'file_thumbnail',
|
'name' => 'attachment_thumbnail',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'file_
|
'attachment_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Attachment.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'thumbnail for what attachment'],
|
||||||
id' => ['type' => 'int', 'foreign key' => true, 'target' => 'File.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'thumbnail for what file'],
|
|
||||||
'width' => ['type' => 'int', 'not null' => true, 'description' => 'width of thumbnail'],
|
'width' => ['type' => 'int', 'not null' => true, 'description' => 'width of thumbnail'],
|
||||||
'height' => ['type' => 'int', 'not null' => true, 'description' => 'height of thumbnail'],
|
'height' => ['type' => 'int', 'not null' => true, 'description' => 'height of thumbnail'],
|
||||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||||
],
|
],
|
||||||
'primary key' => ['file_id', 'width', 'height'],
|
'primary key' => ['attachment_id', 'width', 'height'],
|
||||||
'indexes' => [
|
'indexes' => [
|
||||||
'file_thumbnail_file_id_idx' => ['file_id'],
|
'attachment_thumbnail_attachment_id_idx' => ['attachment_id'],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ use App\Core\Entity;
|
|||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity for relating a file to a post
|
* Entity for relating a attachment to a post
|
||||||
*
|
*
|
||||||
* @category DB
|
* @category DB
|
||||||
* @package GNUsocial
|
* @package GNUsocial
|
||||||
@ -36,22 +36,22 @@ use DateTimeInterface;
|
|||||||
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
||||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
class FileToNote extends Entity
|
class AttachmentToNote extends Entity
|
||||||
{
|
{
|
||||||
// {{{ Autocode
|
// {{{ Autocode
|
||||||
private int $file_id;
|
private int $attachment_id;
|
||||||
private int $note_id;
|
private int $note_id;
|
||||||
private DateTimeInterface $modified;
|
private DateTimeInterface $modified;
|
||||||
|
|
||||||
public function setFileId(int $file_id): self
|
public function setAttachmentId(int $attachment_id): self
|
||||||
{
|
{
|
||||||
$this->file_id = $file_id;
|
$this->attachment_id = $attachment_id;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFileId(): int
|
public function getAttachmentId(): int
|
||||||
{
|
{
|
||||||
return $this->file_id;
|
return $this->attachment_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setNoteId(int $note_id): self
|
public function setNoteId(int $note_id): self
|
||||||
@ -81,15 +81,15 @@ class FileToNote extends Entity
|
|||||||
public static function schemaDef(): array
|
public static function schemaDef(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => 'file_to_note',
|
'name' => 'attachment_to_note',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'file_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'File.id', 'multiplicity' => 'one to one', 'name' => 'file_to_note_file_id_fkey', 'not null' => true, 'description' => 'id of file'],
|
'attachment_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Attachment.id', 'multiplicity' => 'one to one', 'name' => 'attachment_to_note_attachment_id_fkey', 'not null' => true, 'description' => 'id of attachment'],
|
||||||
'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'name' => 'file_to_note_note_id_fkey', 'not null' => true, 'description' => 'id of the note it belongs to'],
|
'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'name' => 'attachment_to_note_note_id_fkey', 'not null' => true, 'description' => 'id of the note it belongs to'],
|
||||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||||
],
|
],
|
||||||
'primary key' => ['file_id', 'note_id'],
|
'primary key' => ['attachment_id', 'note_id'],
|
||||||
'indexes' => [
|
'indexes' => [
|
||||||
'file_id_idx' => ['file_id'],
|
'attachment_id_idx' => ['attachment_id'],
|
||||||
'note_id_idx' => ['note_id'],
|
'note_id_idx' => ['note_id'],
|
||||||
],
|
],
|
||||||
];
|
];
|
@ -25,7 +25,7 @@ use App\Core\Cache;
|
|||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use App\Core\Entity;
|
use App\Core\Entity;
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
use App\Core\NoteScope;
|
use App\Core\VisibilityScope;
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,9 +213,9 @@ class Note extends Entity
|
|||||||
{
|
{
|
||||||
return Cache::get('note-attachments-' . $this->id, function () {
|
return Cache::get('note-attachments-' . $this->id, function () {
|
||||||
return DB::dql(
|
return DB::dql(
|
||||||
'select f from App\Entity\File f ' .
|
'select att from App\Entity\Attachment att ' .
|
||||||
'join App\Entity\FileToNote ftn with ftn.file_id = f.id ' .
|
'join App\Entity\AttachmentToNote atn with atn.attachment_id = att.id ' .
|
||||||
'where ftn.note_id = :note_id',
|
'where atn.note_id = :note_id',
|
||||||
['note_id' => $this->id]
|
['note_id' => $this->id]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -247,7 +247,7 @@ class Note extends Entity
|
|||||||
*/
|
*/
|
||||||
public function isVisibleTo(/* GSActor|LocalUser */ $a): bool
|
public function isVisibleTo(/* GSActor|LocalUser */ $a): bool
|
||||||
{
|
{
|
||||||
$scope = NoteScope::create($this->scope);
|
$scope = VisibilityScope::create($this->scope);
|
||||||
return $scope->public
|
return $scope->public
|
||||||
|| ($scope->follower
|
|| ($scope->follower
|
||||||
&& null != DB::find('follow', ['follower' => $a->getId(), 'followed' => $this->gsactor_id]))
|
&& null != DB::find('follow', ['follower' => $a->getId(), 'followed' => $this->gsactor_id]))
|
||||||
@ -274,7 +274,7 @@ class Note extends Entity
|
|||||||
'source' => ['type' => 'varchar', 'foreign key' => true, 'length' => 32, 'target' => 'NoteSource.code', 'multiplicity' => 'many to one', 'description' => 'fkey to source of note, like "web", "im", or "clientname"'],
|
'source' => ['type' => 'varchar', 'foreign key' => true, 'length' => 32, 'target' => 'NoteSource.code', 'multiplicity' => 'many to one', 'description' => 'fkey to source of note, like "web", "im", or "clientname"'],
|
||||||
'conversation' => ['type' => 'int', 'foreign key' => true, 'target' => 'Conversation.id', 'multiplicity' => 'one to one', 'description' => 'the local conversation id'],
|
'conversation' => ['type' => 'int', 'foreign key' => true, 'target' => 'Conversation.id', 'multiplicity' => 'one to one', 'description' => 'the local conversation id'],
|
||||||
'repeat_of' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'description' => 'note this is a repeat of'],
|
'repeat_of' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'description' => 'note this is a repeat of'],
|
||||||
'scope' => ['type' => 'int', 'not null' => true, 'default' => NoteScope::PUBLIC, 'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = groups; 8 = followers; 16 = messages; null = default'],
|
'scope' => ['type' => 'int', 'not null' => true, 'default' => VisibilityScope::PUBLIC, 'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = groups; 8 = followers; 16 = messages; null = default'],
|
||||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user