forked from GNUsocial/gnu-social
		
	[PLUGIN][ActivityPub] Simplify DB usage
This commit is contained in:
		| @@ -125,7 +125,7 @@ class FreeNetworkActorProtocol extends Entity | ||||
|         } else { | ||||
|             $attributed_protocol->setProtocol($protocol); | ||||
|         } | ||||
|         DB::wrapInTransaction(fn () => DB::persist($attributed_protocol)); | ||||
|         DB::persist($attributed_protocol); | ||||
|     } | ||||
|  | ||||
|     public static function canIActor(string $protocol, int|Actor $actor_id): bool | ||||
|   | ||||
| @@ -48,6 +48,7 @@ use App\Util\Common; | ||||
| use App\Util\Exception\BugFoundException; | ||||
| use App\Util\Exception\NoSuchActorException; | ||||
| use App\Util\Nickname; | ||||
| use Codeception\Coverage\Subscriber\Local; | ||||
| use Component\Collection\Util\Controller\OrderedCollection; | ||||
| use Component\FreeNetwork\Entity\FreeNetworkActorProtocol; | ||||
| use Component\FreeNetwork\Util\Discovery; | ||||
| @@ -148,7 +149,7 @@ class ActivityPub extends Plugin | ||||
|             // Is remote? | ||||
|             !$actor->getIsLocal() | ||||
|             // Is in ActivityPub? | ||||
|             && !\is_null($ap_actor = ActivitypubActor::getByPK(['actor_id' => $actor->getId()])) | ||||
|             && !\is_null($ap_actor = DB::findOneBy(ActivitypubActor::class, ['actor_id' => $actor->getId()], return_null: true)) | ||||
|             // We can only provide a full URL (anything else wouldn't make sense) | ||||
|             && $type === Router::ABSOLUTE_URL | ||||
|         ) { | ||||
| @@ -166,8 +167,8 @@ class ActivityPub extends Plugin | ||||
|     { | ||||
|         // Are both in AP? | ||||
|         if ( | ||||
|             !\is_null($ap_actor = ActivitypubActor::getByPK(['actor_id' => $actor->getId()])) | ||||
|             && !\is_null($ap_other = ActivitypubActor::getByPK(['actor_id' => $other->getId()])) | ||||
|             !\is_null($ap_actor = DB::findOneBy(ActivitypubActor::class, ['actor_id' => $actor->getId()], return_null: true)) | ||||
|             && !\is_null($ap_other = DB::findOneBy(ActivitypubActor::class, ['actor_id' => $other->getId()], return_null: true)) | ||||
|         ) { | ||||
|             // Are they both in the same server? | ||||
|             $canAdmin = parse_url($ap_actor->getUri(), PHP_URL_HOST) === parse_url($ap_other->getUri(), PHP_URL_HOST); | ||||
| @@ -258,7 +259,7 @@ class ActivityPub extends Plugin | ||||
|         $to_addr = []; | ||||
|         foreach ($targets as $actor) { | ||||
|             if (FreeNetworkActorProtocol::canIActor('activitypub', $actor->getId())) { | ||||
|                 if (\is_null($ap_target = ActivitypubActor::getByPK(['actor_id' => $actor->getId()]))) { | ||||
|                 if (\is_null($ap_target = DB::findOneBy(ActivitypubActor::class, ['actor_id' => $actor->getId()], return_null: true))) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 $to_addr[$ap_target->getInboxSharedUri() ?? $ap_target->getInboxUri()][] = $actor; | ||||
| @@ -405,7 +406,7 @@ class ActivityPub extends Plugin | ||||
|                     return $object->getUrl(); | ||||
|                 } else { | ||||
|                     // Try known remote objects | ||||
|                     $known_object = ActivitypubObject::getByPK(['object_type' => 'note', 'object_id' => $object->getId()]); | ||||
|                     $known_object = DB::findOneBy(ActivitypubObject::class, ['object_type' => 'note', 'object_id' => $object->getId()], return_null: true); | ||||
|                     if ($known_object instanceof ActivitypubObject) { | ||||
|                         return $known_object->getObjectUri(); | ||||
|                     } else { | ||||
| @@ -418,8 +419,8 @@ class ActivityPub extends Plugin | ||||
|                 break; | ||||
|             case Activity::class: | ||||
|                 // Try known remote activities | ||||
|                 $known_activity = ActivitypubActivity::getByPK(['activity_id' => $object->getId()]); | ||||
|                 if ($known_activity instanceof ActivitypubActivity) { | ||||
|                 $known_activity = DB::findOneBy(ActivitypubActivity::class, ['activity_id' => $object->getId()], return_null: true); | ||||
|                 if (!\is_null($known_activity)) { | ||||
|                     return $known_activity->getActivityUri(); | ||||
|                 } else { | ||||
|                     return Router::url('activity_view', ['id' => $object->getId()], Router::ABSOLUTE_URL); | ||||
| @@ -444,14 +445,14 @@ class ActivityPub extends Plugin | ||||
|     public static function getObjectByUri(string $resource, bool $try_online = true) | ||||
|     { | ||||
|         // Try known object | ||||
|         $known_object = ActivitypubObject::getByPK(['object_uri' => $resource]); | ||||
|         if ($known_object instanceof ActivitypubObject) { | ||||
|         $known_object = DB::findOneBy(ActivitypubObject::class, ['object_uri' => $resource], return_null: true); | ||||
|         if (!\is_null($known_object)) { | ||||
|             return $known_object->getObject(); | ||||
|         } | ||||
|  | ||||
|         // Try known activity | ||||
|         $known_activity = ActivitypubActivity::getByPK(['activity_uri' => $resource]); | ||||
|         if ($known_activity instanceof ActivitypubActivity) { | ||||
|         $known_activity = DB::findOneBy(ActivitypubActivity::class, ['activity_uri' => $resource], return_null: true); | ||||
|         if (!\is_null($known_activity)) { | ||||
|             return $known_activity->getActivity(); | ||||
|         } | ||||
|  | ||||
| @@ -477,14 +478,14 @@ class ActivityPub extends Plugin | ||||
|  | ||||
|         // Try remote | ||||
|         if (!$try_online) { | ||||
|             return; | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         $response = HTTPClient::get($resource, ['headers' => self::HTTP_CLIENT_HEADERS]); | ||||
|         // If it was deleted | ||||
|         if ($response->getStatusCode() == 410) { | ||||
|             //$obj = Type::create('Tombstone', ['id' => $resource]); | ||||
|             return; | ||||
|             return null; | ||||
|         } elseif (!HTTPClient::statusCodeIsOkay($response)) { // If it is unavailable | ||||
|             throw new Exception('Non Ok Status Code for given Object id.'); | ||||
|         } else { | ||||
| @@ -514,7 +515,7 @@ class ActivityPub extends Plugin | ||||
|                 // actor_view_id | ||||
|                 $reuri = '/\/actor\/(\d+)\/?/m'; | ||||
|                 if (preg_match_all($renick, $str, $matches, PREG_SET_ORDER, 0) === 1) { | ||||
|                     return LocalUser::getByPK(['nickname' => $matches[0][1]])->getActor(); | ||||
|                     return DB::findOneBy(LocalUser::class, ['nickname' => $matches[0][1]])->getActor(); | ||||
|                 } elseif (preg_match_all($reuri, $str, $matches, PREG_SET_ORDER, 0) === 1) { | ||||
|                     return Actor::getById((int) $matches[0][1]); | ||||
|                 } | ||||
|   | ||||
| @@ -96,9 +96,8 @@ class Inbox extends Controller | ||||
|         try { | ||||
|             $resource_parts = parse_url($type->get('actor')); | ||||
|             if ($resource_parts['host'] !== Common::config('site', 'server')) { | ||||
|                 $ap_actor = ActivitypubActor::fromUri($type->get('actor')); | ||||
|                 $ap_actor =  DB::wrapInTransaction(fn() => ActivitypubActor::fromUri($type->get('actor'))); | ||||
|                 $actor    = Actor::getById($ap_actor->getActorId()); | ||||
|                 DB::flush(); | ||||
|             } else { | ||||
|                 throw new Exception('Only remote actors can use this endpoint.'); | ||||
|             } | ||||
| @@ -173,8 +172,8 @@ class Inbox extends Controller | ||||
|         if (!empty($ap_act->_object_mention_ids)) { | ||||
|             $already_known_ids = $ap_act->_object_mention_ids; | ||||
|         } | ||||
|         Event::handle('NewNotification', [$actor, $ap_act->getActivity(), $already_known_ids, _m('{nickname} mentioned you.', ['{nickname}' => $actor->getNickname()])]); | ||||
|         DB::flush(); | ||||
|         Event::handle('NewNotification', [$actor, $ap_act->getActivity(), $already_known_ids, _m('{nickname} mentioned you.', ['{nickname}' => $actor->getNickname()])]); | ||||
|  | ||||
|         dd($ap_act, $act = $ap_act->getActivity(), $act->getActor(), $act->getObject()); | ||||
|  | ||||
|   | ||||
| @@ -261,7 +261,10 @@ class ActivitypubActor 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'  => ['actor_id'], | ||||
|             'primary key'  => ['uri'], | ||||
|             'unique keys' => [ | ||||
|                 'activitypub_actor_id_ukey' => ['actor_id'], | ||||
|             ], | ||||
|             'foreign keys' => [ | ||||
|                 'activitypub_actor_actor_id_fkey' => ['actor', ['actor_id' => 'id']], | ||||
|             ], | ||||
|   | ||||
| @@ -147,7 +147,7 @@ class ActivitypubRsa extends Entity | ||||
|      */ | ||||
|     public static function getByActor(Actor $gsactor, bool $fetch = true): self | ||||
|     { | ||||
|         $apRSA = self::getByPK(['actor_id' => ($actor_id = $gsactor->getId())]); | ||||
|         $apRSA = DB::findOneBy(self::class, ['actor_id' => ($actor_id = $gsactor->getId())], return_null: true); | ||||
|         if (\is_null($apRSA)) { | ||||
|             // Nonexistent key pair for this profile | ||||
|             if ($gsactor->getIsLocal()) { | ||||
| @@ -157,7 +157,7 @@ class ActivitypubRsa extends Entity | ||||
|                     'private_key' => $private_key, | ||||
|                     'public_key'  => $public_key, | ||||
|                 ]); | ||||
|                 DB::wrapInTransaction(fn () => DB::persist($apRSA)); | ||||
|                 DB::persist($apRSA); | ||||
|             } else { | ||||
|                 // ASSERT: This should never happen, but try to recover! | ||||
|                 Log::error('Activitypub_rsa: An impossible thing has happened... Please let the devs know.'); | ||||
|   | ||||
| @@ -32,6 +32,7 @@ declare(strict_types = 1); | ||||
|  | ||||
| namespace Plugin\ActivityPub\Util; | ||||
|  | ||||
| use App\Core\DB\DB; | ||||
| use App\Core\HTTPClient; | ||||
| use App\Core\Log; | ||||
| use App\Util\Exception\NoSuchActorException; | ||||
| @@ -152,8 +153,8 @@ class Explorer | ||||
|  | ||||
|         // Try standard ActivityPub route | ||||
|         // Is this a known filthy little mudblood? | ||||
|         $aprofile = self::get_aprofile_by_url($uri); | ||||
|         if ($aprofile instanceof ActivitypubActor) { | ||||
|         $aprofile = DB::findOneBy(ActivitypubActor::class, ['uri' => $uri], return_null: true); | ||||
|         if (!\is_null($aprofile)) { | ||||
|             Log::debug('ActivityPub Explorer: Found a known Aprofile for ' . $uri); | ||||
|  | ||||
|             // We found something! | ||||
| @@ -216,19 +217,6 @@ class Explorer | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a ActivityPub Profile from it's uri | ||||
|      * | ||||
|      * @param string $v URL | ||||
|      * | ||||
|      * @return ActivitypubActor|bool false if fails | Aprofile object if successful | ||||
|      */ | ||||
|     public static function get_aprofile_by_url(string $v): ActivitypubActor|bool | ||||
|     { | ||||
|         $aprofile = ActivitypubActor::getByPK(['uri' => $v]); | ||||
|         return \is_null($aprofile) ? false : ActivitypubActor::getByPK(['uri' => $v]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Allows the Explorer to transverse a collection of persons. | ||||
|      * | ||||
|   | ||||
| @@ -34,6 +34,7 @@ namespace Plugin\ActivityPub\Util\Model; | ||||
|  | ||||
| use ActivityPhp\Type; | ||||
| use ActivityPhp\Type\AbstractObject; | ||||
| use App\Core\DB\DB; | ||||
| use App\Core\Event; | ||||
| use App\Core\Router\Router; | ||||
| use App\Entity\Activity as GSActivity; | ||||
| @@ -79,7 +80,7 @@ class Activity extends Model | ||||
|  | ||||
|         // Ditch known activities | ||||
|         if ($type_activity->has('id')) { // We can't dereference a transient activity | ||||
|             $ap_act = ActivitypubActivity::getByPK(['activity_uri' => $type_activity->get('id')]); | ||||
|             $ap_act = DB::findOneBy(ActivitypubActivity::class, ['activity_uri' => $type_activity->get('id')], return_null: true); | ||||
|             if (!\is_null($ap_act)) { | ||||
|                 return $ap_act; | ||||
|             } | ||||
|   | ||||
| @@ -104,49 +104,46 @@ class Actor extends Model | ||||
|         } | ||||
|  | ||||
|         // Actor | ||||
|         $actor_map = [ | ||||
|             'nickname' => $object->get('preferredUsername'), | ||||
|             'fullname' => !empty($object->get('name')) ? $object->get('name') : null, | ||||
|             'created'  => new DateTime($object->get('published') ?? 'now'), | ||||
|             'bio'      => $object->get('summary'), | ||||
|             'is_local' => false, // duh! | ||||
|             'type'     => self::$_as2_actor_type_to_gs_actor_type[$object->get('type')], | ||||
|             'roles'    => $roles, | ||||
|             'modified' => new DateTime(), | ||||
|         ]; | ||||
|  | ||||
|         $actor = $options['objects']['Actor'] ?? new GSActor(); | ||||
|  | ||||
|         foreach ($actor_map as $prop => $val) { | ||||
|             $set = Formatting::snakeCaseToCamelCase("set_{$prop}"); | ||||
|             $actor->{$set}($val); | ||||
|         } | ||||
|  | ||||
|         if (!isset($options['objects']['Actor'])) { | ||||
|             DB::wrapInTransaction(fn () => DB::persist($actor)); | ||||
|         if (isset($options['objects']['Actor'])) { | ||||
|             $actor = $options['objects']['Actor']; | ||||
|         } else { | ||||
|             $actor_map = [ | ||||
|                 'nickname' => $object->get('preferredUsername'), | ||||
|                 'fullname' => !empty($object->get('name')) ? $object->get('name') : null, | ||||
|                 'created'  => new DateTime($object->get('published') ?? 'now'), | ||||
|                 'bio'      => $object->get('summary'), | ||||
|                 'is_local' => false, // duh! | ||||
|                 'type'     => self::$_as2_actor_type_to_gs_actor_type[$object->get('type')], | ||||
|                 'roles'    => $roles, | ||||
|                 'modified' => new DateTime(), | ||||
|             ]; | ||||
|             $actor = GSActor::create($actor_map); | ||||
|             DB::persist($actor); | ||||
|         } | ||||
|  | ||||
|         // ActivityPub Actor | ||||
|         $ap_actor = ActivitypubActor::create([ | ||||
|             'inbox_uri'        => $object->get('inbox'), | ||||
|             'inbox_shared_uri' => ($object->has('endpoints') && isset($object->get('endpoints')['sharedInbox'])) ? $object->get('endpoints')['sharedInbox'] : null, | ||||
|             'uri'              => $object->get('id'), | ||||
|             'actor_id'         => $actor->getId(), | ||||
|             'url'              => $object->get('url') ?? null, | ||||
|         ], $options['objects']['ActivitypubActor'] ?? null); | ||||
|  | ||||
|         if (!isset($options['objects']['ActivitypubActor'])) { | ||||
|             DB::wrapInTransaction(fn () => DB::persist($ap_actor)); | ||||
|         if (isset($options['objects']['ActivitypubActor'])) { | ||||
|             $ap_actor = $options['objects']['ActivitypubActor']; | ||||
|         } else { | ||||
|             $ap_actor = ActivitypubActor::create([ | ||||
|                 'inbox_uri'        => $object->get('inbox'), | ||||
|                 'inbox_shared_uri' => ($object->has('endpoints') && isset($object->get('endpoints')['sharedInbox'])) ? $object->get('endpoints')['sharedInbox'] : null, | ||||
|                 'uri'              => $object->get('id'), | ||||
|                 'actor_id'         => $actor->getId(), | ||||
|                 'url'              => $object->get('url') ?? null, | ||||
|             ], $options['objects']['ActivitypubActor'] ?? null); | ||||
|             DB::persist($ap_actor); | ||||
|         } | ||||
|  | ||||
|         // Public Key | ||||
|         $apRSA = ActivitypubRsa::create([ | ||||
|             'actor_id'   => $actor->getID(), | ||||
|             'public_key' => ($object->has('publicKey') && isset($object->get('publicKey')['publicKeyPem'])) ? $object->get('publicKey')['publicKeyPem'] : null, | ||||
|         ], $options['objects']['ActivitypubRsa'] ?? null); | ||||
|  | ||||
|         if (!isset($options['objects']['ActivitypubRsa'])) { | ||||
|             DB::wrapInTransaction(fn () => DB::persist($apRSA)); | ||||
|         if (isset($options['objects']['ActivitypubRsa'])) { | ||||
|             $apRSA = $options['objects']['ActivitypubRsa']; | ||||
|         } else { | ||||
|             $apRSA = ActivitypubRsa::create([ | ||||
|                 'actor_id'   => $actor->getID(), | ||||
|                 'public_key' => ($object->has('publicKey') && isset($object->get('publicKey')['publicKeyPem'])) ? $object->get('publicKey')['publicKeyPem'] : null, | ||||
|             ], $options['objects']['ActivitypubRsa'] ?? null); | ||||
|             DB::persist($apRSA); | ||||
|         } | ||||
|  | ||||
|         // Avatar | ||||
| @@ -170,14 +167,14 @@ class Actor extends Model | ||||
|                         if (!\is_null($avatar = DB::findOneBy(\Component\Avatar\Entity\Avatar::class, ['actor_id' => $actor->getId()], return_null: true))) { | ||||
|                             $avatar->delete(); | ||||
|                         } | ||||
|                         DB::wrapInTransaction(function () use ($attachment, $actor, $object) { | ||||
|  | ||||
|                             DB::persist($attachment); | ||||
|                             DB::persist(\Component\Avatar\Entity\Avatar::create([ | ||||
|                                 'actor_id'      => $actor->getId(), | ||||
|                                 'attachment_id' => $attachment->getId(), | ||||
|                                 'title'         => $object->get('icon')->get('name') ?? null, | ||||
|                             ])); | ||||
|                         }); | ||||
|  | ||||
|                         Event::handle('AvatarUpdate', [$actor->getId()]); | ||||
|                     } | ||||
|                 } | ||||
| @@ -216,7 +213,7 @@ class Actor extends Model | ||||
|         $uri        = $object->getUri(Router::ABSOLUTE_URL); | ||||
|         $attr       = [ | ||||
|             '@context'  => 'https://www.w3.org/ns/activitystreams', | ||||
|             'type'      => ($object->getType() === GSActor::GROUP) ? (LocalGroup::getByPK(['actor_id' => $object->getId()])->getType() === 'organisation' ? 'Organization' : 'Group'): self::$_gs_actor_type_to_as2_actor_type[$object->getType()], | ||||
|             'type'      => ($object->getType() === GSActor::GROUP) ? (DB::findOneBy(LocalGroup::class, ['actor_id' => $object->getId()], return_null: true)?->getType() === 'organisation' ? 'Organization' : 'Group'): self::$_gs_actor_type_to_as2_actor_type[$object->getType()], | ||||
|             'id'        => $uri, | ||||
|             'inbox'     => Router::url('activitypub_actor_inbox', ['gsactor_id' => $object->getId()], Router::ABSOLUTE_URL), | ||||
|             'outbox'    => Router::url('activitypub_actor_outbox', ['gsactor_id' => $object->getId()], Router::ABSOLUTE_URL), | ||||
|   | ||||
| @@ -188,7 +188,7 @@ class Note extends Model | ||||
|                 continue; | ||||
|             } | ||||
|             try { | ||||
|                 $actor                                = ActivityPub::getActorByUri($target); | ||||
|                 $actor = ActivityPub::getActorByUri($target); | ||||
|                 $object_mentions_ids[$actor->getId()] = $target; | ||||
|                 // If $to is a group and note is unlisted, set note's scope as Group | ||||
|                 if ($actor->isGroup() && $map['scope'] === 'unlisted') { | ||||
| @@ -209,18 +209,14 @@ class Note extends Model | ||||
|                 continue; | ||||
|             } | ||||
|             try { | ||||
|                 $actor                                = ActivityPub::getActorByUri($target); | ||||
|                 $actor = ActivityPub::getActorByUri($target); | ||||
|                 $object_mentions_ids[$actor->getId()] = $target; | ||||
|             } catch (Exception $e) { | ||||
|                 Log::debug('ActivityPub->Model->Note->fromJson->getActorByUri', [$e]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $obj = new GSNote(); | ||||
|         foreach ($map as $prop => $val) { | ||||
|             $set = Formatting::snakeCaseToCamelCase("set_{$prop}"); | ||||
|             $obj->{$set}($val); | ||||
|         } | ||||
|         $obj = GSNote::create($map); | ||||
|  | ||||
|         // Attachments | ||||
|         $processed_attachments = []; | ||||
| @@ -235,7 +231,7 @@ class Note extends Model | ||||
|                     // Create an attachment for this | ||||
|                     $temp_file = new TemporaryFile(); | ||||
|                     $temp_file->write($media); | ||||
|                     $filesize      = $temp_file->getSize(); | ||||
|                     $filesize = $temp_file->getSize(); | ||||
|                     $max_file_size = Common::getUploadLimit(); | ||||
|                     if ($max_file_size < $filesize) { | ||||
|                         throw new ClientException(_m('No file may be larger than {quota} bytes and the file you sent was {size} bytes. ' | ||||
| @@ -258,7 +254,7 @@ class Note extends Model | ||||
|                 case 'Mention': | ||||
|                 case 'Group': | ||||
|                     try { | ||||
|                         $actor                                = ActivityPub::getActorByUri($ap_tag->get('href')); | ||||
|                         $actor = ActivityPub::getActorByUri($ap_tag->get('href')); | ||||
|                         $object_mentions_ids[$actor->getId()] = $ap_tag->get('href'); | ||||
|                     } catch (Exception $e) { | ||||
|                         Log::debug('ActivityPub->Model->Note->fromJson->getActorByUri', [$e]); | ||||
| @@ -276,8 +272,8 @@ class Note extends Model | ||||
|                     } | ||||
|                     break; | ||||
|                 case 'Hashtag': | ||||
|                     $match         = ltrim($ap_tag->get('name'), '#'); | ||||
|                     $tag           = Tag::extract($match); | ||||
|                     $match = ltrim($ap_tag->get('name'), '#'); | ||||
|                     $tag = Tag::extract($match); | ||||
|                     $canonical_tag = $ap_tag->get('canonical') ?? Tag::canonicalTag($tag, \is_null($lang_id = $obj->getLanguageId()) ? null : Language::getById($lang_id)->getLocale()); | ||||
|                     DB::persist(NoteTag::create([ | ||||
|                         'tag'           => $tag, | ||||
| @@ -418,7 +414,7 @@ class Note extends Model | ||||
|                 'type'      => 'Document', | ||||
|                 'mediaType' => $attachment->getMimetype(), | ||||
|                 'url'       => $attachment->getUrl(note: $object, type: Router::ABSOLUTE_URL), | ||||
|                 'name'      => AttachmentToNote::getByPK(['attachment_id' => $attachment->getId(), 'note_id' => $object->getId()])->getTitle(), | ||||
|                 'name'      => DB::findOneBy(AttachmentToNote::class, ['attachment_id' => $attachment->getId(), 'note_id' => $object->getId()], return_null: true)?->getTitle(), | ||||
|                 'width'     => $attachment->getWidth(), | ||||
|                 'height'    => $attachment->getHeight(), | ||||
|             ]; | ||||
|   | ||||
| @@ -24,7 +24,9 @@ declare(strict_types = 1); | ||||
| namespace Plugin\Favourite\Controller; | ||||
|  | ||||
| use App\Core\DB\DB; | ||||
| use App\Core\Event; | ||||
| use App\Core\Form; | ||||
| use App\Entity\Actor; | ||||
| use function App\Core\I18n\_m; | ||||
| use App\Core\Log; | ||||
| use App\Core\Router\Router; | ||||
| @@ -72,8 +74,9 @@ class Favourite extends FeedController | ||||
|         $form_add_to_favourite->handleRequest($request); | ||||
|  | ||||
|         if ($form_add_to_favourite->isSubmitted()) { | ||||
|             if (!\is_null(\Plugin\Favourite\Favourite::favourNote(note_id: $id, actor_id: $actor_id))) { | ||||
|             if (!\is_null($activity = \Plugin\Favourite\Favourite::favourNote(note_id: $id, actor_id: $actor_id))) { | ||||
|                 DB::flush(); | ||||
|                 Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $activity, [], _m('{nickname} favoured note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]); | ||||
|             } else { | ||||
|                 throw new ClientException(_m('Note already favoured!')); | ||||
|             } | ||||
| @@ -131,8 +134,10 @@ class Favourite extends FeedController | ||||
|  | ||||
|         $form_remove_favourite->handleRequest($request); | ||||
|         if ($form_remove_favourite->isSubmitted()) { | ||||
|             if (!\is_null(\Plugin\Favourite\Favourite::unfavourNote(note_id: $id, actor_id: $actor_id))) { | ||||
|             if (!\is_null($activity = \Plugin\Favourite\Favourite::unfavourNote(note_id: $id, actor_id: $actor_id))) { | ||||
|                 DB::flush(); | ||||
|                 Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $activity, [], _m('{nickname} unfavoured note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]); | ||||
|  | ||||
|             } else { | ||||
|                 throw new ClientException(_m('Note already unfavoured!')); | ||||
|             } | ||||
|   | ||||
| @@ -81,7 +81,6 @@ class Favourite extends NoteHandlerPlugin | ||||
|             ]); | ||||
|             DB::persist($activity); | ||||
|  | ||||
|             Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $activity, [], _m('{nickname} favoured note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]); | ||||
|         } | ||||
|         return $activity; | ||||
|     } | ||||
| @@ -116,8 +115,6 @@ class Favourite extends NoteHandlerPlugin | ||||
|                 'source'      => $source, | ||||
|             ]); | ||||
|             DB::persist($activity); | ||||
|  | ||||
|             Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $activity, [], _m('{nickname} unfavoured note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]); | ||||
|         } | ||||
|         return $activity; | ||||
|     } | ||||
| @@ -287,7 +284,8 @@ class Favourite extends NoteHandlerPlugin | ||||
|         if ($type_activity->get('type') === 'Like') { // Favourite | ||||
|             if ($type_object instanceof \ActivityPhp\Type\AbstractObject) { | ||||
|                 if ($type_object->get('type') === 'Note' || $type_object->get('type') === 'Page') { | ||||
|                     $note_id = \Plugin\ActivityPub\Util\Model\Note::fromJson($type_object)->getId(); | ||||
|                     $note    = \Plugin\ActivityPub\Util\Model\Note::fromJson($type_object); | ||||
|                     $note_id = $note->getId(); | ||||
|                 } else { | ||||
|                     return Event::next; | ||||
|                 } | ||||
| @@ -315,9 +313,15 @@ class Favourite extends NoteHandlerPlugin | ||||
|         } | ||||
|  | ||||
|         if ($type_activity->get('type') === 'Like') { | ||||
|             $activity = self::favourNote($note_id, $actor->getId(), source: 'ActivityPub'); | ||||
|             if (!\is_null($activity = self::favourNote($note_id, $actor->getId(), source: 'ActivityPub'))) { | ||||
|                 DB::flush(); | ||||
|                 Event::handle('NewNotification', [$actor, $activity, [], _m('{nickname} favoured note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]); | ||||
|             } | ||||
|         } else { | ||||
|             $activity = self::unfavourNote($note_id, $actor->getId(), source: 'ActivityPub'); | ||||
|             if (!\is_null($activity = self::unfavourNote($note_id, $actor->getId(), source: 'ActivityPub'))) { | ||||
|                 DB::flush(); | ||||
|                 Event::handle('NewNotification', [$actor, $activity, [], _m('{nickname} unfavoured note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]); | ||||
|             } | ||||
|         } | ||||
|         if (!\is_null($activity)) { | ||||
|             // Store ActivityPub Activity | ||||
|   | ||||
| @@ -25,7 +25,9 @@ namespace Plugin\RepeatNote\Controller; | ||||
|  | ||||
| use App\Core\Controller; | ||||
| use App\Core\DB\DB; | ||||
| use App\Core\Event; | ||||
| use App\Core\Form; | ||||
| use App\Entity\Actor; | ||||
| use function App\Core\I18n\_m; | ||||
| use App\Core\Log; | ||||
| use App\Core\Router\Router; | ||||
| @@ -71,8 +73,10 @@ class Repeat extends Controller | ||||
|  | ||||
|         $form_add_to_repeat->handleRequest($request); | ||||
|         if ($form_add_to_repeat->isSubmitted()) { | ||||
|             \Plugin\RepeatNote\RepeatNote::repeatNote(note: $note, actor_id: $actor_id); | ||||
|             $repeat_activity = \Plugin\RepeatNote\RepeatNote::repeatNote(note: $note, actor_id: $actor_id); | ||||
|             DB::flush(); | ||||
|             Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $repeat_activity, [], _m('{nickname} repeated note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $repeat_activity->getObjectId()])]); | ||||
|  | ||||
|  | ||||
|             // Redirect user to where they came from | ||||
|             // Prevent open redirect | ||||
| @@ -127,8 +131,9 @@ class Repeat extends Controller | ||||
|  | ||||
|         $form_remove_repeat->handleRequest($request); | ||||
|         if ($form_remove_repeat->isSubmitted()) { | ||||
|             if (!\is_null(\Plugin\RepeatNote\RepeatNote::unrepeatNote(note_id: $note_id, actor_id: $actor_id))) { | ||||
|             if (!\is_null($undo_repeat_activity = \Plugin\RepeatNote\RepeatNote::unrepeatNote(note_id: $note_id, actor_id: $actor_id))) { | ||||
|                 DB::flush(); | ||||
|                 Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $undo_repeat_activity, [], _m('{nickname} unrepeated note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $note_id])]); | ||||
|             } else { | ||||
|                 throw new ClientException(_m('Note wasn\'t repeated!')); | ||||
|             } | ||||
|   | ||||
| @@ -110,11 +110,6 @@ class RepeatNote extends NoteHandlerPlugin | ||||
|         ]); | ||||
|         DB::persist($repeat_activity); | ||||
|  | ||||
|         // Flush before notification | ||||
|         DB::flush(); | ||||
|  | ||||
|         Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $repeat_activity, [], _m('{nickname} repeated note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $repeat_activity->getObjectId()])]); | ||||
|  | ||||
|         return $repeat_activity; | ||||
|     } | ||||
|  | ||||
| @@ -165,8 +160,6 @@ class RepeatNote extends NoteHandlerPlugin | ||||
|             ]); | ||||
|             DB::persist($undo_repeat_activity); | ||||
|  | ||||
|             Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $undo_repeat_activity, [], _m('{nickname} unrepeated note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $note_id])]); | ||||
|  | ||||
|             return $undo_repeat_activity; | ||||
|         } else { | ||||
|             // Either was undoed already | ||||
| @@ -397,9 +390,15 @@ class RepeatNote extends NoteHandlerPlugin | ||||
|         } | ||||
|  | ||||
|         if ($type_activity->get('type') === 'Announce') { | ||||
|             $activity = self::repeatNote($note ?? Note::getById($note_id), $actor->getId(), source: 'ActivityPub'); | ||||
|             if (!\is_null($activity = self::repeatNote($note ?? Note::getById($note_id), $actor->getId(), source: 'ActivityPub'))) { | ||||
|                 DB::flush(); | ||||
|                 Event::handle('NewNotification', [$actor, $activity, [], _m('{nickname} repeated note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]); | ||||
|             } | ||||
|         } else { | ||||
|             $activity = self::unrepeatNote($note_id, $actor->getId(), source: 'ActivityPub'); | ||||
|             if (!\is_null($activity = self::unrepeatNote($note_id, $actor->getId(), source: 'ActivityPub'))) { | ||||
|                 DB::flush(); | ||||
|                 Event::handle('NewNotification', [$actor, $activity, [], _m('{nickname} unrepeated note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $note_id])]); | ||||
|             } | ||||
|         } | ||||
|         if (!\is_null($activity)) { | ||||
|             // Store ActivityPub Activity | ||||
|   | ||||
| @@ -52,14 +52,22 @@ use Functional as F; | ||||
|  * @mixin EntityManager | ||||
|  * @template T of Entity | ||||
|  * | ||||
|  * @method static ?T find(string $class, array<string, mixed> $values)                                                                                                                                                                                                                                        // Finds an Entity by its identifier. | ||||
|  * @method static ?T getReference(string $class, array<string, mixed> $values) // Special cases: It's like find but does not load the object if it has not been loaded yet, it only returns a proxy to the object. (https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/unitofwork.html) | ||||
|  * @method static void remove(object $entity)                                                                                                                                                                                                                                                                 // Removes an entity instance. | ||||
|  * @method static T merge(object $entity)                                                                                                                                                                                                                                                                     // Merges the state of a detached entity into the persistence context | ||||
|  * @method static void persist(object $entity)                                                                                                                                                                                                                                                                // Tells the EntityManager to make an instance managed and persistent. | ||||
|  * @method static bool contains(object $entity)                                                                                                                                                                                                                                                               // Determines whether an entity instance is managed in this EntityManager. | ||||
|  * @method static void flush()                                                                                                                                                                                                                                                                                // Flushes the in-memory state of persisted objects to the database. | ||||
|  * @method mixed  wrapInTransaction(callable $func)                                                                                                                                                                                                                                                           // Executes a function in a transaction. Warning: suppresses exceptions | ||||
|  * // Finds an Entity by its identifier. You probably want to use DB::findBy instead | ||||
|  * @method static ?T find(string $class, array<string, mixed> $values) | ||||
|  * // Special cases: It's like find but does not load the object if it has not been loaded yet, it only returns a proxy to the object. (https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/unitofwork.html) | ||||
|  * @method static ?T getReference(string $class, array<string, mixed> $values) | ||||
|  * // Removes an entity instance. | ||||
|  * @method static void remove(object $entity) | ||||
|  * // Merges the state of a detached entity into the persistence context | ||||
|  * @method static T merge(object $entity) | ||||
|  *  // Tells the EntityManager to make an instance managed and persistent. | ||||
|  * @method static void persist(object $entity) | ||||
|  * // Determines whether an entity instance is managed in this EntityManager. | ||||
|  * @method static bool contains(object $entity) | ||||
|  * // Flushes the in-memory state of persisted objects to the database. | ||||
|  * @method static void flush() | ||||
|  * // Executes a function in a transaction. Warning: suppresses exceptions. Returns the result of the callable. | ||||
|  * @method mixed  wrapInTransaction(callable $func) | ||||
|  */ | ||||
| class DB | ||||
| { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user