<?php
namespace App\Subscriber\User;
use App\Dictionary\PaymentType;
use App\Entity\ActivityFeed;
use App\Entity\BalanceMember;
use App\Event\Content\CommentCreatedEvent;
use App\Event\Content\ContentPublishedEvent;
use App\Event\Guestbook\GuestbookCommentChangedEvent;
use App\Event\Guestbook\GuestbookEntryAcceptedEvent;
use App\Event\Guestbook\GuestbookEntryCreatedEvent;
use App\Event\Guestbook\GuestbookEntryHideEvent;
use App\Event\Guestbook\GuestbookEntrySpamEvent;
use App\Event\Messenger\NewMessageEvent;
use App\Event\Payment\PaymentCreatedEvent;
use App\Event\Payment\PurchaseCreatedEvent;
use App\Event\User\FriendshipRequestedEvent;
use App\Event\User\LivecamOnlineEvent;
use App\Event\User\LoginCreatedEvent;
use App\Event\User\MemberCreatedEvent;
use App\Event\User\ProfileVisitEvent;
use App\Service\ActivityFeedService;
use App\Service\Content\ContentService;
use App\Service\MembersIgnoredService;
use App\Service\User\BalanceMemberService;
use App\Service\User\FriendshipService;
use Frivol\Common\Dict\ActivityFeedType;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ActivityFeedSubscriber implements EventSubscriberInterface
{
protected ActivityFeedService $service;
protected MembersIgnoredService $ignoreService;
protected FriendshipService $friendshipService;
protected ContentService $contentService;
protected BalanceMemberService $balanceMemberService;
public function __construct(
ActivityFeedService $activityFeed, MembersIgnoredService $ignoreService, FriendshipService $friendshipService,
ContentService $contentService, BalanceMemberService $balanceMemberService)
{
$this->service = $activityFeed;
$this->ignoreService = $ignoreService;
$this->friendshipService = $friendshipService;
$this->contentService = $contentService;
$this->balanceMemberService = $balanceMemberService;
}
public static function getSubscribedEvents(): array
{
return [
LoginCreatedEvent::class => [
['onLoginCreateActivityFeed', 0],
],
PaymentCreatedEvent::class => [
['onPaymentCreateActivityFeed', 0],
],
ProfileVisitEvent::class => [
['onProfileVisitCreateActivityFeed', 0],
],
GuestbookEntryAcceptedEvent::class => [
['addActivityOnGuestbookEntryAccept', 0],
],
GuestbookEntryCreatedEvent::class => [
['addActivityOnNewGuestbookEntry', 0],
],
GuestbookEntryHideEvent::class => [
['deleteActivityOnGuestbookHide', 0],
],
GuestbookEntrySpamEvent::class => [
['deleteActivityOnGuestbookSpam', 0],
],
GuestbookCommentChangedEvent::class => [
['handleActivityOnGuestbookCommentChange', 0],
],
CommentCreatedEvent::class => [
['addActivityOnContentComment', 0],
],
FriendshipRequestedEvent::class => [
['onFriendshipRequestCreateActivityFeed', 0],
],
ContentPublishedEvent::class => [
['onContentPublishedCreateActivityFeed', 0],
],
LivecamOnlineEvent::class => [
['onWebcamOnlineCreateActivityFeed', 2],
],
MemberCreatedEvent::class => [
['onMemberCreatedCreateActivityFeed', 0],
],
NewMessageEvent::class => [
['onNewMessageCreateActivity', 0],
],
PurchaseCreatedEvent::class => [
['onBalanceMemberCreateContentPurchaseActivity', 0],
],
];
}
public function onMemberCreatedCreateActivityFeed(MemberCreatedEvent $event): void
{
$member = $event->getMember();
if ($member->getAccount()->hasWebmaster() || $member->getIsAmateur()) {
return;
}
$activity = $this->service->createRegistrationCompletedActivity($member);
$this->service->storeEntity($activity);
}
public function onWebcamOnlineCreateActivityFeed(LivecamOnlineEvent $event): void
{
$member = $event->getMember();
$activity = $this->service->createWebcamOnlineActivity($member);
$this->service->storeActivity($activity);
}
public function onLoginCreateActivityFeed(LoginCreatedEvent $event): void
{
$member = $event->getLogin()->getAccount()->getMember();
if (!$member || $this->ignoreService->isIgnored($member)) {
return;
}
if (!$this->service->canStoreNewActivity($member->getId(), ActivityFeedType::LOGIN)) {
return;
}
$activity = $this->service->createLoginActivity($member);
$this->service->storeEntity($activity);
// $friends = $this->friendshipService->getOnlineFriendsIndex($member, 1, 50)->getQuery()->getResult();
// $newActivities = $this->service->createFriendLoginActivities($member, $friends);
// foreach ($newActivities as $activity) {
// $this->service->storeEntity($activity, false);
// }
// $this->service->delayedFlush();
}
public function onPaymentCreateActivityFeed(PaymentCreatedEvent $event): void
{
$payment = $event->getPayment();
if (PaymentType::BOOKING !== $payment->getType()) {
return;
}
$member = $payment->getAccount()->getMember();
$entity = $this->service->createEntityByMember($member, ActivityFeedType::CONTENT_PURCHASE);
$entity->setCreatedAt($event->getPayment()->getCreatedAt());
$entity->setSpecs([
'paymentId' => $payment->getId(),
'method' => $payment->getMethod(),
'amount' => $payment->getAmount(),
]);
$this->service->storeEntity($entity);
}
public function onBalanceMemberCreateContentPurchaseActivity(PurchaseCreatedEvent $event): void
{
/** @var BalanceMember $balanceMember */
$balanceMemberIds = $event->getPurchase()->getBalanceMember();
if (null === $balanceMember = $this->balanceMemberService->findById(array_pop($balanceMemberIds))) {
return;
}
if (!$balanceMember->isTypeOutput()) {
return;
}
if (null === $content = $this->contentService->getContentById($event->getPurchasable()->getReferenceId())) {
return;
}
$activity = null;
if ($content->isImageset()) {
$activity = $this->service->createContentImagesetPurchaseActivity($balanceMember->getMember(), $content);
}
if ($content->isVideo()) {
$activity = $this->service->createContentVideoPurchaseActivity($balanceMember->getMember(), $content);
}
$amateurActivity = $this->service->createMemberActivityActivity($balanceMember->getMember());
if (null === $activity) {
return;
}
$this->service->storeEntity($activity, false);
$this->service->storeEntity($amateurActivity);
}
public function addActivityOnNewGuestbookEntry(GuestbookEntryCreatedEvent $event): void
{
$activity = $this->service->createGuestbookEntryActivity($event->getEntry());
$this->service->storeEntity($activity);
}
public function addActivityOnGuestbookEntryAccept(GuestbookEntryAcceptedEvent $event): void
{
$activity = $this->service->createGuestbookEntryActivity($event->getEntry());
$this->service->storeEntity($activity);
}
public function deleteActivityOnGuestbookHide(GuestbookEntryHideEvent $event): void
{
if (false === $event->getNewHiddenState()) {
$this->service->removeActivitiesForGuestbookEntry($event->getEntry());
}
}
public function deleteActivityOnGuestbookSpam(GuestbookEntrySpamEvent $event): void
{
if (true === $event->getNewSpamState()) {
$this->service->removeActivitiesForGuestbookEntry($event->getEntry());
}
}
public function handleActivityOnGuestbookCommentChange(GuestbookCommentChangedEvent $event): void
{
$comment = $event->getEntry()->getComment();
$presentActivity = $this->service->getRepository()->findActivityByGuestbookEntryComment($event->getEntry());
if (('' === $comment || null === $comment) && $presentActivity instanceof ActivityFeed) {
$this->service->removeEntity($presentActivity);
return;
}
if (null === $presentActivity && strlen($comment) > 5) {
$activity = $this->service->createGuestbookCommentActivity($event->getEntry());
$this->service->storeActivity($activity);
}
}
public function addActivityOnContentComment(CommentCreatedEvent $event): void
{
$presentActivity = $this->service
->getRepository()
->findContentCommentActivitiesByContentComment($event->getComment());
if (null !== $presentActivity) {
return;
}
$af = $this->service->createContentCommentActivity($event->getComment());
if ($af) {
$this->service->storeActivity($af);
}
}
public function onProfileVisitCreateActivityFeed(ProfileVisitEvent $event): void
{
if ($event->getVisitor() === $event->getProfileOwner()) {
// ignore self visits
return;
}
$activity = $this->service->createEntityByMember($event->getVisitor(), ActivityFeedType::PROFILE_VISIT);
$activity->setVisibleTo($event->getProfileOwner());
$this->service->storeEntity($activity);
}
public function onFriendshipRequestCreateActivityFeed(FriendshipRequestedEvent $event): void
{
$sender = $event->getFriendship()->getOwnerMember();
$recipient = $event->getFriendship()->getTargetMember();
$entity = $this->service->createFriendshipAskActivity($sender, $recipient);
$this->service->storeActivity($entity);
}
public function onContentPublishedCreateActivityFeed(ContentPublishedEvent $event): void
{
$content = $event->getContent();
if (!$content->isPublished()) {
throw new \DomainException('Content not published.');
}
$author = $event->getAuthor();
if (!$author) {
throw new \DomainException('Missing author on published content.');
}
$activity = $this->service->createContentPublishedActivity($author, $content);
$this->service->storeActivity($activity);
if (null !== $activity = $this->service->createContentVideoPublishedActivity($author, $content)) {
$this->service->storeActivity($activity);
}
if (null !== $activity = $this->service->createContentImagesetPublishedActivity($author, $content)) {
$this->service->storeActivity($activity);
}
}
public function onNewMessageCreateActivity(NewMessageEvent $event): void
{
if ((null === $sender = $event->getSender()) || (null === $conversationMessage = $event->getEntity())) {
return;
}
if (null === $recipient = $conversationMessage->getConversation()?->getPartner($sender)) {
return;
}
$activity = $this->service->createNewMessageActivity($sender, $recipient);
$this->service->storeActivity($activity);
}
}