[CORE][ENTITY] Properly port ProfileTag, ProfileTagSubscription and ProfileList as ActorTag, ActorTagSubscription and ActorCircle
This commit is contained in:
parent
11d2cfb9ed
commit
51994406da
@ -42,11 +42,10 @@ use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Entity\ActorCircle;
|
||||
use App\Entity\ActorLanguage;
|
||||
use App\Entity\Language;
|
||||
use App\Entity\UserNotificationPrefs;
|
||||
use App\Util\Common;
|
||||
use App\Util\Exception\AuthenticationException;
|
||||
use App\Util\Exception\RedirectException;
|
||||
@ -55,6 +54,7 @@ use App\Util\Form\ActorArrayTransformer;
|
||||
use App\Util\Form\ArrayTransformer;
|
||||
use App\Util\Form\FormFields;
|
||||
use App\Util\Formatting;
|
||||
use Component\Notification\Entity\UserNotificationPrefs;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Exception;
|
||||
use Functional as F;
|
||||
@ -66,6 +66,7 @@ use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\SubmitButton;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use function App\Core\I18n\_m;
|
||||
|
||||
// }}} Imports
|
||||
|
||||
@ -110,9 +111,6 @@ class UserPanel extends Controller
|
||||
];
|
||||
$extra_step = function ($data, $extra_args) use ($user, $actor) {
|
||||
$user->setNickname($data['nickname']);
|
||||
if (!$data['full_name'] && !$actor->getFullname()) {
|
||||
$actor->setFullname($data['nickname']);
|
||||
}
|
||||
};
|
||||
return Form::handle($form_definition, $request, $actor, $extra, $extra_step, [['self_tags' => $extra['self_tags']]]);
|
||||
}
|
||||
|
@ -199,11 +199,11 @@ class GSFile
|
||||
* Throw a client exception if the cache key $id doesn't contain
|
||||
* exactly one entry
|
||||
*/
|
||||
public static function error($except, $id, array $res)
|
||||
public static function error($exception, $id, array $res)
|
||||
{
|
||||
switch (\count($res)) {
|
||||
case 0:
|
||||
throw new $except();
|
||||
throw new $exception();
|
||||
case 1:
|
||||
return $res[0];
|
||||
default:
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types = 1);
|
||||
declare(strict_types=1);
|
||||
|
||||
// {{{ License
|
||||
|
||||
@ -35,6 +35,8 @@ use App\Util\Nickname;
|
||||
use Component\Avatar\Avatar;
|
||||
use DateTimeInterface;
|
||||
use Functional as F;
|
||||
use function in_array;
|
||||
use function is_null;
|
||||
|
||||
/**
|
||||
* Entity for actors
|
||||
@ -57,7 +59,7 @@ class Actor extends Entity
|
||||
private int $id;
|
||||
private string $nickname;
|
||||
private ?string $fullname = null;
|
||||
private int $roles = 4;
|
||||
private int $roles = 4;
|
||||
private ?string $homepage;
|
||||
private ?string $bio;
|
||||
private ?string $location;
|
||||
@ -91,7 +93,7 @@ class Actor extends Entity
|
||||
return $this->nickname;
|
||||
}
|
||||
|
||||
public function setFullname(string $fullname): self
|
||||
public function setFullname(?string $fullname): self
|
||||
{
|
||||
$this->fullname = $fullname;
|
||||
return $this;
|
||||
@ -99,7 +101,7 @@ class Actor extends Entity
|
||||
|
||||
public function getFullname(): ?string
|
||||
{
|
||||
if (\is_null($this->fullname)) {
|
||||
if (is_null($this->fullname)) {
|
||||
return null;
|
||||
}
|
||||
return $this->fullname;
|
||||
@ -245,43 +247,123 @@ class Actor extends Entity
|
||||
|
||||
public static function getById(int $id): ?self
|
||||
{
|
||||
return Cache::get('actor-id-' . $id, fn () => DB::find('actor', ['id' => $id]));
|
||||
return Cache::get('actor-id-' . $id, fn() => DB::find('actor', ['id' => $id]));
|
||||
}
|
||||
|
||||
public static function getNicknameById(int $id): string
|
||||
{
|
||||
return Cache::get('actor-nickname-id-' . $id, fn () => self::getById($id)->getNickname());
|
||||
return Cache::get('actor-nickname-id-' . $id, fn() => self::getById($id)->getNickname());
|
||||
}
|
||||
|
||||
public static function getFullnameById(int $id): ?string
|
||||
{
|
||||
return Cache::get('actor-fullname-id-' . $id, fn () => self::getById($id)->getFullname());
|
||||
return Cache::get('actor-fullname-id-' . $id, fn() => self::getById($id)->getFullname());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags attributed to self
|
||||
*
|
||||
* @return [ActorCircle]
|
||||
*/
|
||||
public function getSelfTags(bool $_test_force_recompute = false): array
|
||||
{
|
||||
return Cache::get(
|
||||
'selftags-' . $this->id,
|
||||
fn () => DB::findBy('actor_tag', ['tagger' => $this->id, 'tagged' => $this->id]),
|
||||
beta: $_test_force_recompute ? \INF : 1.0,
|
||||
);
|
||||
return $this->getOtherTags(scoped: $this->getId(), _test_force_recompute: $_test_force_recompute);
|
||||
}
|
||||
|
||||
public function setSelfTags(array $tags, array $existing): void
|
||||
/**
|
||||
* Get tags that other people put on this actor, in reverse-chron order
|
||||
*
|
||||
* @param Actor|int|null $scoped Actor we are requesting as:
|
||||
* - If null = All tags attributed to self by other actors (excludes self tags)
|
||||
* - If self = Same as getSelfTags
|
||||
* - otherwise = Tags that $scoped attributed to $this
|
||||
* @param int|null $offset Offset from latest
|
||||
* @param int|null $limit Max number to get
|
||||
* @param bool $_test_force_recompute
|
||||
* @return [ActorCircle] resulting lists
|
||||
*/
|
||||
public function getOtherTags(Actor|int|null $scoped = null, ?int $offset = null, ?int $limit = null, bool $_test_force_recompute = false): array
|
||||
{
|
||||
$tag_existing = F\map($existing, fn ($pt) => $pt->getTag());
|
||||
$tag_to_add = array_diff($tags, $tag_existing);
|
||||
$tag_to_remove = array_diff($tag_existing, $tags);
|
||||
$pt_to_remove = F\filter($existing, fn ($pt) => \in_array($pt->getTag(), $tag_to_remove));
|
||||
foreach ($tag_to_add as $tag) {
|
||||
$pt = ActorTag::create(['tagger' => $this->id, 'tagged' => $this->id, 'tag' => $tag]);
|
||||
DB::persist($pt);
|
||||
if (is_null($scoped)) {
|
||||
return Cache::get(
|
||||
"othertags-{$this->getId()}",
|
||||
fn() => DB::dql(
|
||||
<<< EOQ
|
||||
SELECT circle
|
||||
FROM App\Entity\ActorTag tag
|
||||
JOIN App\Entity\ActorCircle circle
|
||||
WITH
|
||||
tag.tagger = circle.tagger
|
||||
AND tag.tag = circle.tag
|
||||
WHERE tag.tagged = :id
|
||||
ORDER BY tag.modified DESC, tag.tagged DESC
|
||||
EOQ,
|
||||
['id' => $this->getId()],
|
||||
['offset' => $offset,
|
||||
'limit' => $limit])
|
||||
);
|
||||
} else {
|
||||
$scoped_id = is_int($scoped) ? $scoped : $scoped->getId();
|
||||
return Cache::get(
|
||||
"othertags-{$this->getId()}-by-{$scoped_id}",
|
||||
fn() => DB::dql(
|
||||
<<< EOQ
|
||||
SELECT circle
|
||||
FROM App\Entity\ActorTag tag
|
||||
JOIN App\Entity\ActorCircle circle
|
||||
WITH
|
||||
tag.tagger = circle.tagger
|
||||
AND tag.tag = circle.tag
|
||||
WHERE
|
||||
tag.tagged = :id
|
||||
AND ( circle.private != true
|
||||
OR ( circle.tagger = :scoped
|
||||
AND circle.private = true
|
||||
)
|
||||
)
|
||||
ORDER BY tag.modified DESC, tag.tagged DESC
|
||||
EOQ,
|
||||
['id' => $this->getId(),
|
||||
'scoped' => $scoped_id],
|
||||
['offset' => $offset,
|
||||
'limit' => $limit]
|
||||
)
|
||||
);
|
||||
}
|
||||
foreach ($pt_to_remove as $pt) {
|
||||
DB::persist($pt);
|
||||
DB::remove($pt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $tags array of strings to become self tags
|
||||
* @param array|null $existing array of existing self tags (actor_circle[])
|
||||
* @return $this
|
||||
* @throws NotFoundException
|
||||
* @throws \App\Util\Exception\DuplicateFoundException
|
||||
*/
|
||||
public function setSelfTags(array $tags, ?array $existing = null): self
|
||||
{
|
||||
if (is_null($existing)) {
|
||||
$existing = $this->getSelfTags();
|
||||
}
|
||||
Cache::delete('selftags-' . $this->id);
|
||||
$existing_actor_circles = F\map($existing, fn($actor_circle) => $actor_circle->getTag());
|
||||
$tags_to_add = array_diff($tags, $existing_actor_circles);
|
||||
$tags_to_remove = array_diff($existing_actor_circles, $tags);
|
||||
$actor_circles_to_remove = F\filter($existing, fn($actor_circle) => in_array($actor_circle->getTag(), $tags_to_remove));
|
||||
foreach ($tags_to_add as $tag) {
|
||||
$actor_circle = ActorCircle::create(['tagger' => $this->getId(), 'tag' => $tag, 'private' => false]);
|
||||
$actor_tag = ActorTag::create(['tagger' => $this->id, 'tagged' => $this->id, 'tag' => $tag]);
|
||||
DB::persist($actor_circle);
|
||||
DB::persist($actor_tag);
|
||||
}
|
||||
foreach ($actor_circles_to_remove as $actor_circle) {
|
||||
$actor_tag = DB::findOneBy('actor_tag', ['tagger' => $this->getId(), 'tagged' => $this->getId(), 'tag' => $actor_circle->getTag()]);
|
||||
DB::persist($actor_tag);
|
||||
DB::remove($actor_tag);
|
||||
// TODO: use DB::removeBy when implemented
|
||||
DB::remove(DB::getReference('actor_circle', ['id' => $actor_circle->getId()]));
|
||||
}
|
||||
Cache::delete("selftags-{$this->getId()}");
|
||||
Cache::delete("othertags-{$this->getId()}-by-{$this->getId()}");
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSubscribersCount()
|
||||
@ -290,9 +372,9 @@ class Actor extends Entity
|
||||
'subscribers-' . $this->id,
|
||||
function () {
|
||||
return DB::dql(
|
||||
'select count(f) from App\Entity\Subscription f where f.subscribed = :subscribed',
|
||||
['subscribed' => $this->id],
|
||||
)[0][1] - 1; // Remove self subscription
|
||||
'select count(f) from App\Entity\Subscription f where f.subscribed = :subscribed',
|
||||
['subscribed' => $this->id],
|
||||
)[0][1] - 1; // Remove self subscription
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -303,9 +385,9 @@ class Actor extends Entity
|
||||
'subscribed-' . $this->id,
|
||||
function () {
|
||||
return DB::dql(
|
||||
'select count(f) from App\Entity\Subscription f where f.subscriber = :subscriber',
|
||||
['subscriber' => $this->id],
|
||||
)[0][1] - 1; // Remove self subscription
|
||||
'select count(f) from App\Entity\Subscription f where f.subscriber = :subscriber',
|
||||
['subscriber' => $this->id],
|
||||
)[0][1] - 1; // Remove self subscription
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -331,16 +413,16 @@ class Actor extends Entity
|
||||
$nickname = Nickname::normalize($nickname, check_already_used: false);
|
||||
return Cache::get(
|
||||
'relative-nickname-' . $nickname . '-' . $this->getId(),
|
||||
fn () => DB::dql(
|
||||
<<<'EOF'
|
||||
fn() => DB::dql(
|
||||
<<<'EOF'
|
||||
select a from actor a where
|
||||
a.id in (select fa.subscribed from subscription fa join actor aa with fa.subscribed = aa.id where fa.subscriber = :actor_id and aa.nickname = :nickname) or
|
||||
a.id in (select fb.subscriber from subscription fb join actor ab with fb.subscriber = ab.id where fb.subscribed = :actor_id and ab.nickname = :nickname) or
|
||||
a.nickname = :nickname
|
||||
EOF,
|
||||
['nickname' => $nickname, 'actor_id' => $this->getId()],
|
||||
['limit' => 1],
|
||||
)[0] ?? null,
|
||||
['nickname' => $nickname, 'actor_id' => $this->getId()],
|
||||
['limit' => 1],
|
||||
)[0] ?? null,
|
||||
);
|
||||
}
|
||||
|
||||
@ -377,43 +459,43 @@ class Actor extends Entity
|
||||
*/
|
||||
public function getPreferredLanguageChoices(?self $context = null): array
|
||||
{
|
||||
$id = $context?->getId() ?? $this->getId();
|
||||
$key = ActorLanguage::collectionCacheKey($this, $context);
|
||||
$id = $context?->getId() ?? $this->getId();
|
||||
$key = ActorLanguage::collectionCacheKey($this, $context);
|
||||
$langs = Cache::getList(
|
||||
$key,
|
||||
fn () => DB::dql(
|
||||
fn() => DB::dql(
|
||||
'select l from actor_language al join language l with al.language_id = l.id where al.actor_id = :id order by al.ordering ASC',
|
||||
['id' => $id],
|
||||
),
|
||||
) ?: [
|
||||
Language::getFromLocale(Common::config('site', 'language')),
|
||||
];
|
||||
return array_merge(...F\map($langs, fn ($l) => $l->toChoiceFormat()));
|
||||
return array_merge(...F\map($langs, fn($l) => $l->toChoiceFormat()));
|
||||
}
|
||||
|
||||
public static function schemaDef(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'actor',
|
||||
'name' => 'actor',
|
||||
'description' => 'local and remote users, groups and bots are actors, for instance',
|
||||
'fields' => [
|
||||
'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'],
|
||||
'nickname' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'nickname or username'],
|
||||
'fullname' => ['type' => 'text', 'description' => 'display name'],
|
||||
'roles' => ['type' => 'int', 'not null' => true, 'default' => UserRoles::USER, 'description' => 'Bitmap of permissions this actor has'],
|
||||
'homepage' => ['type' => 'text', 'description' => 'identifying URL'],
|
||||
'bio' => ['type' => 'text', 'description' => 'descriptive biography'],
|
||||
'location' => ['type' => 'text', 'description' => 'physical location'],
|
||||
'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'],
|
||||
'fields' => [
|
||||
'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'],
|
||||
'nickname' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'nickname or username'],
|
||||
'fullname' => ['type' => 'text', 'description' => 'display name'],
|
||||
'roles' => ['type' => 'int', 'not null' => true, 'default' => UserRoles::USER, 'description' => 'Bitmap of permissions this actor has'],
|
||||
'homepage' => ['type' => 'text', 'description' => 'identifying URL'],
|
||||
'bio' => ['type' => 'text', 'description' => 'descriptive biography'],
|
||||
'location' => ['type' => 'text', 'description' => 'physical location'],
|
||||
'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_service' => ['type' => 'int', 'description' => 'service used to obtain location id'],
|
||||
'is_local' => ['type' => 'bool', 'not null' => true, 'description' => 'Does this actor have a LocalUser associated'],
|
||||
'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'],
|
||||
'is_local' => ['type' => 'bool', 'not null' => true, 'description' => 'Does this actor have a LocalUser associated'],
|
||||
'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'],
|
||||
],
|
||||
'primary key' => ['id'],
|
||||
'indexes' => [
|
||||
'indexes' => [
|
||||
'actor_nickname_idx' => ['nickname'],
|
||||
],
|
||||
'fulltext indexes' => [
|
||||
|
@ -21,6 +21,8 @@ declare(strict_types = 1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\Entity;
|
||||
use DateTimeInterface;
|
||||
|
||||
@ -35,6 +37,7 @@ use DateTimeInterface;
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @author Hugo Sales <hugo@hsal.es>
|
||||
* @author Diogo Peralta Cordeiro <@diogo.site>
|
||||
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
@ -42,6 +45,7 @@ class ActorCircle extends Entity
|
||||
{
|
||||
// {{{ Autocode
|
||||
// @codeCoverageIgnoreStart
|
||||
private int $id;
|
||||
private int $tagger;
|
||||
private string $tag;
|
||||
private ?string $description;
|
||||
@ -49,6 +53,17 @@ class ActorCircle extends Entity
|
||||
private DateTimeInterface $created;
|
||||
private DateTimeInterface $modified;
|
||||
|
||||
public function setId(int $id): ActorCircle
|
||||
{
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setTagger(int $tagger): self
|
||||
{
|
||||
$this->tagger = $tagger;
|
||||
@ -118,12 +133,32 @@ class ActorCircle extends Entity
|
||||
// @codeCoverageIgnoreEnd
|
||||
// }}} Autocode
|
||||
|
||||
public function getSubscribedActors(?int $offset = null, ?int $limit = null): array
|
||||
{
|
||||
return Cache::get(
|
||||
"circle-{$this->getId()}",
|
||||
fn() => DB::dql(
|
||||
<<< EOQ
|
||||
SELECT actor
|
||||
FROM App\Entity\Actor actor
|
||||
JOIN App\Entity\ActorCircleSubscription subscription
|
||||
WITH actor.id = subscription.actor_id
|
||||
ORDER BY subscription.created DESC, actor.id DESC
|
||||
EOQ,
|
||||
options:
|
||||
['offset' => $offset,
|
||||
'limit' => $limit]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static function schemaDef(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'actor_circle',
|
||||
'description' => 'a actor can have lists of actors, to separate their feed',
|
||||
'fields' => [
|
||||
'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'],
|
||||
'tagger' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'many to one', 'name' => 'actor_list_tagger_fkey', 'not null' => true, 'description' => 'user making the tag'],
|
||||
'tag' => ['type' => 'varchar', 'length' => 64, 'foreign key' => true, 'target' => 'ActorTag.tag', 'multiplicity' => 'many to one', 'not null' => true, 'description' => 'actor tag'], // Join with ActorTag // // so, Doctrine doesn't like that the target is not unique, even though the pair is
|
||||
'description' => ['type' => 'text', 'description' => 'description of the people tag'],
|
||||
@ -131,7 +166,7 @@ class ActorCircle extends Entity
|
||||
'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'],
|
||||
],
|
||||
'primary key' => ['tagger', 'tag'],
|
||||
'primary key' => ['id'],
|
||||
'indexes' => [
|
||||
'actor_list_modified_idx' => ['modified'],
|
||||
'actor_list_tag_idx' => ['tag'],
|
||||
@ -139,4 +174,9 @@ class ActorCircle extends Entity
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getTag();
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ use App\Core\Entity;
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
* Entity for actor Tag Subscription
|
||||
* Entity for actor circle subscriptions
|
||||
*
|
||||
* @category DB
|
||||
* @package GNUsocial
|
||||
@ -33,17 +33,18 @@ use DateTimeInterface;
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @author Hugo Sales <hugo@hsal.es>
|
||||
* @author Diogo Peralta Cordeiro <@diogo.site>
|
||||
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class ActorTagSubscription extends Entity
|
||||
class ActorCircleSubscription extends Entity
|
||||
{
|
||||
// {{{ Autocode
|
||||
// @codeCoverageIgnoreStart
|
||||
private int $actor_id;
|
||||
private int $actor_tag;
|
||||
private \DateTimeInterface $created;
|
||||
private \DateTimeInterface $modified;
|
||||
private int $circle_id;
|
||||
private DateTimeInterface $created;
|
||||
private DateTimeInterface $modified;
|
||||
|
||||
public function setActorId(int $actor_id): self
|
||||
{
|
||||
@ -56,15 +57,15 @@ class ActorTagSubscription extends Entity
|
||||
return $this->actor_id;
|
||||
}
|
||||
|
||||
public function setActorTag(int $actor_tag): self
|
||||
public function setCircleid(int $circle_id): self
|
||||
{
|
||||
$this->actor_tag = $actor_tag;
|
||||
$this->circle_id = $circle_id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getActorTag(): int
|
||||
public function getCircleid(): int
|
||||
{
|
||||
return $this->actor_tag;
|
||||
return $this->circle_id;
|
||||
}
|
||||
|
||||
public function setCreated(DateTimeInterface $created): self
|
||||
@ -95,18 +96,17 @@ class ActorTagSubscription extends Entity
|
||||
public static function schemaDef(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'actor_tag_subscription',
|
||||
'name' => 'actor_tag_subscription',
|
||||
'fields' => [
|
||||
'actor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to one', 'name' => 'actor_tag_subscription_actor_id_fkey', 'not null' => true, 'description' => 'foreign key to actor table'],
|
||||
'actor_tag' => ['type' => 'int', // 'foreign key' => true, 'target' => 'ActorTag.tag', 'multiplicity' => 'one to one', // tag can't unique, but doctrine doesn't understand this
|
||||
'name' => 'actor_tag_subscription_actor_tag_fkey', 'not null' => true, 'description' => 'foreign key to actor_tag', ],
|
||||
'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'],
|
||||
'actor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to one', 'name' => 'actor_circle_subscription_actor_id_fkey', 'not null' => true, 'description' => 'foreign key to actor table'],
|
||||
'circle_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'ActorCircle.id', 'multiplicity' => 'one to one', 'name' => 'actor_circle_subscription_actor_circle_fkey', 'not null' => true, 'description' => 'foreign key to actor_circle'],
|
||||
'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'],
|
||||
],
|
||||
'primary key' => ['actor_tag_id', 'actor_id'],
|
||||
'indexes' => [
|
||||
'actor_tag_subscription_actor_id_idx' => ['actor_id'],
|
||||
'actor_tag_subscription_created_idx' => ['created'],
|
||||
'primary key' => ['circle_id', 'actor_id'],
|
||||
'indexes' => [
|
||||
'actor_circle_subscription_actor_id_idx' => ['actor_id'],
|
||||
'actor_circle_subscription_created_idx' => ['created'],
|
||||
],
|
||||
];
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\Entity;
|
||||
use DateTimeInterface;
|
||||
|
||||
@ -97,7 +99,7 @@ class ActorTag extends Entity
|
||||
return [
|
||||
'name' => 'actor_tag',
|
||||
'fields' => [
|
||||
'tagger' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to one', 'name' => 'actor_tag_tagger_fkey', 'not null' => true, 'description' => 'user making the tag'],
|
||||
'tagger' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to one', 'name' => 'actor_tag_tagger_fkey', 'not null' => true, 'description' => 'actor making the tag'],
|
||||
'tagged' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to one', 'name' => 'actor_tag_tagged_fkey', 'not null' => true, 'description' => 'actor tagged'],
|
||||
'tag' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
|
@ -29,7 +29,7 @@
|
||||
<nav class="profile-info-tags">
|
||||
{% if actor_tags %}
|
||||
{% for tag in actor_tags %}
|
||||
<a href='#'><em>#{{ tag }}</em></a>
|
||||
<a href='#'><em>#{{ tag.getTag() }}</em></a>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{ '(No tags)' | trans }}
|
||||
|
Loading…
Reference in New Issue
Block a user