[COMPONENT][Group] Fix group creation, Refactor related entities to inside the component

Other minor bug fixes and improvements
This commit is contained in:
Diogo Peralta Cordeiro 2021-12-27 17:27:07 +00:00
parent d03572e366
commit c9d05d71f5
Signed by: diogo
GPG Key ID: 18D2D35001FBFAB0
11 changed files with 78 additions and 63 deletions

View File

@ -29,6 +29,7 @@ use App\Core\DB\DB;
use App\Core\Form; 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\Core\UserRoles;
use App\Entity\Actor; use App\Entity\Actor;
use App\Entity as E; use App\Entity as E;
use App\Util\Common; use App\Util\Common;
@ -36,6 +37,8 @@ use App\Util\Exception\ClientException;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use App\Util\Form\ActorForms; use App\Util\Form\ActorForms;
use App\Util\Nickname; use App\Util\Nickname;
use Component\Group\Entity\GroupMember;
use Component\Group\Entity\LocalGroup;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -58,7 +61,7 @@ class Group extends ActorController
public function groupViewNickname(Request $request, string $nickname) public function groupViewNickname(Request $request, string $nickname)
{ {
Nickname::validate($nickname, which: Nickname::CHECK_LOCAL_GROUP); // throws Nickname::validate($nickname, which: Nickname::CHECK_LOCAL_GROUP); // throws
$group = Actor::getByNickname($nickname, type: Actor::GROUP); $group = LocalGroup::getActorByNickname($nickname);
if (\is_null($group)) { if (\is_null($group)) {
$actor = Common::actor(); $actor = Common::actor();
if (!\is_null($actor)) { if (!\is_null($actor)) {
@ -75,21 +78,21 @@ class Group extends ActorController
), ),
); );
$group = Actor::create([ DB::persist($group = Actor::create([
'nickname' => $nickname, 'nickname' => $nickname,
'type' => Actor::GROUP, 'type' => Actor::GROUP,
'is_local' => true, 'is_local' => true,
]); 'roles' => UserRoles::BOT,
DB::persist($group); ]));
DB::persist(LocalGroup::create([
'group_id' => $group->getId(),
'nickname' => $nickname,
]));
DB::persist(E\Subscription::create([ DB::persist(E\Subscription::create([
'subscriber' => $group->getId(), 'subscriber' => $group->getId(),
'subscribed' => $group->getId(), 'subscribed' => $group->getId(),
])); ]));
DB::persist(E\Subscription::create([ DB::persist(GroupMember::create([
'subscriber' => $actor->getId(),
'subscribed' => $group->getId(),
]));
DB::persist(E\GroupMember::create([
'group_id' => $group->getId(), 'group_id' => $group->getId(),
'actor_id' => $actor->getId(), 'actor_id' => $actor->getId(),
'is_admin' => true, 'is_admin' => true,
@ -97,7 +100,7 @@ class Group extends ActorController
DB::flush(); DB::flush();
Cache::delete(Actor::cacheKeys($actor->getId())['subscriber']); Cache::delete(Actor::cacheKeys($actor->getId())['subscriber']);
Cache::delete(Actor::cacheKeys($actor->getId())['subscribed']); Cache::delete(Actor::cacheKeys($actor->getId())['subscribed']);
throw new RedirectException; throw new RedirectException();
} }
return [ return [
@ -114,6 +117,7 @@ class Group extends ActorController
join activity a with n.id = a.object_id join activity a with n.id = a.object_id
join group_inbox gi with a.id = gi.activity_id join group_inbox gi with a.id = gi.activity_id
where a.object_type = 'note' and gi.group_id = :group_id where a.object_type = 'note' and gi.group_id = :group_id
order by a.created desc, a.id desc
EOF, EOF,
['group_id' => $group->getId()], ['group_id' => $group->getId()],
) : []; ) : [];
@ -128,7 +132,7 @@ class Group extends ActorController
public function groupSettings(Request $request, string $nickname) public function groupSettings(Request $request, string $nickname)
{ {
$group = Actor::getByNickname($nickname, type: Actor::GROUP); $group = LocalGroup::getActorByNickname($nickname);
$actor = Common::actor(); $actor = Common::actor();
if (!\is_null($group) && $actor->canAdmin($group)) { if (!\is_null($group) && $actor->canAdmin($group)) {
return [ return [

View File

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types = 1);
// {{{ 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
// //
@ -17,7 +19,7 @@
// 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 Component\Group\Entity;
use App\Core\Entity; use App\Core\Entity;
use DateTimeInterface; use DateTimeInterface;
@ -42,11 +44,11 @@ class GroupAlias extends Entity
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
private string $alias; private string $alias;
private int $group_id; private int $group_id;
private \DateTimeInterface $modified; private DateTimeInterface $modified;
public function setAlias(string $alias): self public function setAlias(string $alias): self
{ {
$this->alias = \mb_substr($alias, 0, 64); $this->alias = mb_substr($alias, 0, 64);
return $this; return $this;
} }
@ -66,13 +68,13 @@ class GroupAlias extends Entity
return $this->group_id; return $this->group_id;
} }
public function setModified(\DateTimeInterface $modified): self public function setModified(DateTimeInterface $modified): self
{ {
$this->modified = $modified; $this->modified = $modified;
return $this; return $this;
} }
public function getModified(): \DateTimeInterface public function getModified(): DateTimeInterface
{ {
return $this->modified; return $this->modified;
} }

View File

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types = 1);
// {{{ 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
// //
@ -17,7 +19,7 @@
// 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 Component\Group\Entity;
use App\Core\Entity; use App\Core\Entity;
use DateTimeInterface; use DateTimeInterface;
@ -43,7 +45,7 @@ class GroupBlock extends Entity
private int $group_id; private int $group_id;
private int $blocked_actor; private int $blocked_actor;
private int $blocker_user; private int $blocker_user;
private \DateTimeInterface $modified; private DateTimeInterface $modified;
public function setGroupId(int $group_id): self public function setGroupId(int $group_id): self
{ {
@ -78,13 +80,13 @@ class GroupBlock extends Entity
return $this->blocker_user; return $this->blocker_user;
} }
public function setModified(\DateTimeInterface $modified): self public function setModified(DateTimeInterface $modified): self
{ {
$this->modified = $modified; $this->modified = $modified;
return $this; return $this;
} }
public function getModified(): \DateTimeInterface public function getModified(): DateTimeInterface
{ {
return $this->modified; return $this->modified;
} }

View File

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types = 1);
// {{{ 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
// //
@ -17,7 +19,7 @@
// 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 Component\Group\Entity;
use App\Core\Entity; use App\Core\Entity;
use DateTimeInterface; use DateTimeInterface;
@ -42,7 +44,7 @@ class GroupInbox extends Entity
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
private int $group_id; private int $group_id;
private int $activity_id; private int $activity_id;
private \DateTimeInterface $created; private DateTimeInterface $created;
public function setGroupId(int $group_id): self public function setGroupId(int $group_id): self
{ {
@ -66,13 +68,13 @@ class GroupInbox extends Entity
return $this->activity_id; return $this->activity_id;
} }
public function setCreated(\DateTimeInterface $created): self public function setCreated(DateTimeInterface $created): self
{ {
$this->created = $created; $this->created = $created;
return $this; return $this;
} }
public function getCreated(): \DateTimeInterface public function getCreated(): DateTimeInterface
{ {
return $this->created; return $this->created;
} }

View File

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types = 1);
// {{{ 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
// //
@ -17,7 +19,7 @@
// 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 Component\Group\Entity;
use App\Core\Entity; use App\Core\Entity;

View File

@ -19,7 +19,7 @@ declare(strict_types = 1);
// 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 Component\Group\Entity;
use App\Core\Entity; use App\Core\Entity;
use DateTimeInterface; use DateTimeInterface;
@ -45,9 +45,9 @@ class GroupMember extends Entity
private int $group_id; private int $group_id;
private int $actor_id; private int $actor_id;
private ?bool $is_admin = false; private ?bool $is_admin = false;
private ?string $uri = null; private ?string $uri = null;
private \DateTimeInterface $created; private DateTimeInterface $created;
private \DateTimeInterface $modified; private DateTimeInterface $modified;
public function setGroupId(int $group_id): self public function setGroupId(int $group_id): self
{ {
@ -84,7 +84,7 @@ class GroupMember extends Entity
public function setUri(?string $uri): self public function setUri(?string $uri): self
{ {
$this->uri = \is_null($uri) ? null : \mb_substr($uri, 0, 191); $this->uri = \is_null($uri) ? null : mb_substr($uri, 0, 191);
return $this; return $this;
} }
@ -93,24 +93,24 @@ class GroupMember extends Entity
return $this->uri; return $this->uri;
} }
public function setCreated(\DateTimeInterface $created): self public function setCreated(DateTimeInterface $created): self
{ {
$this->created = $created; $this->created = $created;
return $this; return $this;
} }
public function getCreated(): \DateTimeInterface public function getCreated(): DateTimeInterface
{ {
return $this->created; return $this->created;
} }
public function setModified(\DateTimeInterface $modified): self public function setModified(DateTimeInterface $modified): self
{ {
$this->modified = $modified; $this->modified = $modified;
return $this; return $this;
} }
public function getModified(): \DateTimeInterface public function getModified(): DateTimeInterface
{ {
return $this->modified; return $this->modified;
} }

View File

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types = 1);
// {{{ License // {{{ License
// This file is part of GNU social - https://www.gnu.org/software/soci // This file is part of GNU social - https://www.gnu.org/software/soci
// //
@ -17,11 +19,12 @@
// 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 Component\Group\Entity;
use App\Core\DB\DB; use App\Core\DB\DB;
use App\Core\Entity; use App\Core\Entity;
use App\Entity\Actor;
use DateTimeInterface; use DateTimeInterface;
/** /**
@ -44,8 +47,8 @@ class LocalGroup extends Entity
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
private int $group_id; private int $group_id;
private ?string $nickname = null; private ?string $nickname = null;
private \DateTimeInterface $created; private DateTimeInterface $created;
private \DateTimeInterface $modified; private DateTimeInterface $modified;
public function setGroupId(int $group_id): self public function setGroupId(int $group_id): self
{ {
@ -60,7 +63,7 @@ class LocalGroup extends Entity
public function setNickname(?string $nickname): self public function setNickname(?string $nickname): self
{ {
$this->nickname = \is_null($nickname) ? null : \mb_substr($nickname, 0, 64); $this->nickname = \is_null($nickname) ? null : mb_substr($nickname, 0, 64);
return $this; return $this;
} }
@ -69,24 +72,24 @@ class LocalGroup extends Entity
return $this->nickname; return $this->nickname;
} }
public function setCreated(\DateTimeInterface $created): self public function setCreated(DateTimeInterface $created): self
{ {
$this->created = $created; $this->created = $created;
return $this; return $this;
} }
public function getCreated(): \DateTimeInterface public function getCreated(): DateTimeInterface
{ {
return $this->created; return $this->created;
} }
public function setModified(\DateTimeInterface $modified): self public function setModified(DateTimeInterface $modified): self
{ {
$this->modified = $modified; $this->modified = $modified;
return $this; return $this;
} }
public function getModified(): \DateTimeInterface public function getModified(): DateTimeInterface
{ {
return $this->modified; return $this->modified;
} }
@ -99,6 +102,18 @@ class LocalGroup extends Entity
return DB::find('actor', ['id' => $this->group_id]); return DB::find('actor', ['id' => $this->group_id]);
} }
public static function getByNickname(string $nickname): ?self
{
$res = DB::findBy(self::class, ['nickname' => $nickname]);
return $res === [] ? null : $res[0];
}
public static function getActorByNickname(string $nickname): ?Actor
{
$res = DB::findBy(Actor::class, ['nickname' => $nickname, 'type' => Actor::GROUP]);
return $res === [] ? null : $res[0];
}
public static function schemaDef(): array public static function schemaDef(): array
{ {
return [ return [

View File

@ -31,6 +31,7 @@ use App\Util\Common;
use App\Util\HTML; use App\Util\HTML;
use App\Util\Nickname; use App\Util\Nickname;
use Component\Group\Controller as C; use Component\Group\Controller as C;
use Component\Group\Entity\LocalGroup;
use Component\Tag\Controller\Tag as TagController; use Component\Tag\Controller\Tag as TagController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -62,7 +63,7 @@ class Group extends Component
{ {
if ($section === 'profile' && $request->get('_route') === 'group_settings') { if ($section === 'profile' && $request->get('_route') === 'group_settings') {
$nickname = $request->get('nickname'); $nickname = $request->get('nickname');
$group = Actor::getByNickname($nickname, type: Actor::GROUP); $group = LocalGroup::getActorByNickname($nickname);
$tabs[] = [ $tabs[] = [
'title' => 'Self tags', 'title' => 'Self tags',
'desc' => 'Add or remove tags on this group', 'desc' => 'Add or remove tags on this group',
@ -82,7 +83,7 @@ class Group extends Component
if (!\is_null($id = $request->get('id'))) { if (!\is_null($id = $request->get('id'))) {
return Actor::getById((int) $id); return Actor::getById((int) $id);
} elseif (!\is_null($nickname = $request->get('nickname'))) { } elseif (!\is_null($nickname = $request->get('nickname'))) {
return Actor::getByNickname($nickname, type: Actor::GROUP); return LocalGroup::getActorByNickname($nickname);
} }
} }
return null; return null;

View File

@ -34,7 +34,6 @@ use App\Core\Security;
use App\Core\VisibilityScope; use App\Core\VisibilityScope;
use App\Entity\Activity; use App\Entity\Activity;
use App\Entity\Actor; use App\Entity\Actor;
use App\Entity\GroupInbox;
use App\Entity\Note; use App\Entity\Note;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\BugFoundException; use App\Util\Exception\BugFoundException;
@ -47,6 +46,8 @@ use App\Util\Formatting;
use Component\Attachment\Entity\ActorToAttachment; use Component\Attachment\Entity\ActorToAttachment;
use Component\Attachment\Entity\AttachmentToNote; use Component\Attachment\Entity\AttachmentToNote;
use Component\Conversation\Conversation; use Component\Conversation\Conversation;
use Component\Group\Entity\GroupInbox;
use Component\Group\Entity\LocalGroup;
use Component\Language\Entity\Language; use Component\Language\Entity\Language;
use Functional as F; use Functional as F;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@ -255,13 +256,13 @@ class Posting extends Component
switch ($target[0]) { switch ($target[0]) {
case '!': case '!':
$mentions[] = [ $mentions[] = [
'mentioned' => [Actor::getByNickname(mb_substr($target, 1), type: Actor::GROUP)], 'mentioned' => [LocalGroup::getActorByNickname(mb_substr($target, 1))],
'type' => 'group', 'type' => 'group',
'text' => mb_substr($target, 1), 'text' => mb_substr($target, 1),
]; ];
break; break;
default: default:
throw new ClientException(_m('Unkown target type give in \'in\' field: ' . $target)); throw new ClientException(_m('Unknown target type give in \'In\' field: ' . $target));
} }
} }

View File

@ -274,20 +274,6 @@ class Actor extends Entity
} }
} }
/**
* @return ?self
*/
public static function getByNickname(string $nickname, int $type = self::PERSON): ?self
{
try {
return DB::findOneBy(self::class, ['nickname' => $nickname, 'type' => $type]);
} catch (NotFoundException) {
return null;
} catch (DuplicateFoundException $e) {
throw new BugFoundException("Multiple actors with the same nickname '{$nickname}' found", previous: $e);
}
}
public function getAvatarUrl(string $size = 'medium') public function getAvatarUrl(string $size = 'medium')
{ {
return Avatar::getUrl($this->getId(), $size); return Avatar::getUrl($this->getId(), $size);
@ -560,7 +546,6 @@ class Actor extends Entity
} }
}, },
); );
break;
default: default:
return false; return false;
} }

View File

@ -38,6 +38,7 @@ use App\Entity\Actor;
use App\Entity\Note; use App\Entity\Note;
use App\Util\Exception\NicknameException; use App\Util\Exception\NicknameException;
use App\Util\Exception\ServerException; use App\Util\Exception\ServerException;
use Component\Group\Entity\LocalGroup;
use Exception; use Exception;
use Functional as F; use Functional as F;
use InvalidArgumentException; use InvalidArgumentException;
@ -356,7 +357,7 @@ abstract class Formatting
$group_matches = self::findMentionsRaw($text, '!'); $group_matches = self::findMentionsRaw($text, '!');
foreach ($group_matches as $group_match) { foreach ($group_matches as $group_match) {
$nickname = Nickname::normalize($group_match[0], check_already_used: false, check_is_allowed: false); $nickname = Nickname::normalize($group_match[0], check_already_used: false, check_is_allowed: false);
$group = Actor::getByNickname($nickname, Actor::GROUP); $group = LocalGroup::getActorByNickname($nickname, Actor::GROUP);
$mentions[] = [ $mentions[] = [
'mentioned' => [$group], 'mentioned' => [$group],