]> git.mxchange.org Git - friendica.git/commitdiff
Merge branch 'develop' into introduce-phpmd
authorArt4 <art4@wlabs.de>
Thu, 23 Jan 2025 08:56:07 +0000 (08:56 +0000)
committerArt4 <art4@wlabs.de>
Thu, 23 Jan 2025 08:56:07 +0000 (08:56 +0000)
1  2 
composer.json
src/Model/APContact.php
src/Model/GServer.php
src/Model/Item.php
src/Model/ItemInserter.php

diff --cc composer.json
Simple merge
index bfb80686b4f1d47b43ed314ed1353fdf558b0970,a364344a51ffbe0906b880909584329d77b2c19d..9c20b5b28344ea6fc9aeb0284f6402887bdcbcc0
@@@ -164,11 -162,9 +162,11 @@@ class APContac
                        DI::cache()->set($cachekey, System::callstack(20), Duration::FIVE_MINUTES);
                }
  
 +              $local_owner = [];
 +
                if (DI::baseUrl()->isLocalUrl($url) && ($local_uid = User::getIdForURL($url))) {
                        try {
-                               $data = Transmitter::getProfile($local_uid);
+                               $data        = Transmitter::getProfile($local_uid);
                                $local_owner = User::getOwnerDataById($local_uid);
                        } catch(HTTPException\NotFoundException $e) {
                                $data = null;
                        return $fetched_contact;
                }
  
-               $apcontact['url'] = $compacted['@id'];
-               $apcontact['uuid'] = JsonLD::fetchElement($compacted, 'diaspora:guid', '@value');
-               $apcontact['type'] = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type'));
 +              return self::compactProfile($apcontact, $compacted, $url, $fetched_contact, $webfinger, $local_owner);
 +      }
 +
 +      /**
 +       * @param array|bool $fetched_contact
 +       * @param array|bool $local_owner
 +       */
 +      private static function compactProfile(array $apcontact, array $compacted, string $url, $fetched_contact, bool $webfinger, $local_owner): array
 +      {
+               $apcontact['url']       = $compacted['@id'];
+               $apcontact['uuid']      = JsonLD::fetchElement($compacted, 'diaspora:guid', '@value');
+               $apcontact['type']      = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type'));
                $apcontact['following'] = JsonLD::fetchElement($compacted, 'as:following', '@id');
                $apcontact['followers'] = JsonLD::fetchElement($compacted, 'as:followers', '@id');
-               $apcontact['inbox'] = (JsonLD::fetchElement($compacted, 'ldp:inbox', '@id') ?? '');
-               $apcontact['outbox'] = JsonLD::fetchElement($compacted, 'as:outbox', '@id');
+               $apcontact['inbox']     = (JsonLD::fetchElement($compacted, 'ldp:inbox', '@id') ?? '');
+               $apcontact['outbox']    = JsonLD::fetchElement($compacted, 'as:outbox', '@id');
  
                $apcontact['sharedinbox'] = '';
                if (!empty($compacted['as:endpoints'])) {
index 4d7743f0dbc3dbbd81c8d0168c5145bd33ad5b6c,90f68b7725a98d1450425c2a86c075f60a624e32..d78d9ecbcb3b015eed2b2e9ac9c0df4ee1bb4df6
@@@ -815,31 -817,12 +817,31 @@@ class GServe
                }
  
                // Count the number of known contacts from this server
-                       Logger::debug('Fetched system actor',  ['url' => $url, 'gsid' => $id, 'contact' => $contact]);
 +              self::countNumberOfKnownContacts((int) $id, $serverdata);
 +
 +              if (in_array($serverdata['network'], [Protocol::DFRN, Protocol::DIASPORA])) {
 +                      self::discoverRelay($url);
 +              }
 +
 +              if (!empty($systemactor)) {
 +                      $contact = Contact::getByURL($systemactor, true, ['gsid', 'baseurl', 'id', 'network', 'url', 'name']);
++                      DI::logger()->debug('Fetched system actor', ['url' => $url, 'gsid' => $id, 'contact' => $contact]);
 +              }
 +
 +              return $ret;
 +      }
 +
 +      /**
 +       * Count the number of known contacts from this server
 +       */
 +      private static function countNumberOfKnownContacts(int $id, array $serverdata): void
 +      {
                if (!empty($id) && !in_array($serverdata['network'], [Protocol::PHANTOM, Protocol::FEED])) {
                        $apcontacts = DBA::count('apcontact', ['gsid' => $id]);
-                       $contacts = DBA::count('contact', ['uid' => 0, 'gsid' => $id, 'failed' => false]);
-                       $max_users = max($apcontacts, $contacts);
+                       $contacts   = DBA::count('contact', ['uid' => 0, 'gsid' => $id, 'failed' => false]);
+                       $max_users  = max($apcontacts, $contacts);
                        if ($max_users > $serverdata['registered-users']) {
-                               Logger::info('Update registered users', ['id' => $id, 'url' => $serverdata['nurl'], 'registered-users' => $max_users]);
+                               DI::logger()->info('Update registered users', ['id' => $id, 'url' => $serverdata['nurl'], 'registered-users' => $max_users]);
                                self::update(['registered-users' => $max_users], ['id' => $id]);
                        }
  
index 6833597a7ca287370c71d3c7d5012c2c8b777c3e,10fc41cc23b25c4bc318d5c6a6cab0834cc8a8cb..7d6318846169b63cb1dabff1897a290b6d73bb88
@@@ -917,11 -1027,52 +916,11 @@@ class Ite
                                return 0;
                        }
  
 -                      $parent_id             = $toplevel_parent['id'];
 -                      $item['parent-uri']    = $toplevel_parent['uri'];
 -                      $item['parent-uri-id'] = $toplevel_parent['uri-id'];
 -                      $item['deleted']       = $toplevel_parent['deleted'];
 -                      $item['wall']          = $toplevel_parent['wall'];
 -
 -                      // Reshares have to keep their permissions to allow groups to work
 -                      if (!$defined_permissions && (!$item['origin'] || ($item['verb'] != Activity::ANNOUNCE))) {
 -                              // Don't store the permissions on pure AP posts
 -                              $store_permissions = ($item['network'] != Protocol::ACTIVITYPUB) || $item['origin'] || !empty($item['diaspora_signed_text']);
 -                              $item['allow_cid'] = $store_permissions ? $toplevel_parent['allow_cid'] : '';
 -                              $item['allow_gid'] = $store_permissions ? $toplevel_parent['allow_gid'] : '';
 -                              $item['deny_cid']  = $store_permissions ? $toplevel_parent['deny_cid'] : '';
 -                              $item['deny_gid']  = $store_permissions ? $toplevel_parent['deny_gid'] : '';
 -                      }
 -
 +                      $parent_id     = (int) $toplevel_parent['id'];
 +                      $item          = self::handleToplevelParent($item, $toplevel_parent, $defined_permissions);
                        $parent_origin = $toplevel_parent['origin'];
 -
 -                      // Don't federate received participation messages
 -                      if ($item['verb'] != Activity::FOLLOW) {
 -                              $item['wall'] = $toplevel_parent['wall'];
 -                      } else {
 -                              $item['wall'] = false;
 -                              // Participations are technical messages, so they are set to "seen" automatically
 -                              $item['unseen'] = false;
 -                      }
 -
 -                      /*
 -                       * If the parent is private, force privacy for the entire conversation
 -                       * This differs from the above settings as it subtly allows comments from
 -                       * email correspondents to be private even if the overall thread is not.
 -                       */
 -                      if (!$defined_permissions && $toplevel_parent['private']) {
 -                              $item['private'] = $toplevel_parent['private'];
 -                      }
 -
 -                      // If its a post that originated here then tag the thread as "mention"
 -                      if ($item['origin'] && $item['uid']) {
 -                              DBA::update('post-thread-user', ['mention' => true], ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
 -                              DI::logger()->info('tagged thread as mention', ['parent' => $parent_id, 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
 -                      }
 -
 -                      // Update the contact relations
 -                      Contact\Relation::store($toplevel_parent['author-id'], $item['author-id'], $item['created']);
                } else {
-                       $parent_id = 0;
+                       $parent_id     = 0;
                        $parent_origin = $item['origin'];
  
                        if ($item['wall'] && empty($item['context'])) {
                        Post\ThreadUser::insert($item['uri-id'], $item['uid'], $item);
                }
  
-               Logger::notice('created item', ['post-id' => $post_user_id, 'uid' => $item['uid'], 'network' => $item['network'], 'uri-id' => $item['uri-id'], 'guid' => $item['guid']]);
+               DI::logger()->notice('created item', ['post-id' => $post_user_id, 'uid' => $item['uid'], 'network' => $item['network'], 'uri-id' => $item['uri-id'], 'guid' => $item['guid']]);
  
 +              return self::handleCreatedItem($orig_item, $post_user_id, $uid, $notify, $copy_permissions, $parent_origin, $priority, $notify_type, $inserted, $source);
 +      }
 +
 +      private static function handleCreatedItem(array $orig_item, int $post_user_id, int $uid, int $notify, bool $copy_permissions, $parent_origin, int $priority, string $notify_type, bool $inserted, $source): int
 +      {
                $posted_item = Post::selectFirst(self::ITEM_FIELDLIST, ['post-user-id' => $post_user_id]);
                if (!DBA::isResult($posted_item)) {
                        // On failure store the data into a spool file so that the "SpoolPost" worker can try again later.
                return $post_user_id;
        }
  
-                       Logger::info('Unknown gravity for verb', ['verb' => $item['verb']]);
 +      private static function validateItemData(array $item, ItemInserter $itemInserter): array
 +      {
 +              $item['wall']          = intval($item['wall'] ?? 0);
 +              $item['extid']         = trim($item['extid'] ?? '');
 +              $item['author-name']   = trim($item['author-name'] ?? '');
 +              $item['author-link']   = trim($item['author-link'] ?? '');
 +              $item['author-avatar'] = trim($item['author-avatar'] ?? '');
 +              $item['owner-name']    = trim($item['owner-name'] ?? '');
 +              $item['owner-link']    = trim($item['owner-link'] ?? '');
 +              $item['owner-avatar']  = trim($item['owner-avatar'] ?? '');
 +              $item['received']      = (isset($item['received'])  ? DateTimeFormat::utc($item['received'])  : DateTimeFormat::utcNow());
 +              $item['created']       = (isset($item['created'])   ? DateTimeFormat::utc($item['created'])   : $item['received']);
 +              $item['edited']        = (isset($item['edited'])    ? DateTimeFormat::utc($item['edited'])    : $item['created']);
 +              $item['changed']       = (isset($item['changed'])   ? DateTimeFormat::utc($item['changed'])   : $item['created']);
 +              $item['commented']     = (isset($item['commented']) ? DateTimeFormat::utc($item['commented']) : $item['created']);
 +              $item['title']         = substr(trim($item['title'] ?? ''), 0, 255);
 +              $item['location']      = trim($item['location'] ?? '');
 +              $item['coord']         = trim($item['coord'] ?? '');
 +              $item['visible']       = (isset($item['visible']) ? intval($item['visible']) : 1);
 +              $item['deleted']       = 0;
 +              $item['verb']          = trim($item['verb'] ?? '');
 +              $item['object-type']   = trim($item['object-type'] ?? '');
 +              $item['object']        = trim($item['object'] ?? '');
 +              $item['target-type']   = trim($item['target-type'] ?? '');
 +              $item['target']        = trim($item['target'] ?? '');
 +              $item['plink']         = substr(trim($item['plink'] ?? ''), 0, 255);
 +              $item['allow_cid']     = trim($item['allow_cid'] ?? '');
 +              $item['allow_gid']     = trim($item['allow_gid'] ?? '');
 +              $item['deny_cid']      = trim($item['deny_cid'] ?? '');
 +              $item['deny_gid']      = trim($item['deny_gid'] ?? '');
 +              $item['private']       = intval($item['private'] ?? self::PUBLIC);
 +              $item['body']          = trim($item['body'] ?? '');
 +              $item['raw-body']      = trim($item['raw-body'] ?? $item['body']);
 +              $item['app']           = trim($item['app'] ?? '');
 +              $item['origin']        = intval($item['origin'] ?? 0);
 +              $item['postopts']      = trim($item['postopts'] ?? '');
 +              $item['resource-id']   = trim($item['resource-id'] ?? '');
 +              $item['event-id']      = intval($item['event-id'] ?? 0);
 +              $item['inform']        = trim($item['inform'] ?? '');
 +              $item['file']          = trim($item['file'] ?? '');
 +
 +              // Items cannot be stored before they happen ...
 +              if ($item['created'] > DateTimeFormat::utcNow()) {
 +                      $item['created'] = DateTimeFormat::utcNow();
 +              }
 +
 +              // We haven't invented time travel by now.
 +              if ($item['edited'] > DateTimeFormat::utcNow()) {
 +                      $item['edited'] = DateTimeFormat::utcNow();
 +              }
 +
 +              $item['plink'] = ($item['plink'] ?? '') ?: DI::baseUrl() . '/display/' . urlencode($item['guid']);
 +
 +              $item['gravity'] = $itemInserter->getGravity($item);
 +
 +              if ($item['gravity'] === self::GRAVITY_UNKNOWN) {
-                       'url' => $item['author-link'], 'name' => $item['author-name'],
++                      DI::logger()->info('Unknown gravity for verb', ['verb' => $item['verb']]);
 +              }
 +
 +              $default = [
-                       'url' => $item['owner-link'], 'name' => $item['owner-name'],
++                      'url'   => $item['author-link'], 'name' => $item['author-name'],
 +                      'photo' => $item['author-avatar'], 'network' => $item['network']
 +              ];
 +              $item['author-id'] = ($item['author-id'] ?? 0) ?: Contact::getIdForURL($item['author-link'], 0, null, $default);
 +
 +              $default = [
-                       Logger::info('tagged thread as mention', ['parent' => $parent_id, 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
++                      'url'   => $item['owner-link'], 'name' => $item['owner-name'],
 +                      'photo' => $item['owner-avatar'], 'network' => $item['network']
 +              ];
 +              $item['owner-id'] = ($item['owner-id'] ?? 0) ?: Contact::getIdForURL($item['owner-link'], 0, null, $default);
 +
 +              $item['post-reason'] = self::getPostReason($item);
 +
 +              return $item;
 +      }
 +
 +      private static function handleToplevelParent(array $item, array $toplevel_parent, bool $defined_permissions): array
 +      {
 +              $parent_id             = (int) $toplevel_parent['id'];
 +              $item['parent-uri']    = $toplevel_parent['uri'];
 +              $item['parent-uri-id'] = $toplevel_parent['uri-id'];
 +              $item['deleted']       = $toplevel_parent['deleted'];
 +              $item['wall']          = $toplevel_parent['wall'];
 +
 +              // Reshares have to keep their permissions to allow groups to work
 +              if (!$defined_permissions && (!$item['origin'] || ($item['verb'] != Activity::ANNOUNCE))) {
 +                      // Don't store the permissions on pure AP posts
 +                      $store_permissions = ($item['network'] != Protocol::ACTIVITYPUB) || $item['origin'] || !empty($item['diaspora_signed_text']);
 +                      $item['allow_cid'] = $store_permissions ? $toplevel_parent['allow_cid'] : '';
 +                      $item['allow_gid'] = $store_permissions ? $toplevel_parent['allow_gid'] : '';
 +                      $item['deny_cid']  = $store_permissions ? $toplevel_parent['deny_cid'] : '';
 +                      $item['deny_gid']  = $store_permissions ? $toplevel_parent['deny_gid'] : '';
 +              }
 +
 +              // Don't federate received participation messages
 +              if ($item['verb'] != Activity::FOLLOW) {
 +                      $item['wall'] = $toplevel_parent['wall'];
 +              } else {
 +                      $item['wall'] = false;
 +                      // Participations are technical messages, so they are set to "seen" automatically
 +                      $item['unseen'] = false;
 +              }
 +
 +              /*
 +               * If the parent is private, force privacy for the entire conversation
 +               * This differs from the above settings as it subtly allows comments from
 +               * email correspondents to be private even if the overall thread is not.
 +               */
 +              if (!$defined_permissions && $toplevel_parent['private']) {
 +                      $item['private'] = $toplevel_parent['private'];
 +              }
 +
 +              // If its a post that originated here then tag the thread as "mention"
 +              if ($item['origin'] && $item['uid']) {
 +                      DBA::update('post-thread-user', ['mention' => true], ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
++                      DI::logger()->info('tagged thread as mention', ['parent' => $parent_id, 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
 +              }
 +
 +              // Update the contact relations
 +              Contact\Relation::store($toplevel_parent['author-id'], $item['author-id'], $item['created']);
 +
 +              return $item;
 +      }
 +
        private static function hasRestrictions(array $item, int $author_id, int $restrictions = null): bool
        {
                if (empty($restrictions) || ($author_id == $item['author-id'])) {
index cf824190ca4a482f57a68f303a930a33f4b246df,0000000000000000000000000000000000000000..0db7ea1d0af253cfa529a852e7aa82a741fc940b
mode 100644,000000..100644
--- /dev/null
@@@ -1,80 -1,0 +1,80 @@@
-               $item['uri'] = substr(trim($item['uri'] ?? '') ?: Item::newURI($item['guid']), 0, 255);
 +<?php
 +
 +// Copyright (C) 2010-2024, the Friendica project
 +// SPDX-FileCopyrightText: 2010-2024 the Friendica project
 +//
 +// SPDX-License-Identifier: AGPL-3.0-or-later
 +
 +namespace Friendica\Model;
 +
 +use Friendica\Content\Item as ItemContent;
 +use Friendica\Protocol\Activity;
 +
 +/**
 + * A helper class for inserting an Item Model
 + *
 + * @see Item::insert()
 + */
 +final class ItemInserter
 +{
 +      private ItemContent $itemContent;
 +
 +      private Activity $activity;
 +
 +      public function __construct(ItemContent $itemContent, Activity $activity)
 +      {
 +              $this->itemContent = $itemContent;
 +              $this->activity    = $activity;
 +      }
 +
 +      public function prepareOriginPost(array $item): array
 +      {
 +              $item = $this->itemContent->initializePost($item);
 +              $item = $this->itemContent->finalizePost($item, false);
 +
 +              return $item;
 +      }
 +
 +      public function prepareItemData(array $item, bool $notify): array
 +      {
 +              $item['guid'] = Item::guid($item, $notify);
++              $item['uri']  = substr(trim($item['uri'] ?? '') ?: Item::newURI($item['guid']), 0, 255);
 +
 +              // Store URI data
 +              $item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]);
 +
 +              // Backward compatibility: parent-uri used to be the direct parent uri.
 +              // If it is provided without a thr-parent, it probably is the old behavior.
 +              if (empty($item['thr-parent']) || empty($item['parent-uri'])) {
 +                      $item['thr-parent'] = trim($item['thr-parent'] ?? $item['parent-uri'] ?? $item['uri']);
 +                      $item['parent-uri'] = $item['thr-parent'];
 +              }
 +
 +              $item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']);
 +              $item['parent-uri-id'] = ItemURI::getIdByURI($item['parent-uri']);
 +
 +              return $item;
 +      }
 +
 +      /**
 +       * Get the gravity for the given item array
 +       *
 +       * @return int gravity
 +       */
 +      public function getGravity(array $item): int
 +      {
 +              if (isset($item['gravity'])) {
 +                      return intval($item['gravity']);
 +              } elseif ($item['parent-uri-id'] === $item['uri-id']) {
 +                      return Item::GRAVITY_PARENT;
 +              } elseif ($this->activity->match($item['verb'], Activity::POST)) {
 +                      return Item::GRAVITY_COMMENT;
 +              } elseif ($this->activity->match($item['verb'], Activity::FOLLOW)) {
 +                      return Item::GRAVITY_ACTIVITY;
 +              } elseif ($this->activity->match($item['verb'], Activity::ANNOUNCE)) {
 +                      return Item::GRAVITY_ACTIVITY;
 +              }
 +
 +              return Item::GRAVITY_UNKNOWN;   // Should not happen
 +      }
 +}