diff --git a/src/Model/Item.php b/src/Model/Item.php index 5eb3ba6a5d..c615cfc0f7 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -141,6 +141,7 @@ class Item Activity::FOLLOW, Activity::ANNOUNCE]; + // Privacy levels const PUBLIC = 0; const PRIVATE = 1; const UNLISTED = 2; diff --git a/src/Object/Post.php b/src/Object/Post.php index 7c73be7796..7c3d739bcb 100644 --- a/src/Object/Post.php +++ b/src/Object/Post.php @@ -585,17 +585,17 @@ class Post } } + // Copy values/set defaults $result['total_comments_num'] = $this->isToplevel() ? $total_children : 0; - $result['private'] = $item['private']; $result['toplevel'] = ($this->isToplevel() ? 'toplevel_item' : ''); + $result['flatten'] = false; + $result['threaded'] = false; if ($this->isThreaded()) { - $result['flatten'] = false; $result['threaded'] = true; } else { $result['flatten'] = true; - $result['threaded'] = false; } return $result; @@ -618,33 +618,32 @@ class Post } /** - * Add a child item + * Add a child post * - * @param Post $item The child item to add + * @param Post $item The child post to add * - * @return mixed + * @return Post|bool Last Post object or bool on any error * @throws \Exception */ public function addChild(Post $item) { - $item_id = $item->getId(); - if (!$item_id) { - Logger::info('[ERROR] Post::addChild : Item has no ID!!'); + if (!$item->getId()) { + Logger::fatal('Post object has no id', ['post' => $item]); return false; } elseif ($this->getChild($item->getId())) { - Logger::info('[WARN] Post::addChild : Item already exists (' . $item->getId() . ').'); + Logger::warning('Post object already exists', ['post' => $item]); return false; } - $activity = DI::activity(); - /* * Only add what will be displayed */ if ($item->getDataValue('network') === Protocol::MAIL && DI::userSession()->getLocalUserId() != $item->getDataValue('uid')) { + Logger::warning('Post object does not belong to local user', ['post' => $item, 'local_user' => $local_user]); return false; - } elseif ($activity->match($item->getDataValue('verb'), Activity::LIKE) || - $activity->match($item->getDataValue('verb'), Activity::DISLIKE)) { + } elseif (DI::activity()->match($item->getDataValue('verb'), Activity::LIKE) || + DI::activity()->match($item->getDataValue('verb'), Activity::DISLIKE)) { + Logger::warning('Post objects is a like/dislike', ['post' => $item]); return false; } @@ -658,7 +657,7 @@ class Post * Get a child by its ID * * @param integer $id The child id - * @return mixed + * @return Thread|null Thread or NULL if not found */ public function getChild(int $id) { @@ -747,6 +746,7 @@ class Post * Set conversation thread * * @param Thread|null $thread + * * @return void */ public function setThread(Thread $thread = null) @@ -785,6 +785,7 @@ class Post * Get a data value * * @param string $name key + * * @return mixed value on success, false on failure */ public function getDataValue(string $name) @@ -798,13 +799,14 @@ class Post } /** - * Set template + * Set template by name * * @param string $name Template name - * @return bool If template was set + * + * @return void * @throws InvalidArgumentException */ - private function setTemplate(string $name): bool + private function setTemplate(string $name) { if (empty($this->available_templates[$name])) { // Throw exception @@ -812,8 +814,6 @@ class Post } $this->template = $this->available_templates[$name]; - - return true; } /** @@ -939,6 +939,7 @@ class Post * Get the comment box * * @param string $indent Indent value + * * @return mixed The comment box string (empty if no comment box), false on failure * @throws \Exception * @todo return false is nowhere in this method? diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index d90b80e6fd..706adb401e 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -246,6 +246,8 @@ class Delivery * * @param string $cmd Command * @param array $item Item array + * + * @return void */ private static function setFailedQueue(string $cmd, array $item) { @@ -268,6 +270,8 @@ class Delivery * @param boolean $top_level Is it a thread starter? * @param boolean $followup Is it an answer to a remote post? * @param int|null $server_protocol The protocol of the server + * + * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ @@ -303,8 +307,8 @@ class Delivery foreach ($items as $item) { // Only add the parent when we don't delete other items. if (($target_item['id'] == $item['id']) || ($cmd != self::DELETION)) { - $item["entry:comment-allow"] = true; - $item["entry:cid"] = ($top_level ? $contact['id'] : 0); + $item['entry:comment-allow'] = true; + $item['entry:cid'] = ($top_level ? $contact['id'] : 0); $msgitems[] = $item; } } @@ -312,7 +316,7 @@ class Delivery $atom = DFRN::entries($msgitems, $owner); } - Logger::debug('Notifier entry: ' . $contact["url"] . ' ' . (($target_item['guid'] ?? '') ?: $target_item['id']) . ' entry: ' . $atom); + Logger::debug('Notifier entry: ' . $contact['url'] . ' ' . (($target_item['guid'] ?? '') ?: $target_item['id']) . ' entry: ' . $atom); $protocol = Post\DeliveryData::DFRN; @@ -326,7 +330,7 @@ class Delivery // We never spool failed relay deliveries if ($public_dfrn) { - Logger::info('Relay delivery to ' . $contact["url"] . ' with guid ' . $target_item["guid"] . ' returns ' . $deliver_status); + Logger::info('Relay delivery to ' . $contact['url'] . ' with guid ' . $target_item['guid'] . ' returns ' . $deliver_status); if ($cmd == Delivery::POST) { if (($deliver_status >= 200) && ($deliver_status <= 299)) { @@ -383,6 +387,8 @@ class Delivery * @param boolean $public_message Is the content public? * @param boolean $top_level Is it a thread starter? * @param boolean $followup Is it an answer to a remote post? + * + * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ @@ -477,6 +483,7 @@ class Delivery * @param array $owner Owner record of the sender * @param array $target_item Item record of the content * @param array $thr_parent Item record of the direct parent in the thread + * * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index 4498723223..9898eed1a0 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -173,7 +173,7 @@ class Notifier $parent = $items[0]; $fields = ['network', 'author-id', 'author-link', 'author-network', 'owner-id']; - $condition = ['uri' => $target_item["thr-parent"], 'uid' => $target_item["uid"]]; + $condition = ['uri' => $target_item['thr-parent'], 'uid' => $target_item['uid']]; $thr_parent = Post::selectFirst($fields, $condition); if (empty($thr_parent)) { $thr_parent = $parent; @@ -376,27 +376,27 @@ class Notifier if (($thr_parent && ($thr_parent['network'] == Protocol::OSTATUS)) || ($parent['network'] == Protocol::OSTATUS)) { $diaspora_delivery = false; - Logger::info('Some parent is OStatus for '.$target_item["guid"]." - Author: ".$thr_parent['author-id']." - Owner: ".$thr_parent['owner-id']); + Logger::info('Some parent is OStatus for ' . $target_item['guid'] . ' - Author: ' . $thr_parent['author-id'] . ' - Owner: ' . $thr_parent['owner-id']); // Send a salmon to the parent author $probed_contact = DBA::selectFirst('contact', ['url', 'notify'], ['id' => $thr_parent['author-id']]); - if (DBA::isResult($probed_contact) && !empty($probed_contact["notify"])) { - Logger::notice('Notify parent author', ['url' => $probed_contact["url"], 'notify' => $probed_contact["notify"]]); - $url_recipients[$probed_contact["notify"]] = $probed_contact["notify"]; + if (DBA::isResult($probed_contact) && !empty($probed_contact['notify'])) { + Logger::notice('Notify parent author', ['url' => $probed_contact['url'], 'notify' => $probed_contact['notify']]); + $url_recipients[$probed_contact['notify']] = $probed_contact['notify']; } // Send a salmon to the parent owner $probed_contact = DBA::selectFirst('contact', ['url', 'notify'], ['id' => $thr_parent['owner-id']]); - if (DBA::isResult($probed_contact) && !empty($probed_contact["notify"])) { - Logger::notice('Notify parent owner', ['url' => $probed_contact["url"], 'notify' => $probed_contact["notify"]]); - $url_recipients[$probed_contact["notify"]] = $probed_contact["notify"]; + if (DBA::isResult($probed_contact) && !empty($probed_contact['notify'])) { + Logger::notice('Notify parent owner', ['url' => $probed_contact['url'], 'notify' => $probed_contact['notify']]); + $url_recipients[$probed_contact['notify']] = $probed_contact['notify']; } // Send a salmon notification to every person we mentioned in the post foreach (Tag::getByURIId($target_item['uri-id'], [Tag::MENTION, Tag::EXCLUSIVE_MENTION, Tag::IMPLICIT_MENTION]) as $tag) { $probed_contact = Contact::getByURL($tag['url']); if (!empty($probed_contact['notify'])) { - Logger::notice('Notify mentioned user', ['url' => $probed_contact["url"], 'notify' => $probed_contact["notify"]]); + Logger::notice('Notify mentioned user', ['url' => $probed_contact['url'], 'notify' => $probed_contact['notify']]); $url_recipients[$probed_contact['notify']] = $probed_contact['notify']; } } @@ -497,11 +497,12 @@ class Notifier * @param array $contacts * @param array $ap_contacts * @param array $conversants - * @return int + * + * @return int Count of delivery queue * @throws InternalServerErrorException * @throws Exception */ - private static function delivery(string $cmd, int $post_uriid, int $sender_uid, array $target_item, array $thr_parent, array $owner, bool $batch_delivery, bool $in_batch, array $contacts, array $ap_contacts, array $conversants = []) + private static function delivery(string $cmd, int $post_uriid, int $sender_uid, array $target_item, array $thr_parent, array $owner, bool $batch_delivery, bool $in_batch, array $contacts, array $ap_contacts, array $conversants = []): int { $a = DI::app(); $delivery_queue_count = 0; @@ -591,11 +592,12 @@ class Notifier * @param array $url_recipients * @param bool $public_message * @param bool $push_notify - * @return int + * + * @return int Count of sent Salmon notifications * @throws InternalServerErrorException * @throws Exception */ - private static function deliverOStatus(int $target_id, array $target_item, array $owner, array $url_recipients, bool $public_message, bool $push_notify) + private static function deliverOStatus(int $target_id, array $target_item, array $owner, array $url_recipients, bool $public_message, bool $push_notify): int { $a = DI::app(); $delivery_queue_count = 0; @@ -616,7 +618,7 @@ class Notifier // Notify PuSH subscribers (Used for OStatus distribution of regular posts) if ($push_notify) { - Logger::info('Activating internal PuSH', ['item' => $target_id]); + Logger::info('Activating internal PuSH', ['uid' => $owner['uid']]); // Handling the pubsubhubbub requests PushSubscriber::publishFeed($owner['uid'], $a->getQueueValue('priority')); @@ -631,9 +633,10 @@ class Notifier * @param array $contact Receiver of the post * @param array $item The post * @param array $thr_parent The thread parent + * * @return bool */ - private static function skipActivityPubForDiaspora(array $contact, array $item, array $thr_parent) + private static function skipActivityPubForDiaspora(array $contact, array $item, array $thr_parent): bool { // No skipping needs to be done when delivery isn't done to Diaspora if ($contact['network'] != Protocol::DIASPORA) { @@ -661,11 +664,12 @@ class Notifier * @param string $cmd Notifier command * @param array $owner Sender of the post * @param string $network Receiver network + * * @return bool * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function isRemovalActivity($cmd, $owner, $network) + private static function isRemovalActivity(string $cmd, array $owner, string $network): bool { return ($cmd == Delivery::DELETION) && $owner['account_removed'] && in_array($network, [Protocol::ACTIVITYPUB, Protocol::DIASPORA]); } @@ -674,11 +678,12 @@ class Notifier * @param int $self_user_id * @param int $priority The priority the Notifier queue item was created with * @param string $created The date the Notifier queue item was created on + * * @return bool * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function notifySelfRemoval($self_user_id, $priority, $created) + private static function notifySelfRemoval(int $self_user_id, int $priority, string $created): bool { $owner = User::getOwnerDataById($self_user_id); if (empty($self_user_id) || empty($owner)) { @@ -713,11 +718,13 @@ class Notifier * @param array $thr_parent * @param int $priority The priority the Notifier queue item was created with * @param string $created The date the Notifier queue item was created on + * * @return array 'count' => The number of delivery tasks created, 'contacts' => their contact ids * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException + * @todo Unused parameter $owner */ - private static function activityPubDelivery($cmd, array $target_item, array $parent, array $thr_parent, $priority, $created, $owner) + private static function activityPubDelivery($cmd, array $target_item, array $parent, array $thr_parent, int $priority, string $created, $owner): array { // Don't deliver via AP when the starting post isn't from a federated network if (!in_array($parent['network'], Protocol::FEDERATED)) { diff --git a/src/Worker/OnePoll.php b/src/Worker/OnePoll.php index 83a7a5f15c..462c90e2f7 100644 --- a/src/Worker/OnePoll.php +++ b/src/Worker/OnePoll.php @@ -44,7 +44,7 @@ class OnePoll { public static function execute(int $contact_id = 0, string $command = '') { - Logger::notice('Start polling/probing contact', ['id' => $contact_id]); + Logger::notice('Start polling/probing contact', ['id' => $contact_id, 'command' => $command]); $force = ($command == 'force'); @@ -119,6 +119,7 @@ class OnePoll * * @param array $contact The personal contact entry * @param array $fields The fields that are updated + * * @return void * @throws \Exception */ @@ -148,7 +149,7 @@ class OnePoll * @return bool Success * @throws \Exception */ - private static function pollFeed(array $contact, $importer) + private static function pollFeed(array $contact, array $importer): bool { // Are we allowed to import from this person? if ($contact['rel'] == Contact::FOLLOWER || $contact['blocked']) { @@ -187,9 +188,11 @@ class OnePoll * @param array $contact The personal contact entry * @param integer $importer_uid The UID of the importer * @param string $updated The updated date + * + * @return bool Success * @throws \Exception */ - private static function pollMail(array $contact, $importer_uid, $updated) + private static function pollMail(array $contact, int $importer_uid, string $updated): bool { Logger::info('Fetching mails', ['addr' => $contact['addr']]); @@ -242,25 +245,25 @@ class OnePoll foreach ($msgs as $msg_uid => $meta) { Logger::info('Parsing mail', ['message-uid' => $msg_uid]); - $datarray = []; - $datarray['uid'] = $importer_uid; - $datarray['contact-id'] = $contact['id']; - $datarray['verb'] = Activity::POST; - $datarray['object-type'] = Activity\ObjectType::NOTE; - $datarray['network'] = Protocol::MAIL; - $datarray['protocol'] = Conversation::PARCEL_IMAP; - $datarray['direction'] = Conversation::PULL; - - // $meta = Email::messageMeta($mbox, $msg_uid); - + $datarray = [ + 'uid' => $importer_uid, + 'contact-id' => $contact['id'], + 'verb' => Activity::POST, + 'object-type' => Activity\ObjectType::NOTE, + 'network' => Protocol::MAIL, + 'protocol' => Conversation::PARCEL_IMAP, + 'direction' => Conversation::PULL, + ]; $datarray['thr-parent'] = $datarray['uri'] = Email::msgid2iri(trim($meta->message_id, '<>')); + // $meta = Email::messageMeta($mbox, $msg_uid); + // Have we seen it before? $fields = ['deleted', 'id']; $condition = ['uid' => $importer_uid, 'uri' => $datarray['uri']]; $item = Post::selectFirst($fields, $condition); if (DBA::isResult($item)) { - Logger::info("Mail: Seen before ".$msg_uid." for ".$mailconf['user']." UID: ".$importer_uid." URI: ".$datarray['uri']); + Logger::info('Mail: Seen before ' . $msg_uid . ' for ' . $mailconf['user'] . ' UID: ' . $importer_uid . ' URI: ' . $datarray['uri']); // Only delete when mails aren't automatically moved or deleted if (($mailconf['action'] != 1) && ($mailconf['action'] != 3)) @@ -271,20 +274,23 @@ class OnePoll switch ($mailconf['action']) { case 0: - Logger::info("Mail: Seen before ".$msg_uid." for ".$mailconf['user'].". Doing nothing."); + Logger::info('Mail: Seen before ' . $msg_uid . ' for ' . $mailconf['user'] . '. Doing nothing.'); break; + case 1: - Logger::notice("Mail: Deleting ".$msg_uid." for ".$mailconf['user']); + Logger::notice('Mail: Deleting ' . $msg_uid . ' for ' . $mailconf['user']); imap_delete($mbox, $msg_uid, FT_UID); break; + case 2: - Logger::notice("Mail: Mark as seen ".$msg_uid." for ".$mailconf['user']); + Logger::notice('Mail: Mark as seen ' . $msg_uid . ' for ' . $mailconf['user']); imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); break; + case 3: - Logger::notice("Mail: Moving ".$msg_uid." to ".$mailconf['movetofolder']." for ".$mailconf['user']); + Logger::notice('Mail: Moving ' . $msg_uid . ' to ' . $mailconf['movetofolder'] . ' for ' . $mailconf['user']); imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); - if ($mailconf['movetofolder'] != "") { + if ($mailconf['movetofolder'] != '') { imap_mail_move($mbox, $msg_uid, $mailconf['movetofolder'], FT_UID); } break; @@ -329,12 +335,12 @@ class OnePoll $datarray['created'] = DateTimeFormat::utc($meta->date); // Is it a reply? - $reply = ((substr(strtolower($datarray['title']), 0, 3) == "re:") || - (substr(strtolower($datarray['title']), 0, 3) == "re-") || - ($raw_refs != "")); + $reply = ((substr(strtolower($datarray['title']), 0, 3) == 're:') || + (substr(strtolower($datarray['title']), 0, 3) == 're-') || + ($raw_refs != '')); // Remove Reply-signs in the subject - $datarray['title'] = self::RemoveReply($datarray['title']); + $datarray['title'] = self::removeReply($datarray['title']); // If it seems to be a reply but a header couldn't be found take the last message with matching subject if (empty($datarray['thr-parent']) && $reply) { @@ -376,11 +382,11 @@ class OnePoll } $datarray['author-name'] = $fromname; - $datarray['author-link'] = "mailto:".$frommail; + $datarray['author-link'] = 'mailto:' . $frommail; $datarray['author-avatar'] = $contact['photo']; $datarray['owner-name'] = $contact['name']; - $datarray['owner-link'] = "mailto:".$contact['addr']; + $datarray['owner-link'] = 'mailto:' . $contact['addr']; $datarray['owner-avatar'] = $contact['photo']; if (empty($datarray['thr-parent']) || ($datarray['thr-parent'] === $datarray['uri'])) { @@ -398,26 +404,29 @@ class OnePoll continue; } - Logger::notice("Mail: Importing ".$msg_uid." for ".$mailconf['user']); + Logger::notice('Mail: Importing ' . $msg_uid . ' for ' . $mailconf['user']); Item::insert($datarray); switch ($mailconf['action']) { case 0: - Logger::info("Mail: Seen before ".$msg_uid." for ".$mailconf['user'].". Doing nothing."); + Logger::info('Mail: Seen before ' . $msg_uid . ' for ' . $mailconf['user'] . '. Doing nothing.'); break; + case 1: - Logger::notice("Mail: Deleting ".$msg_uid." for ".$mailconf['user']); + Logger::notice('Mail: Deleting ' . $msg_uid . ' for ' . $mailconf['user']); imap_delete($mbox, $msg_uid, FT_UID); break; + case 2: - Logger::notice("Mail: Mark as seen ".$msg_uid." for ".$mailconf['user']); + Logger::notice('Mail: Mark as seen ' . $msg_uid . ' for ' . $mailconf['user']); imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); break; + case 3: - Logger::notice("Mail: Moving ".$msg_uid." to ".$mailconf['movetofolder']." for ".$mailconf['user']); + Logger::notice('Mail: Moving ' . $msg_uid . ' to ' . $mailconf['movetofolder'] . ' for ' . $mailconf['user']); imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); - if ($mailconf['movetofolder'] != "") { + if ($mailconf['movetofolder'] != '') { imap_mail_move($mbox, $msg_uid, $mailconf['movetofolder'], FT_UID); } break; @@ -435,9 +444,9 @@ class OnePoll return true; } - private static function RemoveReply($subject) + private static function removeReply(string $subject): string { - while (in_array(strtolower(substr($subject, 0, 3)), ["re:", "aw:"])) { + while (in_array(strtolower(substr($subject, 0, 3)), ['re:', 'aw:'])) { $subject = trim(substr($subject, 4)); } @@ -449,9 +458,11 @@ class OnePoll * @param array $importer * @param array $contact * @param string $hubmode + * + * @return bool Success * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function subscribeToHub(string $url, array $importer, array $contact, string $hubmode = 'subscribe') + private static function subscribeToHub(string $url, array $importer, array $contact, string $hubmode = 'subscribe'): bool { $push_url = DI::baseUrl() . '/pubsub/' . $importer['nick'] . '/' . $contact['id'];